Compare commits
83 Commits
appservice
...
daemon/fea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fb498fa7a | ||
|
|
8f5023ce17 | ||
|
|
4467bc61df | ||
|
|
85f1224616 | ||
|
|
4b3a42d728 | ||
|
|
3c821cbedb | ||
|
|
3129b295ce | ||
|
|
76bde01b86 | ||
|
|
32c652205d | ||
|
|
817316c1d6 | ||
|
|
e03eb40ed8 | ||
|
|
79b7d82748 | ||
|
|
20344416f8 | ||
|
|
8c59050529 | ||
|
|
f932d10916 | ||
|
|
e4762d880b | ||
|
|
017b2e2acd | ||
|
|
d3adeced3f | ||
|
|
48038504a7 | ||
|
|
d17d8fca14 | ||
|
|
35770fbe46 | ||
|
|
39cb3335d6 | ||
|
|
0e1208d555 | ||
|
|
65fa0c0da8 | ||
|
|
cf7125aac8 | ||
|
|
46ba0e64e8 | ||
|
|
a15fe1e3e0 | ||
|
|
1b3305dd98 | ||
|
|
54f2996efe | ||
|
|
7870520b57 | ||
|
|
2dbd99d64a | ||
|
|
44d3f5d26a | ||
|
|
0f67f6227f | ||
|
|
21e1c06794 | ||
|
|
838c146fc0 | ||
|
|
403460b9c2 | ||
|
|
9f1800c8c6 | ||
|
|
29756b392e | ||
|
|
fd122768e7 | ||
|
|
6c40d3a288 | ||
|
|
5b843d19e4 | ||
|
|
97e2b82d0e | ||
|
|
8614fa6253 | ||
|
|
b4966d5e38 | ||
|
|
a7f698faf7 | ||
|
|
d7ea9b40d6 | ||
|
|
5a5d00d910 | ||
|
|
7de7ff989c | ||
|
|
1a1fcfac89 | ||
|
|
452a6f2e78 | ||
|
|
2d1abe8965 | ||
|
|
744b4a3666 | ||
|
|
eb61923584 | ||
|
|
991d4e1dce | ||
|
|
5f513e2155 | ||
|
|
7c3246dd9b | ||
|
|
362c6f1cde | ||
|
|
d2e685abd8 | ||
|
|
ae2b6b1353 | ||
|
|
8cbdc32725 | ||
|
|
c696be90e6 | ||
|
|
9487ef8862 | ||
|
|
a982a1568a | ||
|
|
60d445f92a | ||
|
|
839133fc27 | ||
|
|
2e6405ae1b | ||
|
|
5109ad001c | ||
|
|
4d850312f0 | ||
|
|
1265ca929c | ||
|
|
6302bee05d | ||
|
|
2838d95f25 | ||
|
|
d3d7fc372d | ||
|
|
2bc061fcd8 | ||
|
|
f14cc982b5 | ||
|
|
dd727befe7 | ||
|
|
83561bf1b7 | ||
|
|
7dd688c645 | ||
|
|
7d12b792ea | ||
|
|
c37cb9e15d | ||
|
|
c79c2fc253 | ||
|
|
32fe6513e6 | ||
|
|
12ec558b27 | ||
|
|
375dfceacb |
22
.github/workflows/build-redis-231.yaml
vendored
22
.github/workflows/build-redis-231.yaml
vendored
@@ -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
|
||||
|
||||
44
.github/workflows/build-redis.yaml
vendored
44
.github/workflows/build-redis.yaml
vendored
@@ -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*"
|
||||
|
||||
22
.github/workflows/build-ubuntu2204.yaml
vendored
22
.github/workflows/build-ubuntu2204.yaml
vendored
@@ -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
|
||||
23
.github/workflows/build-wsl2326.yaml
vendored
23
.github/workflows/build-wsl2326.yaml
vendored
@@ -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
|
||||
|
||||
109
.github/workflows/check.yaml
vendored
109
.github/workflows/check.yaml
vendored
@@ -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:
|
||||
@@ -75,7 +67,7 @@ jobs:
|
||||
steps:
|
||||
- id: generate
|
||||
run: |
|
||||
v=1.12.5-$(echo $RANDOM$RANDOM)
|
||||
v=1.12.6-$(echo $RANDOM$RANDOM)
|
||||
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
upload-cli:
|
||||
@@ -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:
|
||||
|
||||
22
.github/workflows/release-cli.yaml
vendored
22
.github/workflows/release-cli.yaml
vendored
@@ -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
|
||||
|
||||
33
.github/workflows/release-daemon.yaml
vendored
33
.github/workflows/release-daemon.yaml
vendored
@@ -46,7 +46,15 @@ jobs:
|
||||
|
||||
- name: install udev-devel and pcap-devel
|
||||
run: |
|
||||
sudo apt update && sudo apt install -y libudev-dev libpcap-dev
|
||||
sudo dpkg --add-architecture arm64
|
||||
# Only modify ubuntu official sources, not third-party sources
|
||||
sudo sed -i 's/^deb http:\/\/azure.archive.ubuntu.com/deb [arch=amd64] http:\/\/azure.archive.ubuntu.com/' /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null || true
|
||||
sudo sed -i 's/^Types: deb$/Types: deb\nArchitectures: amd64/' /etc/apt/sources.list.d/ubuntu.sources 2>/dev/null || true
|
||||
# Add arm64 sources
|
||||
echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports noble main restricted universe multiverse" | sudo tee /etc/apt/sources.list.d/arm64.list
|
||||
echo "deb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports noble-updates main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list.d/arm64.list
|
||||
sudo apt update
|
||||
sudo apt install -y libudev-dev libpcap-dev libudev-dev:arm64 libpcap-dev:arm64
|
||||
|
||||
- name: Install x86_64 cross-compiler
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential
|
||||
@@ -64,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
|
||||
|
||||
110
.github/workflows/release-daily.yaml
vendored
110
.github/workflows/release-daily.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- id: generate
|
||||
run: |
|
||||
v=1.12.5-$(date +"%Y%m%d")
|
||||
v=1.12.6-$(date +"%Y%m%d")
|
||||
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
release-id:
|
||||
@@ -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:
|
||||
|
||||
22
.github/workflows/release-mdns-agent.yaml
vendored
22
.github/workflows/release-mdns-agent.yaml
vendored
@@ -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
|
||||
|
||||
108
.github/workflows/release.yaml
vendored
108
.github/workflows/release.yaml
vendored
@@ -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
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
# Olares: An Open-Source Personal Cloud to </br>Reclaim Your Data<!-- omit in toc -->
|
||||
|
||||
[](#)<br/>
|
||||
[](https://github.com/beclab/olares/commits/main)
|
||||
[](https://github.com/beclab/olares/commits/main)
|
||||

|
||||
[](https://github.com/beclab/olares/releases)
|
||||
[](https://github.com/beclab/olares/stargazers)
|
||||
[](https://github.com/beclab/olares/releases)
|
||||
[](https://github.com/beclab/Olares/stargazers)
|
||||
[](https://discord.gg/olares)
|
||||
[](https://github.com/beclab/olares/blob/main/LICENSE)
|
||||
|
||||
@@ -45,7 +45,7 @@ Just as Public clouds offer IaaS, PaaS, and SaaS layers, Olares provides open-so
|
||||
|
||||

|
||||
|
||||
For detailed description of each component, refer to [Olares architecture](https://docs.olares.com/manual/concepts/system-architecture.html).
|
||||
For detailed description of each component, refer to [Olares architecture](https://docs.olares.com/developer/concepts/system-architecture.html).
|
||||
|
||||
> 🔍 **How is Olares different from traditional NAS?**
|
||||
>
|
||||
|
||||
@@ -317,7 +317,7 @@ spec:
|
||||
chown -R 1000:1000 /uploadstemp && \
|
||||
chown -R 1000:1000 /appdata
|
||||
- name: olares-app-init
|
||||
image: beclab/system-frontend:v1.8.4
|
||||
image: beclab/system-frontend:v1.9.9
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
@@ -439,7 +439,7 @@ spec:
|
||||
- name: NATS_SUBJECT_VAULT
|
||||
value: os.vault.{{ .Values.bfl.username}}
|
||||
- name: user-service
|
||||
image: beclab/user-service:v0.0.84
|
||||
image: beclab/user-service:v0.0.86
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
@@ -415,7 +415,7 @@ export default defineComponent({
|
||||
background-color: $background-1;
|
||||
|
||||
.app_title {
|
||||
font-family: 'Inter';
|
||||
font-family: 'Roboto' !important;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
|
||||
@@ -358,7 +358,7 @@ export default defineComponent({
|
||||
left: 0;
|
||||
|
||||
.app_title {
|
||||
font-family: 'Source Han Sans CN';
|
||||
font-family: 'Roboto' !important;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
|
||||
@@ -18,7 +18,7 @@ fi
|
||||
if [[ x"$VERSION" == x"" ]]; then
|
||||
if [[ "$LOCAL_RELEASE" == "1" ]]; then
|
||||
ts=$(date +%Y%m%d%H%M%S)
|
||||
export VERSION="1.12.5-$ts"
|
||||
export VERSION="1.12.6-$ts"
|
||||
echo "will build and use a local release of Olares with version: $VERSION"
|
||||
echo ""
|
||||
else
|
||||
@@ -28,7 +28,7 @@ fi
|
||||
|
||||
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then
|
||||
echo "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
|
||||
echo "for example: VERSION=1.12.5-20241124 bash $0"
|
||||
echo "for example: VERSION=1.12.6-20241124 bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -202,11 +202,15 @@ if [ "$PREINSTALL" == "1" ]; then
|
||||
fi
|
||||
|
||||
|
||||
echo "configuring storage ..."
|
||||
$sh_c "$INSTALL_OLARES_CLI install storage"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to configure storage"
|
||||
exit 1
|
||||
if [[ "$JUICEFS" == "1" ]]; then
|
||||
echo "configuring storage for juicefs ..."
|
||||
$sh_c "$INSTALL_OLARES_CLI install storage"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to configure storage"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "juicefs is not enabled, skip configuring storage"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ export VERSION="#__VERSION__"
|
||||
|
||||
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then
|
||||
echo "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
|
||||
echo "for example: VERSION=1.12.5-20241124 bash $0"
|
||||
echo "for example: VERSION=1.12.6-20241124 bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -43,6 +43,15 @@ userEnvs:
|
||||
- envName: OLARES_USER_SMTP_SECURITY_PROTOCOLS
|
||||
type: string
|
||||
editable: true
|
||||
options:
|
||||
- title: "TLS"
|
||||
value: "tls"
|
||||
- title: "SSL"
|
||||
value: "ssl"
|
||||
- title: "StartTLS"
|
||||
value: "starttls"
|
||||
- title: "None"
|
||||
value: "none"
|
||||
- envName: OLARES_USER_OPENAI_APIKEY
|
||||
type: password
|
||||
editable: true
|
||||
|
||||
@@ -281,7 +281,7 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
|
||||
func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
cmd := exec.Command("dmesg -T")
|
||||
cmd := exec.Command("dmesg", "-T")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -645,7 +645,7 @@ func checkServiceExists(service string) bool {
|
||||
func NewCmdLogs() *cobra.Command {
|
||||
options := &LogCollectOptions{
|
||||
Since: "7d",
|
||||
MaxLines: 3000,
|
||||
MaxLines: 20000,
|
||||
OutputDir: "./olares-logs",
|
||||
IgnoreKubeErrors: false,
|
||||
}
|
||||
|
||||
@@ -8,26 +8,27 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
corecommon "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/beclab/Olares/cli/pkg/release/builder"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func NewCmdRelease() *cobra.Command {
|
||||
var (
|
||||
baseDir string
|
||||
version string
|
||||
cdn string
|
||||
ignoreMissingImages bool
|
||||
extract bool
|
||||
)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "release",
|
||||
Short: "Build release based on a local Olares repository",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
baseDir := viper.GetString(common.FlagBaseDir)
|
||||
version := viper.GetString(common.FlagVersion)
|
||||
cdn := viper.GetString(common.FlagCDNService)
|
||||
ignoreMissingImages := viper.GetBool(common.FlagIgnoreMissingImages)
|
||||
extract := viper.GetBool(common.FlagExtract)
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
fmt.Printf("failed to get current working directory: %s\n", err)
|
||||
@@ -43,13 +44,13 @@ func NewCmdRelease() *cobra.Command {
|
||||
fmt.Printf("failed to get current user: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
baseDir = filepath.Join(usr.HomeDir, common.DefaultBaseDir)
|
||||
baseDir = filepath.Join(usr.HomeDir, corecommon.DefaultBaseDir)
|
||||
fmt.Printf("--base-dir unspecified, using: %s\n", baseDir)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
if version == "" {
|
||||
version = fmt.Sprintf("1.12.5-%s", time.Now().Format("20060102150405"))
|
||||
version = fmt.Sprintf("1.12.6-%s", time.Now().Format("20060102150405"))
|
||||
fmt.Printf("--version unspecified, using: %s\n", version)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
@@ -75,11 +76,20 @@ func NewCmdRelease() *cobra.Command {
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().StringVarP(&baseDir, "base-dir", "b", "", "base directory of Olares, where this release will be extracted to as a new version if --extract/-e is not disabled, defaults to $HOME/"+common.DefaultBaseDir)
|
||||
cmd.Flags().StringVarP(&version, "version", "v", "", "version of this release, defaults to 0.0.0-local-dev-{yyyymmddhhmmss}")
|
||||
cmd.Flags().StringVar(&cdn, "cdn-service", common.DefaultOlaresCDNService, "CDN used for downloading checksums of dependencies and images")
|
||||
cmd.Flags().BoolVar(&ignoreMissingImages, "ignore-missing-images", true, "ignore missing images when downloading cheksums from CDN, only disable this if no new image is added, or the build may fail because the image is not uploaded to the CDN yet")
|
||||
cmd.Flags().BoolVarP(&extract, "extract", "e", true, "extract this release to --base-dir after build, this can be disabled if only the release file itself is needed")
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
flagSetter.Add(common.FlagIgnoreMissingImages,
|
||||
"",
|
||||
true,
|
||||
"ignore missing images when downloading checksums from CDN, only disable this if no new image is added, or the build may fail because the image is not uploaded to the CDN yet",
|
||||
)
|
||||
flagSetter.Add(common.FlagExtract,
|
||||
"e",
|
||||
true,
|
||||
"extract this release to --base-dir after build, this can be disabled if only the release file itself is needed",
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/user"
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func NewDefaultCommand() *cobra.Command {
|
||||
@@ -25,6 +26,11 @@ func NewDefaultCommand() *cobra.Command {
|
||||
Short: "Olares Installer",
|
||||
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
|
||||
Version: version.VERSION,
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
viper.BindPFlags(cmd.InheritedFlags())
|
||||
viper.BindPFlags(cmd.PersistentFlags())
|
||||
viper.BindPFlags(cmd.Flags())
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if showVendor {
|
||||
fmt.Println(version.VENDOR)
|
||||
|
||||
121
cli/pkg/amdgpu/module.go
Normal file
121
cli/pkg/amdgpu/module.go
Normal 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,
|
||||
}
|
||||
}
|
||||
56
cli/pkg/amdgpu/prepares.go
Normal file
56
cli/pkg/amdgpu/prepares.go
Normal 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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -261,12 +261,14 @@ const (
|
||||
FlagOSPassword = "os-password"
|
||||
EnvLegacyEncryptedOSPassword = "TERMINUS_OS_PASSWORD"
|
||||
|
||||
FlagCDNService = "cdn-service"
|
||||
FlagManifest = "manifest"
|
||||
FlagURLOverride = "url-override"
|
||||
FlagReleaseID = "release-id"
|
||||
FlagKubeType = "kube-type"
|
||||
FlagLegacyKubeType = "kube"
|
||||
FlagCDNService = "cdn-service"
|
||||
FlagExtract = "extract"
|
||||
FlagIgnoreMissingImages = "ignore-missing-images"
|
||||
FlagManifest = "manifest"
|
||||
FlagURLOverride = "url-override"
|
||||
FlagReleaseID = "release-id"
|
||||
FlagKubeType = "kube-type"
|
||||
FlagLegacyKubeType = "kube"
|
||||
|
||||
FlagEnableJuiceFS = "enable-juicefs"
|
||||
FlagLegacyEnableJuiceFS = "with-juicefs"
|
||||
|
||||
@@ -210,7 +210,11 @@ 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.
|
||||
arg.SetBaseDir(viper.GetString(FlagBaseDir))
|
||||
arg.loadMasterHostConfig()
|
||||
return arg
|
||||
}
|
||||
@@ -382,6 +386,10 @@ func (a *Argument) loadMasterHostConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Argument) ClearMasterHostConfig() {
|
||||
a.MasterHostConfig = &MasterHostConfig{}
|
||||
}
|
||||
|
||||
func (a *Argument) SetManifest(manifest string) {
|
||||
a.Manifest = manifest
|
||||
}
|
||||
@@ -408,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()
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
117
cli/pkg/core/connector/amdgpu.go
Normal file
117
cli/pkg/core/connector/amdgpu.go
Normal 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
|
||||
}
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ var (
|
||||
ETCDService = template.Must(template.New("etcd.service").Parse(
|
||||
dedent.Dedent(`[Unit]
|
||||
Description=etcd
|
||||
After=network.target
|
||||
After=network-online.target
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}()},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -18,7 +18,6 @@ func AddNodePipeline() error {
|
||||
}
|
||||
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("addnode.log", true)
|
||||
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
|
||||
@@ -19,7 +19,6 @@ func ChangeIPPipeline() error {
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(terminusVersion)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("changeip.log", true)
|
||||
arg.SetKubeVersion(kubeType)
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
func CheckDownloadInstallationPackage() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
|
||||
func DownloadInstallationPackage() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetOlaresCDNService(viper.GetString(common.FlagCDNService))
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
func DownloadInstallationWizard() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresCDNService(viper.GetString(common.FlagCDNService))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
|
||||
@@ -15,7 +15,6 @@ import (
|
||||
func InstallGpuDrivers() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("gpuinstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
|
||||
@@ -20,7 +20,6 @@ func CliInstallTerminusPipeline() error {
|
||||
}
|
||||
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetKubeVersion(viper.GetString(common.FlagKubeType))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/beclab/Olares/cli/pkg/terminus"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func MasterInfoPipeline() error {
|
||||
@@ -17,7 +16,6 @@ func MasterInfoPipeline() error {
|
||||
fmt.Println("error: Only Linux nodes can be added to an Olares cluster!")
|
||||
os.Exit(1)
|
||||
}
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("masterinfo.log", true)
|
||||
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
func StartPreCheckPipeline() error {
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("precheck.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
|
||||
@@ -28,7 +28,6 @@ func PrepareSystemPipeline(components []string) error {
|
||||
}
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetKubeVersion(viper.GetString(common.FlagKubeType))
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
|
||||
@@ -18,7 +18,6 @@ func CliInstallStoragePipeline() error {
|
||||
}
|
||||
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetStorage(getStorageConfig())
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ func UninstallTerminusPipeline() error {
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(version)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("uninstall.log", true)
|
||||
arg.SetKubeVersion(kubeType)
|
||||
arg.SetStorage(getStorageConfig())
|
||||
arg.ClearMasterHostConfig()
|
||||
|
||||
phase := viper.GetString(common.FlagUninstallPhase)
|
||||
all := viper.GetBool(common.FlagUninstallAll)
|
||||
|
||||
@@ -30,13 +30,7 @@ func UpgradeOlaresPipeline() error {
|
||||
return fmt.Errorf("error parsing current Olares version: %v", err)
|
||||
}
|
||||
|
||||
// should only be and defaults to the current cli version
|
||||
// this argument is for backwards-compatibility with older olaresd
|
||||
targetVersionStr := viper.GetString(common.FlagVersion)
|
||||
if targetVersionStr == "" {
|
||||
targetVersionStr = version.VERSION
|
||||
}
|
||||
targetVersion, err := utils.ParseOlaresVersionString(targetVersionStr)
|
||||
targetVersion, err := utils.ParseOlaresVersionString(version.VERSION)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing target Olares version: %v", err)
|
||||
}
|
||||
@@ -46,7 +40,6 @@ func UpgradeOlaresPipeline() error {
|
||||
}
|
||||
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetConsoleLog("upgrade.log", true)
|
||||
arg.SetKubeVersion(phase.GetKubeType())
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
)
|
||||
|
||||
@@ -57,6 +58,10 @@ func (m *Manager) Package() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.packageEnvConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -121,3 +126,19 @@ func (m *Manager) packageGPU() error {
|
||||
filepath.Join(m.distPath, "wizard/config/gpu"),
|
||||
)
|
||||
}
|
||||
|
||||
func (m *Manager) packageEnvConfig() error {
|
||||
fmt.Println("packaging env config ...")
|
||||
|
||||
systemEnvSrc := filepath.Join(m.olaresRepoRoot, "build", common.OLARES_SYSTEM_ENV_FILENAME)
|
||||
userEnvSrc := filepath.Join(m.olaresRepoRoot, "build", common.OLARES_USER_ENV_FILENAME)
|
||||
|
||||
if err := util.CopyFile(systemEnvSrc, filepath.Join(m.distPath, common.OLARES_SYSTEM_ENV_FILENAME)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := util.CopyFile(userEnvSrc, filepath.Join(m.distPath, common.OLARES_USER_ENV_FILENAME)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -125,6 +125,11 @@ func (t *CreateUserEnvConfigMap) Execute(runtime connector.Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
desiredBytes, err := os.ReadFile(userEnvPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read user env config file")
|
||||
}
|
||||
|
||||
configK8s, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get kubernetes config")
|
||||
@@ -144,17 +149,24 @@ func (t *CreateUserEnvConfigMap) Execute(runtime connector.Runtime) error {
|
||||
defer cancel()
|
||||
|
||||
name := "user-env"
|
||||
namespace := common.NamespaceOsFramework
|
||||
cm := &corev1.ConfigMap{}
|
||||
err = ctrlclient.Get(ctx, types.NamespacedName{Name: name, Namespace: common.NamespaceOsFramework}, cm)
|
||||
err = ctrlclient.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, cm)
|
||||
if apierrors.IsNotFound(err) {
|
||||
// create via kubectl from file
|
||||
kubectl, _ := util.GetCommand(common.CommandKubectl)
|
||||
cmd := fmt.Sprintf("%s -n %s create configmap %s --from-file=%s=%s",
|
||||
kubectl, common.NamespaceOsFramework, name, common.OLARES_USER_ENV_FILENAME, userEnvPath,
|
||||
)
|
||||
if _, cerr := runtime.GetRunner().SudoCmd(cmd, false, true); cerr != nil {
|
||||
return errors.Wrap(errors.WithStack(cerr), "failed to create user-env configmap")
|
||||
cm = &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: namespace,
|
||||
},
|
||||
Data: map[string]string{
|
||||
common.OLARES_USER_ENV_FILENAME: string(desiredBytes),
|
||||
},
|
||||
}
|
||||
|
||||
if err := ctrlclient.Create(ctx, cm); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return errors.Wrap(err, "failed to create user-env configmap")
|
||||
}
|
||||
|
||||
logger.Infof("Created user env configmap from %s", userEnvPath)
|
||||
return nil
|
||||
}
|
||||
@@ -162,57 +174,21 @@ func (t *CreateUserEnvConfigMap) Execute(runtime connector.Runtime) error {
|
||||
return errors.Wrap(err, "failed to get user-env configmap")
|
||||
}
|
||||
|
||||
// If exists, merge missing envs and update via client
|
||||
newDataBytes, err := os.ReadFile(userEnvPath)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to read user env config file")
|
||||
}
|
||||
|
||||
var newCfg UserEnvConfig
|
||||
if err := yaml.Unmarshal(newDataBytes, &newCfg); err != nil {
|
||||
return errors.Wrap(err, "failed to parse user env config file")
|
||||
}
|
||||
|
||||
var existingCfg UserEnvConfig
|
||||
existingContent := cm.Data[common.OLARES_USER_ENV_FILENAME]
|
||||
if existingContent != "" {
|
||||
if err := yaml.Unmarshal([]byte(existingContent), &existingCfg); err != nil {
|
||||
return errors.Wrap(err, "failed to parse existing user env configmap data")
|
||||
}
|
||||
}
|
||||
|
||||
existingSet := make(map[string]struct{}, len(existingCfg.UserEnvs))
|
||||
for _, e := range existingCfg.UserEnvs {
|
||||
existingSet[e.EnvName] = struct{}{}
|
||||
}
|
||||
|
||||
missing := 0
|
||||
for _, e := range newCfg.UserEnvs {
|
||||
if _, ok := existingSet[e.EnvName]; !ok {
|
||||
existingCfg.UserEnvs = append(existingCfg.UserEnvs, e)
|
||||
missing++
|
||||
}
|
||||
}
|
||||
|
||||
if missing == 0 {
|
||||
logger.Infof("No new user envs to add; configmap up to date")
|
||||
return nil
|
||||
}
|
||||
|
||||
updatedBytes, err := yaml.Marshal(existingCfg)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to marshal updated user env config")
|
||||
}
|
||||
if cm.Data == nil {
|
||||
cm.Data = map[string]string{}
|
||||
}
|
||||
cm.Data[common.OLARES_USER_ENV_FILENAME] = string(updatedBytes)
|
||||
if cm.Data[common.OLARES_USER_ENV_FILENAME] == string(desiredBytes) {
|
||||
logger.Infof("user-env configmap is up to date")
|
||||
return nil
|
||||
}
|
||||
|
||||
cm.Data[common.OLARES_USER_ENV_FILENAME] = string(desiredBytes)
|
||||
|
||||
if err := ctrlclient.Update(ctx, cm); err != nil {
|
||||
return errors.Wrap(err, "failed to update user-env configmap")
|
||||
}
|
||||
|
||||
logger.Infof("Appended %d missing user env(s) and updated configmap", missing)
|
||||
logger.Infof("Updated user env configmap from %s", userEnvPath)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -7,19 +7,19 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type upgrader_1_12_5_20260122 struct {
|
||||
type upgrader_1_12_5_20260225 struct {
|
||||
breakingUpgraderBase
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_5_20260122) Version() *semver.Version {
|
||||
return semver.MustParse("1.12.3-20260122")
|
||||
func (u upgrader_1_12_5_20260225) Version() *semver.Version {
|
||||
return semver.MustParse("1.12.5-20260225")
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_5_20260122) UpgradeSystemComponents() []task.Interface {
|
||||
func (u upgrader_1_12_5_20260225) UpgradeSystemComponents() []task.Interface {
|
||||
pre := []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: "UpgradeL4BFLProxy",
|
||||
Action: &upgradeL4BFLProxy{Tag: "v0.3.10"},
|
||||
Action: &upgradeL4BFLProxy{Tag: "v0.3.11"},
|
||||
Retry: 3,
|
||||
Delay: 5 * time.Second,
|
||||
},
|
||||
@@ -28,5 +28,5 @@ func (u upgrader_1_12_5_20260122) UpgradeSystemComponents() []task.Interface {
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerDailyUpgrader(upgrader_1_12_5_20260122{})
|
||||
registerDailyUpgrader(upgrader_1_12_5_20260225{})
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -11,6 +11,13 @@ func AssertPodReady(pod *corev1.Pod) error {
|
||||
return fmt.Errorf("pod is nil")
|
||||
}
|
||||
|
||||
// simply ignore finished pod
|
||||
// it can be seen as just an execution record, not a running pod
|
||||
// and the deployment will create a new replica
|
||||
if pod.Status.Phase == corev1.PodSucceeded || pod.Status.Phase == corev1.PodFailed {
|
||||
return nil
|
||||
}
|
||||
|
||||
podKey := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
|
||||
if pod.DeletionTimestamp != nil {
|
||||
return fmt.Errorf("pod %s is terminating", podKey)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build !(linux && amd64)
|
||||
// +build !linux !amd64
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package intranet
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//go:build linux && amd64
|
||||
// +build linux,amd64
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package intranet
|
||||
|
||||
|
||||
@@ -43,11 +43,12 @@ type state struct {
|
||||
Disk string `json:"disk"`
|
||||
|
||||
// network info
|
||||
WikiConnected bool `json:"wifiConnected"`
|
||||
WifiSSID *string `json:"wifiSSID,omitempty"`
|
||||
WiredConnected bool `json:"wiredConnected"`
|
||||
HostIP string `json:"hostIp"`
|
||||
ExternalIP string `json:"externalIp"`
|
||||
WikiConnected bool `json:"wifiConnected"`
|
||||
WifiSSID *string `json:"wifiSSID,omitempty"`
|
||||
WiredConnected bool `json:"wiredConnected"`
|
||||
HostIP string `json:"hostIp"`
|
||||
ExternalIP string `json:"externalIp"`
|
||||
ExternalIPProbeTime time.Time `json:"-"`
|
||||
|
||||
// installing / uninstalling / upgrading state
|
||||
InstallingState ProcessingState `json:"installingState"`
|
||||
@@ -255,7 +256,10 @@ func CheckCurrentStatus(ctx context.Context) error {
|
||||
}
|
||||
|
||||
CurrentState.HostIP = hostIp
|
||||
CurrentState.ExternalIP = nets.GetMyExternalIPAddr()
|
||||
if time.Since(CurrentState.ExternalIPProbeTime) > 1*time.Minute {
|
||||
CurrentState.ExternalIP = nets.GetMyExternalIPAddr()
|
||||
CurrentState.ExternalIPProbeTime = time.Now()
|
||||
}
|
||||
|
||||
// get olares state
|
||||
|
||||
|
||||
@@ -4,14 +4,17 @@ import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/beclab/Olares/daemon/pkg/commands"
|
||||
"github.com/gofiber/fiber/v2/log"
|
||||
"github.com/libp2p/go-netroute"
|
||||
pkg_errors "github.com/pkg/errors"
|
||||
"github.com/txn2/txeh"
|
||||
@@ -267,15 +270,7 @@ func GetHostIpFromHostsFile(domain string) (string, error) {
|
||||
return ip, nil
|
||||
}
|
||||
|
||||
// GetMyExternalIPAddr get my network outgoing ip address
|
||||
func GetMyExternalIPAddr() string {
|
||||
sites := map[string]string{
|
||||
"httpbin": "https://httpbin.org/ip",
|
||||
"ifconfigme": "https://ifconfig.me/all.json",
|
||||
"externalip": "https://myexternalip.com/json",
|
||||
"joinolares": "https://myip.joinolares.cn/ip",
|
||||
}
|
||||
|
||||
type httpBin struct {
|
||||
Origin string `json:"origin"`
|
||||
}
|
||||
@@ -295,80 +290,80 @@ func GetMyExternalIPAddr() string {
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
var unmarshalFuncs = map[string]func(v []byte) string{
|
||||
"httpbin": func(v []byte) string {
|
||||
var hb httpBin
|
||||
if err := json.Unmarshal(v, &hb); err == nil && hb.Origin != "" {
|
||||
return hb.Origin
|
||||
}
|
||||
return ""
|
||||
},
|
||||
"ifconfigme": func(v []byte) string {
|
||||
var ifMe ifconfigMe
|
||||
if err := json.Unmarshal(v, &ifMe); err == nil && ifMe.IPAddr != "" {
|
||||
return ifMe.IPAddr
|
||||
}
|
||||
return ""
|
||||
},
|
||||
"externalip": func(v []byte) string {
|
||||
var extip externalIP
|
||||
if err := json.Unmarshal(v, &extip); err == nil && extip.IP != "" {
|
||||
return extip.IP
|
||||
}
|
||||
return ""
|
||||
},
|
||||
"joinolares": func(v []byte) string {
|
||||
return strings.TrimSpace(string(v))
|
||||
},
|
||||
type siteConfig struct {
|
||||
url string
|
||||
unmarshalFunc func(v []byte) string
|
||||
}
|
||||
|
||||
ch := make(chan any, len(sites))
|
||||
|
||||
for site := range sites {
|
||||
go func(name string) {
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||
c := http.Client{Timeout: 5 * time.Second}
|
||||
resp, err := c.Get(sites[name])
|
||||
if err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
|
||||
ip := unmarshalFuncs[name](respBytes)
|
||||
//println(name, site, ip)
|
||||
ch <- ip
|
||||
}(site)
|
||||
externalIPServiceURL, err := url.JoinPath(commands.OLARES_REMOTE_SERVICE, "/myip/ip")
|
||||
if err != nil {
|
||||
klog.Error("failed to parse external IP service URL, ", err)
|
||||
return ""
|
||||
}
|
||||
|
||||
tr := time.NewTimer(time.Duration(5*len(sites)+3) * time.Second)
|
||||
|
||||
LOOP:
|
||||
for i := 0; i < len(sites); i++ {
|
||||
select {
|
||||
case r, ok := <-ch:
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
switch v := r.(type) {
|
||||
case string:
|
||||
ip := net.ParseIP(v)
|
||||
if ip != nil && ip.To4() != nil && !ip.IsLoopback() && !ip.IsMulticast() {
|
||||
return v
|
||||
sites := []siteConfig{
|
||||
{
|
||||
url: externalIPServiceURL,
|
||||
unmarshalFunc: func(v []byte) string {
|
||||
return strings.TrimSpace(string(v))
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://httpbin.org/ip",
|
||||
unmarshalFunc: func(v []byte) string {
|
||||
var hb httpBin
|
||||
if err := json.Unmarshal(v, &hb); err == nil && hb.Origin != "" {
|
||||
return hb.Origin
|
||||
}
|
||||
case error:
|
||||
klog.Warningf("got an error, %v", v)
|
||||
}
|
||||
case <-tr.C:
|
||||
tr.Stop()
|
||||
klog.Warning("timed out")
|
||||
break LOOP
|
||||
return ""
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://ifconfig.me/all.json",
|
||||
unmarshalFunc: func(v []byte) string {
|
||||
var ifMe ifconfigMe
|
||||
if err := json.Unmarshal(v, &ifMe); err == nil && ifMe.IPAddr != "" {
|
||||
return ifMe.IPAddr
|
||||
}
|
||||
return ""
|
||||
},
|
||||
},
|
||||
{
|
||||
url: "https://myexternalip.com/json",
|
||||
unmarshalFunc: func(v []byte) string {
|
||||
var extip externalIP
|
||||
if err := json.Unmarshal(v, &extip); err == nil && extip.IP != "" {
|
||||
return extip.IP
|
||||
}
|
||||
return ""
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
client := http.Client{
|
||||
Timeout: 3 * time.Second,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
}
|
||||
for _, site := range sites {
|
||||
resp, err := client.Get(site.url)
|
||||
if err != nil {
|
||||
log.Warnf("failed to get external ip from %s, %v", site.url, err)
|
||||
continue
|
||||
}
|
||||
|
||||
respBytes, readErr := io.ReadAll(resp.Body)
|
||||
resp.Body.Close()
|
||||
if readErr != nil {
|
||||
log.Warnf("failed to read response from %s, %v", site.url, readErr)
|
||||
continue
|
||||
}
|
||||
|
||||
ipStr := site.unmarshalFunc(respBytes)
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip != nil && ip.To4() != nil && !ip.IsLoopback() && !ip.IsMulticast() {
|
||||
return ipStr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -42,7 +43,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 +98,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 +204,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,7 +278,17 @@ func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevic
|
||||
continue
|
||||
}
|
||||
|
||||
if err = mounter.Mount(d.DevPath, mkMountDir, "", []string{"uid=1000", "gid=1000"}); err != nil {
|
||||
options := []string{}
|
||||
fsType, err := getFsTypeOfDevice(ctx, d.DevPath)
|
||||
if err != nil {
|
||||
klog.Warning("get fs type of device error, ", err, ", ", d.DevPath)
|
||||
} else {
|
||||
if strings.Contains(fsType, "FAT") || strings.Contains(fsType, "NTFS") {
|
||||
options = append(options, "uid=1000", "gid=1000")
|
||||
}
|
||||
}
|
||||
|
||||
if err = mounter.Mount(d.DevPath, mkMountDir, "", options); err != nil {
|
||||
klog.Warning("mount usb error, ", err, ", ", d.DevPath, ", ", mkMountDir)
|
||||
// clear the empty mount dir
|
||||
// do not use remove all, only remove the mount point path, assume it's an empty dir
|
||||
@@ -685,3 +703,35 @@ func isDeviceExists(devicePath string) bool {
|
||||
_, err := os.Stat(devicePath)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
func getFsTypeOfDevice(ctx context.Context, devicePath string) (string, error) {
|
||||
// output format
|
||||
// {
|
||||
// "blockdevices": [
|
||||
// {
|
||||
// "fstype": "ext4"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
cmd := exec.CommandContext(ctx, "lsblk", "-f", devicePath, "-o", "fstype", "-J")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var result struct {
|
||||
BlockDevices []struct {
|
||||
FsType string `json:"fstype"`
|
||||
} `json:"blockdevices"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(output, &result); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if len(result.BlockDevices) == 0 {
|
||||
return "", fmt.Errorf("no block devices found for %s", devicePath)
|
||||
}
|
||||
|
||||
return result.BlockDevices[0].FsType, nil
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
476
docs/.vitepress/developer.en.ts
Normal file
476
docs/.vitepress/developer.en.ts
Normal file
@@ -0,0 +1,476 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
export const developerSidebar: DefaultTheme.Sidebar = {
|
||||
"/developer/": [
|
||||
{
|
||||
text: "Concepts",
|
||||
link: "/developer/concepts/",
|
||||
items: [
|
||||
{ text: "Olares architecture", link: "/developer/concepts/system-architecture" },
|
||||
{
|
||||
text: "Olares ID",
|
||||
link: "/developer/concepts/olares-id",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Decentralized ID",
|
||||
link: "/developer/concepts/did",
|
||||
},
|
||||
{
|
||||
text: "Blockchain Registry",
|
||||
link: "/developer/concepts/registry",
|
||||
},
|
||||
{
|
||||
text: "Verifiable Credential",
|
||||
link: "/developer/concepts/vc",
|
||||
},
|
||||
{
|
||||
text: "Autonomous Reputation",
|
||||
link: "/developer/concepts/reputation",
|
||||
},
|
||||
// {
|
||||
// text: "Self-Sovereign Network",
|
||||
// link: "/developer/concepts/self-sovereign-network",
|
||||
// },
|
||||
{
|
||||
text: "Identity Wallet",
|
||||
link: "/developer/concepts/wallet",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "Account", link: "/developer/concepts/account" },
|
||||
{ text: "Application", link: "/developer/concepts/application" },
|
||||
{ text: "Network", link: "/developer/concepts/network" },
|
||||
{ text: "Data", link: "/developer/concepts/data" },
|
||||
{ text: "Secrets", link: "/developer/concepts/secrets" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Installation deep-dive",
|
||||
link: "/developer/install/",
|
||||
items: [
|
||||
{
|
||||
text: "Installation architecture",
|
||||
link: "/developer/install/installation-overview",
|
||||
},
|
||||
{
|
||||
text: "Installation process",
|
||||
link: "/developer/install/installation-process",
|
||||
},
|
||||
{
|
||||
text: "Olares Home",
|
||||
link: "/developer/install/olares-home",
|
||||
},
|
||||
{
|
||||
text: "Environment variables",
|
||||
link: "/developer/install/environment-variables",
|
||||
},
|
||||
{
|
||||
text: "Olares CLI",
|
||||
link: "/developer/install/cli/olares-cli",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Access Olares terminal", link: "/developer/reference/access-olares-terminal" },
|
||||
{
|
||||
text: "backups",
|
||||
link: "/developer/install/cli/backups",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "backup", link: "/developer/install/cli/backups-backup" },
|
||||
{ text: "download", link: "/developer/install/cli/backups-download" },
|
||||
{ text: "region", link: "/developer/install/cli/backups-region" },
|
||||
{ text: "restore", link: "/developer/install/cli/backups-restore" },
|
||||
{ text: "snapshots", link: "/developer/install/cli/backups-snapshots" },
|
||||
],
|
||||
},
|
||||
{ text: "change-ip", link: "/developer/install/cli/change-ip" },
|
||||
{ text: "disk", link: "/developer/install/cli/disk" },
|
||||
{ text: "download", link: "/developer/install/cli/download" },
|
||||
{ text: "gpu", link: "/developer/install/cli/gpu" },
|
||||
{ text: "info", link: "/developer/install/cli/info" },
|
||||
{ text: "install", link: "/developer/install/cli/install" },
|
||||
{ text: "logs", link: "/developer/install/cli/logs" },
|
||||
{ text: "node", link: "/developer/install/cli/node" },
|
||||
{ text: "osinfo", link: "/developer/install/cli/osinfo" },
|
||||
{ text: "precheck", link: "/developer/install/cli/precheck" },
|
||||
{ text: "prepare", link: "/developer/install/cli/prepare" },
|
||||
{ text: "release", link: "/developer/install/cli/release" },
|
||||
{ text: "start", link: "/developer/install/cli/start" },
|
||||
{ text: "stop", link: "/developer/install/cli/stop" },
|
||||
{ text: "uninstall", link: "/developer/install/cli/uninstall" },
|
||||
{ text: "upgrade", link: "/developer/install/cli/upgrade" },
|
||||
{
|
||||
text: "user",
|
||||
link: "/developer/install/cli/user",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "activate", link: "/developer/install/cli/user-activate" },
|
||||
{ text: "create", link: "/developer/install/cli/user-create" },
|
||||
{ text: "delete", link: "/developer/install/cli/user-delete" },
|
||||
{ text: "get", link: "/developer/install/cli/user-get" },
|
||||
{ text: "list", link: "/developer/install/cli/user-list" },
|
||||
{ text: "reset-password", link: "/developer/install/cli/user-reset-password" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares versioning",
|
||||
link: "/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Develop Olares apps",
|
||||
link: "/developer/develop/",
|
||||
items: [
|
||||
{
|
||||
text: "Develop with Studio",
|
||||
collapsed: true,
|
||||
link: "/developer/develop/tutorial/",
|
||||
items: [
|
||||
{
|
||||
text: "Deploy an app",
|
||||
link: "/developer/develop/tutorial/deploy",
|
||||
},
|
||||
{
|
||||
text: "Develop in a dev container",
|
||||
link: "/developer/develop/tutorial/develop",
|
||||
},
|
||||
{
|
||||
text: "Package and upload",
|
||||
link: "/developer/develop/tutorial/package-upload",
|
||||
},
|
||||
{
|
||||
text: "Add app assets",
|
||||
link: "/developer/develop/tutorial/assets",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Application package",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Application chart",
|
||||
link: "/developer/develop/package/chart",
|
||||
},
|
||||
{
|
||||
text: "OlaresManifest",
|
||||
link: "/developer/develop/package/manifest",
|
||||
},
|
||||
/*{
|
||||
text: "Recommendation",
|
||||
link: "/developer/develop/package/recommend",
|
||||
},*/
|
||||
{
|
||||
text: "Helm extension",
|
||||
link: "/developer/develop/package/extension",
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// text: "Advanced",
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {
|
||||
// text: "terminus-info",
|
||||
// link: "/developer/develop/advanced/terminus-info",
|
||||
// },
|
||||
// {
|
||||
// text: "Service provider",
|
||||
// link: "/developer/develop/advanced/provider",
|
||||
// },
|
||||
// {
|
||||
// text: "AI",
|
||||
// link: "/developer/develop/advanced/ai",
|
||||
// },
|
||||
// { text: "Cookie", link: "/developer/develop/advanced/cookie" },
|
||||
// { text: "Database", link: "/developer/develop/advanced/database" },
|
||||
// {
|
||||
// text: "Account",
|
||||
// link: "/developer/develop/advanced/account",
|
||||
// },
|
||||
// {
|
||||
// text: "Market",
|
||||
// link: "/developer/develop/advanced/market",
|
||||
// },
|
||||
// {
|
||||
// text: "Websocket",
|
||||
// link: "/developer/develop/advanced/websocket",
|
||||
// },
|
||||
// {
|
||||
// text: "File upload",
|
||||
// link: "/developer/develop/advanced/file-upload",
|
||||
// },
|
||||
// {
|
||||
// text: "Secret",
|
||||
// link: "/developer/develop/advanced/secret",
|
||||
// },
|
||||
// {
|
||||
// text: "Kubesphere",
|
||||
// link: "/developer/develop/advanced/kubesphere",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
text: "Middleware",
|
||||
link: "/developer/develop/mw-overview",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Elasticsearch",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with Elasticsearch",
|
||||
link: "/developer/develop/mw-integrate-with-es", },
|
||||
{
|
||||
text: "View Elasticsearch data",
|
||||
link: "/developer/develop/mw-view-es-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Grafana",
|
||||
link :"/developer/develop/mw-view-grafana-data",
|
||||
},
|
||||
{
|
||||
text: "MariaDB",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with MariaDB",
|
||||
link: "/developer/develop/mw-integrate-with-mariadb", },
|
||||
{
|
||||
text: "View MariaDB data",
|
||||
link: "/developer/develop/mw-view-mariadb-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "MinIO",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with MinIO",
|
||||
link: "/developer/develop/mw-integrate-with-minio", },
|
||||
{
|
||||
text: "View MinIO data",
|
||||
link: "/developer/develop/mw-view-minio-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "MongoDB",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with MongoDB",
|
||||
link: "/developer/develop/mw-integrate-with-mongodb", },
|
||||
{
|
||||
text: "View MongoDB data",
|
||||
link: "/developer/develop/mw-view-mongodb-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "MySQL",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with MySQL",
|
||||
link: "/developer/develop/mw-integrate-with-mysql", },
|
||||
{
|
||||
text: "View MySQL data",
|
||||
link: "/developer/develop/mw-view-mysql-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "NATS",
|
||||
link :"/developer/develop/mw-view-nats-data",
|
||||
},
|
||||
{
|
||||
text: "OpenTelemetry",
|
||||
link :"/developer/develop/mw-view-otel-data",
|
||||
},
|
||||
{
|
||||
text: "PostgreSQL",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with PostgreSQL",
|
||||
link: "/developer/develop/mw-integrate-with-pg", },
|
||||
{
|
||||
text: "View PostgreSQL data",
|
||||
link: "/developer/develop/mw-view-pg-data",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "RabbitMQ",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with RabbitMQ",
|
||||
link: "/developer/develop/mw-integrate-with-rabbitmq", },
|
||||
{
|
||||
text: "View RabbitMQ data",
|
||||
link: "/developer/develop/mw-view-rabbitmq-data",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Redis",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "Integrate with Redis",
|
||||
link: "/developer/develop/mw-integrate-with-redis", },
|
||||
{
|
||||
text: "View Redis data",
|
||||
link: "/developer/develop/mw-view-redis-data",
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Distribute Olares apps",
|
||||
link: "/developer/develop/distribute-index",
|
||||
items: [
|
||||
{
|
||||
text: "Summit apps",
|
||||
link: "/developer/develop/submit-apps",
|
||||
},
|
||||
{
|
||||
text: "Manage app lifecycle",
|
||||
link: "/developer/develop/manage-apps",
|
||||
},
|
||||
{
|
||||
text: "Promote your apps",
|
||||
link:"/developer/develop/promote-apps"
|
||||
},
|
||||
{
|
||||
text: "Publish paid apps",
|
||||
link: "/developer/develop/paid-apps",
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Contribute to Olares",
|
||||
items: [
|
||||
{
|
||||
text: "Develop system app",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Overview",
|
||||
link: "/developer/contribute/system-app/overview",
|
||||
},
|
||||
{
|
||||
text: "Configure deployment",
|
||||
link: "/developer/contribute/system-app/deployment",
|
||||
},
|
||||
{
|
||||
text: "Configure permissions",
|
||||
link: "/developer/contribute/system-app/olares-manifest",
|
||||
},
|
||||
{
|
||||
text: "Install",
|
||||
link: "/developer/contribute/system-app/install",
|
||||
},
|
||||
{
|
||||
text: "Other",
|
||||
link: "/developer/contribute/system-app/other",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Develop protocols",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Contract",
|
||||
link: "/developer/contribute/olares-id/contract/contract",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Architecture",
|
||||
link: "/developer/contribute/olares-id/contract/architecture",
|
||||
},
|
||||
{
|
||||
text: "DID",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Design",
|
||||
link: "/developer/contribute/olares-id/contract/did/design",
|
||||
},
|
||||
{
|
||||
text: "Official Taggers",
|
||||
link: "/developer/contribute/olares-id/contract/did/official-taggers",
|
||||
},
|
||||
{
|
||||
text: "Release History",
|
||||
link: "/developer/contribute/olares-id/contract/did/release-history",
|
||||
},
|
||||
{
|
||||
text: "FAQ",
|
||||
link: "/developer/contribute/olares-id/contract/did/faq",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Reputation",
|
||||
link: "/developer/contribute/olares-id/contract/contract-reputation",
|
||||
},
|
||||
{
|
||||
text: "Manage",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Contract",
|
||||
link: "/developer/contribute/olares-id/contract/manage/contract",
|
||||
},
|
||||
{
|
||||
text: "SDK",
|
||||
link: "/developer/contribute/olares-id/contract/manage/sdk",
|
||||
},
|
||||
{
|
||||
text: "Environment",
|
||||
link: "/developer/contribute/olares-id/contract/manage/environment",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Verifiable Credential",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/overview",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Issuer",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/issuer",
|
||||
},
|
||||
{
|
||||
text: "Verifer",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/verifer",
|
||||
},
|
||||
{
|
||||
text: "Olares",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
492
docs/.vitepress/developer.zh.ts
Normal file
492
docs/.vitepress/developer.zh.ts
Normal file
@@ -0,0 +1,492 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
export const developerSidebar: DefaultTheme.Sidebar = {
|
||||
"/zh/developer/": [
|
||||
{
|
||||
text: "概念",
|
||||
link: "/zh/developer/concepts/",
|
||||
items: [
|
||||
{ text: "系统架构", link: "/zh/developer/concepts/system-architecture" },
|
||||
{
|
||||
text: "Olares ID",
|
||||
link: "/zh/developer/concepts/olares-id",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "去中心化标识符",
|
||||
link: "/zh/developer/concepts/did",
|
||||
},
|
||||
{
|
||||
text: "DID Registry",
|
||||
link: "/zh/developer/concepts/registry",
|
||||
},
|
||||
{
|
||||
text: "可验证凭证",
|
||||
link: "/zh/developer/concepts/vc",
|
||||
},
|
||||
{
|
||||
text: "自治声誉",
|
||||
link: "/zh/developer/concepts/reputation",
|
||||
},
|
||||
// {
|
||||
// text: "主权网络",
|
||||
// link: "/zh/developer/concepts/self-sovereign-network",
|
||||
// },
|
||||
{
|
||||
text: "身份钱包",
|
||||
link: "/zh/developer/concepts/wallet",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "账户", link: "/zh/developer/concepts/account" },
|
||||
{ text: "应用", link: "/zh/developer/concepts/application" },
|
||||
{ text: "网络", link: "/zh/developer/concepts/network" },
|
||||
{ text: "数据", link: "/zh/developer/concepts/data" },
|
||||
{ text: "密钥", link: "/zh/developer/concepts/secrets" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares 安装详解",
|
||||
link: "/zh/developer/install/",
|
||||
items: [
|
||||
{
|
||||
text: "安装概述",
|
||||
link: "/zh/developer/install/installation-overview",
|
||||
},
|
||||
{
|
||||
text: "安装流程",
|
||||
link: "/zh/developer/install/installation-process",
|
||||
},
|
||||
{
|
||||
text: "Olares Home",
|
||||
link: "/zh/developer/install/olares-home",
|
||||
},
|
||||
{
|
||||
text: "环境变量",
|
||||
link: "/zh/developer/install/environment-variables",
|
||||
},
|
||||
{
|
||||
text: "Olares CLI",
|
||||
link: "/zh/developer/install/cli/olares-cli",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "backups",
|
||||
link: "/zh/developer/install/cli/backups",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "backup", link: "/zh/developer/install/cli/backups-backup" },
|
||||
{ text: "download", link: "/zh/developer/install/cli/backups-download" },
|
||||
{ text: "region", link: "/zh/developer/install/cli/backups-region" },
|
||||
{ text: "restore", link: "/zh/developer/install/cli/backups-restore" },
|
||||
{ text: "snapshots", link: "/zh/developer/install/cli/backups-snapshots" },
|
||||
],
|
||||
},
|
||||
{ text: "change-ip", link: "/zh/developer/install/cli/change-ip" },
|
||||
{ text: "disk", link: "/zh/developer/install/cli/disk" },
|
||||
{ text: "download", link: "/zh/developer/install/cli/download" },
|
||||
{ text: "gpu", link: "/zh/developer/install/cli/gpu" },
|
||||
{ text: "info", link: "/zh/developer/install/cli/info" },
|
||||
{ text: "install", link: "/zh/developer/install/cli/install" },
|
||||
{ text: "logs", link: "/zh/developer/install/cli/logs" },
|
||||
{ text: "node", link: "/zh/developer/install/cli/node" },
|
||||
{ text: "osinfo", link: "/zh/developer/install/cli/osinfo" },
|
||||
{ text: "precheck", link: "/zh/developer/install/cli/precheck" },
|
||||
{ text: "prepare", link: "/zh/developer/install/cli/prepare" },
|
||||
{ text: "release", link: "/zh/developer/install/cli/release" },
|
||||
{ text: "start", link: "/zh/developer/install/cli/start" },
|
||||
{ text: "stop", link: "/zh/developer/install/cli/stop" },
|
||||
{ text: "uninstall", link: "/zh/developer/install/cli/uninstall" },
|
||||
{ text: "upgrade", link: "/zh/developer/install/cli/upgrade" },
|
||||
{
|
||||
text: "user",
|
||||
link: "/zh/developer/install/cli/user",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "activate", link: "/zh/developer/install/cli/user-activate" },
|
||||
{ text: "create", link: "/zh/developer/install/cli/user-create" },
|
||||
{ text: "delete", link: "/zh/developer/install/cli/user-delete" },
|
||||
{ text: "get", link: "/zh/developer/install/cli/user-get" },
|
||||
{ text: "list", link: "/zh/developer/install/cli/user-list" },
|
||||
{ text: "reset-password", link: "/zh/developer/install/cli/user-reset-password" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "版本说明",
|
||||
link: "/zh/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "开发 Olares 应用",
|
||||
link: "/zh/developer/develop/",
|
||||
items: [
|
||||
{
|
||||
text: "使用 Studio 开发",
|
||||
collapsed: true,
|
||||
link: "/zh/developer/develop/tutorial/",
|
||||
items: [
|
||||
{
|
||||
text: "部署应用",
|
||||
link: "/zh/developer/develop/tutorial/deploy",
|
||||
},
|
||||
{
|
||||
text: "使用开发容器",
|
||||
link: "/zh/developer/develop/tutorial/develop",
|
||||
},
|
||||
{
|
||||
text: "打包与上传",
|
||||
link: "/zh/developer/develop/tutorial/package-upload",
|
||||
},
|
||||
{
|
||||
text: "添加应用素材",
|
||||
link: "/zh/developer/develop/tutorial/assets",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "应用包管理",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "应用 Chart 包",
|
||||
link: "/zh/developer/develop/package/chart",
|
||||
},
|
||||
{
|
||||
text: "OlaresManifest",
|
||||
link: "/zh/developer/develop/package/manifest",
|
||||
},
|
||||
/*{
|
||||
text: "推荐算法",
|
||||
link: "/zh/developer/develop/package/recommend",
|
||||
},*/
|
||||
{
|
||||
text: "Helm 扩展",
|
||||
link: "/zh/developer/develop/package/extension",
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// text: "进阶",
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {
|
||||
// text: "terminus-info",
|
||||
// link: "/zh/developer/develop/advanced/terminus-info",
|
||||
// },
|
||||
// {
|
||||
// text: "Service Provider",
|
||||
// link: "/zh/developer/develop/advanced/provider",
|
||||
// },
|
||||
// {
|
||||
// text: "AI",
|
||||
// link: "/zh/developer/develop/advanced/ai",
|
||||
// },
|
||||
// { text: "Cookie", link: "/zh/developer/develop/advanced/cookie" },
|
||||
// { text: "数据库", link: "/zh/developer/develop/advanced/database" },
|
||||
// {
|
||||
// text: "账户",
|
||||
// link: "/zh/developer/develop/advanced/account",
|
||||
// },
|
||||
// {
|
||||
// text: "应用市场",
|
||||
// link: "/zh/developer/develop/advanced/market",
|
||||
// },
|
||||
// {
|
||||
// text: "Analytic",
|
||||
// link: "/zh/developer/develop/advanced/analytic",
|
||||
// },
|
||||
// {
|
||||
// text: "Websocket",
|
||||
// link: "/zh/developer/develop/advanced/websocket",
|
||||
// },
|
||||
// {
|
||||
// text: "文件上传",
|
||||
// link: "/zh/developer/develop/advanced/file-upload",
|
||||
// },
|
||||
// {
|
||||
// text: "Rss",
|
||||
// link: "/zh/developer/develop/advanced/rss",
|
||||
// },
|
||||
// {
|
||||
// text: "密钥",
|
||||
// link: "/zh/developer/develop/advanced/secret",
|
||||
// },
|
||||
// {
|
||||
// text: "Notification",
|
||||
// link: "/zh/developer/develop/advanced/notification",
|
||||
// },
|
||||
// {
|
||||
// text: "Frontend",
|
||||
// link: "/zh/developer/develop/advanced/frontend",
|
||||
// },
|
||||
// {
|
||||
// text: "Kubesphere",
|
||||
// link: "/zh/developer/develop/advanced/kubesphere",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
text: "中间件",
|
||||
link: "/zh/developer/develop/mw-overview",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Elasticsearch",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 Elasticsearch",
|
||||
link: "zh/developer/develop/mw-integrate-with-es", },
|
||||
{
|
||||
text: "查看 Elasticsearch 数据",
|
||||
link: "zh/developer/develop/mw-view-es-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Grafana",
|
||||
link: "zh/developer/develop/mw-view-grafana-data",
|
||||
},
|
||||
{
|
||||
text: "MariaDB",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 MariaDB",
|
||||
link: "zh/developer/develop/mw-integrate-with-mariadb", },
|
||||
{
|
||||
text: "查看 MariaDB 数据",
|
||||
link: "zh/developer/develop/mw-view-mariadb-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "MinIO",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 MinIO",
|
||||
link: "zh/developer/develop/mw-integrate-with-minio", },
|
||||
{
|
||||
text: "查看 MinIO 数据",
|
||||
link: "zh/developer/develop/mw-view-minio-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "MongoDB",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 MongoDB",
|
||||
link: "zh/developer/develop/mw-integrate-with-mongodb", },
|
||||
{
|
||||
text: "查看 MongoDB 数据",
|
||||
link: "zh/developer/develop/mw-view-mongodb-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "MySQL",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 MySQL",
|
||||
link: "zh/developer/develop/mw-integrate-with-mysql", },
|
||||
{
|
||||
text: "查看 MySQL 数据",
|
||||
link: "zh/developer/develop/mw-view-mysql-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "NATS",
|
||||
link :"zh/developer/develop/mw-view-nats-data",
|
||||
},
|
||||
{
|
||||
text: "OpenTelemetry",
|
||||
link :"zh/developer/develop/mw-view-otel-data",
|
||||
},
|
||||
{
|
||||
text: "PostgreSQL",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 PostgreSQL",
|
||||
link: "zh/developer/develop/mw-integrate-with-pg", },
|
||||
{
|
||||
text: "查看 PostgreSQL 数据",
|
||||
link: "zh/developer/develop/mw-view-pg-data",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "RabbitMQ",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 RabbitMQ",
|
||||
link: "zh/developer/develop/mw-integrate-with-rabbitmq", },
|
||||
{
|
||||
text: "查看 RabbitMQ 数据",
|
||||
link: "zh/developer/develop/mw-view-rabbitmq-data",
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Redis",
|
||||
collapsed: true,
|
||||
items :[
|
||||
{
|
||||
text: "集成 Redis",
|
||||
link: "zh/developer/develop/mw-integrate-with-redis", },
|
||||
{
|
||||
text: "查看 Redis 数据",
|
||||
link: "zh/developer/develop/mw-view-redis-data",
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "分发 Olares 应用",
|
||||
link: "/zh/developer/develop/distribute-index",
|
||||
items: [
|
||||
{
|
||||
text: "提交应用",
|
||||
link: "/zh/developer/develop/submit-apps",
|
||||
},
|
||||
{
|
||||
text: "管理应用",
|
||||
link: "/zh/developer/develop/manage-apps",
|
||||
},
|
||||
{
|
||||
text: "推广应用",
|
||||
link:"/zh/developer/develop/promote-apps"
|
||||
},
|
||||
{
|
||||
text: "发布付费应用",
|
||||
link: "/zh/developer/develop/paid-apps",
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "参与贡献",
|
||||
items: [
|
||||
{
|
||||
text: "开发系统应用",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "概述",
|
||||
link: "/zh/developer/contribute/system-app/overview",
|
||||
},
|
||||
{
|
||||
text: "应用部署配置",
|
||||
link: "/zh/developer/contribute/system-app/deployment",
|
||||
},
|
||||
{
|
||||
text: "Olares 权限配置",
|
||||
link: "/zh/developer/contribute/system-app/olares-manifest",
|
||||
},
|
||||
{
|
||||
text: "安装",
|
||||
link: "/zh/developer/contribute/system-app/install",
|
||||
},
|
||||
{
|
||||
text: "其他",
|
||||
link: "/zh/developer/contribute/system-app/other",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "开发协议",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "合约",
|
||||
link: "/zh/developer/contribute/olares-id/contract/contract",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "架构",
|
||||
link: "/zh/developer/contribute/olares-id/contract/architecture",
|
||||
},
|
||||
{
|
||||
text: "DID",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "设计",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/design",
|
||||
},
|
||||
{
|
||||
text: "官方 Tagger",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/official-taggers",
|
||||
},
|
||||
{
|
||||
text: "发布历史",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/release-history",
|
||||
},
|
||||
{
|
||||
text: "FAQ",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/faq",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "声誉",
|
||||
link: "/zh/developer/contribute/olares-id/contract/contract-reputation",
|
||||
},
|
||||
{
|
||||
text: "管理",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "合约",
|
||||
link: "/zh/developer/contribute/olares-id/contract/manage/contract",
|
||||
},
|
||||
{
|
||||
text: "SDK",
|
||||
link: "/zh/developer/contribute/olares-id/contract/manage/sdk",
|
||||
},
|
||||
{
|
||||
text: "环境",
|
||||
link: "/zh/developer/contribute/olares-id/contract/manage/environment",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "可验证凭证(VC)",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/overview",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "发行方",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/issuer",
|
||||
},
|
||||
{
|
||||
text: "验证方",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/verifer",
|
||||
},
|
||||
{
|
||||
text: "Olares 案例",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
import { oneSidebar } from './one.en.ts';
|
||||
import { useCaseSidebar } from './usecase.en.ts';
|
||||
import { developerSidebar } from './developer.en.ts';
|
||||
const side = {
|
||||
"/manual/": [
|
||||
"/manual/": [
|
||||
{
|
||||
text: "What is Olares",
|
||||
link: "/manual/overview",
|
||||
@@ -17,7 +19,7 @@ const side = {
|
||||
link: "/manual/help/olares",
|
||||
},
|
||||
{
|
||||
text: "Installation FAQs",
|
||||
text: "Setup & access FAQs",
|
||||
link: "/manual/help/installation",
|
||||
},
|
||||
{
|
||||
@@ -28,10 +30,21 @@ const side = {
|
||||
// text: "Request support",
|
||||
// link: "/manual/help/request-technical-support",
|
||||
// },
|
||||
// {
|
||||
// text: "Troubleshooting",
|
||||
// link: "/manual/help/troubleshooting",
|
||||
// },
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Troubleshooting",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Insufficient memory or memory not freed",
|
||||
link: "/manual/help/ts-free-memory",
|
||||
},
|
||||
{
|
||||
text: "Missing apps in Market",
|
||||
link: "/manual/help/ts-missing-apps",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -133,53 +146,8 @@ const side = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "LarePass",
|
||||
link: "/manual/larepass/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage accounts",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Create accounts", link: "/manual/larepass/create-account" },
|
||||
{ text: "Back up mnemonics", link: "/manual/larepass/back-up-mnemonics" },
|
||||
{ text: "Manage integrations", link: "/manual/larepass/integrations" },
|
||||
],
|
||||
},
|
||||
{ text: "Use VPN", link: "/manual/larepass/private-network" },
|
||||
{
|
||||
text: "Manage device",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Activate Olares", link: "/manual/larepass/activate-olares" },
|
||||
{ text: "Manage Olares", link: "/manual/larepass/manage-olares" },
|
||||
],
|
||||
},
|
||||
{ text: "Manage files", link: "/manual/larepass/manage-files" },
|
||||
// collapsed: true,
|
||||
//items: [
|
||||
// {text: "Common file operations", link:"/manual/larepass/manage-files"},
|
||||
// {text: "Sync and share", link:"/manual/larepass/sync-share"}
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
text: "Manage passwords",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Autofill passwords", link: "/manual/larepass/autofill" },
|
||||
{ text: "Generate 2FA codes", link: "/manual/larepass/two-factor-verification" },
|
||||
],
|
||||
},
|
||||
/*{
|
||||
text: "Manage knowledge",
|
||||
link: "/manual/larepass/manage-knowledge",
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares applications",
|
||||
collapsed: true,
|
||||
link: "/manual/olares/",
|
||||
items: [
|
||||
{ text: "Desktop", link: "/manual/olares/desktop", },
|
||||
@@ -375,7 +343,7 @@ const side = {
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Change revere proxy",
|
||||
text: "Change reverse proxy",
|
||||
link: "/manual/olares/settings/change-frp",
|
||||
},
|
||||
{
|
||||
@@ -395,13 +363,101 @@ const side = {
|
||||
{ text: "Restore", link: "/manual/olares/settings/restore" },
|
||||
],
|
||||
},
|
||||
{ text: "Developer resources", link: "/manual/olares/settings/developer" },
|
||||
{ text: "Advanced settings", link: "/manual/olares/settings/developer" },
|
||||
]
|
||||
},
|
||||
{ text: "Dashboard", link: "/manual/olares/resources-usage" },
|
||||
{ text: "Profile", link: "/manual/olares/profile" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "LarePass",
|
||||
link: "/manual/larepass/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage accounts",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Create accounts", link: "/manual/larepass/create-account" },
|
||||
{ text: "Back up mnemonics", link: "/manual/larepass/back-up-mnemonics" },
|
||||
{ text: "Manage integrations", link: "/manual/larepass/integrations" },
|
||||
],
|
||||
},
|
||||
{ text: "Use VPN", link: "/manual/larepass/private-network" },
|
||||
{
|
||||
text: "Manage device",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Activate Olares", link: "/manual/larepass/activate-olares" },
|
||||
{ text: "Manage Olares", link: "/manual/larepass/manage-olares" },
|
||||
],
|
||||
},
|
||||
{ text: "Manage files", link: "/manual/larepass/manage-files" },
|
||||
// collapsed: true,
|
||||
//items: [
|
||||
// {text: "Common file operations", link:"/manual/larepass/manage-files"},
|
||||
// {text: "Sync and share", link:"/manual/larepass/sync-share"}
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
text: "Manage passwords",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Autofill passwords", link: "/manual/larepass/autofill" },
|
||||
{ text: "Generate 2FA codes", link: "/manual/larepass/two-factor-verification" },
|
||||
],
|
||||
},
|
||||
/*{
|
||||
text: "Manage knowledge",
|
||||
link: "/manual/larepass/manage-knowledge",
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares Space",
|
||||
link: "/manual/space/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage accounts",
|
||||
link: "/manual/space/manage-accounts",
|
||||
},
|
||||
{
|
||||
text: "Host Olares",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Create Olares",
|
||||
link: "/manual/space/create-olares",
|
||||
},
|
||||
{
|
||||
text: "Manage Olares",
|
||||
link: "/manual/space/manage-olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Host domains",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Set up a custom domain",
|
||||
link: "/manual/space/host-domain",
|
||||
},
|
||||
{
|
||||
text: "Manage a domain",
|
||||
link: "/manual/space/manage-domain",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Back up and restore",
|
||||
link: "/manual/space/backup-restore",
|
||||
},
|
||||
{ text: "Billing", link: "/manual/space/billing" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Tutorials",
|
||||
link: "/manual/best-practices/",
|
||||
@@ -435,475 +491,6 @@ const side = {
|
||||
},
|
||||
{ text: "Glossary", link: "/manual/glossary" },
|
||||
],
|
||||
"/space/": [
|
||||
{
|
||||
text: "Olares Space",
|
||||
link: "/space/",
|
||||
items: [
|
||||
{
|
||||
text: "Manage accounts",
|
||||
link: "/space/manage-accounts",
|
||||
},
|
||||
{
|
||||
text: "Host Olares",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Create Olares",
|
||||
link: "/space/create-olares",
|
||||
},
|
||||
{
|
||||
text: "Manage Olares",
|
||||
link: "/space/manage-olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Host domains",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Set up a custom domain",
|
||||
link: "/space/host-domain",
|
||||
},
|
||||
{
|
||||
text: "Manage a domain",
|
||||
link: "/space/manage-domain",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Back up and restore",
|
||||
link: "/space/backup-restore",
|
||||
},
|
||||
{ text: "Billing", link: "/space/billing" },
|
||||
],
|
||||
},
|
||||
],
|
||||
"/use-cases/": [
|
||||
{
|
||||
text: "Use cases",
|
||||
link: "/use-cases/",
|
||||
items: [
|
||||
{
|
||||
text: "Stable Diffusion",
|
||||
link: "/use-cases/stable-diffusion",
|
||||
},
|
||||
{
|
||||
text: "ComfyUI",
|
||||
link: "/use-cases/comfyui",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage ComfyUI",
|
||||
link: "/use-cases/comfyui-launcher",
|
||||
},
|
||||
{
|
||||
text: "Use ComfyUI for Krita",
|
||||
link: "/use-cases/comfyui-for-krita",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Ollama",
|
||||
link: "/use-cases/ollama",
|
||||
},
|
||||
{
|
||||
text: "Open WebUI",
|
||||
link: "/use-cases/openwebui",
|
||||
},
|
||||
{
|
||||
text: "Perplexica",
|
||||
link: "/use-cases/perplexica",
|
||||
},
|
||||
{
|
||||
text: "Dify",
|
||||
link: "/use-cases/dify",
|
||||
},
|
||||
{
|
||||
text: "Jellyfin",
|
||||
link: "/use-cases/stream-media",
|
||||
},
|
||||
{
|
||||
text: "Steam",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Play directly on Olares",
|
||||
link: "/use-cases/play-games-directly",
|
||||
},
|
||||
{
|
||||
text: "Stream to other devices",
|
||||
link: "/use-cases/stream-game",
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// text: "Redroid",
|
||||
// link: "/use-cases/host-cloud-android",
|
||||
// },
|
||||
{
|
||||
text: "Windows",
|
||||
link: "/use-cases/windows",
|
||||
},
|
||||
{
|
||||
text: "DeerFlow",
|
||||
link: "/use-cases/deerflow",
|
||||
},
|
||||
{
|
||||
text: "Duix.Avatar",
|
||||
link: "/use-cases/duix-avatar",
|
||||
},
|
||||
{
|
||||
text: "ACE-Step",
|
||||
link: "/use-cases/ace-step",
|
||||
},
|
||||
{
|
||||
text: "Stirling PDF",
|
||||
link: "/use-cases/stirling-pdf",
|
||||
},
|
||||
{
|
||||
text: "PDFMathTranslate",
|
||||
link: "/use-cases/pdfmathtranslate",
|
||||
},
|
||||
{
|
||||
text: "LobeChat",
|
||||
link: "/use-cases/lobechat",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"/developer/": [
|
||||
{
|
||||
text: "Concepts",
|
||||
link: "/developer/concepts/",
|
||||
items: [
|
||||
{ text: "Olares architecture", link: "/developer/concepts/system-architecture" },
|
||||
{
|
||||
text: "Olares ID",
|
||||
link: "/developer/concepts/olares-id",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Decentralized ID",
|
||||
link: "/developer/concepts/did",
|
||||
},
|
||||
{
|
||||
text: "Blockchain Registry",
|
||||
link: "/developer/concepts/registry",
|
||||
},
|
||||
{
|
||||
text: "Verifiable Credential",
|
||||
link: "/developer/concepts/vc",
|
||||
},
|
||||
{
|
||||
text: "Autonomous Reputation",
|
||||
link: "/developer/concepts/reputation",
|
||||
},
|
||||
// {
|
||||
// text: "Self-Sovereign Network",
|
||||
// link: "/developer/concepts/self-sovereign-network",
|
||||
// },
|
||||
{
|
||||
text: "Identity Wallet",
|
||||
link: "/developer/concepts/wallet",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "Account", link: "/developer/concepts/account" },
|
||||
{ text: "Application", link: "/developer/concepts/application" },
|
||||
{ text: "Network", link: "/developer/concepts/network" },
|
||||
{ text: "Data", link: "/developer/concepts/data" },
|
||||
{ text: "Secrets", link: "/developer/concepts/secrets" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Installation deep-dive",
|
||||
link: "/developer/install/",
|
||||
items: [
|
||||
{
|
||||
text: "Installation architecture",
|
||||
link: "/developer/install/installation-overview",
|
||||
},
|
||||
{
|
||||
text: "Installation process",
|
||||
link: "/developer/install/installation-process",
|
||||
},
|
||||
{
|
||||
text: "Olares Home",
|
||||
link: "/developer/install/olares-home",
|
||||
},
|
||||
{
|
||||
text: "Environment variables",
|
||||
link: "/developer/install/environment-variables",
|
||||
},
|
||||
{
|
||||
text: "Olares CLI",
|
||||
link: "/developer/install/cli/olares-cli",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "Access Olares terminal", link: "/developer/reference/access-olares-terminal" },
|
||||
{
|
||||
text: "backups",
|
||||
link: "/developer/install/cli/backups",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "backup", link: "/developer/install/cli/backups-backup" },
|
||||
{ text: "download", link: "/developer/install/cli/backups-download" },
|
||||
{ text: "region", link: "/developer/install/cli/backups-region" },
|
||||
{ text: "restore", link: "/developer/install/cli/backups-restore" },
|
||||
{ text: "snapshots", link: "/developer/install/cli/backups-snapshots" },
|
||||
],
|
||||
},
|
||||
{ text: "change-ip", link: "/developer/install/cli/change-ip" },
|
||||
{ text: "disk", link: "/developer/install/cli/disk" },
|
||||
{ text: "download", link: "/developer/install/cli/download" },
|
||||
{ text: "gpu", link: "/developer/install/cli/gpu" },
|
||||
{ text: "info", link: "/developer/install/cli/info" },
|
||||
{ text: "install", link: "/developer/install/cli/install" },
|
||||
{ text: "logs", link: "/developer/install/cli/logs" },
|
||||
{ text: "node", link: "/developer/install/cli/node" },
|
||||
{ text: "osinfo", link: "/developer/install/cli/osinfo" },
|
||||
{ text: "precheck", link: "/developer/install/cli/precheck" },
|
||||
{ text: "prepare", link: "/developer/install/cli/prepare" },
|
||||
{ text: "release", link: "/developer/install/cli/release" },
|
||||
{ text: "start", link: "/developer/install/cli/start" },
|
||||
{ text: "stop", link: "/developer/install/cli/stop" },
|
||||
{ text: "uninstall", link: "/developer/install/cli/uninstall" },
|
||||
{ text: "upgrade", link: "/developer/install/cli/upgrade" },
|
||||
{
|
||||
text: "user",
|
||||
link: "/developer/install/cli/user",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "activate", link: "/developer/install/cli/user-activate" },
|
||||
{ text: "create", link: "/developer/install/cli/user-create" },
|
||||
{ text: "delete", link: "/developer/install/cli/user-delete" },
|
||||
{ text: "get", link: "/developer/install/cli/user-get" },
|
||||
{ text: "list", link: "/developer/install/cli/user-list" },
|
||||
{ text: "reset-password", link: "/developer/install/cli/user-reset-password" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares versioning",
|
||||
link: "/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Develop Olares apps",
|
||||
link: "/developer/develop/",
|
||||
items: [
|
||||
{
|
||||
text: "Develop with Studio",
|
||||
collapsed: true,
|
||||
link: "/developer/develop/tutorial/",
|
||||
items: [
|
||||
{
|
||||
text: "Deploy an app",
|
||||
link: "/developer/develop/tutorial/deploy",
|
||||
},
|
||||
{
|
||||
text: "Develop in a dev container",
|
||||
link: "/developer/develop/tutorial/develop",
|
||||
},
|
||||
{
|
||||
text: "Package and upload",
|
||||
link: "/developer/develop/tutorial/package-upload",
|
||||
},
|
||||
{
|
||||
text: "Add app assets",
|
||||
link: "/developer/develop/tutorial/assets",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Application package",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Application chart",
|
||||
link: "/developer/develop/package/chart",
|
||||
},
|
||||
{
|
||||
text: "OlaresManifest",
|
||||
link: "/developer/develop/package/manifest",
|
||||
},
|
||||
/*{
|
||||
text: "Recommendation",
|
||||
link: "/developer/develop/package/recommend",
|
||||
},*/
|
||||
{
|
||||
text: "Helm extension",
|
||||
link: "/developer/develop/package/extension",
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// text: "Advanced",
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {
|
||||
// text: "terminus-info",
|
||||
// link: "/developer/develop/advanced/terminus-info",
|
||||
// },
|
||||
// {
|
||||
// text: "Service provider",
|
||||
// link: "/developer/develop/advanced/provider",
|
||||
// },
|
||||
// {
|
||||
// text: "AI",
|
||||
// link: "/developer/develop/advanced/ai",
|
||||
// },
|
||||
// { text: "Cookie", link: "/developer/develop/advanced/cookie" },
|
||||
// { text: "Database", link: "/developer/develop/advanced/database" },
|
||||
// {
|
||||
// text: "Account",
|
||||
// link: "/developer/develop/advanced/account",
|
||||
// },
|
||||
// {
|
||||
// text: "Market",
|
||||
// link: "/developer/develop/advanced/market",
|
||||
// },
|
||||
// {
|
||||
// text: "Websocket",
|
||||
// link: "/developer/develop/advanced/websocket",
|
||||
// },
|
||||
// {
|
||||
// text: "File upload",
|
||||
// link: "/developer/develop/advanced/file-upload",
|
||||
// },
|
||||
// {
|
||||
// text: "Secret",
|
||||
// link: "/developer/develop/advanced/secret",
|
||||
// },
|
||||
// {
|
||||
// text: "Kubesphere",
|
||||
// link: "/developer/develop/advanced/kubesphere",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
text: "Submit application",
|
||||
collapsed: true,
|
||||
link: "/developer/develop/submit/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Contribute to Olares",
|
||||
items: [
|
||||
{
|
||||
text: "Develop system app",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Overview",
|
||||
link: "/developer/contribute/system-app/overview",
|
||||
},
|
||||
{
|
||||
text: "Configure deployment",
|
||||
link: "/developer/contribute/system-app/deployment",
|
||||
},
|
||||
{
|
||||
text: "Configure permissions",
|
||||
link: "/developer/contribute/system-app/olares-manifest",
|
||||
},
|
||||
{
|
||||
text: "Install",
|
||||
link: "/developer/contribute/system-app/install",
|
||||
},
|
||||
{
|
||||
text: "Other",
|
||||
link: "/developer/contribute/system-app/other",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Develop protocols",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Contract",
|
||||
link: "/developer/contribute/olares-id/contract/contract",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Architecture",
|
||||
link: "/developer/contribute/olares-id/contract/architecture",
|
||||
},
|
||||
{
|
||||
text: "DID",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Design",
|
||||
link: "/developer/contribute/olares-id/contract/did/design",
|
||||
},
|
||||
{
|
||||
text: "Official Taggers",
|
||||
link: "/developer/contribute/olares-id/contract/did/official-taggers",
|
||||
},
|
||||
{
|
||||
text: "Release History",
|
||||
link: "/developer/contribute/olares-id/contract/did/release-history",
|
||||
},
|
||||
{
|
||||
text: "FAQ",
|
||||
link: "/developer/contribute/olares-id/contract/did/faq",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Reputation",
|
||||
link: "/developer/contribute/olares-id/contract/contract-reputation",
|
||||
},
|
||||
{
|
||||
text: "Manage",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Contract",
|
||||
link: "/developer/contribute/olares-id/contract/manage/contract",
|
||||
},
|
||||
{
|
||||
text: "SDK",
|
||||
link: "/developer/contribute/olares-id/contract/manage/sdk",
|
||||
},
|
||||
{
|
||||
text: "Environment",
|
||||
link: "/developer/contribute/olares-id/contract/manage/environment",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Verifiable Credential",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/overview",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Issuer",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/issuer",
|
||||
},
|
||||
{
|
||||
text: "Verifer",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/verifer",
|
||||
},
|
||||
{
|
||||
text: "Olares",
|
||||
link: "/developer/contribute/olares-id/verifiable-credential/olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const en = defineConfig({
|
||||
@@ -913,12 +500,17 @@ export const en = defineConfig({
|
||||
socialLinks: [{ icon: "github", link: "https://github.com/beclab/olares" }],
|
||||
|
||||
nav: [
|
||||
{ text: "Olares", link: "/manual/overview" },
|
||||
{ text: "Olares Space", link: "/space/" },
|
||||
{ text: "Use Cases", link: "/use-cases/" },
|
||||
{ text: "Developer Guide", link: "/developer/concepts/" },
|
||||
{ text: "Olares OS", link: "/manual/overview" },
|
||||
{ text: "Olares One", link: "/one/" },
|
||||
{ text: "Use cases", link: "/use-cases/" },
|
||||
{ text: "Developer guide", link: "/developer/concepts/" },
|
||||
],
|
||||
|
||||
sidebar: side,
|
||||
sidebar: {
|
||||
...side,
|
||||
...oneSidebar,
|
||||
...useCaseSidebar,
|
||||
...developerSidebar,
|
||||
},
|
||||
},
|
||||
});
|
||||
243
docs/.vitepress/one.en.ts
Normal file
243
docs/.vitepress/one.en.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
export const oneSidebar: DefaultTheme.Sidebar = {
|
||||
"/one/": [
|
||||
{
|
||||
text: "Olares One",
|
||||
link: "/one/",
|
||||
items: [
|
||||
{
|
||||
text: "Technical spec",
|
||||
link: "/one/spec",
|
||||
},
|
||||
{
|
||||
text: "FAQs",
|
||||
link: "/one/faq",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Initial setup",
|
||||
items: [
|
||||
{
|
||||
text: "First boot",
|
||||
link: "/one/first-boot",
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Onboarding",
|
||||
items: [
|
||||
{
|
||||
text: "Open WebUI with Ollama",
|
||||
link: "/one/open-webui",
|
||||
},
|
||||
{
|
||||
text: "Generate images with ComfyUI",
|
||||
link: "/one/comfyui",
|
||||
},
|
||||
{
|
||||
text: "Switch GPU mode",
|
||||
link: "/one/gpu",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Use",
|
||||
items: [
|
||||
{
|
||||
text: "Customize Olares",
|
||||
link: "/one/customize",
|
||||
},
|
||||
{
|
||||
text: "Manage files",
|
||||
link: "/one/files",
|
||||
},
|
||||
{
|
||||
text: "Install & update apps",
|
||||
link: "/one/market",
|
||||
},
|
||||
{
|
||||
text: "Secure passwords",
|
||||
link: "/one/vault",
|
||||
},
|
||||
{
|
||||
text: "Download YouTube videos",
|
||||
link: "/one/wise-download",
|
||||
},
|
||||
{
|
||||
text: "Deploy an app",
|
||||
link: "/one/deploy",
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
// {
|
||||
// text: "Manage",
|
||||
// items: [
|
||||
// {
|
||||
// text: "Set up app entrances",
|
||||
// link: "/one/app-entrances",
|
||||
// },
|
||||
// {
|
||||
// text: "Create users",
|
||||
// link: "/one/users",
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
text: "Monitor",
|
||||
items: [
|
||||
{
|
||||
text: "System resources",
|
||||
link: "/one/dashboard",
|
||||
},
|
||||
{
|
||||
text: "Traffic",
|
||||
link: "/one/space",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Explore",
|
||||
items: [
|
||||
{
|
||||
text: "Play Steam games",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Streaming",
|
||||
link: "/one/steam-stream"
|
||||
},
|
||||
{
|
||||
text: "Direct play",
|
||||
link: "/one/steam-direct-play",
|
||||
}]
|
||||
},
|
||||
{
|
||||
text: "Access Windows in Olares",
|
||||
link: "/one/windows",
|
||||
},
|
||||
{
|
||||
text: "Generate music with Ace-Step",
|
||||
link: "/one/ace-step",
|
||||
},
|
||||
|
||||
{
|
||||
text: "Deep research with DeerFlow",
|
||||
link: "/one/deerflow",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Advanced",
|
||||
items: [
|
||||
{
|
||||
text: "SSH into Olares One",
|
||||
link: "/one/access-terminal-ssh",
|
||||
},
|
||||
{
|
||||
text: "Expand storage",
|
||||
collapsed: true,
|
||||
items:
|
||||
[
|
||||
{
|
||||
text: "USB drive",
|
||||
link: "/one/expand-storage-usb-drive",
|
||||
},
|
||||
{
|
||||
text: "External SSD",
|
||||
link: "/one/expand-storage-external-ssd",
|
||||
},
|
||||
{
|
||||
text: "NVMe SSD",
|
||||
link: "/one/expand-storage-internal-ssd",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Connect two Olares One",
|
||||
link: "/one/connect-two-olares-one"
|
||||
// items:
|
||||
// [
|
||||
// {
|
||||
// text: "Manage GPU",
|
||||
// link: "/one/two-one-gpu",
|
||||
// },
|
||||
// {
|
||||
// text: "Run larger local LLMs",
|
||||
// link: "/one/two-one-llm",
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
{
|
||||
text: "Set up with eGPU",
|
||||
link: "/one/egpu",
|
||||
},
|
||||
{
|
||||
text: "Dual-boot Olares OS with Windows",
|
||||
collapsed: true,
|
||||
items:
|
||||
[
|
||||
{
|
||||
text: "Dual-drive setup (Recommended)",
|
||||
link: "/one/dual-boot-dual-drive",
|
||||
},
|
||||
{
|
||||
text: "Single-drive setup",
|
||||
link: "/one/dual-boot-single-drive",
|
||||
}
|
||||
,
|
||||
{
|
||||
text: "Install drivers on Windows",
|
||||
link: "/one/install-nvidia-driver",
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "System update",
|
||||
items: [
|
||||
{
|
||||
text: "Update OS",
|
||||
link: "/one/update",
|
||||
},
|
||||
{
|
||||
text: "Back up & restore data",
|
||||
link: "/one/backup-resotre",
|
||||
},
|
||||
{
|
||||
text: "Restore Olares One",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Factory reset",
|
||||
link: "/one/factory-reset",
|
||||
},
|
||||
{
|
||||
text: "Restore BIOS defaults",
|
||||
link: "/one/factory-reset-in-bios",
|
||||
},
|
||||
{
|
||||
text: "Reinstall Olares OS",
|
||||
link: "/one/create-drive",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
}
|
||||
243
docs/.vitepress/one.zh.ts
Normal file
243
docs/.vitepress/one.zh.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
export const oneSidebar: DefaultTheme.Sidebar = {
|
||||
"/zh/one/": [
|
||||
{
|
||||
text: "Olares One",
|
||||
link: "/zh/one/",
|
||||
items: [
|
||||
{
|
||||
text: "Technical spec",
|
||||
link: "/zh/one/spec",
|
||||
},
|
||||
{
|
||||
text: "FAQs",
|
||||
link: "/zh/one/faq",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Initial setup",
|
||||
items: [
|
||||
{
|
||||
text: "First boot",
|
||||
link: "/zh/one/first-boot",
|
||||
},
|
||||
{
|
||||
text: "Access Olares via VPN",
|
||||
link: "/zh/one/access-olares-via-vpn",
|
||||
},
|
||||
{
|
||||
text: "Access Olares via .local domain",
|
||||
link: "/zh/one/access-olares-via-local-domain",
|
||||
},
|
||||
{
|
||||
text: "Redeem membership",
|
||||
link: "/zh/one/redeem-membership",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Onboarding",
|
||||
items: [
|
||||
{
|
||||
text: "Open WebUI with Ollama",
|
||||
link: "/zh/one/open-webui",
|
||||
},
|
||||
{
|
||||
text: "Generate images with ComfyUI",
|
||||
link: "/zh/one/comfyui",
|
||||
},
|
||||
{
|
||||
text: "Switch GPU mode",
|
||||
link: "/zh/one/gpu",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Use",
|
||||
items: [
|
||||
{
|
||||
text: "Customize Olares",
|
||||
link: "/zh/one/customize",
|
||||
},
|
||||
{
|
||||
text: "Manage files",
|
||||
link: "/zh/one/files",
|
||||
},
|
||||
{
|
||||
text: "Install & update apps",
|
||||
link: "/zh/one/market",
|
||||
},
|
||||
{
|
||||
text: "Secure passwords",
|
||||
link: "/zh/one/vault",
|
||||
},
|
||||
{
|
||||
text: "Download YouTube videos",
|
||||
link: "/zh/one/wise-download",
|
||||
},
|
||||
{
|
||||
text: "Deploy an app",
|
||||
link: "/zh/one/deploy",
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
// {
|
||||
// text: "Manage",
|
||||
// items: [
|
||||
// {
|
||||
// text: "Set up app entrances",
|
||||
// link: "/zh/one/app-entrances",
|
||||
// },
|
||||
// {
|
||||
// text: "Create users",
|
||||
// link: "/zh/one/users",
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
text: "Monitor",
|
||||
items: [
|
||||
{
|
||||
text: "System resources",
|
||||
link: "/zh/one/dashboard",
|
||||
},
|
||||
{
|
||||
text: "Traffic",
|
||||
link: "/zh/one/space",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Explore",
|
||||
items: [
|
||||
{
|
||||
text: "Play Steam games",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Streaming",
|
||||
link: "/zh/one/steam-stream"
|
||||
},
|
||||
{
|
||||
text: "Direct play",
|
||||
link: "/zh/one/steam-direct-play",
|
||||
}]
|
||||
},
|
||||
{
|
||||
text: "Access Windows in Olares",
|
||||
link: "/zh/one/windows",
|
||||
},
|
||||
{
|
||||
text: "Generate music with Ace-Step",
|
||||
link: "/zh/one/ace-step",
|
||||
},
|
||||
|
||||
{
|
||||
text: "Deep research with DeerFlow",
|
||||
link: "/zh/one/deerflow",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Advanced",
|
||||
items: [
|
||||
{
|
||||
text: "SSH into Olares One",
|
||||
link: "/zh/one/access-terminal-ssh",
|
||||
},
|
||||
{
|
||||
text: "Expand storage",
|
||||
collapsed: true,
|
||||
items:
|
||||
[
|
||||
{
|
||||
text: "USB drive",
|
||||
link: "/zh/one/expand-storage-usb-drive",
|
||||
},
|
||||
{
|
||||
text: "External SSD",
|
||||
link: "/zh/one/expand-storage-external-ssd",
|
||||
},
|
||||
{
|
||||
text: "NVMe SSD",
|
||||
link: "/zh/one/expand-storage-internal-ssd",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Connect two Olares One",
|
||||
link: "/zh/one/connect-two-olares-one",
|
||||
// items:
|
||||
// [
|
||||
// {
|
||||
// text: "Manage GPU",
|
||||
// link: "/zh/one/two-one-gpu",
|
||||
// },
|
||||
// {
|
||||
// text: "Run larger local LLMs",
|
||||
// link: "/zh/one/two-one-llm",
|
||||
// }
|
||||
// ]
|
||||
},
|
||||
{
|
||||
text: "Set up with eGPU",
|
||||
link: "/zh/one/egpu",
|
||||
},
|
||||
{
|
||||
text: "Dual-boot Olares OS with Windows",
|
||||
collapsed: true,
|
||||
items:
|
||||
[
|
||||
{
|
||||
text: "Dual-drive setup (Recommended)",
|
||||
link: "/zh/one/dual-boot-dual-drive",
|
||||
},
|
||||
{
|
||||
text: "Single-drive setup",
|
||||
link: "/zh/one/dual-boot-single-drive",
|
||||
}
|
||||
,
|
||||
{
|
||||
text: "Install drivers on Windows",
|
||||
link: "/zh/one/install-nvidia-driver",
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "System update",
|
||||
items: [
|
||||
{
|
||||
text: "Update OS",
|
||||
link: "/zh/one/update",
|
||||
},
|
||||
{
|
||||
text: "Back up & restore data",
|
||||
link: "/zh/one/backup-resotre",
|
||||
},
|
||||
{
|
||||
text: "Restore Olares One",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Factory reset",
|
||||
link: "/zh/one/factory-reset",
|
||||
},
|
||||
{
|
||||
text: "Restore BIOS defaults",
|
||||
link: "/zh/one/factory-reset-in-bios",
|
||||
},
|
||||
{
|
||||
text: "Reinstall Olares OS",
|
||||
link: "/zh/one/create-drive",
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
],
|
||||
}
|
||||
101
docs/.vitepress/usecase.en.ts
Normal file
101
docs/.vitepress/usecase.en.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
export const useCaseSidebar: DefaultTheme.Sidebar = {
|
||||
"/use-cases/": [
|
||||
{
|
||||
text: "Use cases",
|
||||
link: "/use-cases/",
|
||||
items: [
|
||||
{
|
||||
text: "Stable Diffusion",
|
||||
link: "/use-cases/stable-diffusion",
|
||||
},
|
||||
{
|
||||
text: "ComfyUI",
|
||||
link: "/use-cases/comfyui",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage ComfyUI",
|
||||
link: "/use-cases/comfyui-launcher",
|
||||
},
|
||||
{
|
||||
text: "Use ComfyUI for Krita",
|
||||
link: "/use-cases/comfyui-for-krita",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Ollama",
|
||||
link: "/use-cases/ollama",
|
||||
},
|
||||
{
|
||||
text: "Open WebUI",
|
||||
link: "/use-cases/openwebui",
|
||||
},
|
||||
{
|
||||
text: "Perplexica",
|
||||
link: "/use-cases/perplexica",
|
||||
},
|
||||
{
|
||||
text: "Dify",
|
||||
link: "/use-cases/dify",
|
||||
},
|
||||
{
|
||||
text: "Jellyfin",
|
||||
link: "/use-cases/stream-media",
|
||||
},
|
||||
{
|
||||
text: "Steam",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Play directly on Olares",
|
||||
link: "/use-cases/play-games-directly",
|
||||
},
|
||||
{
|
||||
text: "Stream to other devices",
|
||||
link: "/use-cases/stream-game",
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// text: "Redroid",
|
||||
// link: "/use-cases/host-cloud-android",
|
||||
// },
|
||||
{
|
||||
text: "Windows",
|
||||
link: "/use-cases/windows",
|
||||
},
|
||||
{
|
||||
text: "DeerFlow",
|
||||
link: "/use-cases/deerflow",
|
||||
},
|
||||
{
|
||||
text: "Duix.Avatar",
|
||||
link: "/use-cases/duix-avatar",
|
||||
},
|
||||
{
|
||||
text: "ACE-Step",
|
||||
link: "/use-cases/ace-step",
|
||||
},
|
||||
{
|
||||
text: "Stirling PDF",
|
||||
link: "/use-cases/stirling-pdf",
|
||||
},
|
||||
{
|
||||
text: "PDFMathTranslate",
|
||||
link: "/use-cases/pdfmathtranslate",
|
||||
},
|
||||
{
|
||||
text: "LobeChat",
|
||||
link: "/use-cases/lobechat",
|
||||
},
|
||||
{
|
||||
text: "OpenClaw",
|
||||
link: "/use-cases/openclaw",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
69
docs/.vitepress/usecase.zh.ts
Normal file
69
docs/.vitepress/usecase.zh.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
export const useCaseSidebar: DefaultTheme.Sidebar = {
|
||||
"/zh/use-cases/": [
|
||||
{
|
||||
text: "应用示例",
|
||||
link: "/zh/use-cases/",
|
||||
items: [
|
||||
{
|
||||
text: "Stable Diffusion",
|
||||
link: "/zh/use-cases/stable-diffusion",
|
||||
},
|
||||
{
|
||||
text: "ComfyUI",
|
||||
link: "/zh/use-cases/comfyui",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage ComfyUI",
|
||||
link: "/zh/use-cases/comfyui-launcher",
|
||||
},
|
||||
{
|
||||
text: "Use ComfyUI for Krita",
|
||||
link: "/zh/use-cases/comfyui-for-krita",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Ollama",
|
||||
link: "/zh/use-cases/ollama",
|
||||
},
|
||||
{
|
||||
text: "Open WebUI",
|
||||
link: "/zh/use-cases/openwebui",
|
||||
},
|
||||
{
|
||||
text: "Perplexica",
|
||||
link: "/zh/use-cases/perplexica",
|
||||
},
|
||||
{
|
||||
text: "Dify",
|
||||
link: "/zh/use-cases/dify",
|
||||
},
|
||||
{
|
||||
text: "Jellyfin",
|
||||
link: "/zh/use-cases/stream-media",
|
||||
},
|
||||
{
|
||||
text: "Steam",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "在 Olares 本机游玩",
|
||||
link: "/zh/use-cases/play-games-directly",
|
||||
},
|
||||
{
|
||||
text: "串流到其他设备",
|
||||
link: "/zh/use-cases/stream-game",
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// text: "Redroid",
|
||||
// link: "/zh/use-cases/host-cloud-android",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { defineConfig, type DefaultTheme } from "vitepress";
|
||||
|
||||
import { oneSidebar } from './one.zh.ts';
|
||||
import { useCaseSidebar } from './usecase.zh.ts';
|
||||
import { developerSidebar } from './developer.zh.ts';
|
||||
const side = {
|
||||
"/zh/manual/": [
|
||||
{
|
||||
@@ -17,7 +19,7 @@ const side = {
|
||||
link: "/zh/manual/help/olares",
|
||||
},
|
||||
{
|
||||
text: "安装激活",
|
||||
text: "安装配置与访问",
|
||||
link: "/zh/manual/help/installation",
|
||||
},
|
||||
{
|
||||
@@ -28,10 +30,20 @@ const side = {
|
||||
// text: "技术支持",
|
||||
// link: "/zh/manual/help/request-technical-support",
|
||||
// },
|
||||
// {
|
||||
// text: "Troubleshooting Guide",
|
||||
// link: "/zh/manual/help/troubleshooting-guide",
|
||||
// },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "故障排查",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "内存不足或没有释放",
|
||||
link: "/zh/manual/help/ts-free-memory",
|
||||
},
|
||||
{
|
||||
text: "应用市场应用缺失",
|
||||
link: "/zh/manual/help/ts-missing-apps",
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -132,53 +144,8 @@ const side = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "LarePass",
|
||||
link: "/zh/manual/larepass/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "管理账户",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "创建账户", link: "/zh/manual/larepass/create-account" },
|
||||
{ text: "备份助记词", link: "/zh/manual/larepass/back-up-mnemonics" },
|
||||
{ text: "管理集成", link: "/zh/manual/larepass/integrations" },
|
||||
],
|
||||
},
|
||||
{ text: "使用专用网络", link: "/zh/manual/larepass/private-network" },
|
||||
{
|
||||
text: "管理设备",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "激活 Olares", link: "/zh/manual/larepass/activate-olares" },
|
||||
{ text: "管理 Olares", link: "/zh/manual/larepass/manage-olares" },
|
||||
],
|
||||
},
|
||||
{ text: "管理文件", link: "/zh/manual/larepass/manage-files" },
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {text: "常用文件操作", link:"/zh/manual/larepass/manage-files"},
|
||||
// {text: "同步与共享", link:"/zh/manual/larepass/sync-share"}
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
text: "管理密码",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "自动填充", link: "/zh/manual/larepass/autofill" },
|
||||
{ text: "双重验证", link: "/zh/manual/larepass/two-factor-verification" },
|
||||
],
|
||||
},
|
||||
/*{
|
||||
text: "管理内容",
|
||||
link: "/zh/manual/larepass/manage-knowledge",
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
"text": "Olares 应用",
|
||||
"collapsed": true,
|
||||
"link": "/zh/manual/olares/",
|
||||
"items": [
|
||||
{ "text": "桌面", "link": "/zh/manual/olares/desktop" },
|
||||
@@ -391,7 +358,7 @@ const side = {
|
||||
{ text: "恢复", link: "/zh/manual/olares/settings/restore" },
|
||||
],
|
||||
},
|
||||
{ text: "开发者资源", link: "/zh/manual/olares/settings/developer" },
|
||||
{ text: "高级设置", link: "/zh/manual/olares/settings/developer" },
|
||||
]
|
||||
},
|
||||
{ "text": "仪表盘", "link": "/zh/manual/olares/resources-usage" },
|
||||
@@ -399,9 +366,97 @@ const side = {
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "教程",
|
||||
text: "LarePass",
|
||||
link: "/zh/manual/larepass/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "管理账户",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "创建账户", link: "/zh/manual/larepass/create-account" },
|
||||
{ text: "备份助记词", link: "/zh/manual/larepass/back-up-mnemonics" },
|
||||
{ text: "管理集成", link: "/zh/manual/larepass/integrations" },
|
||||
],
|
||||
},
|
||||
{ text: "使用专用网络", link: "/zh/manual/larepass/private-network" },
|
||||
{
|
||||
text: "管理设备",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "激活 Olares", link: "/zh/manual/larepass/activate-olares" },
|
||||
{ text: "管理 Olares", link: "/zh/manual/larepass/manage-olares" },
|
||||
],
|
||||
},
|
||||
{ text: "管理文件", link: "/zh/manual/larepass/manage-files" },
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {text: "常用文件操作", link:"/zh/manual/larepass/manage-files"},
|
||||
// {text: "同步与共享", link:"/zh/manual/larepass/sync-share"}
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
text: "管理密码",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "自动填充", link: "/zh/manual/larepass/autofill" },
|
||||
{ text: "双重验证", link: "/zh/manual/larepass/two-factor-verification" },
|
||||
],
|
||||
},
|
||||
/*{
|
||||
text: "管理内容",
|
||||
link: "/zh/manual/larepass/manage-knowledge",
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares Space",
|
||||
link: "/zh/manual/space/index",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "管理账号",
|
||||
link: "/zh/manual/space/manage-accounts",
|
||||
},
|
||||
{
|
||||
text: "托管 Olares",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "创建 Olares",
|
||||
link: "/zh/manual/space/create-olares",
|
||||
},
|
||||
{
|
||||
text: "管理 Olares",
|
||||
link: "/zh/manual/space/manage-olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "托管域名",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "设置自定义域名",
|
||||
link: "/zh/manual/space/host-domain",
|
||||
},
|
||||
{
|
||||
text: "管理域名",
|
||||
link: "/zh/manual/space/manage-domain",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "备份与恢复",
|
||||
link: "/zh/manual/space/backup-restore",
|
||||
},
|
||||
{ text: "计费", link: "/zh/manual/space/billing" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "教程",
|
||||
link: "/zh/manual/best-practices/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "设置自定义域名",
|
||||
@@ -429,470 +484,12 @@ const side = {
|
||||
},
|
||||
{
|
||||
text: "本地访问 Olares",
|
||||
link: "/manual/best-practices/local-access",
|
||||
link: "/zh/manual/best-practices/local-access",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "术语", link: "/zh/manual/glossary" },
|
||||
],
|
||||
"/zh/space/": [
|
||||
{
|
||||
text: "Olares Space",
|
||||
link: "/zh/space/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "管理账号",
|
||||
link: "/zh/space/manage-accounts",
|
||||
},
|
||||
{
|
||||
text: "托管 Olares",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "创建 Olares",
|
||||
link: "/zh/space/create-olares",
|
||||
},
|
||||
{
|
||||
text: "管理 Olares",
|
||||
link: "/zh/space/manage-olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "托管域名",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "设置自定义域名",
|
||||
link: "/zh/space/host-domain",
|
||||
},
|
||||
{
|
||||
text: "管理域名",
|
||||
link: "/zh/space/manage-domain",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "备份与恢复",
|
||||
link: "/zh/space/backup-restore",
|
||||
},
|
||||
{ text: "计费", link: "/zh/space/billing" },
|
||||
],
|
||||
},
|
||||
],
|
||||
"/zh/use-cases/": [
|
||||
{
|
||||
text: "应用示例",
|
||||
link: "/zh/use-cases/",
|
||||
items: [
|
||||
{
|
||||
text: "Stable Diffusion",
|
||||
link: "/zh/use-cases/stable-diffusion",
|
||||
},
|
||||
{
|
||||
text: "ComfyUI",
|
||||
link: "/zh/use-cases/comfyui",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Manage ComfyUI",
|
||||
link: "/zh/use-cases/comfyui-launcher",
|
||||
},
|
||||
{
|
||||
text: "Use ComfyUI for Krita",
|
||||
link: "/zh/use-cases/comfyui-for-krita",
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Ollama",
|
||||
link: "/zh/use-cases/ollama",
|
||||
},
|
||||
{
|
||||
text: "Open WebUI",
|
||||
link: "/zh/use-cases/openwebui",
|
||||
},
|
||||
{
|
||||
text: "Perplexica",
|
||||
link: "/zh/use-cases/perplexica",
|
||||
},
|
||||
{
|
||||
text: "Dify",
|
||||
link: "/zh/use-cases/dify",
|
||||
},
|
||||
{
|
||||
text: "Jellyfin",
|
||||
link: "/zh/use-cases/stream-media",
|
||||
},
|
||||
{
|
||||
text: "Steam",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "在 Olares 本机游玩",
|
||||
link: "/zh/use-cases/play-games-directly",
|
||||
},
|
||||
{
|
||||
text: "串流到其他设备",
|
||||
link: "/zh/use-cases/stream-game",
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// text: "Redroid",
|
||||
// link: "/zh/use-cases/host-cloud-android",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
"/zh/developer/": [
|
||||
{
|
||||
text: "概念",
|
||||
link: "/zh/developer/concepts/",
|
||||
items: [
|
||||
{ text: "系统架构", link: "/zh/developer/concepts/system-architecture" },
|
||||
{
|
||||
text: "Olares ID",
|
||||
link: "/zh/developer/concepts/olares-id",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "去中心化标识符",
|
||||
link: "/zh/developer/concepts/did",
|
||||
},
|
||||
{
|
||||
text: "DID Registry",
|
||||
link: "/zh/developer/concepts/registry",
|
||||
},
|
||||
{
|
||||
text: "可验证凭证",
|
||||
link: "/zh/developer/concepts/vc",
|
||||
},
|
||||
{
|
||||
text: "自治声誉",
|
||||
link: "/zh/developer/concepts/reputation",
|
||||
},
|
||||
// {
|
||||
// text: "主权网络",
|
||||
// link: "/zh/developer/concepts/self-sovereign-network",
|
||||
// },
|
||||
{
|
||||
text: "身份钱包",
|
||||
link: "/zh/developer/concepts/wallet",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "账户", link: "/zh/developer/concepts/account" },
|
||||
{ text: "应用", link: "/zh/developer/concepts/application" },
|
||||
{ text: "网络", link: "/zh/developer/concepts/network" },
|
||||
{ text: "数据", link: "/zh/developer/concepts/data" },
|
||||
{ text: "密钥", link: "/zh/developer/concepts/secrets" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares 安装详解",
|
||||
link: "/zh/developer/install/",
|
||||
items: [
|
||||
{
|
||||
text: "安装概述",
|
||||
link: "/zh/developer/install/installation-overview",
|
||||
},
|
||||
{
|
||||
text: "安装流程",
|
||||
link: "/zh/developer/install/installation-process",
|
||||
},
|
||||
{
|
||||
text: "Olares Home",
|
||||
link: "/zh/developer/install/olares-home",
|
||||
},
|
||||
{
|
||||
text: "环境变量",
|
||||
link: "/zh/developer/install/environment-variables",
|
||||
},
|
||||
{
|
||||
text: "Olares CLI",
|
||||
link: "/zh/developer/install/cli/olares-cli",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "访问 Olares 终端", link: "/zh/developer/reference/access-olares-terminal" },
|
||||
{
|
||||
text: "backups",
|
||||
link: "/zh/developer/install/cli/backups",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "backup", link: "/zh/developer/install/cli/backups-backup" },
|
||||
{ text: "download", link: "/zh/developer/install/cli/backups-download" },
|
||||
{ text: "region", link: "/zh/developer/install/cli/backups-region" },
|
||||
{ text: "restore", link: "/zh/developer/install/cli/backups-restore" },
|
||||
{ text: "snapshots", link: "/zh/developer/install/cli/backups-snapshots" },
|
||||
],
|
||||
},
|
||||
{ text: "change-ip", link: "/zh/developer/install/cli/change-ip" },
|
||||
{ text: "disk", link: "/zh/developer/install/cli/disk" },
|
||||
{ text: "download", link: "/zh/developer/install/cli/download" },
|
||||
{ text: "gpu", link: "/zh/developer/install/cli/gpu" },
|
||||
{ text: "info", link: "/zh/developer/install/cli/info" },
|
||||
{ text: "install", link: "/zh/developer/install/cli/install" },
|
||||
{ text: "logs", link: "/zh/developer/install/cli/logs" },
|
||||
{ text: "node", link: "/zh/developer/install/cli/node" },
|
||||
{ text: "osinfo", link: "/zh/developer/install/cli/osinfo" },
|
||||
{ text: "precheck", link: "/zh/developer/install/cli/precheck" },
|
||||
{ text: "prepare", link: "/zh/developer/install/cli/prepare" },
|
||||
{ text: "release", link: "/zh/developer/install/cli/release" },
|
||||
{ text: "start", link: "/zh/developer/install/cli/start" },
|
||||
{ text: "stop", link: "/zh/developer/install/cli/stop" },
|
||||
{ text: "uninstall", link: "/zh/developer/install/cli/uninstall" },
|
||||
{ text: "upgrade", link: "/zh/developer/install/cli/upgrade" },
|
||||
{
|
||||
text: "user",
|
||||
link: "/zh/developer/install/cli/user",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "activate", link: "/zh/developer/install/cli/user-activate" },
|
||||
{ text: "create", link: "/zh/developer/install/cli/user-create" },
|
||||
{ text: "delete", link: "/zh/developer/install/cli/user-delete" },
|
||||
{ text: "get", link: "/zh/developer/install/cli/user-get" },
|
||||
{ text: "list", link: "/zh/developer/install/cli/user-list" },
|
||||
{ text: "reset-password", link: "/zh/developer/install/cli/user-reset-password" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "版本说明",
|
||||
link: "/zh/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "开发 Olares 应用",
|
||||
link: "/zh/developer/develop/",
|
||||
items: [
|
||||
{
|
||||
text: "使用 Studio 开发",
|
||||
collapsed: true,
|
||||
link: "/zh/developer/develop/tutorial/",
|
||||
items: [
|
||||
{
|
||||
text: "部署应用",
|
||||
link: "/zh/developer/develop/tutorial/deploy",
|
||||
},
|
||||
{
|
||||
text: "使用开发容器",
|
||||
link: "/zh/developer/develop/tutorial/develop",
|
||||
},
|
||||
{
|
||||
text: "打包与上传",
|
||||
link: "/zh/developer/develop/tutorial/package-upload",
|
||||
},
|
||||
{
|
||||
text: "添加应用素材",
|
||||
link: "/zh/developer/develop/tutorial/assets",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "应用包管理",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "应用 Chart 包",
|
||||
link: "/zh/developer/develop/package/chart",
|
||||
},
|
||||
{
|
||||
text: "OlaresManifest",
|
||||
link: "/zh/developer/develop/package/manifest",
|
||||
},
|
||||
/*{
|
||||
text: "推荐算法",
|
||||
link: "/zh/developer/develop/package/recommend",
|
||||
},*/
|
||||
{
|
||||
text: "Helm 扩展",
|
||||
link: "/zh/developer/develop/package/extension",
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// text: "进阶",
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {
|
||||
// text: "terminus-info",
|
||||
// link: "/zh/developer/develop/advanced/terminus-info",
|
||||
// },
|
||||
// {
|
||||
// text: "Service Provider",
|
||||
// link: "/zh/developer/develop/advanced/provider",
|
||||
// },
|
||||
// {
|
||||
// text: "AI",
|
||||
// link: "/zh/developer/develop/advanced/ai",
|
||||
// },
|
||||
// { text: "Cookie", link: "/zh/developer/develop/advanced/cookie" },
|
||||
// { text: "数据库", link: "/zh/developer/develop/advanced/database" },
|
||||
// {
|
||||
// text: "账户",
|
||||
// link: "/zh/developer/develop/advanced/account",
|
||||
// },
|
||||
// {
|
||||
// text: "应用市场",
|
||||
// link: "/zh/developer/develop/advanced/market",
|
||||
// },
|
||||
// {
|
||||
// text: "Analytic",
|
||||
// link: "/zh/developer/develop/advanced/analytic",
|
||||
// },
|
||||
// {
|
||||
// text: "Websocket",
|
||||
// link: "/zh/developer/develop/advanced/websocket",
|
||||
// },
|
||||
// {
|
||||
// text: "文件上传",
|
||||
// link: "/zh/developer/develop/advanced/file-upload",
|
||||
// },
|
||||
// {
|
||||
// text: "Rss",
|
||||
// link: "/zh/developer/develop/advanced/rss",
|
||||
// },
|
||||
// {
|
||||
// text: "密钥",
|
||||
// link: "/zh/developer/develop/advanced/secret",
|
||||
// },
|
||||
// {
|
||||
// text: "Notification",
|
||||
// link: "/zh/developer/develop/advanced/notification",
|
||||
// },
|
||||
// {
|
||||
// text: "Frontend",
|
||||
// link: "/zh/developer/develop/advanced/frontend",
|
||||
// },
|
||||
// {
|
||||
// text: "Kubesphere",
|
||||
// link: "/zh/developer/develop/advanced/kubesphere",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
text: "提交应用",
|
||||
collapsed: true,
|
||||
link: "/zh/developer/develop/submit/",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "参与贡献",
|
||||
items: [
|
||||
{
|
||||
text: "开发系统应用",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "概述",
|
||||
link: "/zh/developer/contribute/system-app/overview",
|
||||
},
|
||||
{
|
||||
text: "应用部署配置",
|
||||
link: "/zh/developer/contribute/system-app/deployment",
|
||||
},
|
||||
{
|
||||
text: "Olares 权限配置",
|
||||
link: "/zh/developer/contribute/system-app/olares-manifest",
|
||||
},
|
||||
{
|
||||
text: "安装",
|
||||
link: "/zh/developer/contribute/system-app/install",
|
||||
},
|
||||
{
|
||||
text: "其他",
|
||||
link: "/zh/developer/contribute/system-app/other",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "开发协议",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "合约",
|
||||
link: "/zh/developer/contribute/olares-id/contract/contract",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "架构",
|
||||
link: "/zh/developer/contribute/olares-id/contract/architecture",
|
||||
},
|
||||
{
|
||||
text: "DID",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "设计",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/design",
|
||||
},
|
||||
{
|
||||
text: "官方 Tagger",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/official-taggers",
|
||||
},
|
||||
{
|
||||
text: "发布历史",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/release-history",
|
||||
},
|
||||
{
|
||||
text: "FAQ",
|
||||
link: "/zh/developer/contribute/olares-id/contract/did/faq",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "声誉",
|
||||
link: "/zh/developer/contribute/olares-id/contract/contract-reputation",
|
||||
},
|
||||
{
|
||||
text: "管理",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "合约",
|
||||
link: "/zh/developer/contribute/olares-id/contract/manage/contract",
|
||||
},
|
||||
{
|
||||
text: "SDK",
|
||||
link: "/zh/developer/contribute/olares-id/contract/manage/sdk",
|
||||
},
|
||||
{
|
||||
text: "环境",
|
||||
link: "/zh/developer/contribute/olares-id/contract/manage/environment",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "可验证凭证(VC)",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/overview",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "发行方",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/issuer",
|
||||
},
|
||||
{
|
||||
text: "验证方",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/verifer",
|
||||
},
|
||||
{
|
||||
text: "Olares 案例",
|
||||
link: "/zh/developer/contribute/olares-id/verifiable-credential/olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const zh = defineConfig({
|
||||
@@ -902,12 +499,17 @@ export const zh = defineConfig({
|
||||
socialLinks: [{ icon: "github", link: "https://github.com/beclab/olares" }],
|
||||
|
||||
nav: [
|
||||
{ text: "Olares", link: "zh/manual/overview" },
|
||||
{ text: "Olares Space", link: "/zh/space/" },
|
||||
{ text: "Olares OS", link: "zh/manual/overview" },
|
||||
{ text: "Olares One", link: "/zh/one/" },
|
||||
{ text: "应用示例", link: "/zh/use-cases/" },
|
||||
{ text: "开发者文档", link: "/zh/developer/concepts/" },
|
||||
],
|
||||
|
||||
sidebar: side,
|
||||
sidebar: {
|
||||
...side,
|
||||
...oneSidebar,
|
||||
...useCaseSidebar,
|
||||
...developerSidebar,
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -89,15 +89,9 @@ Key characteristics of shared applications include:
|
||||
* **Centralized management**: Only administrators can install the core service of a shared application. Administrators are responsible for installing, configuring, and hosting the app's service, resources, and runtime environment within the cluster.
|
||||
* **Easy identification**: In Olares Market, shared applications are typically marked with a "Shared" label for easy identification.
|
||||
* **Flexible access**: The method for accessing a shared application depends on the app's form:
|
||||
* **Headless backend service**: For shared applications that typically run as a background service without a graphical UI (e.g., Ollama), users need to install a **reference application** to call the service. For example, users within the cluster can access the Ollama service via Open WebUI or LobeChat.
|
||||
* **Headless backend service**: For shared applications that typically run as a background service without a graphical UI (e.g., Ollama), no dedicated reference application is required. The service exposes standard APIs and shared entrances that can be directly consumed by any compatible third‑party client such as LobeChat and Open WebUI. Users install the client and point it to the shared app’s API endpoint found in the Olares **Settings** > **Applications** > **Entrances**.
|
||||
* **Complete application with built-in UI**: For shared applications that include a complete user interface and backend service themselves (e.g., ComfyUI Shared or Dify Shared), administrators and other users in the cluster can obtain the service access point by directly installing the shared application itself.
|
||||
|
||||
### Reference applications
|
||||
|
||||
Reference applications are applications that have been granted access to specific shared applications within Olares. They typically provide a user-friendly interface, allowing users to easily access the APIs or services exposed by the shared applications.
|
||||
|
||||
For example, Open WebUI, LobeChat, and n8n are reference applications for Ollama. Dify Shared is the reference application of itself.
|
||||
|
||||
### Dependencies
|
||||
|
||||
Dependencies are prerequisite applications that must be present for certain applications to function properly. Before installing an application with dependencies, users must ensure all required dependencies are already installed in the cluster.
|
||||
|
||||
107
docs/developer/develop/distribute-index.md
Normal file
107
docs/developer/develop/distribute-index.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Understand how application distribution works in Olares.
|
||||
---
|
||||
# Distribute Olares applications
|
||||
|
||||
Distributing applications on Olares is based on open standards and automated validation.
|
||||
If your application is already packaged as an Olares Application Chart (OAC), you can publish it to Olares Market and make it available to users with minimal friction.
|
||||
|
||||
This guide walks you through the distribution lifecycle of an Olares application, from understanding how Market indexing works to publishing, maintaining, and promoting your app.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before distributing your application, it helps to understand a few core concepts:
|
||||
|
||||
- **[Olares Application Chart (OAC)](/developer/develop/package/chart.md)**
|
||||
|
||||
The packaging format used to describe an Olares application, including metadata, ownership, versioning, and installation configuration.
|
||||
|
||||
- **Application index**
|
||||
|
||||
A service that provides application metadata to Olares Market. Olares includes a default public index, and developers can deploy their own.
|
||||
|
||||
- **Terminus-Gitbot**
|
||||
|
||||
The automated validation system that checks application submissions and enforces distribution rules.
|
||||
|
||||
- **Owners file (`owners`)**
|
||||
|
||||
A file in the OAC root directory used to validate ownership and permissions. The file has no extension.
|
||||
```text
|
||||
owners:
|
||||
- <your-github-username>
|
||||
- <collaborator1-username>
|
||||
- <collaborator2-username>
|
||||
```
|
||||
- **Control files**
|
||||
|
||||
Special empty files in the OAC root directory that control distribution status:
|
||||
- `.suspend`: suspend distribution
|
||||
- `.remove`: remove an app from the Market
|
||||
|
||||
For details, see [Manage the app lifecycle](/developer/develop/manage-apps.md#control-files).
|
||||
|
||||
## Ownership and collaboration
|
||||
|
||||
To collaborate as a team:
|
||||
- Add all maintainers to the owners file (recommended). Each listed owner can independently fork the repo and submit changes for that app.
|
||||
- Add teammates as collaborators to your forked repository so they can push commits to your PR branch.
|
||||
|
||||
## App distribution workflow
|
||||
|
||||
### 1. Prepare your app package
|
||||
|
||||
Before an app can be distributed, it must be packaged as an **Olares Application Chart (OAC)**.
|
||||
|
||||
At this stage, developers typically:
|
||||
- Develop and test the app on an Olares host.
|
||||
- Verify installation and upgrade behavior.
|
||||
- Finalize chart metadata and structure.
|
||||
|
||||
For details, see [Olares Application Chart (OAC)](/developer/develop/package/chart.md).
|
||||
|
||||
### 2. Submit the app to the default index
|
||||
|
||||
Olares Market indexes applications from Git repositories.
|
||||
To publish an app to the default public index, developers submit their OAC by opening a PR to the official repository.
|
||||
|
||||
During submission:
|
||||
- The PR title declares the action type.
|
||||
- Terminus-Gitbot validates file scope, ownership, and version rules.
|
||||
- Valid PRs are merged automatically without manual review.
|
||||
|
||||
For details, see [Submit applications](/developer/develop/submit-apps.md).
|
||||
|
||||
### 3. Automated validation and indexing
|
||||
|
||||
After a PR is submitted, Terminus-Gitbot performs automated checks to ensure the submission follows distribution rules.
|
||||
|
||||
If all checks pass, the PR is merged automatically.
|
||||
After a short delay, the application becomes visible in Olares Market.
|
||||
|
||||
### 4. Manage the application lifecycle
|
||||
|
||||
After an application is published, developers continue to manage its lifecycle through Pull Requests.
|
||||
|
||||
Lifecycle actions include:
|
||||
- Releasing new versions.
|
||||
- Temporarily suspending distribution.
|
||||
- Permanently removing an application from the Market.
|
||||
|
||||
These actions are controlled using PR types and special control files in the OAC.
|
||||
|
||||
For details, see [Manage the app lifecycle](/developer/develop/manage-apps.md).
|
||||
|
||||
### 5. Optimize your Market listing
|
||||
|
||||
Once published, you can improve how your app is presented in Olares Market by adding icons, screenshots, and featured images.
|
||||
|
||||
For details, see [Promote your apps](/developer/develop/promote-apps.md).
|
||||
|
||||
### 6. (Optional) Publish paid applications
|
||||
|
||||
Olares Market also supports paid application distribution.
|
||||
Paid apps require additional identity registration, pricing configuration, and license management.
|
||||
|
||||
For details, see [Publish paid applications](/developer/develop/paid-apps.md).
|
||||
@@ -27,4 +27,4 @@ To publish your application to the Olares Market, you must structure it accordin
|
||||
## Step 3: Submit your application
|
||||
Once your application is built and packaged, the final step is to share it with the Olares community.
|
||||
|
||||
* **[Submit to Market](./submit/index.md)**: Learn how to submit your application to the Olares Market for review and distribution.
|
||||
* **[Submit to Market](/developer/develop/distribute-index.md)**: Learn how to submit your application to the Olares Market for review and distribution.
|
||||
72
docs/developer/develop/manage-apps.md
Normal file
72
docs/developer/develop/manage-apps.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to update, suspend, or remove your application from Olares Market.
|
||||
---
|
||||
# Manage the app lifecycle
|
||||
|
||||
This guide explains how to manage an application after it has been published, including updating, suspending, or removing it from Olares Market.
|
||||
|
||||
All actions are performed through Pull Requests (PRs) to the `main` branch. Terminus-Gitbot supports three lifecycle actions after your app is published:
|
||||
|
||||
- **UPDATE**: Keep your app up to date. Release new versions, fix bugs, or adjust configurations.
|
||||
- **SUSPEND**: Pause distribution. Stop new discovery, downloads, and installs in Olares Market without affecting existing users.
|
||||
- **REMOVE**: Retire the app. Permanently stop distribution and prevent the chart folder name from being reused.
|
||||
|
||||
:::tip Reduce conflicts
|
||||
Before opening the PR, sync your fork and rebase your branch onto the latest `main` to reduce potential conflicts.
|
||||
:::
|
||||
|
||||
## Control files
|
||||
|
||||
Control files are special empty files in the OAC root directory that manage an application's distribution status in Olares Market.
|
||||
|
||||
| File name | Used for | Version rule | Content needed |
|
||||
|--|--|--|--|
|
||||
| `.suspend` | Suspend distribution | Upgrade (>) | Empty file |
|
||||
| `.remove` | Remove application | Same (=) | Empty file |
|
||||
|
||||
An `UPDATE` PR or a `NEW` PR must not include these files. They are only used for `SUSPEND` and `REMOVE`.
|
||||
|
||||
## Update an app (UPDATE)
|
||||
|
||||
To update an existing application, such as releasing a new version, changing configurations, or updating the owners, submit a PR with type `UPDATE`.
|
||||
|
||||
The PR must meet the following requirements:
|
||||
|
||||
- **Version bump**: The new Chart version must be greater than the current version in the repository. Any change to a chart must bump the Chart version.
|
||||
- **Clean directory**: The OAC root must not contain `.suspend` or `.remove` files.
|
||||
- **No conflict**: The PR branch must not conflict with `beclab/apps:main`.
|
||||
|
||||
:::warning No rollbacks
|
||||
Olares Market does not support version rollbacks. If an issue occurs, you must submit a new version to fix it.
|
||||
:::
|
||||
|
||||
## Suspend an app (SUSPEND)
|
||||
|
||||
To temporarily stop your application from being listed, downloaded, or installed, submit a PR with type `SUSPEND`.
|
||||
|
||||
The PR must meet the following requirements:
|
||||
- **Version bump**: The Chart version must be greater than the current version in the repository.
|
||||
- **Control file**: The OAC root directory contains the `.suspend` file and does not contain the `.remove` file.
|
||||
- **No conflict**: The PR branch must not conflict with `beclab/apps:main`.
|
||||
|
||||
After the PR is merged, the application is no longer listed in Olares Market. Users who have already installed the application can continue to use it.
|
||||
|
||||
## Remove an app (REMOVE)
|
||||
|
||||
To permanently remove an application from Olares Market, submit a PR with type `REMOVE`.
|
||||
|
||||
The PR must meet the following requirements:
|
||||
|
||||
- **Same version**: The Chart version in the PR title must be the same as the current version in the repository.
|
||||
- **Control file**: After the change, the `.remove` file is the only file in the OAC root directory.
|
||||
- **No conflict**: The PR branch must not conflict with `beclab/apps:main`.
|
||||
|
||||
:::warning
|
||||
Removal is irreversible.
|
||||
:::
|
||||
|
||||
After the PR is merged:
|
||||
|
||||
- The chart folder name cannot be reused by the application owners.
|
||||
- Users who have already installed the application can continue to use it.
|
||||
72
docs/developer/develop/mw-integrate-with-es.md
Normal file
72
docs/developer/develop/mw-integrate-with-es.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with Elasticsearch service in Olares.
|
||||
---
|
||||
# Integrate with Elasticsearch
|
||||
|
||||
Use Olares Elasticsearch middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
## Install Elasticsearch service
|
||||
|
||||
Install the Elasticsearch service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "Elasticsearch".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `username` field to specify the Elasticsearch user.
|
||||
- Use the `indexes` field to request one or more indexes. Each index name is used as the key in `.Values.elasticsearch.indexes`.
|
||||
|
||||
**Example**
|
||||
|
||||
```yaml
|
||||
middleware:
|
||||
elasticsearch:
|
||||
username: elasticlient
|
||||
indexes:
|
||||
- name: aaa
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.elasticsearch.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
env:
|
||||
- name: ES_HOST
|
||||
value: "{{ .Values.elasticsearch.host }}"
|
||||
|
||||
- name: ES_PORT
|
||||
value: "{{ .Values.elasticsearch.port }}"
|
||||
|
||||
- name: ES_USER
|
||||
value: "{{ .Values.elasticsearch.username }}"
|
||||
|
||||
- name: ES_PASSWORD
|
||||
value: "{{ .Values.elasticsearch.password }}"
|
||||
|
||||
# Index name
|
||||
# The index name configured in OlaresManifest (for example, aaa)
|
||||
- name: ES_INDEX
|
||||
value: "{{ .Values.elasticsearch.indexes.aaa }}"
|
||||
```
|
||||
|
||||
## Elasticsearch Values reference
|
||||
|
||||
Elasticsearch Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
|`.Values.elasticsearch.host`| String | Elasticsearch service host |
|
||||
|`.Values.elasticsearch.port`| Number | Elasticsearch service port |
|
||||
|`.Values.elasticsearch.username`| String | Elasticsearch username |
|
||||
|`.Values.elasticsearch.password`| String | Elasticsearch password |
|
||||
|`.Values.elasticsearch.indexes` | Map<String,String> | The requested index name is used<br> as the key. For example, if you request `aaa`, the value is available at `.Values.elasticsearch.indexes.aaa`. |
|
||||
72
docs/developer/develop/mw-integrate-with-mariadb.md
Normal file
72
docs/developer/develop/mw-integrate-with-mariadb.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with MariaDB service in Olares.
|
||||
---
|
||||
# Integrate with MariaDB
|
||||
|
||||
Use Olares MariaDB middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
## Install MariaDB service
|
||||
|
||||
Install the MariaDB service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "MariaDB".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `username` field to specify the database username.
|
||||
- Use the `databases` field to request one or more databases. Each database name is used as the key in `.Values.mariadb.databases`.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
mariadb:
|
||||
username: mariadbclient
|
||||
databases:
|
||||
- name: aaa
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.mariadb.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
# For MariaDB, the corresponding value is as follows
|
||||
env:
|
||||
- name: MDB_HOST
|
||||
value: "{{ .Values.mariadb.host }}"
|
||||
|
||||
- name: MDB_PORT
|
||||
value: "{{ .Values.mariadb.port }}"
|
||||
|
||||
- name: MDB_USER
|
||||
value: "{{ .Values.mariadb.username }}"
|
||||
|
||||
- name: MDB_PASSWORD
|
||||
value: "{{ .Values.mariadb.password }}"
|
||||
|
||||
# Database Name
|
||||
# The database name configured in OlaresManifest (e.g., aaa)
|
||||
- name: MDB_DB
|
||||
value: "{{ .Values.mariadb.databases.aaa }}"
|
||||
```
|
||||
|
||||
## MariaDB Values reference
|
||||
|
||||
MariaDB Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.mariadb.host` | String | MariaDB database host |
|
||||
| `.Values.mariadb.port` | Number | MariaDB database port |
|
||||
| `.Values.mariadb.username` | String | MariaDB database username |
|
||||
| `.Values.mariadb.password` | String | MariaDB database password |
|
||||
| `.Values.mariadb.databases` | Map<String,String> | The requested database name is used as the key. <br/>For example, if you request `aaa`, the value is available at `.Values.mariadb.databases.aaa`. |
|
||||
73
docs/developer/develop/mw-integrate-with-minio.md
Normal file
73
docs/developer/develop/mw-integrate-with-minio.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with MinIO service in Olares.
|
||||
---
|
||||
# Integrate with MinIO
|
||||
|
||||
Use Olares MinIO middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
## Install MinIO service
|
||||
|
||||
Install the MinIO service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "MinIO".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `username` field to specify the MinIO access key.
|
||||
- Use the `buckets` field to request one or more buckets. Each bucket name is used as the key in `.Values.minio.buckets`.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
minio:
|
||||
username: miniouser
|
||||
buckets:
|
||||
- name: mybucket
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.minio.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
# For MinIO, the corresponding values are as follows
|
||||
env:
|
||||
# Construct the endpoint using host and port
|
||||
- name: MINIO_ENDPOINT
|
||||
value: "{{ .Values.minio.host }}:{{ .Values.minio.port }}"
|
||||
|
||||
- name: MINIO_PORT
|
||||
value: "{{ .Values.minio.port }}"
|
||||
|
||||
- name: MINIO_ACCESS_KEY
|
||||
value: "{{ .Values.minio.username }}"
|
||||
|
||||
- name: MINIO_SECRET_KEY
|
||||
value: "{{ .Values.minio.password }}"
|
||||
|
||||
# Bucket name
|
||||
# The bucket name configured in OlaresManifest (e.g., mybucket)
|
||||
- name: MINIO_BUCKET
|
||||
value: "{{ .Values.minio.buckets.mybucket }}"
|
||||
```
|
||||
|
||||
## MinIO Values reference
|
||||
|
||||
MinIO Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.minio.host` | String | MinIO service host |
|
||||
| `.Values.minio.port` | Number | MinIO service port |
|
||||
| `.Values.minio.username` | String | MinIO access key |
|
||||
| `.Values.minio.password` | String | MinIO secret key |
|
||||
| `.Values.minio.buckets` | Map<String,String> | The requested bucket name is used as the key. <br>For example, if you request `mybucket`, the value is available at `.Values.minio.buckets.mybucket`. |
|
||||
76
docs/developer/develop/mw-integrate-with-mongodb.md
Normal file
76
docs/developer/develop/mw-integrate-with-mongodb.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with MongoDB service in Olares.
|
||||
---
|
||||
# Integrate with MongoDB
|
||||
|
||||
Use Olares MongoDB middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
## Install MongoDB service
|
||||
|
||||
Install the MongoDB service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "MongoDB".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `username` field to specify the MongoDB database user.
|
||||
- Use the `databases` field to request one or more databases.
|
||||
- (Optional) Use the `script` field under each database to specify initialization scripts that are executed after the database is created.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
mongodb:
|
||||
username: chromium
|
||||
databases:
|
||||
- name: chromium
|
||||
script:
|
||||
- 'db.getSiblingDB("$databasename").myCollection.insertOne({ x: 111 });'
|
||||
# Please make sure each line is a complete query.
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.mongodb.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
# For MongoDB, the corresponding values are as follows
|
||||
env:
|
||||
- name: MONGODB_HOST
|
||||
value: "{{ .Values.mongodb.host }}"
|
||||
|
||||
- name: MONGODB_PORT
|
||||
value: "{{ .Values.mongodb.port }}"
|
||||
|
||||
- name: MONGODB_USER
|
||||
value: "{{ .Values.mongodb.username }}"
|
||||
|
||||
- name: MONGODB_PASSWORD
|
||||
value: "{{ .Values.mongodb.password }}"
|
||||
|
||||
# Database name
|
||||
# The database name configured in OlaresManifest (e.g., app_db)
|
||||
- name: MONGODB_DATABASE
|
||||
value: "{{ .Values.mongodb.databases.app_db }}"
|
||||
```
|
||||
|
||||
## MongoDB Values reference
|
||||
|
||||
MongoDB Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.mongodb.host` | String | MongoDB database host |
|
||||
| `.Values.mongodb.port` | Number | MongoDB database port |
|
||||
| `.Values.mongodb.username` | String | MongoDB database username |
|
||||
| `.Values.mongodb.password` | String | MongoDB database password |
|
||||
| `.Values.mongodb.databases` | Map<String,String> | The requested database name is used as the key. <br/>For example, if you request `app_db`, the value is available at `.Values.mongodb.databases.app_db`. |
|
||||
72
docs/developer/develop/mw-integrate-with-mysql.md
Normal file
72
docs/developer/develop/mw-integrate-with-mysql.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with MySQL service in Olares.
|
||||
---
|
||||
# Integrate with MySQL
|
||||
|
||||
Use Olares MySQL middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
## Install MySQL service
|
||||
|
||||
Install the MySQL service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "MySQL".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `username` field to specify the MySQL database user.
|
||||
- Use the `databases` field to request one or more databases. Each database name is used as the key in `.Values.mysql.databases`.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
mysql:
|
||||
username: mysqlclient
|
||||
databases:
|
||||
- name: aaa
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.mysql.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
# For MySQL, the corresponding values are as follows
|
||||
env:
|
||||
- name: MDB_HOST
|
||||
value: "{{ .Values.mysql.host }}"
|
||||
|
||||
- name: MDB_PORT
|
||||
value: "{{ .Values.mysql.port }}"
|
||||
|
||||
- name: MDB_USER
|
||||
value: "{{ .Values.mysql.username }}"
|
||||
|
||||
- name: MDB_PASSWORD
|
||||
value: "{{ .Values.mysql.password }}"
|
||||
|
||||
# Database name
|
||||
# The database name configured in OlaresManifest (e.g., aaa)
|
||||
- name: MDB_DB
|
||||
value: "{{ .Values.mysql.databases.aaa }}"
|
||||
```
|
||||
|
||||
## MySQL Values reference
|
||||
|
||||
MySQL Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.mysql.host` | String | MySQL database host |
|
||||
| `.Values.mysql.port` | Number | MySQL database port |
|
||||
| `.Values.mysql.username` | String | MySQL database username |
|
||||
| `.Values.mysql.password` | String | MySQL database password |
|
||||
| `.Values.mysql.databases` | Map<String,String> | The requested database name is used as the key. <br/>For example, if you request `aaa`, the value is available at `.Values.mysql.databases.aaa`. |
|
||||
81
docs/developer/develop/mw-integrate-with-pg.md
Normal file
81
docs/developer/develop/mw-integrate-with-pg.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with the built-in PostgreSQL service in Olares.
|
||||
---
|
||||
# Integrate with PostgreSQL
|
||||
|
||||
Use Olares PostgreSQL middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
:::info PosgreSQL installed
|
||||
PostgreSQL service has been installed by default.
|
||||
:::
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `scripts` field to specify scripts that should be executed after the database is created.
|
||||
- Use the `extensions` field to add the corresponding extension in the database.
|
||||
|
||||
:::info Variable injection in scripts
|
||||
The OS provides two variables, `$databasename` and `$dbusername`, which will be replaced by Olares Application Runtime when the command is executed.
|
||||
:::
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
postgres:
|
||||
username: immich
|
||||
databases:
|
||||
- name: immich
|
||||
extensions:
|
||||
- vectors
|
||||
- earthdistance
|
||||
scripts:
|
||||
- BEGIN;
|
||||
- ALTER DATABASE $databasename SET search_path TO "$user", public, vectors;
|
||||
- ALTER SCHEMA vectors OWNER TO $dbusername;
|
||||
- COMMIT;
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.postgres.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
env:
|
||||
# The database name configured in OlaresManifest, specified in middleware.postgres.databases[i].name
|
||||
# NOTE: Replace <dbname> with the actual name defined in the Manifest (e.g., immich)
|
||||
- name: DB_POSTGRESDB_DATABASE
|
||||
value: {{ .Values.postgres.databases.<dbname> }}
|
||||
|
||||
# Host
|
||||
- name: DB_POSTGRESDB_HOST
|
||||
value: {{ .Values.postgres.host }}
|
||||
|
||||
# Port
|
||||
- name: DB_POSTGRESDB_PORT
|
||||
value: "{{ .Values.postgres.port }}"
|
||||
|
||||
# Username
|
||||
- name: DB_POSTGRESDB_USER
|
||||
value: {{ .Values.postgres.username }}
|
||||
|
||||
# Password
|
||||
- name: DB_POSTGRESDB_PASSWORD
|
||||
value: {{ .Values.postgres.password }}
|
||||
```
|
||||
|
||||
## PostgreSQL Values reference
|
||||
|
||||
PostgreSQL Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.postgres.host` | String | PostgreSQL database host |
|
||||
| `.Values.postgres.port` | Number | PostgreSQL database port |
|
||||
| `.Values.postgres.username` | String | PostgreSQL database username |
|
||||
| `.Values.postgres.password` | String | PostgreSQL database password |
|
||||
| `.Values.postgres.databases` | Map<String,String> | The requested database name is used as the key. <br>For example, if you request `app_db`, the value is available at `.Values.postgres.databases.app_db`|
|
||||
91
docs/developer/develop/mw-integrate-with-rabbitmq.md
Normal file
91
docs/developer/develop/mw-integrate-with-rabbitmq.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with RabbitMQ service in Olares.
|
||||
---
|
||||
# Integrate with RabbitMQ
|
||||
|
||||
Use Olares RabbitMQ middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
## Install RabbitMQ service
|
||||
|
||||
Install the RabbitMQ service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "RabbitMQ".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required middleware configuration.
|
||||
|
||||
- Use the `username` field to specify the RabbitMQ user.
|
||||
- Use the `vhosts` field to request one or more virtual hosts (vhosts). Each vhost name is used as the key in `.Values.rabbitmq.vhosts`.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
rabbitmq:
|
||||
username: rabbitmquser
|
||||
vhosts:
|
||||
- name: aaa
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.rabbitmq.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
# For RabbitMQ, the corresponding values are as follows
|
||||
env:
|
||||
- name: RABBITMQ_HOST
|
||||
value: "{{ .Values.rabbitmq.host }}"
|
||||
|
||||
- name: RABBITMQ_PORT
|
||||
value: "{{ .Values.rabbitmq.port }}"
|
||||
|
||||
- name: RABBITMQ_USER
|
||||
value: "{{ .Values.rabbitmq.username }}"
|
||||
|
||||
- name: RABBITMQ_PASSWORD
|
||||
value: "{{ .Values.rabbitmq.password }}"
|
||||
|
||||
# Vhost
|
||||
# The vhost name configured in OlaresManifest (e.g., aaa)
|
||||
- name: RABBITMQ_VHOST
|
||||
value: "{{ .Values.rabbitmq.vhosts.aaa }}"
|
||||
```
|
||||
|
||||
## Construct a RabbitMQ connection URI
|
||||
|
||||
After configuring the environment variables, you can read them in your application code to construct the connection string.
|
||||
|
||||
Below is an example of constructing an AMQP URL using the environment variables:
|
||||
|
||||
```Go
|
||||
// Read environment variables
|
||||
user := os.Getenv("RABBITMQ_USER")
|
||||
password := os.Getenv("RABBITMQ_PASSWORD")
|
||||
vhost := os.Getenv("RABBITMQ_VHOST")
|
||||
host := os.Getenv("RABBITMQ_HOST")
|
||||
portMQ := os.Getenv("RABBITMQ_PORT")
|
||||
|
||||
// Construct AMQP connection string
|
||||
// Format: amqp://user:password@host:port/vhost
|
||||
url := fmt.Sprintf("amqp://%s:%s@%s:%s/%s", user, password, host, portMQ, vhost)
|
||||
```
|
||||
|
||||
## RabbitMQ Values reference
|
||||
|
||||
RabbitMQ Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.rabbitmq.host` | String | RabbitMQ service host |
|
||||
| `.Values.rabbitmq.port` | Number | RabbitMQ service port |
|
||||
| `.Values.rabbitmq.username` | String | RabbitMQ username |
|
||||
| `.Values.rabbitmq.password` | String | RabbitMQ password |
|
||||
| `.Values.rabbitmq.vhosts` | Map<String,String> | The requested vhost name is used as the key. <br/>For example, if you request `aaa`, the value is available at `.Values.rabbitmq.vhosts.aaa`. |
|
||||
65
docs/developer/develop/mw-integrate-with-redis.md
Normal file
65
docs/developer/develop/mw-integrate-with-redis.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to integrate your app with the built-in Redis service in Olares.
|
||||
---
|
||||
# Integrate with Redis
|
||||
|
||||
Use Olares Redis middleware by declaring it in `OlaresManifest.yaml`, then mapping the injected values to your container environment variables.
|
||||
|
||||
:::info Redis installed
|
||||
Redis service has been installed by default.
|
||||
:::
|
||||
|
||||
## Configure `OlaresManifest.yaml`
|
||||
|
||||
In `OlaresManifest.yaml`, add the required Redis middleware configuration.
|
||||
|
||||
- Use the `password` field to specify the Redis access password.
|
||||
- Use the `namespace` field to request a Redis namespace.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
middleware:
|
||||
redis:
|
||||
password: password
|
||||
namespace: db0
|
||||
```
|
||||
|
||||
## Inject environment variables
|
||||
|
||||
In your deployment YAML, map the injected `.Values.redis.*` fields to the environment variables your app uses.
|
||||
|
||||
**Example**
|
||||
```yaml
|
||||
containers:
|
||||
- name: my-app
|
||||
env:
|
||||
# Host
|
||||
- name: REDIS_HOST
|
||||
value: {{ .Values.redis.host }}
|
||||
|
||||
# Port
|
||||
# Quote the value to ensure it's treated as a string
|
||||
- name: REDIS_PORT
|
||||
value: "{{ .Values.redis.port }}"
|
||||
|
||||
# Password
|
||||
# Quote the value to handle special characters correctly
|
||||
- name: REDIS_PASSWORD
|
||||
value: "{{ .Values.redis.password }}"
|
||||
|
||||
# Namespace
|
||||
# NOTE: Replace <namespace> with the actual namespace defined in OlaresManifest (e.g., db0)
|
||||
- name: REDIS_NAMESPACE
|
||||
value: {{ .Values.redis.namespaces.<namespace> }}
|
||||
```
|
||||
|
||||
## Redis Values reference
|
||||
|
||||
Redis Values are predefined environment variables injected into `values.yaml` during deployment. They are system-managed and not user-editable.
|
||||
| Key | Type | Description |
|
||||
|--|--|--|
|
||||
| `.Values.redis.host` | String | Redis service host |
|
||||
| `.Values.redis.port` | Number | Redis service port |
|
||||
| `.Values.redis.password`| String | Redis service password |
|
||||
| `.Values.redis.namespaces` | Map<String, String> | The requested namespace is used as the key. <br>For example, if you request `app_ns`, the value is available at `.Values.redis.namespaces.app_ns`. |
|
||||
64
docs/developer/develop/mw-overview.md
Normal file
64
docs/developer/develop/mw-overview.md
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn what middleware is in Olares and navigate to access and integration guides for each supported service.
|
||||
---
|
||||
# Middleware in Olares
|
||||
|
||||
Middleware refers to infrastructure services that sit between your application and the system, providing data storage, messaging, and other common capabilities.
|
||||
|
||||
Our middleware documentation is organized into two types of guides:
|
||||
- **Access and manage data**: Connect to a running service to inspect data and troubleshoot issues.
|
||||
- **App integrate**: Configure your app to use a middleware service in Olares using `OlaresManifest.yaml`.
|
||||
|
||||
## Document types
|
||||
|
||||
### Access and manage data
|
||||
|
||||
Access and manage data guides explain how to connect to a running middleware service for administration.
|
||||
|
||||
Use these guides when you want to:
|
||||
- Inspect stored data or indexes.
|
||||
- Run queries or commands.
|
||||
- Debug application behavior.
|
||||
- Verify service status.
|
||||
|
||||
The access method (e.g., CLI, Dashboard, or Bytebase) depends on the service.
|
||||
|
||||
### App integration
|
||||
|
||||
App integration guides explain how to connect your application to a middleware service.
|
||||
|
||||
Use these guides when you want your application to:
|
||||
- Declare dependencies in `OlaresManifest.yaml`.
|
||||
- Request service resources.
|
||||
- Read system-injected connection values in your application.
|
||||
|
||||
Integration is declarative and handled by Olares at deployment time.
|
||||
|
||||
## Supported services
|
||||
|
||||
### Databases and caching
|
||||
|
||||
| Service | Access and manage data | App integration |
|
||||
| --- | --- | --- |
|
||||
| Elasticsearch | [Access](./mw-view-es-data.md) | [Integrate](./mw-integrate-with-es.md) |
|
||||
| MariaDB | [Access](./mw-view-mariadb-data.md) | [Integrate](./mw-integrate-with-mariadb.md) |
|
||||
| MongoDB | [Access](./mw-view-mongodb-data.md) | [Integrate](./mw-integrate-with-mongodb.md) |
|
||||
| MySQL | [Access](./mw-view-mysql-data.md) | [Integrate](./mw-integrate-with-mysql.md) |
|
||||
| PostgreSQL | [Access](./mw-view-pg-data.md) | [Integrate](./mw-integrate-with-pg.md) |
|
||||
| Redis | [Access](./mw-view-redis-data.md) | [Integrate](./mw-integrate-with-redis.md) |
|
||||
|
||||
### Messaging and streaming
|
||||
|
||||
| Service | Access and manage data | App integration |
|
||||
| --- | --- | --- |
|
||||
| RabbitMQ | [Access](./mw-view-rabbitmq-data.md) | [Integrate](./mw-integrate-with-rabbitmq.md) |
|
||||
| NATS | [Access](./mw-view-nats-data.md) | — |
|
||||
|
||||
### Storage and observability
|
||||
|
||||
| Service | Access and manage data | App integration |
|
||||
| --- | --- | --- |
|
||||
| MinIO | [Access](./mw-view-minio-data.md) | [Integrate](./mw-integrate-with-minio.md) |
|
||||
| Grafana | [Access](./mw-view-grafana-data.md) | — |
|
||||
| OpenTelemetry | [Access](./mw-view-otel-data.md) | — |
|
||||
69
docs/developer/develop/mw-view-es-data.md
Normal file
69
docs/developer/develop/mw-view-es-data.md
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to connect to and manage Elasticsearch data in Olares using Bytebase.
|
||||
---
|
||||
# View Elasticsearch data
|
||||
|
||||
To use Elasticsearch in Olares, install it from Market first. This guide explains how to access and manage Elasticsearch data using Bytebase.
|
||||
|
||||
## Install Elasticsearch service
|
||||
|
||||
Before connecting, install the Elasticsearch service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "Elasticsearch".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Get connection information
|
||||
|
||||
Before connecting, obtain Elasticsearch connection details from Control Hub.
|
||||
|
||||
1. Open Control Hub from Launchpad.
|
||||
2. In the left navigation pane, go to Middleware and select **Elasticsearch**.
|
||||
3. On the Details panel, record the following information:
|
||||
- **Host**: Used for Bytebase connection.
|
||||
- **User**: Used for Bytebase connection.
|
||||
- **Password**: Used for Bytebase connection.
|
||||
|
||||
{width=60% style="margin-left:0"}
|
||||
|
||||
## Manage via Bytebase
|
||||
|
||||
Bytebase provides a graphical interface for database management and schema changes.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
:::info MongoDB app required
|
||||
Bytebase uses MongoDB to store its metadata. Install MongoDB before installing Bytebase.
|
||||
:::
|
||||
|
||||
1. Open Market and search for "MongoDB".
|
||||
2. Click **Get**, then **Install**, and wait until the service is running.
|
||||
3. After MongoDB is installed, search for "Bytebase" in Market.
|
||||
4. Click **Get**, then **Install**.
|
||||
|
||||
### First-time setup
|
||||
|
||||
When launching Bytebase for the first time, you must configure an administrator account.
|
||||
|
||||
:::tip
|
||||
Remember these credentials. Only the admin account can create new database instances.
|
||||
:::
|
||||
|
||||
1. Open Bytebase from Launchpad.
|
||||
2. Follow the on-screen prompts to set up your admin account with email and password.
|
||||
|
||||
### Create an Elasticsearch instance
|
||||
|
||||
1. Log in to Bytebase with your admin account.
|
||||
2. In the left navigation pane, select **Instances**, then click **+ Add Instance**.
|
||||
3. Choose **Elasticsearch** as the database type.
|
||||
4. Fill in the connection fields using values from Control Hub:
|
||||
- **Host or Socket**: Enter the **Host** address and do not include the port.
|
||||
- **Port**: Keep the default, usually `9200`.
|
||||
- **Username**: Enter the **User** value from Control Hub.
|
||||
- **Password**: Enter the **Password** value from Control Hub.
|
||||
5. Click **Test Connection** to verify connectivity, then click **Create**.
|
||||
|
||||
Creating an instance in Bytebase does not create a new database. Once the instance is created, you can use the corresponding client tools to inspect and manage data.
|
||||
67
docs/developer/develop/mw-view-grafana-data.md
Normal file
67
docs/developer/develop/mw-view-grafana-data.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to visualize Prometheus metrics in Olares using Grafana dashboards.
|
||||
---
|
||||
# Use Grafana dashboards
|
||||
|
||||
To visualize system metrics in Olares, you can run Grafana and connect it to the built-in Prometheus service. This guide explains how to install Grafana, connect the data source, and import a standard dashboard.
|
||||
|
||||
## Install Grafana
|
||||
|
||||
Before using Grafana, install it from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "Grafana".
|
||||
2. Click **Get**, then **Install**.
|
||||
3. In the pop-up window, set your login credentials:
|
||||
- `GF_USERNAME`: Grafana login username.
|
||||
- `GF_PASSWORD`: Grafana login password.
|
||||
:::tip Remember your login credentials
|
||||
These are the login credentials for Grafana. You will need them if you access Grafana later.
|
||||
:::
|
||||
{width=90% style="margin-left:0"}
|
||||
4. Wait for the installation to complete.
|
||||
|
||||
## Access Grafana
|
||||
|
||||
1. Open **Grafana** from Launchpad, then click <i class="material-symbols-outlined">open_in_new</i> to open it in a new tab.
|
||||
2. On the login screen, enter the `GF_USERNAME` and `GF_PASSWORD` you configured during installation.
|
||||
|
||||
After logging in, you will see the Grafana home page.
|
||||
|
||||
## Add Prometheus data source
|
||||
|
||||
Olares runs a built-in Prometheus service that collects system metrics.
|
||||
|
||||
To connect Grafana to this internal service:
|
||||
|
||||
1. In the Grafana left navigation pane, go to **Connections** > **Data sources**.
|
||||
2. Click **Add data source**, then select **Prometheus**.
|
||||
3. For the **Prometheus server URL** field, enter:
|
||||
```text
|
||||
http://dashboard.<olaresid>.olares.com
|
||||
```
|
||||
Replace `<olaresid>` with your Olares ID.
|
||||
4. Click **Save & test** at the bottom of the page. If the connection is successful, you will see the prompt below.
|
||||
{width=90% style="margin-left:0"}
|
||||
|
||||
## Create a dashboard
|
||||
|
||||
This approach is suitable when you need custom metrics and visualizations and are familiar with PromQL.
|
||||
1. In the left navigation pane, click **Dashboards**.
|
||||
2. Click **+ Create dashboard**, then select **+ Add visualization**.
|
||||
3. Select **prometheus** as the data source.
|
||||
4. Configure panels, PromQL queries, and expressions as needed.
|
||||
5. Click **Save dashboard** in the top-right corner for future use.
|
||||
|
||||
## Import a dashboard (recommended)
|
||||
|
||||
If you do not need to build dashboards from scratch, you can import existing dashboards.
|
||||
|
||||
1. Visit the [Grafana Dashboard library](https://grafana.com/grafana/dashboards/).
|
||||
2. Download the required dashboard as a `JSON` file.
|
||||
3. In Grafana, click <i class="material-symbols-outlined">add_2</i> in the top-right corner and select **Import dashboard**.
|
||||
4. Upload the `JSON` file, and select **prometheus** as the data source.
|
||||
5. Click **Import** to complete the import.
|
||||
|
||||
Imported dashboards provide predefined panels and queries and can be customized after import.
|
||||
{width=90%}
|
||||
91
docs/developer/develop/mw-view-mariadb-data.md
Normal file
91
docs/developer/develop/mw-view-mariadb-data.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to connect to and manage MariaDB data in Olares using CLI or Bytebase.
|
||||
---
|
||||
# View MariaDB data
|
||||
|
||||
To use MariaDB in Olares, install it from Market first. This guide explains how to access and manage MariaDB data using CLI or Bytebase.
|
||||
|
||||
## Install MariaDB service
|
||||
|
||||
Before connecting, install the MariaDB service from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "MariaDB".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Get connection information
|
||||
|
||||
Before connecting, obtain MariaDB connection details from Control Hub.
|
||||
|
||||
1. Open Control Hub from Launchpad.
|
||||
2. In the left navigation pane, go to Middleware and select **Mariadb**.
|
||||
3. On the Details panel, record the following information:
|
||||
- **Host**: Used for Bytebase connection.
|
||||
- **User**: Used for Bytebase connection.
|
||||
- **Password**: Used for both CLI and Bytebase.
|
||||
|
||||
{width=60% style="margin-left:0"}
|
||||
|
||||
## Access via CLI
|
||||
|
||||
You can use the Olares terminal to access the MariaDB container for debugging or data operations.
|
||||
|
||||
1. In Control Hub, open the Olares terminal at the bottom of the left navigation pane.
|
||||
2. Retrieve the Pod name for the middleware:
|
||||
|
||||
```bash
|
||||
kubectl get pods -n mariadb-middleware
|
||||
```
|
||||
3. Record the Pod name, then enter the container:
|
||||
|
||||
```bash
|
||||
kubectl exec -it -n mariadb-middleware <mariadb-pod> -- sh
|
||||
```
|
||||
4. Connect to MariaDB:
|
||||
|
||||
```bash
|
||||
mysql -u root -p
|
||||
```
|
||||
5. When prompted, enter the password you retrieved from Control Hub.
|
||||
|
||||
## Manage via Bytebase
|
||||
|
||||
Bytebase provides a graphical interface for database management and schema changes.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
:::info MongoDB app required
|
||||
Bytebase uses MongoDB to store its metadata. Install MongoDB before installing Bytebase.
|
||||
:::
|
||||
|
||||
1. Open Market and search for "MongoDB".
|
||||
2. Click **Get**, then **Install**, and wait until the service is running.
|
||||
3. After MongoDB is installed, search for "Bytebase" in Market.
|
||||
4. Click **Get**, then **Install**.
|
||||
|
||||
### First-time setup
|
||||
|
||||
When launching Bytebase for the first time, you must configure an administrator account.
|
||||
|
||||
:::tip
|
||||
Remember these credentials. Only the admin account can create new database instances.
|
||||
:::
|
||||
|
||||
1. Open Bytebase from Launchpad.
|
||||
2. Follow the on-screen prompts to set up your admin account with email and password.
|
||||
|
||||
### Create a MariaDB instance
|
||||
|
||||
1. Log in to Bytebase with your admin account.
|
||||
2. In the left navigation pane, select **Instances**, then click **+ Add Instance**.
|
||||
3. Choose **MariaDB** as the database type.
|
||||
4. Fill in the connection fields using values from Control Hub:
|
||||
- **Host or Socket**: Enter the **Host** address and do not include the port.
|
||||
- **Port**: Keep the default, usually `3306`.
|
||||
- **Username**: Enter the **User** value from Control Hub.
|
||||
- **Password**: Enter the **Password** value from Control Hub.
|
||||
5. Click **Test Connection** to verify connectivity, then click **Create**.
|
||||
|
||||
Creating an instance in Bytebase does not create a new database. Once the instance is created, you can use the corresponding client tools to inspect and manage data.
|
||||
44
docs/developer/develop/mw-view-minio-data.md
Normal file
44
docs/developer/develop/mw-view-minio-data.md
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to install MinIO and manage object storage in Olares using the MinIO Dashboard.
|
||||
---
|
||||
# View MinIO data
|
||||
|
||||
This guide explains how to install MinIO and manage object storage using MinIO Dashboard in Olares.
|
||||
|
||||
## Install MinIO service
|
||||
|
||||
Before using object storage, install the MinIO service from Market.
|
||||
|
||||
1. Open Market from the Launchpad and search for "MinIO".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
After installation, MinIO service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Install MinIO Dashboard
|
||||
|
||||
MinIO Dashboard depends on the MinIO service and can only be installed after MinIO is available.
|
||||
|
||||
1. In Market, search for "MinIO Dashboard".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
## Get connection information
|
||||
|
||||
Before connecting, obtain MinIO connection details from the Control Hub.
|
||||
|
||||
1. Open Control Hub from Launchpad.
|
||||
2. In the left navigation pane, go to Middleware and select **Minio**.
|
||||
3. On the Details panel, record the following information:
|
||||
- **User**: Used for MinIO Dashboard connection.
|
||||
- **Password**: Used for MinIO Dashboard connection.
|
||||
|
||||
{width=60% style="margin-left:0"}
|
||||
|
||||
## Manage via MinIO Dashboard
|
||||
|
||||
MinIO Dashboard provides a graphical interface for creating buckets, browsing files, and managing permissions.
|
||||
|
||||
1. Open MinIO Dashboard from the Launchpad.
|
||||
2. On the login screen, enter the **User** and **Password** values obtained from Control Hub.
|
||||
|
||||
Upon successful login, you can browse buckets and manage objects directly from the interface.
|
||||
83
docs/developer/develop/mw-view-mongodb-data.md
Normal file
83
docs/developer/develop/mw-view-mongodb-data.md
Normal file
@@ -0,0 +1,83 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to view and manage MongoDB data in Olares using CLI or Bytebase.
|
||||
---
|
||||
# View MongoDB data
|
||||
|
||||
To use MongoDB in Olares, install it from Market first. This guide walks you through the installation steps and shows how to access it from Olares.
|
||||
|
||||
## Install MongoDB service
|
||||
|
||||
Before connecting, install the MongoDB service from Market.
|
||||
1. Open Market from the Launchpad and search for "MongoDB".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Get connection information
|
||||
|
||||
Before connecting, obtain MongoDB connection details from the Control Hub.
|
||||
|
||||
1. Open Control Hub from Launchpad.
|
||||
2. In the left navigation pane, go to Middleware and select **Mongodb**.
|
||||
3. On the Details panel, record the following information:
|
||||
- **Mongos**: The host address provided by Control Hub. Used for Bytebase connection.
|
||||
- **User**: Used for Bytebase connection.
|
||||
- **Password**: Used for both CLI and Bytebase.
|
||||
|
||||
{width=60% style="margin-left:0"}
|
||||
|
||||
## Access via CLI
|
||||
|
||||
You can use the Olares terminal to access the MongoDB container.
|
||||
|
||||
1. In Control Hub, open the Olares terminal at the bottom of the left navigation pane.
|
||||
2. Retrieve the Pod name for the middleware:
|
||||
|
||||
```bash
|
||||
kubectl get pods -n os-platform | grep tapr-middleware
|
||||
```
|
||||
3. Record the Pod name that starts with `tapr-middleware`, then enter the container:
|
||||
|
||||
```bash
|
||||
kubectl exec -it -n os-platform <tapr-middleware-pod> -- sh
|
||||
```
|
||||
4. Connect to MongoDB using `mongosh`:
|
||||
|
||||
```bash
|
||||
mongosh "mongodb://root:<your password from controlhub>@mongodb-mongodb-headless.mongodb-middleware:27017"
|
||||
```
|
||||
|
||||
## Manage via Bytebase
|
||||
|
||||
Bytebase provides a graphical interface for database management and schema changes.
|
||||
|
||||
### Install Bytebase
|
||||
|
||||
1. Open Market and search for "Bytebase".
|
||||
2. Click **Get**, then **Install**.
|
||||
|
||||
### First-time setup
|
||||
|
||||
When launching Bytebase for the first time, you must configure an administrator account.
|
||||
|
||||
:::tip
|
||||
Remember these credentials. Only the admin account can create new database instances.
|
||||
:::
|
||||
|
||||
1. Open Bytebase from Launchpad.
|
||||
2. Follow the on-screen prompts to set up your admin account with email and password.
|
||||
|
||||
### Create a MongoDB instance
|
||||
|
||||
1. Log in to Bytebase with your admin account.
|
||||
2. In the left navigation pane, select **Instances**, then click **+ Add Instance**.
|
||||
3. Choose **MongoDB** as the database type.
|
||||
4. Fill in the connection fields using values from Control Hub:
|
||||
- **Host or Socket**: Enter the **Mongos** host address and do not include the port.
|
||||
- **Port**: Keep the default, usually `27017`.
|
||||
- **Username**: Enter the **User** value from Control Hub.
|
||||
- **Password**: Enter the **Password** value from Control Hub.
|
||||
5. Click **Test Connection** to verify connectivity, then click **Create**.
|
||||
|
||||
Creating an instance in Bytebase does not create a new database. Once the instance is created, you can use the corresponding client tools to inspect and manage data.
|
||||
85
docs/developer/develop/mw-view-mysql-data.md
Normal file
85
docs/developer/develop/mw-view-mysql-data.md
Normal file
@@ -0,0 +1,85 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to view and manage MySQL data in Olares using CLI or Bytebase.
|
||||
---
|
||||
# View MySQL data
|
||||
|
||||
To use MySQL in Olares, install it from Market first. This guide walks you through the installation steps and shows how to access it from Olares.
|
||||
|
||||
## Install MySQL service
|
||||
|
||||
Before connecting, install the MySQL service from Market.
|
||||
1. Open Market from the Launchpad and search for "MySQL".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
Once installed, the service and its connection details will appear in the Middleware list in Control Hub.
|
||||
|
||||
## Get connection information
|
||||
|
||||
Before connecting, obtain MySQL connection details from the Control Hub.
|
||||
|
||||
1. Open Control Hub from Launchpad.
|
||||
2. In the left navigation pane, go to Middleware and select **Mysql**.
|
||||
3. On the Details panel, record the following information:
|
||||
- **Host**: Used for Bytebase connection.
|
||||
- **User**: Used for Bytebase connection.
|
||||
- **Password**: Used for both CLI and Bytebase.
|
||||
|
||||
{width=60% style="margin-left:0"}
|
||||
|
||||
## Access via CLI
|
||||
|
||||
You can use the Olares terminal to access the MySQL container.
|
||||
|
||||
1. In Control Hub, open the Olares terminal at the bottom of the left navigation pane.
|
||||
2. Enter the MySQL container. The container name is fixed.
|
||||
|
||||
```bash
|
||||
kubectl exec -it -n mysql-middleware mysql-mysql-0 -- sh
|
||||
```
|
||||
3. Connect to MySQL:
|
||||
|
||||
```bash
|
||||
mysql -u root -p
|
||||
```
|
||||
4. When prompted, enter the password you retrieved from Control Hub.
|
||||
|
||||
## Manage via Bytebase
|
||||
|
||||
Bytebase provides a graphical interface for database management and schema changes.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
:::info MongoDB app required
|
||||
Bytebase uses MongoDB to store its metadata. Install MongoDB before installing Bytebase.
|
||||
:::
|
||||
|
||||
1. Open Market and search for "MongoDB".
|
||||
2. Click **Get**, then **Install**, and wait until the service is running.
|
||||
3. After MongoDB is installed, search for "Bytebase" in Market.
|
||||
4. Click **Get**, then **Install**.
|
||||
|
||||
### First-time setup
|
||||
|
||||
When launching Bytebase for the first time, you must configure an administrator account.
|
||||
|
||||
:::tip
|
||||
Remember these credentials. Only the admin account can create new database instances.
|
||||
:::
|
||||
|
||||
1. Open Bytebase from Launchpad.
|
||||
2. Follow the on-screen prompts to set up your admin account with email and password.
|
||||
|
||||
### Create a MySQL instance
|
||||
|
||||
1. Log in to Bytebase with your admin account.
|
||||
2. In the left navigation pane, select **Instances**, then click **+ Add Instance**.
|
||||
3. Choose **MySQL** as the database type.
|
||||
4. Fill in the connection fields using values from Control Hub:
|
||||
- **Host or Socket**: Enter the **Host** address and do not include the port.
|
||||
- **Port**: Keep the default, usually `3306`.
|
||||
- **Username**: Enter the **User** value from Control Hub.
|
||||
- **Password**: Enter the **Password** value from Control Hub.
|
||||
5. Click **Test Connection** to verify connectivity, then click **Create**.
|
||||
|
||||
Creating an instance in Bytebase does not create a new database. Once the instance is created, you can use the corresponding client tools to inspect and manage data.
|
||||
76
docs/developer/develop/mw-view-nats-data.md
Normal file
76
docs/developer/develop/mw-view-nats-data.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to subscribe to and publish messages in Olares using NATS CLI, and understand the NATS Subject naming rules and permission model.
|
||||
---
|
||||
# Subscribe and publish messages with NATS
|
||||
|
||||
This guide explains how to use the `nats-box` CLI tool to test NATS message subscription and publication within the Olares cluster, and provides an overview of the NATS Subject naming rules and permission model.
|
||||
|
||||
## Get connection information
|
||||
|
||||
Before connecting, obtain NATS connection details from the Control Hub.
|
||||
|
||||
1. Open Control Hub from Launchpad.
|
||||
2. In the left navigation pane, go to Middleware and select **Nats**.
|
||||
3. On the Subject panel, select a target Subject and record the corresponding information from the same row:
|
||||
- **Subject**: The target message subject.
|
||||
- **User**: The connection username.
|
||||
- **Password**: The connection password.
|
||||
|
||||
{width=60% style="margin-left:0"}
|
||||
|
||||
## Access via CLI
|
||||
|
||||
`nats-box` provides a convenient way to test NATS subscriptions and publications from within the cluster.
|
||||
|
||||
### Deploy `nats-box`
|
||||
|
||||
1. Download the example [`nats-box.yaml`](http://cdn.olares.com/common/nats-box.yaml) file, then upload it to the Olares machine.
|
||||
2. Navigate to the directory containing the YAML file and deploy `nats-box`:
|
||||
```bash
|
||||
kubectl apply -f nats-box.yaml
|
||||
```
|
||||
3. Retrieve the name of the `nats-box` Pod:
|
||||
```bash
|
||||
kubectl get pods -n os-platform | grep nats-box
|
||||
```
|
||||
4. Enter the `nats-box` container:
|
||||
```bash
|
||||
kubectl exec -it -n os-platform <nats-box-pod> -- sh
|
||||
```
|
||||
|
||||
### Subscribe to messages
|
||||
|
||||
Use the Subject, User, and Password obtained from Control Hub to subscribe:
|
||||
```bash
|
||||
nats sub <subject-from-controlhub> --user=<user-from-controlhub> --password=<password-from-controlhub> --all
|
||||
```
|
||||
|
||||
### Publish messages
|
||||
|
||||
Publish a message to the specified Subject:
|
||||
```bash
|
||||
nats pub <subject-from-controlhub> '{"hello":"world"}' --user=<user-from-controlhub> --password=<password-from-controlhub>
|
||||
```
|
||||
|
||||
## Subject naming and permission reference
|
||||
|
||||
This section describes the Subject naming convention and permission model used in Olares.
|
||||
|
||||
### Subject structure
|
||||
|
||||
NATS Subjects use a three-level structure separated by dots (.): `<prefix>.<event>.<olaresId>`.
|
||||
|
||||
| Level | Name | Description |
|
||||
|--|--|--|
|
||||
| 1st |`<prefix>` | Source Identifier. <ul><li>**System services**: Fixed as `os`.</li><li>**Third-party apps**: Uses the corresponding `appId`. </li></ul>|
|
||||
| 2nd | `<event>` | Event type or Domain. <br>Examples: `users`, `groups`, `files`, `notification`. |
|
||||
| 3rd |`<olaresId>` | Represents the Olares ID of the user space. |
|
||||
|
||||
### Permission model
|
||||
Read and write permissions for Subjects vary depending on the application type.
|
||||
|
||||
| App type | Permission scope | Description |
|
||||
|--|--|--|
|
||||
| User space app| Read-only | Can only subscribe to Subjects with a three-level structure containing its own `<olaresId>`. |
|
||||
| System/Cluster app| System-level access | <ul><li>**Subscribe**: Can subscribe to system-level Subjects (e.g., `os.users`, `os.groups`).</li><li>**Write**: Can write to second-level Subjects within its own space.</li><li>**Global Read**: Requires separate approval to subscribe to all second-level Subjects.</li></ul> |
|
||||
188
docs/developer/develop/mw-view-otel-data.md
Normal file
188
docs/developer/develop/mw-view-otel-data.md
Normal file
@@ -0,0 +1,188 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to enable OpenTelemetry auto-instrumentation in an Olares cluster and view trace data in Jaeger.
|
||||
---
|
||||
# View OpenTelemetry data
|
||||
|
||||
This guide walks you through enabling OpenTelemetry auto-instrumentation for services running in an Olares cluster and viewing trace data in Jaeger.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Your target service runs as a Kubernetes workload (Deployment, StatefulSet, or DaemonSet).
|
||||
- You have access to run `kubectl` against the Olares cluster.
|
||||
- You can generate some traffic to the target service. Trace data is generated only when traffic exists.
|
||||
|
||||
## Install Jaeger
|
||||
|
||||
Jaeger is used to visualize trace data. Install Jaeger from Market.
|
||||
|
||||
1. Open Market from Launchpad and search for "Jaeger".
|
||||
2. Click **Get**, then **Install**, and wait for the installation to complete.
|
||||
|
||||
## Apply tracing configuration
|
||||
|
||||
Prepare the tracing backend configuration before enabling auto-instrumentation.
|
||||
|
||||
1. Click [`otc.yaml`](https://cdn.olares.com/common/otc.yaml) to download the configuration file.
|
||||
2. Upload the file to your Olares host.
|
||||
3. In the directory containing the file, apply it:
|
||||
```bash
|
||||
kubectl apply -f otc.yaml
|
||||
```
|
||||
|
||||
## Configure service access
|
||||
|
||||
To enable OpenTelemetry auto-instrumentation, add specific **annotations** to the **Pod template** of your workload.
|
||||
|
||||
Auto-instrumentation is triggered entirely by annotations. No code changes are required.
|
||||
|
||||
:::info Rules for service access configuration
|
||||
- Add annotations under `.spec.template.metadata.annotations` (Pod template, not top-level metadata).
|
||||
- Pods will be recreated (rollout) for injection to take effect.
|
||||
:::
|
||||
|
||||
:::tip Saving changes
|
||||
After you finish editing with `kubectl edit`, save and exit the editor. Kubernetes will roll out updated Pods automatically in most cases.
|
||||
:::
|
||||
|
||||
### BFL service (StatefulSet)
|
||||
|
||||
1. Edit the StatefulSet:
|
||||
```bash
|
||||
kubectl edit sts -n user-space-<olaresid> bfl
|
||||
```
|
||||
2. Under `.spec.template.metadata.annotations`, add:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
tier: bfl
|
||||
# Locate here and add annotations
|
||||
annotations:
|
||||
instrumentation.opentelemetry.io/inject-go: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/go-container-names: "api"
|
||||
instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/bfl-api"
|
||||
instrumentation.opentelemetry.io/inject-nginx: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/inject-nginx-container-names: "ingress"
|
||||
```
|
||||
|
||||
### ChartRepo (Deployment)
|
||||
|
||||
1. Edit the Deployment:
|
||||
```bash
|
||||
kubectl edit deploy -n os-framework chartrepo-deployment
|
||||
```
|
||||
2. Under `.spec.template.metadata.annotations`, add:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: chartrepo
|
||||
io.bytetrade.app: "true"
|
||||
# Locate here and add annotations
|
||||
annotations:
|
||||
instrumentation.opentelemetry.io/inject-go: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/go-container-names: "chartrepo"
|
||||
instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/root/app"
|
||||
```
|
||||
|
||||
### Olares app (Deployment)
|
||||
|
||||
1. Edit the Deployment:
|
||||
```bash
|
||||
kubectl edit deploy -n user-space-<olaresid> olares-app-deployment
|
||||
```
|
||||
2. Under `.spec.template.metadata.annotations`, add:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: olares-app
|
||||
io.bytetrade.app: "true"
|
||||
# Locate here and add annotations
|
||||
annotations:
|
||||
instrumentation.opentelemetry.io/inject-nodejs: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/nodejs-container-names: "user-service"
|
||||
instrumentation.opentelemetry.io/inject-nginx: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/inject-nginx-container-names: "olares-app"
|
||||
```
|
||||
|
||||
### Files (DaemonSet)
|
||||
|
||||
1. Edit the DaemonSet:
|
||||
```bash
|
||||
kubectl edit ds -n os-framework files
|
||||
```
|
||||
2. Under `.spec.template.metadata.annotations`, add:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: files
|
||||
# Locate here and add annotations
|
||||
annotations:
|
||||
instrumentation.opentelemetry.io/inject-nginx: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/inject-nginx-container-names: "nginx"
|
||||
instrumentation.opentelemetry.io/inject-go: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/go-container-names: "gateway,files,uploader"
|
||||
instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/filebrowser"
|
||||
```
|
||||
|
||||
### Market (Deployment)
|
||||
|
||||
1. Edit the Deployment:
|
||||
```bash
|
||||
kubectl edit deploy -n os-framework market-deployment
|
||||
```
|
||||
2. Under `.spec.template.metadata.annotations`, add:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: appstore
|
||||
io.bytetrade.app: "true"
|
||||
# Locate here and add annotations
|
||||
annotations:
|
||||
instrumentation.opentelemetry.io/inject-go: "olares-instrumentation"
|
||||
instrumentation.opentelemetry.io/go-container-names: "appstore-backend"
|
||||
instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/opt/app/market"
|
||||
```
|
||||
|
||||
### System server (Deployment)
|
||||
|
||||
1. Edit the Deployment:
|
||||
```bash
|
||||
kubectl edit deploy -n user-system-<olaresid> system-server
|
||||
```
|
||||
2. Under `.spec.template.metadata.annotations`, add:
|
||||
```yaml
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: systemserver
|
||||
# Locate here and add annotations
|
||||
annotations:
|
||||
instrumentation.opentelemetry.io/go-container-names: "system-server"
|
||||
instrumentation.opentelemetry.io/inject-go: "olares-instrumentation:"
|
||||
instrumentation.opentelemetry.io/otel-go-auto-target-exe: "/system-server"
|
||||
```
|
||||
|
||||
## View traces in Jaeger
|
||||
|
||||
:::info Traces may appear with a delay
|
||||
After rollout, traces may take 1–5 minutes to appear. Make sure the service receives traffic.
|
||||
:::
|
||||
|
||||
Generate traffic to the service.
|
||||
|
||||
1. Open Jaeger from Launchpad.
|
||||
2. Select the service name from the **Service** dropdown.
|
||||
3. Click **Find Traces** to view trace data.
|
||||

|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user