Compare commits
234 Commits
cli/fix/up
...
module-l4-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff7765bcb9 | ||
|
|
c98c855099 | ||
|
|
4ae552f33f | ||
|
|
f2aad6d9f6 | ||
|
|
02bc4fafd5 | ||
|
|
8d34cc995d | ||
|
|
a19e81a4a0 | ||
|
|
ee3f2a7df2 | ||
|
|
73ea65b004 | ||
|
|
4ef2e7124a | ||
|
|
ef46f91ec7 | ||
|
|
0f5a346d86 | ||
|
|
caa799e902 | ||
|
|
2be5f6d108 | ||
|
|
05f3c8ffdc | ||
|
|
c0e242b05c | ||
|
|
7929e420b1 | ||
|
|
66de213f43 | ||
|
|
2166cec66f | ||
|
|
1a0f9727c4 | ||
|
|
810253fe94 | ||
|
|
23429a6193 | ||
|
|
49e40f316f | ||
|
|
1e7b655826 | ||
|
|
adea16ce7e | ||
|
|
c2222859a5 | ||
|
|
e7dde2ff51 | ||
|
|
d06c1e8a99 | ||
|
|
131faacce0 | ||
|
|
8133704761 | ||
|
|
09e61aecad | ||
|
|
bc5fd5fd82 | ||
|
|
1367355661 | ||
|
|
2a506be19a | ||
|
|
30195f1513 | ||
|
|
88b140ccc2 | ||
|
|
39947f464c | ||
|
|
698bdf96ed | ||
|
|
69e6ac35f8 | ||
|
|
f41e66b39a | ||
|
|
1a36faaf6d | ||
|
|
cbdd08d237 | ||
|
|
2fd9d23371 | ||
|
|
f1714534db | ||
|
|
9bc66369df | ||
|
|
ba85b0f60d | ||
|
|
7c2624d418 | ||
|
|
7eb21516d0 | ||
|
|
266aef8616 | ||
|
|
3755bede0c | ||
|
|
cca39eed7e | ||
|
|
b27b90b9a8 | ||
|
|
119ec75234 | ||
|
|
8739bfc040 | ||
|
|
6304739725 | ||
|
|
f8f452b27f | ||
|
|
36acf0384d | ||
|
|
aa5b073b5c | ||
|
|
18dfae6c87 | ||
|
|
a54445db8b | ||
|
|
375e2c4f63 | ||
|
|
c366b56de9 | ||
|
|
85d90a36ed | ||
|
|
172c5342d8 | ||
|
|
dcc0ab1cd2 | ||
|
|
b078f80b5a | ||
|
|
854e25096f | ||
|
|
78949de2b6 | ||
|
|
bd72cb8067 | ||
|
|
3b9f0d33a3 | ||
|
|
3e782c6cea | ||
|
|
28c2979db0 | ||
|
|
fc8ade657d | ||
|
|
74c80a9c7e | ||
|
|
51a06f8964 | ||
|
|
0c50d93d77 | ||
|
|
17b8d2d96e | ||
|
|
5b5e5d289c | ||
|
|
b113f66c4f | ||
|
|
bbbe3ecf9b | ||
|
|
b7ff5db985 | ||
|
|
f39e359ef8 | ||
|
|
4a80ef6148 | ||
|
|
c4af7a5783 | ||
|
|
5c498fbe18 | ||
|
|
4fbe32b141 | ||
|
|
46fc840302 | ||
|
|
5677026de0 | ||
|
|
4d95152e0a | ||
|
|
9560985965 | ||
|
|
1b6d90c2a5 | ||
|
|
2c73b3b7f8 | ||
|
|
22c52398ed | ||
|
|
d1e55515d4 | ||
|
|
5db251520d | ||
|
|
d2b630c7b4 | ||
|
|
0debd332a8 | ||
|
|
9a2c58e3fa | ||
|
|
b8842cfe61 | ||
|
|
70e170b71a | ||
|
|
e975e4aec8 | ||
|
|
9d6d242625 | ||
|
|
86d7b985a2 | ||
|
|
31a2b3ee28 | ||
|
|
9aa7e0b108 | ||
|
|
9092f28458 | ||
|
|
f925268cd4 | ||
|
|
e1c19f7327 | ||
|
|
5e925e0cb6 | ||
|
|
6a0885d37d | ||
|
|
3e46af80e1 | ||
|
|
74c48b81fb | ||
|
|
56aed6b683 | ||
|
|
cbfcf3d3aa | ||
|
|
fd23e52723 | ||
|
|
b48368b934 | ||
|
|
ca9ce45353 | ||
|
|
fa148969c5 | ||
|
|
21c1884bb8 | ||
|
|
b517d08981 | ||
|
|
73e2cd0eb4 | ||
|
|
a631db1e9e | ||
|
|
f3b59b9b3e | ||
|
|
910bf02b48 | ||
|
|
dcc909a06e | ||
|
|
1238ad01f1 | ||
|
|
77ee176f5e | ||
|
|
1d9c3f7b4a | ||
|
|
8a52737f89 | ||
|
|
bd7c46a663 | ||
|
|
9ee4af9040 | ||
|
|
fc86bbadc2 | ||
|
|
52118b1126 | ||
|
|
76be9e82c0 | ||
|
|
478d9f28c8 | ||
|
|
114ed5ad7b | ||
|
|
c85b23d9a9 | ||
|
|
fbc61764ca | ||
|
|
d866966531 | ||
|
|
d140849d7c | ||
|
|
679ddb0f8d | ||
|
|
0ec0a5a4ac | ||
|
|
74ecf9f73d | ||
|
|
028c5c7bdb | ||
|
|
f3ab03becc | ||
|
|
e408da75a4 | ||
|
|
8ffbc82ebd | ||
|
|
304dbf69c5 | ||
|
|
66b0144b40 | ||
|
|
e91a76f92f | ||
|
|
45cd406cd4 | ||
|
|
7ef7ae9335 | ||
|
|
f2f342a28a | ||
|
|
fdca458e4f | ||
|
|
b7141373b7 | ||
|
|
21118c8e95 | ||
|
|
307a6bb502 | ||
|
|
91ec932c95 | ||
|
|
a1cb16cfe9 | ||
|
|
aec5e178b3 | ||
|
|
2624ea5dc5 | ||
|
|
0d1bae720d | ||
|
|
96520a8bc3 | ||
|
|
27b9356037 | ||
|
|
c289d5837c | ||
|
|
e6f9922951 | ||
|
|
a3ad8ce78c | ||
|
|
c70587062a | ||
|
|
f7306b66dc | ||
|
|
325bfeb90d | ||
|
|
bfc3ca0720 | ||
|
|
ef071e43ca | ||
|
|
7440e85c2e | ||
|
|
d71747928c | ||
|
|
473898a715 | ||
|
|
637b1839f7 | ||
|
|
1f1c1a8d3b | ||
|
|
1ddcc3bd4c | ||
|
|
96a2eb524a | ||
|
|
b20d5c0876 | ||
|
|
c4fc3198bb | ||
|
|
260b6154f3 | ||
|
|
ecfcd0d1d8 | ||
|
|
be7f3b3c3f | ||
|
|
99c6d3860d | ||
|
|
9f56cf0f05 | ||
|
|
76c8e93822 | ||
|
|
d38d0d0e1d | ||
|
|
65b32c7c41 | ||
|
|
f6f14e8d9a | ||
|
|
f8653692b1 | ||
|
|
5264df60cc | ||
|
|
1a200ed17c | ||
|
|
48fdaa5481 | ||
|
|
570fe070c9 | ||
|
|
6b18bbd94d | ||
|
|
c6836f9859 | ||
|
|
288869d91d | ||
|
|
8ea8a0857e | ||
|
|
87674cc5d9 | ||
|
|
11f556e9af | ||
|
|
d2d3195fea | ||
|
|
ad3b138284 | ||
|
|
ff609db1aa | ||
|
|
43c6bff906 | ||
|
|
b28dac652c | ||
|
|
fbb5c08227 | ||
|
|
a04d363597 | ||
|
|
994d2b9b91 | ||
|
|
909b7656fd | ||
|
|
c61260cb5a | ||
|
|
fed1a60c63 | ||
|
|
7062408f5d | ||
|
|
583ec7730c | ||
|
|
e9f3b23ac9 | ||
|
|
7f09420bdf | ||
|
|
c93869db02 | ||
|
|
2f23def478 | ||
|
|
4c5c43982a | ||
|
|
a2a6c581c2 | ||
|
|
8b1a7e11f5 | ||
|
|
2181adb67c | ||
|
|
e1b0bd7875 | ||
|
|
e465a2d8fc | ||
|
|
70d0ae1ff5 | ||
|
|
e52db36045 | ||
|
|
1935b1fbb6 | ||
|
|
5dc69bf80e | ||
|
|
e839d5ae41 | ||
|
|
e89c6f35cc | ||
|
|
c4a7c81777 | ||
|
|
a69b5d40a9 | ||
|
|
bab074cd37 | ||
|
|
afb7d49455 |
2
.github/workflows/check.yaml
vendored
2
.github/workflows/check.yaml
vendored
@@ -75,7 +75,7 @@ jobs:
|
||||
steps:
|
||||
- id: generate
|
||||
run: |
|
||||
v=1.12.4-$(echo $RANDOM$RANDOM)
|
||||
v=1.12.5-$(echo $RANDOM$RANDOM)
|
||||
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
upload-cli:
|
||||
|
||||
2
.github/workflows/release-cli.yaml
vendored
2
.github/workflows/release-cli.yaml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.24.3
|
||||
go-version: 1.24.11
|
||||
|
||||
- name: Install x86_64 cross-compiler
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential
|
||||
|
||||
2
.github/workflows/release-daemon.yaml
vendored
2
.github/workflows/release-daemon.yaml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.22.1
|
||||
go-version: 1.24.11
|
||||
|
||||
- name: install udev-devel and pcap-devel
|
||||
run: |
|
||||
|
||||
2
.github/workflows/release-daily.yaml
vendored
2
.github/workflows/release-daily.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- id: generate
|
||||
run: |
|
||||
v=1.12.4-$(date +"%Y%m%d")
|
||||
v=1.12.5-$(date +"%Y%m%d")
|
||||
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
release-id:
|
||||
|
||||
@@ -317,7 +317,7 @@ spec:
|
||||
chown -R 1000:1000 /uploadstemp && \
|
||||
chown -R 1000:1000 /appdata
|
||||
- name: olares-app-init
|
||||
image: beclab/system-frontend:v1.6.28
|
||||
image: beclab/system-frontend:v1.8.2
|
||||
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.81
|
||||
image: beclab/user-service:v0.0.82
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
@@ -1356,6 +1356,17 @@ data:
|
||||
proxy_set_header Connection '$connection_upgrade';
|
||||
more_set_headers 'Upgrade: $http_upgrade';
|
||||
}
|
||||
location /api/refresh {
|
||||
add_header Access-Control-Allow-Headers "access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,content-type,x-auth,x-unauth-error,x-authorization";
|
||||
add_header Access-Control-Allow-Methods "PUT, GET, DELETE, POST, OPTIONS";
|
||||
add_header Access-Control-Allow-Origin $http_origin;
|
||||
add_header Access-Control-Allow-Credentials true;
|
||||
proxy_pass http://authelia-backend-svc:9091;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
}
|
||||
location / {
|
||||
proxy_pass http://headscale-server-svc:8080;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: wizard
|
||||
image: beclab/wizard:v1.6.5
|
||||
image: beclab/wizard:v1.6.40
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
201
apps/README.md
201
apps/README.md
@@ -17,4 +17,203 @@ This directory contains the code for system applications, primarily for LarePass
|
||||
| Settings | A system configuration application. |
|
||||
| Dashboard | An app for monitoring system resource usage. |
|
||||
| Control Hub | The console for Olares, providing precise and autonomous control over the system and its environment. |
|
||||
| DevBox | A development tool for building and deploying Olares applications. |
|
||||
| Studio | A development tool for building and deploying Olares applications. |
|
||||
|
||||
|
||||
# Local Development Guide
|
||||
|
||||
This document describes how to start and develop various sub-projects locally.
|
||||
|
||||
## Available Projects
|
||||
|
||||
| Project | Command | Port |
|
||||
|---------|---------|------|
|
||||
| Desktop | `npm run dev:desktop` | 1090 |
|
||||
| Files | `npm run dev:files` | 5090 |
|
||||
| Settings | `npm run dev:settings` | 9000 |
|
||||
| Market | `npm run dev:market` | 8080 |
|
||||
| Vault | `npm run dev:vault` | 8090 |
|
||||
| Wise | `npm run dev:wise` | 8100 |
|
||||
| Dashboard | `npm run dev:dashboard` | 9003 |
|
||||
| Control Hub | `npm run dev:hub` | 9002 |
|
||||
| Share | `npm run dev:share` | 5070 |
|
||||
| Editor | `npm run dev:editor` | 9100 |
|
||||
| Preview | `npm run dev:preview` | 9001 |
|
||||
| Studio | `npm run dev:studio` | 9001 |
|
||||
|
||||
## Step 1: Modify Local Hosts File
|
||||
|
||||
Projects require access through a specific domain name. You need to configure the local hosts file first.
|
||||
|
||||
### macOS / Linux
|
||||
|
||||
1. Open terminal and edit the hosts file with administrator privileges:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/hosts
|
||||
```
|
||||
|
||||
Or use the nano editor:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/hosts
|
||||
```
|
||||
|
||||
2. Add the following content at the end of the file:
|
||||
|
||||
```
|
||||
127.0.0.1 test.xxx.olares.com
|
||||
```
|
||||
|
||||
3. Save the file and exit
|
||||
- vim: Press `ESC`, type `:wq` and press Enter
|
||||
- nano: Press `Ctrl + O` to save, `Ctrl + X` to exit
|
||||
|
||||
### Windows
|
||||
|
||||
1. Run Notepad as administrator:
|
||||
- Search for "Notepad" in the Start menu
|
||||
- Right-click on "Notepad" and select "Run as administrator"
|
||||
|
||||
2. Open the hosts file in Notepad:
|
||||
- Click `File` -> `Open`
|
||||
- Paste the path in the filename field: `C:\Windows\System32\drivers\etc\hosts`
|
||||
- Change file type to "All Files (*.*)"
|
||||
- Click "Open"
|
||||
|
||||
3. Add the following content at the end of the file:
|
||||
|
||||
```
|
||||
127.0.0.1 test.xxx.olares.com
|
||||
```
|
||||
|
||||
4. Save the file (`Ctrl + S`)
|
||||
|
||||
5. Flush DNS cache (optional):
|
||||
- Open Command Prompt (CMD) as administrator
|
||||
- Run the following command:
|
||||
|
||||
```cmd
|
||||
ipconfig /flushdns
|
||||
```
|
||||
|
||||
## Step 2: Install Dependencies
|
||||
|
||||
Run in the project root directory (`olares-app`):
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## Step 3: Configure Environment Variables
|
||||
|
||||
Create or edit the `.env` file in the `packages/app` directory and add the following content:
|
||||
|
||||
```env
|
||||
ACCOUNT_DOMAIN=xxx.olares.com
|
||||
DEV_DOMAIN=test.xxx.olares.com
|
||||
```
|
||||
|
||||
> **Note**:
|
||||
> - `ACCOUNT_DOMAIN`: Your Olares account domain, used for API proxy
|
||||
> - `DEV_DOMAIN`: Local development server domain, must match the domain configured in the hosts file
|
||||
|
||||
## Step 4: Start the Project
|
||||
|
||||
After configuring the `.env` file, run the corresponding command in the `packages/app` directory:
|
||||
|
||||
```bash
|
||||
# Start Desktop
|
||||
npm run dev:desktop
|
||||
|
||||
# Start Files
|
||||
npm run dev:files
|
||||
|
||||
# Start Settings
|
||||
npm run dev:settings
|
||||
|
||||
# Start Market
|
||||
npm run dev:market
|
||||
|
||||
# Start other projects...
|
||||
npm run dev:<project>
|
||||
```
|
||||
|
||||
## Step 5: Access the Application
|
||||
|
||||
After successful startup, visit in your browser (replace port according to the project):
|
||||
|
||||
| Project | URL |
|
||||
|---------|-----|
|
||||
| Desktop | `https://test.xxx.olares.com:1090` |
|
||||
| Files | `https://test.xxx.olares.com:5090` |
|
||||
| Settings | `https://test.xxx.olares.com:9000` |
|
||||
| Market | `https://test.xxx.olares.com:8080` |
|
||||
| Vault | `https://test.xxx.olares.com:8090` |
|
||||
| Wise | `https://test.xxx.olares.com:8100` |
|
||||
| Dashboard | `https://test.xxx.olares.com:9003` |
|
||||
| Control Hub | `https://test.xxx.olares.com:9002` |
|
||||
| Share | `https://test.xxx.olares.com:5070` |
|
||||
| Editor | `https://test.xxx.olares.com:9100` |
|
||||
| Preview | `https://test.xxx.olares.com:9001` |
|
||||
| Studio | `https://test.xxx.olares.com:9001` |
|
||||
|
||||
> **Note**: Since a self-signed certificate is used, the browser may display an insecure connection warning. Click "Advanced" and select "Proceed" to continue.
|
||||
|
||||
## Environment Variables (.env file)
|
||||
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `ACCOUNT_DOMAIN` | Account domain (for API proxy) | `xxx.olares.com` |
|
||||
| `DEV_DOMAIN` | Development server domain | `test.xxx.olares.com` |
|
||||
|
||||
## FAQ
|
||||
|
||||
### 1. Cannot Access the Application
|
||||
|
||||
- Check if the hosts file is configured correctly
|
||||
- Ensure the development server has started successfully
|
||||
- Check if the firewall is blocking the corresponding port
|
||||
|
||||
### 2. Certificate Error
|
||||
|
||||
The development server uses HTTPS. The browser will show a certificate warning on first visit - this is expected behavior.
|
||||
|
||||
### 3. API Request Failed
|
||||
|
||||
Ensure the `ACCOUNT_DOMAIN` in the `.env` file is set correctly. The proxy configuration relies on this variable to forward requests to the correct backend service.
|
||||
|
||||
## Build for Production
|
||||
|
||||
```bash
|
||||
# Build Desktop
|
||||
npm run build:desktop
|
||||
|
||||
# Build Files
|
||||
npm run build:files
|
||||
|
||||
# Build Settings
|
||||
npm run build:settings
|
||||
|
||||
# Build other projects...
|
||||
npm run build:<project>
|
||||
```
|
||||
|
||||
### Build Output Directory
|
||||
|
||||
| Project | Output Directory |
|
||||
|---------|------------------|
|
||||
| Desktop | `dist/apps/desktop` |
|
||||
| Files | `dist/apps/files` |
|
||||
| Settings | `dist/apps/settings` |
|
||||
| Market | `dist/apps/market` |
|
||||
| Vault | `dist/apps/vault` |
|
||||
| Dashboard | `dist/apps/dashboard` |
|
||||
| Control Hub | `dist/apps/control-hub` |
|
||||
| Share | `dist/apps/share` |
|
||||
| Editor | `dist/apps/editor` |
|
||||
| Preview | `dist/apps/preview` |
|
||||
| **Wise** | `dist/spa` |
|
||||
| **Studio** | `dist/spa` |
|
||||
|
||||
> **Note**: Build outputs for Wise and Studio are located in `dist/spa` directory, not under `dist/apps/`.
|
||||
@@ -1,2 +1,2 @@
|
||||
DEV_DOMAIN=test.guotest334.olares.cn
|
||||
ACCOUNT_DOMAIN=guotest334.olares.cn
|
||||
DEV_DOMAIN=test.xxx.olares.com
|
||||
ACCOUNT_DOMAIN=xxx.olares.com
|
||||
|
||||
@@ -62,6 +62,8 @@ module.exports = configure(function (ctx) {
|
||||
|
||||
env: {
|
||||
PL_SERVER_URL: process.env.PL_SERVER_URL,
|
||||
VAULT_MOCK_BFL_TOKEN: process.env.VAULT_MOCK_BFL_TOKEN,
|
||||
VAULT_MOCK_PASSWORD: process.env.VAULT_MOCK_PASSWORD,
|
||||
PLATFORM: process.env.PLATFORM,
|
||||
DEV_PLATFORM: process.env.DEV_PLATFORM,
|
||||
APPLICATION_SUB: process.env.APPLICATION_SUB,
|
||||
|
||||
@@ -107,4 +107,6 @@ export interface NativeAppPlatform extends AppPlatform {
|
||||
getQuasar(): QVueGlobals | undefined;
|
||||
|
||||
getRouter(): Router | undefined;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -78,4 +78,16 @@ export interface AppPlatform extends Platform, PlatformExtension {
|
||||
isTabbarDisplay(): boolean;
|
||||
|
||||
userAgent: string;
|
||||
|
||||
socialKeys: {
|
||||
facebook: {
|
||||
appId: string;
|
||||
clientToken: string;
|
||||
},
|
||||
google: {
|
||||
webClientId: string;
|
||||
iOSClientId: string;
|
||||
androidClientId: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ClientSchema } from '../../../../globals';
|
||||
import { i18n } from '../../../../boot/i18n';
|
||||
import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc';
|
||||
import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social';
|
||||
import { getAppPlatform } from 'src/application/platform';
|
||||
|
||||
export async function facebookLogin(
|
||||
did: string,
|
||||
@@ -22,12 +23,8 @@ export async function facebookLogin(
|
||||
}
|
||||
const manifest = stringToBase64(JSON.stringify(schema?.manifest));
|
||||
|
||||
// await FacebookLogin.initialize({ appId: '549140590110570' });
|
||||
await LarePassSocialLogin.initialize({
|
||||
facebook: {
|
||||
appId: '549140590110570',
|
||||
clientToken: '82fca90b3fa47e9083aa7dba75744ee0'
|
||||
}
|
||||
facebook: getAppPlatform().socialKeys.facebook
|
||||
});
|
||||
|
||||
const FACEBOOK_PERMISSIONS = ['email'];
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ClientSchema } from '../../../../globals';
|
||||
import { i18n } from '../../../../boot/i18n';
|
||||
import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc';
|
||||
import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social';
|
||||
import { getAppPlatform } from 'src/application/platform';
|
||||
|
||||
export async function googleLogin(
|
||||
did: string,
|
||||
@@ -22,10 +23,10 @@ export async function googleLogin(
|
||||
await LarePassSocialLogin.initialize({
|
||||
google: {
|
||||
webClientId:
|
||||
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms
|
||||
getAppPlatform().socialKeys.google.webClientId,
|
||||
iOSClientId:
|
||||
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS
|
||||
mode: 'online' // replaces grantOfflineAccess
|
||||
getAppPlatform().socialKeys.google.iOSClientId,
|
||||
mode: 'online'
|
||||
}
|
||||
});
|
||||
await LarePassSocialLogin.logout({ provider: 'google' });
|
||||
|
||||
@@ -45,15 +45,14 @@ export default defineComponent({
|
||||
const bfl_token = ref<string>('');
|
||||
|
||||
if (process.env.PL_SERVER_URL) {
|
||||
bfl_token.value =
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg3NzU0OTQsImlhdCI6MTY3ODc2ODI5NCwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.Yr7OhrQ39OXmesVJldORZ34UsFZpiiCWpssKlRxEOR4';
|
||||
bfl_token.value = process.env.VAULT_MOCK_BFL_TOKEN;
|
||||
}
|
||||
|
||||
const url = ref<string>(
|
||||
base_url +
|
||||
'?bfl_token=' +
|
||||
bfl_token.value +
|
||||
'&username=liuyu&password=Test123456'
|
||||
`&username=liuyu&password=${process.env.VAULT_MOCK_PASSWORD}`
|
||||
);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -112,7 +112,6 @@ const genOlares = async ({ text, from, to }) => {
|
||||
const init = {
|
||||
headers: {
|
||||
'Content-type': 'application/json'
|
||||
// 'X-Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NzMzMjE1MjUsImlhdCI6MTc0MTc4NTUyNSwidXNlcm5hbWUiOiJ5YW5neW9uZ2hlbmciLCJncm91cHMiOlsibGxkYXBfcmVndWxhciJdfQ.V3CHWllD4GETOklamEg-hwhT5DR4lKZGLEgpOULpW_ZXuZ-MTYvOFoZatWVWs6wQjT8IrLHF6leyUI09qsgZuw'
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify(params)
|
||||
|
||||
@@ -70,4 +70,16 @@ export class SubAppPlatform extends WebPlatform implements AppPlatform {
|
||||
}
|
||||
|
||||
userAgent = navigator.userAgent;
|
||||
|
||||
socialKeys = {
|
||||
facebook: {
|
||||
appId: '',
|
||||
clientToken: ''
|
||||
},
|
||||
google: {
|
||||
webClientId: '',
|
||||
iOSClientId: '',
|
||||
androidClientId: ''
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,10 +19,9 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
|
||||
];
|
||||
await LarePassSocialLogin.initialize({
|
||||
google: {
|
||||
webClientId:
|
||||
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms
|
||||
webClientId: getAppPlatform().socialKeys.google.webClientId,
|
||||
iOSClientId:
|
||||
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS
|
||||
getAppPlatform().socialKeys.google.iOSClientId,
|
||||
mode: getAppPlatform().getQuasar()?.platform.is?.android
|
||||
? 'offline'
|
||||
: 'online' // replaces grantOfflineAccess
|
||||
@@ -45,8 +44,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
|
||||
let clientId = '';
|
||||
|
||||
if (getAppPlatform().getQuasar()?.platform.is?.android) {
|
||||
clientId =
|
||||
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com';
|
||||
clientId = getAppPlatform().socialKeys.google.androidClientId;
|
||||
response = await axiosInstanceProxy(
|
||||
{
|
||||
baseURL: 'https://cloud-api.jointerminus.com/',
|
||||
@@ -68,8 +66,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
|
||||
);
|
||||
}
|
||||
} else {
|
||||
clientId =
|
||||
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com';
|
||||
clientId = getAppPlatform().socialKeys.google.iOSClientId;
|
||||
}
|
||||
|
||||
const result = {
|
||||
|
||||
@@ -5,6 +5,16 @@ import level from 'level';
|
||||
|
||||
const TERMINUS_NAME = process.env.TERMINUS_NAME || 'did';
|
||||
|
||||
const REFRESH_TOKEN = process.env.REFRESH_TOKEN || '';
|
||||
|
||||
const ACCESS_TOKEN = process.env.ACCESS_TOKEN || '';
|
||||
|
||||
const SESSION_ID = process.env.SESSION_ID || '';
|
||||
|
||||
const BASE32_SECRET = process.env.BASE32_SECRET || ''
|
||||
|
||||
const OTP_AUTH_URL = process.env.OPT_AUTH_URL || '';
|
||||
|
||||
export interface UserInfo {
|
||||
olaresId: string;
|
||||
wizardStatus: string;
|
||||
@@ -259,9 +269,8 @@ export class ApiControllers {
|
||||
const result = {
|
||||
status: 'OK',
|
||||
data: {
|
||||
base32_secret: 'Z6JJH64KWRFXPBHTHVPF2XZT6INZEKVTMSLWPIFNKXXS2FSZ3QUQ',
|
||||
otpauth_url:
|
||||
'otpauth://totp/authelia.com:liuyu?algorithm=SHA1&digits=6&issuer=authelia.com&period=30&secret=Z6JJH64KWRFXPBHTHVPF2XZT6INZEKVTMSLWPIFNKXXS2FSZ3QUQ'
|
||||
base32_secret: BASE32_SECRET,
|
||||
otpauth_url: OTP_AUTH_URL
|
||||
}
|
||||
};
|
||||
|
||||
@@ -294,14 +303,6 @@ export class ApiControllers {
|
||||
const username = request.body['username'];
|
||||
const password = request.body['password'];
|
||||
|
||||
// if (password !== '123456') {
|
||||
// response.set('Content-Type', 'application/json');
|
||||
// response.status(401).send({
|
||||
// status: 'Failed'
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (username != TERMINUS_NAME.split('@')[0]) {
|
||||
response.set('Content-Type', 'application/json');
|
||||
|
||||
@@ -314,13 +315,11 @@ export class ApiControllers {
|
||||
const result = {
|
||||
status: 'OK',
|
||||
data: {
|
||||
access_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
|
||||
refresh_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
|
||||
access_token: ACCESS_TOKEN,
|
||||
refresh_token: REFRESH_TOKEN,
|
||||
fa2: true,
|
||||
redirect: '',
|
||||
session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
|
||||
session_id: SESSION_ID
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,20 +333,13 @@ export class ApiControllers {
|
||||
const result: any = {
|
||||
status: 'OK',
|
||||
data: {
|
||||
access_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
|
||||
refresh_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
|
||||
access_token: ACCESS_TOKEN,
|
||||
refresh_token: REFRESH_TOKEN,
|
||||
fa2: true,
|
||||
redirect: '/abcd',
|
||||
session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
|
||||
session_id: SESSION_ID
|
||||
}
|
||||
};
|
||||
// if (request.body.token !== '123456') {
|
||||
// result = {
|
||||
// status: 'Failed'
|
||||
// };
|
||||
// }
|
||||
|
||||
response.set('Content-Type', 'application/json');
|
||||
response.send(result);
|
||||
|
||||
@@ -1044,16 +1044,6 @@ export class Controller extends API {
|
||||
// }
|
||||
// }
|
||||
|
||||
// {
|
||||
// @didvault/server: status: 'OK',
|
||||
// @didvault/server: data: {
|
||||
// @didvault/server: redirect: '',
|
||||
// @didvault/server: access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
|
||||
// @didvault/server: refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
|
||||
// @didvault/server: fa2: true,
|
||||
// @didvault/server: session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
|
||||
// @didvault/server: }
|
||||
// @didvault/server: }
|
||||
// async cert_firstfactor(
|
||||
// username: string,
|
||||
// password: string,
|
||||
|
||||
@@ -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.4-$ts"
|
||||
export VERSION="1.12.5-$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.4-20241124 bash $0"
|
||||
echo "for example: VERSION=1.12.5-20241124 bash $0"
|
||||
exit 1
|
||||
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.4-20241124 bash $0"
|
||||
echo "for example: VERSION=1.12.5-20241124 bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ fi
|
||||
|
||||
|
||||
find $BASE_DIR/../ -type f -name Olares.yaml | while read f; do
|
||||
if [[ "$f" == *"/vendor/"* ]]; then
|
||||
echo "skip vendor file $f"
|
||||
continue
|
||||
fi
|
||||
echo "Processing $f"
|
||||
declare -a bins
|
||||
IFS=
|
||||
|
||||
21
cli/cmd/ctl/amdgpu/install.go
Normal file
21
cli/cmd/ctl/amdgpu/install.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuInstall() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install AMD ROCm stack via amdgpu-install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuInstall(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
16
cli/cmd/ctl/amdgpu/root.go
Normal file
16
cli/cmd/ctl/amdgpu/root.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package amdgpu
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func NewCmdAmdGpu() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "amdgpu",
|
||||
Short: "Manage AMD GPU ROCm stack",
|
||||
}
|
||||
cmd.AddCommand(NewCmdAmdGpuInstall())
|
||||
cmd.AddCommand(NewCmdAmdGpuUninstall())
|
||||
cmd.AddCommand(NewCmdAmdGpuStatus())
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
21
cli/cmd/ctl/amdgpu/status.go
Normal file
21
cli/cmd/ctl/amdgpu/status.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuStatus() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show AMD GPU driver and ROCm status",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuStatus(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
21
cli/cmd/ctl/amdgpu/uninstall.go
Normal file
21
cli/cmd/ctl/amdgpu/uninstall.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuUninstall() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "uninstall",
|
||||
Short: "Uninstall AMD ROCm stack via amdgpu-install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuUninstall(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -3,19 +3,24 @@ package os
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -242,7 +247,6 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
if err := cmd.Run(); err != nil {
|
||||
logFile.Close()
|
||||
return fmt.Errorf("failed to collect logs for %s: %v", service, err)
|
||||
continue
|
||||
}
|
||||
logFile.Close()
|
||||
|
||||
@@ -276,7 +280,7 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
|
||||
func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
cmd := exec.Command("dmesg")
|
||||
cmd := exec.Command("dmesg -T")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -375,49 +379,153 @@ func collectKubernetesLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
cmd = exec.Command("kubectl", "describe", "pods", "--all-namespaces")
|
||||
output, err = tryKubectlCommand(cmd, "describe pods", options)
|
||||
if err != nil && !options.IgnoreKubeErrors {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
header := &tar.Header{
|
||||
Name: "pods-describe.txt",
|
||||
Mode: 0644,
|
||||
Size: int64(len(output)),
|
||||
ModTime: time.Now(),
|
||||
resourceTypes := []string{"node", "pod", "statefulset", "deployment", "replicaset", "service", "configmap"}
|
||||
|
||||
for _, res := range resourceTypes {
|
||||
cmd = exec.Command("kubectl", "describe", res, "--all-namespaces")
|
||||
output, err = tryKubectlCommand(cmd, fmt.Sprintf("describe %s", res), options)
|
||||
if err != nil && !options.IgnoreKubeErrors {
|
||||
return err
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write pods description header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(output); err != nil {
|
||||
return fmt.Errorf("failed to write pods description data: %v", err)
|
||||
if err == nil {
|
||||
header := &tar.Header{
|
||||
Name: fmt.Sprintf("%s-describe.txt", res),
|
||||
Mode: 0644,
|
||||
Size: int64(len(output)),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write %s description header: %v", res, err)
|
||||
}
|
||||
if _, err := tw.Write(output); err != nil {
|
||||
return fmt.Errorf("failed to write %s description data: %v", res, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd = exec.Command("kubectl", "describe", "node")
|
||||
output, err = tryKubectlCommand(cmd, "describe node", options)
|
||||
if err != nil && !options.IgnoreKubeErrors {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
header := &tar.Header{
|
||||
Name: "node-describe.txt",
|
||||
Mode: 0644,
|
||||
Size: int64(len(output)),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write node description header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(output); err != nil {
|
||||
return fmt.Errorf("failed to write node description data: %v", err)
|
||||
if err := collectNginxLogsFromLabeledPods(tw); err != nil {
|
||||
if !options.IgnoreKubeErrors {
|
||||
return fmt.Errorf("failed to collect nginx logs from labeled pods: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectNginxLogsFromLabeledPods(tw *tar.Writer) error {
|
||||
if _, err := util.GetCommand("kubectl"); err != nil {
|
||||
fmt.Printf("warning: kubectl not found, skipping collecting nginx logs from labeled pods\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get kubeconfig: %v", err)
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create kube client: %v", err)
|
||||
}
|
||||
|
||||
type selectorSpec struct {
|
||||
LabelSelector string
|
||||
ContainerName string
|
||||
}
|
||||
selectors := []selectorSpec{
|
||||
{LabelSelector: "app=l4-bfl-proxy", ContainerName: ""},
|
||||
{LabelSelector: "tier=bfl", ContainerName: "ingress"},
|
||||
}
|
||||
|
||||
type targetPod struct {
|
||||
Namespace string
|
||||
Name string
|
||||
ContainerName string
|
||||
}
|
||||
var targets []targetPod
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
for _, sel := range selectors {
|
||||
podList, err := clientset.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{LabelSelector: sel.LabelSelector})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list pods by label %q: %v", sel.LabelSelector, err)
|
||||
}
|
||||
for _, pod := range podList.Items {
|
||||
targets = append(targets, targetPod{
|
||||
Namespace: pod.Namespace,
|
||||
Name: pod.Name,
|
||||
ContainerName: sel.ContainerName,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(targets) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// simplest approach: use kubectl cp (it already implements copy via tar over exec)
|
||||
tempDir, err := os.MkdirTemp("", "olares-nginx-logs-*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temp directory for nginx logs: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
files := []string{"/var/log/nginx/access.log", "/var/log/nginx/error.log"}
|
||||
for _, target := range targets {
|
||||
for _, remotePath := range files {
|
||||
base := filepath.Base(remotePath)
|
||||
archivePath := filepath.Join("nginx", target.Namespace, target.Name, base)
|
||||
|
||||
dest := filepath.Join(tempDir, fmt.Sprintf("%s__%s__%s", target.Namespace, target.Name, base))
|
||||
|
||||
err := kubectlCopyFile(target.Namespace, target.Name, target.ContainerName, remotePath, dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to kubectl cp %s/%s:%s: %v", target.Namespace, target.Name, remotePath, err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat(dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stat copied nginx log %s: %v", dest, err)
|
||||
}
|
||||
|
||||
f, err := os.Open(dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open copied nginx log %s: %v", dest, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
header := &tar.Header{
|
||||
Name: archivePath,
|
||||
Mode: 0644,
|
||||
Size: fi.Size(),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write header for %s: %v", archivePath, err)
|
||||
}
|
||||
if _, err := io.CopyN(tw, f, header.Size); err != nil {
|
||||
return fmt.Errorf("failed to write data for %s: %v", archivePath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func kubectlCopyFile(namespace, pod, container, remotePath, destPath string) error {
|
||||
args := []string{"-n", namespace, "cp"}
|
||||
if container != "" {
|
||||
args = append(args, "-c", container)
|
||||
}
|
||||
args = append(args, fmt.Sprintf("%s:%s", pod, remotePath), destPath)
|
||||
|
||||
cmd := exec.Command("kubectl", args...)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("kubectl %s failed: %v, output: %s", strings.Join(args, " "), err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
if _, err := util.GetCommand("ip"); err == nil {
|
||||
cmd := exec.Command("ip", "address")
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewCmdRelease() *cobra.Command {
|
||||
}
|
||||
|
||||
if version == "" {
|
||||
version = fmt.Sprintf("1.12.4-%s", time.Now().Format("20060102150405"))
|
||||
version = fmt.Sprintf("1.12.5-%s", time.Now().Format("20060102150405"))
|
||||
fmt.Printf("--version unspecified, using: %s\n", version)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ctl
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/amdgpu"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/disk"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/gpu"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/node"
|
||||
@@ -33,6 +34,7 @@ func NewDefaultCommand() *cobra.Command {
|
||||
cmds.AddCommand(os.NewOSCommands()...)
|
||||
cmds.AddCommand(node.NewNodeCommand())
|
||||
cmds.AddCommand(gpu.NewCmdGpu())
|
||||
cmds.AddCommand(amdgpu.NewCmdAmdGpu())
|
||||
cmds.AddCommand(user.NewUserCommand())
|
||||
cmds.AddCommand(disk.NewDiskCommand())
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"os"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newUserClientFromKubeConfig(kubeconfig string) (client.Client, error) {
|
||||
|
||||
33
cli/go.mod
33
cli/go.mod
@@ -1,27 +1,21 @@
|
||||
module github.com/beclab/Olares/cli
|
||||
|
||||
go 1.24.2
|
||||
|
||||
toolchain go1.24.6
|
||||
go 1.24.11
|
||||
|
||||
replace (
|
||||
bytetrade.io/web3os/app-service => github.com/beclab/app-service v0.4.41
|
||||
bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17
|
||||
github.com/containers/image/v5 => github.com/containers/image/v5 v5.21.1
|
||||
github.com/containers/storage => github.com/containers/storage v1.40.0
|
||||
github.com/estesp/manifest-tool/v2 => github.com/estesp/manifest-tool/v2 v2.0.3
|
||||
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
bytetrade.io/web3os/app-service v0.0.0-00010101000000-000000000000
|
||||
bytetrade.io/web3os/backups-sdk v0.0.0-00010101000000-000000000000
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/PaesslerAG/jsonpath v0.1.1
|
||||
github.com/alecthomas/assert/v2 v2.11.0
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70
|
||||
github.com/beclab/api v0.0.2
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1
|
||||
github.com/containerd/containerd v1.7.28
|
||||
github.com/containerd/containerd v1.7.29
|
||||
github.com/decentralized-identity/web5-go v0.25.0
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
|
||||
github.com/distribution/reference v0.6.0
|
||||
@@ -48,10 +42,10 @@ require (
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
golang.org/x/sys v0.35.0
|
||||
golang.org/x/term v0.34.0
|
||||
golang.org/x/text v0.28.0
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/sys v0.38.0
|
||||
golang.org/x/term v0.37.0
|
||||
golang.org/x/text v0.31.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
helm.sh/helm/v3 v3.18.6
|
||||
@@ -94,9 +88,11 @@ require (
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/containers/image/v5 v5.36.1 // indirect
|
||||
github.com/containers/storage v1.59.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
@@ -174,7 +170,7 @@ require (
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.2.1 // indirect
|
||||
github.com/opencontainers/selinux v1.12.0 // indirect
|
||||
github.com/opencontainers/selinux v1.13.1 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
@@ -205,10 +201,11 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
|
||||
72
cli/go.sum
72
cli/go.sum
@@ -43,10 +43,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70 h1:U3z6m0hokD1gzl788BrUdxCbDyAjdOBBXA8ilYgn6VQ=
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70/go.mod h1:D9wl7y3obLqXMqfubMROMgdxWAwInnKNrFC//d0nyIA=
|
||||
github.com/beclab/api v0.0.2 h1:aD5RcMie2uqa/FZI7aQBa1F4yVEib8/x3IIZSLiHkBM=
|
||||
github.com/beclab/api v0.0.2/go.mod h1:ESZLe8cf4934QFkU6cqbskKfiTyNk67i1qbv/ctS6js=
|
||||
github.com/beclab/app-service v0.4.41 h1:WSIXEqHSAepHweBooPkc+pedVaGGn335RugNwixkciY=
|
||||
github.com/beclab/app-service v0.4.41/go.mod h1:0vEg3rv/DbR7dYznvTlXNXyYNn+TXNMaxz03GQYRWUQ=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
@@ -68,8 +68,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
|
||||
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c=
|
||||
github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
|
||||
github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
|
||||
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
|
||||
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
|
||||
@@ -88,13 +88,17 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
|
||||
github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
|
||||
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||
github.com/containers/image/v5 v5.36.1 h1:6zpXBqR59UcAzoKpa/By5XekeqFV+htWYfr65+Cgjqo=
|
||||
github.com/containers/image/v5 v5.36.1/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4=
|
||||
github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs=
|
||||
github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
|
||||
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
@@ -105,16 +109,14 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=
|
||||
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
@@ -262,6 +264,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
@@ -348,6 +352,8 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nats-io/nats.go v1.45.0 h1:/wGPbnYXDM0pLKFjZTX+2JOw9TQPoIgTFrUaH97giwA=
|
||||
@@ -368,12 +374,12 @@ github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
|
||||
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
|
||||
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
|
||||
github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
|
||||
github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
@@ -502,8 +508,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glB
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU=
|
||||
@@ -542,8 +548,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -552,8 +558,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -564,8 +570,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
@@ -574,8 +580,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -587,14 +593,14 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -606,8 +612,10 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
133
cli/pkg/amdgpu/tasks.go
Normal file
133
cli/pkg/amdgpu/tasks.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"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/Masterminds/semver/v3"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// InstallAmdRocmModule installs AMD ROCm stack on supported Ubuntu if AMD GPU is present.
|
||||
type InstallAmdRocmModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (m *InstallAmdRocmModule) Init() {
|
||||
m.Name = "InstallAMDGPU"
|
||||
|
||||
installAmd := &task.RemoteTask{
|
||||
Name: "InstallAmdRocm",
|
||||
Hosts: m.Runtime.GetHostsByRole(common.Master),
|
||||
Action: &InstallAmdRocm{
|
||||
// no manifest needed
|
||||
},
|
||||
Parallel: false,
|
||||
Retry: 1,
|
||||
}
|
||||
|
||||
m.Tasks = []task.Interface{
|
||||
installAmd,
|
||||
}
|
||||
}
|
||||
|
||||
// InstallAmdRocm installs ROCm using amdgpu-install on Ubuntu 22.04/24.04 for AMD GPUs.
|
||||
type InstallAmdRocm struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *InstallAmdRocm) Execute(runtime connector.Runtime) error {
|
||||
si := runtime.GetSystemInfo()
|
||||
if !si.IsLinux() || !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
amdGPUExists, err := utils.HasAmdIGPU(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// skip rocm install
|
||||
if !amdGPUExists {
|
||||
return nil
|
||||
}
|
||||
rocmV, _ := utils.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())
|
||||
}
|
||||
if rocmV != nil && rocmV.GreaterThan(min) {
|
||||
logger.Warnf("Warning: detected ROCm version %s great than maximum tested version %s")
|
||||
return nil
|
||||
}
|
||||
if rocmV != nil && rocmV.Equal(min) {
|
||||
logger.Infof("detected ROCm version %s, skip rocm install...", min.Original())
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensure python3-setuptools and python3-wheel
|
||||
_, _ = runtime.GetRunner().SudoCmd("apt-get update", false, true)
|
||||
checkPkgs := "dpkg -s python3-setuptools python3-wheel >/dev/null 2>&1 || DEBIAN_FRONTEND=noninteractive apt-get install -y python3-setuptools python3-wheel"
|
||||
if _, err := runtime.GetRunner().SudoCmd(checkPkgs, false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install python3-setuptools and python3-wheel")
|
||||
}
|
||||
// ensure amdgpu-install exists
|
||||
if _, err := exec.LookPath("amdgpu-install"); err != nil {
|
||||
var debURL string
|
||||
if si.IsUbuntuVersionEqual(connector.Ubuntu2404) {
|
||||
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/noble/amdgpu-install_7.1.1.70101-1_all.deb"
|
||||
} else {
|
||||
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/jammy/amdgpu-install_7.1.1.70101-1_all.deb"
|
||||
}
|
||||
tmpDeb := path.Join(runtime.GetBaseDir(), cc.PackageCacheDir, "gpu", "amdgpu-install_7.1.1.70101-1_all.deb")
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("install -d -m 0755 %s", filepath.Dir(tmpDeb)), false, true); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := fmt.Sprintf("sh -c 'wget -O %s %s'", tmpDeb, debURL)
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to download amdgpu-install deb")
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y %s", tmpDeb), false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install amdgpu-install deb")
|
||||
}
|
||||
}
|
||||
// run installer for rocm usecase
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
|
||||
}
|
||||
fmt.Println()
|
||||
logger.Warn("Warning: To enable ROCm, please reboot your machine after installation.")
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmdgpuInstallAction struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *AmdgpuInstallAction) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmdgpuUninstallAction struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *AmdgpuUninstallAction) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install --uninstall -y", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to uninstall AMD ROCm via amdgpu-install")
|
||||
}
|
||||
fmt.Println()
|
||||
logger.Warn("Warning: Please reboot your machine after uninstall to fully remove ROCm components.")
|
||||
return nil
|
||||
}
|
||||
@@ -81,6 +81,7 @@ func (m *RunPrechecksModule) Init() {
|
||||
new(NvidiaCardArchChecker),
|
||||
new(NouveauChecker),
|
||||
new(CudaChecker),
|
||||
new(RocmChecker),
|
||||
}
|
||||
runPreChecks := &task.LocalTask{
|
||||
Name: "RunPrechecks",
|
||||
|
||||
@@ -372,6 +372,48 @@ func (c *CudaChecker) Check(runtime connector.Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RocmChecker checks AMD ROCm version for AMD GPU on Ubuntu 22.04/24.04 only.
|
||||
type RocmChecker struct{}
|
||||
|
||||
func (r *RocmChecker) Name() string {
|
||||
return "ROCm"
|
||||
}
|
||||
|
||||
func (r *RocmChecker) Check(runtime connector.Runtime) error {
|
||||
if !runtime.GetSystemInfo().IsLinux() {
|
||||
return nil
|
||||
}
|
||||
si := runtime.GetSystemInfo()
|
||||
if !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// detect AMD GPU presence
|
||||
amdGPUExists, err := utils.HasAmdIGPU(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// no AMD GPU found, no need to check rocm
|
||||
if !amdGPUExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
curV, err := utils.RocmVersion()
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
min := semver.MustParse("7.1.1")
|
||||
if curV.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", curV.Original(), min.Original())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// precheck - task
|
||||
|
||||
|
||||
@@ -287,7 +287,7 @@ func (a *Argument) LoadReleaseInfo() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *Argument) SaveReleaseInfo() error {
|
||||
func (a *Argument) SaveReleaseInfo(withoutName bool) error {
|
||||
if a.BaseDir == "" {
|
||||
return errors.New("invalid: empty base directory")
|
||||
}
|
||||
@@ -300,15 +300,17 @@ func (a *Argument) SaveReleaseInfo() error {
|
||||
ENV_OLARES_VERSION: a.OlaresVersion,
|
||||
}
|
||||
|
||||
if a.User != nil && a.User.UserName != "" && a.User.DomainName != "" {
|
||||
releaseInfoMap["OLARES_NAME"] = fmt.Sprintf("%s@%s", a.User.UserName, a.User.DomainName)
|
||||
} else {
|
||||
if util.IsExist(OlaresReleaseFile) {
|
||||
// if the user is not set, try to load the user name from the release file
|
||||
envs, err := godotenv.Read(OlaresReleaseFile)
|
||||
if err == nil {
|
||||
if userName, ok := envs["OLARES_NAME"]; ok {
|
||||
releaseInfoMap["OLARES_NAME"] = userName
|
||||
if !withoutName {
|
||||
if a.User != nil && a.User.UserName != "" && a.User.DomainName != "" {
|
||||
releaseInfoMap["OLARES_NAME"] = fmt.Sprintf("%s@%s", a.User.UserName, a.User.DomainName)
|
||||
} else {
|
||||
if util.IsExist(OlaresReleaseFile) {
|
||||
// if the user is not set, try to load the user name from the release file
|
||||
envs, err := godotenv.Read(OlaresReleaseFile)
|
||||
if err == nil {
|
||||
if userName, ok := envs["OLARES_NAME"]; ok {
|
||||
releaseInfoMap["OLARES_NAME"] = userName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,10 +51,12 @@ func (d DebianVersion) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
Ubuntu20 UbuntuVersion = "20."
|
||||
Ubuntu22 UbuntuVersion = "22."
|
||||
Ubuntu24 UbuntuVersion = "24."
|
||||
Ubuntu25 UbuntuVersion = "25."
|
||||
Ubuntu20 UbuntuVersion = "20."
|
||||
Ubuntu22 UbuntuVersion = "22."
|
||||
Ubuntu24 UbuntuVersion = "24."
|
||||
Ubuntu25 UbuntuVersion = "25."
|
||||
Ubuntu2204 UbuntuVersion = "22.04"
|
||||
Ubuntu2404 UbuntuVersion = "24.04"
|
||||
|
||||
Debian9 DebianVersion = "9"
|
||||
Debian10 DebianVersion = "10"
|
||||
|
||||
@@ -86,6 +86,14 @@ func IsDir(path string) bool {
|
||||
return s.IsDir()
|
||||
}
|
||||
|
||||
func IsExecutable(path string) bool {
|
||||
info, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return info.Mode().Perm()&0111 != 0
|
||||
}
|
||||
|
||||
func CountDirFiles(dirName string) int {
|
||||
if !IsDir(dirName) {
|
||||
return 0
|
||||
|
||||
@@ -187,7 +187,7 @@ func (m *InstallPluginModule) Init() {
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
new(common.OnlyFirstMaster),
|
||||
},
|
||||
Action: new(UpdateNodeLabels),
|
||||
Action: new(UpdateNodeGPUInfo),
|
||||
Parallel: false,
|
||||
Retry: 1,
|
||||
}
|
||||
@@ -223,23 +223,6 @@ func (m *InstallPluginModule) Init() {
|
||||
}
|
||||
}
|
||||
|
||||
type GetCudaVersionModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (g *GetCudaVersionModule) Init() {
|
||||
g.Name = "GetCudaVersion"
|
||||
|
||||
getCudaVersion := &task.LocalTask{
|
||||
Name: "GetCudaVersion",
|
||||
Action: new(GetCudaVersion),
|
||||
}
|
||||
|
||||
g.Tasks = []task.Interface{
|
||||
getCudaVersion,
|
||||
}
|
||||
}
|
||||
|
||||
type NodeLabelingModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
@@ -253,7 +236,7 @@ func (l *NodeLabelingModule) Init() {
|
||||
new(CudaInstalled),
|
||||
new(CurrentNodeInK8s),
|
||||
},
|
||||
Action: new(UpdateNodeLabels),
|
||||
Action: new(UpdateNodeGPUInfo),
|
||||
Retry: 1,
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apputils "github.com/beclab/Olares/framework/app-service/pkg/utils"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/clientset"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
@@ -26,7 +29,11 @@ import (
|
||||
"github.com/pelletier/go-toml"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kruntime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/util/retry"
|
||||
)
|
||||
@@ -256,6 +263,10 @@ func (t *PatchK3sDriver) Execute(runtime connector.Runtime) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("apt install -y strace", false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd(dstName, false, false); err != nil {
|
||||
return errors.Wrap(err, "failed to apply CUDA patch for WSL")
|
||||
}
|
||||
@@ -323,59 +334,11 @@ func (t *CheckGpuStatus) Execute(runtime connector.Runtime) error {
|
||||
return fmt.Errorf("GPU Container State is Pending")
|
||||
}
|
||||
|
||||
type GetCudaVersion struct {
|
||||
type UpdateNodeGPUInfo struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (g *GetCudaVersion) Execute(runtime connector.Runtime) error {
|
||||
var nvidiaSmiFile string
|
||||
var systemInfo = runtime.GetSystemInfo()
|
||||
|
||||
switch {
|
||||
case systemInfo.IsWsl():
|
||||
nvidiaSmiFile = "/usr/lib/wsl/lib/nvidia-smi"
|
||||
default:
|
||||
nvidiaSmiFile = "/usr/bin/nvidia-smi"
|
||||
}
|
||||
|
||||
if !util.IsExist(nvidiaSmiFile) {
|
||||
logger.Info("nvidia-smi not exists")
|
||||
return nil
|
||||
}
|
||||
|
||||
var cudaVersion string
|
||||
res, err := runtime.GetRunner().Cmd(fmt.Sprintf("%s --version", nvidiaSmiFile), false, true)
|
||||
if err != nil {
|
||||
logger.Errorf("get cuda version error %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
lines := strings.Split(res, "\n")
|
||||
|
||||
if len(lines) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "CUDA Version") {
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) != 2 {
|
||||
break
|
||||
}
|
||||
cudaVersion = strings.TrimSpace(parts[1])
|
||||
}
|
||||
}
|
||||
if cudaVersion != "" {
|
||||
common.SetSystemEnv("OLARES_SYSTEM_CUDA_VERSION", cudaVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateNodeLabels struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (u *UpdateNodeLabels) Execute(runtime connector.Runtime) error {
|
||||
func (u *UpdateNodeGPUInfo) Execute(runtime connector.Runtime) error {
|
||||
client, err := clientset.NewKubeClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "kubeclient create error")
|
||||
@@ -482,6 +445,85 @@ func UpdateNodeGpuLabel(ctx context.Context, client kubernetes.Interface, driver
|
||||
}
|
||||
}
|
||||
|
||||
if cuda != nil && *cuda != "" {
|
||||
if err := updateCudaVersionSystemEnv(ctx, *cuda); err != nil {
|
||||
logger.Errorf("failed to update SystemEnv for CUDA version: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateCudaVersionSystemEnv(ctx context.Context, cudaVersion string) error {
|
||||
envName := "OLARES_SYSTEM_CUDA_VERSION"
|
||||
common.SetSystemEnv(envName, cudaVersion)
|
||||
config, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get rest config: %w", err)
|
||||
}
|
||||
|
||||
apix, err := apixclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create crd client: %w", err)
|
||||
}
|
||||
|
||||
_, err = apix.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, "systemenvs.sys.bytetrade.io", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
logger.Debugf("SystemEnv CRD not found, skipping CUDA version update")
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to get SystemEnv CRD: %w", err)
|
||||
}
|
||||
|
||||
scheme := kruntime.NewScheme()
|
||||
if err := v1alpha1.AddToScheme(scheme); err != nil {
|
||||
return fmt.Errorf("failed to add systemenv scheme: %w", err)
|
||||
}
|
||||
|
||||
c, err := ctrlclient.New(config, ctrlclient.Options{Scheme: scheme})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create client: %w", err)
|
||||
}
|
||||
|
||||
resourceName, err := apputils.EnvNameToResourceName(envName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid system env name: %s", envName)
|
||||
}
|
||||
|
||||
var existingSystemEnv v1alpha1.SystemEnv
|
||||
err = c.Get(ctx, types.NamespacedName{Name: resourceName}, &existingSystemEnv)
|
||||
if err == nil {
|
||||
if existingSystemEnv.Default != cudaVersion {
|
||||
existingSystemEnv.Default = cudaVersion
|
||||
if err := c.Update(ctx, &existingSystemEnv); err != nil {
|
||||
return fmt.Errorf("failed to update SystemEnv %s: %w", resourceName, err)
|
||||
}
|
||||
logger.Infof("Updated SystemEnv %s default to %s", resourceName, cudaVersion)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to get SystemEnv %s: %w", resourceName, err)
|
||||
}
|
||||
|
||||
systemEnv := &v1alpha1.SystemEnv{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: resourceName,
|
||||
},
|
||||
EnvVarSpec: v1alpha1.EnvVarSpec{
|
||||
EnvName: envName,
|
||||
Default: cudaVersion,
|
||||
},
|
||||
}
|
||||
|
||||
if err := c.Create(ctx, systemEnv); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("failed to create SystemEnv %s: %w", resourceName, err)
|
||||
}
|
||||
|
||||
logger.Infof("Created SystemEnv: %s with default %s", envName, cudaVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,17 +10,39 @@ var (
|
||||
K3sCudaFixValues = template.Must(template.New("cuda_lib_fix.sh").Parse(
|
||||
dedent.Dedent(`#!/bin/bash
|
||||
sh_c="sh -c"
|
||||
real_driver=$($sh_c "find /usr/lib/wsl/drivers/ -name libcuda.so.1.1|head -1")
|
||||
real_driver=""
|
||||
real_nvml=""
|
||||
|
||||
# Try to find the real driver path via strace
|
||||
real_driver_path=$($sh_c "strace -qq -e trace=openat /usr/lib/wsl/lib/nvidia-smi 2>&1|grep '/usr/lib/wsl/drivers'|grep libnvidia-ml.so.1|awk '{print \$2}'|sed 's/[\",]//g'|sed 's/libnvidia-ml.so.1//g'")
|
||||
if [[ x"$real_driver_path" != x"" ]]; then
|
||||
real_driver="${real_driver_path}libcuda.so.1.1"
|
||||
real_nvml="${real_driver_path}libnvidia-ml.so.1"
|
||||
else
|
||||
driver_path=$($sh_c "strace -qq -e trace=openat /usr/lib/wsl/lib/nvidia-smi 2>&1|grep '/usr/lib/wsl/'|grep libnvidia-ml.so.1")
|
||||
if [[ x"$driver_path" != x"" ]]; then
|
||||
echo "already fixed cuda libs, exit now."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ x"$real_driver" == x"" ]]; then
|
||||
real_driver=$($sh_c "find /usr/lib/wsl/drivers/ -name libcuda.so.1.1|head -1")
|
||||
real_nvml=$($sh_c "find /usr/lib/wsl/drivers/ -name libnvidia-ml.so.1|head -1")
|
||||
fi
|
||||
|
||||
if [[ x"$real_driver" != x"" ]]; then
|
||||
$sh_c "ln -s /usr/lib/wsl/lib/libcuda* /usr/lib/x86_64-linux-gnu/"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1.1"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1"
|
||||
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so"
|
||||
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1"
|
||||
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1.1"
|
||||
$sh_c "ln -s $real_driver /usr/lib/x86_64-linux-gnu/libcuda.so.1"
|
||||
$sh_c "ln -s $real_driver /usr/lib/x86_64-linux-gnu/libcuda.so.1.1"
|
||||
$sh_c "cp -f $real_nvml /usr/lib/wsl/lib/libnvidia-ml.so.1"
|
||||
$sh_c "cp -f $real_driver /usr/lib/x86_64-linux-gnu/"
|
||||
$sh_c "cp -f $real_nvml /usr/lib/x86_64-linux-gnu/"
|
||||
$sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1.1 /usr/lib/x86_64-linux-gnu/libcuda.so.1"
|
||||
$sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so"
|
||||
fi`),
|
||||
))
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/k3s/templates"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/registry"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
)
|
||||
|
||||
type InstallContainerModule struct {
|
||||
@@ -470,6 +471,18 @@ func (j *JoinNodesModule) Init() {
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
createSharedLibDirForWorker := &task.RemoteTask{
|
||||
Name: "CreateSharedLibDir(k3s)",
|
||||
Desc: "Create shared lib directory on worker",
|
||||
Hosts: j.Runtime.GetHostsByRole(common.Worker),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
&kubernetes.NodeInCluster{Not: true},
|
||||
new(common.OnlyWorker),
|
||||
},
|
||||
Action: new(storage.CreateSharedLibDir),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
enableK3s := &task.RemoteTask{
|
||||
Name: "EnableK3sService",
|
||||
Desc: "Enable k3s service",
|
||||
@@ -536,6 +549,7 @@ func (j *JoinNodesModule) Init() {
|
||||
k3sService,
|
||||
k3sEnv,
|
||||
k3sRegistryConfig,
|
||||
createSharedLibDirForWorker,
|
||||
enableK3s,
|
||||
copyKubeConfigForMaster,
|
||||
syncKubeConfigToWorker,
|
||||
|
||||
@@ -195,13 +195,13 @@ func (g *GenerateK3sService) Execute(runtime connector.Runtime) error {
|
||||
defaultKubeletArs := map[string]string{
|
||||
"kube-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
|
||||
"system-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
|
||||
"eviction-hard": "memory.available<5%,nodefs.available<10%,imagefs.available<10%",
|
||||
"eviction-hard": "memory.available<5%,nodefs.available<5%,imagefs.available<5%",
|
||||
"config": "/etc/rancher/k3s/kubelet.config",
|
||||
"containerd": container.DefaultContainerdCRISocket,
|
||||
"cgroup-driver": "systemd",
|
||||
"runtime-request-timeout": "5m",
|
||||
"image-gc-high-threshold": "91",
|
||||
"image-gc-low-threshold": "90",
|
||||
"image-gc-high-threshold": "96",
|
||||
"image-gc-low-threshold": "95",
|
||||
"housekeeping_interval": "5s",
|
||||
}
|
||||
defaultKubeProxyArgs := map[string]string{
|
||||
@@ -397,53 +397,23 @@ type CopyK3sKubeConfig struct {
|
||||
}
|
||||
|
||||
func (c *CopyK3sKubeConfig) Execute(runtime connector.Runtime) error {
|
||||
createConfigDirCmd := "mkdir -p /root/.kube && mkdir -p $HOME/.kube"
|
||||
getKubeConfigCmd := "cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config"
|
||||
chmodKubeConfigCmd := "chmod 0600 /root/.kube/config"
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd, chmodKubeConfigCmd}, " && ")
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil {
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
"cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config",
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("cp -f /etc/rancher/k3s/k3s.yaml %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "copy k3s kube config failed")
|
||||
}
|
||||
|
||||
userMkdir := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
userCopyKubeConfig := "cp -f /etc/rancher/k3s/k3s.yaml $HOME/.kube/config"
|
||||
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user copy /etc/rancher/k3s/k3s.yaml to $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config 0600 failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
}
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -493,59 +463,29 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
|
||||
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
|
||||
cluster := v.(*K3sStatus)
|
||||
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
|
||||
}
|
||||
|
||||
oldServer := "server: https://127.0.0.1:6443"
|
||||
newServer := fmt.Sprintf("server: https://%s:%d",
|
||||
s.KubeConf.Cluster.ControlPlaneEndpoint.Domain,
|
||||
s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfig := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1)
|
||||
|
||||
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config")
|
||||
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
userConfigDirCmd := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "$HOME/.kube/config")
|
||||
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
return err
|
||||
}
|
||||
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config"),
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("echo '%s' > %s", newKubeConfig, targetKubeConfigPath),
|
||||
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/prepare"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
)
|
||||
|
||||
type StatusModule struct {
|
||||
@@ -243,6 +244,18 @@ func (j *JoinNodesModule) Init() {
|
||||
Retry: 5,
|
||||
}
|
||||
|
||||
createSharedLibDirForWorker := &task.RemoteTask{
|
||||
Name: "CreateSharedLibDir(k8s)",
|
||||
Desc: "Create shared lib directory on worker",
|
||||
Hosts: j.Runtime.GetHostsByRole(common.Worker),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
&NodeInCluster{Not: true},
|
||||
new(common.OnlyWorker),
|
||||
},
|
||||
Action: new(storage.CreateSharedLibDir),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
joinWorkerNode := &task.RemoteTask{
|
||||
Name: "JoinWorkerNode(k8s)",
|
||||
Desc: "Join worker node",
|
||||
@@ -323,6 +336,7 @@ func (j *JoinNodesModule) Init() {
|
||||
j.Tasks = []task.Interface{
|
||||
generateKubeadmConfig,
|
||||
joinMasterNode,
|
||||
createSharedLibDirForWorker,
|
||||
joinWorkerNode,
|
||||
copyKubeConfig,
|
||||
removeMasterTaint,
|
||||
|
||||
@@ -417,51 +417,23 @@ type CopyKubeConfigForControlPlane struct {
|
||||
}
|
||||
|
||||
func (c *CopyKubeConfigForControlPlane) Execute(runtime connector.Runtime) error {
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
getKubeConfigCmd := "cp -f /etc/kubernetes/admin.conf /root/.kube/config"
|
||||
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd}, " && ")
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil {
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
"cp -f /etc/kubernetes/admin.conf /root/.kube/config",
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("cp -f /etc/kubernetes/admin.conf %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "copy kube config failed")
|
||||
}
|
||||
|
||||
userMkdir := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
userCopyKubeConfig := "cp -f /etc/kubernetes/admin.conf $HOME/.kube/config"
|
||||
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user copy /etc/kubernetes/admin.conf to $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
}
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -521,53 +493,23 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
|
||||
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
|
||||
cluster := v.(*KubernetesStatus)
|
||||
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config")
|
||||
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
userConfigDirCmd := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "$HOME/.kube/config")
|
||||
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
return err
|
||||
}
|
||||
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config"),
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, targetKubeConfigPath),
|
||||
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -296,8 +296,10 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
|
||||
"memory": "250Mi",
|
||||
},
|
||||
"evictionHard": map[string]string{
|
||||
"memory.available": "5%",
|
||||
"pid.available": "10%",
|
||||
"memory.available": "5%",
|
||||
"pid.available": "10%",
|
||||
"nodefs.available": "5%",
|
||||
"imagefs.available": "5%",
|
||||
},
|
||||
"evictionSoft": map[string]string{
|
||||
"memory.available": "10%",
|
||||
@@ -309,8 +311,8 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
|
||||
"evictionPressureTransitionPeriod": "30s",
|
||||
"featureGates": FeatureGatesDefaultConfiguration,
|
||||
"runtimeRequestTimeout": "5m",
|
||||
"imageGCHighThresholdPercent": 91,
|
||||
"imageGCLowThresholdPercent": 90,
|
||||
"imageGCHighThresholdPercent": 96,
|
||||
"imageGCLowThresholdPercent": 95,
|
||||
}
|
||||
|
||||
if securityEnhancement {
|
||||
|
||||
@@ -111,6 +111,7 @@ func (p *phaseBuilder) phaseInstall() *phaseBuilder {
|
||||
PhaseFile: common.TerminusStateFileInstalled,
|
||||
BaseDir: p.runtime.GetBaseDir(),
|
||||
},
|
||||
&terminus.WriteReleaseFileModule{WithoutName: true},
|
||||
)
|
||||
}
|
||||
return p
|
||||
|
||||
@@ -58,7 +58,6 @@ func (l *linuxInstallPhaseBuilder) installGpuPlugin() phase {
|
||||
return []module.Module{
|
||||
&gpu.RestartK3sServiceModule{Skip: !(l.runtime.Arg.Kubetype == common.K3s)},
|
||||
&gpu.InstallPluginModule{Skip: skipGpuPlugin},
|
||||
&gpu.GetCudaVersionModule{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ package system
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/amdgpu"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/os"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/patch"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/container"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/daemon"
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
"github.com/beclab/Olares/cli/pkg/images"
|
||||
"github.com/beclab/Olares/cli/pkg/k3s"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
@@ -82,6 +82,7 @@ func (l *linuxPhaseBuilder) build() []module.Module {
|
||||
addModule(&terminus.WriteReleaseFileModule{}).
|
||||
addModule(gpuModuleBuilder(func() []module.Module {
|
||||
return []module.Module{
|
||||
&amdgpu.InstallAmdRocmModule{},
|
||||
&gpu.InstallDriversModule{
|
||||
ManifestModule: manifest.ManifestModule{
|
||||
Manifest: l.manifestMap,
|
||||
|
||||
101
cli/pkg/pipelines/amdgpu.go
Normal file
101
cli/pkg/pipelines/amdgpu.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package pipelines
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/amdgpu"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/action"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type singleTaskModule struct {
|
||||
common.KubeModule
|
||||
name string
|
||||
act action.Action
|
||||
}
|
||||
|
||||
func (m *singleTaskModule) Init() {
|
||||
m.Name = m.name
|
||||
m.Tasks = []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: m.name,
|
||||
Action: m.act,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AmdGpuInstall() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("amdgpuinstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &pipeline.Pipeline{
|
||||
Name: "InstallAMDGPUDrivers",
|
||||
Runtime: runtime,
|
||||
Modules: []module.Module{
|
||||
&amdgpu.InstallAmdRocmModule{},
|
||||
},
|
||||
}
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func AmdGpuUninstall() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("amdgpuuninstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &pipeline.Pipeline{
|
||||
Name: "UninstallAMDGPUDrivers",
|
||||
Runtime: runtime,
|
||||
Modules: []module.Module{
|
||||
&singleTaskModule{name: "AmdgpuUninstall", act: new(amdgpu.AmdgpuUninstallAction)},
|
||||
},
|
||||
}
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func AmdGpuStatus() error {
|
||||
arg := common.NewArgument()
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.SetRunner(
|
||||
&connector.Runner{
|
||||
Host: &connector.BaseHost{
|
||||
Name: common.LocalHost,
|
||||
Arch: runtime.GetSystemInfo().GetOsArch(),
|
||||
Os: runtime.GetSystemInfo().GetOsType(),
|
||||
},
|
||||
},
|
||||
)
|
||||
amdModel, _ := runtime.GetRunner().SudoCmd("lspci | grep -iE 'VGA|3D|Display' | grep -iE 'AMD|ATI' | head -1 || true", false, false)
|
||||
drvVer, _ := runtime.GetRunner().SudoCmd("modinfo amdgpu 2>/dev/null | awk -F': ' '/^version:/{print $2}' || true", false, false)
|
||||
rocmVer, _ := runtime.GetRunner().SudoCmd("cat /opt/rocm/.info/version 2>/dev/null || true", false, false)
|
||||
|
||||
if strings.TrimSpace(amdModel) != "" {
|
||||
logger.Infof("AMD GPU: %s", strings.TrimSpace(amdModel))
|
||||
} else {
|
||||
logger.Info("AMD GPU: not detected")
|
||||
}
|
||||
if strings.TrimSpace(drvVer) != "" {
|
||||
logger.Infof("AMDGPU driver %s", strings.TrimSpace(drvVer))
|
||||
} else {
|
||||
logger.Info("AMDGPU driver version: unknown")
|
||||
}
|
||||
if strings.TrimSpace(rocmVer) != "" {
|
||||
logger.Infof("ROCm version: %s", strings.TrimSpace(rocmVer))
|
||||
} else {
|
||||
logger.Info("ROCm version: not installed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -396,3 +396,17 @@ func (t *DeleteTerminusData) Execute(runtime connector.Runtime) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateSharedLibDir struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *CreateSharedLibDir) Execute(runtime connector.Runtime) error {
|
||||
if runtime.GetSystemInfo().IsDarwin() {
|
||||
return nil
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", OlaresSharedLibDir, OlaresSharedLibDir), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ func (m *PreparedModule) Init() {
|
||||
|
||||
type WriteReleaseFileModule struct {
|
||||
common.KubeModule
|
||||
WithoutName bool
|
||||
}
|
||||
|
||||
func (m *WriteReleaseFileModule) Init() {
|
||||
@@ -82,7 +83,7 @@ func (m *WriteReleaseFileModule) Init() {
|
||||
m.Tasks = []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: "WriteReleaseFile",
|
||||
Action: new(WriteReleaseFile),
|
||||
Action: &WriteReleaseFile{WithoutName: m.WithoutName},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apputils "bytetrade.io/web3os/app-service/pkg/utils"
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apputils "github.com/beclab/Olares/framework/app-service/pkg/utils"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
@@ -38,12 +38,6 @@ type InstallOsSystem struct {
|
||||
}
|
||||
|
||||
func (t *InstallOsSystem) Execute(runtime connector.Runtime) error {
|
||||
if !runtime.GetSystemInfo().IsDarwin() {
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", storage.OlaresSharedLibDir, storage.OlaresSharedLibDir), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
|
||||
}
|
||||
}
|
||||
|
||||
config, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -367,6 +361,11 @@ func (m *InstallOsSystemModule) Init() {
|
||||
Action: &CreateUserEnvConfigMap{},
|
||||
}
|
||||
|
||||
createSharedLibDir := &task.LocalTask{
|
||||
Name: "CreateSharedLibDir",
|
||||
Action: &storage.CreateSharedLibDir{},
|
||||
}
|
||||
|
||||
installOsSystem := &task.LocalTask{
|
||||
Name: "InstallOsSystem",
|
||||
Action: &InstallOsSystem{},
|
||||
@@ -399,6 +398,7 @@ func (m *InstallOsSystemModule) Init() {
|
||||
m.Tasks = []task.Interface{
|
||||
applySystemEnv,
|
||||
createUserEnvConfigMap,
|
||||
createSharedLibDir,
|
||||
installOsSystem,
|
||||
createBackupConfigMap,
|
||||
checkSystemService,
|
||||
|
||||
@@ -97,25 +97,8 @@ func (t *CheckKeyPodsRunning) Execute(runtime connector.Runtime) error {
|
||||
if !strings.HasPrefix(pod.Namespace, "user-") && !strings.HasPrefix(pod.Namespace, "os-") {
|
||||
continue
|
||||
}
|
||||
if pod.Status.Phase != corev1.PodRunning {
|
||||
return fmt.Errorf("pod %s/%s is not running", pod.Namespace, pod.Name)
|
||||
}
|
||||
if len(pod.Status.ContainerStatuses) != len(pod.Spec.Containers) {
|
||||
return fmt.Errorf("pod %s/%s has not started all containers yet", pod.Namespace, pod.Name)
|
||||
}
|
||||
for _, cStatus := range pod.Status.ContainerStatuses {
|
||||
if cStatus.State.Terminated != nil {
|
||||
if cStatus.State.Terminated.ExitCode != 0 {
|
||||
return fmt.Errorf("container %s in pod %s/%s is terminated", cStatus.Name, pod.Namespace, pod.Name)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if cStatus.State.Running == nil {
|
||||
return fmt.Errorf("container %s in pod %s/%s is not running", cStatus.Name, pod.Namespace, pod.Name)
|
||||
}
|
||||
if !cStatus.Ready {
|
||||
return fmt.Errorf("container %s in pod %s/%s is not ready", cStatus.Name, pod.Namespace, pod.Name)
|
||||
}
|
||||
if err := utils.AssertPodReady(&pod); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -126,29 +109,39 @@ type CheckPodsRunning struct {
|
||||
labels map[string][]string
|
||||
}
|
||||
|
||||
func (c *CheckPodsRunning) Execute(runtime connector.Runtime) error {
|
||||
func (c *CheckPodsRunning) Execute(_ connector.Runtime) error {
|
||||
if c.labels == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
kubectl, err := util.GetCommand(common.CommandKubectl)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "kubectl not found")
|
||||
}
|
||||
|
||||
var ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
kubeConfig, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to load kubeconfig")
|
||||
}
|
||||
kubeClient, err := kubernetes.NewForConfig(kubeConfig)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create kube client")
|
||||
}
|
||||
|
||||
for ns, labels := range c.labels {
|
||||
for _, label := range labels {
|
||||
var cmd = fmt.Sprintf("%s get pod -n %s -l '%s' -o jsonpath='{.items[*].status.phase}'", kubectl, ns, label)
|
||||
phase, err := runtime.GetRunner().SudoCmdContext(ctx, cmd, false, false)
|
||||
podList, err := kubeClient.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{LabelSelector: label})
|
||||
if err != nil {
|
||||
return fmt.Errorf("pod status invalid, namespace: %s, label: %s, waiting ...", ns, label)
|
||||
}
|
||||
|
||||
if phase != "Running" {
|
||||
logger.Infof("pod in namespace: %s, label: %s, current phase: %s, waiting ...", ns, label, phase)
|
||||
return fmt.Errorf("pod is %s, namespace: %s, label: %s, waiting ...", phase, ns, label)
|
||||
if podList == nil || len(podList.Items) == 0 {
|
||||
return fmt.Errorf("no pod found, namespace: %s, label: %s, waiting ...", ns, label)
|
||||
}
|
||||
|
||||
for i := range podList.Items {
|
||||
pod := &podList.Items[i]
|
||||
if err := utils.AssertPodReady(pod); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,13 +243,14 @@ func (t *PrepareFinished) Execute(runtime connector.Runtime) error {
|
||||
|
||||
type WriteReleaseFile struct {
|
||||
common.KubeAction
|
||||
WithoutName bool
|
||||
}
|
||||
|
||||
func (t *WriteReleaseFile) Execute(runtime connector.Runtime) error {
|
||||
if util.IsExist(common.OlaresReleaseFile) {
|
||||
logger.Debugf("found existing release file: %s, overriding ...", common.OlaresReleaseFile)
|
||||
}
|
||||
return t.KubeConf.Arg.SaveReleaseInfo()
|
||||
return t.KubeConf.Arg.SaveReleaseInfo(t.WithoutName)
|
||||
}
|
||||
|
||||
type RemoveReleaseFile struct {
|
||||
|
||||
@@ -9,6 +9,7 @@ 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 {
|
||||
@@ -68,6 +69,15 @@ func (t *WelcomeMessage) Execute(runtime connector.Runtime) error {
|
||||
logger.Infof("Username: %s", t.KubeConf.Arg.User.UserName)
|
||||
logger.Infof("Password: %s", t.KubeConf.Arg.User.Password)
|
||||
fmt.Printf("\n------------------------------------------------\n\n\n\n\n")
|
||||
fmt.Println()
|
||||
|
||||
// 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 {
|
||||
logger.Warnf("\x1b[31mWarning: To enable ROCm, please reboot your machine after activation.\x1b[0m")
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1alpha1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/pkg/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"
|
||||
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1alpha1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/pkg/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"
|
||||
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
@@ -8,36 +8,36 @@ import (
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
)
|
||||
|
||||
var version_1_12_3 = semver.MustParse("1.12.3")
|
||||
var version_1_12_4 = semver.MustParse("1.12.4")
|
||||
|
||||
type upgrader_1_12_3 struct {
|
||||
type upgrader_1_12_4 struct {
|
||||
breakingUpgraderBase
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_3) Version() *semver.Version {
|
||||
func (u upgrader_1_12_4) Version() *semver.Version {
|
||||
cliVersion, err := semver.NewVersion(version.VERSION)
|
||||
// tolerate local dev version
|
||||
if err != nil {
|
||||
return version_1_12_3
|
||||
return version_1_12_4
|
||||
}
|
||||
if samePatchLevelVersion(version_1_12_3, cliVersion) && getReleaseLineOfVersion(cliVersion) == mainLine {
|
||||
if samePatchLevelVersion(version_1_12_4, cliVersion) && getReleaseLineOfVersion(cliVersion) == mainLine {
|
||||
return cliVersion
|
||||
}
|
||||
return version_1_12_3
|
||||
return version_1_12_4
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_3) AddedBreakingChange() bool {
|
||||
if u.Version().Equal(version_1_12_3) {
|
||||
func (u upgrader_1_12_4) AddedBreakingChange() bool {
|
||||
if u.Version().Equal(version_1_12_4) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_3) NeedRestart() bool {
|
||||
func (u upgrader_1_12_4) NeedRestart() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_3) PrepareForUpgrade() []task.Interface {
|
||||
func (u upgrader_1_12_4) PrepareForUpgrade() []task.Interface {
|
||||
tasks := make([]task.Interface, 0)
|
||||
|
||||
tasks = append(tasks, upgradeKsConfig()...)
|
||||
@@ -57,7 +57,7 @@ func (u upgrader_1_12_3) PrepareForUpgrade() []task.Interface {
|
||||
return tasks
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_3) UpgradeSystemComponents() []task.Interface {
|
||||
func (u upgrader_1_12_4) UpgradeSystemComponents() []task.Interface {
|
||||
pre := []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: "UpgradeL4BFLProxy",
|
||||
@@ -69,7 +69,7 @@ func (u upgrader_1_12_3) UpgradeSystemComponents() []task.Interface {
|
||||
return append(pre, u.upgraderBase.UpgradeSystemComponents()...)
|
||||
}
|
||||
|
||||
func (u upgrader_1_12_3) UpdateOlaresVersion() []task.Interface {
|
||||
func (u upgrader_1_12_4) UpdateOlaresVersion() []task.Interface {
|
||||
var tasks []task.Interface
|
||||
tasks = append(tasks,
|
||||
&task.LocalTask{
|
||||
@@ -88,5 +88,5 @@ func (u upgrader_1_12_3) UpdateOlaresVersion() []task.Interface {
|
||||
}
|
||||
|
||||
func init() {
|
||||
registerMainUpgrader(upgrader_1_12_3{})
|
||||
registerMainUpgrader(upgrader_1_12_4{})
|
||||
}
|
||||
@@ -3,7 +3,10 @@ package upgrade
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -222,6 +225,71 @@ type upgradeGPUDriverIfNeeded struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
// fixProcModprobePath fixes the /proc/sys/kernel/modprobe path issue that can cause
|
||||
// nvidia-installer to fail with error:
|
||||
// "The path to the `modprobe` utility reported by '/proc/sys/kernel/modprobe', ”, differs from
|
||||
// the path determined by `nvidia-installer`, `/bin/kmod`, and does not appear to point to a
|
||||
// valid `modprobe` binary."
|
||||
//
|
||||
// This function checks if /proc/sys/kernel/modprobe is empty or invalid, and if so,
|
||||
// writes a valid modprobe path to it.
|
||||
func fixProcModprobePath() {
|
||||
const procModprobePath = "/proc/sys/kernel/modprobe"
|
||||
|
||||
modprobePaths := []string{
|
||||
"/sbin/modprobe",
|
||||
"/usr/sbin/modprobe",
|
||||
"/bin/modprobe",
|
||||
"/usr/bin/modprobe",
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(procModprobePath)
|
||||
if err != nil {
|
||||
logger.Warnf("failed to read %s: %v", procModprobePath, err)
|
||||
}
|
||||
currentPath := strings.TrimSpace(string(data))
|
||||
|
||||
// Check if current path is valid (non-empty and executable)
|
||||
if currentPath != "" {
|
||||
if util.IsExecutable(currentPath) {
|
||||
logger.Debugf("%s already contains valid path: %s", procModprobePath, currentPath)
|
||||
return
|
||||
}
|
||||
// in case it's a symlink that resolves to a valid executable
|
||||
if resolved, err := filepath.EvalSymlinks(currentPath); err == nil && resolved != "" {
|
||||
if util.IsExecutable(resolved) {
|
||||
logger.Debugf("%s contains symlink %s -> %s which is valid", procModprobePath, currentPath, resolved)
|
||||
return
|
||||
}
|
||||
}
|
||||
logger.Warnf("%s contains invalid path: '%s', attempting to fix", procModprobePath, currentPath)
|
||||
} else {
|
||||
logger.Warnf("%s is empty, attempting to fix", procModprobePath)
|
||||
}
|
||||
|
||||
if lookPath, err := exec.LookPath("modprobe"); err == nil && lookPath != "" {
|
||||
modprobePaths = append([]string{lookPath}, modprobePaths...)
|
||||
}
|
||||
|
||||
for _, modprobePath := range modprobePaths {
|
||||
if !util.IsExecutable(modprobePath) {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := os.WriteFile(procModprobePath, []byte(modprobePath), 0644); err != nil {
|
||||
logger.Warnf("failed to write %s to %s: %v", modprobePath, procModprobePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Infof("successfully fixed %s: set to %s", procModprobePath, modprobePath)
|
||||
return
|
||||
}
|
||||
|
||||
// If we get here, we couldn't fix it, but we log a warning and continue
|
||||
// The nvidia-installer might still work, or it might fail, but we don't want to block the upgrade
|
||||
logger.Warnf("could not fix %s, nvidia-installer may fail; continuing anyway", procModprobePath)
|
||||
}
|
||||
|
||||
func (a *upgradeGPUDriverIfNeeded) Execute(runtime connector.Runtime) error {
|
||||
sys := runtime.GetSystemInfo()
|
||||
if sys.IsWsl() {
|
||||
@@ -296,6 +364,9 @@ func (a *upgradeGPUDriverIfNeeded) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends dkms build-essential linux-headers-$(uname -r)", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install kernel build dependencies for NVIDIA runfile")
|
||||
}
|
||||
|
||||
fixProcModprobePath()
|
||||
|
||||
// install runfile
|
||||
runfile := item.FilePath(runtime.GetBaseDir())
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("chmod +x %s", runfile), false, true); err != nil {
|
||||
|
||||
67
cli/pkg/utils/amdgpu.go
Normal file
67
cli/pkg/utils/amdgpu.go
Normal file
@@ -0,0 +1,67 @@
|
||||
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
|
||||
}
|
||||
111
cli/pkg/utils/pod.go
Normal file
111
cli/pkg/utils/pod.go
Normal file
@@ -0,0 +1,111 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
func AssertPodReady(pod *corev1.Pod) error {
|
||||
if pod == nil {
|
||||
return fmt.Errorf("pod is nil")
|
||||
}
|
||||
|
||||
podKey := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
|
||||
if pod.DeletionTimestamp != nil {
|
||||
return fmt.Errorf("pod %s is terminating", podKey)
|
||||
}
|
||||
if pod.Status.Phase != corev1.PodRunning {
|
||||
return fmt.Errorf("pod %s is not running (phase=%s)", podKey, pod.Status.Phase)
|
||||
}
|
||||
|
||||
if len(pod.Spec.InitContainers) > 0 {
|
||||
initStatusByName := make(map[string]corev1.ContainerStatus, len(pod.Status.InitContainerStatuses))
|
||||
for i := range pod.Status.InitContainerStatuses {
|
||||
s := pod.Status.InitContainerStatuses[i]
|
||||
initStatusByName[s.Name] = s
|
||||
}
|
||||
for _, ic := range pod.Spec.InitContainers {
|
||||
s, ok := initStatusByName[ic.Name]
|
||||
if !ok {
|
||||
return fmt.Errorf("pod %s has not started init container %s yet", podKey, ic.Name)
|
||||
}
|
||||
if t := s.State.Terminated; t != nil {
|
||||
if t.ExitCode != 0 {
|
||||
return fmt.Errorf(
|
||||
"init container %s in pod %s terminated (exitCode=%d, reason=%s, message=%s)",
|
||||
s.Name, podKey, t.ExitCode, t.Reason, t.Message,
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if w := s.State.Waiting; w != nil {
|
||||
return fmt.Errorf(
|
||||
"init container %s in pod %s is waiting (reason=%s, message=%s)",
|
||||
s.Name, podKey, w.Reason, w.Message,
|
||||
)
|
||||
}
|
||||
return fmt.Errorf("pod %s init container %s is still running", podKey, s.Name)
|
||||
}
|
||||
}
|
||||
|
||||
readyCondFound := false
|
||||
for i := range pod.Status.Conditions {
|
||||
cond := pod.Status.Conditions[i]
|
||||
if cond.Type != corev1.PodReady {
|
||||
continue
|
||||
}
|
||||
readyCondFound = true
|
||||
if cond.Status != corev1.ConditionTrue {
|
||||
if cond.Reason != "" || cond.Message != "" {
|
||||
return fmt.Errorf("pod %s is not ready (reason=%s, message=%s)", podKey, cond.Reason, cond.Message)
|
||||
}
|
||||
return fmt.Errorf("pod %s is not ready", podKey)
|
||||
}
|
||||
break
|
||||
}
|
||||
if !readyCondFound {
|
||||
return fmt.Errorf("pod %s is not ready (missing Ready condition)", podKey)
|
||||
}
|
||||
|
||||
statusByName := make(map[string]corev1.ContainerStatus, len(pod.Status.ContainerStatuses))
|
||||
for i := range pod.Status.ContainerStatuses {
|
||||
s := pod.Status.ContainerStatuses[i]
|
||||
statusByName[s.Name] = s
|
||||
}
|
||||
|
||||
for _, c := range pod.Spec.Containers {
|
||||
cStatus, ok := statusByName[c.Name]
|
||||
if !ok {
|
||||
return fmt.Errorf("pod %s has not started container %s yet", podKey, c.Name)
|
||||
}
|
||||
|
||||
if t := cStatus.State.Terminated; t != nil {
|
||||
return fmt.Errorf(
|
||||
"container %s in pod %s terminated (exitCode=%d, reason=%s, message=%s)",
|
||||
cStatus.Name,
|
||||
podKey,
|
||||
t.ExitCode,
|
||||
t.Reason,
|
||||
t.Message,
|
||||
)
|
||||
}
|
||||
|
||||
if cStatus.State.Running == nil {
|
||||
if w := cStatus.State.Waiting; w != nil {
|
||||
return fmt.Errorf(
|
||||
"container %s in pod %s is waiting (reason=%s, message=%s)",
|
||||
cStatus.Name,
|
||||
podKey,
|
||||
w.Reason,
|
||||
w.Message,
|
||||
)
|
||||
}
|
||||
return fmt.Errorf("container %s in pod %s is not running", cStatus.Name, podKey)
|
||||
}
|
||||
if !cStatus.Ready {
|
||||
return fmt.Errorf("container %s in pod %s is not ready", cStatus.Name, podKey)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -321,3 +321,54 @@ func GetBufIOReaderOfTerminalInput() (*bufio.Reader, error) {
|
||||
}
|
||||
return bufio.NewReader(tty), nil
|
||||
}
|
||||
|
||||
// ResolveSudoUserHomeAndIDs resolves the home directory, uid, and gid for the user
|
||||
// who invoked sudo. If not running under sudo, it falls back to the current user.
|
||||
// This is useful for commands that need to operate on the invoking user's home
|
||||
// directory rather than /root when running with sudo.
|
||||
func ResolveSudoUserHomeAndIDs(runtime connector.Runtime) (home, uid, gid string, err error) {
|
||||
uid, err = runtime.GetRunner().Cmd("echo ${SUDO_UID:-}", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get SUDO_UID failed")
|
||||
}
|
||||
gid, err = runtime.GetRunner().Cmd("echo ${SUDO_GID:-}", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get SUDO_GID failed")
|
||||
}
|
||||
uid = strings.TrimSpace(uid)
|
||||
gid = strings.TrimSpace(gid)
|
||||
|
||||
if uid == "" {
|
||||
uid, err = runtime.GetRunner().Cmd("id -u", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get current uid failed")
|
||||
}
|
||||
gid, err = runtime.GetRunner().Cmd("id -g", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get current gid failed")
|
||||
}
|
||||
uid = strings.TrimSpace(uid)
|
||||
gid = strings.TrimSpace(gid)
|
||||
}
|
||||
|
||||
home, err = runtime.GetRunner().Cmd(fmt.Sprintf(`getent passwd %s | awk -F: 'NR==1{print $6; exit}'`, uid), false, false)
|
||||
if err != nil {
|
||||
home = ""
|
||||
}
|
||||
home = strings.TrimSpace(home)
|
||||
if home == "" {
|
||||
home, _ = runtime.GetRunner().Cmd(fmt.Sprintf(`awk -F: -v uid=%s '$3==uid {print $6; exit}' /etc/passwd 2>/dev/null`, uid), false, false)
|
||||
home = strings.TrimSpace(home)
|
||||
}
|
||||
if home == "" {
|
||||
home, err = runtime.GetRunner().Cmd("echo $HOME", false, false)
|
||||
if err != nil {
|
||||
return "", "", "", errors.Wrap(errors.WithStack(err), "get HOME failed")
|
||||
}
|
||||
home = strings.TrimSpace(home)
|
||||
}
|
||||
if home == "" {
|
||||
return "", "", "", errors.New("resolve user home failed")
|
||||
}
|
||||
return home, uid, gid, nil
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
DIDGateURL = "https://did-gate-v3.bttcdn.com/1.0/name/"
|
||||
DIDGateTimeout = 10 * time.Second
|
||||
DIDCachePath = "/var/lib/olares"
|
||||
)
|
||||
@@ -90,7 +89,7 @@ type CheckJWSResult struct {
|
||||
}
|
||||
|
||||
// resolveDID resolves a DID either from cache or from the DID gate
|
||||
func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
|
||||
func ResolveOlaresName(gateUrl, olares_id string) (*didcore.ResolutionResult, error) {
|
||||
name := strings.Replace(olares_id, "@", ".", -1)
|
||||
// Try to get from cache first
|
||||
cached, err := getDB().Get([]byte(name), nil)
|
||||
@@ -105,7 +104,7 @@ func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
|
||||
client := &http.Client{
|
||||
Timeout: DIDGateTimeout,
|
||||
}
|
||||
resp, err := client.Get(DIDGateURL + name)
|
||||
resp, err := client.Get(gateUrl + name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch DID from gate: %w", err)
|
||||
}
|
||||
@@ -135,7 +134,7 @@ func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
|
||||
}
|
||||
|
||||
// CheckJWS verifies a JWS and returns the terminus name, body and kid
|
||||
func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) {
|
||||
func CheckJWS(gateUrl, jws string, duration int64) (*CheckJWSResult, error) {
|
||||
var kid string
|
||||
var name string
|
||||
var timestamp int64
|
||||
@@ -198,7 +197,7 @@ func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) {
|
||||
}
|
||||
|
||||
// Resolve DID
|
||||
resolutionResult, err := ResolveOlaresName(name)
|
||||
resolutionResult, err := ResolveOlaresName(gateUrl, name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to resolve DID: %w", err)
|
||||
}
|
||||
|
||||
@@ -25,5 +25,5 @@ build-linux-in-docker:
|
||||
-v $(current_dir):/olaresd \
|
||||
-w /olaresd \
|
||||
-e DEBIAN_FRONTEND=noninteractive \
|
||||
golang:1.24 \
|
||||
sh -c "apt-get -y update; apt-get -y install libudev-dev libpcap-dev; make build-linux"
|
||||
golang:1.24.11 \
|
||||
sh -c "apt-get -y update; apt-get -y install libudev-dev libpcap-dev; make build-linux"
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
module github.com/beclab/Olares/daemon
|
||||
|
||||
go 1.24.2
|
||||
|
||||
toolchain go1.24.4
|
||||
go 1.24.11
|
||||
|
||||
replace (
|
||||
bytetrade.io/web3os/app-service => github.com/beclab/app-service v0.4.37
|
||||
bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17
|
||||
bytetrade.io/web3os/bfl => github.com/beclab/bfl v0.3.36
|
||||
github.com/labstack/echo/v4 => github.com/eball/echo/v4 v4.13.4-patch
|
||||
@@ -18,15 +15,15 @@ replace (
|
||||
)
|
||||
|
||||
require (
|
||||
bytetrade.io/web3os/app-service v0.0.0-00010101000000-000000000000
|
||||
bytetrade.io/web3os/bfl v0.0.0-00010101000000-000000000000
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
|
||||
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89
|
||||
github.com/containerd/containerd v1.7.28
|
||||
github.com/beclab/Olares/cli v0.0.0-20251230161135-5264df60cc33
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70
|
||||
github.com/containerd/containerd v1.7.29
|
||||
github.com/distribution/distribution/v3 v3.0.0
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/eball/zeroconf v0.2.2
|
||||
github.com/eball/zeroconf v0.2.5
|
||||
github.com/godbus/dbus/v5 v5.1.0
|
||||
github.com/gofiber/fiber/v2 v2.52.9
|
||||
github.com/google/gopacket v1.1.19
|
||||
@@ -39,6 +36,7 @@ require (
|
||||
github.com/libp2p/go-netroute v0.2.2
|
||||
github.com/mackerelio/go-osstat v0.2.5
|
||||
github.com/mdlayher/raw v0.1.0
|
||||
github.com/miekg/dns v1.1.55
|
||||
github.com/muka/network_manager v0.0.0-20200903202308-ae5ede816e07
|
||||
github.com/nxadm/tail v1.4.11
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
|
||||
@@ -52,10 +50,11 @@ require (
|
||||
github.com/txn2/txeh v1.5.5
|
||||
github.com/vishvananda/netlink v1.3.0
|
||||
go.opentelemetry.io/otel/trace v1.36.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
|
||||
golang.org/x/sys v0.35.0
|
||||
golang.org/x/sys v0.38.0
|
||||
k8s.io/api v0.34.1
|
||||
k8s.io/apiextensions-apiserver v0.34.0
|
||||
k8s.io/apimachinery v0.34.1
|
||||
k8s.io/client-go v12.0.0+incompatible
|
||||
k8s.io/cri-api v0.34.1
|
||||
@@ -90,10 +89,11 @@ require (
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
@@ -129,7 +129,6 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mdlayher/packet v0.0.0-20220221164757-67998ac0ff93 // indirect
|
||||
github.com/mdlayher/socket v0.2.1 // indirect
|
||||
github.com/miekg/dns v1.1.55 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
@@ -146,7 +145,7 @@ require (
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runc v1.3.0 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.2.1 // indirect
|
||||
github.com/opencontainers/selinux v1.12.0 // indirect
|
||||
github.com/opencontainers/selinux v1.13.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.23.0 // indirect
|
||||
@@ -181,14 +180,14 @@ require (
|
||||
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/mod v0.27.0 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/mod v0.29.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/term v0.37.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools v0.36.0 // indirect
|
||||
golang.org/x/tools v0.38.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
|
||||
@@ -200,7 +199,6 @@ require (
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
howett.net/plist v1.0.0 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.34.0 // indirect
|
||||
k8s.io/apiserver v0.34.0 // indirect
|
||||
k8s.io/component-base v0.34.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
|
||||
|
||||
@@ -24,10 +24,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89 h1:5s9hXV8K3faToQtE9DbiM7O6jt5kIiEsLAaKn6F0UfA=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89/go.mod h1:iEvZxM6PnFxFRppneTzV3hgr2tIxDnsI3dhp4pi7pFg=
|
||||
github.com/beclab/app-service v0.4.37 h1:gt60wQxgPWMc3oN94TNSdiQAvzqTyCv/OUP93jNSQTY=
|
||||
github.com/beclab/app-service v0.4.37/go.mod h1:0vEg3rv/DbR7dYznvTlXNXyYNn+TXNMaxz03GQYRWUQ=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251230161135-5264df60cc33 h1:WYuUPOT/p26aCDJGJEDai1v7YM6QHiaFDusBVynnbBY=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251230161135-5264df60cc33/go.mod h1:ixhzBK5XIovsRB5djk44TChsOK4wum2q4y/hZxJKlNw=
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70 h1:U3z6m0hokD1gzl788BrUdxCbDyAjdOBBXA8ilYgn6VQ=
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70/go.mod h1:D9wl7y3obLqXMqfubMROMgdxWAwInnKNrFC//d0nyIA=
|
||||
github.com/beclab/bfl v0.3.36 h1:PgeSPGc+XoONiwFsKq9xX8rqcL4kVM1G/ut0lYYj/js=
|
||||
github.com/beclab/bfl v0.3.36/go.mod h1:A82u38MxYk1C3Lqnm4iUUK4hBeY9HHIs+xU4V93OnJk=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -45,8 +45,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
|
||||
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c=
|
||||
github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
|
||||
github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
|
||||
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
|
||||
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
|
||||
@@ -65,6 +65,8 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
|
||||
github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
|
||||
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
|
||||
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
@@ -73,20 +75,20 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=
|
||||
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/eball/echo/v4 v4.13.4-patch h1:5w83KQrEqrxhc1BO0BpRBHssC37vFrWualUM27Rt2sg=
|
||||
github.com/eball/echo/v4 v4.13.4-patch/go.mod h1:ORgy8LWTq8knpwgaz538rAJMri7WgpoAD6H3zYccn84=
|
||||
github.com/eball/zeroconf v0.2.2 h1:y23X67tLFlU+b35LyM9THXGsdC88IUz803G+mzfeSeE=
|
||||
github.com/eball/zeroconf v0.2.2/go.mod h1:eIbIjGYo9sSMaKWLcveHEPRWdyblz7q9ih2R1HnNw5M=
|
||||
github.com/eball/zeroconf v0.2.5 h1:RNINVvj8kbm/r4YoqYu/jWD57l5NJmvRUCfbjlIsbJg=
|
||||
github.com/eball/zeroconf v0.2.5/go.mod h1:eIbIjGYo9sSMaKWLcveHEPRWdyblz7q9ih2R1HnNw5M=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
|
||||
@@ -287,8 +289,8 @@ github.com/opencontainers/runc v1.3.0 h1:cvP7xbEvD0QQAs0nZKLzkVog2OPZhI/V2w3WmTm
|
||||
github.com/opencontainers/runc v1.3.0/go.mod h1:9wbWt42gV+KRxKRVVugNP6D5+PQciRbenB4fLVsqGPs=
|
||||
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
|
||||
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
|
||||
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
|
||||
github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
|
||||
github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
@@ -414,8 +416,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
|
||||
@@ -426,8 +428,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -440,8 +442,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
@@ -451,8 +453,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -472,16 +474,16 @@ 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.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -493,8 +495,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -2,8 +2,10 @@ package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/web5/jws"
|
||||
"github.com/beclab/Olares/daemon/pkg/commands"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
@@ -14,8 +16,14 @@ func (h *Handlers) ResolveOlaresName(c *fiber.Ctx) error {
|
||||
klog.Error("olaresName parameter is missing")
|
||||
return h.ErrJSON(c, fiber.StatusBadRequest, "olaresName parameter is required")
|
||||
}
|
||||
|
||||
klog.Infof("Received olaresName: %s", olaresName)
|
||||
result, err := jws.ResolveOlaresName(olaresName)
|
||||
|
||||
didServiceURL, err := getDidGateURL()
|
||||
if err != nil {
|
||||
return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to get DID gate URL")
|
||||
}
|
||||
result, err := jws.ResolveOlaresName(didServiceURL, olaresName)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to resolve DID for %s: %v", olaresName, err)
|
||||
return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to resolve DID")
|
||||
@@ -46,7 +54,11 @@ func (h *Handlers) CheckJWS(c *fiber.Ctx) error {
|
||||
body.Duration = int64(3 * 60 * 1000) // 3 minutes in milliseconds
|
||||
}
|
||||
|
||||
result, err := jws.CheckJWS(body.JWS, body.Duration)
|
||||
didServiceURL, err := getDidGateURL()
|
||||
if err != nil {
|
||||
return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to get DID gate URL")
|
||||
}
|
||||
result, err := jws.CheckJWS(didServiceURL, body.JWS, body.Duration)
|
||||
if err != nil {
|
||||
klog.Errorf("Failed to check JWS: %v", err)
|
||||
return h.ErrJSON(c, fiber.StatusBadRequest, "Invalid JWS")
|
||||
@@ -54,3 +66,12 @@ func (h *Handlers) CheckJWS(c *fiber.Ctx) error {
|
||||
|
||||
return h.OkJSON(c, "success", result)
|
||||
}
|
||||
|
||||
func getDidGateURL() (string, error) {
|
||||
didServiceURL, err := url.JoinPath(commands.OLARES_REMOTE_SERVICE, "/did/1.0/name/")
|
||||
if err != nil {
|
||||
klog.Errorf("failed to parse DID gate service URL: %v, Olares remote service: %s", err, commands.OLARES_REMOTE_SERVICE)
|
||||
return "", err
|
||||
}
|
||||
return didServiceURL, nil
|
||||
}
|
||||
|
||||
@@ -43,16 +43,18 @@ func (h *Handlers) getMountedPath(ctx *fiber.Ctx, mutate func(*disk.UsageStat) *
|
||||
u = mutate(u)
|
||||
}
|
||||
|
||||
res = append(res, &mountedPath{
|
||||
*u,
|
||||
string(p.Type),
|
||||
p.Invalid,
|
||||
p.IDSerial,
|
||||
p.IDSerialShort,
|
||||
p.PartitionUUID,
|
||||
p.Device,
|
||||
p.ReadOnly,
|
||||
})
|
||||
if u != nil {
|
||||
res = append(res, &mountedPath{
|
||||
*u,
|
||||
string(p.Type),
|
||||
p.Invalid,
|
||||
p.IDSerial,
|
||||
p.IDSerialShort,
|
||||
p.PartitionUUID,
|
||||
p.Device,
|
||||
p.ReadOnly,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return h.OkJSON(ctx, "success", res)
|
||||
@@ -64,7 +66,14 @@ func (h *Handlers) GetMountedPath(ctx *fiber.Ctx) error {
|
||||
|
||||
func (h *Handlers) GetMountedPathInCluster(ctx *fiber.Ctx) error {
|
||||
return h.getMountedPath(ctx, func(us *disk.UsageStat) *disk.UsageStat {
|
||||
us.Path = nodePathToClusterPath(us.Path)
|
||||
path := nodePathToClusterPath(us.Path)
|
||||
if path == us.Path {
|
||||
// not in cluster path
|
||||
return nil
|
||||
}
|
||||
|
||||
us.Path = path
|
||||
|
||||
return us
|
||||
})
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func (s *mDNSServer) StartAll() error {
|
||||
host: &DNSConfig{Domain: domain},
|
||||
}
|
||||
}
|
||||
klog.Info("Intranet mDNS server started")
|
||||
klog.V(8).Info("Intranet mDNS server started")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,15 @@ func (p *proxyServer) Start() error {
|
||||
clientIp = h
|
||||
}
|
||||
}
|
||||
|
||||
if c.IsWebSocket() {
|
||||
ctx = context.WithValue(ctx, WSKey, true)
|
||||
swp := c.Request().Header.Get("Sec-WebSocket-Protocol")
|
||||
authToken := c.Request().Header.Get("X-Authorization")
|
||||
if len(authToken) == 0 && len(swp) > 0 {
|
||||
// handle missing auth token for websocket
|
||||
c.Request().Header.Set("X-Authorization", swp)
|
||||
}
|
||||
}
|
||||
r := c.Request().WithContext(ctx)
|
||||
if clientIp != "" {
|
||||
@@ -243,7 +250,7 @@ func (p *proxyServer) customDialContext(d *net.Dialer) func(ctx context.Context,
|
||||
}
|
||||
|
||||
if isWs {
|
||||
klog.Info("WebSocket connection detected, using upgraded dialer")
|
||||
klog.Info("WebSocket connection detected, using upgraded dialer, ", addr)
|
||||
return tlsDial(ctx, d, func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return proxyDial(ctx, d, network, newAddr)
|
||||
}, network, addr, &tls.Config{InsecureSkipVerify: true})
|
||||
|
||||
@@ -147,6 +147,6 @@ func (s *Server) Reload(o *ServerOptions) error {
|
||||
return fmt.Errorf("reload intranet server with %d errors", len(errs))
|
||||
}
|
||||
|
||||
klog.Info("Intranet server reloaded")
|
||||
klog.V(8).Info("Intranet server reloaded")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ func (s *server) Restart() error {
|
||||
instanceName = hostname
|
||||
}
|
||||
|
||||
s.server, err = zeroconf.Register(instanceName, s.serviceName, "local.", hostname, s.port, []string{""}, []net.Interface{*iface})
|
||||
s.server, err = zeroconf.RegisterAll(instanceName, s.serviceName, "local.", hostname, s.port, []string{""}, []net.Interface{*iface}, false, false, false)
|
||||
if err != nil {
|
||||
klog.Error("create mdns server error, ", err)
|
||||
return err
|
||||
|
||||
@@ -79,7 +79,7 @@ func (w *applicationWatcher) Watch(ctx context.Context) {
|
||||
klog.Error("reload intranet server config error, ", err)
|
||||
return
|
||||
}
|
||||
klog.Info("Intranet server config reloaded")
|
||||
klog.V(8).Info("Intranet server config reloaded")
|
||||
} else {
|
||||
// Start the intranet server
|
||||
err = w.intranetServer.Start(o)
|
||||
|
||||
@@ -20,6 +20,12 @@ func NewUsbWatcher() *usbWatcher {
|
||||
return w
|
||||
}
|
||||
|
||||
var UsbSerialKey = struct{}{}
|
||||
|
||||
func WithSerial(ctx context.Context, serial string) context.Context {
|
||||
return context.WithValue(ctx, UsbSerialKey, serial)
|
||||
}
|
||||
|
||||
func (w *usbWatcher) Watch(ctx context.Context) {
|
||||
retry := 1
|
||||
devs, err := utils.DetectdUsbDevices(ctx)
|
||||
@@ -55,6 +61,16 @@ func (w *usbWatcher) Watch(ctx context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
serial := ctx.Value(UsbSerialKey).(string)
|
||||
if serial != "" {
|
||||
klog.Info("mount usb device with serial, ", serial)
|
||||
devs = utils.FilterArray(devs, utils.FilterBySerial(serial))
|
||||
if len(devs) == 0 {
|
||||
klog.Info("no usb device found with serial, ", serial)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
mountedPath, err := utils.MountUsbDevice(ctx, commands.MOUNT_BASE_DIR, devs)
|
||||
if err != nil {
|
||||
klog.Error("mount usb error, ", err)
|
||||
@@ -80,13 +96,13 @@ func (w *umountWatcher) Watch(ctx context.Context) {
|
||||
}
|
||||
|
||||
func NewUsbMonitor(ctx context.Context) error {
|
||||
return utils.MonitorUsbDevice(ctx, func(action string) error {
|
||||
return utils.MonitorUsbDevice(ctx, func(action, serial string) error {
|
||||
switch action {
|
||||
case "add":
|
||||
delay := time.NewTimer(2 * time.Second)
|
||||
go func() {
|
||||
<-delay.C
|
||||
NewUsbWatcher().Watch(ctx)
|
||||
NewUsbWatcher().Watch(WithSerial(ctx, serial))
|
||||
}()
|
||||
case "remove":
|
||||
NewUmountWatcher().Watch(ctx)
|
||||
|
||||
@@ -119,7 +119,7 @@ func DetectdHddDevices(ctx context.Context) (usbDevs []storageDevice, err error)
|
||||
return detectdStorageDevices(ctx, "ata")
|
||||
}
|
||||
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action, serial string) error) error {
|
||||
filter := &usbmon.ActionFilter{Action: usbmon.ActionAll}
|
||||
devs, err := usbmon.ListenFiltered(ctx, filter)
|
||||
if err != nil {
|
||||
@@ -137,8 +137,8 @@ func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
|
||||
fmt.Println("Path: " + dev.Path())
|
||||
fmt.Println("Vendor: " + dev.Vendor())
|
||||
|
||||
if cb != nil {
|
||||
err = cb(dev.Action())
|
||||
if cb != nil && dev.Serial() != "" {
|
||||
err = cb(dev.Action(), dev.Serial())
|
||||
if err != nil {
|
||||
klog.Error("usb action callback error, ", err, ", ", dev.Action())
|
||||
}
|
||||
@@ -197,6 +197,12 @@ func MountedHddPath(ctx context.Context) ([]string, error) {
|
||||
return getMountedPath(hdds)
|
||||
}
|
||||
|
||||
func FilterBySerial(serial string) func(dev storageDevice) bool {
|
||||
return func(dev storageDevice) bool {
|
||||
return strings.HasSuffix(serial, dev.IDSerial) || strings.HasSuffix(serial, dev.IDSerialShort)
|
||||
}
|
||||
}
|
||||
|
||||
func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevice) (mountedPath []string, err error) {
|
||||
mounter := mountutils.New("")
|
||||
mountedList, err := mounter.List()
|
||||
@@ -267,7 +273,8 @@ func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevic
|
||||
if err = mounter.Mount(d.DevPath, mkMountDir, "", []string{"uid=1000", "gid=1000"}); err != nil {
|
||||
klog.Warning("mount usb error, ", err, ", ", d.DevPath, ", ", mkMountDir)
|
||||
// clear the empty mount dir
|
||||
if err = os.RemoveAll(mkMountDir); err != nil {
|
||||
// do not use remove all, only remove the mount point path, assume it's an empty dir
|
||||
if err = os.Remove(mkMountDir); err != nil {
|
||||
klog.Error("remove the mount dir error, ", err)
|
||||
}
|
||||
|
||||
@@ -287,7 +294,8 @@ func umountAndRemovePath(ctx context.Context, path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.RemoveAll(path); err != nil {
|
||||
// do not use remove all, only remove the mount point path, assume it's an empty dir
|
||||
if err = os.Remove(path); err != nil {
|
||||
klog.Error("remove mount point error, ", err)
|
||||
}
|
||||
|
||||
@@ -397,6 +405,11 @@ func UmountBrokenMount(ctx context.Context, baseDir string) error {
|
||||
|
||||
klog.Infof("broken mountpoint: %v, %v, %v", m.Path, m.Device, r.Reason)
|
||||
|
||||
if err = umountAndRemovePath(ctx, m.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !isDeviceExists(m.Device) {
|
||||
klog.Infof("device not exists mountpoint: %v, %v", m.Path, m.Device)
|
||||
if err = umountAndRemovePath(ctx, m.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -659,3 +672,16 @@ func checkMount(mountPoint string, timeout time.Duration) result {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func isDeviceExists(devicePath string) bool {
|
||||
if !strings.HasPrefix(devicePath, "/dev") {
|
||||
return true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(devicePath, "/dev/mapper/") {
|
||||
return true
|
||||
}
|
||||
|
||||
_, err := os.Stat(devicePath)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func DetectdHddDevices(ctx context.Context) (usbDevs []storageDevice, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
|
||||
func MonitorUsbDevice(ctx context.Context, cb func(action, id string) error) error {
|
||||
klog.Warning("not implement")
|
||||
return nil
|
||||
}
|
||||
@@ -72,3 +72,9 @@ func MountedPath(ctx context.Context) ([]mountedPath, error) {
|
||||
klog.Warning("not implement")
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func FilterBySerial(serial string) func(dev storageDevice) bool {
|
||||
return func(dev storageDevice) bool {
|
||||
return dev.IDSerial == serial || dev.IDSerialShort == serial
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,15 +18,14 @@ func ValidateJWS(token string) (bool, string, error) {
|
||||
klog.Errorf("failed to parse DID gate service URL: %v, Olares remote service: %s", err, commands.OLARES_REMOTE_SERVICE)
|
||||
return false, "", err
|
||||
}
|
||||
jws.DIDGateURL = didServiceURL
|
||||
|
||||
// Validate the JWS token with a 20-minute expiration time
|
||||
checkJWS, err := jws.CheckJWS(token, 20*60*1000)
|
||||
checkJWS, err := jws.CheckJWS(didServiceURL, token, 20*60*1000)
|
||||
if err != nil {
|
||||
if strings.HasPrefix(err.Error(), "timestamp") {
|
||||
err = fmt.Errorf("%v, server time: %s", err, time.Now().UTC().Format(time.RFC3339))
|
||||
}
|
||||
klog.Errorf("failed to check JWS: %v, on %s", err, jws.DIDGateURL)
|
||||
klog.Errorf("failed to check JWS: %v, on %s", err, didServiceURL)
|
||||
return false, "", err
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@ import (
|
||||
"k8s.io/utils/pointer"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
|
||||
sysv1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"bytetrade.io/web3os/app-service/pkg/generated/clientset/versioned"
|
||||
sysv1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/beclab/Olares/framework/app-service/pkg/generated/clientset/versioned"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
11
daemon/pkg/utils/utils.go
Normal file
11
daemon/pkg/utils/utils.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package utils
|
||||
|
||||
func FilterArray[T any](items []T, fn func(T) bool) []T {
|
||||
var filtered []T
|
||||
for _, item := range items {
|
||||
if fn(item) {
|
||||
filtered = append(filtered, item)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
@@ -6,19 +6,34 @@ const side = {
|
||||
text: "What is Olares",
|
||||
link: "/manual/overview",
|
||||
items: [
|
||||
{ text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
|
||||
{ text: "Help and support", link: "/manual/help/request-technical-support"}
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// { text: "FAQs", link: "/manual/help/faqs" },
|
||||
// {
|
||||
// text: "Request support",
|
||||
// link: "/manual/help/request-technical-support",
|
||||
// },
|
||||
//{
|
||||
// text: "Troubleshooting Guide",
|
||||
// link: "/manual/help/troubleshooting-guide",
|
||||
// },
|
||||
// { text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
|
||||
{
|
||||
text: "FAQs",
|
||||
// link: "/manual/help/faqs",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Olares FAQs",
|
||||
link: "/manual/help/olares",
|
||||
},
|
||||
{
|
||||
text: "Installation FAQs",
|
||||
link: "/manual/help/installation",
|
||||
},
|
||||
{
|
||||
text: "Usage FAQs",
|
||||
link: "/manual/help/usage",
|
||||
},
|
||||
// {
|
||||
// text: "Request support",
|
||||
// link: "/manual/help/request-technical-support",
|
||||
// },
|
||||
// {
|
||||
// text: "Troubleshooting",
|
||||
// link: "/manual/help/troubleshooting",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -109,7 +124,7 @@ const side = {
|
||||
link: "/manual/larepass/back-up-mnemonics"
|
||||
},
|
||||
{
|
||||
text: "Access Olares locally",
|
||||
text: "Access Olares securely",
|
||||
link: "/manual/get-started/local-access",
|
||||
},
|
||||
{
|
||||
@@ -127,39 +142,39 @@ const side = {
|
||||
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: "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: "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: "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 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: "Autofill passwords", link: "/manual/larepass/autofill" },
|
||||
{ text: "Generate 2FA codes", link: "/manual/larepass/two-factor-verification" },
|
||||
],
|
||||
},
|
||||
{
|
||||
/*{
|
||||
text: "Manage knowledge",
|
||||
link: "/manual/larepass/manage-knowledge",
|
||||
},
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -168,7 +183,24 @@ const side = {
|
||||
link: "/manual/olares/",
|
||||
items: [
|
||||
{ text: "Desktop", link: "/manual/olares/desktop", },
|
||||
{ text: "Market", link: "/manual/olares/market", },
|
||||
{
|
||||
text: "Market",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Basic operations",
|
||||
link: "/manual/olares/market/market",
|
||||
},
|
||||
{
|
||||
text: "Clone applications",
|
||||
link: "/manual/olares/market/clone-apps",
|
||||
},
|
||||
{
|
||||
text: "Manage paid applications",
|
||||
link: "/manual/olares/market/purchase-paid-apps",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Files",
|
||||
collapsed: true,
|
||||
@@ -178,18 +210,26 @@ const side = {
|
||||
text: "Basic file operations",
|
||||
link: "/manual/olares/files/add-edit-download",
|
||||
},
|
||||
// {
|
||||
// text: "Sync and share",
|
||||
// link: "/manual/larepass/sync-share",
|
||||
// },
|
||||
// {
|
||||
// text: "Sync and share",
|
||||
// link: "/manual/larepass/sync-share",
|
||||
// },
|
||||
{
|
||||
text: "Share files",
|
||||
link: "/manual/olares/files/share-files",
|
||||
},
|
||||
{
|
||||
text: "Sync files to local",
|
||||
link: "/manual/olares/files/sync-files",
|
||||
},
|
||||
{
|
||||
text: "Mount SMB",
|
||||
link: "/manual/olares/files/mount-SMB",
|
||||
},
|
||||
{
|
||||
text: "Mount cloud storage",
|
||||
link: "/manual/olares/files/mount-cloud-storage",
|
||||
},
|
||||
{
|
||||
text: "Mount cloud storage",
|
||||
link: "/manual/olares/files/mount-cloud-storage",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -224,17 +264,32 @@ const side = {
|
||||
text: "Basic operations",
|
||||
link: "/manual/olares/wise/basics",
|
||||
},
|
||||
{
|
||||
/*{
|
||||
text: "Get recommendation engine",
|
||||
link: "/manual/olares/wise/recommend",
|
||||
},
|
||||
},*/
|
||||
{
|
||||
text: "Manage your feeds",
|
||||
link: "/manual/olares/wise/subscribe",
|
||||
},
|
||||
{
|
||||
text: "Organize your knowledge",
|
||||
text: "Manage cookies",
|
||||
link: "/manual/olares/wise/manage-cookies",
|
||||
},
|
||||
{
|
||||
text: "Organize with filters",
|
||||
link: "/manual/olares/wise/filter",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Filter syntax",
|
||||
link: "/manual/olares/wise/filter-syntax-guide",
|
||||
},
|
||||
{
|
||||
text: "Filter example",
|
||||
link: "/manual/olares/wise/filter-examples",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -305,16 +360,16 @@ const side = {
|
||||
link: "/manual/olares/settings/manage-app-env",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
text: "Manage integrations",
|
||||
link:"/manual/olares/settings/integrations",
|
||||
},
|
||||
{
|
||||
link: "/manual/olares/settings/integrations",
|
||||
},
|
||||
{
|
||||
text: "Customize appearance",
|
||||
link:"/manual/olares/settings/language-appearance",
|
||||
},
|
||||
{text: "Manage VPN", link: "/manual/olares/settings/remote-access",},
|
||||
link: "/manual/olares/settings/language-appearance",
|
||||
},
|
||||
{ text: "Manage VPN", link: "/manual/olares/settings/remote-access", },
|
||||
{
|
||||
text: "Configure network",
|
||||
collapsed: true,
|
||||
@@ -325,54 +380,59 @@ const side = {
|
||||
},
|
||||
{
|
||||
text: "Set up hosts file",
|
||||
link:"/manual/olares/settings/set-up-hosts",
|
||||
link: "/manual/olares/settings/set-up-hosts",
|
||||
},
|
||||
],
|
||||
},
|
||||
{text: "Manage GPU", link: "/manual/olares/settings/gpu-resource"},
|
||||
{text: "Set video playback", link: "/manual/olares/settings/video"},
|
||||
},
|
||||
{ text: "Manage GPU", link: "/manual/olares/settings/gpu-resource" },
|
||||
{ text: "Set video playback", link: "/manual/olares/settings/video" },
|
||||
{ text: "Manage search rules", link: "/manual/olares/settings/search" },
|
||||
{
|
||||
text: "Backup and restore",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{text: "Backup", link: "/manual/olares/settings/backup"},
|
||||
{text: "Restore", link: "/manual/olares/settings/restore"},
|
||||
{ text: "Backup", link: "/manual/olares/settings/backup" },
|
||||
{ text: "Restore", link: "/manual/olares/settings/restore" },
|
||||
],
|
||||
},
|
||||
{text: "Developer resources", link: "/manual/olares/settings/developer"},
|
||||
]
|
||||
},
|
||||
{text: "Dashboard", link: "/manual/olares/resources-usage"},
|
||||
{text: "Profile", link: "/manual/olares/profile"},
|
||||
],
|
||||
{ text: "Developer resources", link: "/manual/olares/settings/developer" },
|
||||
]
|
||||
},
|
||||
{ text: "Dashboard", link: "/manual/olares/resources-usage" },
|
||||
{ text: "Profile", link: "/manual/olares/profile" },
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Best practices",
|
||||
link: "/manual/best-practices/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Set up custom domain",
|
||||
link: "/manual/best-practices/set-custom-domain",
|
||||
},
|
||||
{
|
||||
text: "Manage knowledge with Wise",
|
||||
link: "/manual/best-practices/organize-content",
|
||||
},
|
||||
{
|
||||
text: "Install a multi-node Olares cluster",
|
||||
link: "/manual/best-practices/install-olares-multi-node",
|
||||
},
|
||||
{
|
||||
text: "Install Olares on PVE with GPU Passthrough",
|
||||
link: "/manual/best-practices/install-olares-gpu-passthrough",
|
||||
},
|
||||
{
|
||||
text: "Expand storage in Olares",
|
||||
{
|
||||
text: "Tutorials",
|
||||
link: "/manual/best-practices/",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "Set up custom domain",
|
||||
link: "/manual/best-practices/set-custom-domain",
|
||||
},
|
||||
{
|
||||
text: "Manage knowledge with Wise",
|
||||
link: "/manual/best-practices/organize-content",
|
||||
},
|
||||
{
|
||||
text: "Install a multi-node Olares cluster",
|
||||
link: "/manual/best-practices/install-olares-multi-node",
|
||||
},
|
||||
{
|
||||
text: "Install Olares on PVE with GPU Passthrough",
|
||||
link: "/manual/best-practices/install-olares-gpu-passthrough",
|
||||
},
|
||||
{
|
||||
text: "Expand storage in Olares",
|
||||
link: "/manual/best-practices/expand-storage-in-olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Access Olares locally",
|
||||
link: "/manual/best-practices/local-access",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "Glossary", link: "/manual/glossary" },
|
||||
],
|
||||
"/space/": [
|
||||
@@ -421,83 +481,106 @@ const side = {
|
||||
},
|
||||
],
|
||||
"/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",
|
||||
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: "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",
|
||||
{
|
||||
text: "Olares ID",
|
||||
link: "/developer/concepts/olares-id",
|
||||
collapsed: true,
|
||||
items: [
|
||||
@@ -534,7 +617,7 @@ const side = {
|
||||
{ text: "Secrets", link: "/developer/concepts/secrets" },
|
||||
],
|
||||
},
|
||||
{
|
||||
{
|
||||
text: "Installation deep-dive",
|
||||
link: "/developer/install/",
|
||||
items: [
|
||||
@@ -559,74 +642,55 @@ const side = {
|
||||
link: "/developer/install/cli/olares-cli",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{ text: "gpu", link: "/developer/install/cli/gpu" },
|
||||
{ text: "osinfo", link: "/developer/install/cli/osinfo" },
|
||||
{ text: "node", link: "/developer/install/cli/node" },
|
||||
{
|
||||
text: "backups",
|
||||
link: "/developer/install/cli/backups",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{text: "download", link: "/developer/install/cli/backups-download"},
|
||||
{text: "region", link: "/developer/install/cli/backups-region"},
|
||||
{text: "backup", link: "/developer/install/cli/backups-backup"},
|
||||
{text: "restore", link: "/developer/install/cli/backups-restore"},
|
||||
{text: "snapshots", link: "/developer/install/cli/backups-snapshots"},
|
||||
],
|
||||
},
|
||||
{ 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: "change-ip",
|
||||
link: "/developer/install/cli/change-ip",
|
||||
},
|
||||
{
|
||||
text: "download",
|
||||
link: "/developer/install/cli/download",
|
||||
},
|
||||
{ text: "info", link: "/developer/install/cli/info" },
|
||||
{
|
||||
text: "install",
|
||||
link: "/developer/install/cli/install",
|
||||
},
|
||||
{
|
||||
text: "user activate",
|
||||
link: "/developer/install/cli/user-activate",
|
||||
},
|
||||
{
|
||||
text: "logs",
|
||||
link: "/developer/install/cli/logs",
|
||||
},
|
||||
{
|
||||
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: "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: "Olares versioning",
|
||||
link: "/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Develop Olares apps",
|
||||
link: "/developer/develop/",
|
||||
@@ -682,43 +746,43 @@ const side = {
|
||||
// items: [
|
||||
// {
|
||||
// text: "terminus-info",
|
||||
// link: "/developer/develop/advanced/terminus-info",
|
||||
// link: "/developer/develop/advanced/terminus-info",
|
||||
// },
|
||||
// {
|
||||
// text: "Service provider",
|
||||
// link: "/developer/develop/advanced/provider",
|
||||
// link: "/developer/develop/advanced/provider",
|
||||
// },
|
||||
// {
|
||||
// text: "AI",
|
||||
// link: "/developer/develop/advanced/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",
|
||||
// link: "/developer/develop/advanced/account",
|
||||
// },
|
||||
// {
|
||||
// text: "Market",
|
||||
// link: "/developer/develop/advanced/market",
|
||||
// link: "/developer/develop/advanced/market",
|
||||
// },
|
||||
// {
|
||||
// text: "Websocket",
|
||||
// link: "/developer/develop/advanced/websocket",
|
||||
// link: "/developer/develop/advanced/websocket",
|
||||
// },
|
||||
// {
|
||||
// text: "File upload",
|
||||
// link: "/developer/develop/advanced/file-upload",
|
||||
// link: "/developer/develop/advanced/file-upload",
|
||||
// },
|
||||
// {
|
||||
// text: "Secret",
|
||||
// link: "/developer/develop/advanced/secret",
|
||||
// link: "/developer/develop/advanced/secret",
|
||||
// },
|
||||
// {
|
||||
// text: "Kubesphere",
|
||||
// link: "/developer/develop/advanced/kubesphere",
|
||||
// link: "/developer/develop/advanced/kubesphere",
|
||||
// },
|
||||
// ],
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
text: "Submit application",
|
||||
@@ -756,86 +820,86 @@ const side = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -856,4 +920,4 @@ export const en = defineConfig({
|
||||
|
||||
sidebar: side,
|
||||
},
|
||||
});
|
||||
});
|
||||
9
docs/.vitepress/theme/components/AppLinkCN.vue
Normal file
9
docs/.vitepress/theme/components/AppLinkCN.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const targetUrl = 'https://www.olares.cn/larepass'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a :href="targetUrl" target="_blank" rel="noreferrer" class="app-link">
|
||||
<slot>LarePass 下载页面</slot>
|
||||
</a>
|
||||
</template>
|
||||
9
docs/.vitepress/theme/components/AppLinkGlobal.vue
Normal file
9
docs/.vitepress/theme/components/AppLinkGlobal.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
const targetUrl = 'https://www.olares.com/larepass'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a :href="targetUrl" target="_blank" rel="noreferrer" class="app-link">
|
||||
<slot>LarePass Download page</slot>
|
||||
</a>
|
||||
</template>
|
||||
@@ -14,6 +14,9 @@ import OSTabs from "./components/OStabs.vue";
|
||||
import VersionSwitcher from "./components/VersionSwitcher.vue";
|
||||
import _ from "lodash";
|
||||
import { redirects } from './redirects';
|
||||
import AppLinkGlobal from './components/AppLinkGlobal.vue'
|
||||
import AppLinkCN from './components/AppLinkCN.vue'
|
||||
|
||||
|
||||
const LANGUAGE_LOCAL_KEY = "language";
|
||||
let isMenuChange = false;
|
||||
@@ -27,6 +30,8 @@ enhanceApp({ app, router }: { app: App; router: Router }) {
|
||||
app.component("FilterableList", FilterableList);
|
||||
app.component("OSTabs", OSTabs);
|
||||
app.component("VersionSwitcher", VersionSwitcher);
|
||||
app.component('AppLinkGlobal', AppLinkGlobal)
|
||||
app.component('AppLinkCN', AppLinkCN)
|
||||
|
||||
router.onBeforeRouteChange = (to: string) => {
|
||||
const path = to.replace(/\.html$/i, ''),
|
||||
@@ -142,4 +147,4 @@ enhanceApp({ app, router }: { app: App; router: Router }) {
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -6,23 +6,36 @@ const side = {
|
||||
text: "Olares 是什么?",
|
||||
link: "/zh/manual/overview",
|
||||
items: [
|
||||
// { text: "应用场景", link: "/zh/manual/why-olares" },
|
||||
//{ text: "功能对比", link: "/zh/manual/feature-overview" },
|
||||
{ text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
|
||||
{text: "帮助与支持", link: "/zh/manual/help/request-technical-support",}
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// { text: "常见问题", link: "/zh/manual/help/faqs" },
|
||||
// {
|
||||
// text: "技术支持",
|
||||
// link: "/zh/manual/help/request-technical-support",
|
||||
// },
|
||||
// { text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
|
||||
{
|
||||
text: "常见问题",
|
||||
// link: "/zh/manual/help/faqs",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
text: "产品",
|
||||
link: "/zh/manual/help/olares",
|
||||
},
|
||||
{
|
||||
text: "安装激活",
|
||||
link: "/zh/manual/help/installation",
|
||||
},
|
||||
{
|
||||
text: "使用",
|
||||
link: "/zh/manual/help/usage",
|
||||
},
|
||||
// {
|
||||
// text: "技术支持",
|
||||
// link: "/zh/manual/help/request-technical-support",
|
||||
// },
|
||||
// {
|
||||
// text: "Troubleshooting Guide",
|
||||
// link: "/zh/manual/help/troubleshooting-guide",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "快速开始",
|
||||
collapsed: false,
|
||||
@@ -110,7 +123,7 @@ const side = {
|
||||
link: "/zh/manual/larepass/back-up-mnemonics",
|
||||
},
|
||||
{
|
||||
text: "内网访问 Olares",
|
||||
text: "安全访问 Olares",
|
||||
link: "zh/manual/get-started/local-access",
|
||||
},
|
||||
{
|
||||
@@ -128,39 +141,39 @@ const side = {
|
||||
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/create-account" },
|
||||
{ text: "备份助记词", link: "/zh/manual/larepass/back-up-mnemonics" },
|
||||
{ text: "管理集成", link: "/zh/manual/larepass/integrations" },
|
||||
],
|
||||
},
|
||||
{text: "使用专用网络", link:"/zh/manual/larepass/private-network"},
|
||||
{ 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: "激活 Olares", link: "/zh/manual/larepass/activate-olares" },
|
||||
{ text: "管理 Olares", link: "/zh/manual/larepass/manage-olares" },
|
||||
],
|
||||
},
|
||||
{text: "管理文件", link:"/zh/manual/larepass/manage-files"},
|
||||
// collapsed: true,
|
||||
{ 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/autofill" },
|
||||
{ text: "双重验证", link: "/zh/manual/larepass/two-factor-verification" },
|
||||
],
|
||||
},
|
||||
{
|
||||
/*{
|
||||
text: "管理内容",
|
||||
link: "/zh/manual/larepass/manage-knowledge",
|
||||
},
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -169,7 +182,24 @@ const side = {
|
||||
"link": "/zh/manual/olares/",
|
||||
"items": [
|
||||
{ "text": "桌面", "link": "/zh/manual/olares/desktop" },
|
||||
{ "text": "应用市场", "link": "/zh/manual/olares/market" },
|
||||
{
|
||||
"text": "应用市场",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{
|
||||
"text": "基本操作",
|
||||
"link": "/zh/manual/olares/market/market"
|
||||
},
|
||||
{
|
||||
"text": "管理付费应用",
|
||||
"link": "/zh/manual/olares/market/purchase-paid-apps"
|
||||
},
|
||||
{
|
||||
"text": "克隆应用",
|
||||
"link": "/zh/manual/olares/market/clone-apps"
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"text": "文件管理器",
|
||||
"collapsed": true,
|
||||
@@ -181,8 +211,16 @@ const side = {
|
||||
},
|
||||
//{
|
||||
// "text": "同步与共享",
|
||||
// "link": "/zh/manual/larepass/sync-share"
|
||||
// "link": "/zh/manual/larepass/sync-share"
|
||||
// },
|
||||
{
|
||||
"text": "分享文件",
|
||||
"link": "/zh/manual/olares/files/share-files"
|
||||
},
|
||||
{
|
||||
"text": "同步文件至本地",
|
||||
"link": "/zh/manual/olares/files/sync-files"
|
||||
},
|
||||
{
|
||||
"text": "挂载 SMB",
|
||||
"link": "/zh/manual/olares/files/mount-SMB"
|
||||
@@ -225,19 +263,34 @@ const side = {
|
||||
"text": "基本操作",
|
||||
"link": "/zh/manual/olares/wise/basics"
|
||||
},
|
||||
{
|
||||
/*{
|
||||
"text": "获取推荐引擎",
|
||||
"link": "/zh/manual/olares/wise/recommend"
|
||||
},
|
||||
},*/
|
||||
{
|
||||
"text": "管理订阅",
|
||||
"link": "/zh/manual/olares/wise/subscribe"
|
||||
},
|
||||
{
|
||||
"text": "整理知识",
|
||||
"link": "/zh/manual/olares/wise/filter"
|
||||
}
|
||||
]
|
||||
text: "管理 Cookie",
|
||||
link: "/zh/manual/olares/wise/manage-cookies",
|
||||
},
|
||||
{
|
||||
"text": "管理知识",
|
||||
"link": "/zh/manual/olares/wise/filter",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{
|
||||
"text": "过滤语法参考",
|
||||
"link": "/zh/manual/olares/wise/filter-syntax-guide"
|
||||
},
|
||||
{
|
||||
"text": "过滤视图示例",
|
||||
"link": "/zh/manual/olares/wise/filter-examples"
|
||||
}
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"text": "控制面板",
|
||||
@@ -271,7 +324,7 @@ const side = {
|
||||
"collapsed": true,
|
||||
"link": "/zh/manual/olares/settings/",
|
||||
"items": [
|
||||
{"text": "我的 Olares", link: "/zh/manual/olares/settings/my-olares"},
|
||||
{ "text": "我的 Olares", link: "/zh/manual/olares/settings/my-olares" },
|
||||
{
|
||||
"text": "管理用户",
|
||||
"collapsed": true,
|
||||
@@ -303,16 +356,16 @@ const side = {
|
||||
link: "/zh/manual/olares/settings/manage-app-env",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
"text": "管理集成",
|
||||
"link":"/zh/manual/olares/settings/integrations",
|
||||
},
|
||||
{
|
||||
"link": "/zh/manual/olares/settings/integrations",
|
||||
},
|
||||
{
|
||||
"text": "自定义外观",
|
||||
"link":"/zh/manual/olares/settings/language-appearance",
|
||||
},
|
||||
{text: "管理 VPN", link: "/zh/manual/olares/settings/remote-access",},
|
||||
"link": "/zh/manual/olares/settings/language-appearance",
|
||||
},
|
||||
{ text: "管理 VPN", link: "/zh/manual/olares/settings/remote-access", },
|
||||
{
|
||||
"text": "配置网络",
|
||||
"collapsed": true,
|
||||
@@ -323,29 +376,30 @@ const side = {
|
||||
},
|
||||
{
|
||||
"text": "设置 hosts 文件",
|
||||
"link":"/zh/manual/olares/settings/set-up-hosts",
|
||||
"link": "/zh/manual/olares/settings/set-up-hosts",
|
||||
},
|
||||
],
|
||||
},
|
||||
{text: "管理 GPU", link: "/zh/manual/olares/settings/gpu-resource"},
|
||||
{text: "视频设置", link: "/zh/manual/olares/settings/video"},
|
||||
},
|
||||
{ text: "管理 GPU", link: "/zh/manual/olares/settings/gpu-resource" },
|
||||
{ text: "视频设置", link: "/zh/manual/olares/settings/video" },
|
||||
{ text: "文件搜索", link: "/zh/manual/olares/settings/search" },
|
||||
{
|
||||
"text": "备份与恢复",
|
||||
"collapsed": true,
|
||||
"items": [
|
||||
{text: "备份", link: "/zh/manual/olares/settings/backup"},
|
||||
{text: "恢复", link: "/zh/manual/olares/settings/restore"},
|
||||
{ text: "备份", link: "/zh/manual/olares/settings/backup" },
|
||||
{ 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" },
|
||||
{ "text": "Profile", "link": "/zh/manual/olares/profile" }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: "Olares 进阶",
|
||||
text: "教程",
|
||||
collapsed: true,
|
||||
link: "/zh/manual/best-practices/",
|
||||
items: [
|
||||
@@ -368,11 +422,15 @@ const side = {
|
||||
{
|
||||
text: "在启用显卡直通的 PVE 上安装 Olares",
|
||||
link: "/zh/manual/best-practices/install-olares-gpu-passthrough",
|
||||
},
|
||||
{
|
||||
},
|
||||
{
|
||||
text: "在 Olares 中扩展存储空间",
|
||||
link: "/zh/manual/best-practices/expand-storage-in-olares",
|
||||
},
|
||||
{
|
||||
text: "本地访问 Olares",
|
||||
link: "/manual/best-practices/local-access",
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "术语", link: "/zh/manual/glossary" },
|
||||
@@ -425,7 +483,7 @@ const side = {
|
||||
],
|
||||
"/zh/use-cases/": [
|
||||
{
|
||||
text: "Tutorials & use cases",
|
||||
text: "应用示例",
|
||||
link: "/zh/use-cases/",
|
||||
items: [
|
||||
{
|
||||
@@ -469,12 +527,22 @@ const side = {
|
||||
},
|
||||
{
|
||||
text: "Steam",
|
||||
link: "/zh/use-cases/stream-game",
|
||||
},
|
||||
{
|
||||
text: "Redroid",
|
||||
link: "/zh/use-cases/host-cloud-android",
|
||||
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",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -484,7 +552,8 @@ const side = {
|
||||
link: "/zh/developer/concepts/",
|
||||
items: [
|
||||
{ text: "系统架构", link: "/zh/developer/concepts/system-architecture" },
|
||||
{ text: "Olares ID",
|
||||
{
|
||||
text: "Olares ID",
|
||||
link: "/zh/developer/concepts/olares-id",
|
||||
collapsed: true,
|
||||
items: [
|
||||
@@ -543,76 +612,56 @@ const side = {
|
||||
},
|
||||
{
|
||||
text: "Olares CLI",
|
||||
collapsed: true,
|
||||
link: "/zh/developer/install/cli/olares-cli",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{text: "gpu", link: "/zh/developer/install/cli/gpu"},
|
||||
{text: "osinfo", link: "/zh/developer/install/cli/osinfo"},
|
||||
{text: "node", link: "/zh/developer/install/cli/node"},
|
||||
{
|
||||
text: "backups",
|
||||
link: "/zh/developer/install/cli/backups",
|
||||
collapsed: true,
|
||||
items: [
|
||||
{text: "download", link: "/zh/developer/install/cli/backups-download"},
|
||||
{text: "region", link: "/zh/developer/install/cli/backups-region"},
|
||||
{text: "backup", link: "/zh/developer/install/cli/backups-backup"},
|
||||
{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: "download",
|
||||
link: "/zh/developer/install/cli/download",
|
||||
},
|
||||
{ text: "info", link: "/zh/developer/install/cli/info" },
|
||||
{
|
||||
text: "install",
|
||||
link: "/zh/developer/install/cli/install",
|
||||
},
|
||||
{
|
||||
text: "user activate",
|
||||
link: "/zh/developer/install/cli/user-activate",
|
||||
},
|
||||
{
|
||||
text: "logs",
|
||||
link: "/zh/developer/install/cli/logs",
|
||||
},
|
||||
{
|
||||
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: "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: "版本说明",
|
||||
link: "/zh/developer/install/versioning",
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -654,7 +703,7 @@ const side = {
|
||||
text: "OlaresManifest",
|
||||
link: "/zh/developer/develop/package/manifest",
|
||||
},
|
||||
/*/{
|
||||
/*{
|
||||
text: "推荐算法",
|
||||
link: "/zh/developer/develop/package/recommend",
|
||||
},*/
|
||||
@@ -664,66 +713,66 @@ const side = {
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// {
|
||||
// text: "进阶",
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
// {
|
||||
// text: "terminus-info",
|
||||
// link: "/zh/developer/develop/advanced/terminus-info",
|
||||
// link: "/zh/developer/develop/advanced/terminus-info",
|
||||
// },
|
||||
// {
|
||||
// text: "Service Provider",
|
||||
// link: "/zh/developer/develop/advanced/provider",
|
||||
// link: "/zh/developer/develop/advanced/provider",
|
||||
// },
|
||||
// {
|
||||
// text: "AI",
|
||||
// link: "/zh/developer/develop/advanced/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",
|
||||
// link: "/zh/developer/develop/advanced/account",
|
||||
// },
|
||||
// {
|
||||
// text: "应用市场",
|
||||
// link: "/zh/developer/develop/advanced/market",
|
||||
// link: "/zh/developer/develop/advanced/market",
|
||||
// },
|
||||
// {
|
||||
// text: "Analytic",
|
||||
// link: "/zh/developer/develop/advanced/analytic",
|
||||
// },
|
||||
// {
|
||||
// text: "Analytic",
|
||||
// link: "/zh/developer/develop/advanced/analytic",
|
||||
// },
|
||||
// {
|
||||
// text: "Websocket",
|
||||
// link: "/zh/developer/develop/advanced/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",
|
||||
// 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: "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,
|
||||
@@ -842,8 +891,8 @@ const side = {
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
],
|
||||
};
|
||||
|
||||
export const zh = defineConfig({
|
||||
lang: "zh",
|
||||
@@ -860,4 +909,4 @@ export const zh = defineConfig({
|
||||
|
||||
sidebar: side,
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -122,7 +122,7 @@ The mechanism consists of three procedures:
|
||||
|
||||
- User
|
||||
|
||||
[Manage apps in Market](../../manual/olares/market.md)<br>
|
||||
[Manage apps in Market](../../manual/olares/market/market.md)<br>
|
||||
|
||||
- Developer
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ outline: [2, 3]
|
||||
### 1. Develop and test your application
|
||||
|
||||
Before submitting an application, please ensure that it has been thoroughly tested on your Olares.
|
||||
- Use Studio's dev-container to test and debug your application in a real online environment. [Learn more about Studio](../tutorial/).
|
||||
- Use Studio's dev-container to test and debug your application in a real online environment. [Learn more about Studio](../tutorial/develop.md).
|
||||
- Use the [custom installation](../tutorial/package-upload.md) in the Market app for user testing.
|
||||
|
||||
### 2. Submit an application
|
||||
|
||||
@@ -92,13 +92,13 @@ This example demonstrates creating a basic web page manually.
|
||||
```
|
||||
5. Create a file named `index.js` in `/root/` with the following content:
|
||||
```js
|
||||
// Ensure the port matches what you defined
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('public/'));
|
||||
app.listen(8080), function() {
|
||||
console.log('Server is running on port 8080');
|
||||
};
|
||||
// Ensure the port matches what you defined
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('public/'));
|
||||
app.listen(8080, function() {
|
||||
console.log('Server is running on port 8080');
|
||||
});
|
||||
```
|
||||
6. Create a `public` directory in `/root/` and add an `index.html` file:
|
||||
```html
|
||||
@@ -204,15 +204,15 @@ Once deployed, go to **Services** > **Ports**. You can see your new port listed
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.static('public/'));
|
||||
app.listen(8080), function() {
|
||||
console.log('Server is running on port 8080');
|
||||
};
|
||||
app.listen(8080, function() {
|
||||
console.log('Server is running on port 8080');
|
||||
});
|
||||
// Add the following
|
||||
const app_new = express();
|
||||
app_new.use(express.static('new/'));
|
||||
app_new.listen(8081), function() {
|
||||
console.log('Server is running on port 8081');
|
||||
};
|
||||
app_new.listen(8081, function() {
|
||||
console.log('Server is running on port 8081');
|
||||
});
|
||||
```
|
||||
2. Create a `new` directory in `/root/` and add an `index.html` file:
|
||||
```html
|
||||
|
||||
@@ -65,7 +65,7 @@ These options apply to all backends:
|
||||
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
|
||||
```
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
```bash
|
||||
# Backup to Tencent COS
|
||||
olares-cli backups backup cos --path /data --repo-name my_repo \
|
||||
|
||||
@@ -12,7 +12,7 @@ olares-cli backups download [options]
|
||||
|--------------------|-----------|--------------------------------------------------------|-------------------------|--------------------|
|
||||
| `--download-cdn-url`| | Specifies the CDN URL for downloading the Restic tool. | No | System default URL |
|
||||
| `--help` | `-h` | Displays help information. | No | N/A |
|
||||
## Example
|
||||
## Examples
|
||||
```bash d
|
||||
# Download Restic using a custom CDN URL
|
||||
olares-cli backups download --download-cdn-url https://custom-cdn.example.com/restic
|
||||
|
||||
@@ -17,7 +17,7 @@ olares-cli backups region space [options]
|
||||
|
||||
1. To retrieve the access token and Olares DID, inspect the payload of the network requests made by the Olares Space web interface after logging in. The `token` field corresponds to the access token, and the `userid` field corresponds to the Olares DID.
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
```bash
|
||||
# Query cloud name and region ID
|
||||
olares-cli backups region space \
|
||||
|
||||
@@ -69,7 +69,7 @@ These options apply to all backends:
|
||||
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
|
||||
```
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
```bash
|
||||
# Restore the data from Tencent COS
|
||||
olares-cli backups restore cos --path /data_restore --repo-name my_repo \
|
||||
|
||||
@@ -61,7 +61,7 @@ These options apply to all backends:
|
||||
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
|
||||
```
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
```bash
|
||||
# List snapshots for Tencent COS
|
||||
olares-cli backups snapshots cos --repo-name my_repo \
|
||||
|
||||
33
docs/developer/install/cli/disk.md
Normal file
33
docs/developer/install/cli/disk.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# `disk`
|
||||
|
||||
## Synopsis
|
||||
|
||||
The `disk` command provides a set of tools to manage storage resources in the Olares system. It is specifically used for managing LVM-based storage configurations.
|
||||
|
||||
|
||||
```bash
|
||||
olares-cli disk <subcommand>
|
||||
```
|
||||
|
||||
## Subcommands
|
||||
|
||||
| Subcommand | Description |
|
||||
|--|--|
|
||||
| `extend` | Extends Olares storage capacity on LVM-based installations. |
|
||||
| `list-unmounted` | Lists unmounted disks. |
|
||||
|
||||
## Options
|
||||
|
||||
| Name | Shorthand | Usage |
|
||||
|--|--|--|
|
||||
| `--help` | `-h` | Displays help information.|
|
||||
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# List all disks that are connected but not mounted
|
||||
olares-cli disk list-unmounted
|
||||
|
||||
# Extend Olares storage by adding newly detected unmounted disks
|
||||
olares-cli disk extend
|
||||
```
|
||||
@@ -32,7 +32,7 @@ olares-cli gpu <subcommand> [options]
|
||||
| `--version`| `-v` | Specifies the Olares version for GPU drivers and components. <br>Version values follow the format `x.y.z` (e.g., `1.10.0`) or include a build date (e.g., `1.10.0-20241109`).<br> Refer to the [GitHub Releases page](https://github.com/beclab/Olares/releases) for available versions. | No | Current version |
|
||||
| `--help` | `-h` | Displays help information. | No | N/A |
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Install GPU drivers and dependencies to a specific directory
|
||||
|
||||
@@ -7,7 +7,7 @@ The `info` command displays general information about the installed Olares versi
|
||||
olares-cli info
|
||||
```
|
||||
|
||||
## Flag
|
||||
## Options
|
||||
|
||||
| Name | Shorthand | Usage |
|
||||
|----------|-----------|---------------------------|
|
||||
|
||||
@@ -28,7 +28,7 @@ olares-cli logs [option]
|
||||
| `--output-dir` | | Saves logs to the specified directory. Creates the directory if it does not exist. | No | `./olares-logs` |
|
||||
| `--since` | | Fetches logs newer than a specified relative duration (e.g., `5s`, `2m`, `3h`). | No | `7d` |
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
```bash
|
||||
# Collect all logs with default settings
|
||||
olares-cli logs
|
||||
|
||||
@@ -29,7 +29,7 @@ olares-cli node <subcommand> [options]
|
||||
| `--version` | `-v` | Specifies the Olares version. <br>Version values follow the format `x.y.z` (e.g., `1.10.0`) or include a build date (e.g., `1.10.0-20241109`).<br> Refer to the [GitHub Releases page](https://github.com/beclab/Olares/releases) for available versions. | No | Current version |
|
||||
| `--help` | `-h` | Displays help information. | No | N/A | |
|
||||
|
||||
## Example
|
||||
## Examples
|
||||
|
||||
```bash
|
||||
# Retrieve system information from a master node at IP 192.168.1.15
|
||||
|
||||
@@ -28,12 +28,13 @@ wsl -d Ubuntu
|
||||
## Syntax
|
||||
The Olares CLI uses the following syntax:
|
||||
|
||||
> `olares-cli command [subcommand] [option]`
|
||||
> `olares-cli command [subcommand] [argument] [options] `
|
||||
|
||||
where
|
||||
- `command`: Specifies the main operation you want to perform. For example, `olares-cli install`.
|
||||
- `subcommand`: Further specifies the task for commands that support additional operations. For example, `wizard` or `component`.
|
||||
- `option`: Optional arguments that modify the behavior of the `command`. Options include flags and options with arguments.
|
||||
- `argument`: Specifies the target resource or input data for the command, typically an ID, name, or file path. For example, in `olares-cli user activate <Olares ID> [options]`, `<Olares ID>` is the argument.
|
||||
- `options`: Optional arguments that modify the behavior of the `command`. Options include flags and options with arguments.
|
||||
|
||||
Olares CLI allows you to temporarily override certain Olares default settings. Each option applies only to the command in which it is used.
|
||||
|
||||
@@ -43,21 +44,23 @@ To get detailed help for any command, run `olares-cli help`.
|
||||
|
||||
## Available CLI commands
|
||||
|
||||
| Operation | Syntax | Description |
|
||||
|--------------------|----------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `gpu` | `olares-cli gpu <subcommand> [option]` | Manages GPU-related operations. |
|
||||
| `info` | `olares-cli info <subcommand> [option]` | Displays general information about the operating system of the current device. |
|
||||
| `node` | `olares-cli node <subcommand> [option]` | Manages node-related operations. |
|
||||
| `backups` | `olares-cli backups <subcommand> [option]` | Manages backup-related operations. |
|
||||
| `change-ip` | `olares-cli change-ip [option]` | Changes the IP address of the Olares OS. |
|
||||
| `download` | `olares-cli download <subcommand> [option]` | Downloads specific resources. |
|
||||
| `info` | `olares-cli info [option]` | Displays general information about the downloaded Olares OS. |
|
||||
| `install` | `olares-cli install [option]` | Deploys system-level and user-level components of Olares. |
|
||||
| `logs` | `olares-cli logs [option]` | Collects logs from Olares system components for debugging and troubleshooting. |
|
||||
| `precheck` | `olares-cli precheck [option]` | Verifies whether the system environment meets all requirements for Olares installation. |
|
||||
| `prepare` | `olares-cli prepare [option]` | Prepares the environment for the installation process, including setting up essential services and configurations of Olares. |
|
||||
| `release` | `olares-cli release [option]` | Packages Olares installation resources for distribution or deployment. |
|
||||
| `start` | `olares-cli start [option]` | Starts Olares services and components. |
|
||||
| `stop` | `olares-cli stop [option]` | Stops Olares services and components. |
|
||||
| `uninstall` | `olares-cli uninstall [option]` | Uninstalls Olares completely, or roll back the installation to a specific phase. |
|
||||
|
||||
| Operation | Syntax | Description |
|
||||
|--|--|--|
|
||||
| `backups` | `olares-cli backups <subcommand> [options]` | Manages backup-related operations. |
|
||||
| `change-ip` | `olares-cli change-ip [options]` | Changes the IP address of the Olares OS. |
|
||||
| `disk` | `olares-cli disk <subcommand>` | Manages storage resources in the Olares system. |
|
||||
| `download` | `olares-cli download <subcommand> [options]` | Downloads specific resources. |
|
||||
| `gpu` | `olares-cli gpu <subcommand> [options]` | Manages GPU-related operations. |
|
||||
| `info` | `olares-cli info [options]` | Displays general information about the downloaded Olares OS. |
|
||||
| `install` | `olares-cli install [options]` | Deploys system-level and user-level components of Olares. |
|
||||
| `logs` | `olares-cli logs [options]` | Collects logs from Olares system components for debugging and troubleshooting. |
|
||||
| `node` | `olares-cli node <subcommand> [options]` | Manages node-related operations. |
|
||||
| `osinfo` | `olares-cli osinfo <subcommand> [options]` | Displays general information about the operating system of the current device. |
|
||||
| `precheck` | `olares-cli precheck [options]` | Verifies whether the system environment meets all requirements for Olares installation. |
|
||||
| `prepare` | `olares-cli prepare [options]` | Prepares the environment for the installation process, including setting up essential services and configurations of Olares. |
|
||||
| `release` | `olares-cli release [options]` | Packages Olares installation resources for distribution or deployment. |
|
||||
| `start` | `olares-cli start [options]` | Starts Olares services and components. |
|
||||
| `stop` | `olares-cli stop [options]` | Stops Olares services and components. |
|
||||
| `uninstall` | `olares-cli uninstall [options]` | Uninstalls Olares completely, or roll back the installation to a specific phase. |
|
||||
| `upgrade` | `olares-cli upgrade <subcommand> [options]` | Upgrades Olares and checks upgrade readiness and compatibility.|
|
||||
| `user` | `olares-cli user <subcommand> [options]`| Manages users in the Olares system |
|
||||
@@ -8,13 +8,13 @@ The `osinfo` command provides detailed information about the operating system of
|
||||
olares-cli osinfo <subcommand> [options]
|
||||
```
|
||||
|
||||
## Subcommand
|
||||
## Subcommands
|
||||
|
||||
| Subcommand | Description |
|
||||
|------------|----------------------------------------------------------------------|
|
||||
| `show` | Prints information about the operating system of the current device. |
|
||||
|
||||
## Flag
|
||||
## Options
|
||||
|
||||
| Name | Short | Description |
|
||||
|--------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user