Compare commits

...

19 Commits

Author SHA1 Message Date
eball
f8b5f05f02 Merge branch 'main' into module-l4-bfl-proxy
* main:
  fix: coscmd invalid parameters
  Add VERSION environment variable to workflow
  fix: update error handling to check for both 403 and 404 HTTP status codes in upload scripts
2026-03-03 11:06:16 +08:00
eball
e03eb40ed8 fix: coscmd invalid parameters 2026-03-03 00:44:47 +08:00
eball
79b7d82748 Add VERSION environment variable to workflow 2026-03-02 23:59:23 +08:00
aby913
abe84160be fix: update error handling to check for both 403 and 404 HTTP status codes in upload scripts 2026-03-02 22:43:45 +08:00
eball
20344416f8 fix: update error handling to check for both 403 and 404 HTTP status codes in upload scripts 2026-03-02 22:33:27 +08:00
aby913
360b935833 l4-bfl-proxy: fix multi users app custom domain 2026-03-02 22:31:17 +08:00
aby913
10c130b1bf l4-bfl-proxy: fix multi users app custom domain (#2597) 2026-03-02 22:26:33 +08:00
eball
8c59050529 fix: remove unnecessary 'cp' argument from coscmd upload commands in release workflows 2026-03-02 15:18:40 +08:00
eball
f932d10916 fix: update upload command in release workflows to remove unnecessary 'cp' argument 2026-03-02 15:15:45 +08:00
eball
e4762d880b fix: remove public-read ACL from coscmd upload commands in release workflows 2026-03-02 15:08:27 +08:00
eball
017b2e2acd ci: change cdn backend storage to cos (#2592) 2026-03-02 14:55:26 +08:00
dkeven
d3adeced3f fix(cli): dynamic creation of nvidia runtimeclass (#2591) 2026-03-02 13:50:29 +08:00
hysyeah
48038504a7 fix: add kubeblocks addon chart image to manifest (#2590) 2026-03-02 13:50:04 +08:00
Yajing
d17d8fca14 docs: update Windows local access steps & tidy wording (#2587)
update Windows .local access & tidy wording
2026-03-02 13:23:57 +08:00
Teng
35770fbe46 docs: fix model name used in tutorial (#2582)
* fix model name used in tutorial

* Update docs/use-cases/openclaw.md

---------

Co-authored-by: Power-One-2025 <zhengchunhong@bytetrade.io>
2026-02-28 22:37:40 +08:00
Yajing
39cb3335d6 docs: fix & streamline ssh access (#2584)
fix & streamline ssh access
2026-02-28 22:29:49 +08:00
Yajing
0e1208d555 docs: add how to check SSH password in vault (#2571)
* add how to check SSH password in vault

* reuse reset ssh content, improve wording & flow
2026-02-28 14:24:10 +08:00
Yajing
65fa0c0da8 docs: add factory reset via BIOS and reinstall via USB (#2576)
* add factory reset via BIOS and reinstall via USB

* refine wording & add screenshots

* add zh docs

* address comments
2026-02-28 13:12:21 +08:00
eball
cf7125aac8 cli, daemon: enhance DGX Spark support and update GPU type handling (#2496)
* feat(gpu): enhance DGX Spark support and update GPU type handling

* feat(amdgpu): refactor AMD GPU detection and support for GB10 chip and APU

* feat(connector): enhance GB10 chip detection with environment variable support

* feat(gpu): enhance DGX Spark support and update GPU type handling

* feat(amdgpu): refactor AMD GPU detection and support for GB10 chip and APU

* feat(connector): enhance GB10 chip detection with environment variable support

* feat: add nvidia device plugin for gb10

* fix(gpu): update pod selector for hami-device-plugin based on GB10 chip detection

fix(deploy): bump app-service image version to 0.4.78

* feat: enable CGO for building on ARM architecture and adjust build constraints for Linux

* feat: enhance multi-architecture support for ARM64 in release workflow

* feat: update multi-arch setup for ARM64 in release workflow

* feat: enhance ARM64 multi-architecture support in release workflow

* feat: streamline ARM64 cross-compilation setup in release workflow

* feat: enhance ARM64 support by adding architecture-specific package installations

* feat: update ARM64 package sources in release workflow for improved compatibility

* feat: amd device plugin and container toolkit install

* refactor: remove GB10 chip type check from GPU info update

* feat(gpu): update hami version to v2.6.10-compatible for spark

* fix: remove gb10 device plugin checking

* fix: update klauspost/cpuid to v2.3.0

* fix: amd gpu check (#2522)

* feat: enhance storage device detection with USB serial properties

* feat: update hami version to v2.6.11-compatible-arm

* feat: add chip type support for AMD and NVIDIA GPUs in node label updates

* feat(gpu): supports auto binding GPU to app

* feat(gpu): remove chip type handling from GPU label updates

* feat(gpu): remove GPU type specification from DaemonSet and values.yaml

* feat(gpu): remove GB10 device plugin installation and related checks

* feat(gpu): update HAMi to v2.6.11

---------

Co-authored-by: dkeven <dkvvven@gmail.com>
Co-authored-by: hys <hysyeah@gmail.com>
2026-02-28 11:44:02 +08:00
99 changed files with 2185 additions and 1032 deletions

View File

@@ -11,10 +11,22 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- run: |
bash build/build-redis.sh linux/amd64 glibc-231

View File

@@ -11,12 +11,24 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- run: |
bash build/build-redis.sh linux/amd64
push-arm64:
@@ -34,10 +46,22 @@ jobs:
run: |
sudo apt install -y make gcc
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- run: |
sudo -E sh -c "bash build/build-redis.sh linux/arm64 && rm -rf redis*"

View File

@@ -11,10 +11,22 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- run: |
bash build/build-ubuntu2204.sh

View File

@@ -11,10 +11,23 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- run: |
bash build/build-wsl-install-msi.sh

View File

@@ -60,14 +60,6 @@ jobs:
- name: Run chart-testing (lint)
run: ct lint --chart-dirs .dist/wizard/config,.dist/wizard/config/apps,.dist/wizard/config/gpu --check-version-increment=false --all
# - name: Create kind cluster
# if: steps.list-changed.outputs.changed == 'true'
# uses: helm/kind-action@v1.7.0
# - name: Run chart-testing (install)
# if: steps.list-changed.outputs.changed == 'true'
# run: ct install --chart-dirs wizard/charts,wizard/config --target-branch ${{ github.event.repository.default_branch }}
test-version:
runs-on: ubuntu-latest
outputs:
@@ -107,12 +99,23 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- run: |
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf
push-image-arm64:
@@ -132,12 +135,23 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Install coscmd
run: pip install coscmd
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- run: |
export PATH=$PATH:/usr/local/bin:/home/ubuntu/.local/bin
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf linux/arm64
@@ -154,11 +168,23 @@ jobs:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ needs.test-version.outputs.version }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
run: |
@@ -179,11 +205,21 @@ jobs:
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ needs.test-version.outputs.version }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
run: |
@@ -206,15 +242,28 @@ jobs:
run: |
bash build/build.sh ${{ needs.test-version.outputs.version }}
- name: Upload package
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- name: Upload package
run: |
md5sum install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz > install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt s3://terminus-os-install/install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz s3://terminus-os-install/install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz --acl=public-read
coscmd upload install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt /install-wizard-v${{ needs.test-version.outputs.version }}.md5sum.txt && \
coscmd upload install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz /install-wizard-v${{ needs.test-version.outputs.version }}.tar.gz
install-test:

View File

@@ -60,12 +60,24 @@ jobs:
OLARES_RELEASE_ID: ${{ inputs.release-id }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to S3
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- name: Upload to CDN
run: |
cd cli/output && for file in $(ls *.tar.gz | grep -v no-release-id); do
aws s3 cp "$file" s3://terminus-os-install${{ secrets.REPO_PATH }}${file} --acl=public-read
coscmd upload "$file" ${{ secrets.REPO_PATH }}${file}
done

View File

@@ -72,12 +72,25 @@ jobs:
version: v1.18.2
args: release --clean
- name: Upload to CDN
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- name: Upload to CDN
run: |
cd daemon/output && for file in $(ls *.tar.gz | grep -v no-release-id); do
aws s3 cp "$file" s3://terminus-os-install${{ secrets.REPO_PATH }}${file} --acl=public-read
coscmd upload "$file" ${{ secrets.REPO_PATH }}${file}
done

View File

@@ -55,11 +55,23 @@ jobs:
- name: 'Checkout source code'
uses: actions/checkout@v3
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- run: |
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf
push-images-arm64:
@@ -69,11 +81,23 @@ jobs:
- name: 'Checkout source code'
uses: actions/checkout@v3
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- run: |
export PATH=$PATH:/usr/local/bin:/home/ubuntu/.local/bin
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf linux/arm64
@@ -85,11 +109,24 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ needs.daily-version.outputs.version }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
@@ -104,11 +141,24 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ needs.daily-version.outputs.version }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
@@ -129,19 +179,31 @@ jobs:
run: |
bash build/build.sh ${{ needs.daily-version.outputs.version }} ${{ needs.release-id.outputs.id }}
- name: Upload to S3
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- name: Upload to COS
id: upload
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
run: |
md5sum install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz > install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz --acl=public-read && \
coscmd upload install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt ${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt && \
coscmd upload install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz ${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.${{ needs.release-id.outputs.id }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.${{ needs.release-id.outputs.id }}.tar.gz --acl=public-read
coscmd upload install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt ${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.${{ needs.release-id.outputs.id }}.md5sum.txt && \
coscmd upload install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz ${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.${{ needs.release-id.outputs.id }}.tar.gz
release:

View File

@@ -60,12 +60,24 @@ jobs:
args: release --clean --skip-validate -f .goreleaser.agent.yml
workdir: './daemon'
- name: Upload to CDN
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- name: Upload to CDN
run: |
cd daemon/output && for file in *.tar.gz; do
aws s3 cp "$file" s3://terminus-os-install/$file --acl=public-read
coscmd upload "$file" ${{ secrets.REPO_PATH }}$file
done

View File

@@ -51,10 +51,23 @@ jobs:
with:
ref: ${{ github.event.inputs.tags }}
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
VERSION: ${{ github.event.inputs.tags }}
run: |
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf
@@ -68,10 +81,24 @@ jobs:
with:
ref: ${{ github.event.inputs.tags }}
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
VERSION: ${{ github.event.inputs.tags }}
run: |
export PATH=$PATH:/usr/local/bin:/home/ubuntu/.local/bin
@@ -85,11 +112,24 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ github.event.inputs.tags }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
@@ -104,11 +144,25 @@ jobs:
- name: "Checkout source code"
uses: actions/checkout@v3
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
# test
- env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ github.event.inputs.tags }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
@@ -131,18 +185,30 @@ jobs:
run: |
bash build/build.sh ${{ github.event.inputs.tags }} ${{ needs.release-id.outputs.id }}
- name: Upload to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
- name: Install coscmd
run: pip install coscmd
- name: Configure coscmd
env:
TENCENT_SECRET_ID: ${{ secrets.TENCENT_SECRET_ID }}
TENCENT_SECRET_KEY: ${{ secrets.TENCENT_SECRET_KEY }}
COS_BUCKET: ${{ secrets.COS_BUCKET }}
COS_REGION: ${{ secrets.COS_REGION }}
END_POINT: ${{ secrets.END_POINT }}
run: |
coscmd config -a $TENCENT_SECRET_ID \
-s $TENCENT_SECRET_KEY \
-b $COS_BUCKET \
-r $COS_REGION
- name: Upload to COS
run: |
md5sum install-wizard-v${{ github.event.inputs.tags }}.tar.gz > install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.tar.gz --acl=public-read
coscmd upload install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt ${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt && \
coscmd upload install-wizard-v${{ github.event.inputs.tags }}.tar.gz ${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.tar.gz
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.tar.gz --acl=public-read
coscmd upload install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt ${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.md5sum.txt && \
coscmd upload install-wizard-v${{ github.event.inputs.tags }}.tar.gz ${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.tar.gz
release:
runs-on: ubuntu-latest

View File

@@ -27,4 +27,5 @@ mkdir redis-5.0.14 && \
cp /usr/local/bin/redis* ./redis-5.0.14/
tar czvf ./redis-5.0.14.tar.gz ./redis-5.0.14/ && \
aws s3 cp redis-5.0.14.tar.gz s3://terminus-os-install/redis-5.0.14_${os}_${arch}${SUFFIX}.tar.gz --acl=public-read
# aws s3 cp redis-5.0.14.tar.gz s3://terminus-os-install/redis-5.0.14_${os}_${arch}${SUFFIX}.tar.gz --acl=public-read
coscmd upload redis-5.0.14.tar.gz /redis-5.0.14_${os}_${arch}${SUFFIX}.tar.gz --acl=public-read

View File

@@ -6,4 +6,5 @@ set -xe
curl -Lo Ubuntu2204.appx https://wslstorestorage.blob.core.windows.net/wslblob/Ubuntu2204-221101.AppxBundle
ubuntu2204=$(md5sum Ubuntu2204.appx|awk '{print $1}')
aws s3 cp Ubuntu2204.appx s3://terminus-os-install/${ubuntu2204} --acl=public-read
# aws s3 cp Ubuntu2204.appx s3://terminus-os-install/${ubuntu2204} --acl=public-read
coscmd upload Ubuntu2204.appx /${ubuntu2204} --acl=public-read

View File

@@ -6,9 +6,11 @@ set -xe
curl -Lo wsl.2.3.26.0.amd64.msi https://github.com/microsoft/WSL/releases/download/2.3.26/wsl.2.3.26.0.x64.msi
wsl_2_3_26=$(md5sum wsl.2.3.26.0.amd64.msi|awk '{print $1}')
aws s3 cp wsl.2.3.26.0.amd64.msi s3://terminus-os-install/${wsl_2_3_26} --acl=public-read
# aws s3 cp wsl.2.3.26.0.amd64.msi s3://terminus-os-install/${wsl_2_3_26} --acl=public-read
coscmd upload wsl.2.3.26.0.amd64.msi /${wsl_2_3_26} --acl=public-read
curl -Lo wsl.2.3.26.0.arm64.msi https://github.com/microsoft/WSL/releases/download/2.3.26/wsl.2.3.26.0.arm64.msi
wsl_2_3_26_arm64=$(md5sum wsl.2.3.26.0.arm64.msi|awk '{print $1}')
aws s3 cp wsl.2.3.26.0.arm64.msi s3://terminus-os-install/arm64/${wsl_2_3_26_arm64} --acl=public-read
# aws s3 cp wsl.2.3.26.0.arm64.msi s3://terminus-os-install/arm64/${wsl_2_3_26_arm64} --acl=public-read
coscmd upload wsl.2.3.26.0.arm64.msi /arm64/${wsl_2_3_26_arm64} --acl=public-read

View File

@@ -31,7 +31,7 @@ while read line; do
curl -fsSLI https://cdn.olares.com/$path$name > /dev/null
if [ $? -ne 0 ]; then
code=$(curl -o /dev/null -fsSLI -w "%{http_code}" https://cdn.olares.com/$path$name)
if [ $code -eq 403 ]; then
if [[ $code -eq 403 || $code -eq 404 ]]; then
bash ${BASE_DIR}/download-deps.sh $PLATFORM $line
if [ $? -ne 0 ]; then
@@ -46,28 +46,25 @@ while read line; do
fi
set -ex
aws s3 cp $name s3://terminus-os-install/$path$name --acl=public-read
aws s3 cp $name s3://terminus-os-install/backup/$path$backup_file --acl=public-read
aws s3 cp $checksum s3://terminus-os-install/$path$checksum --acl=public-read
echo "upload $name to s3 completed"
# aws s3 cp $name s3://terminus-os-install/$path$name --acl=public-read
# aws s3 cp $name s3://terminus-os-install/backup/$path$backup_file --acl=public-read
# aws s3 cp $checksum s3://terminus-os-install/$path$checksum --acl=public-read
# echo "upload $name to s3 completed"
coscmd upload ./$name /$path$name
coscmd upload ./$name /backup/$path$backup_file
coscmd upload ./$checksum /$path$checksum
echo "upload $name to cos completed"
set +ex
else
if [ $code -ne 200 ]; then
echo "failed to check image"
echo "failed to check file"
exit -1
fi
fi
fi
# upload to tencent cloud cos
# curl -fsSLI https://cdn.joinolares.cn/$path$name > /dev/null
# if [ $? -ne 0 ]; then
# set -ex
# coscmd upload ./$name /$path$name
# coscmd upload ./$checksum /$path$checksum
# echo "upload $name to cos completed"
# set +ex
# fi
done < components
popd

View File

@@ -15,7 +15,7 @@ cat $1|while read image; do
curl -fsSLI https://cdn.olares.com/$path$name.tar.gz > /dev/null
if [ $? -ne 0 ]; then
code=$(curl -o /dev/null -fsSLI -w "%{http_code}" https://cdn.olares.com/$path$name.tar.gz)
if [ $code -eq 403 ]; then
if [[ $code -eq 403 || $code -eq 404 ]]; then
set -ex
skopeo copy --insecure-policy docker://$image oci-archive:$name.tar
gzip $name.tar
@@ -28,11 +28,16 @@ cat $1|while read image; do
fi
echo "start to upload [$name.tar.gz]"
aws s3 cp $name.tar.gz s3://terminus-os-install/$path$name.tar.gz --acl=public-read
aws s3 cp $name.tar.gz s3://terminus-os-install/backup/$path$backup_file --acl=public-read
aws s3 cp $checksum s3://terminus-os-install/$path$checksum --acl=public-read
echo "upload $name completed"
# aws s3 cp $name.tar.gz s3://terminus-os-install/$path$name.tar.gz --acl=public-read
# aws s3 cp $name.tar.gz s3://terminus-os-install/backup/$path$backup_file --acl=public-read
# aws s3 cp $checksum s3://terminus-os-install/$path$checksum --acl=public-read
# echo "upload $name completed"
coscmd upload ./$name.tar.gz /$path$name.tar.gz
coscmd upload ./$name.tar.gz /backup/$path$backup_file
coscmd upload ./$checksum /$path$checksum
echo "upload $name to cos completed"
set +ex
else
if [ $code -ne 200 ]; then
@@ -48,7 +53,7 @@ cat $1|while read image; do
curl -fsSLI https://cdn.olares.com/$path$checksum > /dev/null
if [ $? -ne 0 ]; then
code=$(curl -o /dev/null -fsSLI -w "%{http_code}" https://cdn.olares.com/$path$checksum)
if [ $code -eq 403 ]; then
if [[ $code -eq 403 || $code -eq 404 ]]; then
set -ex
skopeo copy --insecure-policy docker://$image oci-archive:$name.tar
gzip $name.tar
@@ -60,10 +65,16 @@ cat $1|while read image; do
exit 1
fi
aws s3 cp $name.tar.gz s3://terminus-os-install/$path$name.tar.gz --acl=public-read
aws s3 cp $name.tar.gz s3://terminus-os-install/backup/$path$backup_file --acl=public-read
aws s3 cp $checksum s3://terminus-os-install/$path$checksum --acl=public-read
echo "upload $name completed"
# aws s3 cp $name.tar.gz s3://terminus-os-install/$path$name.tar.gz --acl=public-read
# aws s3 cp $name.tar.gz s3://terminus-os-install/backup/$path$backup_file --acl=public-read
# aws s3 cp $checksum s3://terminus-os-install/$path$checksum --acl=public-read
# echo "upload $name completed"
coscmd upload ./$name.tar.gz /$path$name.tar.gz
coscmd upload ./$name.tar.gz /backup/$path$backup_file
coscmd upload ./$checksum /$path$checksum
echo "upload $name to cos completed"
set +ex
else
if [ $code -ne 200 ]; then
@@ -77,13 +88,16 @@ cat $1|while read image; do
curl -fsSLI https://cdn.olares.com/$path$manifest > /dev/null
if [ $? -ne 0 ]; then
code=$(curl -o /dev/null -fsSLI -w "%{http_code}" https://cdn.olares.com/$path$manifest)
if [ $code -eq 403 ]; then
if [[ $code -eq 403 || $code -eq 404 ]]; then
set -ex
BASE_DIR=$(dirname $(realpath -s $0))
python3 $BASE_DIR/get-manifest.py $image -o $manifest
aws s3 cp $manifest s3://terminus-os-install/$path$manifest --acl=public-read
# aws s3 cp $manifest s3://terminus-os-install/$path$manifest --acl=public-read
coscmd upload $manifest /$path$manifest
echo "upload $name manifest completed"
set +ex
else
if [ $code -ne 200 ]; then

121
cli/pkg/amdgpu/module.go Normal file
View File

@@ -0,0 +1,121 @@
package amdgpu
import (
"time"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/prepare"
"github.com/beclab/Olares/cli/pkg/core/task"
)
// InstallAmdContainerToolkitModule installs AMD container toolkit on supported Ubuntu if ROCm is installed.
type InstallAmdContainerToolkitModule struct {
common.KubeModule
Skip bool // conditional execution based on ROCm detection
SkipRocmCheck bool
}
func (m *InstallAmdContainerToolkitModule) IsSkip() bool {
return m.Skip
}
func (m *InstallAmdContainerToolkitModule) Init() {
m.Name = "InstallAmdContainerToolkit"
if m.IsSkip() {
return
}
prepareCollection := prepare.PrepareCollection{}
if !m.SkipRocmCheck {
prepareCollection = append(prepareCollection, new(RocmInstalled))
}
updateAmdSource := &task.RemoteTask{
Name: "UpdateAmdContainerToolkitSource",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Action: new(UpdateAmdContainerToolkitSource),
Prepare: &prepareCollection,
Parallel: false,
Retry: 1,
}
installAmdContainerToolkit := &task.RemoteTask{
Name: "InstallAmdContainerToolkit",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Prepare: &prepareCollection,
Action: new(InstallAmdContainerToolkit),
Parallel: false,
Retry: 1,
}
generateAndValidateCDI := &task.RemoteTask{
Name: "GenerateAndValidateAmdCDI",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Prepare: &prepareCollection,
Action: new(GenerateAndValidateAmdCDI),
Parallel: false,
Retry: 1,
}
m.Tasks = []task.Interface{
updateAmdSource,
installAmdContainerToolkit,
generateAndValidateCDI,
}
}
// InstallAmdPluginModule installs AMD GPU device plugin on Kubernetes.
type InstallAmdPluginModule struct {
common.KubeModule
Skip bool // conditional execution based on GPU enablement
}
func (m *InstallAmdPluginModule) IsSkip() bool {
return m.Skip
}
func (m *InstallAmdPluginModule) Init() {
m.Name = "InstallAmdPlugin"
// update node with AMD GPU labels
updateNode := &task.RemoteTask{
Name: "UpdateNodeAmdGPUInfo",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Prepare: &prepare.PrepareCollection{
new(common.OnlyFirstMaster),
},
Action: new(UpdateNodeAmdGPUInfo),
Parallel: false,
Retry: 1,
}
installPlugin := &task.RemoteTask{
Name: "InstallAmdPlugin",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Prepare: &prepare.PrepareCollection{
new(common.OnlyFirstMaster),
},
Action: new(InstallAmdPlugin),
Parallel: false,
Retry: 1,
}
checkGpuState := &task.RemoteTask{
Name: "CheckAmdGPUState",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Prepare: &prepare.PrepareCollection{
new(common.OnlyFirstMaster),
new(RocmInstalled),
},
Action: new(CheckAmdGpuStatus),
Parallel: false,
Retry: 50,
Delay: 10 * time.Second,
}
m.Tasks = []task.Interface{
updateNode,
installPlugin,
checkGpuState,
}
}

View File

@@ -0,0 +1,56 @@
package amdgpu
import (
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger"
)
// RocmInstalled checks if AMD ROCm is installed on the system.
type RocmInstalled struct {
common.KubePrepare
}
func (p *RocmInstalled) PreCheck(runtime connector.Runtime) (bool, error) {
rocmV, err := connector.RocmVersion()
if err != nil {
logger.Debugf("ROCm version check error: %v", err)
return false, nil
}
if rocmV == nil {
return false, nil
}
logger.Infof("Detected ROCm version: %s", rocmV.Original())
return true, nil
}
// RocmNotInstalled checks if AMD ROCm is NOT installed on the system.
type RocmNotInstalled struct {
common.KubePrepare
RocmInstalled
}
func (p *RocmNotInstalled) PreCheck(runtime connector.Runtime) (bool, error) {
installed, err := p.RocmInstalled.PreCheck(runtime)
if err != nil {
return false, err
}
return !installed, nil
}
// ContainerdInstalled checks if containerd is installed on the system.
type ContainerdInstalled struct {
common.KubePrepare
}
func (p *ContainerdInstalled) PreCheck(runtime connector.Runtime) (bool, error) {
containerdCheck := precheck.ConflictingContainerdCheck{}
if err := containerdCheck.Check(runtime); err != nil {
return true, nil
}
logger.Info("containerd is not installed, ignore task")
return false, nil
}

View File

@@ -1,17 +1,20 @@
package amdgpu
import (
"context"
"fmt"
"os/exec"
"path"
"path/filepath"
"github.com/beclab/Olares/cli/pkg/clientset"
"github.com/beclab/Olares/cli/pkg/common"
cc "github.com/beclab/Olares/cli/pkg/core/common"
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/utils"
"github.com/beclab/Olares/cli/pkg/core/util"
"github.com/beclab/Olares/cli/pkg/gpu"
"github.com/Masterminds/semver/v3"
"github.com/pkg/errors"
@@ -26,8 +29,8 @@ func (m *InstallAmdRocmModule) Init() {
m.Name = "InstallAMDGPU"
installAmd := &task.RemoteTask{
Name: "InstallAmdRocm",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Name: "InstallAmdRocm",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Action: &InstallAmdRocm{
// no manifest needed
},
@@ -51,7 +54,7 @@ func (t *InstallAmdRocm) Execute(runtime connector.Runtime) error {
return nil
}
amdGPUExists, err := utils.HasAmdIGPU(runtime)
amdGPUExists, err := connector.HasAmdAPUOrGPU(runtime)
if err != nil {
return err
}
@@ -59,7 +62,7 @@ func (t *InstallAmdRocm) Execute(runtime connector.Runtime) error {
if !amdGPUExists {
return nil
}
rocmV, _ := utils.RocmVersion()
rocmV, _ := connector.RocmVersion()
min := semver.MustParse("7.1.1")
if rocmV != nil && rocmV.LessThan(min) {
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", rocmV.Original(), min.Original())
@@ -131,3 +134,163 @@ func (t *AmdgpuUninstallAction) Execute(runtime connector.Runtime) error {
logger.Warn("Warning: Please reboot your machine after uninstall to fully remove ROCm components.")
return nil
}
// UpdateAmdContainerToolkitSource configures the AMD container toolkit APT repository.
type UpdateAmdContainerToolkitSource struct {
common.KubeAction
}
func (t *UpdateAmdContainerToolkitSource) Execute(runtime connector.Runtime) error {
// Install prerequisites
if _, err := runtime.GetRunner().SudoCmd("apt update && apt install -y wget gnupg2", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install prerequisites for AMD container toolkit")
}
if _, err := runtime.GetRunner().SudoCmd("install -d -m 0755 /etc/apt/keyrings", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to create /etc/apt/keyrings directory")
}
cmd := "wget https://repo.radeon.com/rocm/rocm.gpg.key -O - | gpg --dearmor | tee /etc/apt/keyrings/rocm.gpg > /dev/null"
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to download and install AMD ROCm GPG key")
}
si := runtime.GetSystemInfo()
var ubuntuCodename string
if si.IsUbuntuVersionEqual(connector.Ubuntu2404) {
ubuntuCodename = "noble"
} else if si.IsUbuntuVersionEqual(connector.Ubuntu2204) {
ubuntuCodename = "jammy"
} else {
return fmt.Errorf("unsupported Ubuntu version for AMD container toolkit")
}
aptSourceLine := fmt.Sprintf("deb [signed-by=/etc/apt/keyrings/rocm.gpg] https://repo.radeon.com/amd-container-toolkit/apt/ %s main", ubuntuCodename)
cmd = fmt.Sprintf("echo '%s' > /etc/apt/sources.list.d/amd-container-toolkit.list", aptSourceLine)
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to add AMD container toolkit APT source")
}
logger.Infof("AMD container toolkit repository configured successfully")
return nil
}
// InstallAmdContainerToolkit installs the AMD container toolkit package.
type InstallAmdContainerToolkit struct {
common.KubeAction
}
func (t *InstallAmdContainerToolkit) Execute(runtime connector.Runtime) error {
logger.Infof("Installing AMD container toolkit...")
if _, err := runtime.GetRunner().SudoCmd("apt update && apt install -y amd-container-toolkit", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install AMD container toolkit")
}
logger.Infof("AMD container toolkit installed successfully")
return nil
}
// GenerateAndValidateAmdCDI generates and validates the AMD CDI spec.
type GenerateAndValidateAmdCDI struct {
common.KubeAction
}
func (t *GenerateAndValidateAmdCDI) Execute(runtime connector.Runtime) error {
// Ensure /etc/cdi directory exists
if _, err := runtime.GetRunner().SudoCmd("install -d -m 0755 /etc/cdi", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to create /etc/cdi directory")
}
// Generate CDI spec
logger.Infof("Generating AMD CDI spec...")
if _, err := runtime.GetRunner().SudoCmd("amd-ctk cdi generate --output=/etc/cdi/amd.json", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to generate AMD CDI spec")
}
// Validate CDI spec
logger.Infof("Validating AMD CDI spec...")
if _, err := runtime.GetRunner().SudoCmd("amd-ctk cdi validate --path=/etc/cdi/amd.json", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to validate AMD CDI spec")
}
logger.Infof("AMD CDI spec generated and validated successfully")
return nil
}
// UpdateNodeAmdGPUInfo updates Kubernetes node labels with AMD GPU information.
type UpdateNodeAmdGPUInfo struct {
common.KubeAction
}
func (u *UpdateNodeAmdGPUInfo) Execute(runtime connector.Runtime) error {
client, err := clientset.NewKubeClient()
if err != nil {
return errors.Wrap(errors.WithStack(err), "kubeclient create error")
}
// Check if AMD GPU/APU exists
amdGPUExists, err := connector.HasAmdAPUOrGPU(runtime)
if err != nil {
return err
}
if !amdGPUExists {
logger.Info("AMD GPU/APU is not detected")
return nil
}
// Get ROCm version
rocmV, err := connector.RocmVersion()
if err != nil || rocmV == nil {
logger.Info("ROCm is not installed")
return nil
}
rocmVersion := rocmV.Original()
// Determine GPU type (APU vs discrete GPU)
gpuType := gpu.AmdGpuCardType
if runtime.GetSystemInfo().IsAmdApu() {
gpuType = gpu.AmdApuCardType
}
// Use ROCm version as both driver and "cuda" version for AMD
return gpu.UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), &rocmVersion, nil, nil, &gpuType)
}
// InstallAmdPlugin installs the AMD GPU device plugin DaemonSet.
type InstallAmdPlugin struct {
common.KubeAction
}
func (t *InstallAmdPlugin) Execute(runtime connector.Runtime) error {
amdPluginPath := path.Join(runtime.GetInstallerDir(), "wizard/config/gpu/nvidia/amdgpu-device-plugin.yaml")
_, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("kubectl apply -f %s", amdPluginPath), false, true)
if err != nil {
return errors.Wrap(errors.WithStack(err), "failed to apply AMD GPU device plugin")
}
logger.Infof("AMD GPU device plugin installed successfully")
return nil
}
// CheckAmdGpuStatus checks if the AMD GPU device plugin pod is running.
type CheckAmdGpuStatus struct {
common.KubeAction
}
func (t *CheckAmdGpuStatus) Execute(runtime connector.Runtime) error {
kubectlpath, err := util.GetCommand(common.CommandKubectl)
if err != nil {
return fmt.Errorf("kubectl not found")
}
// Check AMD device plugin pod status using the label from amdgpu-device-plugin.yaml
selector := "name=amdgpu-dp-ds"
cmd := fmt.Sprintf("%s get pod -n kube-system -l '%s' -o jsonpath='{.items[*].status.phase}'", kubectlpath, selector)
rphase, _ := runtime.GetRunner().SudoCmd(cmd, false, false)
if rphase == "Running" {
logger.Infof("AMD GPU device plugin is running")
return nil
}
return fmt.Errorf("AMD GPU device plugin state is not Running (current: %s)", rphase)
}

View File

@@ -59,7 +59,7 @@ func (t *PatchTask) Execute(runtime connector.Runtime) error {
pre_reqs = pre_reqs + " network-manager "
}
pre_reqs += " conntrack socat apache2-utils net-tools make gcc bison flex tree unzip "
pre_reqs += " conntrack socat apache2-utils net-tools make gcc bison flex tree unzip lshw"
var systemInfo = runtime.GetSystemInfo()
var platformFamily = systemInfo.GetOsPlatformFamily()

View File

@@ -338,7 +338,9 @@ func (c *CudaChecker) Name() string {
}
func (c *CudaChecker) Check(runtime connector.Runtime) error {
if !runtime.GetSystemInfo().IsLinux() {
if !runtime.GetSystemInfo().IsLinux() ||
// Skip check on NVIDIA DGX Spark systems, which have their own GPU management
runtime.GetSystemInfo().IsGB10Chip() {
return nil
}
@@ -388,17 +390,17 @@ func (r *RocmChecker) Check(runtime connector.Runtime) error {
return nil
}
// detect AMD GPU presence
amdGPUExists, err := utils.HasAmdIGPU(runtime)
// detect AMD APU/GPU presence
amdGPUExists, err := connector.HasAmdAPUOrGPU(runtime)
if err != nil {
return err
}
// no AMD GPU found, no need to check rocm
// no AMD APU/GPU found, no need to check rocm
if !amdGPUExists {
return nil
}
curV, err := utils.RocmVersion()
curV, err := connector.RocmVersion()
if err != nil && !os.IsNotExist(err) {
return err
}

View File

@@ -210,6 +210,7 @@ func NewArgument() *Argument {
arg.IsCloudInstance, _ = strconv.ParseBool(os.Getenv(ENV_TERMINUS_IS_CLOUD_VERSION))
arg.IsOlaresInContainer = os.Getenv(ENV_CONTAINER_MODE) == "oic"
si.IsOIC = arg.IsOlaresInContainer
si.ProductName = arg.GetProductName()
// Ensure BaseDir is initialized before loading master.conf
// so master host config can be loaded from ${base-dir}/master.conf reliably.
@@ -415,6 +416,57 @@ func (a *Argument) SetSwapConfig(config SwapConfig) {
a.Swappiness = config.Swappiness
}
func (a *Argument) SetMasterHostOverride(config MasterHostConfig) {
if config.MasterHost != "" {
a.MasterHost = config.MasterHost
}
if config.MasterNodeName != "" {
a.MasterNodeName = config.MasterNodeName
}
// set a dummy name to bypass validity checks
// as it will be overridden later when the node name is fetched
if a.MasterNodeName == "" {
a.MasterNodeName = "master"
}
if config.MasterSSHPassword != "" {
a.MasterSSHPassword = config.MasterSSHPassword
}
if config.MasterSSHUser != "" {
a.MasterSSHUser = config.MasterSSHUser
}
if config.MasterSSHPort != 0 {
a.MasterSSHPort = config.MasterSSHPort
}
if config.MasterSSHPrivateKeyPath != "" {
a.MasterSSHPrivateKeyPath = config.MasterSSHPrivateKeyPath
}
}
func (a *Argument) LoadMasterHostConfigIfAny() error {
if a.BaseDir == "" {
return errors.New("basedir unset")
}
content, err := os.ReadFile(filepath.Join(a.BaseDir, MasterHostConfigFile))
if os.IsNotExist(err) {
return nil
}
if err != nil {
return err
}
return json.Unmarshal(content, a.MasterHostConfig)
}
func (a *Argument) GetProductName() string {
data, err := os.ReadFile("/sys/class/dmi/id/product_name")
if err != nil {
fmt.Printf("\nCannot get product name on this device, %s\n", err)
return ""
}
return strings.TrimSpace(string(data))
}
func NewKubeRuntime(arg Argument) (*KubeRuntime, error) {
loader := NewLoader(arg)
cluster, err := loader.Load()

View File

@@ -98,4 +98,6 @@ const (
const (
ZfsSnapshotter = "/var/lib/containerd/io.containerd.snapshotter.v1.zfs"
ENV_GB10_CHIP = "GB10_CHIP" // for building images for NVIDIA GB10 Superchip systems
)

View File

@@ -0,0 +1,117 @@
package connector
import (
"fmt"
"os"
"os/exec"
"strings"
"github.com/Masterminds/semver/v3"
)
func hasAmdAPU(cmdExec func(s string) (string, error)) (bool, error) {
// Detect by CPU model names that bundle AMD AI NPU/graphics
targets := []string{
"AMD Ryzen AI Max+ 395",
"AMD Ryzen AI Max 390",
"AMD Ryzen AI Max 385",
"AMD Ryzen AI 9 HX 375",
"AMD Ryzen AI 9 HX 370",
"AMD Ryzen AI 9 365",
}
// try lscpu first: extract 'Model name' field
out, err := cmdExec("lscpu 2>/dev/null | awk -F': *' '/^Model name/{print $2; exit}' || true")
if err != nil {
return false, err
}
if out != "" {
lo := strings.ToLower(strings.TrimSpace(out))
for _, t := range targets {
if strings.Contains(lo, strings.ToLower(t)) {
return true, nil
}
}
}
// fallback to /proc/cpuinfo
out, err = cmdExec("awk -F': *' '/^model name/{print $2; exit}' /proc/cpuinfo 2>/dev/null || true")
if err != nil {
return false, err
}
if out != "" {
lo := strings.ToLower(strings.TrimSpace(out))
for _, t := range targets {
if strings.Contains(lo, strings.ToLower(t)) {
return true, nil
}
}
}
return false, nil
}
func hasAmdAPUOrGPU(cmdExec func(s string) (string, error)) (bool, error) {
out, err := cmdExec("lspci -d '1002:' 2>/dev/null | grep 'AMD' || true")
if err != nil {
return false, err
}
if out != "" {
return true, nil
}
out, err = cmdExec("lshw -c display -numeric -disable network 2>/dev/null | grep 'vendor: .* \\[1002\\]' || true")
if err != nil {
return false, err
}
if out != "" {
return true, nil
}
return false, nil
}
func HasAmdAPU(execRuntime Runtime) (bool, error) {
return hasAmdAPU(func(s string) (string, error) {
return execRuntime.GetRunner().SudoCmd(s, false, false)
})
}
func HasAmdAPULocal() (bool, error) {
return hasAmdAPU(func(s string) (string, error) {
out, err := exec.Command("sh", "-c", s).Output()
if err != nil {
return "", err
}
return string(out), nil
})
}
func HasAmdAPUOrGPULocal() (bool, error) {
return hasAmdAPUOrGPU(func(s string) (string, error) {
out, err := exec.Command("sh", "-c", s).Output()
if err != nil {
return "", err
}
return string(out), nil
})
}
func HasAmdAPUOrGPU(execRuntime Runtime) (bool, error) {
return hasAmdAPUOrGPU(func(s string) (string, error) {
return execRuntime.GetRunner().SudoCmd(s, false, false)
})
}
func RocmVersion() (*semver.Version, error) {
const rocmVersionFile = "/opt/rocm/.info/version"
data, err := os.ReadFile(rocmVersionFile)
if err != nil {
// no ROCm installed, nothing to check
if os.IsNotExist(err) {
return nil, err
}
return nil, err
}
curStr := strings.TrimSpace(string(data))
cur, err := semver.NewVersion(curStr)
if err != nil {
return nil, fmt.Errorf("invalid rocm version: %s", curStr)
}
return cur, nil
}

View File

@@ -76,6 +76,10 @@ type Systems interface {
IsPveOrPveLxc() bool
IsRaspbian() bool
IsLinux() bool
IsGB10Chip() bool
IsAmdApu() bool
IsAmdGPU() bool
IsAmdGPUOrAPU() bool
IsUbuntu() bool
IsDebian() bool
@@ -111,16 +115,18 @@ type Systems interface {
}
type SystemInfo struct {
HostInfo *HostInfo `json:"host"`
CpuInfo *CpuInfo `json:"cpu"`
DiskInfo *DiskInfo `json:"disk"`
MemoryInfo *MemoryInfo `json:"memory"`
FsInfo *FileSystemInfo `json:"filesystem"`
CgroupInfo *CgroupInfo `json:"cgroup,omitempty"`
LocalIp string `json:"local_ip"`
NatGateway string `json:"nat_gateway"`
PkgManager string `json:"pkg_manager"`
IsOIC bool `json:"is_oic,omitempty"`
HostInfo *HostInfo `json:"host"`
CpuInfo *CpuInfo `json:"cpu"`
DiskInfo *DiskInfo `json:"disk"`
MemoryInfo *MemoryInfo `json:"memory"`
FsInfo *FileSystemInfo `json:"filesystem"`
CgroupInfo *CgroupInfo `json:"cgroup,omitempty"`
LocalIp string `json:"local_ip"`
NatGateway string `json:"nat_gateway"`
PkgManager string `json:"pkg_manager"`
IsOIC bool `json:"is_oic,omitempty"`
ProductName string `json:"product_name,omitempty"`
HasAmdGPU bool `json:"has_amd_gpu,omitempty"`
}
func (s *SystemInfo) IsSupport() error {
@@ -235,6 +241,22 @@ func (s *SystemInfo) IsLinux() bool {
return s.HostInfo.OsType == common.Linux
}
func (s *SystemInfo) IsGB10Chip() bool {
return s.CpuInfo.IsGB10Chip
}
func (s *SystemInfo) IsAmdApu() bool {
return s.CpuInfo.HasAmdAPU
}
func (s *SystemInfo) IsAmdGPU() bool {
return s.HasAmdGPU
}
func (s *SystemInfo) IsAmdGPUOrAPU() bool {
return s.CpuInfo.HasAmdAPU || s.HasAmdGPU
}
func (s *SystemInfo) IsUbuntu() bool {
return s.HostInfo.OsPlatformFamily == common.Ubuntu
}
@@ -322,6 +344,12 @@ func GetSystemInfo() *SystemInfo {
si.MemoryInfo = getMem()
si.FsInfo = getFs()
hasAmdGPU, err := getAmdGPU()
if err != nil {
panic(errors.Wrap(err, "failed to get amd apu/gpu"))
}
si.HasAmdGPU = hasAmdGPU
localIP, err := util.GetLocalIP()
if err != nil {
panic(errors.Wrap(err, "failed to get local ip"))
@@ -437,6 +465,28 @@ type CpuInfo struct {
CpuModel string `json:"cpu_model"`
CpuLogicalCount int `json:"cpu_logical_count"`
CpuPhysicalCount int `json:"cpu_physical_count"`
IsGB10Chip bool `json:"is_gb10_chip,omitempty"`
HasAmdAPU bool `json:"has_amd_apu,omitempty"`
}
// Not considering the case where AMD GPU and AMD APU coexist.
func getAmdGPU() (bool, error) {
APUOrGPUExists, err := HasAmdAPUOrGPULocal()
if err != nil {
fmt.Printf("Error checking AMD APU/GPU: %v\n", err)
return false, err
}
hasAmdAPU, err := HasAmdAPULocal()
if err != nil {
fmt.Printf("Error checking AMD APU: %v\n", err)
return false, err
}
if APUOrGPUExists && !hasAmdAPU {
return true, nil
}
return false, nil
}
func getCpu() *CpuInfo {
@@ -452,10 +502,36 @@ func getCpu() *CpuInfo {
cpuModel = cpuInfo[0].ModelName
}
// check if is GB10 chip
isGB10Chip := false
// In Linux systems, it is recognized via lspci as "NVIDIA Corporation Device 2e12 (rev a1)
// or NVIDIA Corporation GB20B [GB10] (rev a1)
cmd := exec.Command("sh", "-c", "lspci | grep -i vga | egrep 'GB10|2e12'")
output, err := cmd.Output()
if err == nil && strings.TrimSpace(string(output)) != "" {
isGB10Chip = true
} else {
fmt.Printf("Error checking GB10 chip: %v\n", err)
gb10env := os.Getenv(common.ENV_GB10_CHIP)
if gb10env == "1" || strings.EqualFold(gb10env, "true") {
isGB10Chip = true
}
}
// check if it has amd igpu
hasAmdAPU, err := HasAmdAPULocal()
if err != nil {
fmt.Printf("Error checking AMD iGPU: %v\n", err)
hasAmdAPU = false
}
return &CpuInfo{
CpuModel: cpuModel,
CpuLogicalCount: cpuLogicalCount,
CpuPhysicalCount: cpuPhysicalCount,
IsGB10Chip: isGB10Chip,
HasAmdAPU: hasAmdAPU,
}
}

View File

@@ -37,6 +37,11 @@ type CudaInstalled struct {
}
func (p *CudaInstalled) PreCheck(runtime connector.Runtime) (bool, error) {
if runtime.GetSystemInfo().IsGB10Chip() {
logger.Debug("Assume DGX Spark or GB10 OEM system has CUDA installed")
return true, nil
}
st, err := utils.GetNvidiaStatus(runtime)
if err != nil {
return false, err
@@ -50,17 +55,15 @@ func (p *CudaInstalled) PreCheck(runtime connector.Runtime) (bool, error) {
type CudaNotInstalled struct {
common.KubePrepare
CudaInstalled
}
func (p *CudaNotInstalled) PreCheck(runtime connector.Runtime) (bool, error) {
st, err := utils.GetNvidiaStatus(runtime)
installed, err := p.CudaInstalled.PreCheck(runtime)
if err != nil {
return false, err
}
if st == nil || !st.Installed {
return true, nil
}
return false, nil
return !installed, nil
}
type CurrentNodeInK8s struct {

View File

@@ -325,7 +325,8 @@ func (t *CheckGpuStatus) Execute(runtime connector.Runtime) error {
return fmt.Errorf("kubectl not found")
}
cmd := fmt.Sprintf("%s get pod -n kube-system -l 'app.kubernetes.io/component=hami-device-plugin' -o jsonpath='{.items[*].status.phase}'", kubectlpath)
selector := "app.kubernetes.io/component=hami-device-plugin"
cmd := fmt.Sprintf("%s get pod -n kube-system -l '%s' -o jsonpath='{.items[*].status.phase}'", kubectlpath, selector)
rphase, _ := runtime.GetRunner().SudoCmd(cmd, false, false)
if rphase == "Running" {
@@ -363,7 +364,16 @@ func (u *UpdateNodeGPUInfo) Execute(runtime connector.Runtime) error {
driverVersion = st.LibraryVersion
}
return UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), &driverVersion, &st.CudaVersion, &supported)
// TODO:
gpuType := NvidiaCardType
switch {
case runtime.GetSystemInfo().IsAmdApu():
gpuType = AmdApuCardType
case runtime.GetSystemInfo().IsGB10Chip():
gpuType = GB10ChipType
}
return UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), &driverVersion, &st.CudaVersion, &supported, &gpuType)
}
type RemoveNodeLabels struct {
@@ -376,12 +386,12 @@ func (u *RemoveNodeLabels) Execute(runtime connector.Runtime) error {
return errors.Wrap(errors.WithStack(err), "kubeclient create error")
}
return UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), nil, nil, nil)
return UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), nil, nil, nil, nil)
}
// update k8s node labels gpu.bytetrade.io/driver and gpu.bytetrade.io/cuda.
// if labels are not exists, create it.
func UpdateNodeGpuLabel(ctx context.Context, client kubernetes.Interface, driver, cuda *string, supported *string) error {
func UpdateNodeGpuLabel(ctx context.Context, client kubernetes.Interface, driver, cuda *string, supported *string, gpuType *string) error {
// get node name from hostname
nodeName, err := os.Hostname()
if err != nil {
@@ -408,6 +418,7 @@ func UpdateNodeGpuLabel(ctx context.Context, client kubernetes.Interface, driver
{GpuDriverLabel, driver},
{GpuCudaLabel, cuda},
{GpuCudaSupportedLabel, supported},
{GpuType, gpuType},
} {
old, ok := labels[label.key]
switch {

View File

@@ -8,4 +8,13 @@ var (
GpuDriverLabel = GpuLabelGroup + "/driver"
GpuCudaLabel = GpuLabelGroup + "/cuda"
GpuCudaSupportedLabel = GpuLabelGroup + "/cuda-supported"
GpuType = GpuLabelGroup + "/type"
)
const (
NvidiaCardType = "nvidia" // handling by HAMi
AmdGpuCardType = "amd-gpu" //
AmdApuCardType = "amd-apu" // AMD APU with integrated GPU , AI Max 395 etc.
GB10ChipType = "nvidia-gb10" // NVIDIA GB10 Superchip & unified system memory
StrixHaloChipType = "strix-halo" // AMD Strix Halo GPU & unified system memory
)

View File

@@ -1,6 +1,7 @@
package cluster
import (
"github.com/beclab/Olares/cli/pkg/amdgpu"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/module"
"github.com/beclab/Olares/cli/pkg/gpu"
@@ -58,6 +59,12 @@ func (l *linuxInstallPhaseBuilder) installGpuPlugin() phase {
return []module.Module{
&gpu.RestartK3sServiceModule{Skip: !(l.runtime.Arg.Kubetype == common.K3s)},
&gpu.InstallPluginModule{Skip: skipGpuPlugin},
&amdgpu.InstallAmdPluginModule{Skip: func() bool {
if l.runtime.GetSystemInfo().IsAmdGPUOrAPU() {
return false
}
return true
}()},
}
}

View File

@@ -83,6 +83,13 @@ func (l *linuxPhaseBuilder) build() []module.Module {
addModule(gpuModuleBuilder(func() []module.Module {
return []module.Module{
&amdgpu.InstallAmdRocmModule{},
&amdgpu.InstallAmdContainerToolkitModule{Skip: func() bool {
if l.runtime.GetSystemInfo().IsAmdGPUOrAPU() {
return false
}
return true
}(),
},
&gpu.InstallDriversModule{
ManifestModule: manifest.ManifestModule{
Manifest: l.manifestMap,

View File

@@ -9,7 +9,6 @@ import (
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/utils"
)
type WelcomeMessage struct {
@@ -73,7 +72,7 @@ func (t *WelcomeMessage) Execute(runtime connector.Runtime) error {
// If AMD GPU on Ubuntu 22.04/24.04, print warning about reboot for ROCm
if si := runtime.GetSystemInfo(); si.IsUbuntu() && (si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
if hasAmd, _ := utils.HasAmdIGPU(runtime); hasAmd {
if hasAmd, _ := connector.HasAmdAPUOrGPU(runtime); hasAmd {
logger.Warnf("\x1b[31mWarning: To enable ROCm, please reboot your machine after activation.\x1b[0m")
fmt.Println()
}

View File

@@ -380,7 +380,7 @@ func (a *upgradeGPUDriverIfNeeded) Execute(runtime connector.Runtime) error {
if err != nil {
return errors.Wrap(errors.WithStack(err), "kubeclient create error")
}
err = gpu.UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), &targetDriverVersionStr, ptr.To(common.CurrentVerifiedCudaVersion), ptr.To("true"))
err = gpu.UpdateNodeGpuLabel(context.Background(), client.Kubernetes(), &targetDriverVersionStr, ptr.To(common.CurrentVerifiedCudaVersion), ptr.To("true"), ptr.To(gpu.NvidiaCardType))
if err != nil {
return err
}

View File

@@ -1,67 +0,0 @@
package utils
import (
"fmt"
"os"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/pkg/core/connector"
)
func HasAmdIGPU(execRuntime connector.Runtime) (bool, error) {
// Detect by CPU model names that bundle AMD AI NPU/graphics
targets := []string{
"AMD Ryzen AI Max+ 395",
"AMD Ryzen AI Max 390",
"AMD Ryzen AI Max 385",
"AMD Ryzen AI 9 HX 375",
"AMD Ryzen AI 9 HX 370",
"AMD Ryzen AI 9 365",
}
// try lscpu first: extract 'Model name' field
out, err := execRuntime.GetRunner().SudoCmd("lscpu 2>/dev/null | awk -F': *' '/^Model name/{print $2; exit}' || true", false, false)
if err != nil {
return false, err
}
if out != "" {
lo := strings.ToLower(strings.TrimSpace(out))
for _, t := range targets {
if strings.Contains(lo, strings.ToLower(t)) {
return true, nil
}
}
}
// fallback to /proc/cpuinfo
out, err = execRuntime.GetRunner().SudoCmd("awk -F': *' '/^model name/{print $2; exit}' /proc/cpuinfo 2>/dev/null || true", false, false)
if err != nil {
return false, err
}
if out != "" {
lo := strings.ToLower(strings.TrimSpace(out))
for _, t := range targets {
if strings.Contains(lo, strings.ToLower(t)) {
return true, nil
}
}
}
return false, nil
}
func RocmVersion() (*semver.Version, error) {
const rocmVersionFile = "/opt/rocm/.info/version"
data, err := os.ReadFile(rocmVersionFile)
if err != nil {
// no ROCm installed, nothing to check
if os.IsNotExist(err) {
return nil, err
}
return nil, err
}
curStr := strings.TrimSpace(string(data))
cur, err := semver.NewVersion(curStr)
if err != nil {
return nil, fmt.Errorf("invalid rocm version: %s", curStr)
}
return cur, nil
}

View File

@@ -1,7 +1,7 @@
project_name: olaresd
builds:
- env:
- CGO_ENABLED=0
- CGO_ENABLED=1
# - CC=aarch64-linux-gnu-gcc
# - CXX=aarch64-linux-gnu-g++
main: ./cmd/terminusd/main.go
@@ -17,6 +17,12 @@ builds:
goamd64: v1
env:
- CGO_ENABLED=1
- goarch: arm64
goos: linux
env:
- CGO_ENABLED=1
- CC=aarch64-linux-gnu-gcc
- CXX=aarch64-linux-gnu-g++
tags:
containers_image_openpgp
ldflags:

View File

@@ -20,6 +20,9 @@ build: fmt vet ;$(info $(M)...Begin to build terminusd.) @
build-linux: fmt vet ;$(info $(M)...Begin to build terminusd (linux version).) @
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -o bin/olaresd cmd/terminusd/main.go
build-arm: fmt vet ;$(info $(M)...Begin to build terminusd (linux version).) @
CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -o bin/olaresd cmd/terminusd/main.go
build-linux-in-docker:
docker run -it --platform linux/amd64 --rm \
-v $(current_dir):/olaresd \
@@ -27,3 +30,11 @@ build-linux-in-docker:
-e DEBIAN_FRONTEND=noninteractive \
golang:1.24.11 \
sh -c "apt-get -y update; apt-get -y install libudev-dev libpcap-dev; make build-linux"
build-arm-in-docker:
docker run -it --platform linux/arm64 --rm \
-v $(current_dir):/olaresd \
-w /olaresd \
-e DEBIAN_FRONTEND=noninteractive \
golang:1.24.11 \
sh -c "apt-get -y update; apt-get -y install libudev-dev libpcap-dev; make build-arm"

View File

@@ -31,7 +31,7 @@ require (
github.com/jaypipes/ghw v0.13.0
github.com/jochenvg/go-udev v0.0.0-20171110120927-d6b62d56d37b
github.com/joho/godotenv v1.5.1
github.com/klauspost/cpuid/v2 v2.2.8
github.com/klauspost/cpuid/v2 v2.3.0
github.com/labstack/echo/v4 v4.0.0-00010101000000-000000000000
github.com/libp2p/go-netroute v0.2.2
github.com/mackerelio/go-osstat v0.2.5

View File

@@ -205,8 +205,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
@@ -471,7 +471,6 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=

View File

@@ -1,5 +1,5 @@
//go:build !(linux && amd64)
// +build !linux !amd64
//go:build !linux
// +build !linux
package intranet

View File

@@ -1,5 +1,5 @@
//go:build linux && amd64
// +build linux,amd64
//go:build linux
// +build linux
package intranet

View File

@@ -42,7 +42,7 @@ func detectdStorageDevices(ctx context.Context, bus string) (usbDevs []storageDe
for _, d := range ds {
if d.Properties()["ID_BUS"] == bus {
usbs = append(usbs, d)
} else if d.Properties()["ID_BUS"] == "ata" &&
} else if (d.Properties()["ID_BUS"] == "ata" || d.Properties()["ID_BUS"] == "scsi") &&
d.Properties()["ID_USB_TYPE"] == "disk" &&
bus == "usb" {
usbs = append(usbs, d)
@@ -97,14 +97,18 @@ func detectdStorageDevices(ctx context.Context, bus string) (usbDevs []storageDe
idSerial := device.Properties()["ID_SERIAL"]
idSerialShort := device.Properties()["ID_SERIAL_SHORT"]
idUsbSerial := device.Properties()["ID_USB_SERIAL"]
idUsbSerialShort := device.Properties()["ID_USB_SERIAL_SHORT"]
partUUID := device.Properties()["ID_PART_ENTRY_UUID"]
usbDevs = append(usbDevs, storageDevice{
DevPath: devPath,
Vender: vender,
IDSerial: idSerial,
IDSerialShort: idSerialShort,
PartitionUUID: partUUID,
DevPath: devPath,
Vender: vender,
IDSerial: idSerial,
IDSerialShort: idSerialShort,
IDUsbSerial: idUsbSerial,
IDUsbSerialShort: idUsbSerialShort,
PartitionUUID: partUUID,
})
}
@@ -199,7 +203,10 @@ func MountedHddPath(ctx context.Context) ([]string, error) {
func FilterBySerial(serial string) func(dev storageDevice) bool {
return func(dev storageDevice) bool {
return strings.HasSuffix(serial, dev.IDSerial) || strings.HasSuffix(serial, dev.IDSerialShort)
return strings.HasSuffix(serial, dev.IDSerial) ||
strings.HasSuffix(serial, dev.IDSerialShort) ||
strings.HasSuffix(serial, dev.IDUsbSerial) ||
strings.HasSuffix(serial, dev.IDUsbSerialShort)
}
}

View File

@@ -3,11 +3,13 @@ package utils
import "strings"
type storageDevice struct {
DevPath string
Vender string
IDSerial string
IDSerialShort string
PartitionUUID string
DevPath string
Vender string
IDSerial string
IDSerialShort string
IDUsbSerial string
IDUsbSerialShort string
PartitionUUID string
}
type mountedPath struct {

View File

@@ -24,9 +24,13 @@ export const oneSidebar: DefaultTheme.Sidebar = {
link: "/one/first-boot",
},
{
text: "Access Olares securely",
text: "Access Olares via VPN",
link: "/one/access-olares-via-vpn",
},
{
text: "Access Olares via .local domain",
link: "/one/access-olares-via-local-domain",
},
{
text: "Redeem membership",
link: "/one/redeem-membership",
@@ -202,10 +206,6 @@ export const oneSidebar: DefaultTheme.Sidebar = {
}
]
},
{
text: "Create a bootable USB",
link: "/one/create-drive",
},
]
},
{
@@ -221,9 +221,23 @@ export const oneSidebar: DefaultTheme.Sidebar = {
},
{
text: "Factory reset",
link: "/one/factory-reset",
collapsed: true,
items: [
{
text: "Using LarePass",
link: "/one/factory-reset",
},
{
text: "In BIOS",
link: "/one/factory-reset-in-bios",
},
{
text: "Using bootable USB",
link: "/one/create-drive",
},
],
},
]
},
],
}
}

View File

@@ -24,11 +24,15 @@ export const oneSidebar: DefaultTheme.Sidebar = {
link: "/zh/one/first-boot",
},
{
text: "Access Olares securely",
text: "Access Olares via VPN",
link: "/zh/one/access-olares-via-vpn",
},
{
text: "Redeem Olares Space membership",
text: "Access Olares via .local domain",
link: "/zh/one/access-olares-via-local-domain",
},
{
text: "Redeem membership",
link: "/zh/one/redeem-membership",
},
]
@@ -165,7 +169,7 @@ export const oneSidebar: DefaultTheme.Sidebar = {
},
{
text: "Connect two Olares One",
link: "/zh/one/connect-two-olares-one"
link: "/zh/one/connect-two-olares-one",
// items:
// [
// {
@@ -202,10 +206,6 @@ export const oneSidebar: DefaultTheme.Sidebar = {
}
]
},
{
text: "Create a bootable USB",
link: "/zh/one/create-drive",
},
]
},
{
@@ -221,9 +221,23 @@ export const oneSidebar: DefaultTheme.Sidebar = {
},
{
text: "Factory reset",
link: "/zh/one/factory-reset",
collapsed: true,
items: [
{
text: "Using LarePass",
link: "/zh/one/factory-reset",
},
{
text: "In BIOS",
link: "/zh/one/factory-reset-in-bios",
},
{
text: "Using bootable USB",
link: "/zh/one/create-drive",
},
],
},
]
},
],
}
}

View File

@@ -3,6 +3,7 @@ outline: [2,3]
description: Learn the different methods to access Olares services locally for improved speed and offline capability.
---
# Access Olares services locally
Olares is designed to provide seamless access to your self-hosted services anytime, anywhere.
However, accessing your devices locally provides several advantages:
@@ -11,7 +12,6 @@ However, accessing your devices locally provides several advantages:
- **Offline independence**: Access your data and apps even when your internet service is unavailable.
## Objectives
By the end of this tutorial, you will learn how to:
- Establish a secure, high-speed local connection using the LarePass VPN.
@@ -34,74 +34,48 @@ There are four ways to establish a local connection:
## Method 1: Enable LarePass VPN
The LarePass VPN is designed to secure your connection while optimizing performance. When enabled, LarePass detects if you are on the same network as your device and switches to **Intranet** mode.
:::tip Always enable VPN for remote access
Keep LarePass VPN enabled. It automatically prioritizes the fastest available route to ensure you always get the best speed possible without manual switching.
:::
:::info iOS and macOS setup
On iOS or macOS, you may be prompted to add a VPN Configuration to your system settings the first time you enable the feature. Allow this to complete the setup.
:::
<!--@include: ../../reusables/larepass-vpn.md{19,24}-->
Enable the LarePass VPN directly on the device you are currently using to access Olares.
<tabs>
<template #On-LarePass-mobile-client>
1. Open the LarePass app, and go to **Settings**.
2. In the **My Olares** card, toggle on the VPN switch.
![Enable LarePass VPN on mobile](/images/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #On-LarePass-desktop-client>
1. Open the LarePass app, and click your avatar in the top-left corner to open the user menu.
2. Toggle on the switch for **VPN connection**.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
Once enabled, check the status indicator in LarePass to verify the connection type:
| Status | Description |
|:-------------|:---------------------------------------------------------|
| **Intranet** | Direct connection via your local LAN IP. Fastest speeds. |
| **P2P** | Direct encrypted tunnel between devices. High speed. |
| **DERP** | Routed via a secure relay server. Used as a fallback. |
<!--@include: ../../reusables/larepass-vpn.md{26,50}-->
## Method 2: Use `.local` domain
If you prefer not to install additional apps, you can access services using the `.local` domain. There are two domain formats available depending on your operating system.
:::info Use HTTP protocol
The `.local` domain does not support HTTPS. You must explicitly use `http://` at the beginning of the URL.
:::
If you prefer not to install additional apps, you can access services using the `.local` domain. There are two domain formats available depending on your operating system.
### Single-level domain (All operating systems)
:::warning Supported for community apps only
Olares system apps such as Desktop and Files do not support this URL format and will not load correctly.
:::
This format uses a single-level domain by connecting the entrance ID and the username with hyphens (`-`).
- **Default URL**:
```plain
https://<entrance_id>.<username>.olares.com
```
- **Local-access URL**:
```plain
http://<entrance_id>-<username>-olares.local
```
### Multi-level domain (macOS and iOS only)
Apple devices support local service discovery via [Bonjour](https://developer.apple.com/bonjour/) (zeroconfiguration networking), which can resolve multilabel domains under `.local` on macOS and iOS. This allows a local URL format that mirrors the remote address.
**Standard URL**
```plain
https://<entrance_id>.<username>.olares.com
```
**Local URL**
```plain
http://<entrance_id>-<username>-olares.local
```
### Multi-level domain
The multi-level format below matches the structure of your standard Olares URL. Use it as shown.
<!--@include: ../../reusables/local-domain.md{7,23}-->
- **Default URL**:
```plain
https://<entrance_id>.<username>.olares.com
```
- **Local-access URL**:
```plain
http://<entrance_id>.<username>.olares.local
```
![Multi-level local domain](/images/manual/get-started/multilevel-local-domain-mac.png#bordered)
#### macOS and iOS
Apple devices support local service discovery via [Bonjour](https://developer.apple.com/bonjour/) (zeroconfiguration networking), which can resolve multilabel domains under `.local` on macOS and iOS.
Therefore, no extra setup is needed. You can directly use local URL in your browser.
#### Windows
<!--@include: ../../reusables/local-domain.md{26,40}-->
## Method 3: Configure local DNS
For a seamless experience where standard URLs resolve to your local IP address automatically, you can configure your network DNS. This configuration ensures consistent access across all devices on the network without requiring individual client setup.
@@ -212,39 +186,7 @@ If the IP address starts with `192.168`, it indicates successful configuration.
## FAQs
### Why doesn't LarePass VPN work on my Mac anymore?
If you successfully enabled the VPN previously, but it has stopped working, you might need to reset the system extension.
:::info
Depending on your macOS version, the UI might look slightly different.
:::
1. Open **System Settings**, search for "Extension", and select **Login Items & Extensions**.
2. Scroll to the **Network Extensions** section and click the info icon (ⓘ) to view loaded extensions.
3. Find LarePass, click the three dots (...), and select **Delete Extension**.
4. Confirm the uninstallation.
5. Restart your Mac and re-enable the VPN in the LarePass desktop client.
### Why can't I enable LarePass VPN on Windows?
Third-party antivirus software might mistakenly flag the LarePass desktop client as suspicious, preventing it from launching the VPN service.
<!--@include: ../../reusables/larepass-vpn.md{50,75}-->
If prompted by your antivirus when opening LarePass for the first time, allow the application to continue.
If the VPN still fails to enable:
1. Open your security software and check if LarePass was blocked.
2. Add the main LarePass executable to the allowlist or exclusions of your antivirus.
3. Restart LarePass and enable the VPN.
### Why the `.local` domain does not work in Chrome (macOS)?
Chrome may fail to access local URLs if macOS blocks local network permissions.
To enable access:
1. Open Apple menu and go to **System Settings**.
2. Go to **Privacy & Security** > **Local Network**.
3. Find Google Chrome and Google Chrome Helper in the list and enable the toggles.
![Enable local network](/images/manual/larepass/mac-chrome-local-access.png#bordered){width=400}
4. Restart Chrome and try accessing the local URL again.
### Why does the application fail to load in an iFrame when using a `.local` domain on Chrome (macOS)?
Chrome might default to HTTPS when using local domains, and you might see a "connection not secure" warning.
![Incorrect local address](/images/manual/get-started/incorrect-local-address.png#bordered)
To address this, explicitly add the HTTP protocol (`http://`) to the beginning of the URL. This tells Chrome it's a local, non-encrypted connection, which is expected on your home network.
<!--@include: ../../reusables/local-domain.md{42,75}-->

View File

@@ -1,81 +1,48 @@
---
outline: [2,3]
description: Learn how to access your Olares services securely using the LarePass VPN.
description: Learn how to access your Olares services securely using LarePass VPN or the .local domain.
---
# Access Olares services securely using LarePass VPN
# Access Olares services securely
Typically, you access Olares services through a browser using a URL like `https://desktop.<username>.olares.com`. This way, you can reach your services from any device at any time.
Typically, you access Olares services through a browser using a URL like `https://desktop.<username>.olares.com`. This way, you can reach your services from any device at any time. You can access Olares securely from your home network or from elsewhere.
While this address works from anywhere, it's recommended to enable the LarePass VPN to ensure your connection is always secure and efficient. The client automatically detects your network environment and selects the best connection method:
- **At home**: It establishes a direct **Intranet** connection to allow faster file transfers on your local network.
- **From remote**: It switches to a secure encrypted tunnel to ensure you remain connected safely when accessing remotely.
- [Using LarePass VPN](#using-larepass-vpn): Use this whether you are on your home network or away.
- [Using the .local domain](#using-the-local-domain): Use this only when your client device and Olares are on the same LAN.
## Download LarePass
To use the secure VPN connection, the LarePass client must be installed on the device you are using.
- **Mobile**: Use the LarePass app installed during the Olares ID creation process.
- **Desktop**: Download and install the LarePass desktop client.
## Using LarePass VPN
1. Visit <AppLinkGlobal />.
2. Download the version compatible with your operating system.
It is recommended to enable the LarePass VPN to ensure your connection is always secure and efficient. The client automatically detects your network environment and selects the best connection method:
## Enable LarePass VPN
Once installed, enable the VPN directly on the device you are using to access Olares.
- **At home**: It establishes a direct Intranet connection to allow faster file transfers on your local network.
- **From remote**: It switches to a secure encrypted tunnel so you remain connected safely when accessing remotely.
:::tip Always enable VPN for remote access
Keep LarePass VPN enabled. It automatically prioritizes the fastest available route to ensure you always get the best speed possible without manual switching.
:::
:::info iOS and macOS setup
On iOS or macOS, you may be prompted to add a VPN Configuration to your system settings the first time you enable the feature. Allow this to complete the setup.
:::
<!--@include: ../../reusables/larepass-vpn.md{19,24}-->
<tabs>
<template #On-LarePass-mobile-client>
Enable the LarePass VPN directly on the device you are currently using to access Olares.
1. Open the LarePass app and go to **Settings**.
2. In the **My Olares** card, toggle on the VPN switch.
<!--@include: ../../reusables/larepass-vpn.md{26,50}-->
![Enable LarePass VPN on mobile](/images/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #On-LarePass-desktop-client>
## Using the .local domain
1. Open the LarePass app and click your avatar in the top-left corner to open the user menu.
2. Toggle on the switch for **VPN connection**.
Use the `.local` domain when your device and Olares are on the same LAN.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
### URL format
## Verify the connection type
Once enabled, check the status indicator in LarePass to verify the connection type:
<!--@include: ../../reusables/local-domain.md{7,23}-->
| Status | Description |
|:-------------|:---------------------------------------------------------|
| **Intranet** | Direct connection via your local LAN IP. Fastest speeds. |
| **P2P** | Direct encrypted tunnel between devices. High speed. |
| **DERP** | Routed via a secure relay server. Used as a fallback. |
### macOS
## FAQs
### Why doesn't LarePass VPN work on my Mac anymore?
If you successfully enabled the VPN previously, but it has stopped working, you might need to reset the system extension.
:::info
Depending on your macOS version, the UI might look slightly different.
:::
1. Open **System Settings**, search for "Extension", and select **Login Items & Extensions**.
2. Scroll to the **Network Extensions** section and click the info icon (ⓘ) to view loaded extensions.
3. Find LarePass, click the three dots (...), and select **Delete Extension**.
4. Confirm the uninstallation.
5. Restart your Mac and re-enable the VPN in the LarePass desktop client.
No setup is needed. Use the local URL in your browser (for example, `http://desktop.<username>.olares.local`).
### Why can't I enable LarePass VPN on Windows?
Third-party antivirus software might mistakenly flag the LarePass desktop client as suspicious, preventing it from launching the VPN service.
### Windows
<!--@include: ../../reusables/local-domain.md{26,40}-->
If prompted by your antivirus when opening LarePass for the first time, allow the application to continue.
### FAQs
If the VPN still fails to enable:
1. Open your security software and check if LarePass was blocked.
2. Add the main LarePass executable to the allowlist or exclusions of your antivirus.
3. Restart LarePass and enable the VPN.
<!--@include: ../../reusables/larepass-vpn.md{50,75}-->
<!--@include: ../../reusables/local-domain.md{42,75}-->
## Learn more
- [Access Olares locally](../best-practices/local-access.md): Explore detailed instructions for all available local network connection methods.
- [Network](../../developer/concepts/network.md): Learn about the different entry points in Olares.
- [Network](../../developer/concepts/network.md): Learn about the different entry points in Olares.

View File

@@ -0,0 +1,41 @@
---
outline: [2, 3]
description: Learn how to access your Olares services on the same network using the `.local` domain.
head:
- - meta
- name: keywords
content: Olares, .local domain, local access
---
# Access Olares via .local domain
When your computer or phone is on the same local network as Olares One, you can use a `.local` domain to reach your Olares services so traffic stays on your LAN.
## Prerequisites
**Hardware**
- Olares One is set up and connected to your network.
- A client device (computer or phone) on the same network as Olares One.
**LarePass** (Required for Windows)
- The LarePass desktop client is installed on your Windows device.
- You have imported your Olares ID on the LarePass desktop client.
## URL format
<!--@include: ../reusables/local-domain.md{10,23}-->
## macOS
No setup is needed. Use the local URL in your browser (for example, `http://desktop.<username>.olares.local`).
## Windows
<!--@include: ../reusables/local-domain.md{26,40}-->
## Troubleshooting
<!--@include: ../reusables/local-domain.md{42,75}-->
## Learn more
- [Access Olares services locally](../manual/best-practices/local-access.md): DNS configuration, hosts file, and other local access methods.

View File

@@ -21,75 +21,17 @@ While this address works from anywhere, it's recommended to enable the LarePass
- A client device (computer or mobile phone) with internet access.
## Step 1: Download LarePass
To use the secure VPN connection, the LarePass client must be installed on the device you are using to access Olares.
- **Mobile**: Use the LarePass app installed during the Olares ID creation process.
- **Desktop**: Download and install the LarePass desktop client.
1. Visit <AppLinkGlobal />.
2. Download the version compatible with your operating system.
3. Install the application and log in with your Olares ID.
<!--@include: ../reusables/larepass-vpn.md{7,16}-->
## Step 2: Enable LarePass VPN
Once installed, enable the VPN directly on the device.
:::tip Always enable VPN for remote access
Keep LarePass VPN enabled. It automatically prioritizes the fastest available route to ensure you always get the best speed possible without manual switching.
:::
:::info iOS and macOS setup
On iOS or macOS, you may be prompted to add a VPN Configuration to your system settings the first time you enable the feature. Allow this to complete the setup.
:::
<tabs>
<template #On-LarePass-mobile-client>
1. Open the LarePass app and go to **Settings**.
2. In the **My Olares** card, toggle on the VPN switch.
![Enable LarePass VPN on mobile](/images/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #On-LarePass-desktop-client>
1. Open the LarePass app and click your avatar in the top-left corner to open the user menu.
2. Toggle on the switch for **VPN connection**.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
<!--@include: ../reusables/larepass-vpn.md{18,41}-->
## Step 3: Verify the connection type
Once enabled, check the status indicator in LarePass to confirm how you are connected:
| Status | Description |
|:-------------|:---------------------------------------------------------|
| **Intranet** | Direct connection via your local LAN IP. Fastest speeds. |
| **P2P** | Direct encrypted tunnel between devices. High speed. |
| **DERP** | Routed via a secure relay server. Used as a fallback. |
<!--@include: ../reusables/larepass-vpn.md{42,49}-->
## Troubleshooting
### Why doesn't LarePass VPN work on my Mac anymore?
If the VPN was working previously but has stopped, you might need to reset the system extension.
:::info
Depending on your macOS version, the UI might look slightly different.
:::
1. Open System Settings, search for "Extension", and select **Login Items & Extensions**.
2. Scroll to the **Network Extensions** section and click the info icon (ⓘ) to view loaded extensions.
3. Find LarePass, click the three dots (...), and select **Delete Extension**.
4. Restart your Mac.
5. Open the LarePass desktop client and re-enable the VPN.
### Why can't I enable LarePass VPN on Windows?
Third-party antivirus software may mistakenly flag the LarePass client, blocking the VPN service.
If prompted by your antivirus when opening LarePass for the first time, allow the application to continue.
If the VPN still fails to enable:
1. Check your antivirus software to see if LarePass was blocked.
2. Add the main LarePass executable to the allowlist or exclusions of your antivirus.
3. Restart LarePass and try enabling the VPN again.
## Learn more
- [Access Olares locally](../manual/best-practices/local-access.md): Explore detailed instructions for all available local network connection methods.
- [Access Olares terminal](access-terminal-ssh.md): Learn how to connect to the host shell using SSH or the Control Hub web terminal.
- [Network](../developer/concepts/network.md): Learn about the different entry points in Olares.
<!--@include: ../reusables/larepass-vpn.md{50,74}-->

View File

@@ -17,14 +17,6 @@ You can connect to the host shell using one of the following methods:
- **Control Hub Terminal** is a web-based interface for direct root access. It is recommended for quick tasks.
- **Secure Shell (SSH)** is the standard protocol for remote management and complex operations.
## Before you begin
- The default username and password for Olares One are both `olares`.
:::warning Reset default SSH password
Even if you primarily use the Control Hub terminal, you must reset this password immediately in **Settings** > **My hardware** to secure your device against unauthorized access.
:::
- SSH access grants powerful control over the system. Ensure you keep your credentials secure.
## Prerequisites
**Hardware**
- Your Olares One is set up and connected to a network.
@@ -33,9 +25,6 @@ You can connect to the host shell using one of the following methods:
**Experience**
- Basic familiarity with terminal commands and the command-line interface (CLI).
**LarePass** (Required for remote access)
- The LarePass app is installed on your device. This is required only if you plan to connect via SSH from a remote location outside your local network.
## Method 1: Access via Control Hub
For quick access without configuring SSH clients, you can use the web-based terminal built directly into Control Hub.
@@ -53,7 +42,7 @@ The Control Hub terminal runs as `root` by default. You do not need to use `sudo
SSH establishes a secure session over the network, allowing you to use command-line operations for Olares One on your current device.
### Get IP address of Olares One
### Step 1: Get IP address of Olares One
To connect via SSH, you first need to find the internal IP address of your Olares One.
1. Open the LarePass app, and go to **Settings** > **System** to navigate to the **Olares management** page.
@@ -67,43 +56,20 @@ You can check the IP using the `ifconfig` command in the Control Hub terminal.
Look for your active connection, typically named `enp3s0` (wired) or `wlo1` (wireless). The IP address follows `inet`.
:::
### Connect via SSH (local network)
If your computer and the Olares One are on the same Wi-Fi or LAN:
### Step 2: Check SSH password in Vault
<!--@include: ./reusables-reset-ssh.md{7,16}-->
### Step 3: Connect via SSH
1. Open a terminal on your computer.
2. Run the `ssh` command using Olares One's local IP address:
```bash
ssh <username>@<host_ip_address>
# The default username for Olares One is olares.
ssh olares@<host_ip_address>
```
For example:
3. Enter the password when prompted.
```bash
ssh olares@192.168.31.155
```
3. Enter the host password when prompted.
### Connect via SSH (remote access)
If you are away from home, you can use LarePass VPN to bridge the connection securely.
#### Allow SSH access via VPN
For security, SSH access via VPN is disabled by default. You must enable it once.
1. On Olares, open the Settings app.
2. Navigate to **VPN**.
3. Toggle on **Allow SSH via VPN**.
#### Enable LarePass VPN
1. Open the LarePass desktop client on your computer.
2. Click your avatar in the top-left corner and toggle on **VPN connection**.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
3. Open a terminal on your computer.
4. Run the `ssh` command using Olares One's local IP address. LarePass handles the routing automatically.
```bash
ssh <username>@<host_ip_address>
```
For example:
```bash
ssh olares@192.168.31.155
```
5. Enter the host password when prompted.
## Reset SSH password
<!--@include: ./reusables-reset-ssh.md{19,}-->

View File

@@ -1,65 +1,81 @@
---
outline: [2, 3]
description: Learn how to create a bootable USB installer for Olares OS using balenaEtcher.
description: Reinstall Olares OS on Olares One using a bootable USB to restore the device to factory state.
head:
- - meta
- name: keywords
content: Olares, Olares One, install Olares, bootable USB, ISO, balenaEtcher
content: Olares One, reinstall, factory reset, bootable USB, installation USB
---
# Create a bootable USB drive <Badge type="tip" text="15 min"/>
# Reset to factory settings using installation USB <Badge type="tip" text="15 min"/>
To reinstall or recover Olares OS on your Olares One, you must create a bootable USB installation drive. This drive allows you to reset the device to its factory state.
Resetting to factory settings returns your Olares One to the initial setup state. You can reinstall Olares OS using the bootable USB drive included with Olares One.
:::warning Data loss warning
This process will erase all data on your USB drive. If you have important files on the drive, back them up before proceeding.
:::
:::warning Image compatibility
Olares One requires a specific system image designed for its hardware. If you install the generic self-hosted ISO, Olares One will fail to boot.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
:::
## Prerequisites
- USB flash drive: A drive with 8 GB or higher capacity.
:::info
Ensure that your USB drive is empty or backed up. The flashing process re-formats the drive, which means existing data on it will be permanently deleted.
:::
- Computer: A Windows, macOS, or Linux computer to perform the setup.
- Internet connection: Stable network for downloading the image file and related software.
**Hardware**<br>
- The bootable USB drive that came with Olares One.
- A monitor and keyboard connected to Olares One.
## Step 1. Download Olares image
## Step 1: Boot from the USB drive
Click to download the [ISO image for Olares One](https://cdn.olares.com/one/olares.iso). The file `olares.iso` will be saved to your computer.
1. Insert the bootable USB drive into Olares One.
2. Power on Olares One or restart it if it is already running.
3. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
## Step 2. Install flashing tool
4. Navigate to the **Boot** tab, set **Boot Option #1** to the USB drive, and then press **Enter**.
![Set boot option](/images/one/bios-set-boot-option.png#bordered)
It is recommended to use balenaEtcher for this task because it is free, easy to use, and works on all major operating systems.
5. Press **F10**, then select **Yes** to save and exit.
![Save and exit](/images/one/bios-save-usb-boot.png#bordered)
1. Go to the [balenaEtcher website](https://etcher.balena.io/).
2. Download and install the version appropriate for your computer (Windows, macOS, or Linux).
## Step 3. Flash the drive
Olares One will restart and boot into the Olares installer interface.
Use balenaEtcher to turn your USB stick into a bootable installer.
## Step 2: Install Olares to disk
1. Insert your USB flash drive into the computer.
2. Open balenaEtcher.
3. Follow the steps on the screen:
1. From the installer interface, select **Install Olares to Hard Disk** and press **Enter**.
![Olares installer](/images/one/olares-installer.png#bordered)
a. Click **Flash from file** and select the Olares ISO file you downloaded.
2. When prompted for the installation target, the installer shows a list of available disks. Type `/dev/` followed by the disk name (e.g. `nvme0n1`) from that list and press **Enter**.
![Select disk](/images/one/olares-installer-select-disk.png#bordered)
b. Click **Select target** and select your USB drive.
For example, to install to `nvme0n1`, enter:
```bash
/dev/nvme0n1
```
c. Click **Flash!** to start writing the installer to the USB drive.
3. When you see prompts about NVIDIA GPU drivers, press **Enter** to accept the default.
![Install NVIDIA drivers](/images/one/olares-installer-install-nvidia-drivers.png#bordered)
![Bootable USB](/images/one/balenaEtcher.png#bordered)
4. When you see the message below, the reinstallation is complete:
```bash
Installation completed successfully!
```
4. When the flashing process is completed, the USB drive is ready to use, and you can safely eject it.
5. Remove the USB drive, then press **Ctrl + Alt + Delete** to restart.
## Next steps
## Step 3: Verify the installation
You can now insert the bootable USB drive into Olares One or other target hardware to begin the installation.
After the reboot, the system starts in a clean factory state and shows a text-based Ubuntu login prompt.
## Resources
1. Log in with the default credentials:
- **Username**: `olares`
- **Password**: `olares`
![Log in](/images/one/olares-login.png#bordered)
- [Install Olares via ISO](../manual/get-started/install-linux-iso.md)
- [Install Olares](../manual/get-started/install-olares.md)
- [Installation FAQs](../manual/help/installation.md)
2. (Optional) Run the following command to verify the installation:
```bash
sudo olares-check
```
Example output:
![Olares check](/images/one/olares-check.png#bordered)
## Step 4: Complete activation via LarePass
You can then activate Olares One again via LarePass. For detailed instructions, see [First boot](first-boot.md).

View File

@@ -21,15 +21,16 @@ This dual-drive configuration physically isolates the systems. This ensures Olar
## Step 1: Boot into BIOS
1. Insert the Windows USB boot drive into a USB port on Olares One.
2. Power on Olares One or restart if it is already running.
3. Immediately press and hold the **Delete** key repeatedly until the BIOS setup screen appears.
2. Power on Olares One or restart it if it is already running.
3. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
## Step 2: Boot from USB
1. Navigate to the **Boot** tab using the arrow keys on your keyboard.
2. Locate **Boot Option #1** or **Boot Override** and select your USB flash drive.
3. Press **Enter** to boot from the USB drive immediately.
4. The system will restart and load the Windows installation interface.
2. Set **Boot Option #1** to your Windows USB flash drive, and press **Enter**.
3. Press **F10**, then select **Yes** to save and exit BIOS.
4. The system restarts and boots from the USB drive into the Windows installation interface.
## Step 3: Install Windows
1. Follow the on-screen prompts to begin the Windows installation.
@@ -49,16 +50,16 @@ Because the operating systems are on separate physical drives, you switch betwee
### Switch to Olares OS
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Go to the **Boot** tab.
4. Set **Boot Option #1** to the SSD containing Olares OS.
5. Press **F4** to confirm.
5. Press **F10** to save and exit BIOS.
### Switch to Windows
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Set **Boot Option #1** to the secondary SSD containing Windows.
4. Press **F4** to confirm.
4. Press **F10** to save and exit BIOS.
## Resources
- [Install NVIDIA drivers on Windows](install-nvidia-driver.md)

View File

@@ -34,11 +34,13 @@ Partitioning a drive carries a risk of data loss. If you have important data on
## Step 1: Install Windows
1. Insert the Windows USB boot drive into a USB port on Olares One.
2. Power on Olares One or restart if it is already running.
3. Immediately press and hold the **Delete** key repeatedly until the BIOS setup screen appears.
2. Power on Olares One or restart it if it is already running.
3. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
4. Navigate to the **Boot** tab using the arrow keys on your keyboard.
5. Locate **Boot Option #1** or **Boot Override** and select your USB flash drive.
6. Press **Enter** to boot from the USB drive immediately.
5. Set **Boot Option #1** to your Windows USB flash drive, and press **Enter**.
6. Press **F10**, then select **Yes** to save and exit BIOS. The system restarts and boots from the USB drive into the Windows installation interface.
7. Follow the on-screen prompts to begin the Windows installation.
8. When the installation finishes and the system restarts, unplug the Windows USB drive.
@@ -59,13 +61,14 @@ The system will boot into Windows automatically.
Olares OS runs on top of a Linux kernel. You will install Ubuntu to serve as the host system.
1. Insert the Ubuntu USB drive and restart Olares One.
2. Press **Delete** repeatedly to enter BIOS, then select the USB drive as the boot device.
3. Follow the installer prompts until you reach the **Installation type** screen.
4. Select **Install Ubuntu alongside Windows Boot Manager**.
2. When the Olares logo appears, press the **Delete** key repeatedly to enter **BIOS setup**.
3. Navigate to the **Boot** tab, set **Boot Option #1** to your Ubuntu USB flash drive, and then press **Enter**.
4. Press **F10**, then select **Yes** to save and exit BIOS. The system restarts and boots from the USB drive into the Ubuntu installer.
5. Follow the installer prompts until you reach the **Installation type** screen.
:::tip
If this option does not appear, select the manual installation option to manually assign the unallocated space to Ubuntu.
:::
5. When the installation finishes and the system restarts, unplug the Ubuntu USB drive.
6. When the installation finishes and the system restarts, unplug the Ubuntu USB drive.
The system will boot into Ubuntu automatically.
@@ -120,17 +123,17 @@ After setup is complete, the LarePass app returns to the home screen, and the br
You switch between Windows and Olares using the BIOS boot priority.
### Switch to Olares OS
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Go to the **Boot** tab.
4. Set **Boot Override** to Ubuntu.
5. Press **F4** to confirm.
5. Press **F10** to save and exit BIOS.
### Switch to Windows
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Go to the **Boot** tab.
4. Set **Boot Override** to Windows.
5. Press **F4** to confirm.
5. Press **F10** to save and exit BIOS.
## Troubleshooting

View File

@@ -0,0 +1,39 @@
---
outline: [2, 3]
description: Learn how to restore your Olares One to factory settings in BIOS.
head:
- - meta
- name: keywords
content: Factory reset, Olares One, BIOS
---
# Reset to factory settings in BIOS <Badge type="tip" text="10 min" />
Resetting to factory settings returns your Olares One to its initial setup state. If you have a monitor and keyboard connected, you can perform this reset directly in BIOS instead of using LarePass.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
:::
## Prerequisites
**Hardware**<br>
- A wired keyboard connected to your Olares One.
- A monitor connected to your Olares One.
## Step 1: Load optimized defaults in BIOS
1. Power on Olares One or restart it if it is already running.
2. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
3. Press **F9**, then select **Yes** to restore factory settings.
![Load optimized defaults](/images/one/bios-load-optimized-defaults.png#bordered)
4. Press **F10**, then select **Yes** to save and exit. The device restarts automatically.
![Save and exit](/images/one/bios-save-load-defaults.png#bordered)
Once finished, Olares One reboots into the initial setup phase.
## Step 2: Complete activation via LarePass
You can then activate Olares One again via LarePass. For detailed instructions, see [First boot](first-boot.md).

View File

@@ -6,23 +6,17 @@ head:
- name: keywords
content: Factory reset, Olares One
---
# Reset to factory settings <Badge type="tip" text="10 min" />
# Reset to factory settings using LarePass <Badge type="tip" text="10 min" />
Resetting to factory settings returns your Olares One to the initial setup state.
If you have already activated Olares One and want to return it to the factory state, you can perform a reset in LarePass.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
:::
## Learning objectives
By the end of this tutorial, you will learn how to:
- Perform a factory reset from LarePass.
- Complete the required confirmation and local password verification.
## Prerequisites
Before starting, ensure that:
**Hardware**<br>
- Olares One is powered on.
- Your phone and Olares One are on the same network.
- You are signed in to LarePass as an administrator.
@@ -30,15 +24,17 @@ Before starting, ensure that:
## Reset Olares One to factory settings
1. Open LarePass on your phone and go to **Settings**.
2. In the **My Olares** card, tap **System** to enter the **Olares management** page.
2. In the **My Olares** card, tap **System** to open the **Olares management** page.
3. Tap **Restore to factory settings**.
4. Review the risk prompt, then tap **Restore to factory settings** to continue.
4. Review the risk prompt carefully, then tap **Restore to factory settings** to continue.
![Review risk prompt](/images/manual/larepass/review-risk-prompt.png#bordered)
5. Enter your local LarePass lock screen password and tap **Confirm**.
5. Enter your local LarePass lock-screen password and tap **Confirm**.
![Enter local unlock password](/images/manual/larepass/enter-password-to-uninstall.png#bordered)
If you have not set a local password, you will be prompted to set one first.
6. Wait for the reset process to complete.
Once finished, Olares One reboots into the initial setup phase. You will be redirected to the activation flow, where you can scan the local network to reinstall or reactivate Olares.
Once finished, Olares One reboots into the initial setup phase. You are redirected to the activation flow, where you can scan the local network to reactivate Olares.
For detailed instructions, see [First boot](first-boot.md).

View File

@@ -89,21 +89,17 @@ Your Olares ID is secured by a unique 12-word mnemonic phrase. This phrase is th
4. Enter the local password as prompted.
5. Write the 12 words onto the **Recovery Sheet**, and then store the sheet in a secure, offline location.
### Reset SSH password
<!--@include: ./reusables-reset-ssh.md{7,16}-->
For instructions on how to SSH into Olares One, see [Connect to Olares One via SSH](access-terminal-ssh.md).
### Access Olares services securely
For secure remote access without complex network configuration, it is recommended to enable the LarePass VPN.
See [Access Olares services securely using LarePass VPN](access-olares-via-vpn.md).
### Reset SSH password
If you plan to connect to your Olares One via terminal (SSH), you must update the default SSH password.
1. Open Olares Settings, on the **My hardware** page, click **Reset SSH password**.
2. In the dialog, enter a new SSH password that meets all strength requirements, then click **OK**.
3. Open the LarePass app and scan the QR code shown on the screen.
4. Click **Confirm** on LarePass to finish.
For details, see [Connect to Olares One via SSH](access-terminal-ssh.md).
### Explore
Olares OS comes with pre-installed system apps. You can also browse the **Market** to download additional applications that best suit your needs.

View File

@@ -0,0 +1,27 @@
---
search: false
---
## Reset SSH password
### Reset upon activation
Right after you activate Olares, you will be prompted to reset the SSH password on the LarePass app. The password is automatically generated and saved to your Vault.
To view the saved password in Vault:
1. Tap **Vault** in the LarePass app. When prompted, enter your local password to unlock.
2. In the top-left corner, tap **Authenticator** to open the side navigation, then tap **All vaults** to display all saved items.
![Switch Vault filter](/images/one/ssh-switch-filter.png#bordered)
3. Find the item with the <span class="material-symbols-outlined">terminal</span> icon and tap it to reveal the password.
![Check saved SSH password in Vault](/images/one/ssh-check-password-in-vault.png#bordered)
### Reset in Olares Settings
If you prefer to use an SSH password instead of the automatically generated one, you can manually reset the password in Settings.
1. Open Settings. On the **My Olares** page, select **My hardware**.
2. Select **Reset SSH login password** at the bottom.
![Reset SSH login password](/images/one/ssh-reset-password-in-settings.png#bordered){width=70%}
3. In the dialog, enter a new SSH password that meets all strength requirements, then click **OK**.
4. Open the LarePass app and scan the QR code shown on the screen.
5. Click **Confirm** on LarePass to finish.

View File

@@ -67,7 +67,12 @@ You need to access the Sunshine Web UI running on your Olares One to enter a pai
1. Copy the URL of your current Steam Headless browser tab.
2. Open a new browser tab and modify the URL to access port `47990`. The address varies depending on your network.
- **Same network**: Use HTTPS with your `.local` address. Either format works (dots or hyphens in the hostname):
- **Same network**: Use HTTPS with your `.local` address. Either
format works (dots or hyphens in the hostname):
:::info Sunshine and .local
Use HTTPS (not HTTP) with your `.local` address for this app.
:::
```plain
https://139ebc4f0.<your Olares ID>.olares.local:47990
@@ -135,9 +140,9 @@ The following steps demonstrate local streaming.
### Why can't I access the Sunshine Web UI using the `.local` address?
Olares supports `.local` addresses with the HTTP protocol for most services. The Sunshine Web UI is different because it requires HTTPS to secure local communication. If you use `http://` with your `.local` URL, the Sunshine page will not load.
For most Olares services, you use HTTP with `.local` addresses. Sunshine is an exception and requires HTTPS to secure local communication. If you use `http://` with your `.local` URL, the Sunshine page will not load.
To fix this, use `https://` instead of `http://` in your browser's address bar (for example, `https://139ebc4f0.<your Olares ID>.olares.local:47990`).
Use `https://` in your browser's address bar (for example, `https://139ebc4f0.<your Olares ID>.olares.local:47990`).
### Why isn't the game displaying in full screen?

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

10
docs/reusables/README.md Normal file
View File

@@ -0,0 +1,10 @@
# Reusables
This directory holds shared content included in multiple docs via `<!--@include: path/to/reusables/file.md{start,end}-->`.
Add new reusable fragments here and document line ranges in a comment at the top of each file.
- **local-domain.md**: .local domain description, URL format, HTTP note, and troubleshooting (Chrome, Safari). Used by `manual/get-started/local-access.md`, `manual/best-practices/local-access.md`, and `one/access-olares-via-local-domain.md`.
- **larepass-vpn.md**: LarePass VPN procedure (Download, Enable, Verify connection type) and FAQs (Mac extension reset, Windows antivirus). Used by `manual/get-started/local-access.md`, `manual/best-practices/local-access.md`, and `one/access-olares-via-vpn.md`.

View File

@@ -0,0 +1,74 @@
---
search: false
---
<!-- Reusable LarePass VPN content. Include by line range.
Steps (no headings): Step 1 7-16, Step 2 18-41, Step 3 42-49.
FAQs: 50-75 -->
To use the secure VPN connection, the LarePass client must be installed on the device you are using to access Olares.
- **Mobile**: Use the LarePass app installed during the Olares ID creation process.
- **Desktop**: Download and install the LarePass desktop client.
1. Visit <AppLinkGlobal />.
2. Download the version compatible with your operating system.
3. Install the application and log in with your Olares ID.
Once installed, enable the VPN directly on the device.
:::tip Always enable VPN for remote access
Keep LarePass VPN enabled. It automatically prioritizes the fastest available route to ensure you always get the best speed possible without manual switching.
:::
:::info iOS and macOS setup
On iOS or macOS, you may be prompted to add a VPN Configuration to your system settings the first time you enable the feature. Allow this to complete the setup.
:::
<tabs>
<template #On-LarePass-mobile-client>
1. Open the LarePass app and go to **Settings**.
2. In the **My Olares** card, toggle on the VPN switch.
![Enable LarePass VPN on mobile](/images/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #On-LarePass-desktop-client>
1. Open the LarePass app and click your avatar in the top-left corner to open the user menu.
2. Toggle on the switch for **VPN connection**.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
Once enabled, check the status indicator in LarePass to verify the connection type:
| Status | Description |
|:-------------|:---------------------------------------------------------|
| **Intranet** | Direct connection via your local LAN IP. Fastest speeds. |
| **P2P** | Direct encrypted tunnel between devices. High speed. |
| **DERP** | Routed via a secure relay server. Used as a fallback. |
### Why doesn't LarePass VPN work on my Mac anymore?
If you successfully enabled the VPN previously, but it has stopped working, you might need to reset the system extension.
:::info
Depending on your macOS version, the UI might look slightly different.
:::
1. Open **System Settings**, search for "Extension", and select **Login Items & Extensions**.
2. Scroll to the **Network Extensions** section and click the info icon (ⓘ) to view loaded extensions.
3. Find LarePass, click the three dots (...), and select **Delete Extension**.
4. Confirm the uninstallation.
5. Restart your Mac and re-enable the VPN in the LarePass desktop client.
### Why can't I enable LarePass VPN on Windows?
Third-party antivirus software might mistakenly flag the LarePass desktop client as suspicious, preventing it from launching the VPN service.
If prompted by your antivirus when opening LarePass for the first time, allow the application to continue.
If the VPN still fails to enable:
1. Open your security software and check if LarePass was blocked.
2. Add the main LarePass executable to the allowlist or exclusions of your antivirus.
3. Restart LarePass and enable the VPN.

View File

@@ -0,0 +1,74 @@
---
search: false
---
<!-- Reusable .local domain content. Include by line range.
Order: description, URL+HTTP, Windows, then FAQs.
Ranges: description 7-8, URL+HTTP 10-23, Windows 25-40 (content only 26-40), FAQs 42-75 -->
When your device is on the same local network as Olares, you can use a `.local` domain to reach your services so traffic stays on your LAN.
Use a multi-level `.local` hostname that mirrors your standard URL. This format works with Olares system apps and community apps.
:::tip
Use `http://`, not `https://`, with the `.local` URL.
:::
**Standard URL**
```text
https://<entrance_id>.<username>.olares.com
```
**Local URL**
```text
http://<entrance_id>.<username>.olares.local
```
### Windows
On Windows, `.local` hostnames are not resolved by default. Use the LarePass desktop app to add the necessary entries to your hosts file so multi-level `.local` URLs resolve to your Olares device.
1. Open the LarePass app, click your avatar, then **Settings**.
2. Scroll to **Enable local service domain** and click **Add**. LarePass will update your hosts file automatically.
![Enable local service domain](/images/one/larepass-win-update-hosts.png#bordered)
3. When the update completes, a success message appears. If a command line window opens, you can close it.
4. (Optional) To verify the changes to the hosts file:
a. Go to `C:\Windows\System32\drivers\etc\`.
b. Open the `hosts` file in a text editor. You should see the `.local` entries that LarePass added.
![Hosts file updated by LarePass](/images/one/larepass-updated-hosts.png#bordered)
### Why doesn't the .local domain work in Chrome on macOS?
Chrome may block local URLs if macOS has not granted it local network access.
1. Open the Apple menu and go to **System Settings**.
2. Go to **Privacy & Security** > **Local Network**.
3. Find **Google Chrome** and **Google Chrome Helper** and turn their toggles on.
4. Restart Chrome and try the `.local` URL again.
![Enable local network](/images/manual/larepass/mac-chrome-local-access.png#bordered){width=400}
### Why does the app show "connection not secure" or fail to load in Chrome?
Chrome sometimes forces HTTPS for `.local` hostnames, which is not supported.
Use `http://` explicitly at the start of the URL (e.g. `http://desktop.<username>.olares.local`). On your home network, this unencrypted local connection is expected and keeps the `.local` domain working.
![Incorrect local address](/images/manual/get-started/incorrect-local-address.png#bordered)
### Why does the iframe flicker when I open a .local URL in Safari?
Safari applies stricter handling to `.local` (and other non-HTTPS) content in iframes, which can make the iframe flicker or reload. Enabling two options in **Privacy** settings fixes it.
To fix it:
1. Open **Safari** and go to **Settings**.
2. Open the **Privacy** tab.
3. Enable the two options:
- Prevent cross-site tracking
- Hide IP address from trackers
![Safari Privacy settings for .local](/images/manual/get-started/safari-privacy-settings.png#bordered){width=70%}
4. Reload the `.local` page.

View File

@@ -26,7 +26,12 @@ By the end of this tutorial, you are be able to:
## Prerequisites
- Local model: Ensure Ollama is installed and running. You must have a tool-capable model installed, such as `glm-4.7-flash`, `qwen3`, and `llama3.1`. This tutorial uses `llama3.1:8b`.
- Local model: Ensure Ollama is installed and running. You must have a tool-capable model installed, such as `glm-4.7-flash`, `qwen3.5:27b`, and `gpt-oss:20b`. This tutorial uses `qwen3.5:27b`.
:::tip
OpenClaw requires a large "context window" (that is the AI's short-term memory) to handle complex tasks without forgetting your previous instructions. If you are using local models, it is recommended to select a model that natively supports a context window of at least 64K tokens.
:::
- Discord account: Required to create the bot application.
- Discord server: A server where you have permissions to add bots.
- (Optional) Brave search API key: Required for the agent to search the web for real-time information.
@@ -190,7 +195,7 @@ Connect the Control UI to the OpenClaw CLI to use the graphical dashboard.
"agents": {
"defaults": {
"model": {
"primary": "ollama/llama3.1:8b"
"primary": "ollama/qwen3.5:27b"
},
"workspace": "/home/node/.openclaw/workspace",
"maxConcurrent": 4,

View File

@@ -34,74 +34,48 @@ Olares 的设计初衷是让你随时随地都能无缝访问自己的服务。
## 方法 1启用 LarePass VPN
LarePass VPN 旨在兼顾连接安全与性能优化。启用后LarePass 会自动检测设备是否处于同一网络,并切换至**内网**模式。
:::tip 始终启用 VPN 以进行远程访问
保持 LarePass VPN 启用。它会自动优先选择最快的可用路由,确保你无需手动切换即可获得最佳速度。
:::
:::info iOS 和 macOS 设置
在 iOS 或 macOS 上首次启用该功能时,系统可能会提示你添加 VPN 配置文件。允许此操作以完成设置。
:::
<!--@include: ../../reusables/larepass-vpn.md{19,24}-->
直接在你当前用于访问 Olares 的设备上启用 LarePass VPN。
在用来访问 Olares 的当前设备上直接启用 LarePass VPN。
<tabs>
<template #使用-LarePass-移动端>
1. 打开 LarePass 应用,进入**设置**。
2. 在**我的 Olares** 卡片中,打开 VPN 开关。
![移动端开启 LarePass VPN](/images/zh/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #使用-LarePass-桌面端>
1. 打开 LarePass 应用,点击左上角的头像打开用户菜单。
2. 打开**专用网络连接**开关。
![桌面端开启 LarePass VPN](/images/zh/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
启用后,可以查看 LarePass 中的网络状态以确认连接类型:
| 状态 | 描述 |
|:-----------|:---------------------------|
| **内网** | 通过本地局域网 IP 直连。速度最快。 |
| **P2P** | 设备间的直接加密隧道。连接速度快。 |
| **DERP** | 通过安全中继服务器路由,仅在无法直连时作为备用方案。 |
<!--@include: ../../reusables/larepass-vpn.md{26,50}-->
## 方法 2使用 `.local` 域名
若不希望安装额外应用,可使用 `.local` 域名访问服务。根据操作系统不同,有两种域名格式。
:::info 使用 HTTP 协议
`.local` 域名不支持 HTTPS。务必在 URL 开头显式添加 `http://`
:::
如果不希望安装额外应用,可使用 `.local` 域名访问服务。根据操作系统不同,有两种域名格式。
### 单级域名(所有操作系统适用)
:::warning 仅支持社区应用
Desktop 和文件管理器等 Olares 系统应用不支持此 URL 格式,因此无法正确加载。
:::
此格式通过连字符(`-`)连接入口 ID 和用户名来使用单级主机名。
- **默认 URL**
```plain
https://<entrance_id>.<username>.olares.cn
```
- **本地访问 URL**
```plain
http://<entrance_id>-<username>-olares.local
```
### 多级域名 (macOS 和 iOS 适用)
Apple 设备支持通过 [Bonjour](https://developer.apple.com/bonjour/)(零配置网络)进行本地服务发现,因此能够在 macOS 和 iOS 上解析 `.local` 下的多级域名。这使得本地 URL 格式可以与默认的远程访问地址保持结构一致。
**标准 URL**
```plain
https://<entrance_id>.<username>.olares.cn
```
**本地访问 URL**
```plain
http://<entrance_id>-<username>-olares.local
```
### 多级域名
The multi-level format below matches the structure of your standard Olares URL. Use it as shown.
<!--@include: ../../reusables/local-domain.md{7,23}-->
- **默认 URL**
```plain
https://<entrance_id>.<username>.olares.cn
```
- **本地访问 URL**
```plain
http://<entrance_id>.<username>.olares.local
```
![多级域名](/images/manual/get-started/multilevel-local-domain-mac.png#bordered)
#### macOS and iOS
Apple devices support local service discovery via [Bonjour](https://developer.apple.com/bonjour/) (zeroconfiguration networking), which can resolve multilabel domains under `.local` on macOS and iOS.
Therefore, no extra setup is needed. You can directly use local URL in your browser.
#### Windows
<!--@include: ../../reusables/local-domain.md{26,40}-->
## 方法 3配置本地 DNS
为了获得无缝体验(即标准 URL 自动解析为你的本地 IP 地址),你可以配置网络 DNS。此配置确保网络上所有设备的访问一致无需单独设置客户端。
@@ -212,39 +186,7 @@ ping desktop.<username>.olares.cn
## 常见问题
### 为什么在 Mac 上无法再启用 LarePass VPN
如果之前成功启用过 VPN但现在停止工作可能需要重置系统扩展。
:::info
根据 macOS 版本不同,界面可能略有差异。
:::
1. 打开**系统设置**,搜索`扩展`,选择**登录项与扩展**。
2. 滚动到**网络扩展** 部分,点击信息图标 (ⓘ) 查看已加载的扩展。
3. 找到 LarePass点击三个点 (...),选择**删除扩展**。
4. 确认卸载。
5. 重启 Mac 并在 LarePass 桌面客户端中重新启用 VPN。
### 为什么我在 Windows 上无法启用 LarePass VPN
第三方杀毒软件可能会错误地将 LarePass 桌面客户端标记为可疑,从而阻止其启动 VPN 服务。
<!--@include: ../../reusables/larepass-vpn.md{50,75}-->
如果在首次打开 LarePass 时收到杀毒软件提示,请允许应用程序继续运行。
如果 VPN 仍然无法启用:
1. 打开安全软件,检查 LarePass 是否被拦截。
2. 将 LarePass 主程序添加到杀毒软件的白名单或排除项中。
3. 重启 LarePass 并启用 VPN。
### 为什么在 macOS 上Chrome 无法访问 `.local` 域名?
如果 macOS 未授予局域网访问权限Chrome 可能会无法访问本地 URL。
要启用访问权限:
1. 打开 Apple 菜单,进入**系统设置**。
2. 进入**隐私与安全性** > **局域网**。
3. 在列表中找到 Google Chrome 和 Google Chrome Helper并开启开关。
![启用局域网权限](/images/manual/larepass/mac-chrome-local-access.png#bordered){width=400}
4. 重启 Chrome 并再次尝试访问本地 URL。
### 为什么在 Chrome 上使用 `.local` 域名时,应用无法在 iFrame 中加载 (macOS)
使用本地域名时Chrome 可能会默认使用 HTTPS你可能会看到“连接不安全”的警告。
![本地地址错误](/images/manual/get-started/incorrect-local-address.png#bordered)
要解决此问题,在 URL 开头显式添加 HTTP 协议头 (`http://`),告诉浏览器这是一个仅在本地网络中使用的链接。
<!--@include: ../../reusables/local-domain.md{42,75}-->

View File

@@ -1,81 +1,48 @@
---
outline: [2,3]
description: 了解如何使用 LarePass VPN 安全访问 Olares 服务。
description: 了解如何使用 LarePass VPN 或 .local 域名安全访问 Olares 服务。
---
# 使用 LarePass VPN 安全访问 Olares 服务
# 安全访问 Olares 服务
通常,你会使用类似 `https://desktop.<username>.olares.cn` 的网址在浏览器中访问 Olares。这种方式允许你在任何设备上随时随地访问服务。
通常,你会通过浏览器使用类似 `https://desktop.<username>.olares.com` 的网址访问 Olares,从而在任何设备上随时访问服务。你可以从家庭网络或外网安全访问 Olares。
虽然该地址可从任意网络访问,但为了获得更安全、高效的连接,建议启用 LarePass VPN。客户端会自动检测网络环境并智能切换连接模式
- **居家**:建立直连内网通道,大幅提升局域网文件传输速度
- **远程**:切换至加密安全隧道,保障远程访问的数据安全。
- [使用 LarePass VPN](#使用-larepass-vpn):无论在内网还是外网均可使用。
- [使用 .local 域名](#使用-local-域名):仅当客户端设备与 Olares 在同一局域网时使用
## 下载 LarePass
要使用安全 VPN 连接,需先在当前设备上安装 LarePass 客户端。
- **移动端**:使用在创建 Olares ID 过程中安装的 LarePass 移动端。
- **桌面端**:下载并安装 LarePass 桌面客户端。
## 使用 LarePass VPN
1. 访问 <AppLinkCN />。
2. 下载对应操作系统的版本。
建议启用 LarePass VPN以获得更安全、高效的连接。客户端会自动检测网络环境并选择最佳连接方式
## 启用 LarePass VPN
安装完成后,在当前设备上启用 VPN
- **居家**:建立直连内网,加快局域网文件传输。
- **远程**:切换至加密隧道,保障远程访问安全
:::tip 始终启用 VPN 以进行远程访问
建议保持 LarePass VPN 开启。系统会自动优选最佳路由,让你无需手动切换即可确保持续获得最快速度。
:::
:::info iOS 和 macOS 设置
首次在 iOS 或 macOS 上开启此功能时,系统可能会弹窗请求添加 VPN 配置。允许此操作以完成设置。
:::
<!--@include: ../../reusables/larepass-vpn.md{19,24}-->
<tabs>
<template #使用-LarePass-移动端>
在用来访问 Olares 的当前设备上直接启用 LarePass VPN。
1. 打开 LarePass 应用,进入**设置**。
2. 在**我的 Olares** 卡片中,打开 VPN 开关。
<!--@include: ../../reusables/larepass-vpn.md{26,50}-->
![移动端开启 LarePass VPN](/images/zh/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #使用-LarePass-桌面端>
## 使用 .local 域名
1. 打开 LarePass 应用,点击左上角的头像打开用户菜单
2. 打开**专用网络连接**开关。
当设备与 Olares 在同一局域网时,可使用 .local 域名
![桌面端开启 LarePass VPN](/images/zh/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
### URL 格式
## 确认连接状态
开启后,查看 LarePass 中的状态标签来确认当前的连接模式:
<!--@include: ../../reusables/local-domain.md{7,23}-->
| 状态 | 描述 |
|:-----------|:---------------------------|
| **内网** | 通过本地局域网 IP 直连。速度最快。 |
| **P2P** | 设备间的直接加密隧道。连接速度快。 |
| **DERP** | 通过安全中继服务器路由,仅在无法直连时作为备用方案。 |
### macOS
## 常见问题
### 为什么在 Mac 上无法再启用 LarePass VPN
如果之前成功启用过 VPN但现在停止工作可能需要重置系统扩展。
:::info
根据 macOS 版本不同,界面可能略有差异。
:::
1. 打开**系统设置**,搜索`扩展`,选择**登录项与扩展**。
2. 滚动到**网络扩展** 部分,点击信息图标 (ⓘ) 查看已加载的扩展。
3. 找到 LarePass点击三个点 (...),选择**删除扩展**。
4. 确认卸载。
5. 重启 Mac 并在 LarePass 桌面客户端中重新启用 VPN。
无需配置。在浏览器中直接使用本地 URL例如 `http://desktop.<username>.olares.local`)。
### 为什么我在 Windows 上无法启用 LarePass VPN
第三方杀毒软件可能会错误地将 LarePass 桌面客户端标记为可疑,从而阻止其启动 VPN 服务。
### Windows
<!--@include: ../../reusables/local-domain.md{26,40}-->
如果在首次打开 LarePass 时收到杀毒软件提示,请允许应用程序继续运行。
### 常见问题
如果 VPN 仍然无法启用:
1. 打开安全软件,检查 LarePass 是否被拦截。
2. 将 LarePass 主程序添加到杀毒软件的白名单或排除项中。
3. 重启 LarePass 并启用 VPN。
<!--@include: ../../reusables/larepass-vpn.md{50,75}-->
<!--@include: ../../reusables/local-domain.md{42,75}-->
## 了解更多
- [本地访问 Olares 服务](../best-practices/local-access.md)了解所有 Olares 本地连接方式
- [网络](../../../zh/developer/concepts/network.md):了解 Olares 中的应用的各类入口。
- [本地访问 Olares 服务](../best-practices/local-access.md)查看所有本地网络连接方式的详细说明
- [网络](../../developer/concepts/network.md):了解 Olares 中的各类应用入口。

View File

@@ -0,0 +1,41 @@
---
outline: [2, 3]
description: Learn how to access your Olares services on the same network using the `.local` domain.
head:
- - meta
- name: keywords
content: Olares, .local domain, local access
---
# Access Olares via .local domain
When your computer or phone is on the same local network as Olares One, you can use a `.local` domain to reach your Olares services so traffic stays on your LAN.
## Prerequisites
**Hardware**
- Olares One is set up and connected to your network.
- A client device (computer or phone) on the same network as Olares One.
**LarePass** (Required for Windows)
- The LarePass desktop client is installed on your Windows device.
- You have imported your Olares ID on the LarePass desktop client.
## URL format
<!--@include: ../../reusables/local-domain.md{10,23}-->
## macOS
No setup is needed. Use the local URL in your browser (for example, `http://desktop.<username>.olares.local`).
## Windows
<!--@include: ../../reusables/local-domain.md{26,40}-->
## Troubleshooting
<!--@include: ../../reusables/local-domain.md{42,75}-->
## Learn more
- [Access Olares services locally](../manual/best-practices/local-access.md): DNS configuration, hosts file, and other local access methods.

View File

@@ -21,75 +21,17 @@ While this address works from anywhere, it's recommended to enable the LarePass
- A client device (computer or mobile phone) with internet access.
## Step 1: Download LarePass
To use the secure VPN connection, the LarePass client must be installed on the device you are using to access Olares.
- **Mobile**: Use the LarePass app installed during the Olares ID creation process.
- **Desktop**: Download and install the LarePass desktop client.
1. Visit <AppLinkGlobal />.
2. Download the version compatible with your operating system.
3. Install the application and log in with your Olares ID.
<!--@include: ../../reusables/larepass-vpn.md{7,16}-->
## Step 2: Enable LarePass VPN
Once installed, enable the VPN directly on the device.
:::tip Always enable VPN for remote access
Keep LarePass VPN enabled. It automatically prioritizes the fastest available route to ensure you always get the best speed possible without manual switching.
:::
:::info iOS and macOS setup
On iOS or macOS, you may be prompted to add a VPN Configuration to your system settings the first time you enable the feature. Allow this to complete the setup.
:::
<tabs>
<template #On-LarePass-mobile-client>
1. Open the LarePass app and go to **Settings**.
2. In the **My Olares** card, toggle on the VPN switch.
![Enable LarePass VPN on mobile](/images/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #On-LarePass-desktop-client>
1. Open the LarePass app and click your avatar in the top-left corner to open the user menu.
2. Toggle on the switch for **VPN connection**.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
<!--@include: ../../reusables/larepass-vpn.md{18,41}-->
## Step 3: Verify the connection type
Once enabled, check the status indicator in LarePass to confirm how you are connected:
| Status | Description |
|:-------------|:---------------------------------------------------------|
| **Intranet** | Direct connection via your local LAN IP. Fastest speeds. |
| **P2P** | Direct encrypted tunnel between devices. High speed. |
| **DERP** | Routed via a secure relay server. Used as a fallback. |
<!--@include: ../../reusables/larepass-vpn.md{42,49}-->
## Troubleshooting
### Why doesn't LarePass VPN work on my Mac anymore?
If the VPN was working previously but has stopped, you might need to reset the system extension.
:::info
Depending on your macOS version, the UI might look slightly different.
:::
1. Open System Settings, search for "Extension", and select **Login Items & Extensions**.
2. Scroll to the **Network Extensions** section and click the info icon (ⓘ) to view loaded extensions.
3. Find LarePass, click the three dots (...), and select **Delete Extension**.
4. Restart your Mac.
5. Open the LarePass desktop client and re-enable the VPN.
### Why can't I enable LarePass VPN on Windows?
Third-party antivirus software may mistakenly flag the LarePass client, blocking the VPN service.
If prompted by your antivirus when opening LarePass for the first time, allow the application to continue.
If the VPN still fails to enable:
1. Check your antivirus software to see if LarePass was blocked.
2. Add the main LarePass executable to the allowlist or exclusions of your antivirus.
3. Restart LarePass and try enabling the VPN again.
## Learn more
- [Access Olares locally](../manual/best-practices/local-access.md): Explore detailed instructions for all available local network connection methods.
- [Access Olares terminal](access-terminal-ssh.md): Learn how to connect to the host shell using SSH or the Control Hub web terminal.
- [Network](../developer/concepts/network.md): Learn about the different entry points in Olares.
<!--@include: ../../reusables/larepass-vpn.md{50,74}-->

View File

@@ -17,14 +17,6 @@ You can connect to the host shell using one of the following methods:
- **Control Hub Terminal** is a web-based interface for direct root access. It is recommended for quick tasks.
- **Secure Shell (SSH)** is the standard protocol for remote management and complex operations.
## Before you begin
- The default username and password for Olares One are both `olares`.
:::warning Reset default SSH password
Even if you primarily use the Control Hub terminal, you must reset this password immediately in **Settings** > **My hardware** to secure your device against unauthorized access.
:::
- SSH access grants powerful control over the system. Ensure you keep your credentials secure.
## Prerequisites
**Hardware**
- Your Olares One is set up and connected to a network.
@@ -33,9 +25,6 @@ You can connect to the host shell using one of the following methods:
**Experience**
- Basic familiarity with terminal commands and the command-line interface (CLI).
**LarePass** (Required for remote access)
- The LarePass app is installed on your device. This is required only if you plan to connect via SSH from a remote location outside your local network.
## Method 1: Access via Control Hub
For quick access without configuring SSH clients, you can use the web-based terminal built directly into Control Hub.
@@ -53,7 +42,7 @@ The Control Hub terminal runs as `root` by default. You do not need to use `sudo
SSH establishes a secure session over the network, allowing you to use command-line operations for Olares One on your current device.
### Get IP address of Olares One
### Step 1: Get IP address of Olares One
To connect via SSH, you first need to find the internal IP address of your Olares One.
1. Open the LarePass app, and go to **Settings** > **System** to navigate to the **Olares management** page.
@@ -67,43 +56,20 @@ You can check the IP using the `ifconfig` command in the Control Hub terminal.
Look for your active connection, typically named `enp3s0` (wired) or `wlo1` (wireless). The IP address follows `inet`.
:::
### Connect via SSH (local network)
If your computer and the Olares One are on the same Wi-Fi or LAN:
### Step 2: Check SSH password in Vault
<!--@include: ./reusables-reset-ssh.md{7,16}-->
### Step 3: Connect via SSH
1. Open a terminal on your computer.
2. Run the `ssh` command using Olares One's local IP address:
```bash
ssh <username>@<host_ip_address>
# The default username for Olares One is olares.
ssh olares@<host_ip_address>
```
For example:
3. Enter the password when prompted.
```bash
ssh olares@192.168.31.155
```
3. Enter the host password when prompted.
### Connect via SSH (remote access)
If you are away from home, you can use LarePass VPN to bridge the connection securely.
#### Allow SSH access via VPN
For security, SSH access via VPN is disabled by default. You must enable it once.
1. On Olares, open the Settings app.
2. Navigate to **VPN**.
3. Toggle on **Allow SSH via VPN**.
#### Enable LarePass VPN
1. Open the LarePass desktop client on your computer.
2. Click your avatar in the top-left corner and toggle on **VPN connection**.
![Enable LarePass VPN on desktop](/images/manual/get-started/larepass-vpn-desktop.png#bordered)
3. Open a terminal on your computer.
4. Run the `ssh` command using Olares One's local IP address. LarePass handles the routing automatically.
```bash
ssh <username>@<host_ip_address>
```
For example:
```bash
ssh olares@192.168.31.155
```
5. Enter the host password when prompted.
## Reset SSH password
<!--@include: ./reusables-reset-ssh.md{19,}-->

View File

@@ -1,65 +1,81 @@
---
outline: [2, 3]
description: Learn how to create a bootable USB installer for Olares OS using balenaEtcher.
description: Reinstall Olares OS on Olares One using a bootable USB to restore the device to factory state.
head:
- - meta
- name: keywords
content: Olares, Olares One, install Olares, bootable USB, ISO, balenaEtcher
content: Olares One, reinstall, factory reset, bootable USB, installation USB
---
# Create a bootable USB drive <Badge type="tip" text="15 min"/>
# Reset to factory settings using installation USB <Badge type="tip" text="15 min"/>
To reinstall or recover Olares OS on your Olares One, you must create a bootable USB installation drive. This drive allows you to reset the device to its factory state.
Resetting to factory settings returns your Olares One to the initial setup state. You can reinstall Olares OS using the bootable USB drive included with Olares One.
:::warning Data loss warning
This process will erase all data on your USB drive. If you have important files on the drive, back them up before proceeding.
:::
:::warning Image compatibility
Olares One requires a specific system image designed for its hardware. If you install the generic self-hosted ISO, Olares One will fail to boot.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
:::
## Prerequisites
- USB flash drive: A drive with 8 GB or higher capacity.
:::info
Ensure that your USB drive is empty or backed up. The flashing process re-formats the drive, which means existing data on it will be permanently deleted.
:::
- Computer: A Windows, macOS, or Linux computer to perform the setup.
- Internet connection: Stable network for downloading the image file and related software.
**Hardware**<br>
- The bootable USB drive that came with Olares One.
- A monitor and keyboard connected to Olares One.
## Step 1. Download Olares image
## Step 1: Boot from the USB drive
Click to download the [ISO image for Olares One](https://cdn.olares.com/one/olares.iso). The file `olares.iso` will be saved to your computer.
1. Insert the bootable USB drive into Olares One.
2. Power on Olares One or restart it if it is already running.
3. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
## Step 2. Install flashing tool
4. Navigate to the **Boot** tab, set **Boot Option #1** to the USB drive, and then press **Enter**.
![Set boot option](/images/one/bios-set-boot-option.png#bordered)
It is recommended to use balenaEtcher for this task because it is free, easy to use, and works on all major operating systems.
5. Press **F10**, then select **Yes** to save and exit.
![Save and exit](/images/one/bios-save-usb-boot.png#bordered)
1. Go to the [balenaEtcher website](https://etcher.balena.io/).
2. Download and install the version appropriate for your computer (Windows, macOS, or Linux).
## Step 3. Flash the drive
Olares One will restart and boot into the Olares installer interface.
Use balenaEtcher to turn your USB stick into a bootable installer.
## Step 2: Install Olares to disk
1. Insert your USB flash drive into the computer.
2. Open balenaEtcher.
3. Follow the steps on the screen:
1. From the installer interface, select **Install Olares to Hard Disk** and press **Enter**.
![Olares installer](/images/one/olares-installer.png#bordered)
a. Click **Flash from file** and select the Olares ISO file you downloaded.
2. When prompted for the installation target, the installer shows a list of available disks. Type `/dev/` followed by the disk name (e.g. `nvme0n1`) from that list and press **Enter**.
![Select disk](/images/one/olares-installer-select-disk.png#bordered)
b. Click **Select target** and select your USB drive.
For example, to install to `nvme0n1`, enter:
```bash
/dev/nvme0n1
```
c. Click **Flash!** to start writing the installer to the USB drive.
3. When you see prompts about NVIDIA GPU drivers, press **Enter** to accept the default.
![Install NVIDIA drivers](/images/one/olares-installer-install-nvidia-drivers.png#bordered)
![Bootable USB](/images/one/balenaEtcher.png#bordered)
4. When you see the message below, the reinstallation is complete:
```bash
Installation completed successfully!
```
4. When the flashing process is completed, the USB drive is ready to use, and you can safely eject it.
5. Remove the USB drive, then press **Ctrl + Alt + Delete** to restart.
## Next steps
## Step 3: Verify the installation
You can now insert the bootable USB drive into Olares One or other target hardware to begin the installation.
After the reboot, the system starts in a clean factory state and shows a text-based Ubuntu login prompt.
## Resources
1. Log in with the default credentials:
- **Username**: `olares`
- **Password**: `olares`
![Log in](/images/one/olares-login.png#bordered)
- [Install Olares via ISO](../manual/get-started/install-linux-iso.md)
- [Install Olares](../manual/get-started/install-olares.md)
- [Installation FAQs](../manual/help/installation.md)
2. (Optional) Run the following command to verify the installation:
```bash
sudo olares-check
```
Example output:
![Olares check](/images/one/olares-check.png#bordered)
## Step 4: Complete activation via LarePass
You can then activate Olares One again via LarePass. For detailed instructions, see [First boot](first-boot.md).

View File

@@ -21,15 +21,16 @@ This dual-drive configuration physically isolates the systems. This ensures Olar
## Step 1: Boot into BIOS
1. Insert the Windows USB boot drive into a USB port on Olares One.
2. Power on Olares One or restart if it is already running.
3. Immediately press and hold the **Delete** key repeatedly until the BIOS setup screen appears.
2. Power on Olares One or restart it if it is already running.
3. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
## Step 2: Boot from USB
1. Navigate to the **Boot** tab using the arrow keys on your keyboard.
2. Locate **Boot Option #1** or **Boot Override** and select your USB flash drive.
3. Press **Enter** to boot from the USB drive immediately.
4. The system will restart and load the Windows installation interface.
2. Set **Boot Option #1** to your Windows USB flash drive, and press **Enter**.
3. Press **F10**, then select **Yes** to save and exit BIOS.
4. The system restarts and boots from the USB drive into the Windows installation interface.
## Step 3: Install Windows
1. Follow the on-screen prompts to begin the Windows installation.
@@ -49,16 +50,16 @@ Because the operating systems are on separate physical drives, you switch betwee
### Switch to Olares OS
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Go to the **Boot** tab.
4. Set **Boot Option #1** to the SSD containing Olares OS.
5. Press **F4** to confirm.
5. Press **F10** to save and exit BIOS.
### Switch to Windows
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Set **Boot Option #1** to the secondary SSD containing Windows.
4. Press **F4** to confirm.
4. Press **F10** to save and exit BIOS.
## Resources
- [Install NVIDIA drivers on Windows](install-nvidia-driver.md)

View File

@@ -34,11 +34,13 @@ Partitioning a drive carries a risk of data loss. If you have important data on
## Step 1: Install Windows
1. Insert the Windows USB boot drive into a USB port on Olares One.
2. Power on Olares One or restart if it is already running.
3. Immediately press and hold the **Delete** key repeatedly until the BIOS setup screen appears.
2. Power on Olares One or restart it if it is already running.
3. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
4. Navigate to the **Boot** tab using the arrow keys on your keyboard.
5. Locate **Boot Option #1** or **Boot Override** and select your USB flash drive.
6. Press **Enter** to boot from the USB drive immediately.
5. Set **Boot Option #1** to your Windows USB flash drive, and press **Enter**.
6. Press **F10**, then select **Yes** to save and exit BIOS. The system restarts and boots from the USB drive into the Windows installation interface.
7. Follow the on-screen prompts to begin the Windows installation.
8. When the installation finishes and the system restarts, unplug the Windows USB drive.
@@ -59,13 +61,14 @@ The system will boot into Windows automatically.
Olares OS runs on top of a Linux kernel. You will install Ubuntu to serve as the host system.
1. Insert the Ubuntu USB drive and restart Olares One.
2. Press **Delete** repeatedly to enter BIOS, then select the USB drive as the boot device.
3. Follow the installer prompts until you reach the **Installation type** screen.
4. Select **Install Ubuntu alongside Windows Boot Manager**.
2. When the Olares logo appears, press the **Delete** key repeatedly to enter **BIOS setup**.
3. Navigate to the **Boot** tab, set **Boot Option #1** to your Ubuntu USB flash drive, and then press **Enter**.
4. Press **F10**, then select **Yes** to save and exit BIOS. The system restarts and boots from the USB drive into the Ubuntu installer.
5. Follow the installer prompts until you reach the **Installation type** screen.
:::tip
If this option does not appear, select the manual installation option to manually assign the unallocated space to Ubuntu.
:::
5. When the installation finishes and the system restarts, unplug the Ubuntu USB drive.
6. When the installation finishes and the system restarts, unplug the Ubuntu USB drive.
The system will boot into Ubuntu automatically.
@@ -120,17 +123,17 @@ After setup is complete, the LarePass app returns to the home screen, and the br
You switch between Windows and Olares using the BIOS boot priority.
### Switch to Olares OS
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Go to the **Boot** tab.
4. Set **Boot Override** to Ubuntu.
5. Press **F4** to confirm.
5. Press **F10** to save and exit BIOS.
### Switch to Windows
1. Restart Olares One.
2. Press **Delete** repeatedly to enter BIOS.
2. Press the **Delete** key repeatedly to enter **BIOS setup**.
3. Go to the **Boot** tab.
4. Set **Boot Override** to Windows.
5. Press **F4** to confirm.
5. Press **F10** to save and exit BIOS.
## Troubleshooting

View File

@@ -0,0 +1,39 @@
---
outline: [2, 3]
description: Learn how to restore your Olares One to factory settings in BIOS.
head:
- - meta
- name: keywords
content: Factory reset, Olares One, BIOS
---
# Reset to factory settings in BIOS <Badge type="tip" text="10 min" />
Resetting to factory settings returns your Olares One to its initial setup state. If you have a monitor and keyboard connected, you can perform this reset directly in BIOS instead of using LarePass.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
:::
## Prerequisites
**Hardware**<br>
- A wired keyboard connected to your Olares One.
- A monitor connected to your Olares One.
## Step 1: Load optimized defaults in BIOS
1. Power on Olares One or restart it if it is already running.
2. When the Olares logo appears, immediately press the **Delete** key repeatedly to enter **BIOS setup**.
![BIOS setup](/images/one/bios-setup.png#bordered)
3. Press **F9**, then select **Yes** to restore factory settings.
![Load optimized defaults](/images/one/bios-load-optimized-defaults.png#bordered)
4. Press **F10**, then select **Yes** to save and exit. The device restarts automatically.
![Save and exit](/images/one/bios-save-load-defaults.png#bordered)
Once finished, Olares One reboots into the initial setup phase.
## Step 2: Complete activation via LarePass
You can then activate Olares One again via LarePass. For detailed instructions, see [First boot](first-boot.md).

View File

@@ -6,23 +6,17 @@ head:
- name: keywords
content: Factory reset, Olares One
---
# Reset to factory settings <Badge type="tip" text="10 min" />
# Reset to factory settings using LarePass <Badge type="tip" text="10 min" />
Resetting to factory settings returns your Olares One to the initial setup state.
If you have already activated Olares One and want to return it to the factory state, you can perform a reset in LarePass.
:::warning Data loss
This will permanently delete all accounts, settings, and data on the device. This action cannot be undone.
:::
## Learning objectives
By the end of this tutorial, you will learn how to:
- Perform a factory reset from LarePass.
- Complete the required confirmation and local password verification.
## Prerequisites
Before starting, ensure that:
**Hardware**<br>
- Olares One is powered on.
- Your phone and Olares One are on the same network.
- You are signed in to LarePass as an administrator.
@@ -30,15 +24,17 @@ Before starting, ensure that:
## Reset Olares One to factory settings
1. Open LarePass on your phone and go to **Settings**.
2. In the **My Olares** card, tap **System** to enter the **Olares management** page.
2. In the **My Olares** card, tap **System** to open the **Olares management** page.
3. Tap **Restore to factory settings**.
4. Review the risk prompt, then tap **Restore to factory settings** to continue.
4. Review the risk prompt carefully, then tap **Restore to factory settings** to continue.
![Review risk prompt](/images/manual/larepass/review-risk-prompt.png#bordered)
5. Enter your local LarePass lock screen password and tap **Confirm**.
5. Enter your local LarePass lock-screen password and tap **Confirm**.
![Enter local unlock password](/images/manual/larepass/enter-password-to-uninstall.png#bordered)
If you have not set a local password, you will be prompted to set one first.
6. Wait for the reset process to complete.
Once finished, Olares One reboots into the initial setup phase. You will be redirected to the activation flow, where you can scan the local network to reinstall or reactivate Olares.
Once finished, Olares One reboots into the initial setup phase. You are redirected to the activation flow, where you can scan the local network to reactivate Olares.
For detailed instructions, see [First boot](first-boot.md).

View File

@@ -89,21 +89,17 @@ Your Olares ID is secured by a unique 12-word mnemonic phrase. This phrase is th
4. Enter the local password as prompted.
5. Write the 12 words onto the **Recovery Sheet**, and then store the sheet in a secure, offline location.
### Reset SSH password
<!--@include: ./reusables-reset-ssh.md{7,16}-->
For instructions on how to SSH into Olares One, see [Connect to Olares One via SSH](access-terminal-ssh.md).
### Access Olares services securely
For secure remote access without complex network configuration, it is recommended to enable the LarePass VPN.
See [Access Olares services securely using LarePass VPN](access-olares-via-vpn.md).
### Reset SSH password
If you plan to connect to your Olares One via terminal (SSH), you must update the default SSH password.
1. Open Olares Settings, on the **My hardware** page, click **Reset SSH password**.
2. In the dialog, enter a new SSH password that meets all strength requirements, then click **OK**.
3. Open the LarePass app and scan the QR code shown on the screen.
4. Click **Confirm** on LarePass to finish.
For details, see [Connect to Olares One via SSH](access-terminal-ssh.md).
### Explore
Olares OS comes with pre-installed system apps. You can also browse the **Market** to download additional applications that best suit your needs.

View File

@@ -0,0 +1,27 @@
---
search: false
---
## Reset SSH password
### Reset upon activation
Right after you activate Olares, you will be prompted to reset the SSH password on the LarePass app. The password is automatically generated and saved to your Vault.
To view the saved password in Vault:
1. Tap **Vault** in the LarePass app. When prompted, enter your local password to unlock.
2. In the top-left corner, tap **Authenticator** to open the side navigation, then tap **All vaults** to display all saved items.
![Switch Vault filter](/images/one/ssh-switch-filter.png#bordered)
3. Find the item with the <span class="material-symbols-outlined">terminal</span> icon and tap it to reveal the password.
![Check saved SSH password in Vault](/images/one/ssh-check-password-in-vault.png#bordered)
### Reset in Olares Settings
If you prefer to use an SSH password instead of the automatically generated one, you can manually reset the password in Settings.
1. Open Settings. On the **My Olares** page, select **My hardware**.
2. Select **Reset SSH login password** at the bottom.
![Reset SSH login password](/images/one/ssh-reset-password-in-settings.png#bordered){width=70%}
3. In the dialog, enter a new SSH password that meets all strength requirements, then click **OK**.
4. Open the LarePass app and scan the QR code shown on the screen.
5. Click **Confirm** on LarePass to finish.

View File

@@ -0,0 +1,8 @@
# Reusables可复用片段
本目录存放通过 `<!--@include: path/to/reusables/file.md{start,end}-->` 在多个文档中引用的共享内容。
- **local-domain.md**`.local` 域名说明、URL 格式、HTTP 说明及故障排除Chrome、Safari。被 `manual/get-started/local-access.md``manual/best-practices/local-access.md` 引用。
- **larepass-vpn.md**LarePass VPN 步骤下载、启用、确认连接类型及常见问题Mac 扩展重置、Windows 杀毒软件)。被 `manual/get-started/local-access.md``manual/best-practices/local-access.md` 引用。
在各文件顶部注释中注明可引用的行号范围。

View File

@@ -0,0 +1,74 @@
---
search: false
---
<!-- 可复用的 LarePass VPN 内容。按行号范围引用。
步骤无标题Step 1 7-16Step 2 18-41Step 3 42-49。
常见问题50-75 -->
要使用安全 VPN 连接,必须在用来访问 Olares 的设备上安装 LarePass 客户端。
- **移动端**:使用在创建 Olares ID 时安装的 LarePass 应用。
- **桌面端**:下载并安装 LarePass 桌面客户端。
1. 访问 <AppLinkCN />。
2. 下载与当前操作系统匹配的版本。
3. 安装应用并使用 Olares ID 登录。
安装完成后,在设备上直接启用 VPN。
:::tip 始终启用 VPN 以进行远程访问
保持 LarePass VPN 开启。它会自动优先选择最快可用路由,无需手动切换即可获得最佳速度。
:::
:::info iOS 和 macOS 设置
首次在 iOS 或 macOS 上启用时,系统可能会提示添加 VPN 配置。选择允许以完成设置。
:::
<tabs>
<template #使用-LarePass-移动端>
1. 打开 LarePass 应用,进入**设置**。
2. 在**我的 Olares** 卡片中,打开 VPN 开关。
![移动端开启 LarePass VPN](/images/zh/manual/get-started/larepass-vpn-mobile.png#bordered)
</template>
<template #使用-LarePass-桌面端>
1. 打开 LarePass 应用,点击左上角头像打开用户菜单。
2. 打开**专用网络连接**开关。
![桌面端开启 LarePass VPN](/images/zh/manual/get-started/larepass-vpn-desktop.png#bordered)
</template>
</tabs>
启用后,在 LarePass 中查看状态指示以确认连接类型:
| 状态 | 描述 |
|:-----------|:--------------------------------------------------|
| **内网** | 通过本地局域网 IP 直连,速度最快。 |
| **P2P** | 设备间直接加密隧道,速度较快。 |
| **DERP** | 经安全中继服务器路由,作为备用。 |
### 为什么在 Mac 上无法再启用 LarePass VPN
如果之前能正常启用 VPN 但现在失效,可能需要重置系统扩展。
:::info
不同 macOS 版本下界面可能略有差异。
:::
1. 打开**系统设置**,搜索“扩展”,选择**登录项与扩展**。
2. 滚动到**网络扩展**,点击信息图标 (ⓘ) 查看已加载的扩展。
3. 找到 LarePass点击三点 (...),选择**删除扩展**。
4. 确认卸载。
5. 重启 Mac在 LarePass 桌面客户端中重新启用 VPN。
### 为什么在 Windows 上无法启用 LarePass VPN
第三方杀毒软件可能误将 LarePass 桌面客户端标记为可疑,导致无法启动 VPN 服务。
首次打开 LarePass 时如果杀毒软件有提示,选择允许应用继续运行。
如果 VPN 仍然无法启用:
1. 打开安全软件,查看是否拦截了 LarePass。
2. 将 LarePass 主程序加入杀毒软件的白名单或排除项。
3. 重启 LarePass 并再次启用 VPN。

View File

@@ -0,0 +1,73 @@
---
search: false
---
<!-- 可复用的 .local 域名内容。按行号范围引用。
顺序描述、URL+HTTP、Windows、常见问题。
范围:描述 7-8URL+HTTP 10-23Windows 25-40仅正文 26-40常见问题 42-75 -->
当设备与 Olares 在同一局域网时,可使用 `.local` 域名访问服务,使流量保持在本地网络。
使用与标准 URL 结构一致的多级 `.local` 主机名。此格式适用于 Olares 系统应用和社区应用。
:::tip
使用 `.local` URL 时使用 `http://`,不要使用 `https://`
:::
**标准 URL**
```text
https://<entrance_id>.<username>.olares.com
```
**本地 URL**
```text
http://<entrance_id>.<username>.olares.local
```
### Windows
在 Windows 上,`.local` 主机名默认不会解析。使用 LarePass 桌面端在 hosts 文件中添加所需条目,使多级 `.local` URL 解析到你的 Olares 设备。
1. 打开 LarePass 应用,点击头像,选择**设置**。
2. 找到**启用本地服务域名**并点击**添加**。LarePass 会自动更新 hosts 文件。
![启用本地服务域名](/images/one/larepass-win-update-hosts.png#bordered)
3. 更新完成后会显示成功提示。如果弹出命令行窗口,直接关闭。
4. (可选)要验证 hosts 变更:
a. 进入 `C:\Windows\System32\drivers\etc\`
b. 用记事本打开 `hosts` 文件,可以看到 LarePass 添加的 `.local` 条目。
![LarePass 更新后的 hosts 文件](/images/one/larepass-updated-hosts.png#bordered)
### 为什么在 macOS 的 Chrome 中 .local 域名无法使用?
如果 macOS 没有授予 Chrome 本地网络访问权限Chrome 可能会拦截本地 URL。
1. 打开 Apple 菜单,进入**系统设置**。
2. 进入**隐私与安全性** > **本地网络**
3. 找到 **Google Chrome****Google Chrome Helper**,打开其开关。
4. 重启 Chrome 后再次尝试 `.local` URL。
![启用本地网络](/images/manual/larepass/mac-chrome-local-access.png#bordered){width=400}
### 为什么应用显示“连接不安全”或在 Chrome 中无法加载?
Chrome 有时会强制对 `.local` 主机名使用 HTTPS而本地并不支持。
在 URL 开头显式使用 `http://`(例如 `http://desktop.<username>.olares.local`)。在家庭网络中,这类未加密本地连接是预期行为,能保证 `.local` 域名正常使用。
![错误的本地地址](/images/manual/get-started/incorrect-local-address.png#bordered)
### 为什么在 Safari 中打开 .local URL 时 iframe 会闪烁?
Safari 对 iframe 中的 `.local` 及其他非 HTTPS 内容处理更严格,可能导致 iframe 闪烁或重载。在**隐私**设置中启用下面两个选项即可解决。
解决方法:
1. 打开 **Safari**,进入**设置**。
2. 打开**隐私**标签页。
3. 启用下面两个选项:
- 防止跨站跟踪
- 对跟踪器隐藏 IP 地址
![Safari 隐私设置(.local](/images/manual/get-started/safari-privacy-settings.png#bordered){width=70%}
4. 重新加载 `.local` 页面。

View File

@@ -3,5 +3,5 @@ target: prebuilt
output:
containers:
-
name: beclab/l4-bfl-proxy:v0.3.11
# must have blank new line
name: beclab/l4-bfl-proxy:v0.3.12
# must have blank new line

View File

@@ -371,87 +371,96 @@ func (s *Server) lookupHostAddr(svc string) (string, error) {
return "", fmt.Errorf("svc %s, no host lookup", svc)
}
func (s *Server) listApplications() ([]string, []string, []string) {
func (s *Server) listApplications() ([]string, []string, []string, map[string][]string) {
publicApps := []string{"headscale"} // hardcode headscale appid
var publicCustomDomainApps []string
var customDomainApps []string
var customDomainAppsWithUsers = make(map[string][]string)
// DEPRECATED:
//
// list, err := s.client.Resource(appGVR).List(context.TODO(), metav1.ListOptions{})
// if err != nil {
// return nil, nil, nil
// }
list, err := s.client.Resource(appGVR).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return nil, nil, nil, nil
}
// data, err := list.MarshalJSON()
// if err != nil {
// return nil, nil, nil
// }
data, err := list.MarshalJSON()
if err != nil {
return nil, nil, nil, nil
}
// var appList appv2alpha1.ApplicationList
// if err = json.Unmarshal(data, &appList); err != nil {
// return nil, nil, nil
// }
var appList appv2alpha1.ApplicationList
if err = json.Unmarshal(data, &appList); err != nil {
return nil, nil, nil, nil
}
// getAppPrefix := func(entrancecount, index int, appid string) string {
// if entrancecount == 1 {
// return appid
// }
// return fmt.Sprintf("%s%d", appid, index)
// }
getAppPrefix := func(entrancecount, index int, appid string) string {
if entrancecount == 1 {
return appid
}
return fmt.Sprintf("%s%d", appid, index)
}
// for _, app := range appList.Items {
// if len(app.Spec.Entrances) == 0 {
// continue
// }
for _, app := range appList.Items {
if len(app.Spec.Entrances) == 0 {
continue
}
// var customDomains []string
// var customDomainsPrefix []string
// var entrancecounts = len(app.Spec.Entrances)
var customDomains []string
var customDomainsPrefix []string
var entrancecounts = len(app.Spec.Entrances)
var name = app.Spec.Owner
// for index, entrance := range app.Spec.Entrances {
// prefix := getAppPrefix(entrancecounts, index, app.Spec.Appid)
for index, entrance := range app.Spec.Entrances {
prefix := getAppPrefix(entrancecounts, index, app.Spec.Appid)
// customDomainEntrancesMap := getSettingsKeyMap(&app, settingsCustomDomain)
// entranceAuthorizationLevel := entrance.AuthLevel
customDomainEntrancesMap := getSettingsKeyMap(&app, settingsCustomDomain)
entranceAuthorizationLevel := entrance.AuthLevel
// customDomainEntrance, ok := customDomainEntrancesMap[entrance.Name]
// if ok {
// if entrancePrefix := customDomainEntrance[settingsCustomDomainThirdLevelDomain]; entrancePrefix != "" {
// if entranceAuthorizationLevel == ApplicationAuthorizationLevelPublic {
// customDomainsPrefix = append(customDomainsPrefix, entrancePrefix)
// }
// }
// if entranceCustomDomain := customDomainEntrance[settingsCustomDomainThirdPartyDomain]; entranceCustomDomain != "" {
// customDomainApps = append(customDomainApps, entranceCustomDomain)
customDomainEntrance, ok := customDomainEntrancesMap[entrance.Name]
if ok {
if entrancePrefix := customDomainEntrance[settingsCustomDomainThirdLevelDomain]; entrancePrefix != "" {
if entranceAuthorizationLevel == ApplicationAuthorizationLevelPublic {
customDomainsPrefix = append(customDomainsPrefix, entrancePrefix)
}
}
if entranceCustomDomain := customDomainEntrance[settingsCustomDomainThirdPartyDomain]; entranceCustomDomain != "" {
customDomainApps = append(customDomainApps, entranceCustomDomain)
// if entranceAuthorizationLevel == ApplicationAuthorizationLevelPublic {
// customDomains = append(customDomains, entranceCustomDomain)
// }
// }
// }
val, userExists := customDomainAppsWithUsers[name]
if !userExists {
customDomainAppsWithUsers[name] = []string{entranceCustomDomain}
} else {
val = append(val, entranceCustomDomain)
customDomainAppsWithUsers[name] = val
}
// if prefix != "" {
// if entranceAuthorizationLevel == ApplicationAuthorizationLevelPublic {
// publicApps = append(publicApps, prefix)
// }
if entranceAuthorizationLevel == ApplicationAuthorizationLevelPublic {
customDomains = append(customDomains, entranceCustomDomain)
}
}
}
// if len(customDomainsPrefix) > 0 {
// publicApps = append(publicApps, customDomainsPrefix...)
// }
if prefix != "" {
if entranceAuthorizationLevel == ApplicationAuthorizationLevelPublic {
publicApps = append(publicApps, prefix)
}
// if len(customDomains) > 0 {
// publicCustomDomainApps = append(publicCustomDomainApps, customDomains...)
// }
// }
// }
// }
if len(customDomainsPrefix) > 0 {
publicApps = append(publicApps, customDomainsPrefix...)
}
return publicApps, publicCustomDomainApps, customDomainApps
if len(customDomains) > 0 {
publicCustomDomainApps = append(publicCustomDomainApps, customDomains...)
}
}
}
}
return publicApps, publicCustomDomainApps, customDomainApps, customDomainAppsWithUsers
}
func (s *Server) listUsers() (Users, error) {
publicAppIdList, publicCustomDomainAppList, customDomainAppList := s.listApplications()
publicAppIdList, publicCustomDomainAppList, customDomainAppList, customDomainAppListWithUsers := s.listApplications()
_ = customDomainAppList
list, err := s.client.Resource(iamUserGVR).List(context.TODO(), metav1.ListOptions{})
if err != nil {
@@ -530,9 +539,14 @@ func (s *Server) listUsers() (Users, error) {
denyAllStatus = getUserAnnotation(&user, userDenyAllPolicy)
allowedDomainsAnno = getPublicAccessDomain(zone, publicAppIdList, publicCustomDomainAppList, denyAllStatus)
if len(customDomainAppList) > 0 {
ngxServerNameDomains = append(ngxServerNameDomains, customDomainAppList...)
userCustomDomains, ok := customDomainAppListWithUsers[user.Name]
if ok && len(userCustomDomains) > 0 {
ngxServerNameDomains = append(ngxServerNameDomains, userCustomDomains...)
}
// if len(customDomainAppList) > 0 {
// ngxServerNameDomains = append(ngxServerNameDomains, customDomainAppList...)
// }
} else {
// creator user
creator := getUserAnnotation(&user, userAnnotationCreator)

View File

@@ -1,4 +1,6 @@
{{- if and .Values.devicePlugin.createRuntimeClass .Values.devicePlugin.runtimeClassName }}
{{- $existingRuntimeClass := lookup "node.k8s.io/v1" "RuntimeClass" "" .Values.devicePlugin.runtimeClassName }}
{{- if not $existingRuntimeClass }}
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
@@ -7,3 +9,4 @@ metadata:
helm.sh/hook: pre-install,pre-upgrade
handler: nvidia
{{- end }}
{{- end }}

View File

@@ -4,7 +4,7 @@ nameOverride: ""
fullnameOverride: ""
namespaceOverride: ""
imagePullSecrets: []
version: "v2.6.10"
version: "v2.6.11"
# Nvidia GPU Parameters
resourceName: "nvidia.com/gpu"
@@ -151,9 +151,9 @@ devicePlugin:
deviceMemoryScaling: 1
deviceCoreScaling: 1
# The runtime class name to be used by the device plugin, and added to the pod.spec.runtimeClassName of applications utilizing NVIDIA GPUs
runtimeClassName: ""
runtimeClassName: "nvidia"
# Whether to create runtime class, name comes from runtimeClassName when it is set
createRuntimeClass: false
createRuntimeClass: true
migStrategy: "none"
disablecorelimit: "false"
passDeviceSpecsEnabled: false

View File

@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: amdgpu-device-plugin
namespace: kube-system
spec:
selector:
matchLabels:
name: amdgpu-dp-ds
template:
metadata:
labels:
name: amdgpu-dp-ds
spec:
restartPolicy: Always
nodeSelector:
kubernetes.io/arch: amd64
priorityClassName: system-node-critical
tolerations:
- key: CriticalAddonsOnly
operator: Exists
containers:
- image: rocm/k8s-device-plugin
name: amdgpu-dp-cntr
securityContext:
privileged: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: dp
mountPath: /var/lib/kubelet/device-plugins
- name: sys
mountPath: /sys
volumes:
- name: dp
hostPath:
path: /var/lib/kubelet/device-plugins
- name: sys
hostPath:
path: /sys

View File

@@ -3,7 +3,7 @@ target: prebuilt
output:
containers:
-
name: beclab/hami:v2.6.10
name: beclab/hami:v2.6.11
-
name: beclab/hami-webui-fe-oss:v1.0.8
-

View File

@@ -7,4 +7,4 @@ output:
-
name: beclab/kubeblocks:1.0.1-ext1
-
name: beclab/kubeblock-addon-charts:v1.0.1-ext2
name: beclab/kubeblock-addon-charts:v1.0.1-ext3

View File

@@ -11,7 +11,7 @@ spec:
or cluster of machines.
helm:
chartLocationURL: file:///minio-1.0.1.tgz
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext2
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext3
chartsPathInImage: /charts
installValues: {}
valuesMapping:
@@ -44,7 +44,7 @@ spec:
and scaling.
helm:
chartLocationURL: file:///mongodb-1.0.1.tgz
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext2
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext3
installable:
autoInstall: true
type: Helm
@@ -68,7 +68,7 @@ spec:
speed and relevance on production-scale workloads.
helm:
chartLocationURL: file:///elasticsearch-1.0.1.tgz
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext2
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext3
installable:
autoInstall: true
type: Helm
@@ -90,7 +90,7 @@ spec:
description: RabbitMQ is a reliable and mature messaging and streaming broker.
helm:
chartLocationURL: file:///rabbitmq-1.0.1.tgz
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext2
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext3
installable:
autoInstall: true
type: Helm
@@ -113,7 +113,7 @@ spec:
system that is widely used for web and application servers
helm:
chartLocationURL: file:///mariadb-1.0.1.tgz
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext2
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext3
installable:
autoInstall: true
type: Helm
@@ -136,7 +136,7 @@ spec:
system (RDBMS)
helm:
chartLocationURL: file:///mysql-1.0.1.tgz
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext2
chartsImage: beclab/kubeblock-addon-charts:v1.0.1-ext3
installable:
autoInstall: true
type: Helm