Compare commits
183 Commits
cli/fix/up
...
fix/sync_b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d8fca10fb | ||
|
|
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 | ||
|
|
473898a715 | ||
|
|
637b1839f7 | ||
|
|
1f1c1a8d3b | ||
|
|
1ddcc3bd4c | ||
|
|
96a2eb524a | ||
|
|
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/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
@@ -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: |
|
||||
|
||||
@@ -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.6.42
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -5,17 +5,18 @@ import (
|
||||
"compress/gzip"
|
||||
"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"
|
||||
|
||||
"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 +243,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()
|
||||
|
||||
@@ -375,43 +375,27 @@ 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(),
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
resourceTypes := []string{"node", "pod", "statefulset", "deployment", "replicaset", "service", "configmap"}
|
||||
|
||||
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(),
|
||||
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 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 == 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`),
|
||||
))
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -250,13 +250,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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.4
|
||||
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.4 h1:S5nUHLu2zhpA8YuR/Ue/vXPiY6ynPECkpDXjYV+Ckj4=
|
||||
github.com/eball/zeroconf v0.2.4/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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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,7 +6,7 @@ const side = {
|
||||
text: "What is Olares",
|
||||
link: "/manual/overview",
|
||||
items: [
|
||||
{ text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
|
||||
// { text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
|
||||
{ text: "Help and support", link: "/manual/help/request-technical-support"}
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
@@ -127,9 +127,9 @@ 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"},
|
||||
@@ -137,29 +137,29 @@ const side = {
|
||||
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 +168,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 +195,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 +249,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 +345,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,18 +365,19 @@ 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 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"},
|
||||
@@ -346,33 +387,33 @@ const side = {
|
||||
{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: "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",
|
||||
link: "/manual/best-practices/expand-storage-in-olares",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{ text: "Glossary", link: "/manual/glossary" },
|
||||
],
|
||||
"/space/": [
|
||||
@@ -421,83 +462,94 @@ 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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"/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 +586,7 @@ const side = {
|
||||
{ text: "Secrets", link: "/developer/concepts/secrets" },
|
||||
],
|
||||
},
|
||||
{
|
||||
{
|
||||
text: "Installation deep-dive",
|
||||
link: "/developer/install/",
|
||||
items: [
|
||||
@@ -567,12 +619,12 @@ const side = {
|
||||
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: "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: "change-ip",
|
||||
@@ -621,12 +673,12 @@ const side = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares versioning",
|
||||
link: "/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Olares versioning",
|
||||
link: "/developer/install/versioning",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: "Develop Olares apps",
|
||||
link: "/developer/develop/",
|
||||
@@ -682,43 +734,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 +808,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",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -8,7 +8,7 @@ const side = {
|
||||
items: [
|
||||
// { text: "应用场景", link: "/zh/manual/why-olares" },
|
||||
//{ text: "功能对比", link: "/zh/manual/feature-overview" },
|
||||
{ text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
|
||||
// { text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
|
||||
{text: "帮助与支持", link: "/zh/manual/help/request-technical-support",}
|
||||
// collapsed: true,
|
||||
// items: [
|
||||
@@ -157,10 +157,10 @@ const side = {
|
||||
{text: "双重验证", link: "/zh/manual/larepass/two-factor-verification"},
|
||||
],
|
||||
},
|
||||
{
|
||||
/*{
|
||||
text: "管理内容",
|
||||
link: "/zh/manual/larepass/manage-knowledge",
|
||||
},
|
||||
},*/
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -169,7 +169,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,
|
||||
@@ -183,6 +200,14 @@ const side = {
|
||||
// "text": "同步与共享",
|
||||
// "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 +250,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": "控制面板",
|
||||
@@ -329,6 +369,7 @@ const side = {
|
||||
},
|
||||
{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,
|
||||
@@ -425,7 +466,7 @@ const side = {
|
||||
],
|
||||
"/zh/use-cases/": [
|
||||
{
|
||||
text: "Tutorials & use cases",
|
||||
text: "应用示例",
|
||||
link: "/zh/use-cases/",
|
||||
items: [
|
||||
{
|
||||
@@ -469,12 +510,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",
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -9,7 +9,33 @@ You can use Docker to install and run Olares in a containerized environment. Thi
|
||||
For best performance and stability, we recommend [installing Olares on Linux via script](/manual/get-started/install-olares.md).
|
||||
:::
|
||||
|
||||
<!--@include: ./reusables.md{52,65}-->
|
||||
## System requirements
|
||||
|
||||
Make sure your device meets the following requirements.
|
||||
|
||||
### Required specifications
|
||||
|
||||
- **CPU**: At least 4 cores.
|
||||
- **RAM**: At least 8 GB of available memory.
|
||||
- **Storage**: At least 150 GB of available SSD storage.
|
||||
:::warning SSD required
|
||||
The installation will fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- **Supported systems**:
|
||||
- Ubuntu 22.04-25.04 LTS
|
||||
- Debian 12 or 13
|
||||
|
||||
:::info Version compatibility
|
||||
While these specific versions are confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
|
||||
:::
|
||||
|
||||
### Optional hardware
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- **GPU (NVIDIA only)**:
|
||||
- **Architecture**: Turing or newer (e.g., GTX 16 series, RTX 20 series).
|
||||
- **Verification**: Run `lspci | grep -i nvidia` and check the [compatible GPU table](https://github.com/NVIDIA/open-gpu-kernel-modules?tab=readme-ov-file#compatible-gpus).
|
||||
|
||||
## Before you begin
|
||||
Before you begin, ensure the following:
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Install Olares on a physical machine using the official ISO image, including system requirements, installation steps, and activation process.
|
||||
---
|
||||
|
||||
@@ -10,6 +11,7 @@ This guide explains how to install Olares on a physical machine using the offici
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Required
|
||||
- **Host requirements**:
|
||||
- **CPU**: Minimum 4 cores with **x86-64 architecture** (Intel or AMD). ARM-based processors are not currently supported for this method.
|
||||
- **Memory**: At least 8 GB of available RAM.
|
||||
@@ -19,7 +21,15 @@ This guide explains how to install Olares on a physical machine using the offici
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
|
||||
- **Other**: A USB flash drive with at least **8 GB** capacity.
|
||||
- **USB flash drive**: **8 GB** capacity or larger.
|
||||
|
||||
### Optional
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- **GPU (NVIDIA only)**:
|
||||
- **Architecture**: Turing or newer (e.g., GTX 16 series, RTX 20 series).
|
||||
- **Verification**: Run `lspci | grep -i nvidia` and check the [compatible GPU table](https://github.com/NVIDIA/open-gpu-kernel-modules?tab=readme-ov-file#compatible-gpus).
|
||||
|
||||
## Create a bootable USB drive
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Detailed instructions for installing Olares on Linux systems including Ubuntu and Debian. Covers system requirements, installation steps, and activation process.
|
||||
---
|
||||
# Install Olares on Linux via the script
|
||||
@@ -6,7 +7,33 @@ This guide explains how to install Olares on Linux using the provided installati
|
||||
|
||||
<!--@include: ./reusables.md{44,51}-->
|
||||
|
||||
<!--@include: ./reusables.md{52,65}-->
|
||||
## System requirements
|
||||
|
||||
Make sure your device meets the following requirements.
|
||||
|
||||
### Required specifications
|
||||
|
||||
- **CPU**: At least 4 cores.
|
||||
- **RAM**: At least 8 GB of available memory.
|
||||
- **Storage**: At least 150 GB of available SSD storage.
|
||||
:::warning SSD required
|
||||
The installation will fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- **Supported systems**:
|
||||
- Ubuntu 22.04-25.04 LTS
|
||||
- Debian 12 or 13
|
||||
|
||||
:::info Version compatibility
|
||||
While these specific versions are confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
|
||||
:::
|
||||
|
||||
### Optional hardware
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- **GPU (NVIDIA only)**:
|
||||
- **Architecture**: Turing or newer (e.g., GTX 16 series, RTX 20 series).
|
||||
- **Verification**: Run `lspci | grep -i nvidia` and check the [compatible GPU table](https://github.com/NVIDIA/open-gpu-kernel-modules?tab=readme-ov-file#compatible-gpus).
|
||||
|
||||
## Install Olares
|
||||
|
||||
|
||||
@@ -12,21 +12,31 @@ Currently, Olares on LXC has certain limitations. We recommend using it only for
|
||||
|
||||
## System requirements
|
||||
Make sure your device meets the following requirements.
|
||||
|
||||
### Required specifications
|
||||
- CPU: At least 4 cores
|
||||
- RAM: At least 8GB of available memory
|
||||
- Storage: At least 150GB of available SSD storage.
|
||||
- RAM: At least 8 GB of available memory
|
||||
- Storage: At least 150 GB of available SSD storage.
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- Supported systems:
|
||||
- PVE 8.2.2
|
||||
- Linux container: Debian 12 (for existing LXC containers on PVE)
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
|
||||
|
||||
:::info Version compatibility
|
||||
While the specific versions are confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
|
||||
:::
|
||||
|
||||
### Optional hardware
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- GPU (NVIDIA only):
|
||||
- Architecture: Turing or newer (e.g., GTX 16 series, RTX 20 series, and later).
|
||||
- Verification: Run `lspci | grep -i nvidia` in the PVE host shell to confirm the card is detected.
|
||||
- Setup: To utilize the GPU, you must configure LXC device passthrough. Please refer to [Configure GPU passthrough in PVE](/manual/best-practices/install-olares-gpu-passthrough.md#configure-gpu-passthrough-in-pve) for detailed instructions.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Working directories for storing images and packages on the PVE host. You can set it using the following command:
|
||||
|
||||
@@ -20,11 +20,14 @@ Make sure your device meets the following requirements.
|
||||
|
||||
- Architecture: AMD64 or ARM64
|
||||
- CPU: At least 4 cores
|
||||
- RAM: At least 8GB of available memory
|
||||
- Storage: At least 150GB of available SSD storage.
|
||||
- RAM: At least 8 GB of available memory
|
||||
- Storage: At least 150 GB of available SSD storage.
|
||||
::: warning SSD required
|
||||
The installation will fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
::: info GPU limitation
|
||||
Olares GPU acceleration currently supports NVIDIA GPUs only. Consequently, GPU resources cannot be managed or utilized for AI workloads on macOS devices.
|
||||
:::
|
||||
|
||||
## Before you begin
|
||||
Before you begin, ensure the following:
|
||||
|
||||
@@ -16,12 +16,16 @@ We recommend using it only for development or testing purposes.
|
||||
|
||||
## System compatibility
|
||||
Make sure your Mac meets the following requirements.
|
||||
- Architecture: X86-64 or ARM64
|
||||
- RAM: 8 GB or above (available memory)
|
||||
- Storage: 150 GB or above of available space on SSD
|
||||
- MacOS: Monterey (12) or later
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
- Architecture: X86-64 or ARM64.
|
||||
- RAM: At least 8 GB of available memory.
|
||||
- Storage: At least 150 GB of available SSD storage.
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- MacOS: Monterey (12) or later.
|
||||
|
||||
::: info GPU limitation
|
||||
Olares GPU acceleration currently supports NVIDIA GPUs only. Consequently, GPU resources cannot be managed or utilized for AI workloads on macOS devices.
|
||||
:::
|
||||
|
||||
## Before you begin
|
||||
|
||||
@@ -12,12 +12,24 @@ Currently, Olares on PVE has certain limitations. We recommend using it only for
|
||||
|
||||
## System requirements
|
||||
Make sure your device meets the following requirements.
|
||||
|
||||
**CPU**: Minimum 4 cores with **x86-64 architecture** (Intel or AMD). ARM-based processors are not currently supported for this method.
|
||||
- RAM: At least 8GB of available memory
|
||||
- Storage: At least 200GB of available SSD storage. The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
### Required specifications
|
||||
- CPU: Minimum 4 cores with x86-64 architecture (Intel or AMD). ARM-based processors are not currently supported for this method.
|
||||
- RAM: At least 8 GB of available memory
|
||||
- Storage: At least 200 GB of available SSD storage.
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- Supported Systems: PVE 8.2.2
|
||||
|
||||
### Optional hardware
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- GPU (NVIDIA only):
|
||||
- Architecture: Turing or newer (e.g., GTX 16 series, RTX 20 series, and later).
|
||||
- Verification: Run `lspci | grep -i nvidia` in the PVE host shell to confirm the card is detected.
|
||||
- Setup: To utilize the GPU, you must configure PCI passthrough. Please refer to [Configure GPU passthrough in PVE](/manual/best-practices/install-olares-gpu-passthrough.md#configure-gpu-passthrough-in-pve) for detailed instructions.
|
||||
|
||||
## Download Olares ISO image
|
||||
Click [here](https://cdn.olares.com/olares-latest-amd64.iso) to download the official Olares ISO image.
|
||||
|
||||
|
||||
@@ -13,19 +13,28 @@ Currently, Olares on PVE has certain limitations. We recommend using it only for
|
||||
## System requirements
|
||||
Make sure your device meets the following requirements.
|
||||
|
||||
### Required specifications
|
||||
- CPU: At least 4 cores
|
||||
- RAM: At least 8GB of available memory
|
||||
- Storage: At least 150GB of available SSD storage.
|
||||
- RAM: At least 8 GB of available memory
|
||||
- Storage: At least 150 GB of available SSD storage.
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- Supported Systems: PVE 8.2.2
|
||||
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
|
||||
:::info Version compatibility
|
||||
While the specific version is confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
|
||||
:::
|
||||
|
||||
### Optional hardware
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- GPU (NVIDIA only):
|
||||
- Architecture: Turing or newer (e.g., GTX 16 series, RTX 20 series, and later).
|
||||
- Verification: Run `lspci | grep -i nvidia` in the PVE host shell to confirm the card is detected.
|
||||
- Setup: To utilize the GPU, you must configure PCI passthrough. Please refer to [Configure GPU passthrough in PVE](/manual/best-practices/install-olares-gpu-passthrough.md#configure-gpu-passthrough-in-pve) for detailed instructions.
|
||||
|
||||
## Install on PVE
|
||||
|
||||
In PVE CLI, run the following command:
|
||||
|
||||
@@ -14,10 +14,12 @@ Make sure your Raspbian device meets the following requirements.
|
||||
- Hardware: Raspberry Pi 4B or Raspberry Pi 5 with 8GB memory
|
||||
- Operating system: Raspbian 12
|
||||
- Storage: At least 150GB of available SSD storage.
|
||||
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
::: info GPU limitation
|
||||
Olares GPU acceleration currently supports NVIDIA GPUs only. Consequently, GPU resources cannot be managed or utilized for AI workloads on macOS devices.
|
||||
:::
|
||||
|
||||
## Set up system environment
|
||||
1. Configure the Raspbian environment to enable necessary features:
|
||||
|
||||
@@ -17,15 +17,27 @@ We recommend using it only for development or testing purposes.
|
||||
|
||||
## System compatibility
|
||||
Make sure your Windows meets the following requirements.
|
||||
### Required specifications
|
||||
- CPU: At least 4 cores
|
||||
- RAM: At least 16GB of available memory
|
||||
- Storage: At least 150GB of available SSD storage.
|
||||
- RAM: At least 16 GB of available memory
|
||||
- Storage: At least 150 GB of available SSD storage.
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
- Supported systems:
|
||||
- Windows 10 or 11
|
||||
- Linux (on WSL 2): Ubuntu 22.04 LTS or later; Debian 12 or later
|
||||
::: warning SSD required
|
||||
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
|
||||
:::
|
||||
|
||||
### Optional hardware
|
||||
|
||||
A GPU is not required to install Olares, but is necessary for AI applications.
|
||||
|
||||
- **GPU (NVIDIA only)**:
|
||||
- Architecture: Turing or newer (e.g., GTX 16 series, RTX 20 series, and later).
|
||||
- Verification:
|
||||
1. Open **Task Manager > Performance** to confirm your GPU model (must be NVIDIA).
|
||||
2. Run `nvidia-smi` inside your WSL terminal to confirm the driver is accessible.
|
||||
|
||||
## Set up system environment
|
||||
1. Enable the required Windows features for virtualization.
|
||||
|
||||
|
||||
@@ -62,4 +62,47 @@ Make sure your device meets the following requirements.
|
||||
|
||||
:::info Version compatibility
|
||||
While these specific versions are confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
|
||||
:::
|
||||
:::
|
||||
<!--Sync files, reused in LarePass > Manage files-->
|
||||
## Sync files to local computer
|
||||
|
||||
With LarePass desktop, you can sync cloud files (organized by libraries or folders) to your local computer. This creates a corresponding folder on your machine. After set up, your files will stay updated bi-directionally in real time.
|
||||
|
||||
:::tip Note
|
||||
The **Sync to local** feature is only available for libraries or folders within the **Sync** directory.
|
||||
:::
|
||||
|
||||
### Create a library
|
||||
|
||||
Library is the fundamental unit for organizing, syncing, and sharing your digital content. Each user is automatically provided with their own personal library (My Library) as a starting point.
|
||||
|
||||
To create a new library:
|
||||
|
||||
1. To the right of **Sync**, click <i class="material-symbols-outlined">add_circle</i> to open the **New library** dialog.
|
||||
|
||||
{width=55%}
|
||||
|
||||
2. Enter a name for the library and click **Create**.
|
||||
|
||||
### Enable synchronization
|
||||
|
||||
To enable sync for a library or folder:
|
||||
|
||||
1. Open LarePass desktop and locate the **Sync** directory.
|
||||
2. Hover your mouse over the target library or folder, click <i class="material-symbols-outlined">more_horiz</i> that appears on the right, and then click **Sync to local**.
|
||||
|
||||
{width=58%}
|
||||
|
||||
3. In the **Sync library** popup window, set the file download location, and then click **Confirm**.
|
||||
|
||||
Syncing will begin immediately. Once completed, a green checkmark will appear on the bottom-left corner of the folder icon, indicating that the sync is finished.
|
||||
|
||||
### Manage synchronization
|
||||
|
||||
After setting up synchronization, you can manage your files and control the sync status with the following operations:
|
||||
|
||||
- If you want to quickly locate the sync directory on your local drive, hover your mouse over the target library or folder, click <i class="material-symbols-outlined">more_horiz</i> that appears on the right, and then click **Open local sync folder**. The system will directly open the folder's location on your computer.
|
||||
|
||||
- If you no longer need to sync a folder, hover your mouse over it, click <i class="material-symbols-outlined">more_horiz</i> that appears on the right, and then click **Unsychronize**.
|
||||
|
||||
- If you want to temporarily stop data transfer, click <i class="material-symbols-outlined">pause_circle</i> to the right of the **Sync** directory. All sync tasks will be paused.
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn essential file operations in Larepass including adding new files, editing existing content, and downloading files across different devices.
|
||||
---
|
||||
# Common file operations on LarePass
|
||||
@@ -72,6 +73,8 @@ You can view, pause, or cancel the download tasks in **Transfer** > **Download**
|
||||
</template>
|
||||
</Tabs>
|
||||
|
||||
<!--@include: ../get-started/reusables.md{67,108}-->
|
||||
|
||||
## Delete files
|
||||
:::warning
|
||||
Deleted files cannot be recovered.
|
||||
|
||||
@@ -54,12 +54,19 @@ To install a system update:
|
||||
2. On the **System update** page, confirm the available version in the **New version** field, then click **Upgrade**.
|
||||

|
||||
|
||||
3. In the pop-up dialog, choose your upgrade method and tap **Confirm**:
|
||||
- **Download only**: Olares will only download the update package. After the download completes, click **Upgrade** on the **System update** page to start the installation. You can continue using Olares during the download process.
|
||||
- **Download and upgrade**: Olares will immediately download and install the update package. The system will be temporarily unavailable during the upgrade process.
|
||||

|
||||
3. In the pop-up dialog, select how you want to upgrade:
|
||||
|
||||
4. Wait for the upgrade to finish. You will see a success message, and Olares will automatically resume normal operation.
|
||||
- **Download only**<br>
|
||||
Olares downloads the update package in the background while you continue using the system.
|
||||
|
||||
- **Download and upgrade**<br>
|
||||
Olares downloads the update package and will install it after you confirm a restart.
|
||||
|
||||

|
||||
|
||||
4. If you selected **Download only**, click **Upgrade now** on the **System update** page to initiate the process.
|
||||
5. If you selected **Download and upgrade**, confirm the restart when prompted to begin installation.
|
||||
6. Wait for the upgrade and restart to finish. When Olares starts up again, you'll see a success message and can continue using it.
|
||||
|
||||
### Restart or shut down Olares remotely
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ From the Launchpad, you can:
|
||||
Built-in system applications such as Files, Market, and Profile cannot be uninstalled.
|
||||
:::
|
||||
|
||||
|
||||
### Controll application windows
|
||||
### Control application windows
|
||||
|
||||
You can access applications via two modes.
|
||||
|
||||
@@ -53,20 +52,26 @@ Some applications only support opening in a tabbed view.
|
||||
|
||||
## Search within Olares
|
||||
|
||||
You can quickly call out global search using one of the following methods:
|
||||
You can quickly open global search using one of the following methods:
|
||||
|
||||
* Press the keyboard shortcut: `Shift + Space`
|
||||
* Click the "Search" icon in the Dock.
|
||||
- Press the keyboard shortcut: `Shift + Space`
|
||||
- Click the <i class="material-symbols-outlined">search</i> icon in the Dock.
|
||||
|
||||
Global search can find applications, files, and other supported search targets.
|
||||
|
||||
| Search target | Supported actions |
|
||||
|:--------------------------------------------|:----------------------------------------------------------|
|
||||
| Installed Applications | Open the application directly. |
|
||||
| Documents directory in File Manager Storage | Search by filename or full-text content. |
|
||||
| Other directories in File Manager Storage | Search by filename only. |
|
||||
| File Manager Synced Drive | Search by filename only. |
|
||||
| Wise Reader Content | Search full-text content of RSS feeds, web pages, & PDFs. |
|
||||
| **More** | |
|
||||
| Settings | Adjust Olares appearance. |
|
||||
| Applications | Install, uninstall, or update applications. |
|
||||
| Supported search target | Supported search capability |
|
||||
|:--|:--|
|
||||
| Applications (built-in and installed) | Search by application name and open the app directly.|
|
||||
| Directories enabled for full-text search | Search files by filename and by text content inside <br>supported documents. |
|
||||
| Other directories in File manager storage | Search files by filename only. |
|
||||
| Team shared files | Search shared files by filename only. |
|
||||
| File manager synced drive | Search synced files by filename only. |
|
||||
| Wise reader content | Search RSS feeds, web pages, and PDFs by name. |
|
||||
|
||||
### Configure file search rules
|
||||
|
||||
By default, global search searches files by filename only.
|
||||
|
||||
To improve search efficiency or enable searching file contents, go to **Settings** > **Search** > **File Search** to configure full-text search and exclusion rules.
|
||||
|
||||
For details, see [Configure file search](/manual/olares/settings/search.md).
|
||||
@@ -1,8 +1,9 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn essential file operations in Olares including adding new files, editing existing content, and downloading files across different devices.
|
||||
---
|
||||
# Basic file operations
|
||||
Operations in Fileare essentially the same as in other file managers. This page will introduce some common tasks in Files to get you started.
|
||||
Operations in Files are essentially the same as in other file managers. This page will introduce some common tasks in Files to get you started.
|
||||
|
||||
## Upload files
|
||||
|
||||
@@ -72,16 +73,28 @@ When downloading multiple files, the behavior differs between the Files in Olare
|
||||
3. Select the save location in the popup window.
|
||||
|
||||
## Preview and edit files
|
||||
Double-click a file to open its preview. The Files app supports previewing the following file formats:
|
||||
|
||||
* **Images**: JPG, JPEG, PNG, BMP, WEBP, SVG
|
||||
* **Videos**: MP4, MKV, AVI, MOV, MPEG, MTS, TS, WMV, WEBM, RM, 3GP
|
||||
* **Audio**: MP3, WMA, WAV, OGG, AAC, M4A, APE, FLAC
|
||||
* **Text**: PDF, TXT, JS, CSS, XML, YAML, HTML
|
||||
### Supported formats
|
||||
|
||||
The Files app also supports editing the following text formats: TXT, JS, CSS, XML, YAML, HTML.
|
||||
The Files app supports the following file formats for previewing and editing:
|
||||
- Preview:
|
||||
* Images: JPG, JPEG, PNG, BMP, WEBP, SVG
|
||||
* Videos: MP4, MKV, MOV, MPEG, MTS, WMV, WEBM, RM, 3GP
|
||||
* Audio: MP3, WMA, WAV, OGG, AAC, M4A, APE, FLAC
|
||||
* Text: PDF, TXT, JS, CSS, XML, YAML, HTML
|
||||
- Edit:
|
||||
* TXT, JS, CSS, XML, YAML, HTML
|
||||
|
||||
### Procedure
|
||||
|
||||
- To preview a file, double-click the target file.
|
||||
- To edit a file:
|
||||
1. Double-click a supported text file.
|
||||
2. Click <i class="material-symbols-outlined">edit_square</i> in the top-right corner.
|
||||
3. Modify the content, and then save your changes by clicking <i class="material-symbols-outlined">save</i>.
|
||||
|
||||

|
||||
|
||||

|
||||
## Search files
|
||||
You can easily find files in the Files app using desktop search.
|
||||
:::tip
|
||||
|
||||
@@ -10,15 +10,18 @@ Olares's built-in Files app offers users a secure and efficient solution for fil
|
||||
* **Centralized storage**: Simplifies information retrieval and integration, making it easier to access, manage, and update your data, whether personal documents or team-shared materials.
|
||||
|
||||
## Understand the interface
|
||||
|
||||
The interface is similar to Windows Explorer or macOS Finder, allowing you to organize and access documents, images, videos, or any other files you own.
|
||||
|
||||

|
||||

|
||||
|
||||
It consists of three main components:
|
||||
It mainly consists of the following components:
|
||||
|
||||
* **Drive**: Stores personal files that don’t require constant synchronization or frequent edits. Each user has a Home directory with default folders such as Documents, Pictures, Videos, and Downloads. External storage (e.g., USB drives or SMB shares) appears under External.
|
||||
* **Sync**: A library-based high-efficiency storage area providing file synchronization services. You can create multiple independent libraries, each serving as a separate file entry point (similar to an independent cloud drive). Ideal for storing files and data requiring frequent modifications, real-time cross-device synchronization, or team collaboration.
|
||||
* **Application**: Reserved for application-specific data. Primarily for development and debugging, not general file storage.
|
||||
* **Cloud storage**: Connected through [Integrations](../../larepass/integrations.md), including Google Drive, AWS S3, and Tencent Cloud Object Storage (COS). These allow you to link, access, and manage remote files directly from Olares.
|
||||
* **Share**: The centralized hub for managing all shared folders, including Internal shares, SMB shares, and Public shares, allowing you to monitor sharing status, adjust permissions, or cancel shares in one place.
|
||||
|
||||
---
|
||||
<div>
|
||||
|
||||
146
docs/manual/olares/files/share-files.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: A comprehensive guide to sharing files in Olares using Internal, Public, and SMB methods. Learn how to configure access permissions, manage shared content, and facilitate secure collaboration within your team or via LAN.
|
||||
---
|
||||
|
||||
# Share files
|
||||
|
||||
This feature supports sharing folders with internal members or external users through different methods. You can flexibly set access permissions, passwords, and expiration dates, and manage or cancel these shares at any time.
|
||||
|
||||
## Share types and support scope
|
||||
|
||||
Currently, file sharing is only supported at the **folder** level. Supported sharing types vary depending on the directory location of the folder. Refer to the following table for details:
|
||||
|
||||
| Directory type | Public share | Internal share | SMB share |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| **Home** | Supported | Supported | Supported |
|
||||
| **External** | - | Supported | Supported |
|
||||
| **Sync** | - | Supported | - |
|
||||
| **Data** | Supported | Supported | Supported |
|
||||
| **Cache** | - | Supported | Supported |
|
||||
|
||||
Where,
|
||||
- **Public share**: Generates an access link with password protection supported, suitable for external sharing.
|
||||
- **Internal share**: Restricted to members within the same Olares cluster, suitable for internal team collaboration. For more information, see [Manage your team](../settings/manage-team.md).
|
||||
- **SMB share**: Shared via the SMB protocol within the Local Area Network (LAN).
|
||||
|
||||

|
||||
|
||||
## User permissions
|
||||
|
||||
You can assign specific permissions to members in **Internal share** and **SMB share** to control their level of access and allowed operations.
|
||||
|
||||
| Permission | Description |
|
||||
| :--- | :--- |
|
||||
| **Admin** | The user has the full access, including:<ul><li>Add, view, edit, and delete files.</li><li>Invite and remove members.</li> <li>Modify share settings.</li></ul> |
|
||||
| **Edit** | The user can add, view, modify, and delete files. |
|
||||
| **View** | The user can only open, view, and download files. They cannot upload, modify, or <br>delete any content. |
|
||||
|
||||
## Create share
|
||||
|
||||
### Create Internal share
|
||||
|
||||
1. Right-click the target folder,and then click **Internal share**.
|
||||
2. In the **Invite users** section, click <i class="material-symbols-outlined">add</i>, search for and select the target user or group, and then click **Invite**.
|
||||
|
||||
{width=60%}
|
||||
|
||||
3. In the **Set user permissions** list, click <i class="material-symbols-outlined">chevron_forward</i> to the right of the user avatar to assign specific permissions, and then click **Submit**.
|
||||
4. Click **Confirm**.
|
||||
|
||||
### Create SMB share
|
||||
|
||||
SMB sharing utilizes a dedicated local Linux account system. The SMB accounts generated within this system are independent of Olares members, strictly for LAN file access.
|
||||
|
||||
1. Right-click the target folder, and then click **SMB share**.
|
||||
2. Select whether to make it **Public**.
|
||||
- If you selected **Yes**, click **Confirm**, and then it will be accessible to anyone on the LAN.
|
||||
- If you selected **No**, authentication is required. You must select or create a dedicated SMB account by using Step3 or Step4.
|
||||
3. Select an existing SMB account to authorize.
|
||||
|
||||
a. In the **Invite users** field, click <i class="material-symbols-outlined">add</i>.
|
||||
|
||||
{width=60%}
|
||||
|
||||
b. Search for the SMB account, select it, and then click **Invite**.
|
||||
|
||||
c. In the **Set user permissions** list, click <i class="material-symbols-outlined">chevron_forward</i> to the right of the user avatar to assign specific permissions, and then click **Submit**.
|
||||
|
||||
d. Click **Confirm**.
|
||||
|
||||
4. Create a new SMB account to authorize.
|
||||
|
||||
a. To the right of **Invite users**, click **Add user accounts**.
|
||||
|
||||
{width=60%}
|
||||
|
||||
b. Enter a unique user name.
|
||||
|
||||
c. In the **Set password** field, a secure system-generated password is provided by default. You can also manually enter a new password or click **Regenerate** to create a new random one.
|
||||
|
||||
d. Click **Confirm**. The system will automatically generate this account for you.
|
||||
|
||||
e. In the **Invite users** field, click <i class="material-symbols-outlined">add</i>.
|
||||
|
||||
f. Search for the newly created account, select it, and then click **Invite**.
|
||||
|
||||
g. In the **Set user permissions** list, click <i class="material-symbols-outlined">chevron_forward</i> to the right of the user avatar to assign specific permissions, and then click **Submit**.
|
||||
|
||||
h. Click **Confirm**.
|
||||
|
||||
### Create Public share
|
||||
|
||||
1. Right-click the target folder, and then click **Public share**.
|
||||
|
||||
{width=56%}
|
||||
|
||||
2. In the **Set password** field, a secure system-generated password is provided by default. You can also manually enter a new password or click **Regenerate** to create a new random one.
|
||||
3. In the **Set expiration** region, select the specific expiration time for the share link.
|
||||
4. Select the following restrictions as needed:
|
||||
- **Limit file size**: To limit the size of files uploaded by visitors, select this checkbox, enter a value, and then select the unit (Mi/Gi/Ti).
|
||||
- **Allow uploads only**: If you select this checkbox, visitors can only upload files and cannot view or download existing content.
|
||||
5. Click **Confirm** to generate the link.
|
||||
6. Copy or note down the link address, and then click **Confirm**.
|
||||
|
||||
## Manage shares
|
||||
|
||||
You can view and manage all shared folders in the **Share** list.
|
||||
|
||||
### View share list and attributes
|
||||
|
||||
1. Open the Files application from the Dock or Launchpad on Olares.
|
||||
2. Click **Share** in the left sidebar.
|
||||
2. You can view the list of all currently shared folders on the right.
|
||||
3. If you want to view the details of a specific folder, right-click the target folder and click **Attributes**.
|
||||
|
||||
You will see the sharer, current path, original path, share scope, owner, current permissions, expiration date, and link details.
|
||||
|
||||
### Modify password or permissions
|
||||
|
||||
For shared folders, you can change their password and permission settings at any time.
|
||||
|
||||
1. Open the Files application from the Dock or Launchpad on Olares.
|
||||
2. Click **Share** in the left sidebar to view the **Share** list on the right.
|
||||
3. To reset password (**Public share** only):
|
||||
|
||||
a. Right-click the folder and select **Reset Password**.
|
||||
|
||||
b. Enter a new password or click **Regenerate**.
|
||||
|
||||
c. Click **Confirm**.
|
||||
4. To edit permissions (**Internal share** and **SMB share** only):
|
||||
|
||||
a. Right-click the folder and select **Edit permissions**.
|
||||
|
||||
b. Add or remove users, or modify permissions for existing users.
|
||||
|
||||
c. Click **Confirm**.
|
||||
|
||||
### Cancel share
|
||||
|
||||
If you no longer need to share a folder, you can cancel the share at any time.
|
||||
|
||||
1. Open the Files application from the Dock or Launchpad on Olares.
|
||||
2. Click **Share** in the left sidebar, and then to the **Share** list is displayed on the right.
|
||||
3. Right-click the target folder and click **Revoke sharing**.
|
||||
4. Click **Confirm**.
|
||||
20
docs/manual/olares/files/sync-files.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Guide to synchronizing files between your local devices and Olares. Learn how to set up two-way sync tasks, manage sync status, and ensure seamless data access across all your platforms.
|
||||
---
|
||||
|
||||
# Sync files to local computer
|
||||
|
||||
<!--@include: ../../get-started/reusables.md{69,73}-->
|
||||
|
||||
## Create a library
|
||||
|
||||
<!--@include: ../../get-started/reusables.md{77,85}-->
|
||||
|
||||
## Enable synchronization
|
||||
|
||||
<!--@include: ../../get-started/reusables.md{89,98}-->
|
||||
|
||||
## Manage synchronization
|
||||
|
||||
<!--@include: ../../get-started/reusables.md{102,108}-->
|
||||
@@ -13,7 +13,7 @@ Explore the following guides to get the most out of Olares’s built-in apps:
|
||||
|
||||
[**Navigate and customize your Desktop**](./desktop.md): Launch apps, organize your workspace, and search across Olares.
|
||||
|
||||
[**Install and manage apps with Market**](./market.md): Discover, install, update, or remove apps and recommendation algorithms from an open permisionless application store.
|
||||
[**Install and manage apps with Market**](./market/market.md): Discover, install, update, remove, and clone apps, as well as purchase and restore paid applications.
|
||||
|
||||
[**Store, sync, and access Files**](./files/): Upload, download, organize, and share files securely across devices with centralized storage and real-time synchronization.
|
||||
|
||||
|
||||
43
docs/manual/olares/market/clone-apps.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to use the Clone feature in Olares to run multiple instances of the same application with independent configurations.
|
||||
---
|
||||
|
||||
# Clone applications
|
||||
|
||||
You can install multiple instances of the same application, which is also known as "clone". This is useful for scenarios requiring different configurations or versions, such as running multiple Windows virtual machines.
|
||||
|
||||
## Clone an application
|
||||
|
||||
The following steps demonstrate the cloning workflow by using the Windows application as an example.
|
||||
|
||||
### Step 1. Verify cloning support
|
||||
|
||||
Confirm that the target application supports cloning:
|
||||
|
||||
1. Open **Market** from Dock or Launchpad, and click the application to open the details page.
|
||||
2. Check the **Required permissions** section. Only applications with the **Multiple Instances** property support cloning.
|
||||
|
||||

|
||||
|
||||
### Step 2. Clone and configure the instance
|
||||
|
||||
To create a clone, a primary instance must exist on your system. Ensure that the application is installed, and then complete the following steps:
|
||||
|
||||
1. Click **My Olares** from the left sidebar of **Market**. The list of installed applications will appear on the right.
|
||||
2. Locate the target application, click the drop-down arrow next to the **Open** button, and then click **Clone**.
|
||||
|
||||

|
||||
|
||||
3. In the **Clone app** window, configure the instance details:
|
||||
|
||||
a. **New app title**: Enter a unique name to identify the application in the **Market** and **My Olares** list.
|
||||
|
||||
b. **Desktop shortcut name**: Set the name for the desktop shortcut. You can name each icon individually if the application has multiple entry points.
|
||||
|
||||
4. Click **Confirm** to proceed.
|
||||
5. In the **Configure Environment Variables** window, complete the corresponding setup, and then click **Confirm**.
|
||||
|
||||
In the installed applications list, the newly created application will appear with a "Clone" tag next to it.
|
||||
|
||||

|
||||
@@ -14,40 +14,42 @@ Before you start, it is recommended to familiarize yourself with a few concepts
|
||||
|
||||
| Terminology | Description |
|
||||
|-----------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [System application](../../developer/concepts/application.md#system-applications) | Built-in applications that come pre-installed with Olares,<br/> such as Profile, Files, and Vault. |
|
||||
| [Community application](../../developer/concepts/application.md#community-applications) | Applications that are created and maintained by third-party<br/> developers. |
|
||||
| [Shared application](../../developer/concepts/application.md#cluster-scoped-applications) | A special category of community applications on Olares<br/> designed to provide unified, shared resources or services to all <br/>users within an Olares cluster. Only one <br/>instance is allowed per cluster. |
|
||||
| [Reference application](../../developer/concepts/application.md#reference-applications) | The applications that have been granted access to specific<br/> shared applications |
|
||||
| [Dependencies](../../developer/concepts/application.md#dependencies) | Prerequisite applications that must already be<br/> installed before a user can access an application <br/>that requires them. |
|
||||
| [System application](../../../developer/concepts/application.md#system-applications) | Built-in applications that come pre-installed with Olares,<br/> such as Profile, Files, and Vault. [](../../../developer/concepts/) |
|
||||
| [Community application](../../../developer/concepts/application.md#community-applications) | Applications that are created and maintained by third-party<br/> developers. |
|
||||
| [Shared application](../../../developer/concepts/application.md#cluster-scoped-applications) | A special category of community applications on Olares<br/> designed to provide unified, shared resources or services to all <br/>users within an Olares cluster. Only one <br/>instance is allowed per cluster. |
|
||||
| [Reference application](../../../developer/concepts/application.md#reference-applications) | The applications that have been granted access to specific<br/> shared applications |
|
||||
| [Dependencies](../../../developer/concepts/application.md#dependencies) | Prerequisite applications that must already be<br/> installed before a user can access an application <br/>that requires them. |
|
||||
|
||||
## Find applications
|
||||
|
||||
The Olares Market offers various ways to discover and browse applications.
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
### Browse by categories
|
||||
|
||||
On **Discover** page:
|
||||
* **Featured Applications**: Curated by the editorial team, showcasing trending and seasonally relevant apps.
|
||||
Upon launching the Market app, the **Discover** page serves as your central hub for exploration, organizing content into intuitive sections to guide your journey:
|
||||
* **Discover Amazing Apps**: Featured applications curated by the editorial team, showcasing trending and seasonally relevant apps. Click these banners to access in-depth editorial features such as comprehensive guides, industry use cases, and detailed app comparisons to help you choose the right tools.
|
||||
* **Community choices**: Most loved and recommended apps by the Olares community.
|
||||
* **Top apps**: Apps with the highest usage and download rates.
|
||||
* **Latest apps**: Recently added applications to the market.
|
||||
* **Top apps on Olares**: Apps with the highest usage and download rates.
|
||||
* **Latest apps on Olares**: Recently added applications to the market.
|
||||
|
||||
You can also browse applications based on their functionality:
|
||||
* **Creativity**: Apps for creating and publishing digital content, from AI-generated art and 3D models to blogs and design projects.
|
||||
* **Productivity**: Apps for team collaboration, project management, data organization, and building custom AI-powered agents.
|
||||
* **Developer Tools**: Toolchain for the software development lifecycle, including code hosting, CI/CD, observability, and database management.
|
||||
* **Fun**: Self-hosted applications for entertainment and fun such as gaming, video streaming, and connecting with people.
|
||||
* **Lifestyle**: Self-hosted applications for managing your smart home, personal photo libraries, and AI identity.
|
||||
* **Fun**: Selfhosted applications for entertainment and fun such as gaming, video streaming, and connecting with people.
|
||||
* **Utilities**: Tools for system management, file sharing, data backup, and running local AI models.
|
||||
* **Developer Tools** Toolchain for the software development lifecycle, including code hosting, CI/CD, observability, and database management.
|
||||
* **AI**: Latest open-source LLMs and generative tools for text, audio, and 3D assets.
|
||||
|
||||
### Search using keywords
|
||||
|
||||
To search an app in the market:
|
||||
|
||||
1. Open the Market app from the Dock or Launchpad.
|
||||
2. In the **Manage** sub-memu on the left, click **Search**.
|
||||
2. In the **Manage** submenu on the left, click **Search**.
|
||||
2. Enter the keywords. The relevant results will appear as you type.
|
||||
|
||||

|
||||
@@ -63,7 +65,7 @@ You can switch market sources to speed up browsing, searching, and downloading,
|
||||
3. Fill in the source name, URL, and description as required, then click **Confirm** to finish adding.
|
||||
4. In the source list, select the target source to activate it. Wait for about 10 minutes for the store page to switch.
|
||||
|
||||
::: tip Note
|
||||
:::info
|
||||
Applications from different installation sources will generate corresponding tabs in **My Olares** for easier application management.
|
||||
:::
|
||||
|
||||
@@ -73,8 +75,8 @@ To install an application from Market:
|
||||
|
||||
1. Open Market from Dock or Launchpad.
|
||||
2. Navigate to the app you want, and click **Get**.
|
||||
3. When the operation button changes to "**Install**", click it to start the installation.
|
||||
4. Once finished, the button will change to "**Open**".
|
||||
3. When the operation button changes to **Install**, click it to start the installation.
|
||||
4. Once finished, the button will change to **Open**.
|
||||
|
||||
:::tip
|
||||
To cancel an installation, hover over the operation button and click **Cancel** when it appears.
|
||||
@@ -157,7 +159,7 @@ The application operation log details the processes and statuses of app operatio
|
||||
|
||||
You can also click the <i class="material-symbols-outlined">download</i> button to download the logs.
|
||||
|
||||
## FAQ
|
||||
## FAQs
|
||||
|
||||
### Why can't I install an application?
|
||||
If you can't install an application, it might be due to:
|
||||
@@ -165,3 +167,34 @@ If you can't install an application, it might be due to:
|
||||
* **Missing dependencies**: Check the **Dependency** section on the application details page and make sure all required apps are installed.
|
||||
* **Incompatible system version**: Try upgrading Olares to the latest version.
|
||||
* **Shared application restrictions** (for Olares member): Install the reference app, and contact your Olares admin to install the corresponding shared application.
|
||||
|
||||
### Why can't I resume my application?
|
||||
|
||||
When you try to resume an application in Olares and receive an error message about insufficient CPU, memory, or disk, it means the system's current available resources cannot support running the application. You need to close other applications to free up resources.
|
||||
|
||||
#### Why was my application stopped?
|
||||
|
||||
An application is usually stopped due to one of the following reasons:
|
||||
* **System auto stop**: To ensure Olares's stability, the Olares system monitors resource usage. If an application consumes excessive resources (such as CPU or memory) causing a high system load, the system might automatically pause it to prevent the entire device from freezing or crashing.
|
||||
* **Manual stop**: You or an administrator might have manually stopped the application previously, and the application has not been resumed yet.
|
||||
|
||||
#### Why can't I resume my application now?
|
||||
|
||||
Starting an application requires reserving a specific amount of computing resources. If other running applications are already occupying most of the resources, the remaining free resources are not enough for the application you want to start.
|
||||
|
||||
Therefore, when you try to resume the application, you might encounter the following messages:
|
||||
|
||||
| Error message | Description |
|
||||
| :--- | :--- |
|
||||
| Insufficient system CPU/memory | The physical resources of the entire system are nearly exhausted. |
|
||||
| Insufficient disk space | The hard drive is full, and new data cannot be written. |
|
||||
| Available CPU/memory insufficient | There are some resources left, they are less than the minimum<br> amount required by this specific application. |
|
||||
|
||||
#### How to resume my application?
|
||||
|
||||
To resume your application, you need to free up some occupied resources:
|
||||
|
||||
1. Go to **Settings** > **Application** to view the applications that are currently **Running**.
|
||||
2. Find applications that you do not need to use right now.
|
||||
3. Stop each application by clicking the app and clicking <i class="material-symbols-outlined">toggle_on</i> to toggle off **Running**.
|
||||
4. After resources are freed, go back to your target application and click **Resume** again.
|
||||
97
docs/manual/olares/market/purchase-paid-apps.md
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to purchase paid applications on Olares Market and restore previously purchased applications.
|
||||
---
|
||||
|
||||
# Manage paid applications
|
||||
|
||||
You can purchase paid applications directly from the Olares Market, or restore your previously purchased apps without additional payment.
|
||||
|
||||
## Purchase paid applications
|
||||
|
||||
You can purchase paid applications directly from the Olares Market. The payment process requires coordination between the Olares system, the LarePass mobile app, and a digital wallet such as MetaMask.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
Before you begin, ensure that you have completed the following tasks:
|
||||
- You have installed and logged into a browser wallet extension, such as MetaMask. To successfully complete the transaction, ensure that your wallet holds both of the following funds:
|
||||
- Application fee: Used to pay for the software license. The specific token required is determined by the app's `price.yaml` configuration, typically USDC or USDT.
|
||||
- Network gas fee: Used to pay for blockchain transaction costs. Note that gas fees must be paid in ETH.
|
||||
- You have installed the LarePass app on your phone and logged into the same account as your Olares system.
|
||||
|
||||
### Step 1: Initiate purchase and identity verification
|
||||
|
||||
1. Open the Olares Market.
|
||||
2. Search for the target paid app, click **Get**, and then click **Buy**.
|
||||
3. In the **Verify payment access** popup, click **Verify now**.
|
||||
4. Open your LarePass mobile app:
|
||||
|
||||
a. Review the request popup titled **Authorize payment access**.
|
||||
|
||||
b. Tap **Confirm**.
|
||||
|
||||
c. If the popup does not appear, return to the app page in Olares Market and click **Buy** again to re-initiate the request.
|
||||
|
||||

|
||||
|
||||
### Step 2: Confirm order
|
||||
|
||||
1. After successful verification, return to the app page in Olares Market and click **Buy** again.
|
||||
2. In the **Verify purchase request** popup, click **Verify now**.
|
||||
3. Check your LarePass mobile app again:
|
||||
|
||||
a. Review the request popup titled **Authorize purchase**.
|
||||
|
||||
b. Tap **Confirm**.
|
||||
|
||||

|
||||
|
||||
### Step 3: Complete payment via wallet
|
||||
|
||||
1. Return to the app page in Olares Market and click **Pay**.
|
||||
2. The browser will automatically open **MetaMask** or your connected wallet extension.
|
||||
3. Review the amount in the wallet popup, and then confirm and approve the transaction.
|
||||
4. Wait for the blockchain to confirm the transaction.
|
||||
5. Once the payment is successfully completed, click **Install** to install the application.
|
||||
6. After the payment is completed, navigate to **Settings** > **Safety** > **VC cards** to verify your purchase credential from your LarePass mobile app.
|
||||
|
||||

|
||||
|
||||
## Restore purchased applications
|
||||
|
||||
If you have previously purchased a paid application, you can restore and re-install it without additional payment, whether you simply uninstalled the app, reset your system, or migrated to a new Olares host.
|
||||
|
||||
### Re-install after uninstallation
|
||||
|
||||
If you are re-installing a paid app that was uninstalled from your current Olares system, the system preserves your license locally.
|
||||
|
||||
You can find the app in the Market, click **Get**, and then click **Install** to re-install it.
|
||||
|
||||
### Restore after system reset or migration
|
||||
|
||||
:::info Identity binding
|
||||
Your purchase history binds to your Olares ID rather than specific hardware. If you have access to LarePass or a backup of your mnemonic phrase, you can activate the new system with the same Olares ID and restore your apps.
|
||||
:::
|
||||
|
||||
:::warning Risk of data loss
|
||||
If you lose your mnemonic phrase, you permanently lose your digital identity and all paid apps. In this case, you must create a new account and repurchase the application.
|
||||
Note that license restoration also requires the developer's service to be online. If their service is unavailable, you might be unable to restore the application.
|
||||
:::
|
||||
|
||||
If you have reset Olares OS or switched to new hardware, your local license data is cleared. You must verify your on-chain identity to retrieve your purchase rights, which will allow you to re-install the application.
|
||||
|
||||
1. Ensure that the current Olares OS is activated with the same **Olares ID** used for the original purchase.
|
||||
2. Open the Olares Market.
|
||||
3. Search for the target paid app, click **Get**, and then click **Buy**.
|
||||
|
||||
:::info
|
||||
The system will detect your on-chain purchase record and will not charge you again.
|
||||
:::
|
||||
|
||||
4. In the **Authorize payment access** popup, click **Verify now**.
|
||||
|
||||
:::info
|
||||
This step verifies your identity ownership and does not initiate a new transaction.
|
||||
:::
|
||||
|
||||
5. Once verified, the button will change to **Install**. Click it to start installation.
|
||||
@@ -4,107 +4,127 @@ description: Manage and optimize GPU resources in Olares with centralized contro
|
||||
---
|
||||
# Manage GPU usage
|
||||
:::info
|
||||
Only Olares admin can configure GPU usage mode. This ensures optimal resource management across the system and prevents conflicts between users' resource needs.
|
||||
Only Olares admins can change GPU modes. This helps avoid conflicts and keeps GPU performance predictable for everyone.
|
||||
:::
|
||||
|
||||
Olares allows you to harness the full power of your GPUs to accelerate demanding tasks such as large language models, image and video generation, and gaming. Whether your GPUs are on a single node or spread across multiple nodes, you can manage them conveniently from one centralized interface.
|
||||
Olares lets you manage your graphics cards, or GPUs, to speed up tasks like AI, image and video generation, and gaming. You can control how your applications use these resources from Olares Settings page.
|
||||
|
||||
This guide helps you understand and configure GPU allocation modes to maximize hardware performance.
|
||||
This guide explains:
|
||||
- How to choose the right GPU mode.
|
||||
- How to configure GPU modes step by step.
|
||||
|
||||
::: tip GPU support
|
||||
Olares supports **only Nvidia GPUs** of **Turing architecture or later** (Turing, Ampere, Ada Lovelace, and Blackwell).
|
||||
## Choose the right GPU mode
|
||||
|
||||
- Quick check: GTX/RTX **16 series and newer** consumer cards are supported.
|
||||
- For other models, cross-check with the [compatible GPU table](https://github.com/NVIDIA/open-gpu-kernel-modules?tab=readme-ov-file#compatible-gpus).
|
||||
- Other models: Cross-check with the [compatible GPU table](https://github.com/NVIDIA/open-gpu-kernel-modules?tab=readme-ov-file#compatible-gpus).
|
||||
- Unknown model: Run `lspci | grep -i nvidia` to query the GPU architecture code and determine compatibility.
|
||||
:::
|
||||
Use the table below to pick a mode based on your workload.
|
||||
|
||||
:::warning AI Performance
|
||||
Even if your GPU architecture is supported, **low VRAM capacity may cause AI applications to fail**. Ensure your GPU has enough memory for your workloads.
|
||||
:::
|
||||
|
||||
## Understand GPU allocation modes
|
||||
|
||||
Olares supports three GPU allocation modes. Choosing the right mode helps optimize performance based on your needs.
|
||||
|
||||
### Time Slicing
|
||||
|
||||
In this mode, a GPU can be bound to multiple applications and rotates execution in time slices.
|
||||
|
||||
* At any instant, only one application uses all available compute and VRAM of the GPU.
|
||||
* Other apps enter a wait queue; Their VRAM contents (e.g., CUDA context, etc.) may be temporarily swapped out to system memory.
|
||||
|
||||
:::info Default GPU allocation
|
||||
By default, GPUs run in time-slicing mode. Applications without allocated GPU resources automatically join the time-sliced GPU queue. If no time-sliced GPU is available, the application pauses after a startup timeout. In this case, you need to allocate a GPU (for example, set a GPU to time-slicing mode, or assign a VRAM quota to the application), then manually resume the application.
|
||||
:::
|
||||
|
||||
### App Exclusive
|
||||
|
||||
In this mode, the entire GPU is allocated to a single application.
|
||||
|
||||
* During execution, the app can use all compute and VRAM of the bound GPU.
|
||||
* No cross-app contention or scheduling overhead so that best performance is guaranteed.
|
||||
|
||||
### Memory Slicing
|
||||
In this mode, VRAM of the GPU is partitioned into fixed quotas for multiple designated applications.
|
||||
|
||||
* Users need to manually set a quota for each app.
|
||||
* The sum of quotas must not exceed physical VRAM of the bound GPU. Oversubscription is not supported.
|
||||
* Apps with quota assigned can run concurrently, each limited to its own quota.
|
||||
|
||||
:::tip Multi-GPU allocation
|
||||
- All three allcation modes support assigning multiple GPUs to the same application. Olares only assigns multiple GPUs to the application’s container without fusing VRAM or compute in any way. Whether multi-GPU is utilized depends on the application/framework itself.
|
||||
|
||||
- In multi-node environments, you can't assign multiple GPUs across nodes to the same application simultaneously.
|
||||
:::
|
||||
| GPU mode | Definition | Use scenario |
|
||||
| :--- | :--- | :--- |
|
||||
| **Time slicing** (Default) | Multiple apps share one GPU<br> by taking turns using compute<br> and VRAM. | General workloads that run several lightweight apps. |
|
||||
| **App exclusive** | One app gets full, uninterrupted<br> access to the compute and VRAM<br> of a single GPU. | Heavy workloads that require maximum stability, such as LLMs and high‑end gaming. |
|
||||
| **Memory slicing** | The GPU's VRAM is divided into<br> fixed quotas, and apps run concurrently<br> within their limits. | Running specific apps simultaneously while strictly limiting their memory usage. |
|
||||
|
||||
## View GPU status
|
||||
|
||||
To view your GPU status:
|
||||
To see your GPUs and their current configuration:
|
||||
|
||||
1. Navigate to **Settings** > **GPU**. The GPU list shows each GPU’s model, associated node, total VRAM, and current GPU mode.
|
||||
2. Click on a specific GPU to visit its details.
|
||||
1. Go to **Settings** > **GPU**.
|
||||
2. Review the list to see each GPU's model, node, total VRAM, and current mode.
|
||||

|
||||
3. Click a GPU to open its details page.
|
||||
|
||||

|
||||
|
||||
::: tip Note
|
||||
If your Olares only has one GPU, navigating to the GPU section will take you directly to the GPU details page.
|
||||
:::tip
|
||||
If you have only one GPU, Olares may open the GPU details page directly.
|
||||
:::
|
||||
|
||||
## Configure GPU mode
|
||||
|
||||
On the **GPU details** page, select your desired mode from the **GPU mode** dropdown. Depending on your selected mode, different follow-up options apply.
|
||||
Follow these steps to change how a GPU is used:
|
||||
|
||||
* **Time Slicing**:
|
||||
1. Select this mode from the GPU mode dropdown.
|
||||
2. In the **Pin application** section, click **+Add an application** to manually pin an application to this specific GPU in a multi-GPU setup.
|
||||
1. Go to **Settings** > **GPU**.
|
||||
2. Click the GPU you want to configure.
|
||||
3. Choose a mode from the **GPU mode** dropdown.
|
||||
|
||||

|
||||
:::warning Restart notice
|
||||
Changing a GPU's mode will unbind apps from that GPU and restart their containers.
|
||||
|
||||
:::tip Note
|
||||
No manual binding is required if you only have one GPU in your cluster.
|
||||
:::
|
||||
|
||||
* **App Exclusive**
|
||||
1. Select this mode from the GPU mode dropdown.
|
||||
2. In the **Select exclusive app** dropbox, choose your target application.
|
||||
3. Click **Confirm**.
|
||||

|
||||
|
||||
* **Memory Slicing**
|
||||
1. Select this mode from the dropdown.
|
||||
2. In the **Allocate VRAM** section, click **Add an application**.
|
||||
3. Select your target application and assign it a specific amount of VRAM in GB.
|
||||
4. Repeat for other applications and click **Confirm**.
|
||||

|
||||
|
||||
:::tip Unbinding
|
||||
- After binding an GPU or its VRAM to an application, you can manually unbind it under the corresponding GPU mode to release GPU resources.
|
||||
|
||||
- When you switch a GPU’s allocation mode, all applications allocated under that mode are unbound, and the application containers will restart.
|
||||
After restart, apps without specific GPU bindings are automatically scheduled to any available GPU in Time slicing mode.
|
||||
:::
|
||||
|
||||
### Time slicing
|
||||
|
||||
**Time slicing** is the default mode in Olares. Use this mode to allow multiple applications to share resources.
|
||||
|
||||
Apps without a specific GPU binding are automatically scheduled onto GPUs in **Time slicing** mode.
|
||||
|
||||

|
||||
|
||||
#### Bind app
|
||||
To assign an app to this GPU:
|
||||
1. In **Pin application** section, click **Bind App**.
|
||||
2. Choose your target application and click **Confirm**.
|
||||
|
||||
#### Switch GPU
|
||||
|
||||
:::info Same-node limitation
|
||||
An application can use multiple GPUs only if they are located on the same node. If you switch an app to a GPU on a different node, the app is moved and bound only to the target GPU.
|
||||
:::
|
||||
|
||||
If your system has more than one GPU, you can move an assigned app to a different GPU:
|
||||
1. In **Pin application** section, find the app you want to move.
|
||||
2. Click <i class="material-symbols-outlined">repeat</i>, then choose the target GPU and click **Confirm**.
|
||||
|
||||
|
||||
#### Unbind app
|
||||
To remove an app from this GPU:
|
||||
1. In **Pin application** section, find the app you want to remove.
|
||||
2. Click <i class="material-symbols-outlined">link_off</i>, then **Confirm**.
|
||||
|
||||
### App exclusive
|
||||
|
||||
Use **App exclusive** mode to dedicate a GPU entirely to one high-demand application.
|
||||
|
||||

|
||||
|
||||
#### Bind app
|
||||
To give an app exclusive access:
|
||||
1. In **Select exclusive app** section, click **Bind App**.
|
||||
2. Select your target application and click **Confirm**.
|
||||
|
||||
#### Switch app
|
||||
To replace the current exclusive app with a new one:
|
||||
1. In **Select exclusive app** section, click **Switch App**.
|
||||
2. Choose the new application and confirm.
|
||||
|
||||
The previous app is unbound, and the new app takes over exclusive access.
|
||||
|
||||
#### Switch GPU
|
||||
If your system has more than one GPU, you can move the exclusive app to a different GPU:
|
||||
1. In **Select exclusive app** section, click <i class="material-symbols-outlined">repeat</i>.
|
||||
2. Choose the target GPU and confirm.
|
||||
|
||||
:::info Same-node limitation
|
||||
An application can use multiple GPUs only if they are located on the same node. If you switch an app to a GPU on a different node, the app is moved and bound only to the target GPU.
|
||||
:::
|
||||
|
||||
#### Unbind app
|
||||
To remove the exclusive binding:
|
||||
1. In **Select exclusive app** section, click <i class="material-symbols-outlined">link_off</i>.
|
||||
2. Click **Confirm**.
|
||||
|
||||
### Memory slicing
|
||||
|
||||
Use **Memory slicing** to run apps concurrently with strict VRAM limits.
|
||||
|
||||

|
||||
|
||||
#### Bind app and allocate VRAM
|
||||
|
||||
1. In **Allocate VRAM** section, click **Bind App**.
|
||||
2. Select your target application, assign it a specific amount of VRAM in GB, and click **Confirm**.
|
||||
:::warning
|
||||
The total of all VRAM limits must not exceed the GPU total VRAM.
|
||||
:::
|
||||
3. Repeat for other apps as needed.
|
||||
|
||||
## Learn more
|
||||
- [Monitor GPU usage in Olares](../resources-usage.md)
|
||||
@@ -14,6 +14,7 @@ Settings is organized into the following sections:
|
||||
- Manage integrations – Connect Olares to external web services and tools.
|
||||
- Customize appearance – Set system language and background preferences.
|
||||
- Configure network – Set up FRP, VPN, and edit the hosts file.
|
||||
- Configure search - Configure indexing rules to optimize your search experience.
|
||||
- Backup and restore – Create and manage backup and restore tasks for selected directories.
|
||||
- Update system – View system details and install updates.
|
||||
- Export system log – Generate and export system logs for diagnostics.
|
||||
|
||||
77
docs/manual/olares/settings/search.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
outline: [2,3]
|
||||
description: Configure file indexing in Olares to control search scope, manage exclusions, and enable full-text search for specific directories.
|
||||
---
|
||||
# Configure file search
|
||||
|
||||
File search settings allow you to customize how Olares indexes and searches your data. By defining specific rules, you can control which files are excluded from global search and which directories support deep content searching.
|
||||
|
||||
This guide helps you understand and configure indexing rules to optimize your search experience.
|
||||
|
||||
See also [Search within Olares](/manual/olares/desktop.md#search-within-olares) for how to use global search.
|
||||
|
||||
:::tip Search scope
|
||||
These settings apply only to your own files in Olares.
|
||||
|
||||
Files or folders shared with you by other team members are searchable globally by default and do not need to be manually added to these rules.
|
||||
:::
|
||||
|
||||
## Understand search settings
|
||||
|
||||
Olares file search is configured in **File search**, which contains three main sections:
|
||||
|
||||
- **Search index**: Shows the current indexing status and lets you manually rebuild the index when needed.
|
||||
- **Excluded files**: Acts as a global ignore list for the search engine, defining which files are excluded from the index.
|
||||
- **Full-text search directories**: Lists the folders where content search is enabled, so files are searchable by both filename and text content.
|
||||
|
||||

|
||||
|
||||
## View search index status
|
||||
|
||||
To view the current search indexing status:
|
||||
|
||||
1. Open Settings from the Launchpad.
|
||||
2. Go to **Search** > **File search**.
|
||||
3. Locate the Search Index section at the top of the panel.
|
||||
|
||||
If you need changes reflected immediately, click **Rebuild**.
|
||||
|
||||
## Exclude files from search
|
||||
|
||||
Use the Excluded files section if certain files, such as logs or temporary files, clutter your search results.
|
||||
|
||||
You exclude them by adding exclusion rules. Each rule uses a regex pattern to specify the file paths you want Olares to ignore.
|
||||
|
||||
### Add a rule
|
||||
1. Under Excluded files, click **Add pattern**.
|
||||
2. Enter a valid regular expression (regex) to match the files you wish to ignore.
|
||||
3. Click **Confirm**.
|
||||
|
||||
### Remove a rule
|
||||
1. Under Excluded files, locate the target rule.
|
||||
2. Click the <i class="material-symbols-outlined">delete</i> icon next to the pattern.
|
||||
3. In the prompt window, click **Confirm**.
|
||||
|
||||
:::warning Regex patterns
|
||||
If you are not familiar with regular expressions, start with simple patterns and test them carefully. Incorrect patterns may cause important files to disappear from search results
|
||||
:::
|
||||
|
||||
## Search inside file content
|
||||
|
||||
Use the Full-text search directories section when you want to search inside documents, not just by filename.
|
||||
|
||||
By adding a folder to the full-text directory list, you enable full-text search. Once added, supported files in that folder become searchable by both filename and content.
|
||||
|
||||
### Add a rule
|
||||
1. Under Full-text search directories, click **Add directory**.
|
||||
2. Select the target folder from the file picker.
|
||||
3. Click **Confirm** to add it to the list.
|
||||
|
||||
### Remove a rule
|
||||
1. Under Full-text search directories, locate the target directory.
|
||||
2. Click the <i class="material-symbols-outlined">delete</i> icon next to the directory.
|
||||
3. In the prompt window, click **Confirm**.
|
||||
|
||||
:::tip Supported formats
|
||||
Full-text search is supported for the following file types:<br> `.pdf`, `.doc`, `.docx`, `.csv`, `.rtf`, `.txt`, `.md`, `.json`, `.xml`.
|
||||
:::
|
||||
@@ -4,83 +4,144 @@ description: Get started with Wise in Olares. Learn to collect content, organize
|
||||
---
|
||||
# Wise basics
|
||||
|
||||
Wise helps you curate and organize your reading materials with flexible options for collecting, reading, and managing content. This page covers the essential tasks to get you started with Wise.
|
||||
Wise helps you build a focused reading workflow on top of your personal information hub. This page walks you through the core actions you'll use every day: collecting content, organizing what to read next, and capturing your own insights.
|
||||
|
||||
## Add content to your library
|
||||
Save interesting content using any of these methods.
|
||||
This page focuses on saving and working with individual items. For a deeper look at feeds and subscriptions, see [Subscribe and manage feeds](./subscribe).
|
||||
|
||||
### Add to Inbox or Read Later
|
||||
Organize your reading flow with two collections:
|
||||
|
||||
* **Inbox**: Your primary collection for content you want to read soon.
|
||||
* **Read Later**: Your backlog for content to revisit in the future.
|
||||
## Before you begin
|
||||
|
||||
While browsing the title or reading, click **<i class="material-symbols-outlined">inbox</i> Inbox** or **<i class="material-symbols-outlined">schedule</i> Read Later** to save content to either collection.
|
||||
To unlock the full potential of Wise, it is recommended to install the following apps from Olares Market:
|
||||
|
||||

|
||||
- **Rss Subscribe**: Use it to subscribe to RSS feeds directly while browsing web pages.
|
||||
- **YT-DLP**: Use it to download audio and video from supported web pages into Wise.
|
||||
|
||||
### Manually add content
|
||||
Wise supports various content types including videos, audio, PDFs, and eBooks:
|
||||
:::tip
|
||||
Wise works without these apps, but in-browser subscription and media download will be unavailable until you install them.
|
||||
:::
|
||||
|
||||
1. Click <i class="material-symbols-outlined">add_circle</i> in the menu bar.
|
||||
2. To add a web page, select **Web page**.
|
||||
3. To add a downloadable link, select **Download link**.
|
||||
4. To add a PDF or E-book (in EPUB format) from your local machine, select **Upload**.
|
||||
5. To add an RSS feed, select **RSS**.
|
||||
:::tip
|
||||
To explore how you can leverage RSS subscription with Wise, see [Subscribe to an RSS feed](./subscribe).
|
||||
:::
|
||||
## Build your library
|
||||
|
||||
## Automatic download
|
||||
Wise automatically creates download tasks for new audio or video content, saving media files to Olares for convenient offline access.
|
||||
Wise pulls content into your library in two ways:
|
||||
|
||||
This feature:
|
||||
- **Saved items:** Individual web pages, files, audio, and video that you capture manually. These items appear in your main **Inbox** and are automatically sorted into categories such as **Articles**.
|
||||
- **Feeds:** Subscriptions to dynamic sources like websites, blogs, and podcasts. New updates appear under **Feeds**, where you can select specific entries to save to your library.
|
||||
|
||||
* Ensures your content is always available offline
|
||||
* Prevents content loss if the original source becomes unavailable
|
||||
* Provides quick access to your media files
|
||||
### Save items
|
||||
|
||||
To view all your downloaded media files, go to <i class="material-symbols-outlined">settings</i> > **Transmission** > **Download**. This page shows a complete list of your downloads along with their details.
|
||||

|
||||
You can save individual items to Wise in three ways:
|
||||
- Upload files
|
||||
- Add items via link
|
||||
- Save from browser with LarePass extension
|
||||
|
||||
You can click <i class="material-symbols-outlined">folder_open</i> to locate the target content in the Files app.
|
||||
#### Upload files
|
||||
|
||||
## Organize your reading
|
||||
Import files directly from your computer, including PDFs, EPUBs, audio, video, and other document types. Wise automatically places each supported format into the right content folder in your library.
|
||||
|
||||
### Use tags for organization
|
||||
To create a structured content collection with tags:
|
||||
1. Click <i class="material-symbols-outlined">add_circle</i> in the bottom-left menu bar, and select **Upload**.
|
||||
2. Select one or more files from your local computer.
|
||||
|
||||
1. On the list page, click <i class="material-symbols-outlined" style="font-variation-settings: 'wght' 200;">sell</i> on the content card.
|
||||
2. In the tag input box, select or create tags relevant to the current content.
|
||||
#### Add items via link
|
||||
|
||||

|
||||
Paste a URL to save articles, videos, or subscribe to feeds.
|
||||
|
||||
You can find and manage your tags in the page <i class="material-symbols-outlined">settings</i> > **Tags**.
|
||||
::: tip Handle restricted content
|
||||
If a link requires login or other access control, Wise may need cookies to fetch it correctly. To configure cookies for protected sites, see **[Manage cookies for Wise](./manage-cookies)**.
|
||||
:::
|
||||
|
||||
### Capture insights with notes
|
||||
1. While reading, click <i class="material-symbols-outlined" style="font-variation-settings: 'wght' 200;">right_panel_open</i> to open the **Info** panel.
|
||||
2. Add your thoughts in the **Note** section.
|
||||
3. Click **Save** to store your notes.
|
||||
1. Click <i class="material-symbols-outlined">add_circle</i> in the bottom-left menu bar, and select **Add Link**.
|
||||
2. Paste or type a URL.
|
||||
|
||||
You can edit or delete note later.
|
||||
Wise analyzes the link and lists all actions available:
|
||||
- **Save to library**: The content will be saved as an item in your library and added to **Inbox**.
|
||||
- **Subscribe to RSS feed**: If Wise detects one or more RSS feeds for the site, they will be listed here. Select the feed you want to follow, and new items from that feed will be automatically [added to **Feeds**](./subscribe).
|
||||
{width=300}
|
||||
- **Download file**: If Wise detects videos or other downloadable files on the page, this option will appear. Select the file you want to download to save it for offline access. **[YT-DLP](https://market.olares.com/app/market.olares/ytdlp)** is required.
|
||||
{width=300}
|
||||
|
||||

|
||||
Newly saved items will appear under their content type.
|
||||
|
||||
#### Save from browser with LarePass extension
|
||||
|
||||
You can also save content to Wise directly from your browser using the [LarePass extension](https://www.olares.com/larepass), without opening Wise first.
|
||||
|
||||
1. Open the LarePass browser extension and select the "Collect" icon.
|
||||
2. Under **Save to library**, review the content detected on the current page.
|
||||
3. Click <i class="material-symbols-outlined">box_add</i> next to the item you want to save.
|
||||

|
||||
|
||||
Items saved via LarePass are added to your Wise library and appear in the main **Inbox** folder and under the appropriate content type.
|
||||
|
||||
### Monitor and manage media downloads
|
||||
|
||||
When you add new audio or video content, Wise automatically creates download tasks and save media files to Olares. This:
|
||||
|
||||
- Ensures your media is available offline.
|
||||
- Protects your library if the original source is removed.
|
||||
- Makes it faster to open and play items.
|
||||
|
||||
To manage all download tasks:
|
||||
|
||||
1. Go to **<i class="material-symbols-outlined">settings</i> Settings** > **Transmission** > **Download**.
|
||||
2. Review the list of media downloads and their status.
|
||||
3. You can:
|
||||
|
||||
- Click <i class="material-symbols-outlined">folder_open</i> to locate a downloaded file in Files.
|
||||
- Click <i class="material-symbols-outlined">do_not_disturb_on</i> to remove it from the list.
|
||||
|
||||
## Use reading tools
|
||||
|
||||
Wise provides several tools to enhance your reading experience and help you keep track of what matters.
|
||||
|
||||

|
||||
|
||||
### Track reading progress
|
||||
|
||||
### Track your reading progress
|
||||
Wise uses green dot indicators on article covers to help you track unread content. When you open an article, it's automatically marked as read.
|
||||
{width=600}
|
||||
|
||||
While reading, you can manually toggle between **<i class="material-symbols-outlined">playlist_add_check</i>Seen** or **<i class="material-symbols-outlined">playlist_remove</i>Unseen** status in the toolbar to maintain your reading progress.
|
||||
In the reader toolbar, you can manually toggle between **<i class="material-symbols-outlined">playlist_add_check</i>Seen** or **<i class="material-symbols-outlined">playlist_remove</i>Unseen** to maintain your reading progress.
|
||||
|
||||
### Search from Wise
|
||||
<!--@include: ../tutorials/wise.reusables.md{4,13}-->
|
||||
### Capture notes
|
||||
|
||||
You can add private notes to any content in your library:
|
||||
|
||||
1. While browsing, click <i class="material-symbols-outlined" style="font-variation-settings: 'wght' 200;">right_panel_open</i> to open the **Info** panel.
|
||||
2. Type your thoughts in the **Note** section.
|
||||
3. Click **Save**.
|
||||
|
||||
You can edit or delete notes from the same panel at any time.
|
||||
|
||||
## Use tags
|
||||
|
||||
Tags allow you to add flexible labels to your content for easy retrieval later.
|
||||
|
||||
1. On the list page, click <i class="material-symbols-outlined" style="font-variation-settings: 'wght' 200;">sell</i> on the content card to add tags to it.
|
||||
2. Select an existing tag, or type a new name to create one.
|
||||
|
||||
{width=600}
|
||||
|
||||
You can manage all your tags in **<i class="material-symbols-outlined">settings</i> Settings** > **Tags**.
|
||||
|
||||
::: tip
|
||||
Tags become even more powerful when combined with filtered views. See [Organize your knowledge with filters](./filter) to build tag-based views such as "AI articles" or "Design inspiration".
|
||||
:::
|
||||
|
||||
## Search your library
|
||||
|
||||
Once you've collected your content in Wise, you can search for particular content themes or entries using aggregated search in Olares.
|
||||
|
||||
1. Click <i class="material-symbols-outlined">search</i> in the Dock to open the search window.
|
||||
2. Specify the search scope to Wise, and enter the keywords to search.
|
||||

|
||||
|
||||
## Customize appearance
|
||||
|
||||
## Change appearance
|
||||
By default, Wise follows your system's light/dark theme settings. You can override this to set your preferred appearance:
|
||||
|
||||
1. Click the <i class="material-symbols-outlined">settings</i> in the bottom left corner and select **Preferences**。
|
||||
2. Under **Theme**, choose your preferred appearance:
|
||||
1. Click the <i class="material-symbols-outlined">settings</i> in the bottom left corner and select **Preferences**.
|
||||
2. Under **Theme**, choose your preferred system theme:
|
||||
- Light mode
|
||||
- Dark mode
|
||||
|
||||
## Learn more
|
||||
- [Build your knowledge hub with Wise](../../best-practices/organize-content.md)
|
||||
Your choice applies to the Wise interface and reader.
|
||||
@@ -1,58 +1,73 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Learn how to use Wise powerful filtering system to organize your library. Create tag-based views, add custom filtered views, and utilize advanced query parameters to manage your content effectively.
|
||||
---
|
||||
# Organize your knowledge with filters
|
||||
# Organize your knowledge with filtered views
|
||||
|
||||
As your Wise library grows, staying organized can become challenging. With filtered views, you can easily sort and access content by applying filters based on parameters like tags, saved dates, authors, and more.
|
||||
As your Wise library grows, finding specific content by browsing folders can become difficult. Filtered views allow you to group related content into dynamic "smart folders" based on rules you define, such as specific tags, content types, or dates.
|
||||
|
||||
This guide covers how to:
|
||||
- Create filtered views from tags and subscribed feeds.
|
||||
- Add custom filtered views using queries.
|
||||
Unlike standard folders, these views update automatically. Once created, any new item that matches your criteria will instantly appear in the view without you having to move it manually.
|
||||
|
||||
:::info
|
||||
Only entries from feeds or entries saved to **<i class="material-symbols-outlined">inbox</i> Inbox** or **<i class="material-symbols-outlined">schedule</i> Read Later** can be queried.
|
||||
:::
|
||||
|
||||
## Use tags or feeds to filter entries
|
||||
Filtered views allow you to organize your content by grouping entries based on tags or feeds. This helps you quickly access content related to specific topics or sources.
|
||||
This guide explains how to:
|
||||
- Build filtered views from existing tags and feeds.
|
||||
- Create custom views using query language.
|
||||
- Pin your favorite views to the sidebar.
|
||||
- Discover advanced filter options.
|
||||
|
||||
1. Open Wise, click <i class="material-symbols-outlined">settings</i> in the bottom left corner.
|
||||
2. Depending on your preference:
|
||||
- Select **Tags** to filter content by specific topics or categories.
|
||||
- Select **RSS feeds** to filter content from specific sources.
|
||||
3. For existing tags, click **Manage views...**. You can:
|
||||
- Group content from the tag or feed into an existing view, or
|
||||
- Create a new view to group all related content.
|
||||
## Create quick views from tags or feeds
|
||||
|
||||

|
||||
4. If creating a new view:
|
||||
- Enter a name for the view (e.g., `Tech Articles`).
|
||||
- Click **Confirm** to save the view.
|
||||
The quickest way to create a view is to base it on a tag or feed you already use.
|
||||
|
||||
## Add custom filter view
|
||||
For more flexibility, you can create custom filtered views using query language. This allows you to define precise conditions for grouping content.
|
||||
1. In Wise, click <i class="material-symbols-outlined">settings</i> in the bottom left corner.
|
||||
2. Select either **Tags** (for topics) or **RSS feeds** (for sources).
|
||||
3. Locate the item you want to use and click **Manage views...**.
|
||||
4. Choose an action:
|
||||
- Add to an existing view: Group this tag/feed into a view you already created.
|
||||
- Create a new view: Create a standalone view that groups all related entries.
|
||||
|
||||
a. Enter a name for the view.
|
||||
|
||||
b. Click **Confirm** to save the view.
|
||||
|
||||
The following demonstrates how to create a view for the tag "AI" using query language:
|
||||

|
||||
|
||||
1. Open Wise, click <i class="material-symbols-outlined">settings</i> in the bottom left corner and select **Filtered views**.
|
||||
2. In the top-right corner, select **Add view**.
|
||||
3. Enter a name for the view (e.g., "AI trends"), and enter `tag:AI` in the **Query** filed.
|
||||
4. Click **Confirm** to save this view.
|
||||
## Create custom filtered views
|
||||
|
||||
{width=70%}
|
||||
For more flexibility, you can create views using query language. This lets you define precise conditions for grouping content.
|
||||
|
||||
To create a custom filtered view:
|
||||
|
||||
1. In Wise, click <i class="material-symbols-outlined">settings</i> in the bottom left corner.
|
||||
2. Select **Filtered views**.
|
||||
3. In the top-right corner, click **Add view**.
|
||||
4. Enter a name for the view (for example, `AI trends`).
|
||||
5. In the **Query** field, enter your filter expression. For example:
|
||||
- `tag:AI` – entries tagged with `AI`.
|
||||
|
||||
{width=60%}
|
||||
6. Click **Confirm** to save the view.
|
||||
|
||||
The view will run immediately and include all entries that match the query.
|
||||
|
||||
## Pin views to sidebar
|
||||
You can pin filtered views to the sidebar using either of these methods:
|
||||
|
||||
- Locate the view in the list and click <i class="material-symbols-outlined">keep</i> in the corresponding **Operations** column.
|
||||
- Open the filtered view, click <i class="material-symbols-outlined">keyboard_arrow_down</i> in the header, and select **Pin to sidebar**.
|
||||
You can pin your filtered views to the sidebar so they are always one click away.
|
||||
|
||||
{width=50%}
|
||||
## Available filters
|
||||
1. In Wise, click <i class="material-symbols-outlined">settings</i> in the bottom left corner.
|
||||
2. Select **Filtered views**.
|
||||
3. Choose the ways to pin your target view:
|
||||
- Click <i class="material-symbols-outlined">keep</i> in the **Operations** column.
|
||||
- Click the filtered view to open it, click <i class="material-symbols-outlined">keyboard_arrow_down</i> in the header, and select **Pin to sidebar**.
|
||||
{width=50%}
|
||||
|
||||
Pinned views appear in the sidebar alongside your other navigation items.
|
||||
|
||||
## Common filters and syntax
|
||||
To explore all available filtering options and learn how to use them, refer to the following:
|
||||
|
||||
- [Filtered view examples](filter-examples)
|
||||
- [Filter syntax reference](filter-syntax-guide.md)
|
||||
|
||||
|
||||
|
||||
- [Filter syntax reference](filter-syntax-guide.md)
|
||||
@@ -1,33 +1,62 @@
|
||||
---
|
||||
description: Transform your Olares into a powerful information hub with Wise - featuring AI-driven content curation, cross-platform aggregation, and seamless bookmarking capabilities.
|
||||
outline: [2, 3]
|
||||
description: Transform your Olares into a powerful information hub with Wise, featuring cross-platform aggregation, and seamless bookmarking capabilities.
|
||||
---
|
||||
# Curate information hub with Wise
|
||||
# Curate your information hub with Wise
|
||||
|
||||
Wise is a local-first, AI-driven modern reader and a core application within the Olares ecosystem. Working together with the LarePass Chrome extension, Wise assists you in collecting, consuming, and managing content from various platforms, thereby creating and maintaining a personal information hub.
|
||||
Wise is a local-first modern reader designed to turn scattered information into a personal information hub. As a core application within the Olares ecosystem, it serves as your central repository for managing digital content securely and efficiently.
|
||||
|
||||
Key features include:
|
||||
Wise empowers you to build this hub through two main capabilities:
|
||||
|
||||
* **Self-hosted recommendation algorithms**: You can run personalized algorithms to filter and sort online content, breaking through the information bubble and receiving diverse and personalized content recommendations.
|
||||
* **Cross-platform content aggregation**: Wise integrates articles, videos, audio, and feeds from different sources, offering you a comprehensive experience.
|
||||
* **Seamless bookmarking**: With the LarePass browser extension, you can save web pages to Olares with a single click, making it easy to access and manage content anytime.
|
||||
- **Cross-platform content aggregation**: Centralize your reading by integrating articles, videos, audio, and feeds from various sources into a single, distraction-free interface.
|
||||
- **One-click bookmarking**: Save web pages directly to Olares using the LarePass browser extension, ensuring your content is always accessible and owned by you.
|
||||
|
||||
---
|
||||
## Install and open Wise
|
||||
|
||||
1. Open the Market, and search for "Wise".
|
||||
2. Click **Get**, then **Install**.
|
||||
3. Once installed, open Wise from the Launchpad.
|
||||
|
||||
## Understand the interface
|
||||
|
||||
The Wise interface is designed to help you organize and consume content efficiently.
|
||||
|
||||

|
||||
|
||||
### Sidebar navigation
|
||||
|
||||
The sidebar organizes your content into the following sections:
|
||||
|
||||
- **Feeds:** Contains your subscribed sources, including websites, blogs, and video channels.
|
||||
- **Inbox:** Your central workspace for active content. It aggregates items from all sources, including saved web pages, uploaded files like PDFs or EPUBs, and feed items added to your library.
|
||||
- **Content types:** Automatically categorizes your content by format, such as **Articles**, **Videos**, and **Books**.
|
||||
|
||||
### Item status
|
||||
|
||||
Every item in Wise has a status that can be either **Inbox** or **Read Later**. You can change an item's status using the icons in the list view or the reader view.
|
||||
|
||||
- **<i class="material-symbols-outlined">inbox</i> Inbox**: Your primary collection for content you want to read soon.
|
||||
- **<i class="material-symbols-outlined">schedule</i> Read Later**: Your backlog for content to revisit in the future.
|
||||
|
||||
## Next steps
|
||||
|
||||
Explore the following guides to master your Wise workflow:
|
||||
<div>
|
||||
<h4><a href="./wise-basics">Wise basics</a></h4>
|
||||
Learn the essential tasks for collecting, reading, and managing your content library in Wise.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4><a href="./recommend">Discover themed content</a></h4>
|
||||
Learn how self-hosted recommendation algorithms work in Wise.
|
||||
<h4><a href="./basics">Wise basics</a></h4>
|
||||
Learn essential tasks for collecting, reading, and managing your content library.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4><a href="./subscribe">Subscribe and manage feeds</a></h4>
|
||||
Set up and organize your content sources through RSS feeds, manual subscriptions, and the LarePass browser extension.
|
||||
Set up and organize content sources via RSS, manual subscriptions, and LarePass browser extension.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4><a href="./manage-cookies">Manage cookies for Wise</a></h4>
|
||||
Learn how to upload cookies to grant Wise access to content behind logins or paywalls.
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4><a href="./filter">Add filtered view</a></h4>
|
||||
Learn how to use advanced filters to organize and display content based on specific criteria like tags, authors, or publication dates.
|
||||
Use advanced filters to organize content by tags, authors, or publication dates.
|
||||
</div>
|
||||
93
docs/manual/olares/wise/manage-cookies.md
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
outline: [2, 3]
|
||||
description: Manage cookies for Wise so it can access protected websites and feeds. Learn why cookies matter, supported formats, how to obtain them, and ways to upload and maintain cookies.
|
||||
---
|
||||
|
||||
# Manage cookies for Wise
|
||||
|
||||
Some websites require a login to access their content. To allow Wise to fetch content from these protected sources, you may need to upload cookies so it can authenticate the connection.
|
||||
|
||||
This grants Wise permission to pass login checks, ensuring that features like **Save to library** or **Subscribe to RSS feed** work securely on restricted sites.
|
||||
|
||||
This guide explains how to manage cookies in Olares for Wise.
|
||||
|
||||
## Upload cookies
|
||||
|
||||
Olares provides flexible options for uploading cookies, depending on whether you want to capture them instantly while browsing or manage them manually in batch.
|
||||
|
||||
### Upload via LarePass browser extension
|
||||
|
||||
This is the easiest way to handle cookies. When you are browsing a site that requires a login, [LarePass browser extension](https://www.olares.com/larepass) can capture and upload the cookies for the current page in one flow.
|
||||
|
||||
1. Navigate to the target website and make sure you are logged in.
|
||||
2. Open the LarePass browser extension and select the "Collect" icon.
|
||||
3. Click **Upload** to upload the cookies for the current page.
|
||||
|
||||
{width=40%}
|
||||
|
||||
After upload, Wise will use these cookies when you **Save to library** or **Subscribe to RSS feed** for that site.
|
||||
|
||||
### Upload manually in batch
|
||||
|
||||
You can manually paste cookie strings in Netscape, JSON, or Header String formats. This is useful if you use browser extensions like [Cookie-Editor](https://chromewebstore.google.com/detail/cookie-editor/iphcomljdfghbkdcfndaijbokpgddeno?utm_source=ext_app_menu) to export credentials from specific websites.
|
||||
|
||||
You can upload cookie strings via the Wise app interface or directly through the system Settings.
|
||||
|
||||
<Tabs>
|
||||
<template #Upload-to-Wise>
|
||||
|
||||
This method allows you to upload cookies directly without leaving the Wise application.
|
||||
|
||||
:::info
|
||||
Wise supports uploading only. To view, manage, or delete these cookies later, you must navigate to the **Settings** > **Integration** > **Manage Your Cookies** page.
|
||||
:::
|
||||
|
||||
1. In Wise, click <i class="material-symbols-outlined">settings</i> **Settings** in the bottom left corner.
|
||||
2. Select **Preferences**.
|
||||
3. Enable **Batch cookie upload**.
|
||||
4. Click <i class="material-symbols-outlined">add_circle</i> in the bottom-left menu bar.
|
||||
5. Select **Upload Cookie**.
|
||||
6. Select the format for your cookie file, and paste the corresponding raw text into the input box.
|
||||
7. Click **Confirm**.
|
||||
|
||||

|
||||
|
||||
Cookies uploaded this way are stored for Wise and will be used whenever Wise accesses matching domains.
|
||||
|
||||
</template>
|
||||
|
||||
<template #Upload-to-Integration>
|
||||
|
||||
This method allows you to upload, view, and manage your cookies in the same interface.
|
||||
|
||||
1. Open **Settings** from the Launchpad.
|
||||
2. Go to **Integration** > **Manage Your Cookies**.
|
||||
3. Click **Import Cookie** or the <i class="material-symbols-outlined">add_circle</i> icon in the top-right corner to open the **Upload Cookie** dialog.
|
||||
4. Select the format for your cookie file, paste the corresponding raw text into the input box, and click **Confirm**.
|
||||
|
||||
Wise automatically detects and uses these cookies when accessing matching domains.
|
||||
</template>
|
||||
</Tabs>
|
||||
|
||||
## Manage cookies
|
||||
|
||||
You usually do not need to manage cookies frequently, but it can be helpful to review or clean them up from time to time.
|
||||
|
||||
### Check cookie status
|
||||
|
||||
To view existing cookies and their details:
|
||||
|
||||
1. Open **Settings** from the Launchpad.
|
||||
2. Go to **Integration** > **Manage Your Cookies**.
|
||||
|
||||
When needed, you can update them by re-uploading new cookie strings using the same steps as above.
|
||||
|
||||
### Remove cookies
|
||||
|
||||
If you no longer need access to a particular site, or want to clean up old credentials:
|
||||
|
||||
1. Open **Settings** from the Launchpad.
|
||||
2. Go to **Integration** > **Manage Your Cookies**.
|
||||
3. Find your target cookie item and click <i class="material-symbols-outlined">delete</i> or **Delete All**.
|
||||
|
||||
After removal, Wise will no longer use those cookies and may not be able to access protected content for that site until new cookies are provided.
|
||||
@@ -4,79 +4,93 @@ description: Learn how to manage content subscriptions in Olares, including addi
|
||||
---
|
||||
|
||||
# Subscribe and manage feeds
|
||||
|
||||
Wise offers flexible subscription options to help you follow your favorite content sources, including articles, blogs, podcasts, and video channels. This guide explains how to add and manage your subscriptions.
|
||||
|
||||
## Subscribe methods
|
||||
:::tip
|
||||
When you subscribe to podcast or video channels in Wise, new episodes automatically download to your Olares storage. This ensures your media content is always available—even offline—and protected from source deletion or unavailability.
|
||||
## Understand feeds
|
||||
|
||||
Subscribing to a feed creates a direct link to a content source. New entries will appear in the **Feeds** list automatically as they are published.
|
||||
|
||||
Please note the difference between viewing and keeping:
|
||||
|
||||
- **Feeds are for discovery**: You can open and read any entry from the feed list, but these items are temporary. If the feed changes or you unsubscribe, they may no longer be available.
|
||||
- **Your library is for ownership**: If you find an entry you want to keep or read later, you must **Save to library**. Only saved items become part of your library and can be managed with status, tags, notes, and filters.
|
||||
|
||||
## Add subscriptions
|
||||
|
||||
You can subscribe to feeds from within Wise or directly from your browser.
|
||||
|
||||
::: tip Handle restricted content
|
||||
If a link requires login or other access control, Wise may need cookies to fetch it correctly. To configure cookies for protected sites, see **[Manage cookies for Wise](./manage-cookies)**.
|
||||
:::
|
||||
|
||||
### Add subscriptions from For you
|
||||
When browsing recommended content on the **For you** page, you can subscribe to content sources using the following options:
|
||||
### Add feeds via link
|
||||
|
||||
* Click **Subscribe this Feed** in the **Info** column
|
||||
* Click <i class="material-symbols-outlined">bookmark_add</i> in the toolbar
|
||||
If you have a website or feed URL, you can subscribe using **Add Link**.
|
||||
|
||||
### Add RSS feeds manually
|
||||
1. Open the RSS feed dialog with either option:
|
||||
* Click <i class="material-symbols-outlined">add_circle</i> on the bottom left, and select **RSS feed**.
|
||||
* Click <i class="material-symbols-outlined">settings</i> on the bottom left, select **RSS feeds**, then click **Add feed** in the top right corner.
|
||||
2. In the dialog, enter the feed information using any of these formats:
|
||||
* Feed name. For example, `techcrunch`.
|
||||
* Website URL for RSS feed search.
|
||||
* Direct RSS link.
|
||||
3. Click **Add** to complete the subscription.
|
||||
1. Click <i class="material-symbols-outlined">add_circle</i> in the bottom-left menu bar and choose **Add Link**.
|
||||
2. Paste a website or feed URL. If one or more feeds are detected, they will be listed under the **Subscribe to RSS feed** section.
|
||||
3. Click <i class="material-symbols-outlined">bookmark_add</i> next to the feed you want to subscribe to.
|
||||
|
||||
### Import RSS feeds from OPML
|
||||
OPML files allow you to easily import RSS feed collections from other users or RSS readers. This is a convenient way to migrate your existing feed subscriptions or add curated feed collections.
|
||||
{width=300}
|
||||
|
||||
1. Click <i class="material-symbols-outlined">settings</i> in the bottom left corner and select **Preferences**.
|
||||
2. Under **Import/Export**, click **Import feeds from OPML file**.
|
||||
3. Select your OPML file and open it.
|
||||
The selected feed will be added to **Feeds**, and new entries from it will be fetched automatically.
|
||||
|
||||
After import, you can view and manage your RSS feeds under <i class="material-symbols-outlined">settings</i> > **RSS feeds**.
|
||||
### Import feeds from OPML files
|
||||
|
||||
:::info
|
||||
Only new feed subscriptions will be imported. Historical feed content from your previous reader won't be transferred.
|
||||
The OPML file imports your subscription list only, not the articles themselves.
|
||||
|
||||
Wise will fetch the latest available content from these sources immediately after import, but it cannot transfer your reading history or archived articles from your previous reader.
|
||||
:::
|
||||
### Use LarePass for web subscriptions
|
||||
:::tip
|
||||
LarePass extension is currently available for Chrome browsers only. Download it from the [official page](https://www.olares.com/larepass).
|
||||
:::
|
||||
1. Open the LarePass browser extension, and click **Collect**.
|
||||
2. For the current webpage, check available subscriptions in the **RSS** section.
|
||||
:::info
|
||||
The **RSS** option appears only when feeds are detected on the current page.
|
||||
:::
|
||||
3. Click <i class="material-symbols-outlined">bookmark_add</i> to add the feed to Wise.
|
||||
|
||||
:::tip Upload cookie
|
||||
If you already use another RSS reader, or someone shares a curated feed list, you can import those subscriptions using an OPML file.
|
||||
|
||||
Some websites require cookies for accessing content:
|
||||
1. Log in to the target website.
|
||||
2. Open the LarePass browser extension, and click **Collect** > **Cookie**.
|
||||
3. Click **Upload** to apply changes or enable **Auto Sync**.
|
||||
1. Click <i class="material-symbols-outlined">settings</i> in the bottom left corner and select **Preferences**.
|
||||
2. Under **Import/Export**, click **Import feeds from OPML**.
|
||||
3. Select your OPML file and open it.
|
||||
|
||||
You can hover over cookies to view details.
|
||||
:::
|
||||
## View subscription list
|
||||
Access all your RSS feed subscriptions from <i class="material-symbols-outlined">settings</i> > **RSS feeds**.
|
||||
After import, the feeds will appear under <i class="material-symbols-outlined">settings</i> > **RSS feeds**.
|
||||
|
||||
You can:
|
||||
### Use LarePass browser extension
|
||||
|
||||
* View feed details and descriptions
|
||||
* Search for specific feeds
|
||||
* Copy RSS links
|
||||
* Edit feed names and descriptions
|
||||
The [LarePass browser extension](https://www.olares.com/larepass) lets you subscribe to feeds while you browse, without switching back to Wise.
|
||||
|
||||
1. Open the LarePass browser extension and click the "Collect" icon.
|
||||
2. If one or more feeds are detected, they will be listed under the **Subscribe to RSS feed** section.
|
||||
3. Click <i class="material-symbols-outlined">bookmark_add</i> next to the feed you want to subscribe to.
|
||||

|
||||
|
||||
## Manage subscriptions
|
||||
|
||||
You can view, rename, organize, or remove feeds from the central management page or directly within the reader interface.
|
||||
|
||||
### View and edit details
|
||||
|
||||
1. Click <i class="material-symbols-outlined">settings</i> in the bottom left corner.
|
||||
2. Select **RSS feeds**.
|
||||
3. Perform the following operations as needed:
|
||||
- View feed details and descriptions.
|
||||
- Search for specific feeds.
|
||||
- Copy RSS links.
|
||||
- Edit feed names and descriptions.
|
||||
- Remove RSS links.
|
||||
|
||||
Changes here are reflected in the **Feeds** section of the Wise sidebar.
|
||||
|
||||
### Unsubscribe
|
||||
|
||||
If you no longer want to follow a source, you can unsubscribe from its feed.
|
||||
|
||||
## Unsubscribe
|
||||
:::warning
|
||||
Unsubscribing removes all articles from this feed unless they're saved to your Library. This action cannot be undone.
|
||||
When you unsubscribe from a feed, all entries from that feed are removed from Wise unless they have been explicitly saved to your library. This action cannot be undone.
|
||||
:::
|
||||
|
||||
You can unsubscribe from content sources in several ways:
|
||||
You can remove a feed subscription in several places:
|
||||
|
||||
* From the **Info** column
|
||||
* Through the reading page toolbar
|
||||
* Via the LarePass browser extension
|
||||
* On the **RSS Feeds management** page
|
||||
- From the **Info** panel of an entry belonging to that feed.
|
||||
{width=500}
|
||||
- From the reader toolbar while viewing an entry.
|
||||
{width=500}
|
||||
- From <i class="material-symbols-outlined">settings</i> > **RSS feeds** in Wise.
|
||||
{width=500}
|
||||
BIN
docs/public/images/manual/get-started/win-add-pc1.png
Normal file
|
After Width: | Height: | Size: 509 KiB |
|
After Width: | Height: | Size: 74 KiB |
BIN
docs/public/images/manual/larepass/download-first-restart.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
docs/public/images/manual/olares/authorize-pay-1.png
Normal file
|
After Width: | Height: | Size: 205 KiB |
BIN
docs/public/images/manual/olares/authorize-pay.png
Normal file
|
After Width: | Height: | Size: 208 KiB |
BIN
docs/public/images/manual/olares/authorize-purchase-1.png
Normal file
|
After Width: | Height: | Size: 199 KiB |
BIN
docs/public/images/manual/olares/authorize-purchase.png
Normal file
|
After Width: | Height: | Size: 201 KiB |
BIN
docs/public/images/manual/olares/clone-apps-1.png
Normal file
|
After Width: | Height: | Size: 962 KiB |
BIN
docs/public/images/manual/olares/clone-apps-result.png
Normal file
|
After Width: | Height: | Size: 993 KiB |
BIN
docs/public/images/manual/olares/clone-apps-support.png
Normal file
|
After Width: | Height: | Size: 303 KiB |
BIN
docs/public/images/manual/olares/clone-apps.png
Normal file
|
After Width: | Height: | Size: 957 KiB |
BIN
docs/public/images/manual/olares/file-search.png
Normal file
|
After Width: | Height: | Size: 42 KiB |