Compare commits
253 Commits
cli/fix/up
...
module-bfl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a61c37dea1 | ||
|
|
ac03f2a13d | ||
|
|
f6eb6574d6 | ||
|
|
9113e14b7a | ||
|
|
fc62d8280a | ||
|
|
cfb74ce1d2 | ||
|
|
5639d4844b | ||
|
|
f74fcec59e | ||
|
|
ddbb13533d | ||
|
|
b65a3e3514 | ||
|
|
1f110184bd | ||
|
|
90eed09f10 | ||
|
|
44ccf86032 | ||
|
|
67425162c2 | ||
|
|
8a786c7c5a | ||
|
|
c026e82615 | ||
|
|
e29c7f264e | ||
|
|
c98c855099 | ||
|
|
4ae552f33f | ||
|
|
f2aad6d9f6 | ||
|
|
02bc4fafd5 | ||
|
|
b8d6e2f3cc | ||
|
|
763c80c5fa | ||
|
|
3091e40ff0 | ||
|
|
8d34cc995d | ||
|
|
a19e81a4a0 | ||
|
|
ee3f2a7df2 | ||
|
|
73ea65b004 | ||
|
|
4ef2e7124a | ||
|
|
ef46f91ec7 | ||
|
|
0f5a346d86 | ||
|
|
caa799e902 | ||
|
|
2be5f6d108 | ||
|
|
05f3c8ffdc | ||
|
|
c0e242b05c | ||
|
|
7929e420b1 | ||
|
|
66de213f43 | ||
|
|
2166cec66f | ||
|
|
1a0f9727c4 | ||
|
|
810253fe94 | ||
|
|
23429a6193 | ||
|
|
49e40f316f | ||
|
|
1e7b655826 | ||
|
|
adea16ce7e | ||
|
|
c2222859a5 | ||
|
|
e7dde2ff51 | ||
|
|
d06c1e8a99 | ||
|
|
131faacce0 | ||
|
|
8133704761 | ||
|
|
09e61aecad | ||
|
|
bc5fd5fd82 | ||
|
|
1367355661 | ||
|
|
2a506be19a | ||
|
|
30195f1513 | ||
|
|
88b140ccc2 | ||
|
|
39947f464c | ||
|
|
698bdf96ed | ||
|
|
69e6ac35f8 | ||
|
|
f41e66b39a | ||
|
|
1a36faaf6d | ||
|
|
cbdd08d237 | ||
|
|
2fd9d23371 | ||
|
|
f1714534db | ||
|
|
9bc66369df | ||
|
|
ba85b0f60d | ||
|
|
7c2624d418 | ||
|
|
7eb21516d0 | ||
|
|
266aef8616 | ||
|
|
3755bede0c | ||
|
|
cca39eed7e | ||
|
|
b27b90b9a8 | ||
|
|
119ec75234 | ||
|
|
8739bfc040 | ||
|
|
6304739725 | ||
|
|
f8f452b27f | ||
|
|
36acf0384d | ||
|
|
aa5b073b5c | ||
|
|
18dfae6c87 | ||
|
|
a54445db8b | ||
|
|
375e2c4f63 | ||
|
|
c366b56de9 | ||
|
|
85d90a36ed | ||
|
|
172c5342d8 | ||
|
|
dcc0ab1cd2 | ||
|
|
b078f80b5a | ||
|
|
854e25096f | ||
|
|
78949de2b6 | ||
|
|
bd72cb8067 | ||
|
|
3b9f0d33a3 | ||
|
|
3e782c6cea | ||
|
|
28c2979db0 | ||
|
|
fc8ade657d | ||
|
|
74c80a9c7e | ||
|
|
51a06f8964 | ||
|
|
0c50d93d77 | ||
|
|
17b8d2d96e | ||
|
|
5b5e5d289c | ||
|
|
b113f66c4f | ||
|
|
bbbe3ecf9b | ||
|
|
b7ff5db985 | ||
|
|
f39e359ef8 | ||
|
|
4a80ef6148 | ||
|
|
c4af7a5783 | ||
|
|
5c498fbe18 | ||
|
|
4fbe32b141 | ||
|
|
46fc840302 | ||
|
|
5677026de0 | ||
|
|
4d95152e0a | ||
|
|
9560985965 | ||
|
|
1b6d90c2a5 | ||
|
|
2c73b3b7f8 | ||
|
|
22c52398ed | ||
|
|
d1e55515d4 | ||
|
|
5db251520d | ||
|
|
d2b630c7b4 | ||
|
|
0debd332a8 | ||
|
|
9a2c58e3fa | ||
|
|
b8842cfe61 | ||
|
|
70e170b71a | ||
|
|
e975e4aec8 | ||
|
|
9d6d242625 | ||
|
|
86d7b985a2 | ||
|
|
31a2b3ee28 | ||
|
|
9aa7e0b108 | ||
|
|
9092f28458 | ||
|
|
f925268cd4 | ||
|
|
e1c19f7327 | ||
|
|
5e925e0cb6 | ||
|
|
6a0885d37d | ||
|
|
3e46af80e1 | ||
|
|
74c48b81fb | ||
|
|
56aed6b683 | ||
|
|
cbfcf3d3aa | ||
|
|
fd23e52723 | ||
|
|
b48368b934 | ||
|
|
ca9ce45353 | ||
|
|
fa148969c5 | ||
|
|
21c1884bb8 | ||
|
|
b517d08981 | ||
|
|
73e2cd0eb4 | ||
|
|
a631db1e9e | ||
|
|
f3b59b9b3e | ||
|
|
910bf02b48 | ||
|
|
dcc909a06e | ||
|
|
1238ad01f1 | ||
|
|
77ee176f5e | ||
|
|
1d9c3f7b4a | ||
|
|
8a52737f89 | ||
|
|
bd7c46a663 | ||
|
|
9ee4af9040 | ||
|
|
fc86bbadc2 | ||
|
|
52118b1126 | ||
|
|
76be9e82c0 | ||
|
|
478d9f28c8 | ||
|
|
114ed5ad7b | ||
|
|
c85b23d9a9 | ||
|
|
fbc61764ca | ||
|
|
d866966531 | ||
|
|
d140849d7c | ||
|
|
679ddb0f8d | ||
|
|
0ec0a5a4ac | ||
|
|
74ecf9f73d | ||
|
|
028c5c7bdb | ||
|
|
f3ab03becc | ||
|
|
e408da75a4 | ||
|
|
8ffbc82ebd | ||
|
|
304dbf69c5 | ||
|
|
66b0144b40 | ||
|
|
e91a76f92f | ||
|
|
45cd406cd4 | ||
|
|
7ef7ae9335 | ||
|
|
f2f342a28a | ||
|
|
fdca458e4f | ||
|
|
b7141373b7 | ||
|
|
21118c8e95 | ||
|
|
307a6bb502 | ||
|
|
91ec932c95 | ||
|
|
a1cb16cfe9 | ||
|
|
aec5e178b3 | ||
|
|
2624ea5dc5 | ||
|
|
0d1bae720d | ||
|
|
96520a8bc3 | ||
|
|
27b9356037 | ||
|
|
c289d5837c | ||
|
|
e6f9922951 | ||
|
|
a3ad8ce78c | ||
|
|
c70587062a | ||
|
|
f7306b66dc | ||
|
|
325bfeb90d | ||
|
|
bfc3ca0720 | ||
|
|
ef071e43ca | ||
|
|
7440e85c2e | ||
|
|
d71747928c | ||
|
|
473898a715 | ||
|
|
637b1839f7 | ||
|
|
1f1c1a8d3b | ||
|
|
1ddcc3bd4c | ||
|
|
96a2eb524a | ||
|
|
b20d5c0876 | ||
|
|
c4fc3198bb | ||
|
|
260b6154f3 | ||
|
|
ecfcd0d1d8 | ||
|
|
be7f3b3c3f | ||
|
|
99c6d3860d | ||
|
|
9f56cf0f05 | ||
|
|
76c8e93822 | ||
|
|
d38d0d0e1d | ||
|
|
65b32c7c41 | ||
|
|
f6f14e8d9a | ||
|
|
f8653692b1 | ||
|
|
5264df60cc | ||
|
|
1a200ed17c | ||
|
|
48fdaa5481 | ||
|
|
570fe070c9 | ||
|
|
6b18bbd94d | ||
|
|
c6836f9859 | ||
|
|
288869d91d | ||
|
|
8ea8a0857e | ||
|
|
87674cc5d9 | ||
|
|
11f556e9af | ||
|
|
d2d3195fea | ||
|
|
ad3b138284 | ||
|
|
ff609db1aa | ||
|
|
43c6bff906 | ||
|
|
b28dac652c | ||
|
|
fbb5c08227 | ||
|
|
a04d363597 | ||
|
|
994d2b9b91 | ||
|
|
909b7656fd | ||
|
|
c61260cb5a | ||
|
|
fed1a60c63 | ||
|
|
7062408f5d | ||
|
|
583ec7730c | ||
|
|
e9f3b23ac9 | ||
|
|
7f09420bdf | ||
|
|
c93869db02 | ||
|
|
2f23def478 | ||
|
|
4c5c43982a | ||
|
|
a2a6c581c2 | ||
|
|
8b1a7e11f5 | ||
|
|
2181adb67c | ||
|
|
e1b0bd7875 | ||
|
|
e465a2d8fc | ||
|
|
70d0ae1ff5 | ||
|
|
e52db36045 | ||
|
|
1935b1fbb6 | ||
|
|
5dc69bf80e | ||
|
|
e839d5ae41 | ||
|
|
e89c6f35cc | ||
|
|
c4a7c81777 | ||
|
|
a69b5d40a9 | ||
|
|
bab074cd37 | ||
|
|
afb7d49455 |
2
.github/workflows/check.yaml
vendored
2
.github/workflows/check.yaml
vendored
@@ -75,7 +75,7 @@ jobs:
|
||||
steps:
|
||||
- id: generate
|
||||
run: |
|
||||
v=1.12.4-$(echo $RANDOM$RANDOM)
|
||||
v=1.12.5-$(echo $RANDOM$RANDOM)
|
||||
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
upload-cli:
|
||||
|
||||
2
.github/workflows/release-cli.yaml
vendored
2
.github/workflows/release-cli.yaml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.24.3
|
||||
go-version: 1.24.11
|
||||
|
||||
- name: Install x86_64 cross-compiler
|
||||
run: sudo apt-get update && sudo apt-get install -y build-essential
|
||||
|
||||
2
.github/workflows/release-daemon.yaml
vendored
2
.github/workflows/release-daemon.yaml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.22.1
|
||||
go-version: 1.24.11
|
||||
|
||||
- name: install udev-devel and pcap-devel
|
||||
run: |
|
||||
|
||||
2
.github/workflows/release-daily.yaml
vendored
2
.github/workflows/release-daily.yaml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- id: generate
|
||||
run: |
|
||||
v=1.12.4-$(date +"%Y%m%d")
|
||||
v=1.12.5-$(date +"%Y%m%d")
|
||||
echo "version=$v" >> "$GITHUB_OUTPUT"
|
||||
|
||||
release-id:
|
||||
|
||||
@@ -54,6 +54,7 @@ rules:
|
||||
- "/system/configuration/encoding"
|
||||
- "/api/search/get_directory/"
|
||||
- "/api/search/sync_search/"
|
||||
- "/api/share/smb_share_user/"
|
||||
verbs: ["*"]
|
||||
|
||||
---
|
||||
|
||||
@@ -317,7 +317,7 @@ spec:
|
||||
chown -R 1000:1000 /uploadstemp && \
|
||||
chown -R 1000:1000 /appdata
|
||||
- name: olares-app-init
|
||||
image: beclab/system-frontend:v1.6.28
|
||||
image: beclab/system-frontend:v1.8.3
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
@@ -439,7 +439,7 @@ spec:
|
||||
- name: NATS_SUBJECT_VAULT
|
||||
value: os.vault.{{ .Values.bfl.username}}
|
||||
- name: user-service
|
||||
image: beclab/user-service:v0.0.81
|
||||
image: beclab/user-service:v0.0.83
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
@@ -1356,6 +1356,17 @@ data:
|
||||
proxy_set_header Connection '$connection_upgrade';
|
||||
more_set_headers 'Upgrade: $http_upgrade';
|
||||
}
|
||||
location /api/refresh {
|
||||
add_header Access-Control-Allow-Headers "access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,content-type,x-auth,x-unauth-error,x-authorization";
|
||||
add_header Access-Control-Allow-Methods "PUT, GET, DELETE, POST, OPTIONS";
|
||||
add_header Access-Control-Allow-Origin $http_origin;
|
||||
add_header Access-Control-Allow-Credentials true;
|
||||
proxy_pass http://authelia-backend-svc:9091;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
}
|
||||
location / {
|
||||
proxy_pass http://headscale-server-svc:8080;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
@@ -12,4 +12,5 @@ rules:
|
||||
- "/task/*"
|
||||
- "/search/*"
|
||||
- "/monitorsetting/*"
|
||||
- "/file/*"
|
||||
verbs: ["*"]
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: wizard
|
||||
image: beclab/wizard:v1.6.5
|
||||
image: beclab/wizard:v1.6.40
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
201
apps/README.md
201
apps/README.md
@@ -17,4 +17,203 @@ This directory contains the code for system applications, primarily for LarePass
|
||||
| Settings | A system configuration application. |
|
||||
| Dashboard | An app for monitoring system resource usage. |
|
||||
| Control Hub | The console for Olares, providing precise and autonomous control over the system and its environment. |
|
||||
| DevBox | A development tool for building and deploying Olares applications. |
|
||||
| Studio | A development tool for building and deploying Olares applications. |
|
||||
|
||||
|
||||
# Local Development Guide
|
||||
|
||||
This document describes how to start and develop various sub-projects locally.
|
||||
|
||||
## Available Projects
|
||||
|
||||
| Project | Command | Port |
|
||||
|---------|---------|------|
|
||||
| Desktop | `npm run dev:desktop` | 1090 |
|
||||
| Files | `npm run dev:files` | 5090 |
|
||||
| Settings | `npm run dev:settings` | 9000 |
|
||||
| Market | `npm run dev:market` | 8080 |
|
||||
| Vault | `npm run dev:vault` | 8090 |
|
||||
| Wise | `npm run dev:wise` | 8100 |
|
||||
| Dashboard | `npm run dev:dashboard` | 9003 |
|
||||
| Control Hub | `npm run dev:hub` | 9002 |
|
||||
| Share | `npm run dev:share` | 5070 |
|
||||
| Editor | `npm run dev:editor` | 9100 |
|
||||
| Preview | `npm run dev:preview` | 9001 |
|
||||
| Studio | `npm run dev:studio` | 9001 |
|
||||
|
||||
## Step 1: Modify Local Hosts File
|
||||
|
||||
Projects require access through a specific domain name. You need to configure the local hosts file first.
|
||||
|
||||
### macOS / Linux
|
||||
|
||||
1. Open terminal and edit the hosts file with administrator privileges:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/hosts
|
||||
```
|
||||
|
||||
Or use the nano editor:
|
||||
|
||||
```bash
|
||||
sudo nano /etc/hosts
|
||||
```
|
||||
|
||||
2. Add the following content at the end of the file:
|
||||
|
||||
```
|
||||
127.0.0.1 test.xxx.olares.com
|
||||
```
|
||||
|
||||
3. Save the file and exit
|
||||
- vim: Press `ESC`, type `:wq` and press Enter
|
||||
- nano: Press `Ctrl + O` to save, `Ctrl + X` to exit
|
||||
|
||||
### Windows
|
||||
|
||||
1. Run Notepad as administrator:
|
||||
- Search for "Notepad" in the Start menu
|
||||
- Right-click on "Notepad" and select "Run as administrator"
|
||||
|
||||
2. Open the hosts file in Notepad:
|
||||
- Click `File` -> `Open`
|
||||
- Paste the path in the filename field: `C:\Windows\System32\drivers\etc\hosts`
|
||||
- Change file type to "All Files (*.*)"
|
||||
- Click "Open"
|
||||
|
||||
3. Add the following content at the end of the file:
|
||||
|
||||
```
|
||||
127.0.0.1 test.xxx.olares.com
|
||||
```
|
||||
|
||||
4. Save the file (`Ctrl + S`)
|
||||
|
||||
5. Flush DNS cache (optional):
|
||||
- Open Command Prompt (CMD) as administrator
|
||||
- Run the following command:
|
||||
|
||||
```cmd
|
||||
ipconfig /flushdns
|
||||
```
|
||||
|
||||
## Step 2: Install Dependencies
|
||||
|
||||
Run in the project root directory (`olares-app`):
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
## Step 3: Configure Environment Variables
|
||||
|
||||
Create or edit the `.env` file in the `packages/app` directory and add the following content:
|
||||
|
||||
```env
|
||||
ACCOUNT_DOMAIN=xxx.olares.com
|
||||
DEV_DOMAIN=test.xxx.olares.com
|
||||
```
|
||||
|
||||
> **Note**:
|
||||
> - `ACCOUNT_DOMAIN`: Your Olares account domain, used for API proxy
|
||||
> - `DEV_DOMAIN`: Local development server domain, must match the domain configured in the hosts file
|
||||
|
||||
## Step 4: Start the Project
|
||||
|
||||
After configuring the `.env` file, run the corresponding command in the `packages/app` directory:
|
||||
|
||||
```bash
|
||||
# Start Desktop
|
||||
npm run dev:desktop
|
||||
|
||||
# Start Files
|
||||
npm run dev:files
|
||||
|
||||
# Start Settings
|
||||
npm run dev:settings
|
||||
|
||||
# Start Market
|
||||
npm run dev:market
|
||||
|
||||
# Start other projects...
|
||||
npm run dev:<project>
|
||||
```
|
||||
|
||||
## Step 5: Access the Application
|
||||
|
||||
After successful startup, visit in your browser (replace port according to the project):
|
||||
|
||||
| Project | URL |
|
||||
|---------|-----|
|
||||
| Desktop | `https://test.xxx.olares.com:1090` |
|
||||
| Files | `https://test.xxx.olares.com:5090` |
|
||||
| Settings | `https://test.xxx.olares.com:9000` |
|
||||
| Market | `https://test.xxx.olares.com:8080` |
|
||||
| Vault | `https://test.xxx.olares.com:8090` |
|
||||
| Wise | `https://test.xxx.olares.com:8100` |
|
||||
| Dashboard | `https://test.xxx.olares.com:9003` |
|
||||
| Control Hub | `https://test.xxx.olares.com:9002` |
|
||||
| Share | `https://test.xxx.olares.com:5070` |
|
||||
| Editor | `https://test.xxx.olares.com:9100` |
|
||||
| Preview | `https://test.xxx.olares.com:9001` |
|
||||
| Studio | `https://test.xxx.olares.com:9001` |
|
||||
|
||||
> **Note**: Since a self-signed certificate is used, the browser may display an insecure connection warning. Click "Advanced" and select "Proceed" to continue.
|
||||
|
||||
## Environment Variables (.env file)
|
||||
|
||||
| Variable | Description | Example |
|
||||
|----------|-------------|---------|
|
||||
| `ACCOUNT_DOMAIN` | Account domain (for API proxy) | `xxx.olares.com` |
|
||||
| `DEV_DOMAIN` | Development server domain | `test.xxx.olares.com` |
|
||||
|
||||
## FAQ
|
||||
|
||||
### 1. Cannot Access the Application
|
||||
|
||||
- Check if the hosts file is configured correctly
|
||||
- Ensure the development server has started successfully
|
||||
- Check if the firewall is blocking the corresponding port
|
||||
|
||||
### 2. Certificate Error
|
||||
|
||||
The development server uses HTTPS. The browser will show a certificate warning on first visit - this is expected behavior.
|
||||
|
||||
### 3. API Request Failed
|
||||
|
||||
Ensure the `ACCOUNT_DOMAIN` in the `.env` file is set correctly. The proxy configuration relies on this variable to forward requests to the correct backend service.
|
||||
|
||||
## Build for Production
|
||||
|
||||
```bash
|
||||
# Build Desktop
|
||||
npm run build:desktop
|
||||
|
||||
# Build Files
|
||||
npm run build:files
|
||||
|
||||
# Build Settings
|
||||
npm run build:settings
|
||||
|
||||
# Build other projects...
|
||||
npm run build:<project>
|
||||
```
|
||||
|
||||
### Build Output Directory
|
||||
|
||||
| Project | Output Directory |
|
||||
|---------|------------------|
|
||||
| Desktop | `dist/apps/desktop` |
|
||||
| Files | `dist/apps/files` |
|
||||
| Settings | `dist/apps/settings` |
|
||||
| Market | `dist/apps/market` |
|
||||
| Vault | `dist/apps/vault` |
|
||||
| Dashboard | `dist/apps/dashboard` |
|
||||
| Control Hub | `dist/apps/control-hub` |
|
||||
| Share | `dist/apps/share` |
|
||||
| Editor | `dist/apps/editor` |
|
||||
| Preview | `dist/apps/preview` |
|
||||
| **Wise** | `dist/spa` |
|
||||
| **Studio** | `dist/spa` |
|
||||
|
||||
> **Note**: Build outputs for Wise and Studio are located in `dist/spa` directory, not under `dist/apps/`.
|
||||
@@ -1,2 +1,2 @@
|
||||
DEV_DOMAIN=test.guotest334.olares.cn
|
||||
ACCOUNT_DOMAIN=guotest334.olares.cn
|
||||
DEV_DOMAIN=test.xxx.olares.com
|
||||
ACCOUNT_DOMAIN=xxx.olares.com
|
||||
|
||||
@@ -62,6 +62,8 @@ module.exports = configure(function (ctx) {
|
||||
|
||||
env: {
|
||||
PL_SERVER_URL: process.env.PL_SERVER_URL,
|
||||
VAULT_MOCK_BFL_TOKEN: process.env.VAULT_MOCK_BFL_TOKEN,
|
||||
VAULT_MOCK_PASSWORD: process.env.VAULT_MOCK_PASSWORD,
|
||||
PLATFORM: process.env.PLATFORM,
|
||||
DEV_PLATFORM: process.env.DEV_PLATFORM,
|
||||
APPLICATION_SUB: process.env.APPLICATION_SUB,
|
||||
|
||||
@@ -107,4 +107,6 @@ export interface NativeAppPlatform extends AppPlatform {
|
||||
getQuasar(): QVueGlobals | undefined;
|
||||
|
||||
getRouter(): Router | undefined;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -78,4 +78,16 @@ export interface AppPlatform extends Platform, PlatformExtension {
|
||||
isTabbarDisplay(): boolean;
|
||||
|
||||
userAgent: string;
|
||||
|
||||
socialKeys: {
|
||||
facebook: {
|
||||
appId: string;
|
||||
clientToken: string;
|
||||
},
|
||||
google: {
|
||||
webClientId: string;
|
||||
iOSClientId: string;
|
||||
androidClientId: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ClientSchema } from '../../../../globals';
|
||||
import { i18n } from '../../../../boot/i18n';
|
||||
import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc';
|
||||
import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social';
|
||||
import { getAppPlatform } from 'src/application/platform';
|
||||
|
||||
export async function facebookLogin(
|
||||
did: string,
|
||||
@@ -22,12 +23,8 @@ export async function facebookLogin(
|
||||
}
|
||||
const manifest = stringToBase64(JSON.stringify(schema?.manifest));
|
||||
|
||||
// await FacebookLogin.initialize({ appId: '549140590110570' });
|
||||
await LarePassSocialLogin.initialize({
|
||||
facebook: {
|
||||
appId: '549140590110570',
|
||||
clientToken: '82fca90b3fa47e9083aa7dba75744ee0'
|
||||
}
|
||||
facebook: getAppPlatform().socialKeys.facebook
|
||||
});
|
||||
|
||||
const FACEBOOK_PERMISSIONS = ['email'];
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ClientSchema } from '../../../../globals';
|
||||
import { i18n } from '../../../../boot/i18n';
|
||||
import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc';
|
||||
import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social';
|
||||
import { getAppPlatform } from 'src/application/platform';
|
||||
|
||||
export async function googleLogin(
|
||||
did: string,
|
||||
@@ -22,10 +23,10 @@ export async function googleLogin(
|
||||
await LarePassSocialLogin.initialize({
|
||||
google: {
|
||||
webClientId:
|
||||
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms
|
||||
getAppPlatform().socialKeys.google.webClientId,
|
||||
iOSClientId:
|
||||
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS
|
||||
mode: 'online' // replaces grantOfflineAccess
|
||||
getAppPlatform().socialKeys.google.iOSClientId,
|
||||
mode: 'online'
|
||||
}
|
||||
});
|
||||
await LarePassSocialLogin.logout({ provider: 'google' });
|
||||
|
||||
@@ -45,15 +45,14 @@ export default defineComponent({
|
||||
const bfl_token = ref<string>('');
|
||||
|
||||
if (process.env.PL_SERVER_URL) {
|
||||
bfl_token.value =
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg3NzU0OTQsImlhdCI6MTY3ODc2ODI5NCwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.Yr7OhrQ39OXmesVJldORZ34UsFZpiiCWpssKlRxEOR4';
|
||||
bfl_token.value = process.env.VAULT_MOCK_BFL_TOKEN;
|
||||
}
|
||||
|
||||
const url = ref<string>(
|
||||
base_url +
|
||||
'?bfl_token=' +
|
||||
bfl_token.value +
|
||||
'&username=liuyu&password=Test123456'
|
||||
`&username=liuyu&password=${process.env.VAULT_MOCK_PASSWORD}`
|
||||
);
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -112,7 +112,6 @@ const genOlares = async ({ text, from, to }) => {
|
||||
const init = {
|
||||
headers: {
|
||||
'Content-type': 'application/json'
|
||||
// 'X-Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NzMzMjE1MjUsImlhdCI6MTc0MTc4NTUyNSwidXNlcm5hbWUiOiJ5YW5neW9uZ2hlbmciLCJncm91cHMiOlsibGxkYXBfcmVndWxhciJdfQ.V3CHWllD4GETOklamEg-hwhT5DR4lKZGLEgpOULpW_ZXuZ-MTYvOFoZatWVWs6wQjT8IrLHF6leyUI09qsgZuw'
|
||||
},
|
||||
method: 'POST',
|
||||
body: JSON.stringify(params)
|
||||
|
||||
@@ -70,4 +70,16 @@ export class SubAppPlatform extends WebPlatform implements AppPlatform {
|
||||
}
|
||||
|
||||
userAgent = navigator.userAgent;
|
||||
|
||||
socialKeys = {
|
||||
facebook: {
|
||||
appId: '',
|
||||
clientToken: ''
|
||||
},
|
||||
google: {
|
||||
webClientId: '',
|
||||
iOSClientId: '',
|
||||
androidClientId: ''
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,10 +19,9 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
|
||||
];
|
||||
await LarePassSocialLogin.initialize({
|
||||
google: {
|
||||
webClientId:
|
||||
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms
|
||||
webClientId: getAppPlatform().socialKeys.google.webClientId,
|
||||
iOSClientId:
|
||||
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS
|
||||
getAppPlatform().socialKeys.google.iOSClientId,
|
||||
mode: getAppPlatform().getQuasar()?.platform.is?.android
|
||||
? 'offline'
|
||||
: 'online' // replaces grantOfflineAccess
|
||||
@@ -45,8 +44,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
|
||||
let clientId = '';
|
||||
|
||||
if (getAppPlatform().getQuasar()?.platform.is?.android) {
|
||||
clientId =
|
||||
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com';
|
||||
clientId = getAppPlatform().socialKeys.google.androidClientId;
|
||||
response = await axiosInstanceProxy(
|
||||
{
|
||||
baseURL: 'https://cloud-api.jointerminus.com/',
|
||||
@@ -68,8 +66,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
|
||||
);
|
||||
}
|
||||
} else {
|
||||
clientId =
|
||||
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com';
|
||||
clientId = getAppPlatform().socialKeys.google.iOSClientId;
|
||||
}
|
||||
|
||||
const result = {
|
||||
|
||||
@@ -5,6 +5,16 @@ import level from 'level';
|
||||
|
||||
const TERMINUS_NAME = process.env.TERMINUS_NAME || 'did';
|
||||
|
||||
const REFRESH_TOKEN = process.env.REFRESH_TOKEN || '';
|
||||
|
||||
const ACCESS_TOKEN = process.env.ACCESS_TOKEN || '';
|
||||
|
||||
const SESSION_ID = process.env.SESSION_ID || '';
|
||||
|
||||
const BASE32_SECRET = process.env.BASE32_SECRET || ''
|
||||
|
||||
const OTP_AUTH_URL = process.env.OPT_AUTH_URL || '';
|
||||
|
||||
export interface UserInfo {
|
||||
olaresId: string;
|
||||
wizardStatus: string;
|
||||
@@ -259,9 +269,8 @@ export class ApiControllers {
|
||||
const result = {
|
||||
status: 'OK',
|
||||
data: {
|
||||
base32_secret: 'Z6JJH64KWRFXPBHTHVPF2XZT6INZEKVTMSLWPIFNKXXS2FSZ3QUQ',
|
||||
otpauth_url:
|
||||
'otpauth://totp/authelia.com:liuyu?algorithm=SHA1&digits=6&issuer=authelia.com&period=30&secret=Z6JJH64KWRFXPBHTHVPF2XZT6INZEKVTMSLWPIFNKXXS2FSZ3QUQ'
|
||||
base32_secret: BASE32_SECRET,
|
||||
otpauth_url: OTP_AUTH_URL
|
||||
}
|
||||
};
|
||||
|
||||
@@ -294,14 +303,6 @@ export class ApiControllers {
|
||||
const username = request.body['username'];
|
||||
const password = request.body['password'];
|
||||
|
||||
// if (password !== '123456') {
|
||||
// response.set('Content-Type', 'application/json');
|
||||
// response.status(401).send({
|
||||
// status: 'Failed'
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (username != TERMINUS_NAME.split('@')[0]) {
|
||||
response.set('Content-Type', 'application/json');
|
||||
|
||||
@@ -314,13 +315,11 @@ export class ApiControllers {
|
||||
const result = {
|
||||
status: 'OK',
|
||||
data: {
|
||||
access_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
|
||||
refresh_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
|
||||
access_token: ACCESS_TOKEN,
|
||||
refresh_token: REFRESH_TOKEN,
|
||||
fa2: true,
|
||||
redirect: '',
|
||||
session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
|
||||
session_id: SESSION_ID
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,20 +333,13 @@ export class ApiControllers {
|
||||
const result: any = {
|
||||
status: 'OK',
|
||||
data: {
|
||||
access_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
|
||||
refresh_token:
|
||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
|
||||
access_token: ACCESS_TOKEN,
|
||||
refresh_token: REFRESH_TOKEN,
|
||||
fa2: true,
|
||||
redirect: '/abcd',
|
||||
session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
|
||||
session_id: SESSION_ID
|
||||
}
|
||||
};
|
||||
// if (request.body.token !== '123456') {
|
||||
// result = {
|
||||
// status: 'Failed'
|
||||
// };
|
||||
// }
|
||||
|
||||
response.set('Content-Type', 'application/json');
|
||||
response.send(result);
|
||||
|
||||
@@ -1044,16 +1044,6 @@ export class Controller extends API {
|
||||
// }
|
||||
// }
|
||||
|
||||
// {
|
||||
// @didvault/server: status: 'OK',
|
||||
// @didvault/server: data: {
|
||||
// @didvault/server: redirect: '',
|
||||
// @didvault/server: access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
|
||||
// @didvault/server: refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
|
||||
// @didvault/server: fa2: true,
|
||||
// @didvault/server: session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
|
||||
// @didvault/server: }
|
||||
// @didvault/server: }
|
||||
// async cert_firstfactor(
|
||||
// username: string,
|
||||
// password: string,
|
||||
|
||||
@@ -18,7 +18,7 @@ fi
|
||||
if [[ x"$VERSION" == x"" ]]; then
|
||||
if [[ "$LOCAL_RELEASE" == "1" ]]; then
|
||||
ts=$(date +%Y%m%d%H%M%S)
|
||||
export VERSION="1.12.4-$ts"
|
||||
export VERSION="1.12.5-$ts"
|
||||
echo "will build and use a local release of Olares with version: $VERSION"
|
||||
echo ""
|
||||
else
|
||||
@@ -28,7 +28,7 @@ fi
|
||||
|
||||
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then
|
||||
echo "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
|
||||
echo "for example: VERSION=1.12.4-20241124 bash $0"
|
||||
echo "for example: VERSION=1.12.5-20241124 bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -66,13 +66,7 @@ if ! command_exists tar; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ x"$KUBE_TYPE" == x"" ]]; then
|
||||
echo "the KUBE_TYPE env var is not set, defaulting to \"k3s\""
|
||||
echo ""
|
||||
export KUBE_TYPE="k3s"
|
||||
fi
|
||||
|
||||
BASE_DIR="$HOME/.olares"
|
||||
export BASE_DIR="$HOME/.olares"
|
||||
if [ ! -d $BASE_DIR ]; then
|
||||
mkdir -p $BASE_DIR
|
||||
fi
|
||||
@@ -148,10 +142,6 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
PARAMS="--version $VERSION --base-dir $BASE_DIR"
|
||||
KUBE_PARAM="--kube $KUBE_TYPE"
|
||||
CDN="--cdn-service ${cdn_url}"
|
||||
|
||||
if [[ -f $BASE_DIR/.prepared ]]; then
|
||||
echo "file $BASE_DIR/.prepared detected, skip preparing phase"
|
||||
echo ""
|
||||
@@ -162,7 +152,7 @@ else
|
||||
echo ""
|
||||
else
|
||||
echo "building local release ..."
|
||||
$sh_c "$INSTALL_OLARES_CLI release $PARAMS $CDN"
|
||||
$sh_c "$INSTALL_OLARES_CLI release"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to build local release"
|
||||
exit 1
|
||||
@@ -171,16 +161,13 @@ else
|
||||
else
|
||||
echo "running system prechecks ..."
|
||||
echo ""
|
||||
$sh_c "$INSTALL_OLARES_CLI precheck $PARAMS"
|
||||
$sh_c "$INSTALL_OLARES_CLI precheck"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
echo "downloading installation wizard..."
|
||||
echo ""
|
||||
if [[ ! -z "$RELEASE_ID_SUFFIX" ]]; then
|
||||
DOWNLOAD_WIZARD_RELEASE_ID_PARAM="--release-id $RELEASE_ID"
|
||||
fi
|
||||
$sh_c "$INSTALL_OLARES_CLI download wizard $PARAMS $KUBE_PARAM $CDN $DOWNLOAD_WIZARD_RELEASE_ID_PARAM"
|
||||
$sh_c "$INSTALL_OLARES_CLI download wizard"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to download installation wizard"
|
||||
exit 1
|
||||
@@ -189,7 +176,7 @@ else
|
||||
|
||||
echo "downloading installation packages..."
|
||||
echo ""
|
||||
$sh_c "$INSTALL_OLARES_CLI download component $PARAMS $KUBE_PARAM $CDN"
|
||||
$sh_c "$INSTALL_OLARES_CLI download component"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to download installation packages"
|
||||
exit 1
|
||||
@@ -197,11 +184,7 @@ else
|
||||
|
||||
echo "preparing installation environment..."
|
||||
echo ""
|
||||
# env 'REGISTRY_MIRRORS' is a docker image cache mirrors, separated by commas
|
||||
if [ x"$REGISTRY_MIRRORS" != x"" ]; then
|
||||
extra="--registry-mirrors $REGISTRY_MIRRORS"
|
||||
fi
|
||||
$sh_c "$INSTALL_OLARES_CLI prepare $PARAMS $KUBE_PARAM $extra"
|
||||
$sh_c "$INSTALL_OLARES_CLI prepare"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to prepare installation environment"
|
||||
exit 1
|
||||
@@ -218,38 +201,18 @@ if [ "$PREINSTALL" == "1" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ "$JUICEFS" == "1" ]]; then
|
||||
echo "JuiceFS is enabled"
|
||||
fsflag="--with-juicefs=true"
|
||||
if [[ "$STORAGE" == "" ]]; then
|
||||
echo "installing MinIO ..."
|
||||
else
|
||||
echo "checking storage config ..."
|
||||
fi
|
||||
$sh_c "$INSTALL_OLARES_CLI install storage $PARAMS"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "configuring storage ..."
|
||||
$sh_c "$INSTALL_OLARES_CLI install storage"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to configure storage"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$SWAPPINESS" ]]; then
|
||||
swapflag="$swapflag --swappiness $SWAPPINESS"
|
||||
fi
|
||||
if [[ "$ENABLE_POD_SWAP" == "1" ]]; then
|
||||
swapflag="$swapflag --enable-pod-swap"
|
||||
fi
|
||||
if [[ "$ENABLE_ZRAM" == "1" ]]; then
|
||||
swapflag="$swapflag --enable-zram"
|
||||
fi
|
||||
if [[ -n "$ZRAM_SIZE" ]]; then
|
||||
swapflag="$swapflag --zram-size $ZRAM_SIZE"
|
||||
fi
|
||||
if [[ -n "$ZRAM_SWAP_PRIORITY" ]]; then
|
||||
swapflag="$swapflag --zram-swap-priority $ZRAM_SWAP_PRIORITY"
|
||||
fi
|
||||
|
||||
echo "installing Olares..."
|
||||
echo ""
|
||||
$sh_c "$INSTALL_OLARES_CLI install $PARAMS $KUBE_PARAM $fsflag $swapflag"
|
||||
$sh_c "$INSTALL_OLARES_CLI install"
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo "error: failed to install Olares"
|
||||
|
||||
@@ -158,7 +158,7 @@ export VERSION="#__VERSION__"
|
||||
|
||||
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then
|
||||
echo "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
|
||||
echo "for example: VERSION=1.12.4-20241124 bash $0"
|
||||
echo "for example: VERSION=1.12.5-20241124 bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -36,6 +36,10 @@ fi
|
||||
|
||||
|
||||
find $BASE_DIR/../ -type f -name Olares.yaml | while read f; do
|
||||
if [[ "$f" == *"/vendor/"* ]]; then
|
||||
echo "skip vendor file $f"
|
||||
continue
|
||||
fi
|
||||
echo "Processing $f"
|
||||
declare -a bins
|
||||
IFS=
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type Addon struct {
|
||||
Name string `yaml:"name" json:"name,omitempty"`
|
||||
Namespace string `yaml:"namespace" json:"namespace,omitempty"`
|
||||
Sources Sources `yaml:"sources" json:"sources,omitempty"`
|
||||
Retries int `yaml:"retries" json:"retries,omitempty"`
|
||||
Delay int `yaml:"delay" json:"delay,omitempty"`
|
||||
}
|
||||
|
||||
type Sources struct {
|
||||
Chart Chart `yaml:"chart" json:"chart,omitempty"`
|
||||
Yaml Yaml `yaml:"yaml" json:"yaml,omitempty"`
|
||||
}
|
||||
|
||||
type Chart struct {
|
||||
Name string `yaml:"name" json:"name,omitempty"`
|
||||
Repo string `yaml:"repo" json:"repo,omitempty"`
|
||||
Path string `yaml:"path" json:"path,omitempty"`
|
||||
Version string `yaml:"version" json:"version,omitempty"`
|
||||
ValuesFile string `yaml:"valuesFile" json:"valuesFile,omitempty"`
|
||||
Values []string `yaml:"values" json:"values,omitempty"`
|
||||
}
|
||||
|
||||
type Yaml struct {
|
||||
Path []string `yaml:"path" json:"path,omitempty"`
|
||||
}
|
||||
@@ -1,403 +0,0 @@
|
||||
/*
|
||||
Copyright 2021.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// ClusterSpec defines the desired state of Cluster
|
||||
type ClusterSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
// Foo is an example field of Cluster. Edit Cluster_types.go to remove/update
|
||||
Hosts []HostCfg `yaml:"hosts" json:"hosts,omitempty"`
|
||||
RoleGroups RoleGroups `yaml:"roleGroups" json:"roleGroups,omitempty"`
|
||||
ControlPlaneEndpoint ControlPlaneEndpoint `yaml:"controlPlaneEndpoint" json:"controlPlaneEndpoint,omitempty"`
|
||||
Kubernetes Kubernetes `yaml:"kubernetes" json:"kubernetes,omitempty"`
|
||||
Network NetworkConfig `yaml:"network" json:"network,omitempty"`
|
||||
Registry RegistryConfig `yaml:"registry" json:"registry,omitempty"`
|
||||
Addons []Addon `yaml:"addons" json:"addons,omitempty"`
|
||||
KubeSphere KubeSphere `json:"kubesphere,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterStatus defines the observed state of Cluster
|
||||
type ClusterStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
JobInfo JobInfo `json:"jobInfo,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
NetworkPlugin string `json:"networkPlugin,omitempty"`
|
||||
NodesCount int `json:"nodesCount,omitempty"`
|
||||
EtcdCount int `json:"etcdCount,omitempty"`
|
||||
MasterCount int `json:"masterCount,omitempty"`
|
||||
WorkerCount int `json:"workerCount,omitempty"`
|
||||
Nodes []NodeStatus `json:"nodes,omitempty"`
|
||||
Conditions []Condition `json:"Conditions,omitempty"`
|
||||
}
|
||||
|
||||
// JobInfo defines the job information to be used to create a cluster or add a node.
|
||||
type JobInfo struct {
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Pods []PodInfo `json:"pods,omitempty"`
|
||||
}
|
||||
|
||||
// PodInfo defines the pod information to be used to create a cluster or add a node.
|
||||
type PodInfo struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Containers []ContainerInfo `json:"containers,omitempty"`
|
||||
}
|
||||
|
||||
// ContainerInfo defines the container information to be used to create a cluster or add a node.
|
||||
type ContainerInfo struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// NodeStatus defines the status information of the nodes in the cluster.
|
||||
type NodeStatus struct {
|
||||
InternalIP string `json:"internalIP,omitempty"`
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
Roles map[string]bool `json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
// Condition defines the process information.
|
||||
type Condition struct {
|
||||
Step string `json:"step,omitempty"`
|
||||
StartTime metav1.Time `json:"startTime,omitempty"`
|
||||
EndTime metav1.Time `json:"endTime,omitempty"`
|
||||
Status bool `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +genclient:nonNamespaced
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
|
||||
// Cluster is the Schema for the clusters API
|
||||
// +kubebuilder:resource:path=clusters,scope=Cluster
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ClusterSpec `json:"spec,omitempty"`
|
||||
Status ClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// ClusterList contains a list of Cluster
|
||||
type ClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
}
|
||||
|
||||
// HostCfg defines host information for cluster.
|
||||
type HostCfg struct {
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
Address string `yaml:"address,omitempty" json:"address,omitempty"`
|
||||
InternalAddress string `yaml:"internalAddress,omitempty" json:"internalAddress,omitempty"`
|
||||
Port int `yaml:"port,omitempty" json:"port,omitempty"`
|
||||
User string `yaml:"user,omitempty" json:"user,omitempty"`
|
||||
Password string `yaml:"password,omitempty" json:"password,omitempty"`
|
||||
PrivateKey string `yaml:"privateKey,omitempty" json:"privateKey,omitempty"`
|
||||
PrivateKeyPath string `yaml:"privateKeyPath,omitempty" json:"privateKeyPath,omitempty"`
|
||||
Arch string `yaml:"arch,omitempty" json:"arch,omitempty"`
|
||||
|
||||
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
|
||||
ID string `yaml:"id,omitempty" json:"id,omitempty"`
|
||||
Index int `json:"-"`
|
||||
IsEtcd bool `json:"-"`
|
||||
IsMaster bool `json:"-"`
|
||||
IsWorker bool `json:"-"`
|
||||
|
||||
EtcdExist bool `json:"-"`
|
||||
EtcdName string `json:"-"`
|
||||
}
|
||||
|
||||
// RoleGroups defines the grouping of role for hosts (etcd / master / worker).
|
||||
type RoleGroups struct {
|
||||
Etcd []string `yaml:"etcd" json:"etcd,omitempty"`
|
||||
Master []string `yaml:"master" json:"master,omitempty"`
|
||||
Worker []string `yaml:"worker" json:"worker,omitempty"`
|
||||
}
|
||||
|
||||
// HostGroups defines the grouping of hosts for cluster (all / etcd / master / worker / k8s).
|
||||
type HostGroups struct {
|
||||
All []HostCfg
|
||||
Etcd []HostCfg
|
||||
Master []HostCfg
|
||||
Worker []HostCfg
|
||||
K8s []HostCfg
|
||||
}
|
||||
|
||||
// ControlPlaneEndpoint defines the control plane endpoint information for cluster.
|
||||
type ControlPlaneEndpoint struct {
|
||||
InternalLoadbalancer string `yaml:"internalLoadbalancer" json:"internalLoadbalancer,omitempty"`
|
||||
Domain string `yaml:"domain" json:"domain,omitempty"`
|
||||
Address string `yaml:"address" json:"address,omitempty"`
|
||||
Port int `yaml:"port" json:"port,omitempty"`
|
||||
}
|
||||
|
||||
// RegistryConfig defines the configuration information of the image's repository.
|
||||
type RegistryConfig struct {
|
||||
RegistryMirrors []string `yaml:"registryMirrors" json:"registryMirrors,omitempty"`
|
||||
InsecureRegistries []string `yaml:"insecureRegistries" json:"insecureRegistries,omitempty"`
|
||||
PrivateRegistry string `yaml:"privateRegistry" json:"privateRegistry,omitempty"`
|
||||
}
|
||||
|
||||
// KubeSphere defines the configuration information of the KubeSphere.
|
||||
type KubeSphere struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Configurations string `json:"configurations,omitempty"`
|
||||
}
|
||||
|
||||
// ExternalEtcd defines configuration information of external etcd.
|
||||
type ExternalEtcd struct {
|
||||
Endpoints []string
|
||||
CaFile string
|
||||
CertFile string
|
||||
KeyFile string
|
||||
}
|
||||
|
||||
// Copy is used to create a copy for Runtime.
|
||||
func (h *HostCfg) Copy() *HostCfg {
|
||||
host := *h
|
||||
return &host
|
||||
}
|
||||
|
||||
// GenerateCertSANs is used to generate cert sans for cluster.
|
||||
func (cfg *ClusterSpec) GenerateCertSANs() []string {
|
||||
clusterSvc := fmt.Sprintf("kubernetes.default.svc.%s", cfg.Kubernetes.ClusterName)
|
||||
defaultCertSANs := []string{"kubernetes", "kubernetes.default", "kubernetes.default.svc", clusterSvc, "localhost", "127.0.0.1"}
|
||||
extraCertSANs := []string{}
|
||||
|
||||
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Domain)
|
||||
extraCertSANs = append(extraCertSANs, cfg.ControlPlaneEndpoint.Address)
|
||||
|
||||
for _, host := range cfg.Hosts {
|
||||
extraCertSANs = append(extraCertSANs, host.Name)
|
||||
extraCertSANs = append(extraCertSANs, fmt.Sprintf("%s.%s", host.Name, cfg.Kubernetes.ClusterName))
|
||||
if host.Address != cfg.ControlPlaneEndpoint.Address {
|
||||
extraCertSANs = append(extraCertSANs, host.Address)
|
||||
}
|
||||
if host.InternalAddress != host.Address && host.InternalAddress != cfg.ControlPlaneEndpoint.Address {
|
||||
extraCertSANs = append(extraCertSANs, host.InternalAddress)
|
||||
}
|
||||
}
|
||||
|
||||
extraCertSANs = append(extraCertSANs, util.ParseIp(cfg.Network.KubeServiceCIDR)[0])
|
||||
|
||||
defaultCertSANs = append(defaultCertSANs, extraCertSANs...)
|
||||
|
||||
if cfg.Kubernetes.ApiserverCertExtraSans != nil {
|
||||
defaultCertSANs = append(defaultCertSANs, cfg.Kubernetes.ApiserverCertExtraSans...)
|
||||
}
|
||||
|
||||
return defaultCertSANs
|
||||
}
|
||||
|
||||
// GroupHosts is used to group hosts according to the configuration file.s
|
||||
func (cfg *ClusterSpec) GroupHosts() (*HostGroups, error) {
|
||||
clusterHostsGroups := HostGroups{}
|
||||
|
||||
hostList := map[string]string{}
|
||||
for _, host := range cfg.Hosts {
|
||||
hostList[host.Name] = host.Name
|
||||
}
|
||||
|
||||
etcdGroup, masterGroup, workerGroup, err := cfg.ParseRolesList(hostList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for index, host := range cfg.Hosts {
|
||||
host.Index = index
|
||||
if len(etcdGroup) > 0 {
|
||||
for _, hostName := range etcdGroup {
|
||||
if host.Name == hostName {
|
||||
host.IsEtcd = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(masterGroup) > 0 {
|
||||
for _, hostName := range masterGroup {
|
||||
if host.Name == hostName {
|
||||
host.IsMaster = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(workerGroup) > 0 {
|
||||
for _, hostName := range workerGroup {
|
||||
if hostName != "" && host.Name == hostName {
|
||||
host.IsWorker = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if host.IsEtcd {
|
||||
clusterHostsGroups.Etcd = append(clusterHostsGroups.Etcd, host)
|
||||
}
|
||||
if host.IsMaster {
|
||||
clusterHostsGroups.Master = append(clusterHostsGroups.Master, host)
|
||||
}
|
||||
if host.IsWorker {
|
||||
clusterHostsGroups.Worker = append(clusterHostsGroups.Worker, host)
|
||||
}
|
||||
if host.IsMaster || host.IsWorker {
|
||||
clusterHostsGroups.K8s = append(clusterHostsGroups.K8s, host)
|
||||
}
|
||||
clusterHostsGroups.All = append(clusterHostsGroups.All, host)
|
||||
}
|
||||
|
||||
//Check that the parameters under roleGroups are incorrect
|
||||
if len(masterGroup) == 0 {
|
||||
logger.Fatal(errors.New("The number of master cannot be 0"))
|
||||
}
|
||||
if len(etcdGroup) == 0 {
|
||||
logger.Fatal(errors.New("The number of etcd cannot be 0"))
|
||||
}
|
||||
|
||||
if len(masterGroup) != len(clusterHostsGroups.Master) {
|
||||
return nil, errors.New("Incorrect nodeName under roleGroups/master in the configuration file")
|
||||
}
|
||||
if len(etcdGroup) != len(clusterHostsGroups.Etcd) {
|
||||
return nil, errors.New("Incorrect nodeName under roleGroups/etcd in the configuration file")
|
||||
}
|
||||
if len(workerGroup) != len(clusterHostsGroups.Worker) {
|
||||
return nil, errors.New("Incorrect nodeName under roleGroups/work in the configuration file")
|
||||
}
|
||||
|
||||
return &clusterHostsGroups, nil
|
||||
}
|
||||
|
||||
// ClusterIP is used to get the kube-apiserver service address inside the cluster.
|
||||
func (cfg *ClusterSpec) ClusterIP() string {
|
||||
return util.ParseIp(cfg.Network.KubeServiceCIDR)[0]
|
||||
}
|
||||
|
||||
// CorednsClusterIP is used to get the coredns service address inside the cluster.
|
||||
func (cfg *ClusterSpec) CorednsClusterIP() string {
|
||||
return util.ParseIp(cfg.Network.KubeServiceCIDR)[2]
|
||||
}
|
||||
|
||||
// ClusterDNS is used to get the dns server address inside the cluster.
|
||||
func (cfg *ClusterSpec) ClusterDNS() string {
|
||||
if cfg.Kubernetes.EnableNodelocaldns() {
|
||||
return "169.254.25.10"
|
||||
}
|
||||
return cfg.CorednsClusterIP()
|
||||
}
|
||||
|
||||
// ParseRolesList is used to parse the host grouping list.
|
||||
func (cfg *ClusterSpec) ParseRolesList(hostList map[string]string) ([]string, []string, []string, error) {
|
||||
etcdGroupList := []string{}
|
||||
masterGroupList := []string{}
|
||||
workerGroupList := []string{}
|
||||
|
||||
for _, host := range cfg.RoleGroups.Etcd {
|
||||
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
|
||||
etcdGroupList = append(etcdGroupList, getHostsRange(host, hostList, "etcd")...)
|
||||
} else {
|
||||
if err := hostVerify(hostList, host, "etcd"); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
etcdGroupList = append(etcdGroupList, host)
|
||||
}
|
||||
}
|
||||
|
||||
for _, host := range cfg.RoleGroups.Master {
|
||||
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
|
||||
masterGroupList = append(masterGroupList, getHostsRange(host, hostList, "master")...)
|
||||
} else {
|
||||
if err := hostVerify(hostList, host, "master"); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
masterGroupList = append(masterGroupList, host)
|
||||
}
|
||||
}
|
||||
|
||||
for _, host := range cfg.RoleGroups.Worker {
|
||||
if strings.Contains(host, "[") && strings.Contains(host, "]") && strings.Contains(host, ":") {
|
||||
workerGroupList = append(workerGroupList, getHostsRange(host, hostList, "worker")...)
|
||||
} else {
|
||||
if err := hostVerify(hostList, host, "worker"); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
workerGroupList = append(workerGroupList, host)
|
||||
}
|
||||
}
|
||||
return etcdGroupList, masterGroupList, workerGroupList, nil
|
||||
}
|
||||
|
||||
func getHostsRange(rangeStr string, hostList map[string]string, group string) []string {
|
||||
hostRangeList := []string{}
|
||||
r := regexp.MustCompile(`\[(\d+)\:(\d+)\]`)
|
||||
nameSuffix := r.FindStringSubmatch(rangeStr)
|
||||
namePrefix := strings.Split(rangeStr, nameSuffix[0])[0]
|
||||
nameSuffixStart, _ := strconv.Atoi(nameSuffix[1])
|
||||
nameSuffixEnd, _ := strconv.Atoi(nameSuffix[2])
|
||||
for i := nameSuffixStart; i <= nameSuffixEnd; i++ {
|
||||
if err := hostVerify(hostList, fmt.Sprintf("%s%d", namePrefix, i), group); err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
hostRangeList = append(hostRangeList, fmt.Sprintf("%s%d", namePrefix, i))
|
||||
}
|
||||
return hostRangeList
|
||||
}
|
||||
|
||||
func hostVerify(hostList map[string]string, hostName string, group string) error {
|
||||
if _, ok := hostList[hostName]; !ok {
|
||||
return fmt.Errorf("[%s] is in [%s] group, but not in hosts list", hostName, group)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
Haproxy = "haproxy"
|
||||
)
|
||||
|
||||
func (c ControlPlaneEndpoint) IsInternalLBEnabled() bool {
|
||||
if c.InternalLoadbalancer == Haproxy {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPreDir = "kubekey"
|
||||
DefaultTmpDir = "/tmp/kubekey"
|
||||
DefaultSSHPort = 22
|
||||
DefaultLBPort = 6443
|
||||
DefaultLBDomain = "lb.kubesphere.local"
|
||||
DefaultNetworkPlugin = "calico"
|
||||
DefaultPodsCIDR = "10.233.64.0/18"
|
||||
DefaultServiceCIDR = "10.233.0.0/18"
|
||||
DefaultKubeImageNamespace = "kubesphere"
|
||||
DefaultClusterName = "cluster.local"
|
||||
DefaultArch = "amd64"
|
||||
DefaultEtcdVersion = "v3.4.13"
|
||||
DefaultEtcdPort = "2379"
|
||||
DefaultDockerVersion = "20.10.8"
|
||||
DefaultCrictlVersion = "v1.22.0"
|
||||
DefaultKubeVersion = "v1.21.5"
|
||||
DefaultCalicoVersion = "v3.20.0"
|
||||
DefaultFlannelVersion = "v0.12.0"
|
||||
DefaultCniVersion = "v0.9.1"
|
||||
DefaultCiliumVersion = "v1.8.3"
|
||||
DefaultKubeovnVersion = "v1.5.0"
|
||||
DefaultHelmVersion = "v3.6.3"
|
||||
DefaultMaxPods = 200
|
||||
DefaultNodeCidrMaskSize = 24
|
||||
DefaultIPIPMode = "Always"
|
||||
DefaultVXLANMode = "Never"
|
||||
DefaultVethMTU = 1440
|
||||
DefaultBackendMode = "vxlan"
|
||||
DefaultProxyMode = "ipvs"
|
||||
DefaultCrioEndpoint = "unix:///var/run/crio/crio.sock"
|
||||
DefaultContainerdEndpoint = "unix:///run/containerd/containerd.sock"
|
||||
DefaultIsulaEndpoint = "unix:///var/run/isulad.sock"
|
||||
Etcd = "etcd"
|
||||
Master = "master"
|
||||
Worker = "worker"
|
||||
K8s = "k8s"
|
||||
DefaultEtcdBackupDir = "/var/backups/kube_etcd"
|
||||
DefaultEtcdBackupPeriod = 30
|
||||
DefaultKeepBackNumber = 5
|
||||
DefaultEtcdBackupScriptDir = "/usr/local/bin/kube-scripts"
|
||||
DefaultJoinCIDR = "100.64.0.0/16"
|
||||
DefaultNetworkType = "geneve"
|
||||
DefaultVlanID = "100"
|
||||
DefaultOvnLabel = "node-role.kubernetes.io/control-plane"
|
||||
DefaultDPDKVersion = "19.11"
|
||||
DefaultDNSAddress = "114.114.114.114"
|
||||
|
||||
Docker = "docker"
|
||||
Containerd = "containerd"
|
||||
Crio = "crio"
|
||||
Isula = "isula"
|
||||
)
|
||||
|
||||
func (cfg *ClusterSpec) SetDefaultClusterSpec(incluster bool) (*ClusterSpec, *HostGroups, error) {
|
||||
clusterCfg := ClusterSpec{}
|
||||
|
||||
clusterCfg.Hosts = SetDefaultHostsCfg(cfg)
|
||||
clusterCfg.RoleGroups = cfg.RoleGroups
|
||||
hostGroups, err := clusterCfg.GroupHosts()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
clusterCfg.ControlPlaneEndpoint = SetDefaultLBCfg(cfg, hostGroups.Master, incluster)
|
||||
clusterCfg.Network = SetDefaultNetworkCfg(cfg)
|
||||
clusterCfg.Kubernetes = SetDefaultClusterCfg(cfg)
|
||||
clusterCfg.Registry = cfg.Registry
|
||||
clusterCfg.Addons = cfg.Addons
|
||||
clusterCfg.KubeSphere = cfg.KubeSphere
|
||||
|
||||
if cfg.Kubernetes.ClusterName == "" {
|
||||
clusterCfg.Kubernetes.ClusterName = DefaultClusterName
|
||||
}
|
||||
if cfg.Kubernetes.Version == "" {
|
||||
clusterCfg.Kubernetes.Version = DefaultKubeVersion
|
||||
}
|
||||
if cfg.Kubernetes.MaxPods == 0 {
|
||||
clusterCfg.Kubernetes.MaxPods = DefaultMaxPods
|
||||
}
|
||||
if cfg.Kubernetes.NodeCidrMaskSize == 0 {
|
||||
clusterCfg.Kubernetes.NodeCidrMaskSize = DefaultNodeCidrMaskSize
|
||||
}
|
||||
if cfg.Kubernetes.ProxyMode == "" {
|
||||
clusterCfg.Kubernetes.ProxyMode = DefaultProxyMode
|
||||
}
|
||||
return &clusterCfg, hostGroups, nil
|
||||
}
|
||||
|
||||
func SetDefaultHostsCfg(cfg *ClusterSpec) []HostCfg {
|
||||
var hostscfg []HostCfg
|
||||
if len(cfg.Hosts) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, host := range cfg.Hosts {
|
||||
if len(host.Address) == 0 && len(host.InternalAddress) > 0 {
|
||||
host.Address = host.InternalAddress
|
||||
}
|
||||
if len(host.InternalAddress) == 0 && len(host.Address) > 0 {
|
||||
host.InternalAddress = host.Address
|
||||
}
|
||||
if host.User == "" {
|
||||
host.User = "root"
|
||||
}
|
||||
if host.Port == 0 {
|
||||
host.Port = DefaultSSHPort
|
||||
}
|
||||
if host.PrivateKey == "" {
|
||||
if host.Password == "" && host.PrivateKeyPath == "" {
|
||||
host.PrivateKeyPath = "~/.ssh/id_rsa"
|
||||
}
|
||||
if host.PrivateKeyPath != "" && strings.HasPrefix(strings.TrimSpace(host.PrivateKeyPath), "~/") {
|
||||
homeDir, _ := util.Home()
|
||||
host.PrivateKeyPath = strings.Replace(host.PrivateKeyPath, "~/", fmt.Sprintf("%s/", homeDir), 1)
|
||||
}
|
||||
}
|
||||
|
||||
if host.Arch == "" {
|
||||
host.Arch = DefaultArch
|
||||
}
|
||||
hostscfg = append(hostscfg, host)
|
||||
}
|
||||
return hostscfg
|
||||
}
|
||||
|
||||
func SetDefaultLBCfg(cfg *ClusterSpec, masterGroup []HostCfg, incluster bool) ControlPlaneEndpoint {
|
||||
if !incluster {
|
||||
//The detection is not an HA environment, and the address at LB does not need input
|
||||
if len(masterGroup) == 1 && cfg.ControlPlaneEndpoint.Address != "" {
|
||||
fmt.Println("When the environment is not HA, the LB address does not need to be entered, so delete the corresponding value.")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
//Check whether LB should be configured
|
||||
if len(masterGroup) >= 3 && !cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address == "" {
|
||||
fmt.Println("When the environment has at least three masters, You must set the value of the LB address or enable the internal loadbalancer.")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Check whether LB address and the internal LB are both enabled
|
||||
if cfg.ControlPlaneEndpoint.IsInternalLBEnabled() && cfg.ControlPlaneEndpoint.Address != "" {
|
||||
fmt.Println("You cannot set up the internal load balancer and the LB address at the same time.")
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
if cfg.ControlPlaneEndpoint.Address == "" || cfg.ControlPlaneEndpoint.Address == "127.0.0.1" {
|
||||
cfg.ControlPlaneEndpoint.Address = masterGroup[0].InternalAddress
|
||||
}
|
||||
if cfg.ControlPlaneEndpoint.Domain == "" {
|
||||
cfg.ControlPlaneEndpoint.Domain = DefaultLBDomain
|
||||
}
|
||||
if cfg.ControlPlaneEndpoint.Port == 0 {
|
||||
cfg.ControlPlaneEndpoint.Port = DefaultLBPort
|
||||
}
|
||||
defaultLbCfg := cfg.ControlPlaneEndpoint
|
||||
return defaultLbCfg
|
||||
}
|
||||
|
||||
func SetDefaultNetworkCfg(cfg *ClusterSpec) NetworkConfig {
|
||||
if cfg.Network.Plugin == "" {
|
||||
cfg.Network.Plugin = DefaultNetworkPlugin
|
||||
}
|
||||
if cfg.Network.KubePodsCIDR == "" {
|
||||
cfg.Network.KubePodsCIDR = DefaultPodsCIDR
|
||||
}
|
||||
if cfg.Network.KubeServiceCIDR == "" {
|
||||
cfg.Network.KubeServiceCIDR = DefaultServiceCIDR
|
||||
}
|
||||
if cfg.Network.Calico.IPIPMode == "" {
|
||||
cfg.Network.Calico.IPIPMode = DefaultIPIPMode
|
||||
}
|
||||
if cfg.Network.Calico.VXLANMode == "" {
|
||||
cfg.Network.Calico.VXLANMode = DefaultVXLANMode
|
||||
}
|
||||
if cfg.Network.Calico.VethMTU == 0 {
|
||||
cfg.Network.Calico.VethMTU = DefaultVethMTU
|
||||
}
|
||||
if cfg.Network.Flannel.BackendMode == "" {
|
||||
cfg.Network.Flannel.BackendMode = DefaultBackendMode
|
||||
}
|
||||
// kube-ovn default config
|
||||
if cfg.Network.Kubeovn.JoinCIDR == "" {
|
||||
cfg.Network.Kubeovn.JoinCIDR = DefaultJoinCIDR
|
||||
}
|
||||
if cfg.Network.Kubeovn.Label == "" {
|
||||
cfg.Network.Kubeovn.Label = DefaultOvnLabel
|
||||
}
|
||||
if cfg.Network.Kubeovn.VlanID == "" {
|
||||
cfg.Network.Kubeovn.VlanID = DefaultVlanID
|
||||
}
|
||||
if cfg.Network.Kubeovn.NetworkType == "" {
|
||||
cfg.Network.Kubeovn.NetworkType = DefaultNetworkType
|
||||
}
|
||||
if cfg.Network.Kubeovn.PingerExternalAddress == "" {
|
||||
cfg.Network.Kubeovn.PingerExternalAddress = DefaultDNSAddress
|
||||
}
|
||||
if cfg.Network.Kubeovn.DpdkVersion == "" {
|
||||
cfg.Network.Kubeovn.DpdkVersion = DefaultDPDKVersion
|
||||
}
|
||||
defaultNetworkCfg := cfg.Network
|
||||
|
||||
return defaultNetworkCfg
|
||||
}
|
||||
|
||||
func SetDefaultClusterCfg(cfg *ClusterSpec) Kubernetes {
|
||||
if cfg.Kubernetes.Version == "" {
|
||||
cfg.Kubernetes.Version = DefaultKubeVersion
|
||||
} else {
|
||||
s := strings.Split(cfg.Kubernetes.Version, "-")
|
||||
if len(s) > 1 {
|
||||
cfg.Kubernetes.Version = s[0]
|
||||
cfg.Kubernetes.Type = s[1]
|
||||
}
|
||||
}
|
||||
if cfg.Kubernetes.ClusterName == "" {
|
||||
cfg.Kubernetes.ClusterName = DefaultClusterName
|
||||
}
|
||||
if cfg.Kubernetes.EtcdBackupDir == "" {
|
||||
cfg.Kubernetes.EtcdBackupDir = DefaultEtcdBackupDir
|
||||
}
|
||||
if cfg.Kubernetes.EtcdBackupPeriod == 0 {
|
||||
cfg.Kubernetes.EtcdBackupPeriod = DefaultEtcdBackupPeriod
|
||||
}
|
||||
if cfg.Kubernetes.KeepBackupNumber == 0 {
|
||||
cfg.Kubernetes.KeepBackupNumber = DefaultKeepBackNumber
|
||||
}
|
||||
if cfg.Kubernetes.EtcdBackupScriptDir == "" {
|
||||
cfg.Kubernetes.EtcdBackupScriptDir = DefaultEtcdBackupScriptDir
|
||||
}
|
||||
if cfg.Kubernetes.ContainerManager == "" {
|
||||
cfg.Kubernetes.ContainerManager = Docker
|
||||
}
|
||||
if cfg.Kubernetes.ContainerRuntimeEndpoint == "" {
|
||||
switch cfg.Kubernetes.ContainerManager {
|
||||
case Docker:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
|
||||
case Crio:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultCrioEndpoint
|
||||
case Containerd:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultContainerdEndpoint
|
||||
case Isula:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = DefaultIsulaEndpoint
|
||||
default:
|
||||
cfg.Kubernetes.ContainerRuntimeEndpoint = ""
|
||||
}
|
||||
}
|
||||
defaultClusterCfg := cfg.Kubernetes
|
||||
|
||||
return defaultClusterCfg
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2021.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package v1alpha1 contains API Schema definitions for the kubekey v1alpha1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=kubekey.kubesphere.io
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = GroupVersion
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "kubekey.kubesphere.io", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return GroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
type Kubernetes struct {
|
||||
Type string `yaml:"type" json:"type,omitempty"`
|
||||
Version string `yaml:"version" json:"version,omitempty"`
|
||||
ClusterName string `yaml:"clusterName" json:"clusterName,omitempty"`
|
||||
MasqueradeAll bool `yaml:"masqueradeAll" json:"masqueradeAll,omitempty"`
|
||||
MaxPods int `yaml:"maxPods" json:"maxPods,omitempty"`
|
||||
NodeCidrMaskSize int `yaml:"nodeCidrMaskSize" json:"nodeCidrMaskSize,omitempty"`
|
||||
ApiserverCertExtraSans []string `yaml:"apiserverCertExtraSans" json:"apiserverCertExtraSans,omitempty"`
|
||||
ProxyMode string `yaml:"proxyMode" json:"proxyMode,omitempty"`
|
||||
// +optional
|
||||
Nodelocaldns *bool `yaml:"nodelocaldns" json:"nodelocaldns,omitempty"`
|
||||
EtcdBackupDir string `yaml:"etcdBackupDir" json:"etcdBackupDir,omitempty"`
|
||||
EtcdBackupPeriod int `yaml:"etcdBackupPeriod" json:"etcdBackupPeriod,omitempty"`
|
||||
KeepBackupNumber int `yaml:"keepBackupNumber" json:"keepBackupNumber,omitempty"`
|
||||
EtcdBackupScriptDir string `yaml:"etcdBackupScript" json:"etcdBackupScript,omitempty"`
|
||||
ContainerManager string `yaml:"containerManager" json:"containerManager,omitempty"`
|
||||
ContainerRuntimeEndpoint string `yaml:"containerRuntimeEndpoint" json:"containerRuntimeEndpoint,omitempty"`
|
||||
ApiServerArgs []string `yaml:"apiserverArgs" json:"apiserverArgs,omitempty"`
|
||||
ControllerManagerArgs []string `yaml:"controllerManagerArgs" json:"controllerManagerArgs,omitempty"`
|
||||
SchedulerArgs []string `yaml:"schedulerArgs" json:"schedulerArgs,omitempty"`
|
||||
KubeletArgs []string `yaml:"kubeletArgs" json:"kubeletArgs,omitempty"`
|
||||
KubeProxyArgs []string `yaml:"kubeProxyArgs" json:"kubeProxyArgs,omitempty"`
|
||||
KubeletConfiguration runtime.RawExtension `yaml:"kubeletConfiguration" json:"kubeletConfiguration,omitempty"`
|
||||
KubeProxyConfiguration runtime.RawExtension `yaml:"kubeProxyConfiguration" json:"kubeProxyConfiguration,omitempty"`
|
||||
}
|
||||
|
||||
// EnableNodelocaldns is used to determine whether to deploy nodelocaldns.
|
||||
func (k *Kubernetes) EnableNodelocaldns() bool {
|
||||
if k.Nodelocaldns == nil {
|
||||
return true
|
||||
}
|
||||
return *k.Nodelocaldns
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
type NetworkConfig struct {
|
||||
Plugin string `yaml:"plugin" json:"plugin,omitempty"`
|
||||
KubePodsCIDR string `yaml:"kubePodsCIDR" json:"kubePodsCIDR,omitempty"`
|
||||
KubeServiceCIDR string `yaml:"kubeServiceCIDR" json:"kubeServiceCIDR,omitempty"`
|
||||
Calico CalicoCfg `yaml:"calico" json:"calico,omitempty"`
|
||||
Flannel FlannelCfg `yaml:"flannel" json:"flannel,omitempty"`
|
||||
Kubeovn KubeovnCfg `yaml:"kubeovn" json:"kubeovn,omitempty"`
|
||||
}
|
||||
|
||||
type CalicoCfg struct {
|
||||
IPIPMode string `yaml:"ipipMode" json:"ipipMode,omitempty"`
|
||||
VXLANMode string `yaml:"vxlanMode" json:"vxlanMode,omitempty"`
|
||||
VethMTU int `yaml:"vethMTU" json:"vethMTU,omitempty"`
|
||||
}
|
||||
|
||||
type FlannelCfg struct {
|
||||
BackendMode string `yaml:"backendMode" json:"backendMode,omitempty"`
|
||||
Directrouting bool `yaml:"directRouting" json:"directRouting,omitempty"`
|
||||
}
|
||||
|
||||
type KubeovnCfg struct {
|
||||
JoinCIDR string `yaml:"joinCIDR" json:"joinCIDR,omitempty"`
|
||||
NetworkType string `yaml:"networkType" json:"networkType,omitempty"`
|
||||
Label string `yaml:"label" json:"label,omitempty"`
|
||||
Iface string `yaml:"iface" json:"iface,omitempty"`
|
||||
VlanInterfaceName string `yaml:"vlanInterfaceName" json:"vlanInterfaceName,omitempty"`
|
||||
VlanID string `yaml:"vlanID" json:"vlanID,omitempty"`
|
||||
DpdkMode bool `yaml:"dpdkMode" json:"dpdkMode,omitempty"`
|
||||
EnableSSL bool `yaml:"enableSSL" json:"enableSSL,omitempty"`
|
||||
EnableMirror bool `yaml:"enableMirror" json:"enableMirror,omitempty"`
|
||||
HwOffload bool `yaml:"hwOffload" json:"hwOffload,omitempty"`
|
||||
DpdkVersion string `yaml:"dpdkVersion" json:"dpdkVersion,omitempty"`
|
||||
PingerExternalAddress string `yaml:"pingerExternalAddress" json:"pingerExternalAddress,omitempty"`
|
||||
PingerExternalDomain string `yaml:"pingerExternalDomain" json:"pingerExternalDomain,omitempty"`
|
||||
}
|
||||
@@ -1,611 +0,0 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2020 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Addon) DeepCopyInto(out *Addon) {
|
||||
*out = *in
|
||||
in.Sources.DeepCopyInto(&out.Sources)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Addon.
|
||||
func (in *Addon) DeepCopy() *Addon {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Addon)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CalicoCfg) DeepCopyInto(out *CalicoCfg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CalicoCfg.
|
||||
func (in *CalicoCfg) DeepCopy() *CalicoCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CalicoCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Chart) DeepCopyInto(out *Chart) {
|
||||
*out = *in
|
||||
if in.Values != nil {
|
||||
in, out := &in.Values, &out.Values
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Chart.
|
||||
func (in *Chart) DeepCopy() *Chart {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Chart)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Cluster) DeepCopyInto(out *Cluster) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||
func (in *Cluster) DeepCopy() *Cluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Cluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Cluster) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Cluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
||||
func (in *ClusterList) DeepCopy() *ClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
||||
*out = *in
|
||||
if in.Hosts != nil {
|
||||
in, out := &in.Hosts, &out.Hosts
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
in.RoleGroups.DeepCopyInto(&out.RoleGroups)
|
||||
out.ControlPlaneEndpoint = in.ControlPlaneEndpoint
|
||||
in.Kubernetes.DeepCopyInto(&out.Kubernetes)
|
||||
out.Network = in.Network
|
||||
in.Registry.DeepCopyInto(&out.Registry)
|
||||
if in.Addons != nil {
|
||||
in, out := &in.Addons, &out.Addons
|
||||
*out = make([]Addon, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.KubeSphere = in.KubeSphere
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
||||
func (in *ClusterSpec) DeepCopy() *ClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
||||
*out = *in
|
||||
in.JobInfo.DeepCopyInto(&out.JobInfo)
|
||||
if in.Nodes != nil {
|
||||
in, out := &in.Nodes, &out.Nodes
|
||||
*out = make([]NodeStatus, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
||||
func (in *ClusterStatus) DeepCopy() *ClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Condition) DeepCopyInto(out *Condition) {
|
||||
*out = *in
|
||||
in.StartTime.DeepCopyInto(&out.StartTime)
|
||||
in.EndTime.DeepCopyInto(&out.EndTime)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition.
|
||||
func (in *Condition) DeepCopy() *Condition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Condition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ContainerInfo) DeepCopyInto(out *ContainerInfo) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerInfo.
|
||||
func (in *ContainerInfo) DeepCopy() *ContainerInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ContainerInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ControlPlaneEndpoint) DeepCopyInto(out *ControlPlaneEndpoint) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneEndpoint.
|
||||
func (in *ControlPlaneEndpoint) DeepCopy() *ControlPlaneEndpoint {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ControlPlaneEndpoint)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalEtcd) DeepCopyInto(out *ExternalEtcd) {
|
||||
*out = *in
|
||||
if in.Endpoints != nil {
|
||||
in, out := &in.Endpoints, &out.Endpoints
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalEtcd.
|
||||
func (in *ExternalEtcd) DeepCopy() *ExternalEtcd {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalEtcd)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FlannelCfg) DeepCopyInto(out *FlannelCfg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FlannelCfg.
|
||||
func (in *FlannelCfg) DeepCopy() *FlannelCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FlannelCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostCfg) DeepCopyInto(out *HostCfg) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostCfg.
|
||||
func (in *HostCfg) DeepCopy() *HostCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostGroups) DeepCopyInto(out *HostGroups) {
|
||||
*out = *in
|
||||
if in.All != nil {
|
||||
in, out := &in.All, &out.All
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Etcd != nil {
|
||||
in, out := &in.Etcd, &out.Etcd
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Master != nil {
|
||||
in, out := &in.Master, &out.Master
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Worker != nil {
|
||||
in, out := &in.Worker, &out.Worker
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.K8s != nil {
|
||||
in, out := &in.K8s, &out.K8s
|
||||
*out = make([]HostCfg, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostGroups.
|
||||
func (in *HostGroups) DeepCopy() *HostGroups {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostGroups)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JobInfo) DeepCopyInto(out *JobInfo) {
|
||||
*out = *in
|
||||
if in.Pods != nil {
|
||||
in, out := &in.Pods, &out.Pods
|
||||
*out = make([]PodInfo, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JobInfo.
|
||||
func (in *JobInfo) DeepCopy() *JobInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(JobInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeSphere) DeepCopyInto(out *KubeSphere) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSphere.
|
||||
func (in *KubeSphere) DeepCopy() *KubeSphere {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeSphere)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KubeovnCfg) DeepCopyInto(out *KubeovnCfg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeovnCfg.
|
||||
func (in *KubeovnCfg) DeepCopy() *KubeovnCfg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KubeovnCfg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Kubernetes) DeepCopyInto(out *Kubernetes) {
|
||||
*out = *in
|
||||
if in.ApiserverCertExtraSans != nil {
|
||||
in, out := &in.ApiserverCertExtraSans, &out.ApiserverCertExtraSans
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Nodelocaldns != nil {
|
||||
in, out := &in.Nodelocaldns, &out.Nodelocaldns
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.ApiServerArgs != nil {
|
||||
in, out := &in.ApiServerArgs, &out.ApiServerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ControllerManagerArgs != nil {
|
||||
in, out := &in.ControllerManagerArgs, &out.ControllerManagerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SchedulerArgs != nil {
|
||||
in, out := &in.SchedulerArgs, &out.SchedulerArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.KubeletArgs != nil {
|
||||
in, out := &in.KubeletArgs, &out.KubeletArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.KubeProxyArgs != nil {
|
||||
in, out := &in.KubeProxyArgs, &out.KubeProxyArgs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.KubeletConfiguration.DeepCopyInto(&out.KubeletConfiguration)
|
||||
in.KubeProxyConfiguration.DeepCopyInto(&out.KubeProxyConfiguration)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kubernetes.
|
||||
func (in *Kubernetes) DeepCopy() *Kubernetes {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Kubernetes)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NetworkConfig) DeepCopyInto(out *NetworkConfig) {
|
||||
*out = *in
|
||||
out.Calico = in.Calico
|
||||
out.Flannel = in.Flannel
|
||||
out.Kubeovn = in.Kubeovn
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkConfig.
|
||||
func (in *NetworkConfig) DeepCopy() *NetworkConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NetworkConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *NodeStatus) DeepCopyInto(out *NodeStatus) {
|
||||
*out = *in
|
||||
if in.Roles != nil {
|
||||
in, out := &in.Roles, &out.Roles
|
||||
*out = make(map[string]bool, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeStatus.
|
||||
func (in *NodeStatus) DeepCopy() *NodeStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(NodeStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodInfo) DeepCopyInto(out *PodInfo) {
|
||||
*out = *in
|
||||
if in.Containers != nil {
|
||||
in, out := &in.Containers, &out.Containers
|
||||
*out = make([]ContainerInfo, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodInfo.
|
||||
func (in *PodInfo) DeepCopy() *PodInfo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PodInfo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RegistryConfig) DeepCopyInto(out *RegistryConfig) {
|
||||
*out = *in
|
||||
if in.RegistryMirrors != nil {
|
||||
in, out := &in.RegistryMirrors, &out.RegistryMirrors
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.InsecureRegistries != nil {
|
||||
in, out := &in.InsecureRegistries, &out.InsecureRegistries
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegistryConfig.
|
||||
func (in *RegistryConfig) DeepCopy() *RegistryConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RegistryConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *RoleGroups) DeepCopyInto(out *RoleGroups) {
|
||||
*out = *in
|
||||
if in.Etcd != nil {
|
||||
in, out := &in.Etcd, &out.Etcd
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Master != nil {
|
||||
in, out := &in.Master, &out.Master
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Worker != nil {
|
||||
in, out := &in.Worker, &out.Worker
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoleGroups.
|
||||
func (in *RoleGroups) DeepCopy() *RoleGroups {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(RoleGroups)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Sources) DeepCopyInto(out *Sources) {
|
||||
*out = *in
|
||||
in.Chart.DeepCopyInto(&out.Chart)
|
||||
in.Yaml.DeepCopyInto(&out.Yaml)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Sources.
|
||||
func (in *Sources) DeepCopy() *Sources {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Sources)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Yaml) DeepCopyInto(out *Yaml) {
|
||||
*out = *in
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Yaml.
|
||||
func (in *Yaml) DeepCopy() *Yaml {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Yaml)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -48,7 +48,6 @@ type ClusterSpec struct {
|
||||
Network NetworkConfig `yaml:"network" json:"network,omitempty"`
|
||||
Registry RegistryConfig `yaml:"registry" json:"registry,omitempty"`
|
||||
Addons []Addon `yaml:"addons" json:"addons,omitempty"`
|
||||
KubeSphere KubeSphere `json:"kubesphere,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterStatus defines the observed state of Cluster
|
||||
@@ -134,10 +133,6 @@ type ClusterList struct {
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
}
|
||||
|
||||
// HostCfg defines host information for cluster.
|
||||
type HostCfg struct {
|
||||
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||
@@ -187,13 +182,6 @@ type RegistryConfig struct {
|
||||
Auths runtime.RawExtension `yaml:"auths" json:"auths,omitempty"`
|
||||
}
|
||||
|
||||
// KubeSphere defines the configuration information of the KubeSphere.
|
||||
type KubeSphere struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Configurations string `json:"configurations,omitempty"`
|
||||
}
|
||||
|
||||
// GenerateCertSANs is used to generate cert sans for cluster.
|
||||
func (cfg *ClusterSpec) GenerateCertSANs() []string {
|
||||
clusterSvc := fmt.Sprintf("kubernetes.default.svc.%s", cfg.Kubernetes.DNSDomain)
|
||||
|
||||
@@ -133,7 +133,6 @@ func (cfg *ClusterSpec) SetDefaultClusterSpec(incluster bool, macos bool) (*Clus
|
||||
clusterCfg.Kubernetes = SetDefaultClusterCfg(cfg)
|
||||
clusterCfg.Registry = cfg.Registry
|
||||
clusterCfg.Addons = cfg.Addons
|
||||
clusterCfg.KubeSphere = cfg.KubeSphere
|
||||
|
||||
if cfg.Kubernetes.ClusterName == "" {
|
||||
clusterCfg.Kubernetes.ClusterName = DefaultClusterName
|
||||
|
||||
@@ -138,7 +138,3 @@ type ManifestList struct {
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Manifest `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Manifest{}, &ManifestList{})
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
83
cli/cmd/config/common_flags.go
Normal file
83
cli/cmd/config/common_flags.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
)
|
||||
|
||||
func AddStorageFlagsBy(flagSetter CommandFlagSetter) {
|
||||
// Storage backend type: managed-minio, s3, oss, cos, minio
|
||||
flagSetter.Add(common.FlagStorageType,
|
||||
"",
|
||||
"",
|
||||
"Set storage backend type: managed-minio, s3, oss, cos, minio",
|
||||
).WithAlias(common.FlagLegacyStorageType)
|
||||
|
||||
flagSetter.Add(common.FlagS3Bucket, "", "", "Object storage bucket name")
|
||||
flagSetter.Add(common.FlagBackupKeyPrefix, "", "", "Object storage key prefix for backups")
|
||||
flagSetter.Add(common.FlagAWSAccessKeyIDSetup, "", "", "Access key ID for object storage")
|
||||
flagSetter.Add(common.FlagAWSSecretAccessKeySetup, "", "", "Secret access key for object storage")
|
||||
flagSetter.Add(common.FlagAWSSessionTokenSetup, "", "", "Session token for temporary credentials")
|
||||
flagSetter.Add(common.FlagClusterID, "", "", "Cluster ID used as JuiceFS filesystem name in cloud environments")
|
||||
flagSetter.Add(common.FlagBackupSecret, "", "", "Backup sync secret for Terminus cloud")
|
||||
flagSetter.Add(common.FlagBackupClusterBucket, "", "", "Backup cluster bucket name")
|
||||
flagSetter.Add(common.FlagIsCloudVersion, "", "", "Set to true when running in Terminus cloud environment")
|
||||
}
|
||||
|
||||
func AddVersionFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagVersion,
|
||||
"v",
|
||||
version.VERSION,
|
||||
"Set Olares version, e.g., 1.10.0, 1.10.0-20241109",
|
||||
)
|
||||
}
|
||||
|
||||
func AddBaseDirFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagBaseDir,
|
||||
"b",
|
||||
"",
|
||||
"Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir,
|
||||
)
|
||||
}
|
||||
|
||||
func AddMiniKubeProfileFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagMiniKubeProfile,
|
||||
"p",
|
||||
"",
|
||||
"Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile,
|
||||
).WithAlias(common.FlagLegacyMiniKubeProfile)
|
||||
}
|
||||
|
||||
func AddKubeTypeFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagKubeType,
|
||||
"",
|
||||
common.K3s,
|
||||
"Set kube type, e.g., k3s or k8s",
|
||||
).WithAlias(common.FlagLegacyKubeType)
|
||||
}
|
||||
|
||||
func AddCDNServiceFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagCDNService,
|
||||
"",
|
||||
cc.DefaultOlaresCDNService,
|
||||
"Set the CDN accelerated download address in the format https://cdn.olares.cn. If not set, the default download address will be used",
|
||||
).WithEnv(common.ENV_OLARES_CDN_SERVICE)
|
||||
}
|
||||
|
||||
func AddManifestFlagBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagManifest,
|
||||
"",
|
||||
"",
|
||||
"Set package manifest file, defaults to ${base-dir}/versions/v{version}/installation.manifest",
|
||||
)
|
||||
}
|
||||
|
||||
func AddMasterHostFlagsBy(flagSetter CommandFlagSetter) {
|
||||
flagSetter.Add(common.FlagMasterHost, "", "", "IP address of the master node")
|
||||
flagSetter.Add(common.FlagMasterNodeName, "", "", "Name of the master node")
|
||||
flagSetter.Add(common.FlagMasterSSHUser, "", "", "Username of the master node, defaults to root")
|
||||
flagSetter.Add(common.FlagMasterSSHPassword, "", "", "Password of the master node")
|
||||
flagSetter.Add(common.FlagMasterSSHPrivateKeyPath, "", "", "Path to the SSH key to access the master node, defaults to ~/.ssh/id_rsa")
|
||||
flagSetter.Add(common.FlagMasterSSHPort, "", 0, "SSH Port of the master node, defaults to 22")
|
||||
}
|
||||
110
cli/cmd/config/flag_setter.go
Normal file
110
cli/cmd/config/flag_setter.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
)
|
||||
|
||||
// Init initializes viper as the single source of truth:
|
||||
// 1) Load /etc/olares/release (dotenv) into the process env if present
|
||||
// 2) Enable viper to read environment variables
|
||||
// 3) Bind environment variables for all known keys we care about
|
||||
func Init() {
|
||||
godotenv.Load(common.OlaresReleaseFile)
|
||||
viper.SetEnvPrefix("OLARES")
|
||||
viper.SetEnvKeyReplacer(envKeyReplacer)
|
||||
viper.AutomaticEnv()
|
||||
}
|
||||
|
||||
var aliasToFlag = map[string]string{}
|
||||
var envToFlag = map[string]string{}
|
||||
var envKeyReplacer = strings.NewReplacer("-", "_")
|
||||
|
||||
type CommandFlagSetter interface {
|
||||
Add(flag string, short string, defValue any, description string) CommandFlagItem
|
||||
}
|
||||
|
||||
type CommandFlagItem interface {
|
||||
WithAlias(aliases ...string) CommandFlagItem
|
||||
WithEnv(envs ...string) CommandFlagItem
|
||||
}
|
||||
|
||||
func NewFlagSetterFor(cmd *cobra.Command) CommandFlagSetter {
|
||||
if cmd == nil {
|
||||
panic(fmt.Errorf("command is nil"))
|
||||
}
|
||||
cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
if f, ok := aliasToFlag[name]; ok {
|
||||
return pflag.NormalizedName(f)
|
||||
}
|
||||
return pflag.NormalizedName(name)
|
||||
})
|
||||
return &commandFlagSetterImpl{
|
||||
command: cmd,
|
||||
}
|
||||
}
|
||||
|
||||
type commandFlagSetterImpl struct {
|
||||
command *cobra.Command
|
||||
}
|
||||
|
||||
type commandFlagItemImpl struct {
|
||||
command *cobra.Command
|
||||
flag string
|
||||
}
|
||||
|
||||
func (c *commandFlagSetterImpl) Add(flag string, short string, defValue any, description string) CommandFlagItem {
|
||||
switch reflect.TypeOf(defValue).Kind() {
|
||||
case reflect.Bool:
|
||||
c.command.Flags().BoolP(flag, short, defValue.(bool), description)
|
||||
case reflect.String:
|
||||
c.command.Flags().StringP(flag, short, defValue.(string), description)
|
||||
case reflect.Int:
|
||||
c.command.Flags().IntP(flag, short, defValue.(int), description)
|
||||
}
|
||||
viper.BindPFlag(flag, c.command.Flags().Lookup(flag))
|
||||
|
||||
// transitional support for legacy envs without prefix
|
||||
// it should be removed after all envs are migrated
|
||||
viper.BindEnv(flag, strings.ToUpper(envKeyReplacer.Replace(flag)))
|
||||
return &commandFlagItemImpl{
|
||||
flag: flag,
|
||||
command: c.command,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *commandFlagItemImpl) WithAlias(aliases ...string) CommandFlagItem {
|
||||
for _, a := range aliases {
|
||||
if f, ok := aliasToFlag[a]; ok {
|
||||
if f != c.flag {
|
||||
panic(fmt.Errorf("flag alias %s already exists for flag %s, please use a different alias", a, f))
|
||||
}
|
||||
continue
|
||||
}
|
||||
viper.BindEnv(c.flag, a)
|
||||
aliasToFlag[a] = c.flag
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *commandFlagItemImpl) WithEnv(envs ...string) CommandFlagItem {
|
||||
for _, e := range envs {
|
||||
if f, ok := envToFlag[e]; ok {
|
||||
if f != c.flag {
|
||||
panic(fmt.Errorf("env %s already exists for flag %s, please use a different env", e, f))
|
||||
}
|
||||
continue
|
||||
}
|
||||
viper.BindEnv(c.flag, e)
|
||||
envToFlag[e] = c.flag
|
||||
}
|
||||
return c
|
||||
}
|
||||
21
cli/cmd/ctl/amdgpu/install.go
Normal file
21
cli/cmd/ctl/amdgpu/install.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuInstall() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install AMD ROCm stack via amdgpu-install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuInstall(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
16
cli/cmd/ctl/amdgpu/root.go
Normal file
16
cli/cmd/ctl/amdgpu/root.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package amdgpu
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func NewCmdAmdGpu() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "amdgpu",
|
||||
Short: "Manage AMD GPU ROCm stack",
|
||||
}
|
||||
cmd.AddCommand(NewCmdAmdGpuInstall())
|
||||
cmd.AddCommand(NewCmdAmdGpuUninstall())
|
||||
cmd.AddCommand(NewCmdAmdGpuStatus())
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
21
cli/cmd/ctl/amdgpu/status.go
Normal file
21
cli/cmd/ctl/amdgpu/status.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuStatus() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show AMD GPU driver and ROCm status",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuStatus(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
21
cli/cmd/ctl/amdgpu/uninstall.go
Normal file
21
cli/cmd/ctl/amdgpu/uninstall.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAmdGpuUninstall() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "uninstall",
|
||||
Short: "Uninstall AMD ROCm stack via amdgpu-install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AmdGpuUninstall(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
@@ -3,22 +3,23 @@ package gpu
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdInstallGpu() *cobra.Command {
|
||||
o := options.NewInstallGpuOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install GPU drivers for Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.InstallGpuDrivers(o); err != nil {
|
||||
if err := pipelines.InstallGpuDrivers(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,22 +3,25 @@ package node
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdAddNode() *cobra.Command {
|
||||
o := options.NewAddNodeOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "add worker node to the cluster",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.AddNodePipeline(o); err != nil {
|
||||
if err := pipelines.AddNodePipeline(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddMasterHostFlagsBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,22 +3,24 @@ package node
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdMasterInfo() *cobra.Command {
|
||||
o := options.NewMasterInfoOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "masterinfo",
|
||||
Short: "get information about master node, and check whether current node can be added to the cluster",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.MasterInfoPipeline(o); err != nil {
|
||||
if err := pipelines.MasterInfoPipeline(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddMasterHostFlagsBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
type CliTerminusUninstallOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
All bool
|
||||
Phase string
|
||||
Quiet bool
|
||||
}
|
||||
|
||||
func NewCliTerminusUninstallOptions() *CliTerminusUninstallOptions {
|
||||
return &CliTerminusUninstallOptions{}
|
||||
}
|
||||
|
||||
func (o *CliTerminusUninstallOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().BoolVar(&o.All, "all", false, "Uninstall Olares completely, including prepared dependencies")
|
||||
cmd.Flags().StringVar(&o.Phase, "phase", cluster.PhaseInstall.String(), "Uninstall from a specified phase and revert to the previous one. For example, using --phase install will remove the tasks performed in the 'install' phase, effectively returning the system to the 'prepare' state.")
|
||||
cmd.Flags().BoolVar(&o.Quiet, "quiet", false, "Quiet mode, default: false")
|
||||
}
|
||||
|
||||
type CliTerminusInstallOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
WithJuiceFS bool
|
||||
MiniKubeProfile string
|
||||
BaseDir string
|
||||
EnableReverseProxy *bool
|
||||
common.SwapConfig
|
||||
}
|
||||
|
||||
func NewCliTerminusInstallOptions() *CliTerminusInstallOptions {
|
||||
return &CliTerminusInstallOptions{
|
||||
EnableReverseProxy: pointer.Bool(false),
|
||||
}
|
||||
}
|
||||
|
||||
func (o *CliTerminusInstallOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().BoolVar(o.EnableReverseProxy, "enable-reverse-proxy", false, "Enable reverse proxy, if not set, will be dynamically enabled if public IP is not detected, and disabled otherwise")
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().BoolVar(&o.WithJuiceFS, "with-juicefs", false, "Use JuiceFS as the rootfs for Olares workloads, rather than the local disk.")
|
||||
cmd.Flags().StringVarP(&o.MiniKubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
(&o.SwapConfig).AddFlags(cmd.Flags())
|
||||
}
|
||||
|
||||
type CliPrepareSystemOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
RegistryMirrors string
|
||||
BaseDir string
|
||||
MinikubeProfile string
|
||||
}
|
||||
|
||||
func NewCliPrepareSystemOptions() *CliPrepareSystemOptions {
|
||||
return &CliPrepareSystemOptions{}
|
||||
}
|
||||
|
||||
func (o *CliPrepareSystemOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().StringVarP(&o.RegistryMirrors, "registry-mirrors", "r", "", "Docker Container registry mirrors, multiple mirrors are separated by commas")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVarP(&o.MinikubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
|
||||
}
|
||||
|
||||
type ChangeIPOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
NewMasterHost string
|
||||
WSLDistribution string
|
||||
MinikubeProfile string
|
||||
}
|
||||
|
||||
func NewChangeIPOptions() *ChangeIPOptions {
|
||||
return &ChangeIPOptions{}
|
||||
}
|
||||
|
||||
func (o *ChangeIPOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVar(&o.NewMasterHost, "new-master-host", "", "Update the master node's IP if it's changed, only in Linux worker node")
|
||||
cmd.Flags().StringVarP(&o.WSLDistribution, "distribution", "d", "", "Set WSL distribution name, only in Windows platform, defaults to "+common.WSLDefaultDistribution)
|
||||
cmd.Flags().StringVarP(&o.MinikubeProfile, "profile", "p", "", "Set Minikube profile name, only in MacOS platform, defaults to "+common.MinikubeDefaultProfile)
|
||||
}
|
||||
|
||||
type PreCheckOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewPreCheckOptions() *PreCheckOptions {
|
||||
return &PreCheckOptions{}
|
||||
}
|
||||
|
||||
func (o *PreCheckOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
type InstallStorageOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewInstallStorageOptions() *InstallStorageOptions {
|
||||
return &InstallStorageOptions{}
|
||||
}
|
||||
|
||||
func (o *InstallStorageOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
type AddNodeOptions struct {
|
||||
common.MasterHostConfig
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewAddNodeOptions() *AddNodeOptions {
|
||||
return &AddNodeOptions{}
|
||||
}
|
||||
|
||||
func (o *AddNodeOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
(&o.MasterHostConfig).AddFlags(cmd.Flags())
|
||||
}
|
||||
|
||||
type MasterInfoOptions struct {
|
||||
BaseDir string
|
||||
common.MasterHostConfig
|
||||
}
|
||||
|
||||
func NewMasterInfoOptions() *MasterInfoOptions {
|
||||
return &MasterInfoOptions{}
|
||||
}
|
||||
|
||||
func (o *MasterInfoOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
(&o.MasterHostConfig).AddFlags(cmd.Flags())
|
||||
}
|
||||
|
||||
type UpgradeOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func NewUpgradeOptions() *UpgradeOptions {
|
||||
return &UpgradeOptions{}
|
||||
}
|
||||
|
||||
func (o *UpgradeOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set target Olares version to upgrade to, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type CliDownloadWizardOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
BaseDir string
|
||||
CDNService string
|
||||
ReleaseID string
|
||||
UrlOverride string
|
||||
}
|
||||
|
||||
func NewCliDownloadWizardOptions() *CliDownloadWizardOptions {
|
||||
return &CliDownloadWizardOptions{}
|
||||
}
|
||||
|
||||
func (o *CliDownloadWizardOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().StringVar(&o.CDNService, "cdn-service", "", "Set the CDN accelerated download address in the format https://example.cdn.com. If not set, the default download address will be used")
|
||||
cmd.Flags().StringVar(&o.UrlOverride, "url-override", "", "Set another URL for wizard download explicitly")
|
||||
cmd.Flags().StringVar(&o.ReleaseID, "release-id", "", "Set the specific release id of the release version")
|
||||
}
|
||||
|
||||
type CliDownloadOptions struct {
|
||||
Version string
|
||||
KubeType string
|
||||
Manifest string
|
||||
BaseDir string
|
||||
CDNService string
|
||||
}
|
||||
|
||||
func NewCliDownloadOptions() *CliDownloadOptions {
|
||||
return &CliDownloadOptions{}
|
||||
}
|
||||
|
||||
func (o *CliDownloadOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir , defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
cmd.Flags().StringVar(&o.Manifest, "manifest", "", "Set package manifest file , defaults to {base-dir}/versions/v{version}/installation.manifest")
|
||||
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
|
||||
cmd.Flags().StringVar(&o.CDNService, "cdn-service", "", "Set the CDN accelerated download address in the format https://example.cdn.com. If not set, the default download address will be used")
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type GpuOptions struct {
|
||||
Version string
|
||||
BaseDir string
|
||||
}
|
||||
|
||||
func (o *GpuOptions) AddFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().StringVarP(&o.Version, "version", "v", "", "Set Olares version, e.g., 1.10.0, 1.10.0-20241109")
|
||||
cmd.Flags().StringVarP(&o.BaseDir, "base-dir", "b", "", "Set Olares package base dir, defaults to $HOME/"+cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
type InstallGpuOptions struct {
|
||||
GpuOptions
|
||||
Cuda string
|
||||
}
|
||||
|
||||
func NewInstallGpuOptions() *InstallGpuOptions {
|
||||
return &InstallGpuOptions{}
|
||||
}
|
||||
|
||||
func (o *InstallGpuOptions) AddFlags(cmd *cobra.Command) {
|
||||
o.GpuOptions.AddFlags(cmd)
|
||||
cmd.Flags().StringVar(&o.Cuda, "cuda", "", fmt.Sprintf("The version of the CUDA driver, current supported versions are %s", common.CurrentVerifiedCudaVersion))
|
||||
}
|
||||
@@ -3,22 +3,36 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdChangeIP() *cobra.Command {
|
||||
o := options.NewChangeIPOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "change-ip",
|
||||
Short: "change The IP address of Olares OS",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.ChangeIPPipeline(o); err != nil {
|
||||
if err := pipelines.ChangeIPPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
|
||||
// todo: merge master host config with release info
|
||||
// be backward compatible with old version and olaresd
|
||||
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddMasterHostFlagsBy(flagSetter)
|
||||
flagSetter.Add(common.FlagWSLDistribution,
|
||||
"d",
|
||||
"",
|
||||
"Set WSL distribution name, only on Windows platform, defaults to "+common.WSLDefaultDistribution,
|
||||
).WithAlias(common.FlagLegacyWSLDistribution)
|
||||
config.AddMiniKubeProfileFlagBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -22,52 +23,61 @@ func NewCmdRootDownload() *cobra.Command {
|
||||
}
|
||||
|
||||
func NewCmdDownload() *cobra.Command {
|
||||
o := options.NewCliDownloadOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "component",
|
||||
Short: "Download the packages and components needed to install Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err := pipelines.DownloadInstallationPackage(o); err != nil {
|
||||
if err := pipelines.DownloadInstallationPackage(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
config.AddManifestFlagBy(flagSetter)
|
||||
|
||||
o.AddFlags(cmd)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdDownloadWizard() *cobra.Command {
|
||||
o := options.NewCliDownloadWizardOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "wizard",
|
||||
Short: "Download the Olares installation wizard",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err := pipelines.DownloadInstallationWizard(o); err != nil {
|
||||
if err := pipelines.DownloadInstallationWizard(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
o.AddFlags(cmd)
|
||||
flagSetter.Add(common.FlagReleaseID, "", "", "Set the specific release id of the release version")
|
||||
flagSetter.Add(common.FlagURLOverride, "", "", "Set another URL for wizard download explicitly")
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
func NewCmdCheckDownload() *cobra.Command {
|
||||
o := options.NewCliDownloadOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "check",
|
||||
Short: "Check Downloaded Olares Installation Package",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if err := pipelines.CheckDownloadInstallationPackage(o); err != nil {
|
||||
if err := pipelines.CheckDownloadInstallationPackage(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddManifestFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,36 +3,81 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type InstallOsOptions struct {
|
||||
InstallOptions *options.CliTerminusInstallOptions
|
||||
}
|
||||
|
||||
func NewInstallOsOptions() *InstallOsOptions {
|
||||
return &InstallOsOptions{
|
||||
InstallOptions: options.NewCliTerminusInstallOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdInstallOs() *cobra.Command {
|
||||
o := NewInstallOsOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "install",
|
||||
Short: "Install Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if !cmd.Flags().Changed("enable-reverse-proxy") {
|
||||
o.InstallOptions.EnableReverseProxy = nil
|
||||
}
|
||||
if err := pipelines.CliInstallTerminusPipeline(o.InstallOptions); err != nil {
|
||||
if err := pipelines.CliInstallTerminusPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.InstallOptions.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
flagSetter.Add(common.FlagOSUserName,
|
||||
"",
|
||||
"",
|
||||
"Set the username for the Olares instance, if not set, will be prompted for input",
|
||||
).WithEnv(common.EnvLegacyOSUserName)
|
||||
flagSetter.Add(common.FlagOSDomainName,
|
||||
"",
|
||||
"",
|
||||
"Set the domain name for the Olares instance, if not set, will be prompted for input",
|
||||
).WithEnv(common.EnvLegacyOSDomainName)
|
||||
flagSetter.Add(common.FlagOSPassword,
|
||||
"",
|
||||
"",
|
||||
"Set the inital password for the first user of the Olares instance, if not set, a randomly generated password will be used",
|
||||
)
|
||||
flagSetter.Add(common.FlagEnableReverseProxy,
|
||||
"",
|
||||
false,
|
||||
"Enable reverse proxy, if not set, will be dynamically enabled if public IP is not detected, and disabled otherwise",
|
||||
)
|
||||
flagSetter.Add(common.FlagEnableJuiceFS,
|
||||
"",
|
||||
false,
|
||||
"Use JuiceFS as the rootfs for Olares workloads, rather than the local disk.",
|
||||
).WithAlias(common.FlagLegacyEnableJuiceFS).WithEnv(common.EnvLegacyEnableJuiceFS)
|
||||
flagSetter.Add(common.FlagEnablePodSwap,
|
||||
"",
|
||||
false,
|
||||
"Enable pods on Kubernetes cluster to use swap, setting --enable-zram, --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args, note that only pods of the BestEffort QOS group can use swap due to K8s design",
|
||||
)
|
||||
flagSetter.Add(common.FlagSwappiness,
|
||||
"",
|
||||
false,
|
||||
"Configure the Linux swappiness value, if not set, the current configuration is remained",
|
||||
)
|
||||
flagSetter.Add(common.FlagEnableZRAM,
|
||||
"",
|
||||
false,
|
||||
"Set up a ZRAM device to be used for swap, setting --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args",
|
||||
)
|
||||
flagSetter.Add(common.FlagZRAMSize,
|
||||
"",
|
||||
"",
|
||||
"Set the size of the ZRAM device, takes a format of https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity, defaults to half of the total RAM",
|
||||
)
|
||||
flagSetter.Add(common.FlagZRAMSwapPriority,
|
||||
"",
|
||||
false,
|
||||
"Set the swap priority of the ZRAM device, between -1 and 32767, defaults to 100",
|
||||
)
|
||||
|
||||
config.AddCDNServiceFlagBy(flagSetter)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
config.AddKubeTypeFlagBy(flagSetter)
|
||||
config.AddMiniKubeProfileFlagBy(flagSetter)
|
||||
|
||||
cmd.AddCommand(NewCmdInstallStorage())
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,22 +3,28 @@ package os
|
||||
import (
|
||||
"archive/tar"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// LogCollectOptions holds options for collecting logs
|
||||
@@ -242,7 +248,6 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
if err := cmd.Run(); err != nil {
|
||||
logFile.Close()
|
||||
return fmt.Errorf("failed to collect logs for %s: %v", service, err)
|
||||
continue
|
||||
}
|
||||
logFile.Close()
|
||||
|
||||
@@ -276,7 +281,7 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
|
||||
func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
cmd := exec.Command("dmesg")
|
||||
cmd := exec.Command("dmesg -T")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -375,49 +380,153 @@ func collectKubernetesLogs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
}
|
||||
|
||||
cmd = exec.Command("kubectl", "describe", "pods", "--all-namespaces")
|
||||
output, err = tryKubectlCommand(cmd, "describe pods", options)
|
||||
if err != nil && !options.IgnoreKubeErrors {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
header := &tar.Header{
|
||||
Name: "pods-describe.txt",
|
||||
Mode: 0644,
|
||||
Size: int64(len(output)),
|
||||
ModTime: time.Now(),
|
||||
resourceTypes := []string{"node", "pod", "statefulset", "deployment", "replicaset", "service", "configmap"}
|
||||
|
||||
for _, res := range resourceTypes {
|
||||
cmd = exec.Command("kubectl", "describe", res, "--all-namespaces")
|
||||
output, err = tryKubectlCommand(cmd, fmt.Sprintf("describe %s", res), options)
|
||||
if err != nil && !options.IgnoreKubeErrors {
|
||||
return err
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write pods description header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(output); err != nil {
|
||||
return fmt.Errorf("failed to write pods description data: %v", err)
|
||||
if err == nil {
|
||||
header := &tar.Header{
|
||||
Name: fmt.Sprintf("%s-describe.txt", res),
|
||||
Mode: 0644,
|
||||
Size: int64(len(output)),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write %s description header: %v", res, err)
|
||||
}
|
||||
if _, err := tw.Write(output); err != nil {
|
||||
return fmt.Errorf("failed to write %s description data: %v", res, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd = exec.Command("kubectl", "describe", "node")
|
||||
output, err = tryKubectlCommand(cmd, "describe node", options)
|
||||
if err != nil && !options.IgnoreKubeErrors {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
header := &tar.Header{
|
||||
Name: "node-describe.txt",
|
||||
Mode: 0644,
|
||||
Size: int64(len(output)),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write node description header: %v", err)
|
||||
}
|
||||
if _, err := tw.Write(output); err != nil {
|
||||
return fmt.Errorf("failed to write node description data: %v", err)
|
||||
if err := collectNginxLogsFromLabeledPods(tw); err != nil {
|
||||
if !options.IgnoreKubeErrors {
|
||||
return fmt.Errorf("failed to collect nginx logs from labeled pods: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectNginxLogsFromLabeledPods(tw *tar.Writer) error {
|
||||
if _, err := util.GetCommand("kubectl"); err != nil {
|
||||
fmt.Printf("warning: kubectl not found, skipping collecting nginx logs from labeled pods\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
cfg, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get kubeconfig: %v", err)
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create kube client: %v", err)
|
||||
}
|
||||
|
||||
type selectorSpec struct {
|
||||
LabelSelector string
|
||||
ContainerName string
|
||||
}
|
||||
selectors := []selectorSpec{
|
||||
{LabelSelector: "app=l4-bfl-proxy", ContainerName: ""},
|
||||
{LabelSelector: "tier=bfl", ContainerName: "ingress"},
|
||||
}
|
||||
|
||||
type targetPod struct {
|
||||
Namespace string
|
||||
Name string
|
||||
ContainerName string
|
||||
}
|
||||
var targets []targetPod
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
for _, sel := range selectors {
|
||||
podList, err := clientset.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{LabelSelector: sel.LabelSelector})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list pods by label %q: %v", sel.LabelSelector, err)
|
||||
}
|
||||
for _, pod := range podList.Items {
|
||||
targets = append(targets, targetPod{
|
||||
Namespace: pod.Namespace,
|
||||
Name: pod.Name,
|
||||
ContainerName: sel.ContainerName,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if len(targets) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// simplest approach: use kubectl cp (it already implements copy via tar over exec)
|
||||
tempDir, err := os.MkdirTemp("", "olares-nginx-logs-*")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temp directory for nginx logs: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
files := []string{"/var/log/nginx/access.log", "/var/log/nginx/error.log"}
|
||||
for _, target := range targets {
|
||||
for _, remotePath := range files {
|
||||
base := filepath.Base(remotePath)
|
||||
archivePath := filepath.Join("nginx", target.Namespace, target.Name, base)
|
||||
|
||||
dest := filepath.Join(tempDir, fmt.Sprintf("%s__%s__%s", target.Namespace, target.Name, base))
|
||||
|
||||
err := kubectlCopyFile(target.Namespace, target.Name, target.ContainerName, remotePath, dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to kubectl cp %s/%s:%s: %v", target.Namespace, target.Name, remotePath, err)
|
||||
}
|
||||
|
||||
fi, err := os.Stat(dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to stat copied nginx log %s: %v", dest, err)
|
||||
}
|
||||
|
||||
f, err := os.Open(dest)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open copied nginx log %s: %v", dest, err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
header := &tar.Header{
|
||||
Name: archivePath,
|
||||
Mode: 0644,
|
||||
Size: fi.Size(),
|
||||
ModTime: time.Now(),
|
||||
}
|
||||
if err := tw.WriteHeader(header); err != nil {
|
||||
return fmt.Errorf("failed to write header for %s: %v", archivePath, err)
|
||||
}
|
||||
if _, err := io.CopyN(tw, f, header.Size); err != nil {
|
||||
return fmt.Errorf("failed to write data for %s: %v", archivePath, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func kubectlCopyFile(namespace, pod, container, remotePath, destPath string) error {
|
||||
args := []string{"-n", namespace, "cp"}
|
||||
if container != "" {
|
||||
args = append(args, "-c", container)
|
||||
}
|
||||
args = append(args, fmt.Sprintf("%s:%s", pod, remotePath), destPath)
|
||||
|
||||
cmd := exec.Command("kubectl", args...)
|
||||
if out, err := cmd.CombinedOutput(); err != nil {
|
||||
return fmt.Errorf("kubectl %s failed: %v, output: %s", strings.Join(args, " "), err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
if _, err := util.GetCommand("ip"); err == nil {
|
||||
cmd := exec.Command("ip", "address")
|
||||
@@ -501,13 +610,9 @@ func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error {
|
||||
}
|
||||
|
||||
func getBaseDir() (string, error) {
|
||||
// quick path to get basedir from argument instance
|
||||
arg := &common.Argument{}
|
||||
if err := arg.LoadReleaseInfo(); err != nil {
|
||||
return "", fmt.Errorf("failed to load olares release info: %v", err)
|
||||
}
|
||||
if arg.BaseDir != "" {
|
||||
return arg.BaseDir, nil
|
||||
basedir := viper.GetString(common.FlagBaseDir)
|
||||
if basedir != "" {
|
||||
return basedir, nil
|
||||
}
|
||||
homeDir, err := util.Home()
|
||||
if err != nil {
|
||||
|
||||
@@ -3,22 +3,23 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdPrecheck() *cobra.Command {
|
||||
o := options.NewPreCheckOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "precheck",
|
||||
Short: "precheck the installation compatibility of the system",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.StartPreCheckPipeline(o); err != nil {
|
||||
if err := pipelines.StartPreCheckPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,32 +3,34 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type PrepareSystemOptions struct {
|
||||
PrepareOptions *options.CliPrepareSystemOptions
|
||||
}
|
||||
|
||||
func NewPrepareSystemOptions() *PrepareSystemOptions {
|
||||
return &PrepareSystemOptions{
|
||||
PrepareOptions: options.NewCliPrepareSystemOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdPrepare() *cobra.Command {
|
||||
o := NewPrepareSystemOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "prepare [component1 component2 ...]",
|
||||
Short: "Prepare install",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.PrepareSystemPipeline(o.PrepareOptions, args); err != nil {
|
||||
if err := pipelines.PrepareSystemPipeline(args); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.PrepareOptions.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
flagSetter.Add(common.FlagRegistryMirrors,
|
||||
"r",
|
||||
"",
|
||||
"Extra Docker Container registry mirrors, multiple mirrors are separated by commas",
|
||||
)
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
config.AddKubeTypeFlagBy(flagSetter)
|
||||
config.AddMiniKubeProfileFlagBy(flagSetter)
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ func NewCmdRelease() *cobra.Command {
|
||||
}
|
||||
|
||||
if version == "" {
|
||||
version = fmt.Sprintf("1.12.4-%s", time.Now().Format("20060102150405"))
|
||||
version = fmt.Sprintf("1.12.5-%s", time.Now().Format("20060102150405"))
|
||||
fmt.Printf("--version unspecified, using: %s\n", version)
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
@@ -3,23 +3,26 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewCmdInstallStorage() *cobra.Command {
|
||||
o := options.NewInstallStorageOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "storage",
|
||||
Short: "install a storage backend for the Olares shared filesystem, or in the case of external storage, validate the config",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.CliInstallStoragePipeline(o); err != nil {
|
||||
if err := pipelines.CliInstallStoragePipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.AddFlags(cmd)
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,33 +3,37 @@ package os
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type UninstallOsOptions struct {
|
||||
UninstallOptions *options.CliTerminusUninstallOptions
|
||||
}
|
||||
|
||||
func NewUninstallOsOptions() *UninstallOsOptions {
|
||||
return &UninstallOsOptions{
|
||||
UninstallOptions: options.NewCliTerminusUninstallOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdUninstallOs() *cobra.Command {
|
||||
o := NewUninstallOsOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "uninstall",
|
||||
Short: "Uninstall Olares",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := pipelines.UninstallTerminusPipeline(o.UninstallOptions)
|
||||
err := pipelines.UninstallTerminusPipeline()
|
||||
if err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.UninstallOptions.AddFlags(cmd)
|
||||
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
config.AddStorageFlagsBy(flagSetter)
|
||||
|
||||
// these two flags' names are too general, and only used in cmd options, so we manually bind them to the viper
|
||||
// inside the pipeline creator, it still uses the flag vars to get the values
|
||||
cmd.Flags().Bool("all", false, "Uninstall Olares completely, including prepared dependencies")
|
||||
viper.BindPFlag(common.FlagUninstallAll, cmd.Flags().Lookup("all"))
|
||||
cmd.Flags().String("phase", cluster.PhaseInstall.String(), "Uninstall from a specified phase and revert to the previous one. For example, using --phase install will remove the tasks performed in the 'install' phase, effectively returning the system to the 'prepare' state.")
|
||||
viper.BindPFlag(common.FlagUninstallPhase, cmd.Flags().Lookup("phase"))
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -3,39 +3,33 @@ package os
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/pipelines"
|
||||
"github.com/beclab/Olares/cli/pkg/upgrade"
|
||||
"github.com/beclab/Olares/cli/version"
|
||||
"github.com/spf13/cobra"
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type UpgradeOsOptions struct {
|
||||
UpgradeOptions *options.UpgradeOptions
|
||||
}
|
||||
|
||||
func NewUpgradeOsOptions() *UpgradeOsOptions {
|
||||
return &UpgradeOsOptions{
|
||||
UpgradeOptions: options.NewUpgradeOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdUpgradeOs() *cobra.Command {
|
||||
o := NewUpgradeOsOptions()
|
||||
cmd := &cobra.Command{
|
||||
Use: "upgrade",
|
||||
Short: "Upgrade Olares to a newer version",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := pipelines.UpgradeOlaresPipeline(o.UpgradeOptions); err != nil {
|
||||
if err := pipelines.UpgradeOlaresPipeline(); err != nil {
|
||||
log.Fatalf("error: %v", err)
|
||||
}
|
||||
},
|
||||
}
|
||||
o.UpgradeOptions.AddFlags(cmd)
|
||||
|
||||
flagSetter := config.NewFlagSetterFor(cmd)
|
||||
config.AddVersionFlagBy(flagSetter)
|
||||
config.AddBaseDirFlagBy(flagSetter)
|
||||
|
||||
cmd.AddCommand(NewCmdCurrentVersionUpgradeSpec())
|
||||
cmd.AddCommand(NewCmdUpgradeViable())
|
||||
cmd.AddCommand(NewCmdUpgradePrecheck())
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package ctl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/config"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/amdgpu"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/disk"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/gpu"
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/node"
|
||||
@@ -13,6 +17,9 @@ import (
|
||||
|
||||
func NewDefaultCommand() *cobra.Command {
|
||||
var showVendor bool
|
||||
cobra.OnInitialize(func() {
|
||||
config.Init()
|
||||
})
|
||||
cmds := &cobra.Command{
|
||||
Use: "olares-cli",
|
||||
Short: "Olares Installer",
|
||||
@@ -20,7 +27,7 @@ func NewDefaultCommand() *cobra.Command {
|
||||
Version: version.VERSION,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if showVendor {
|
||||
println(version.VENDOR)
|
||||
fmt.Println(version.VENDOR)
|
||||
} else {
|
||||
cmd.Usage()
|
||||
}
|
||||
@@ -33,6 +40,7 @@ func NewDefaultCommand() *cobra.Command {
|
||||
cmds.AddCommand(os.NewOSCommands()...)
|
||||
cmds.AddCommand(node.NewNodeCommand())
|
||||
cmds.AddCommand(gpu.NewCmdGpu())
|
||||
cmds.AddCommand(amdgpu.NewCmdAmdGpu())
|
||||
cmds.AddCommand(user.NewUserCommand())
|
||||
cmds.AddCommand(disk.NewDiskCommand())
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"os"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newUserClientFromKubeConfig(kubeconfig string) (client.Client, error) {
|
||||
|
||||
47
cli/go.mod
47
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
|
||||
@@ -30,8 +24,6 @@ require (
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/libp2p/go-netroute v0.2.2
|
||||
github.com/lithammer/dedent v1.1.0
|
||||
github.com/mitchellh/mapstructure v1.4.1
|
||||
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33
|
||||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/multiformats/go-varint v0.0.7
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
@@ -43,15 +35,16 @@ require (
|
||||
github.com/shirou/gopsutil/v4 v4.25.7
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.7
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
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 +87,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
|
||||
@@ -118,6 +113,7 @@ require (
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.1 // indirect
|
||||
github.com/go-resty/resty/v2 v2.16.5 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
@@ -174,7 +170,8 @@ 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/pelletier/go-toml/v2 v2.2.4 // 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
|
||||
@@ -185,11 +182,14 @@ require (
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rubenv/sql-migrate v1.8.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/smartystreets/goconvey v1.8.1 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/thoas/go-funk v0.9.3 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
@@ -205,10 +205,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
|
||||
|
||||
106
cli/go.sum
106
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=
|
||||
@@ -179,6 +181,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe h1:zn8tqiUbec4wR94o7Qj3LZCAT6uGobhEgnDRg6isG5U=
|
||||
github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
@@ -224,8 +228,6 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g=
|
||||
github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k=
|
||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
@@ -262,10 +264,10 @@ 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=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
@@ -312,8 +314,6 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
@@ -338,8 +338,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33 h1:T5IbS9C1G2zeHb6eBy6OfIvj5tfQB23kGFpewCJuGDg=
|
||||
github.com/modood/table v0.0.0-20220527013332-8d47e76dad33/go.mod h1:41qyXVI5QH9/ObyPj27CGCVau5v/njfc3Gjj7yzr0HQ=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
|
||||
@@ -348,6 +346,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,14 +368,16 @@ 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/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
|
||||
@@ -416,6 +418,8 @@ github.com/rubenv/sql-migrate v1.8.0 h1:dXnYiJk9k3wetp7GfQbKJcPHjVJL6YK19tKj8t2N
|
||||
github.com/rubenv/sql-migrate v1.8.0/go.mod h1:F2bGFBwCU+pnmbtNYDeKvSuvL6lBVtXDXUUv5t+u1qw=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
|
||||
@@ -434,17 +438,19 @@ github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+Yg
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY=
|
||||
github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec=
|
||||
github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY=
|
||||
github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60=
|
||||
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
|
||||
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -460,6 +466,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
|
||||
@@ -502,8 +510,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 +550,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 +560,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 +572,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 +582,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 +595,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 +614,10 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
133
cli/pkg/amdgpu/tasks.go
Normal file
133
cli/pkg/amdgpu/tasks.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package amdgpu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
cc "github.com/beclab/Olares/cli/pkg/core/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// InstallAmdRocmModule installs AMD ROCm stack on supported Ubuntu if AMD GPU is present.
|
||||
type InstallAmdRocmModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (m *InstallAmdRocmModule) Init() {
|
||||
m.Name = "InstallAMDGPU"
|
||||
|
||||
installAmd := &task.RemoteTask{
|
||||
Name: "InstallAmdRocm",
|
||||
Hosts: m.Runtime.GetHostsByRole(common.Master),
|
||||
Action: &InstallAmdRocm{
|
||||
// no manifest needed
|
||||
},
|
||||
Parallel: false,
|
||||
Retry: 1,
|
||||
}
|
||||
|
||||
m.Tasks = []task.Interface{
|
||||
installAmd,
|
||||
}
|
||||
}
|
||||
|
||||
// InstallAmdRocm installs ROCm using amdgpu-install on Ubuntu 22.04/24.04 for AMD GPUs.
|
||||
type InstallAmdRocm struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *InstallAmdRocm) Execute(runtime connector.Runtime) error {
|
||||
si := runtime.GetSystemInfo()
|
||||
if !si.IsLinux() || !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
amdGPUExists, err := utils.HasAmdIGPU(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// skip rocm install
|
||||
if !amdGPUExists {
|
||||
return nil
|
||||
}
|
||||
rocmV, _ := utils.RocmVersion()
|
||||
min := semver.MustParse("7.1.1")
|
||||
if rocmV != nil && rocmV.LessThan(min) {
|
||||
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", rocmV.Original(), min.Original())
|
||||
}
|
||||
if rocmV != nil && rocmV.GreaterThan(min) {
|
||||
logger.Warnf("Warning: detected ROCm version %s great than maximum tested version %s")
|
||||
return nil
|
||||
}
|
||||
if rocmV != nil && rocmV.Equal(min) {
|
||||
logger.Infof("detected ROCm version %s, skip rocm install...", min.Original())
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensure python3-setuptools and python3-wheel
|
||||
_, _ = runtime.GetRunner().SudoCmd("apt-get update", false, true)
|
||||
checkPkgs := "dpkg -s python3-setuptools python3-wheel >/dev/null 2>&1 || DEBIAN_FRONTEND=noninteractive apt-get install -y python3-setuptools python3-wheel"
|
||||
if _, err := runtime.GetRunner().SudoCmd(checkPkgs, false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install python3-setuptools and python3-wheel")
|
||||
}
|
||||
// ensure amdgpu-install exists
|
||||
if _, err := exec.LookPath("amdgpu-install"); err != nil {
|
||||
var debURL string
|
||||
if si.IsUbuntuVersionEqual(connector.Ubuntu2404) {
|
||||
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/noble/amdgpu-install_7.1.1.70101-1_all.deb"
|
||||
} else {
|
||||
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/jammy/amdgpu-install_7.1.1.70101-1_all.deb"
|
||||
}
|
||||
tmpDeb := path.Join(runtime.GetBaseDir(), cc.PackageCacheDir, "gpu", "amdgpu-install_7.1.1.70101-1_all.deb")
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("install -d -m 0755 %s", filepath.Dir(tmpDeb)), false, true); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := fmt.Sprintf("sh -c 'wget -O %s %s'", tmpDeb, debURL)
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to download amdgpu-install deb")
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y %s", tmpDeb), false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install amdgpu-install deb")
|
||||
}
|
||||
}
|
||||
// run installer for rocm usecase
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
|
||||
}
|
||||
fmt.Println()
|
||||
logger.Warn("Warning: To enable ROCm, please reboot your machine after installation.")
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmdgpuInstallAction struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *AmdgpuInstallAction) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AmdgpuUninstallAction struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (t *AmdgpuUninstallAction) Execute(runtime connector.Runtime) error {
|
||||
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install --uninstall -y", false, true); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "failed to uninstall AMD ROCm via amdgpu-install")
|
||||
}
|
||||
fmt.Println()
|
||||
logger.Warn("Warning: Please reboot your machine after uninstall to fully remove ROCm components.")
|
||||
return nil
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package confirm
|
||||
|
||||
import (
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type InstallConfirmModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (i *InstallConfirmModule) IsSkip() bool {
|
||||
return i.Skip
|
||||
}
|
||||
|
||||
func (i *InstallConfirmModule) Init() {
|
||||
i.Name = "ConfirmModule"
|
||||
i.Desc = "Display confirmation form"
|
||||
|
||||
display := &task.LocalTask{
|
||||
Name: "ConfirmForm",
|
||||
Desc: "Display confirmation form",
|
||||
Action: new(InstallationConfirm),
|
||||
}
|
||||
|
||||
i.Tasks = []task.Interface{
|
||||
display,
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package confirm
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/modood/table"
|
||||
"github.com/pkg/errors"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
)
|
||||
|
||||
// PreCheckResults defines the items to be checked.
|
||||
type PreCheckResults struct {
|
||||
Name string `table:"name"`
|
||||
Sudo string `table:"sudo"`
|
||||
Curl string `table:"curl"`
|
||||
Openssl string `table:"openssl"`
|
||||
Ebtables string `table:"ebtables"`
|
||||
Socat string `table:"socat"`
|
||||
Ipset string `table:"ipset"`
|
||||
Ipvsadm string `table:"ipvsadm"`
|
||||
Conntrack string `table:"conntrack"`
|
||||
Chronyd string `table:"chrony"`
|
||||
Docker string `table:"docker"`
|
||||
Containerd string `table:"containerd"`
|
||||
Nfs string `table:"nfs client"`
|
||||
Ceph string `table:"ceph client"`
|
||||
Glusterfs string `table:"glusterfs client"`
|
||||
Time string `table:"time"`
|
||||
}
|
||||
|
||||
type InstallationConfirm struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (i *InstallationConfirm) Execute(runtime connector.Runtime) error {
|
||||
var (
|
||||
results []PreCheckResults
|
||||
stopFlag bool
|
||||
)
|
||||
|
||||
pre := make([]map[string]string, 0, len(runtime.GetAllHosts()))
|
||||
for _, host := range runtime.GetAllHosts() {
|
||||
if v, ok := host.GetCache().Get(common.NodePreCheck); ok {
|
||||
pre = append(pre, v.(map[string]string))
|
||||
} else {
|
||||
return errors.New("get node check result failed by host cache")
|
||||
}
|
||||
}
|
||||
|
||||
for node := range pre {
|
||||
var result PreCheckResults
|
||||
_ = mapstructure.Decode(pre[node], &result)
|
||||
results = append(results, result)
|
||||
}
|
||||
table.OutputA(results)
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
if i.KubeConf.Arg.Artifact == "" {
|
||||
for _, host := range results {
|
||||
if host.Sudo == "" {
|
||||
logger.Errorf("%s: sudo is required.", host.Name)
|
||||
stopFlag = true
|
||||
}
|
||||
|
||||
if host.Conntrack == "" {
|
||||
logger.Errorf("%s: conntrack is required.", host.Name)
|
||||
stopFlag = true
|
||||
}
|
||||
|
||||
if host.Socat == "" {
|
||||
logger.Errorf("%s: socat is required.", host.Name)
|
||||
stopFlag = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("")
|
||||
fmt.Println("This is a simple check of your environment.")
|
||||
fmt.Println("Before installation, ensure that your machines meet all requirements specified at")
|
||||
fmt.Println("https://github.com/kubesphere/kubekey#requirements-and-recommendations")
|
||||
fmt.Println("")
|
||||
|
||||
if k8sVersion, err := versionutil.ParseGeneric(i.KubeConf.Cluster.Kubernetes.Version); err == nil {
|
||||
if k8sVersion.AtLeast(versionutil.MustParseSemantic("v1.24.0")) && i.KubeConf.Cluster.Kubernetes.ContainerManager == common.Docker {
|
||||
fmt.Println("[Notice]")
|
||||
fmt.Println("Incorrect runtime. Please specify a container runtime other than Docker to install Kubernetes v1.24 or later.")
|
||||
fmt.Println("You can set \"spec.kubernetes.containerManager\" in the configuration file to \"containerd\" or add \"--container-manager containerd\" to the \"./kk create cluster\" command.")
|
||||
fmt.Println("For more information, see:")
|
||||
fmt.Println("https://github.com/kubesphere/kubekey/blob/master/docs/commands/kk-create-cluster.md")
|
||||
fmt.Println("https://kubernetes.io/docs/setup/production-environment/container-runtimes/#container-runtimes")
|
||||
fmt.Println("https://kubernetes.io/blog/2022/02/17/dockershim-faq/")
|
||||
fmt.Println("")
|
||||
stopFlag = true
|
||||
}
|
||||
}
|
||||
|
||||
if stopFlag {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
confirmOK := true // TODO: force skip
|
||||
for !confirmOK {
|
||||
fmt.Printf("Continue this installation? [yes/no]: ")
|
||||
input, err := reader.ReadString('\n')
|
||||
if err != nil {
|
||||
logger.Fatal(err)
|
||||
}
|
||||
input = strings.TrimSpace(strings.ToLower(input))
|
||||
|
||||
switch strings.ToLower(input) {
|
||||
case "yes", "y":
|
||||
confirmOK = true
|
||||
case "no", "n":
|
||||
os.Exit(0)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -81,6 +81,7 @@ func (m *RunPrechecksModule) Init() {
|
||||
new(NvidiaCardArchChecker),
|
||||
new(NouveauChecker),
|
||||
new(CudaChecker),
|
||||
new(RocmChecker),
|
||||
}
|
||||
runPreChecks := &task.LocalTask{
|
||||
Name: "RunPrechecks",
|
||||
|
||||
@@ -372,6 +372,48 @@ func (c *CudaChecker) Check(runtime connector.Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RocmChecker checks AMD ROCm version for AMD GPU on Ubuntu 22.04/24.04 only.
|
||||
type RocmChecker struct{}
|
||||
|
||||
func (r *RocmChecker) Name() string {
|
||||
return "ROCm"
|
||||
}
|
||||
|
||||
func (r *RocmChecker) Check(runtime connector.Runtime) error {
|
||||
if !runtime.GetSystemInfo().IsLinux() {
|
||||
return nil
|
||||
}
|
||||
si := runtime.GetSystemInfo()
|
||||
if !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// detect AMD GPU presence
|
||||
amdGPUExists, err := utils.HasAmdIGPU(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// no AMD GPU found, no need to check rocm
|
||||
if !amdGPUExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
curV, err := utils.RocmVersion()
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
min := semver.MustParse("7.1.1")
|
||||
if curV.LessThan(min) {
|
||||
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", curV.Original(), min.Original())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// precheck - task
|
||||
|
||||
@@ -489,7 +531,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
defer cancel()
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.annotations.bytetrade\\.io/s3-ak}'", kubectl), false, false); err != nil {
|
||||
storageAccessKey = os.Getenv(common.ENV_AWS_ACCESS_KEY_ID_SETUP)
|
||||
storageAccessKey = t.KubeConf.Arg.Storage.StorageAccessKey
|
||||
if storageAccessKey == "" {
|
||||
logger.Errorf("storage access key not found")
|
||||
}
|
||||
@@ -498,7 +540,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
}
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.annotations.bytetrade\\.io/s3-sk}'", kubectl), false, false); err != nil {
|
||||
storageSecretKey = os.Getenv(common.ENV_AWS_SECRET_ACCESS_KEY_SETUP)
|
||||
storageSecretKey = t.KubeConf.Arg.Storage.StorageSecretKey
|
||||
if storageSecretKey == "" {
|
||||
logger.Errorf("storage secret key not found")
|
||||
}
|
||||
@@ -507,7 +549,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
}
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.annotations.bytetrade\\.io/s3-sts}'", kubectl), false, false); err != nil {
|
||||
storageToken = os.Getenv(common.ENV_AWS_SESSION_TOKEN_SETUP)
|
||||
storageToken = t.KubeConf.Arg.Storage.StorageToken
|
||||
if storageToken == "" {
|
||||
logger.Errorf("storage token not found")
|
||||
}
|
||||
@@ -516,7 +558,7 @@ func (t *GetStorageKeyTask) Execute(runtime connector.Runtime) error {
|
||||
}
|
||||
|
||||
if stdout, err := runtime.GetRunner().CmdContext(ctx, fmt.Sprintf("%s get terminus terminus -o jsonpath='{.metadata.labels.bytetrade\\.io/cluster-id}'", kubectl), false, false); err != nil {
|
||||
storageClusterId = os.Getenv(common.ENV_CLUSTER_ID)
|
||||
storageClusterId = t.KubeConf.Arg.Storage.StorageClusterId
|
||||
if storageClusterId == "" {
|
||||
logger.Errorf("storage cluster id not found")
|
||||
}
|
||||
|
||||
@@ -23,31 +23,19 @@ import (
|
||||
const (
|
||||
DefaultK8sVersion = "v1.33.3"
|
||||
DefaultK3sVersion = "v1.33.3-k3s"
|
||||
DefaultKubernetesVersion = ""
|
||||
DefaultKubeSphereVersion = "v3.3.0"
|
||||
CurrentVerifiedCudaVersion = "13.1"
|
||||
)
|
||||
|
||||
const (
|
||||
K3s = "k3s"
|
||||
K8e = "k8e"
|
||||
Kubernetes = "kubernetes"
|
||||
K3s = "k3s"
|
||||
|
||||
LocalHost = "localhost"
|
||||
|
||||
AllInOne = "allInOne"
|
||||
File = "file"
|
||||
Operator = "operator"
|
||||
CommandLine = "commandLine"
|
||||
|
||||
Master = "master"
|
||||
Worker = "worker"
|
||||
ETCD = "etcd"
|
||||
K8s = "k8s"
|
||||
Registry = "registry"
|
||||
KubeKey = "kubekey"
|
||||
Harbor = "harbor"
|
||||
DockerCompose = "compose"
|
||||
Master = "master"
|
||||
Worker = "worker"
|
||||
ETCD = "etcd"
|
||||
K8s = "k8s"
|
||||
Registry = "registry"
|
||||
|
||||
KubeBinaries = "KubeBinaries"
|
||||
WslBinaries = "WslBinaries"
|
||||
@@ -58,23 +46,14 @@ const (
|
||||
BinDir = "/usr/local/bin"
|
||||
KubeConfigDir = "/etc/kubernetes"
|
||||
KubeAddonsDir = "/etc/kubernetes/addons"
|
||||
KubeEtcdCertDir = "/etc/kubernetes/etcd"
|
||||
KubeCertDir = "/etc/kubernetes/pki"
|
||||
KubeManifestDir = "/etc/kubernetes/manifests"
|
||||
KubeScriptDir = "/usr/local/bin/kube-scripts"
|
||||
KubeletFlexvolumesPluginsDir = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec"
|
||||
K3sImageDir = "/var/lib/images"
|
||||
MinikubeDefaultProfile = "olares-0"
|
||||
MinikubeEtcdCertDir = "/var/lib/minikube/certs/etcd"
|
||||
WSLDefaultDistribution = "Ubuntu"
|
||||
RunLockDir = "/var/run/lock"
|
||||
|
||||
InstallerScriptsDir = "scripts"
|
||||
|
||||
ETCDCertDir = "/etc/ssl/etcd/ssl"
|
||||
RegistryCertDir = "/etc/ssl/registry/ssl"
|
||||
|
||||
HaproxyDir = "/etc/kubekey/haproxy"
|
||||
ETCDCertDir = "/etc/ssl/etcd/ssl"
|
||||
|
||||
IPv4Regexp = "[\\d]+\\.[\\d]+\\.[\\d]+\\.[\\d]+"
|
||||
IPv6Regexp = "[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){0,7}::[a-f0-9]{0,4}(:[a-f0-9]{1,4}){0,7}"
|
||||
@@ -85,7 +64,6 @@ const (
|
||||
Kubeovn = "kubeovn"
|
||||
|
||||
Docker = "docker"
|
||||
Crictl = "crictl"
|
||||
Containerd = "containerd"
|
||||
Crio = "crio"
|
||||
Isula = "isula"
|
||||
@@ -94,14 +72,8 @@ const (
|
||||
// global cache key
|
||||
// PreCheckModule
|
||||
NodePreCheck = "nodePreCheck"
|
||||
K8sVersion = "k8sVersion" // current k8s version
|
||||
MaxK8sVersion = "maxK8sVersion" // max k8s version of nodes
|
||||
KubeSphereVersion = "kubeSphereVersion" // current KubeSphere version
|
||||
ClusterNodeStatus = "clusterNodeStatus"
|
||||
ClusterNodeCRIRuntimes = "ClusterNodeCRIRuntimes"
|
||||
DesiredK8sVersion = "desiredK8sVersion"
|
||||
PlanK8sVersion = "planK8sVersion"
|
||||
NodeK8sVersion = "NodeK8sVersion"
|
||||
|
||||
// ETCDModule
|
||||
ETCDCluster = "etcdCluster"
|
||||
@@ -113,15 +85,6 @@ const (
|
||||
ClusterExist = "clusterExist"
|
||||
|
||||
MasterInfo = "masterInfo"
|
||||
|
||||
// CertsModule
|
||||
Certificate = "certificate"
|
||||
CaCertificate = "caCertificate"
|
||||
|
||||
// Artifact pipeline
|
||||
Artifact = "artifact"
|
||||
|
||||
SkipMasterNodePullImages = "skipMasterNodePullImages"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -147,16 +110,6 @@ const (
|
||||
Fedora = "fedora"
|
||||
RHEl = "rhel"
|
||||
Raspbian = "raspbian"
|
||||
PVE = "pve"
|
||||
WSL = "wsl"
|
||||
)
|
||||
|
||||
const (
|
||||
TRUE = "true"
|
||||
FALSE = "false"
|
||||
|
||||
YES = "yes"
|
||||
NO = "no"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -271,32 +224,82 @@ const (
|
||||
ENV_OLARES_VERSION = "OLARES_VERSION"
|
||||
ENV_TERMINUS_IS_CLOUD_VERSION = "TERMINUS_IS_CLOUD_VERSION"
|
||||
ENV_KUBE_TYPE = "KUBE_TYPE"
|
||||
ENV_REGISTRY_MIRRORS = "REGISTRY_MIRRORS"
|
||||
ENV_OLARES_CDN_SERVICE = "OLARES_SYSTEM_CDN_SERVICE"
|
||||
ENV_STORAGE = "STORAGE"
|
||||
ENV_S3_BUCKET = "S3_BUCKET"
|
||||
ENV_LOCAL_GPU_ENABLE = "LOCAL_GPU_ENABLE"
|
||||
ENV_AWS_ACCESS_KEY_ID_SETUP = "AWS_ACCESS_KEY_ID_SETUP"
|
||||
ENV_AWS_SECRET_ACCESS_KEY_SETUP = "AWS_SECRET_ACCESS_KEY_SETUP"
|
||||
ENV_AWS_SESSION_TOKEN_SETUP = "AWS_SESSION_TOKEN_SETUP"
|
||||
ENV_BACKUP_KEY_PREFIX = "BACKUP_KEY_PREFIX"
|
||||
ENV_BACKUP_SECRET = "BACKUP_SECRET"
|
||||
ENV_CLUSTER_ID = "CLUSTER_ID"
|
||||
ENV_BACKUP_CLUSTER_BUCKET = "BACKUP_CLUSTER_BUCKET"
|
||||
ENV_HOST_IP = "HOST_IP"
|
||||
ENV_PREINSTALL = "PREINSTALL"
|
||||
ENV_DISABLE_HOST_IP_PROMPT = "DISABLE_HOST_IP_PROMPT"
|
||||
ENV_AUTO_ADD_FIREWALL_RULES = "AUTO_ADD_FIREWALL_RULES"
|
||||
ENV_TERMINUS_OS_DOMAINNAME = "TERMINUS_OS_DOMAINNAME"
|
||||
ENV_DEFAULT_WSL_DISTRO_LOCATION = "DEFAULT_WSL_DISTRO_LOCATION" // If set to 1, the default WSL distro storage will be used.
|
||||
|
||||
ENV_CONTAINER = "container"
|
||||
ENV_CONTAINER_MODE = "CONTAINER_MODE" // running in docker container
|
||||
|
||||
OLARES_SYSTEM_ENV_FILENAME = "system-env.yaml"
|
||||
OLARES_USER_ENV_FILENAME = "user-env.yaml"
|
||||
)
|
||||
|
||||
const (
|
||||
FlagVersion = "version"
|
||||
FlagBaseDir = "base-dir"
|
||||
|
||||
FlagWSLDistribution = "wsl-distribution"
|
||||
FlagLegacyWSLDistribution = "distribution"
|
||||
|
||||
FlagMasterHost = "master-host"
|
||||
FlagMasterNodeName = "master-node-name"
|
||||
FlagMasterSSHUser = "master-ssh-user"
|
||||
FlagMasterSSHPassword = "master-ssh-password"
|
||||
FlagMasterSSHPrivateKeyPath = "master-ssh-private-key-path"
|
||||
FlagMasterSSHPort = "master-ssh-port"
|
||||
|
||||
FlagOSUserName = "os-username"
|
||||
EnvLegacyOSUserName = "TERMINUS_OS_USERNAME"
|
||||
|
||||
FlagOSDomainName = "os-domainname"
|
||||
EnvLegacyOSDomainName = "TERMINUS_OS_DOMAINNAME"
|
||||
|
||||
FlagOSPassword = "os-password"
|
||||
EnvLegacyEncryptedOSPassword = "TERMINUS_OS_PASSWORD"
|
||||
|
||||
FlagCDNService = "cdn-service"
|
||||
FlagManifest = "manifest"
|
||||
FlagURLOverride = "url-override"
|
||||
FlagReleaseID = "release-id"
|
||||
FlagKubeType = "kube-type"
|
||||
FlagLegacyKubeType = "kube"
|
||||
|
||||
FlagEnableJuiceFS = "enable-juicefs"
|
||||
FlagLegacyEnableJuiceFS = "with-juicefs"
|
||||
EnvLegacyEnableJuiceFS = "JUICEFS"
|
||||
|
||||
FlagMiniKubeProfile = "minikube-profile"
|
||||
FlagLegacyMiniKubeProfile = "profile"
|
||||
|
||||
FlagEnableReverseProxy = "enable-reverse-proxy"
|
||||
FlagEnablePodSwap = "enable-pod-swap"
|
||||
FlagSwappiness = "swappiness"
|
||||
FlagEnableZRAM = "enable-zram"
|
||||
FlagZRAMSize = "zram-size"
|
||||
FlagZRAMSwapPriority = "zram-swap-priority"
|
||||
FlagRegistryMirrors = "registry-mirrors"
|
||||
|
||||
FlagStorageType = "storage-type"
|
||||
FlagLegacyStorageType = "storage"
|
||||
|
||||
FlagS3Bucket = "s3-bucket"
|
||||
FlagBackupKeyPrefix = "backup-key-prefix"
|
||||
FlagAWSAccessKeyIDSetup = "aws-access-key-id-setup"
|
||||
FlagAWSSecretAccessKeySetup = "aws-secret-access-key-setup"
|
||||
FlagAWSSessionTokenSetup = "aws-session-token-setup"
|
||||
FlagClusterID = "cluster-id"
|
||||
FlagBackupSecret = "backup-secret"
|
||||
FlagBackupClusterBucket = "backup-cluster-bucket"
|
||||
FlagIsCloudVersion = "is-cloud-version"
|
||||
|
||||
FlagUninstallPhase = "uninstall-phase"
|
||||
FlagUninstallAll = "uninstall-all"
|
||||
)
|
||||
|
||||
func SetSystemEnv(key, value string) {
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
|
||||
@@ -29,10 +29,8 @@ type KubeAction struct {
|
||||
func (k *KubeAction) AutoAssert(runtime connector.Runtime) {
|
||||
kubeRuntime := runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -22,11 +22,8 @@ import (
|
||||
)
|
||||
|
||||
type KubeConf struct {
|
||||
ClusterHosts []string
|
||||
ClusterName string
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Kubeconfig string
|
||||
Arg *Argument
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Arg *Argument
|
||||
}
|
||||
|
||||
type KubeModule struct {
|
||||
@@ -41,27 +38,8 @@ func (k *KubeModule) IsSkip() bool {
|
||||
func (k *KubeModule) AutoAssert() {
|
||||
kubeRuntime := k.Runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
}
|
||||
|
||||
type KubeCustomModule struct {
|
||||
module.CustomModule
|
||||
KubeConf *KubeConf
|
||||
}
|
||||
|
||||
func (k *KubeCustomModule) AutoAssert() {
|
||||
kubeRuntime := k.Runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -29,9 +29,8 @@ type KubePrepare struct {
|
||||
func (k *KubePrepare) AutoAssert(runtime connector.Runtime) {
|
||||
kubeRuntime := runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -29,10 +29,8 @@ type KubeRollback struct {
|
||||
func (k *KubeRollback) AutoAssert(runtime connector.Runtime) {
|
||||
kubeRuntime := runtime.(*KubeRuntime)
|
||||
conf := &KubeConf{
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
ClusterName: kubeRuntime.ClusterName,
|
||||
Kubeconfig: kubeRuntime.Kubeconfig,
|
||||
Arg: kubeRuntime.Arg,
|
||||
Cluster: kubeRuntime.Cluster,
|
||||
Arg: kubeRuntime.Arg,
|
||||
}
|
||||
|
||||
k.KubeConf = conf
|
||||
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
"github.com/joho/godotenv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
kubekeyapiv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
"github.com/beclab/Olares/cli/pkg/core/common"
|
||||
@@ -40,43 +40,19 @@ import (
|
||||
|
||||
type KubeRuntime struct {
|
||||
connector.BaseRuntime
|
||||
ClusterName string
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Kubeconfig string
|
||||
Arg *Argument
|
||||
Cluster *kubekeyapiv1alpha2.ClusterSpec
|
||||
Arg *Argument
|
||||
}
|
||||
|
||||
type Argument struct {
|
||||
NodeName string `json:"node_name"`
|
||||
FilePath string `json:"file_path"`
|
||||
KubernetesVersion string `json:"kubernetes_version"`
|
||||
KsEnable bool `json:"ks_enable"`
|
||||
KsVersion string `json:"ks_version"`
|
||||
OlaresVersion string `json:"olares_version"`
|
||||
Debug bool `json:"debug"`
|
||||
IgnoreErr bool `json:"ignore_err"`
|
||||
SkipPullImages bool `json:"skip_pull_images"`
|
||||
SKipPushImages bool `json:"skip_push_images"`
|
||||
SecurityEnhancement bool `json:"security_enhancement"`
|
||||
DeployLocalStorage *bool `json:"deploy_local_storage"`
|
||||
// DownloadCommand func(path, url string) string
|
||||
SkipConfirmCheck bool `json:"skip_confirm_check"`
|
||||
InCluster bool `json:"in_cluster"`
|
||||
ContainerManager string `json:"container_manager"`
|
||||
FromCluster bool `json:"from_cluster"`
|
||||
KubeConfig string `json:"kube_config"`
|
||||
Artifact string `json:"artifact"`
|
||||
InstallPackages bool `json:"install_packages"`
|
||||
ImagesDir string `json:"images_dir"`
|
||||
Namespace string `json:"namespace"`
|
||||
DeleteCRI bool `json:"delete_cri"`
|
||||
Role string `json:"role"`
|
||||
Type string `json:"type"`
|
||||
Kubetype string `json:"kube_type"`
|
||||
SystemInfo connector.Systems
|
||||
InCluster bool `json:"in_cluster"`
|
||||
ContainerManager string `json:"container_manager"`
|
||||
Kubetype string `json:"kube_type"`
|
||||
SystemInfo connector.Systems
|
||||
|
||||
// Extra args
|
||||
ExtraAddon string `json:"extra_addon"` // addon yaml config
|
||||
RegistryMirrors string `json:"registry_mirrors"`
|
||||
OlaresCDNService string `json:"olares_cdn_service"`
|
||||
|
||||
@@ -86,10 +62,6 @@ type Argument struct {
|
||||
// master node ssh config
|
||||
*MasterHostConfig
|
||||
|
||||
LocalSSHPort int `json:"-"`
|
||||
|
||||
SkipMasterPullImages bool `json:"skip_master_pull_images"`
|
||||
|
||||
// User
|
||||
User *User `json:"user"`
|
||||
// if juicefs is opted off, the local storage is used directly
|
||||
@@ -102,8 +74,6 @@ type Argument struct {
|
||||
NetworkSettings *NetworkSettings `json:"network_settings"`
|
||||
GPU *GPU `json:"gpu"`
|
||||
|
||||
Request any `json:"-"`
|
||||
|
||||
IsCloudInstance bool `json:"is_cloud_instance"`
|
||||
MinikubeProfile string `json:"minikube_profile"`
|
||||
WSLDistribution string `json:"wsl_distribution"`
|
||||
@@ -114,8 +84,6 @@ type Argument struct {
|
||||
ConsoleLogTruncate bool `json:"console_log_truncate"`
|
||||
HostIP string `json:"host_ip"`
|
||||
|
||||
CudaVersion string `json:"cuda_version"`
|
||||
|
||||
IsOlaresInContainer bool `json:"is_olares_in_container"`
|
||||
}
|
||||
|
||||
@@ -127,14 +95,6 @@ type SwapConfig struct {
|
||||
ZRAMSwapPriority int `json:"zram_swap_priority"`
|
||||
}
|
||||
|
||||
func (cfg *SwapConfig) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.BoolVar(&cfg.EnablePodSwap, "enable-pod-swap", false, "Enable pods on Kubernetes cluster to use swap, setting --enable-zram, --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args, note that only pods of the BestEffort QOS group can use swap due to K8s design")
|
||||
fs.IntVar(&cfg.Swappiness, "swappiness", 0, "Configure the Linux swappiness value, if not set, the current configuration is remained")
|
||||
fs.BoolVar(&cfg.EnableZRAM, "enable-zram", false, "Set up a ZRAM device to be used for swap, setting --zram-size or --zram-swap-priority implicitly enables this option, regardless of the command line args")
|
||||
fs.StringVar(&cfg.ZRAMSize, "zram-size", "", "Set the size of the ZRAM device, takes a format of https://kubernetes.io/docs/reference/kubernetes-api/common-definitions/quantity, defaults to half of the total RAM")
|
||||
fs.IntVar(&cfg.ZRAMSwapPriority, "zram-swap-priority", 0, "Set the swap priority of the ZRAM device, between -1 and 32767, defaults to 100")
|
||||
}
|
||||
|
||||
func (cfg *SwapConfig) Validate() error {
|
||||
if cfg.ZRAMSize == "" {
|
||||
return nil
|
||||
@@ -164,21 +124,12 @@ type MasterHostConfig struct {
|
||||
MasterSSHPort int `json:"master_ssh_port"`
|
||||
}
|
||||
|
||||
func (cfg *MasterHostConfig) AddFlags(fs *pflag.FlagSet) {
|
||||
fs.StringVar(&cfg.MasterHost, "master-host", "", "IP address of the master node")
|
||||
fs.StringVar(&cfg.MasterNodeName, "master-node-name", "", "Name of the master node")
|
||||
fs.StringVar(&cfg.MasterSSHUser, "master-ssh-user", "", "Username of the master node, defaults to root")
|
||||
fs.StringVar(&cfg.MasterSSHPassword, "master-ssh-password", "", "Password of the master node")
|
||||
fs.StringVar(&cfg.MasterSSHPrivateKeyPath, "master-ssh-private-key-path", "", "Path to the SSH key to access the master node, defaults to ~/.ssh/id_rsa")
|
||||
fs.IntVar(&cfg.MasterSSHPort, "master-ssh-port", 0, "SSH Port of the master node, defaults to 22")
|
||||
}
|
||||
|
||||
func (cfg *MasterHostConfig) Validate() error {
|
||||
if cfg.MasterHost == "" {
|
||||
return errors.New("--master-host is not provided")
|
||||
return errors.New("master host is not provided")
|
||||
}
|
||||
if cfg.MasterSSHUser != "" && cfg.MasterSSHUser != "root" && cfg.MasterSSHPassword == "" {
|
||||
return errors.New("--master-ssh-password must be provided for non-root user in order to execute sudo command")
|
||||
return errors.New("master ssh password must be provided for non-root user in order to execute sudo command")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -222,9 +173,9 @@ type Storage struct {
|
||||
StorageAccessKey string `json:"storage_access_key"`
|
||||
StorageSecretKey string `json:"storage_secret_key"`
|
||||
|
||||
StorageToken string `json:"storage_token"` // juicefs --> from env
|
||||
StorageClusterId string `json:"storage_cluster_id"` // use only on the Terminus cloud, juicefs --> from env
|
||||
StorageSyncSecret string `json:"storage_sync_secret"` // use only on the Terminus cloud --> from env
|
||||
StorageToken string `json:"storage_token"` // juicefs
|
||||
StorageClusterId string `json:"storage_cluster_id"` // use only on the Terminus cloud, juicefs
|
||||
StorageSyncSecret string `json:"storage_sync_secret"` // use only on the Terminus cloud
|
||||
BackupClusterBucket string `json:"backup_cluster_bucket"`
|
||||
}
|
||||
|
||||
@@ -235,59 +186,36 @@ type GPU struct {
|
||||
func NewArgument() *Argument {
|
||||
si := connector.GetSystemInfo()
|
||||
arg := &Argument{
|
||||
KsEnable: true,
|
||||
KsVersion: DefaultKubeSphereVersion,
|
||||
InstallPackages: false,
|
||||
SKipPushImages: false,
|
||||
ContainerManager: Containerd,
|
||||
SystemInfo: si,
|
||||
Storage: &Storage{
|
||||
StorageType: ManagedMinIO,
|
||||
},
|
||||
GPU: &GPU{
|
||||
Enable: !strings.EqualFold(os.Getenv(ENV_LOCAL_GPU_ENABLE), "0"), // default enable GPU, not set or 1 means enable
|
||||
GPU: &GPU{},
|
||||
User: &User{
|
||||
UserName: strings.TrimSpace(viper.GetString(FlagOSUserName)),
|
||||
DomainName: strings.TrimSpace(viper.GetString(FlagOSDomainName)),
|
||||
Password: strings.TrimSpace(viper.GetString(FlagOSPassword)),
|
||||
},
|
||||
User: &User{},
|
||||
NetworkSettings: &NetworkSettings{},
|
||||
RegistryMirrors: os.Getenv(ENV_REGISTRY_MIRRORS),
|
||||
OlaresCDNService: os.Getenv(ENV_OLARES_CDN_SERVICE),
|
||||
HostIP: os.Getenv(ENV_HOST_IP),
|
||||
RegistryMirrors: viper.GetString(FlagRegistryMirrors),
|
||||
OlaresCDNService: viper.GetString(FlagCDNService),
|
||||
HostIP: viper.GetString(ENV_HOST_IP),
|
||||
Environment: os.Environ(),
|
||||
MasterHostConfig: &MasterHostConfig{},
|
||||
SwapConfig: &SwapConfig{},
|
||||
}
|
||||
// default enable GPU unless explicitly set to "0"
|
||||
arg.GPU.Enable = !strings.EqualFold(os.Getenv(ENV_LOCAL_GPU_ENABLE), "0")
|
||||
arg.IsCloudInstance, _ = strconv.ParseBool(os.Getenv(ENV_TERMINUS_IS_CLOUD_VERSION))
|
||||
arg.IsOlaresInContainer = os.Getenv("CONTAINER_MODE") == "oic"
|
||||
arg.IsOlaresInContainer = os.Getenv(ENV_CONTAINER_MODE) == "oic"
|
||||
si.IsOIC = arg.IsOlaresInContainer
|
||||
|
||||
if err := arg.LoadReleaseInfo(); err != nil {
|
||||
fmt.Printf("error loading release info: %v", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
arg.loadMasterHostConfig()
|
||||
return arg
|
||||
}
|
||||
|
||||
// LoadReleaseInfo loads base directory and version settings
|
||||
// from /etc/olares/release and environment variables,
|
||||
// with the latter takes precedence.
|
||||
// Note that the command line options --base-dir and --version
|
||||
// still have the highest priority and will override any values loaded here
|
||||
func (a *Argument) LoadReleaseInfo() error {
|
||||
// load envs from the release file
|
||||
// already existing envs are not overridden so
|
||||
err := godotenv.Load(OlaresReleaseFile)
|
||||
|
||||
// silently ignore the non-existence of a release file
|
||||
// otherwise, return the error
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
a.BaseDir = os.Getenv(ENV_OLARES_BASE_DIR)
|
||||
a.OlaresVersion = os.Getenv(ENV_OLARES_VERSION)
|
||||
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 +228,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -370,14 +300,6 @@ func (a *Argument) SetOlaresVersion(version string) {
|
||||
a.OlaresVersion = version
|
||||
}
|
||||
|
||||
func (a *Argument) SetRegistryMirrors(registryMirrors string) {
|
||||
a.RegistryMirrors = registryMirrors
|
||||
}
|
||||
|
||||
func (a *Argument) SetDeleteCRI(deleteCRI bool) {
|
||||
a.DeleteCRI = deleteCRI
|
||||
}
|
||||
|
||||
func (a *Argument) SetStorage(storage *Storage) {
|
||||
a.Storage = storage
|
||||
}
|
||||
@@ -409,11 +331,6 @@ func (a *Argument) SetKubeVersion(kubeType string) {
|
||||
a.Kubetype = kubeType
|
||||
}
|
||||
|
||||
func (a *Argument) SetKubernetesVersion(kubeType string, kubeVersion string) {
|
||||
a.KubernetesVersion = kubeVersion
|
||||
a.Kubetype = kubeType
|
||||
}
|
||||
|
||||
func (a *Argument) SetBaseDir(dir string) {
|
||||
if dir != "" {
|
||||
a.BaseDir = dir
|
||||
@@ -432,10 +349,36 @@ func (a *Argument) SetBaseDir(dir string) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Argument) SetCudaVersion(cudaVersion string) {
|
||||
a.CudaVersion = CurrentVerifiedCudaVersion
|
||||
if cudaVersion != "" {
|
||||
a.CudaVersion = cudaVersion
|
||||
// loadMasterHostConfig loads master host configuration from master.conf file (if exists)
|
||||
// and then overrides with any values set via command line flags or environment variables.
|
||||
func (a *Argument) loadMasterHostConfig() {
|
||||
// First, try to load from master.conf file
|
||||
configPath := filepath.Join(a.BaseDir, MasterHostConfigFile)
|
||||
if content, err := os.ReadFile(configPath); err == nil {
|
||||
json.Unmarshal(content, a.MasterHostConfig)
|
||||
}
|
||||
// Then override with viper values (from flags or env)
|
||||
if v := viper.GetString(FlagMasterHost); v != "" {
|
||||
a.MasterHost = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterNodeName); v != "" {
|
||||
a.MasterNodeName = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterSSHUser); v != "" {
|
||||
a.MasterSSHUser = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterSSHPassword); v != "" {
|
||||
a.MasterSSHPassword = v
|
||||
}
|
||||
if v := viper.GetString(FlagMasterSSHPrivateKeyPath); v != "" {
|
||||
a.MasterSSHPrivateKeyPath = v
|
||||
}
|
||||
if v := viper.GetInt(FlagMasterSSHPort); v != 0 {
|
||||
a.MasterSSHPort = v
|
||||
}
|
||||
// Set a dummy name to bypass validity checks if master host is set but node name is not
|
||||
if a.MasterHost != "" && a.MasterNodeName == "" {
|
||||
a.MasterNodeName = "master"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,60 +408,15 @@ func (a *Argument) SetSwapConfig(config SwapConfig) {
|
||||
a.Swappiness = config.Swappiness
|
||||
}
|
||||
|
||||
func (a *Argument) SetMasterHostOverride(config MasterHostConfig) {
|
||||
if config.MasterHost != "" {
|
||||
a.MasterHost = config.MasterHost
|
||||
}
|
||||
if config.MasterNodeName != "" {
|
||||
a.MasterNodeName = config.MasterNodeName
|
||||
}
|
||||
|
||||
// set a dummy name to bypass validity checks
|
||||
// as it will be overridden later when the node name is fetched
|
||||
if a.MasterNodeName == "" {
|
||||
a.MasterNodeName = "master"
|
||||
}
|
||||
if config.MasterSSHPassword != "" {
|
||||
a.MasterSSHPassword = config.MasterSSHPassword
|
||||
}
|
||||
if config.MasterSSHUser != "" {
|
||||
a.MasterSSHUser = config.MasterSSHUser
|
||||
}
|
||||
if config.MasterSSHPort != 0 {
|
||||
a.MasterSSHPort = config.MasterSSHPort
|
||||
}
|
||||
if config.MasterSSHPrivateKeyPath != "" {
|
||||
a.MasterSSHPrivateKeyPath = config.MasterSSHPrivateKeyPath
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Argument) LoadMasterHostConfigIfAny() error {
|
||||
if a.BaseDir == "" {
|
||||
return errors.New("basedir unset")
|
||||
}
|
||||
content, err := os.ReadFile(filepath.Join(a.BaseDir, MasterHostConfigFile))
|
||||
if os.IsNotExist(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return json.Unmarshal(content, a.MasterHostConfig)
|
||||
}
|
||||
|
||||
func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
loader := NewLoader(flag, arg)
|
||||
func NewKubeRuntime(arg Argument) (*KubeRuntime, error) {
|
||||
loader := NewLoader(arg)
|
||||
cluster, err := loader.Load()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = loadExtraAddons(cluster, arg.ExtraAddon); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base := connector.NewBaseRuntime(cluster.Name, connector.NewDialer(),
|
||||
arg.Debug, arg.IgnoreErr, arg.BaseDir, arg.OlaresVersion, arg.ConsoleLogFileName, arg.ConsoleLogTruncate, arg.SystemInfo)
|
||||
arg.BaseDir, arg.OlaresVersion, arg.ConsoleLogFileName, arg.ConsoleLogTruncate, arg.SystemInfo)
|
||||
|
||||
clusterSpec := &cluster.Spec
|
||||
defaultCluster, roleGroups := clusterSpec.SetDefaultClusterSpec(arg.InCluster, arg.SystemInfo.IsDarwin())
|
||||
@@ -528,9 +426,6 @@ func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
if host.IsRole(Master) || host.IsRole(Worker) {
|
||||
host.SetRole(K8s)
|
||||
}
|
||||
if host.IsRole(Master) && arg.SkipMasterPullImages {
|
||||
host.GetCache().Set(SkipMasterNodePullImages, true)
|
||||
}
|
||||
if _, ok := hostSet[host.GetName()]; !ok {
|
||||
hostSet[host.GetName()] = struct{}{}
|
||||
base.AppendHost(host)
|
||||
@@ -544,12 +439,9 @@ func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) {
|
||||
args, _ := json.Marshal(arg)
|
||||
logger.Debugf("[runtime] arg: %s", string(args))
|
||||
|
||||
arg.KsEnable = defaultCluster.KubeSphere.Enabled
|
||||
arg.KsVersion = defaultCluster.KubeSphere.Version
|
||||
r := &KubeRuntime{
|
||||
Cluster: defaultCluster,
|
||||
ClusterName: cluster.Name,
|
||||
Arg: &arg,
|
||||
Cluster: defaultCluster,
|
||||
Arg: &arg,
|
||||
}
|
||||
r.BaseRuntime = base
|
||||
|
||||
|
||||
@@ -17,15 +17,9 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -33,10 +27,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
|
||||
kubekeyapiv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
"github.com/beclab/Olares/cli/pkg/version/kubesphere"
|
||||
"github.com/pkg/errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -47,137 +38,19 @@ type Loader interface {
|
||||
Load() (*kubekeyapiv1alpha2.Cluster, error)
|
||||
}
|
||||
|
||||
type Options map[string]interface{}
|
||||
|
||||
func NewLoader(flag string, arg Argument) Loader {
|
||||
switch flag {
|
||||
case File:
|
||||
return NewFileLoader(arg)
|
||||
case Operator:
|
||||
return &ConfigMapLoader{}
|
||||
case AllInOne:
|
||||
return NewDefaultLoader(arg)
|
||||
case CommandLine:
|
||||
return NewCommandLineLoader(arg)
|
||||
default:
|
||||
return NewDefaultLoader(arg)
|
||||
}
|
||||
}
|
||||
|
||||
type CommandLineLoader struct {
|
||||
arg Argument
|
||||
hostname string
|
||||
kubernetesVersion string
|
||||
}
|
||||
|
||||
func NewCommandLineLoader(arg Argument) *CommandLineLoader {
|
||||
return &CommandLineLoader{
|
||||
arg: arg,
|
||||
kubernetesVersion: arg.KubernetesVersion,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CommandLineLoader) validate() error {
|
||||
hostname, err := os.Hostname()
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Failed to get hostname: %v\n", err))
|
||||
}
|
||||
|
||||
c.hostname = hostname
|
||||
|
||||
// flags
|
||||
if c.arg.MasterNodeName == "" {
|
||||
return errors.New("No master nodeName provided, with flag '--master-node-name'")
|
||||
}
|
||||
if c.arg.MasterHost == "" {
|
||||
return errors.New("No master host provided, with flag '--master-host'")
|
||||
}
|
||||
if c.arg.MasterSSHUser == "" {
|
||||
return errors.New("No master ssh user provided, with flag '--master-ssh-user'")
|
||||
}
|
||||
if c.arg.KubernetesVersion == "" {
|
||||
return errors.New("No kubernetes version provided, with flag '--with-kubernetes'")
|
||||
}
|
||||
if c.arg.MasterSSHPassword == "" && c.arg.MasterSSHPrivateKeyPath == "" {
|
||||
return errors.New("No master ssh password and private key file, with flag '--master-ssh-password' or '--master-ssh-private-keyfile'")
|
||||
}
|
||||
|
||||
if err := localSSH(c.arg.SystemInfo.GetOsType()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommandLineLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
u, err := currentUser(c.arg.SystemInfo.GetOsType())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := c.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cluster := &kubekeyapiv1alpha2.Cluster{}
|
||||
|
||||
// current node
|
||||
cluster.Spec.Hosts = append(cluster.Spec.Hosts, kubekeyapiv1alpha2.HostCfg{
|
||||
Name: c.hostname,
|
||||
Address: "",
|
||||
InternalAddress: "",
|
||||
Port: c.arg.LocalSSHPort,
|
||||
User: u.Name,
|
||||
PrivateKeyPath: fmt.Sprintf("%s/.ssh/id_rsa", u.HomeDir),
|
||||
Arch: "",
|
||||
})
|
||||
|
||||
cluster.Spec.RoleGroups = map[string][]string{
|
||||
Worker: {c.hostname},
|
||||
}
|
||||
|
||||
// master node
|
||||
masterHostCfg := kubekeyapiv1alpha2.HostCfg{
|
||||
Name: c.arg.MasterNodeName,
|
||||
Address: c.arg.MasterHost,
|
||||
InternalAddress: c.arg.MasterHost,
|
||||
Port: c.arg.MasterSSHPort,
|
||||
User: c.arg.MasterSSHUser,
|
||||
Arch: "",
|
||||
}
|
||||
if c.arg.MasterSSHPassword != "" {
|
||||
masterHostCfg.Password = c.arg.MasterSSHPassword
|
||||
}
|
||||
if c.arg.MasterSSHPrivateKeyPath != "" {
|
||||
masterHostCfg.Password = ""
|
||||
masterHostCfg.PrivateKeyPath = c.arg.MasterSSHPrivateKeyPath
|
||||
}
|
||||
|
||||
cluster.Spec.Hosts = append(cluster.Spec.Hosts, masterHostCfg)
|
||||
|
||||
cluster.Spec.RoleGroups[Master] = []string{c.arg.MasterNodeName}
|
||||
cluster.Spec.RoleGroups[ETCD] = []string{c.arg.MasterNodeName}
|
||||
|
||||
if err := defaultCommonClusterConfig(cluster, c.arg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cluster, nil
|
||||
func NewLoader(arg Argument) Loader {
|
||||
return NewDefaultLoader(arg)
|
||||
}
|
||||
|
||||
type DefaultLoader struct {
|
||||
arg Argument
|
||||
KubernetesVersion string
|
||||
KubeSphereVersion string
|
||||
KubeSphereEnable bool
|
||||
}
|
||||
|
||||
func NewDefaultLoader(arg Argument) *DefaultLoader {
|
||||
return &DefaultLoader{
|
||||
arg: arg,
|
||||
KubernetesVersion: arg.KubernetesVersion,
|
||||
KubeSphereVersion: arg.KsVersion,
|
||||
KubeSphereEnable: arg.KsEnable,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,16 +141,6 @@ func (d *DefaultLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
}
|
||||
}
|
||||
|
||||
if d.KubeSphereEnable {
|
||||
ver := normalizedBuildVersion(d.KubeSphereVersion)
|
||||
if ver == "" {
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported Kubesphere Version: %v\n", d.KubeSphereVersion))
|
||||
}
|
||||
if err := defaultKSConfig(&allInOne.Spec.KubeSphere, ver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := defaultCommonClusterConfig(allInOne, d.arg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -289,147 +152,6 @@ func (d *DefaultLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
return allInOne, nil
|
||||
}
|
||||
|
||||
type FileLoader struct {
|
||||
arg Argument
|
||||
FilePath string
|
||||
KubernetesVersion string
|
||||
KubeSphereVersion string
|
||||
KubeSphereEnable bool
|
||||
}
|
||||
|
||||
func NewFileLoader(arg Argument) *FileLoader {
|
||||
return &FileLoader{
|
||||
arg: arg,
|
||||
FilePath: arg.FilePath,
|
||||
KubernetesVersion: arg.KubernetesVersion,
|
||||
KubeSphereVersion: arg.KsVersion,
|
||||
KubeSphereEnable: arg.KsEnable,
|
||||
}
|
||||
}
|
||||
|
||||
func (f FileLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
var objName string
|
||||
|
||||
clusterCfg := kubekeyapiv1alpha2.Cluster{}
|
||||
fp, err := filepath.Abs(f.FilePath)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to look up current directory")
|
||||
}
|
||||
// fixme: It will lead to nil pointer err
|
||||
//if len(f.KubernetesVersion) != 0 {
|
||||
// _ = exec.Command("/bin/sh", "-c", fmt.Sprintf("sed -i \"/version/s/\\:.*/\\: %s/g\" %s", f.KubernetesVersion, fp)).Run()
|
||||
//}
|
||||
file, err := os.Open(fp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to open the given cluster configuration file")
|
||||
}
|
||||
defer file.Close()
|
||||
b1 := bufio.NewReader(file)
|
||||
for {
|
||||
result := make(map[string]interface{})
|
||||
content, err := k8syaml.NewYAMLReader(b1).Read()
|
||||
if len(content) == 0 {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to read the given cluster configuration file")
|
||||
}
|
||||
err = yaml.Unmarshal(content, &result)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to unmarshal the given cluster configuration file")
|
||||
}
|
||||
|
||||
if result["kind"] == "Cluster" {
|
||||
contentToJson, err := k8syaml.ToJSON(content)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unable to convert configuration to json")
|
||||
}
|
||||
if err := json.Unmarshal(contentToJson, &clusterCfg); err != nil {
|
||||
return nil, errors.Wrap(err, "Failed to unmarshal configuration")
|
||||
}
|
||||
metadata := result["metadata"].(map[interface{}]interface{})
|
||||
objName = metadata["name"].(string)
|
||||
}
|
||||
|
||||
if result["kind"] == "ConfigMap" || result["kind"] == "ClusterConfiguration" {
|
||||
metadata := result["metadata"].(map[interface{}]interface{})
|
||||
labels := metadata["labels"].(map[interface{}]interface{})
|
||||
clusterCfg.Spec.KubeSphere.Enabled = true
|
||||
|
||||
v, ok := labels["version"]
|
||||
if !ok {
|
||||
return nil, errors.New("Unknown version")
|
||||
}
|
||||
|
||||
version := v.(string)
|
||||
_, stable := kubesphere.StabledVersionSupport(version)
|
||||
_, latest := kubesphere.LatestRelease(version)
|
||||
_, dev := kubesphere.DevRelease(version)
|
||||
if stable || latest || dev {
|
||||
clusterCfg.Spec.KubeSphere.Configurations = "---\n" + string(content)
|
||||
clusterCfg.Spec.KubeSphere.Version = version
|
||||
} else {
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported KubeSphere version: %s", version))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if f.KubeSphereEnable {
|
||||
ver := normalizedBuildVersion(f.KubeSphereVersion)
|
||||
if ver == "" {
|
||||
return nil, errors.New(fmt.Sprintf("Unsupported Kubesphere Version: %v\n", f.KubeSphereVersion))
|
||||
}
|
||||
if err := defaultKSConfig(&clusterCfg.Spec.KubeSphere, ver); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if ver := normalizedBuildVersion(f.KubernetesVersion); ver != "" {
|
||||
s := strings.Split(ver, "-")
|
||||
if len(s) > 1 {
|
||||
clusterCfg.Spec.Kubernetes.Version = s[0]
|
||||
clusterCfg.Spec.Kubernetes.Type = s[1]
|
||||
} else {
|
||||
clusterCfg.Spec.Kubernetes.Version = ver
|
||||
}
|
||||
}
|
||||
|
||||
if f.arg.ContainerManager != "" && f.arg.ContainerManager != Docker {
|
||||
clusterCfg.Spec.Kubernetes.ContainerManager = f.arg.ContainerManager
|
||||
}
|
||||
|
||||
clusterCfg.Spec.Kubernetes.Version = normalizedBuildVersion(clusterCfg.Spec.Kubernetes.Version)
|
||||
clusterCfg.Spec.KubeSphere.Version = normalizedBuildVersion(clusterCfg.Spec.KubeSphere.Version)
|
||||
clusterCfg.Name = objName
|
||||
return &clusterCfg, nil
|
||||
}
|
||||
|
||||
type ConfigMapLoader struct {
|
||||
}
|
||||
|
||||
func (c ConfigMapLoader) Load() (*kubekeyapiv1alpha2.Cluster, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func defaultKSConfig(ks *kubekeyapiv1alpha2.KubeSphere, version string) error {
|
||||
ks.Enabled = true
|
||||
version = strings.TrimSpace(version)
|
||||
ksInstaller, ok := kubesphere.StabledVersionSupport(version)
|
||||
if ok {
|
||||
ks.Version = ksInstaller.Version
|
||||
ks.Configurations = ksInstaller.CCToString()
|
||||
} else if latest, ok := kubesphere.LatestRelease(version); ok {
|
||||
ks.Version = version
|
||||
ks.Configurations = latest.CCToString()
|
||||
} else if dev, ok := kubesphere.DevRelease(version); ok {
|
||||
ks.Version = version
|
||||
ks.Configurations = dev.CCToString()
|
||||
} else {
|
||||
return errors.New(fmt.Sprintf("Unsupported KubeSphere version: %s", version))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// normalizedBuildVersion used to returns normalized build version (with "v" prefix if needed)
|
||||
// If input doesn't match known version pattern, returns empty string.
|
||||
func normalizedBuildVersion(version string) string {
|
||||
@@ -442,57 +164,6 @@ func normalizedBuildVersion(version string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type ExtraAddon struct {
|
||||
Addons []kubekeyapiv1alpha2.Addon `yaml:"Addons"`
|
||||
}
|
||||
|
||||
// load addon from argument
|
||||
func loadExtraAddons(cluster *kubekeyapiv1alpha2.Cluster, addonFile string) error {
|
||||
if addonFile == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
fp, err := filepath.Abs(addonFile)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, fmt.Sprintf("Failed to load addon in file: %s", addonFile))
|
||||
}
|
||||
|
||||
content, err := ioutil.ReadFile(fp)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to open the given addon config file")
|
||||
}
|
||||
|
||||
if len(content) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
var result ExtraAddon
|
||||
err = yaml.Unmarshal(content, &result)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unable to read the given addon configuration file")
|
||||
}
|
||||
|
||||
if len(result.Addons) > 0 {
|
||||
cluster.Spec.Addons = append(cluster.Spec.Addons, result.Addons...)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func currentUser(osType string) (*user.User, error) {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if osType != Darwin && osType != Windows {
|
||||
if u.Username != "root" {
|
||||
return nil, errors.New(fmt.Sprintf("Current user is %s. Please use root!", u.Username))
|
||||
}
|
||||
}
|
||||
return u, nil
|
||||
}
|
||||
|
||||
func installSUDOIfMissing() error {
|
||||
p, _ := util.GetCommand("sudo")
|
||||
if p != "" {
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeSphere Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type LocalRuntime struct {
|
||||
connector.BaseRuntime
|
||||
}
|
||||
|
||||
func NewLocalRuntime(debug, ingoreErr bool) (LocalRuntime, error) {
|
||||
var localRuntime LocalRuntime
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return localRuntime, err
|
||||
}
|
||||
if u.Username != "root" {
|
||||
return localRuntime, fmt.Errorf("current user is %s. Please use root", u.Username)
|
||||
}
|
||||
|
||||
if output, err := exec.Command("/bin/sh", "-c", "if [ ! -f \"$HOME/.ssh/id_rsa\" ]; then mkdir -p \"$HOME/.ssh\" && ssh-keygen -t rsa-sha2-512 -P \"\" -f $HOME/.ssh/id_rsa && ls $HOME/.ssh;fi;").CombinedOutput(); err != nil {
|
||||
return localRuntime, errors.New(fmt.Sprintf("Failed to generate public key: %v\n%s", err, string(output)))
|
||||
}
|
||||
if output, err := exec.Command("/bin/sh", "-c", "echo \"\n$(cat $HOME/.ssh/id_rsa.pub)\" >> $HOME/.ssh/authorized_keys && awk ' !x[$0]++{print > \"'$HOME'/.ssh/authorized_keys.tmp\"}' $HOME/.ssh/authorized_keys && mv $HOME/.ssh/authorized_keys.tmp $HOME/.ssh/authorized_keys").CombinedOutput(); err != nil {
|
||||
return localRuntime, errors.New(fmt.Sprintf("Failed to copy public key to authorized_keys: %v\n%s", err, string(output)))
|
||||
}
|
||||
|
||||
name, err := os.Hostname()
|
||||
if err != nil {
|
||||
return localRuntime, err
|
||||
}
|
||||
base := connector.NewBaseRuntime(name, connector.NewDialer(), debug, ingoreErr, "", "", "", false, nil)
|
||||
|
||||
host := connector.NewHost()
|
||||
host.Name = name
|
||||
host.Address = ""
|
||||
host.InternalAddress = ""
|
||||
host.Port = 22
|
||||
host.User = u.Username
|
||||
host.Password = ""
|
||||
host.PrivateKeyPath = fmt.Sprintf("%s/.ssh/id_rsa", u.HomeDir)
|
||||
host.Arch = ""
|
||||
host.SetRole(KubeKey)
|
||||
|
||||
base.AppendHost(host)
|
||||
base.AppendRoleMap(host)
|
||||
|
||||
local := LocalRuntime{base}
|
||||
return local, nil
|
||||
}
|
||||
@@ -51,7 +51,6 @@ type ModuleRuntime interface {
|
||||
GetBaseDir() string
|
||||
GetInstallerDir() string
|
||||
GetWorkDir() string
|
||||
GetIgnoreErr() bool
|
||||
GetAllHosts() []Host
|
||||
SetAllHosts([]Host)
|
||||
GetHostsByRole(role string) []Host
|
||||
|
||||
@@ -39,8 +39,6 @@ type BaseRuntime struct {
|
||||
baseDir string
|
||||
installerDir string
|
||||
workDir string
|
||||
verbose bool
|
||||
ignoreErr bool
|
||||
allHosts []Host
|
||||
roleHosts map[string][]Host
|
||||
deprecatedHosts map[string]string
|
||||
@@ -50,12 +48,10 @@ type BaseRuntime struct {
|
||||
k8sClient *kubernetes.Clientset
|
||||
}
|
||||
|
||||
func NewBaseRuntime(name string, connector Connector, verbose bool, ignoreErr bool, baseDir string, olaresVersion string, consoleLogFileName string, consoleLogTruncate bool, systemInfo Systems) BaseRuntime {
|
||||
func NewBaseRuntime(name string, connector Connector, baseDir string, olaresVersion string, consoleLogFileName string, consoleLogTruncate bool, systemInfo Systems) BaseRuntime {
|
||||
base := BaseRuntime{
|
||||
ObjName: name,
|
||||
connector: connector,
|
||||
verbose: verbose,
|
||||
ignoreErr: ignoreErr,
|
||||
allHosts: make([]Host, 0, 0),
|
||||
roleHosts: make(map[string][]Host),
|
||||
deprecatedHosts: make(map[string]string),
|
||||
@@ -169,10 +165,6 @@ func (b *BaseRuntime) GetWorkDir() string {
|
||||
return b.workDir
|
||||
}
|
||||
|
||||
func (b *BaseRuntime) GetIgnoreErr() bool {
|
||||
return b.ignoreErr
|
||||
}
|
||||
|
||||
func (b *BaseRuntime) GetAllHosts() []Host {
|
||||
hosts := make([]Host, 0, 0)
|
||||
for i := range b.allHosts {
|
||||
|
||||
@@ -51,10 +51,12 @@ func (d DebianVersion) String() string {
|
||||
}
|
||||
|
||||
const (
|
||||
Ubuntu20 UbuntuVersion = "20."
|
||||
Ubuntu22 UbuntuVersion = "22."
|
||||
Ubuntu24 UbuntuVersion = "24."
|
||||
Ubuntu25 UbuntuVersion = "25."
|
||||
Ubuntu20 UbuntuVersion = "20."
|
||||
Ubuntu22 UbuntuVersion = "22."
|
||||
Ubuntu24 UbuntuVersion = "24."
|
||||
Ubuntu25 UbuntuVersion = "25."
|
||||
Ubuntu2204 UbuntuVersion = "22.04"
|
||||
Ubuntu2404 UbuntuVersion = "24.04"
|
||||
|
||||
Debian9 DebianVersion = "9"
|
||||
Debian10 DebianVersion = "10"
|
||||
|
||||
@@ -59,20 +59,6 @@ func (b *BaseTaskModule) Run(result *ending.ModuleResult) {
|
||||
logger.Infof("[A] %s: %s %s (%s)", ac.Host.GetName(), t.GetName(), ac.Status.String(), util.ShortDur(elapsed))
|
||||
|
||||
result.AppendHostResult(ac)
|
||||
|
||||
if _, ok := t.(*task.RemoteTask); ok {
|
||||
if b.Runtime.GetIgnoreErr() {
|
||||
if len(b.Runtime.GetAllHosts()) > 0 {
|
||||
if ac.GetStatus() == ending.FAILED {
|
||||
res.Status = ending.SUCCESS
|
||||
b.Runtime.DeleteHost(ac.Host)
|
||||
}
|
||||
} else {
|
||||
result.ErrResult(errors.Wrapf(res.CombineErr(), "Module[%s] exec failed", b.Name))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if res.IsFailed() {
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
@@ -158,7 +165,7 @@ func (t *UpdateNvidiaContainerToolkitSource) Execute(runtime connector.Runtime)
|
||||
|
||||
// decide mirror based on OLARES_SYSTEM_CDN_SERVICE
|
||||
var mirrorHost string
|
||||
cdnService := os.Getenv(common.ENV_OLARES_CDN_SERVICE)
|
||||
cdnService := t.KubeConf.Arg.OlaresCDNService
|
||||
if cdnService != "" {
|
||||
cdnRaw := cdnService
|
||||
if !strings.HasPrefix(cdnRaw, "http") {
|
||||
@@ -256,6 +263,10 @@ func (t *PatchK3sDriver) Execute(runtime connector.Runtime) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("apt install -y strace", false, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd(dstName, false, false); err != nil {
|
||||
return errors.Wrap(err, "failed to apply CUDA patch for WSL")
|
||||
}
|
||||
@@ -323,59 +334,11 @@ func (t *CheckGpuStatus) Execute(runtime connector.Runtime) error {
|
||||
return fmt.Errorf("GPU Container State is Pending")
|
||||
}
|
||||
|
||||
type GetCudaVersion struct {
|
||||
type UpdateNodeGPUInfo struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (g *GetCudaVersion) Execute(runtime connector.Runtime) error {
|
||||
var nvidiaSmiFile string
|
||||
var systemInfo = runtime.GetSystemInfo()
|
||||
|
||||
switch {
|
||||
case systemInfo.IsWsl():
|
||||
nvidiaSmiFile = "/usr/lib/wsl/lib/nvidia-smi"
|
||||
default:
|
||||
nvidiaSmiFile = "/usr/bin/nvidia-smi"
|
||||
}
|
||||
|
||||
if !util.IsExist(nvidiaSmiFile) {
|
||||
logger.Info("nvidia-smi not exists")
|
||||
return nil
|
||||
}
|
||||
|
||||
var cudaVersion string
|
||||
res, err := runtime.GetRunner().Cmd(fmt.Sprintf("%s --version", nvidiaSmiFile), false, true)
|
||||
if err != nil {
|
||||
logger.Errorf("get cuda version error %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
lines := strings.Split(res, "\n")
|
||||
|
||||
if len(lines) == 0 {
|
||||
return nil
|
||||
}
|
||||
for _, line := range lines {
|
||||
if strings.Contains(line, "CUDA Version") {
|
||||
parts := strings.Split(line, ":")
|
||||
if len(parts) != 2 {
|
||||
break
|
||||
}
|
||||
cudaVersion = strings.TrimSpace(parts[1])
|
||||
}
|
||||
}
|
||||
if cudaVersion != "" {
|
||||
common.SetSystemEnv("OLARES_SYSTEM_CUDA_VERSION", cudaVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type UpdateNodeLabels struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (u *UpdateNodeLabels) Execute(runtime connector.Runtime) error {
|
||||
func (u *UpdateNodeGPUInfo) Execute(runtime connector.Runtime) error {
|
||||
client, err := clientset.NewKubeClient()
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "kubeclient create error")
|
||||
@@ -482,6 +445,85 @@ func UpdateNodeGpuLabel(ctx context.Context, client kubernetes.Interface, driver
|
||||
}
|
||||
}
|
||||
|
||||
if cuda != nil && *cuda != "" {
|
||||
if err := updateCudaVersionSystemEnv(ctx, *cuda); err != nil {
|
||||
logger.Errorf("failed to update SystemEnv for CUDA version: %v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateCudaVersionSystemEnv(ctx context.Context, cudaVersion string) error {
|
||||
envName := "OLARES_SYSTEM_CUDA_VERSION"
|
||||
common.SetSystemEnv(envName, cudaVersion)
|
||||
config, err := ctrl.GetConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get rest config: %w", err)
|
||||
}
|
||||
|
||||
apix, err := apixclientset.NewForConfig(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create crd client: %w", err)
|
||||
}
|
||||
|
||||
_, err = apix.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, "systemenvs.sys.bytetrade.io", metav1.GetOptions{})
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
logger.Debugf("SystemEnv CRD not found, skipping CUDA version update")
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("failed to get SystemEnv CRD: %w", err)
|
||||
}
|
||||
|
||||
scheme := kruntime.NewScheme()
|
||||
if err := v1alpha1.AddToScheme(scheme); err != nil {
|
||||
return fmt.Errorf("failed to add systemenv scheme: %w", err)
|
||||
}
|
||||
|
||||
c, err := ctrlclient.New(config, ctrlclient.Options{Scheme: scheme})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create client: %w", err)
|
||||
}
|
||||
|
||||
resourceName, err := apputils.EnvNameToResourceName(envName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid system env name: %s", envName)
|
||||
}
|
||||
|
||||
var existingSystemEnv v1alpha1.SystemEnv
|
||||
err = c.Get(ctx, types.NamespacedName{Name: resourceName}, &existingSystemEnv)
|
||||
if err == nil {
|
||||
if existingSystemEnv.Default != cudaVersion {
|
||||
existingSystemEnv.Default = cudaVersion
|
||||
if err := c.Update(ctx, &existingSystemEnv); err != nil {
|
||||
return fmt.Errorf("failed to update SystemEnv %s: %w", resourceName, err)
|
||||
}
|
||||
logger.Infof("Updated SystemEnv %s default to %s", resourceName, cudaVersion)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if !apierrors.IsNotFound(err) {
|
||||
return fmt.Errorf("failed to get SystemEnv %s: %w", resourceName, err)
|
||||
}
|
||||
|
||||
systemEnv := &v1alpha1.SystemEnv{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: resourceName,
|
||||
},
|
||||
EnvVarSpec: v1alpha1.EnvVarSpec{
|
||||
EnvName: envName,
|
||||
Default: cudaVersion,
|
||||
},
|
||||
}
|
||||
|
||||
if err := c.Create(ctx, systemEnv); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("failed to create SystemEnv %s: %w", resourceName, err)
|
||||
}
|
||||
|
||||
logger.Infof("Created SystemEnv: %s with default %s", envName, cudaVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -10,17 +10,39 @@ var (
|
||||
K3sCudaFixValues = template.Must(template.New("cuda_lib_fix.sh").Parse(
|
||||
dedent.Dedent(`#!/bin/bash
|
||||
sh_c="sh -c"
|
||||
real_driver=$($sh_c "find /usr/lib/wsl/drivers/ -name libcuda.so.1.1|head -1")
|
||||
real_driver=""
|
||||
real_nvml=""
|
||||
|
||||
# Try to find the real driver path via strace
|
||||
real_driver_path=$($sh_c "strace -qq -e trace=openat /usr/lib/wsl/lib/nvidia-smi 2>&1|grep '/usr/lib/wsl/drivers'|grep libnvidia-ml.so.1|awk '{print \$2}'|sed 's/[\",]//g'|sed 's/libnvidia-ml.so.1//g'")
|
||||
if [[ x"$real_driver_path" != x"" ]]; then
|
||||
real_driver="${real_driver_path}libcuda.so.1.1"
|
||||
real_nvml="${real_driver_path}libnvidia-ml.so.1"
|
||||
else
|
||||
driver_path=$($sh_c "strace -qq -e trace=openat /usr/lib/wsl/lib/nvidia-smi 2>&1|grep '/usr/lib/wsl/'|grep libnvidia-ml.so.1")
|
||||
if [[ x"$driver_path" != x"" ]]; then
|
||||
echo "already fixed cuda libs, exit now."
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ x"$real_driver" == x"" ]]; then
|
||||
real_driver=$($sh_c "find /usr/lib/wsl/drivers/ -name libcuda.so.1.1|head -1")
|
||||
real_nvml=$($sh_c "find /usr/lib/wsl/drivers/ -name libnvidia-ml.so.1|head -1")
|
||||
fi
|
||||
|
||||
if [[ x"$real_driver" != x"" ]]; then
|
||||
$sh_c "ln -s /usr/lib/wsl/lib/libcuda* /usr/lib/x86_64-linux-gnu/"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1.1"
|
||||
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1"
|
||||
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so"
|
||||
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1"
|
||||
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1.1"
|
||||
$sh_c "ln -s $real_driver /usr/lib/x86_64-linux-gnu/libcuda.so.1"
|
||||
$sh_c "ln -s $real_driver /usr/lib/x86_64-linux-gnu/libcuda.so.1.1"
|
||||
$sh_c "cp -f $real_nvml /usr/lib/wsl/lib/libnvidia-ml.so.1"
|
||||
$sh_c "cp -f $real_driver /usr/lib/x86_64-linux-gnu/"
|
||||
$sh_c "cp -f $real_nvml /usr/lib/x86_64-linux-gnu/"
|
||||
$sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1.1 /usr/lib/x86_64-linux-gnu/libcuda.so.1"
|
||||
$sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so"
|
||||
fi`),
|
||||
))
|
||||
|
||||
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/k3s/templates"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/registry"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
)
|
||||
|
||||
type InstallContainerModule struct {
|
||||
@@ -470,6 +471,18 @@ func (j *JoinNodesModule) Init() {
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
createSharedLibDirForWorker := &task.RemoteTask{
|
||||
Name: "CreateSharedLibDir(k3s)",
|
||||
Desc: "Create shared lib directory on worker",
|
||||
Hosts: j.Runtime.GetHostsByRole(common.Worker),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
&kubernetes.NodeInCluster{Not: true},
|
||||
new(common.OnlyWorker),
|
||||
},
|
||||
Action: new(storage.CreateSharedLibDir),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
enableK3s := &task.RemoteTask{
|
||||
Name: "EnableK3sService",
|
||||
Desc: "Enable k3s service",
|
||||
@@ -536,6 +549,7 @@ func (j *JoinNodesModule) Init() {
|
||||
k3sService,
|
||||
k3sEnv,
|
||||
k3sRegistryConfig,
|
||||
createSharedLibDirForWorker,
|
||||
enableK3s,
|
||||
copyKubeConfigForMaster,
|
||||
syncKubeConfigToWorker,
|
||||
@@ -579,22 +593,3 @@ func (d *DeleteClusterModule) Init() {
|
||||
execScript,
|
||||
}
|
||||
}
|
||||
|
||||
type SaveKubeConfigModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfigModule) Init() {
|
||||
s.Name = "SaveKubeConfigModule"
|
||||
s.Desc = "Save kube config file as a configmap"
|
||||
|
||||
save := &task.LocalTask{
|
||||
Name: "SaveKubeConfig(k3s)",
|
||||
Desc: "Save kube config as a configmap",
|
||||
Action: new(SaveKubeConfig),
|
||||
}
|
||||
|
||||
s.Tasks = []task.Interface{
|
||||
save,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
package k3s
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -41,11 +39,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/k3s/templates"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
versionutil "k8s.io/apimachinery/pkg/util/version"
|
||||
kube "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
type GetClusterStatus struct {
|
||||
@@ -195,13 +189,13 @@ func (g *GenerateK3sService) Execute(runtime connector.Runtime) error {
|
||||
defaultKubeletArs := map[string]string{
|
||||
"kube-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
|
||||
"system-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
|
||||
"eviction-hard": "memory.available<5%,nodefs.available<10%,imagefs.available<10%",
|
||||
"eviction-hard": "memory.available<5%,nodefs.available<5%,imagefs.available<5%",
|
||||
"config": "/etc/rancher/k3s/kubelet.config",
|
||||
"containerd": container.DefaultContainerdCRISocket,
|
||||
"cgroup-driver": "systemd",
|
||||
"runtime-request-timeout": "5m",
|
||||
"image-gc-high-threshold": "91",
|
||||
"image-gc-low-threshold": "90",
|
||||
"image-gc-high-threshold": "96",
|
||||
"image-gc-low-threshold": "95",
|
||||
"housekeeping_interval": "5s",
|
||||
}
|
||||
defaultKubeProxyArgs := map[string]string{
|
||||
@@ -397,53 +391,23 @@ type CopyK3sKubeConfig struct {
|
||||
}
|
||||
|
||||
func (c *CopyK3sKubeConfig) Execute(runtime connector.Runtime) error {
|
||||
createConfigDirCmd := "mkdir -p /root/.kube && mkdir -p $HOME/.kube"
|
||||
getKubeConfigCmd := "cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config"
|
||||
chmodKubeConfigCmd := "chmod 0600 /root/.kube/config"
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd, chmodKubeConfigCmd}, " && ")
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil {
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
"cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config",
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("cp -f /etc/rancher/k3s/k3s.yaml %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "copy k3s kube config failed")
|
||||
}
|
||||
|
||||
userMkdir := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
userCopyKubeConfig := "cp -f /etc/rancher/k3s/k3s.yaml $HOME/.kube/config"
|
||||
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user copy /etc/rancher/k3s/k3s.yaml to $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config 0600 failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
}
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -493,59 +457,29 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
|
||||
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
|
||||
cluster := v.(*K3sStatus)
|
||||
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
|
||||
}
|
||||
|
||||
oldServer := "server: https://127.0.0.1:6443"
|
||||
newServer := fmt.Sprintf("server: https://%s:%d",
|
||||
s.KubeConf.Cluster.ControlPlaneEndpoint.Domain,
|
||||
s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfig := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1)
|
||||
|
||||
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config")
|
||||
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
userConfigDirCmd := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "$HOME/.kube/config")
|
||||
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
return err
|
||||
}
|
||||
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config"),
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("echo '%s' > %s", newKubeConfig, targetKubeConfigPath),
|
||||
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -575,65 +509,6 @@ func (e *ExecUninstallScript) Execute(runtime connector.Runtime) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type SaveKubeConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfig) Execute(_ connector.Runtime) error {
|
||||
status, ok := s.PipelineCache.Get(common.ClusterStatus)
|
||||
if !ok {
|
||||
return errors.New("get kubernetes status failed by pipeline cache")
|
||||
}
|
||||
cluster := status.(*K3sStatus)
|
||||
|
||||
oldServer := fmt.Sprintf("https://%s:%d", s.KubeConf.Cluster.ControlPlaneEndpoint.Domain, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newServer := fmt.Sprintf("https://%s:%d", s.KubeConf.Cluster.ControlPlaneEndpoint.Address, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfigStr := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1)
|
||||
kubeConfigBase64 := base64.StdEncoding.EncodeToString([]byte(newKubeConfigStr))
|
||||
|
||||
config, err := clientcmd.NewClientConfigFromBytes([]byte(newKubeConfigStr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
restConfig, err := config.ClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientsetForCluster, err := kube.NewForConfig(restConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespace := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubekey-system",
|
||||
},
|
||||
}
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
Namespaces().
|
||||
Create(context.TODO(), namespace, metav1.CreateOptions{}); err != nil {
|
||||
// return err
|
||||
}
|
||||
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-kubeconfig", s.KubeConf.ClusterName),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"kubeconfig": kubeConfigBase64,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
|
||||
// return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GenerateK3sRegistryConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/core/prepare"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
)
|
||||
|
||||
type StatusModule struct {
|
||||
@@ -243,6 +244,18 @@ func (j *JoinNodesModule) Init() {
|
||||
Retry: 5,
|
||||
}
|
||||
|
||||
createSharedLibDirForWorker := &task.RemoteTask{
|
||||
Name: "CreateSharedLibDir(k8s)",
|
||||
Desc: "Create shared lib directory on worker",
|
||||
Hosts: j.Runtime.GetHostsByRole(common.Worker),
|
||||
Prepare: &prepare.PrepareCollection{
|
||||
&NodeInCluster{Not: true},
|
||||
new(common.OnlyWorker),
|
||||
},
|
||||
Action: new(storage.CreateSharedLibDir),
|
||||
Parallel: true,
|
||||
}
|
||||
|
||||
joinWorkerNode := &task.RemoteTask{
|
||||
Name: "JoinWorkerNode(k8s)",
|
||||
Desc: "Join worker node",
|
||||
@@ -323,6 +336,7 @@ func (j *JoinNodesModule) Init() {
|
||||
j.Tasks = []task.Interface{
|
||||
generateKubeadmConfig,
|
||||
joinMasterNode,
|
||||
createSharedLibDirForWorker,
|
||||
joinWorkerNode,
|
||||
copyKubeConfig,
|
||||
removeMasterTaint,
|
||||
@@ -380,26 +394,6 @@ func (c *UmountKubeModule) Init() {
|
||||
}
|
||||
}
|
||||
|
||||
type SaveKubeConfigModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfigModule) Init() {
|
||||
s.Name = "SaveKubeConfigModule"
|
||||
s.Desc = "Save kube config file as a configmap"
|
||||
|
||||
save := &task.LocalTask{
|
||||
Name: "SaveKubeConfig(k8s)",
|
||||
Desc: "Save kube config as a configmap",
|
||||
Action: new(SaveKubeConfig),
|
||||
Retry: 5,
|
||||
}
|
||||
|
||||
s.Tasks = []task.Interface{
|
||||
save,
|
||||
}
|
||||
}
|
||||
|
||||
type ConfigureKubernetesModule struct {
|
||||
common.KubeModule
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package kubernetes
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -34,11 +33,6 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kubeerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kube "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
|
||||
kubekeyv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
@@ -417,51 +411,23 @@ type CopyKubeConfigForControlPlane struct {
|
||||
}
|
||||
|
||||
func (c *CopyKubeConfigForControlPlane) Execute(runtime connector.Runtime) error {
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
getKubeConfigCmd := "cp -f /etc/kubernetes/admin.conf /root/.kube/config"
|
||||
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd}, " && ")
|
||||
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil {
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
"cp -f /etc/kubernetes/admin.conf /root/.kube/config",
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("cp -f /etc/kubernetes/admin.conf %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "copy kube config failed")
|
||||
}
|
||||
|
||||
userMkdir := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
userCopyKubeConfig := "cp -f /etc/kubernetes/admin.conf $HOME/.kube/config"
|
||||
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user copy /etc/kubernetes/admin.conf to $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
}
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -521,53 +487,23 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
|
||||
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
|
||||
cluster := v.(*KubernetesStatus)
|
||||
|
||||
createConfigDirCmd := "mkdir -p /root/.kube"
|
||||
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config")
|
||||
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
|
||||
}
|
||||
|
||||
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
|
||||
}
|
||||
|
||||
userConfigDirCmd := "mkdir -p $HOME/.kube"
|
||||
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
|
||||
}
|
||||
|
||||
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "$HOME/.kube/config")
|
||||
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
|
||||
}
|
||||
|
||||
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
// }
|
||||
|
||||
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
|
||||
// if err != nil {
|
||||
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
// }
|
||||
|
||||
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
|
||||
targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user id failed")
|
||||
return err
|
||||
}
|
||||
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
|
||||
|
||||
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
|
||||
if err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "get user group id failed")
|
||||
cmds := []string{
|
||||
"mkdir -p /root/.kube",
|
||||
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config"),
|
||||
"chmod 0600 /root/.kube/config",
|
||||
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
|
||||
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, targetKubeConfigPath),
|
||||
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
|
||||
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
|
||||
}
|
||||
|
||||
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId)
|
||||
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
|
||||
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
|
||||
return errors.Wrap(errors.WithStack(err), "sync kube config failed")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -660,91 +596,6 @@ func (k *KubectlDeleteCurrentWorkerNode) Execute(runtime connector.Runtime) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
type SaveKubeConfig struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
func (s *SaveKubeConfig) Execute(runtime connector.Runtime) error {
|
||||
status, ok := s.PipelineCache.Get(common.ClusterStatus)
|
||||
if !ok {
|
||||
return errors.New("get kubernetes status failed by pipeline cache")
|
||||
}
|
||||
cluster := status.(*KubernetesStatus)
|
||||
kubeConfigStr := cluster.KubeConfig
|
||||
|
||||
clusterPublicAddress := s.KubeConf.Cluster.ControlPlaneEndpoint.Address
|
||||
master1 := runtime.GetHostsByRole(common.Master)[0]
|
||||
if clusterPublicAddress == master1.GetInternalAddress() {
|
||||
clusterPublicAddress = master1.GetAddress()
|
||||
}
|
||||
|
||||
oldServer := fmt.Sprintf("https://%s:%d", s.KubeConf.Cluster.ControlPlaneEndpoint.Domain, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newServer := fmt.Sprintf("https://%s:%d", clusterPublicAddress, s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
|
||||
newKubeConfigStr := strings.Replace(kubeConfigStr, oldServer, newServer, -1)
|
||||
kubeConfigBase64 := base64.StdEncoding.EncodeToString([]byte(newKubeConfigStr))
|
||||
|
||||
config, err := clientcmd.NewClientConfigFromBytes([]byte(newKubeConfigStr))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
restConfig, err := config.ClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientsetForCluster, err := kube.NewForConfig(restConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
namespace := &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "kubekey-system",
|
||||
},
|
||||
}
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
Namespaces().
|
||||
Get(context.TODO(), namespace.Name, metav1.GetOptions{}); kubeerrors.IsNotFound(err) {
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
Namespaces().
|
||||
Create(context.TODO(), namespace, metav1.CreateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: fmt.Sprintf("%s-kubeconfig", s.KubeConf.ClusterName),
|
||||
},
|
||||
Data: map[string]string{
|
||||
"kubeconfig": kubeConfigBase64,
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Get(context.TODO(), cm.Name, metav1.GetOptions{}); kubeerrors.IsNotFound(err) {
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := clientsetForCluster.
|
||||
CoreV1().
|
||||
ConfigMaps("kubekey-system").
|
||||
Update(context.TODO(), cm, metav1.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ConfigureKubernetes struct {
|
||||
common.KubeAction
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
@@ -387,10 +389,6 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
|
||||
}
|
||||
}
|
||||
|
||||
if kubeConf.Arg.Debug {
|
||||
logger.Debugf("Set kubeletConfiguration: %v", kubeletConfiguration)
|
||||
}
|
||||
|
||||
return kubeletConfiguration
|
||||
}
|
||||
|
||||
|
||||
@@ -46,11 +46,6 @@ func (m *DeleteKubeSphereCachesModule) Init() {
|
||||
|
||||
type DeployModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (d *DeployModule) IsSkip() bool {
|
||||
return d.Skip
|
||||
}
|
||||
|
||||
func (d *DeployModule) Init() {
|
||||
@@ -76,11 +71,6 @@ func (d *DeployModule) Init() {
|
||||
|
||||
type CheckResultModule struct {
|
||||
common.KubeModule
|
||||
Skip bool
|
||||
}
|
||||
|
||||
func (c *CheckResultModule) IsSkip() bool {
|
||||
return c.Skip
|
||||
}
|
||||
|
||||
func (c *CheckResultModule) Init() {
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
kubekeyapiv1alpha2 "github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/confirm"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/os"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
|
||||
"github.com/beclab/Olares/cli/pkg/certs"
|
||||
@@ -36,11 +35,11 @@ func NewDarwinClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
|
||||
},
|
||||
},
|
||||
&kubesphere.DeployMiniKubeModule{},
|
||||
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&kubesphere.DeployModule{},
|
||||
&ksplugins.DeployKsCoreConfigModule{}, // ks-core-config
|
||||
&ksplugins.DeployPrometheusModule{},
|
||||
&ksplugins.DeployKsCoreModule{},
|
||||
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&kubesphere.CheckResultModule{},
|
||||
}
|
||||
|
||||
return m
|
||||
@@ -53,13 +52,6 @@ func NewK3sCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.
|
||||
baseDir = path.Join(runtime.Arg.GetWslUserPath(), cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
skipLocalStorage := true
|
||||
if runtime.Arg.DeployLocalStorage != nil {
|
||||
skipLocalStorage = !*runtime.Arg.DeployLocalStorage
|
||||
} else if runtime.Cluster.KubeSphere.Enabled {
|
||||
skipLocalStorage = false
|
||||
}
|
||||
|
||||
m := []module.Module{
|
||||
&k3s.StatusModule{},
|
||||
&os.ConfigureOSModule{},
|
||||
@@ -87,13 +79,12 @@ func NewK3sCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.
|
||||
&kubernetes.ConfigureKubernetesModule{},
|
||||
&filesystem.ChownModule{},
|
||||
&certs.AutoRenewCertsModule{Skip: !runtime.Cluster.Kubernetes.EnableAutoRenewCerts()},
|
||||
&k3s.SaveKubeConfigModule{},
|
||||
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
|
||||
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&storage.DeployLocalVolumeModule{},
|
||||
&kubesphere.DeployModule{},
|
||||
&ksplugins.DeployKsCoreConfigModule{},
|
||||
&ksplugins.DeployPrometheusModule{},
|
||||
&ksplugins.DeployKsCoreModule{},
|
||||
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&kubesphere.CheckResultModule{},
|
||||
}
|
||||
|
||||
return m
|
||||
@@ -106,16 +97,8 @@ func NewCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
|
||||
baseDir = path.Join(runtime.Arg.GetWslUserPath(), cc.DefaultBaseDir)
|
||||
}
|
||||
|
||||
skipLocalStorage := true
|
||||
if runtime.Arg.DeployLocalStorage != nil {
|
||||
skipLocalStorage = !*runtime.Arg.DeployLocalStorage
|
||||
} else if runtime.Cluster.KubeSphere.Enabled {
|
||||
skipLocalStorage = false
|
||||
}
|
||||
|
||||
m := []module.Module{
|
||||
&precheck.NodePreCheckModule{},
|
||||
&confirm.InstallConfirmModule{Skip: runtime.Arg.SkipConfirmCheck},
|
||||
&kubernetes.StatusModule{},
|
||||
&os.ConfigureOSModule{},
|
||||
&etcd.PreCheckModule{Skip: runtime.Cluster.Etcd.Type != kubekeyapiv1alpha2.KubeKey},
|
||||
@@ -144,13 +127,12 @@ func NewCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
|
||||
&filesystem.ChownModule{},
|
||||
&certs.AutoRenewCertsModule{Skip: !runtime.Cluster.Kubernetes.EnableAutoRenewCerts()},
|
||||
&kubernetes.SecurityEnhancementModule{Skip: !runtime.Arg.SecurityEnhancement},
|
||||
&kubernetes.SaveKubeConfigModule{},
|
||||
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
|
||||
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
|
||||
&storage.DeployLocalVolumeModule{},
|
||||
&kubesphere.DeployModule{},
|
||||
&ksplugins.DeployKsCoreConfigModule{}, // ! ks-core-config
|
||||
&ksplugins.DeployPrometheusModule{},
|
||||
&ksplugins.DeployKsCoreModule{},
|
||||
&kubesphere.CheckResultModule{Skip: !runtime.Cluster.KubeSphere.Enabled}, // check ks-apiserver phase
|
||||
&kubesphere.CheckResultModule{}, // check ks-apiserver phase
|
||||
}
|
||||
|
||||
return m
|
||||
|
||||
@@ -111,6 +111,7 @@ func (p *phaseBuilder) phaseInstall() *phaseBuilder {
|
||||
PhaseFile: common.TerminusStateFileInstalled,
|
||||
BaseDir: p.runtime.GetBaseDir(),
|
||||
},
|
||||
&terminus.WriteReleaseFileModule{WithoutName: true},
|
||||
)
|
||||
}
|
||||
return p
|
||||
|
||||
@@ -58,7 +58,6 @@ func (l *linuxInstallPhaseBuilder) installGpuPlugin() phase {
|
||||
return []module.Module{
|
||||
&gpu.RestartK3sServiceModule{Skip: !(l.runtime.Arg.Kubetype == common.K3s)},
|
||||
&gpu.InstallPluginModule{Skip: skipGpuPlugin},
|
||||
&gpu.GetCudaVersionModule{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@ package system
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/amdgpu"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/os"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/patch"
|
||||
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"github.com/beclab/Olares/cli/pkg/container"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/daemon"
|
||||
"github.com/beclab/Olares/cli/pkg/gpu"
|
||||
"github.com/beclab/Olares/cli/pkg/images"
|
||||
"github.com/beclab/Olares/cli/pkg/k3s"
|
||||
"github.com/beclab/Olares/cli/pkg/manifest"
|
||||
@@ -82,6 +82,7 @@ func (l *linuxPhaseBuilder) build() []module.Module {
|
||||
addModule(&terminus.WriteReleaseFileModule{}).
|
||||
addModule(gpuModuleBuilder(func() []module.Module {
|
||||
return []module.Module{
|
||||
&amdgpu.InstallAmdRocmModule{},
|
||||
&gpu.InstallDriversModule{
|
||||
ManifestModule: manifest.ManifestModule{
|
||||
Manifest: l.manifestMap,
|
||||
|
||||
@@ -5,32 +5,27 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func AddNodePipeline(opts *options.AddNodeOptions) error {
|
||||
func AddNodePipeline() error {
|
||||
arg := common.NewArgument()
|
||||
if !arg.SystemInfo.IsLinux() {
|
||||
fmt.Println("error: Only Linux nodes can be added to an Olares cluster!")
|
||||
os.Exit(1)
|
||||
}
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
if opts.Version == "" {
|
||||
return errors.New("Olares version must be specified")
|
||||
}
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
if err := arg.LoadMasterHostConfigIfAny(); err != nil {
|
||||
return errors.Wrap(err, "failed to load master host config")
|
||||
}
|
||||
arg.SetMasterHostOverride(opts.MasterHostConfig)
|
||||
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("addnode.log", true)
|
||||
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid master host config: %w", err)
|
||||
}
|
||||
arg.SetConsoleLog("addnode.log", true)
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating runtime: %v", err)
|
||||
}
|
||||
|
||||
101
cli/pkg/pipelines/amdgpu.go
Normal file
101
cli/pkg/pipelines/amdgpu.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package pipelines
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/amdgpu"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/action"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/module"
|
||||
"github.com/beclab/Olares/cli/pkg/core/pipeline"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
)
|
||||
|
||||
type singleTaskModule struct {
|
||||
common.KubeModule
|
||||
name string
|
||||
act action.Action
|
||||
}
|
||||
|
||||
func (m *singleTaskModule) Init() {
|
||||
m.Name = m.name
|
||||
m.Tasks = []task.Interface{
|
||||
&task.LocalTask{
|
||||
Name: m.name,
|
||||
Action: m.act,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AmdGpuInstall() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("amdgpuinstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &pipeline.Pipeline{
|
||||
Name: "InstallAMDGPUDrivers",
|
||||
Runtime: runtime,
|
||||
Modules: []module.Module{
|
||||
&amdgpu.InstallAmdRocmModule{},
|
||||
},
|
||||
}
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func AmdGpuUninstall() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("amdgpuuninstall.log", true)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p := &pipeline.Pipeline{
|
||||
Name: "UninstallAMDGPUDrivers",
|
||||
Runtime: runtime,
|
||||
Modules: []module.Module{
|
||||
&singleTaskModule{name: "AmdgpuUninstall", act: new(amdgpu.AmdgpuUninstallAction)},
|
||||
},
|
||||
}
|
||||
return p.Start()
|
||||
}
|
||||
|
||||
func AmdGpuStatus() error {
|
||||
arg := common.NewArgument()
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
runtime.SetRunner(
|
||||
&connector.Runner{
|
||||
Host: &connector.BaseHost{
|
||||
Name: common.LocalHost,
|
||||
Arch: runtime.GetSystemInfo().GetOsArch(),
|
||||
Os: runtime.GetSystemInfo().GetOsType(),
|
||||
},
|
||||
},
|
||||
)
|
||||
amdModel, _ := runtime.GetRunner().SudoCmd("lspci | grep -iE 'VGA|3D|Display' | grep -iE 'AMD|ATI' | head -1 || true", false, false)
|
||||
drvVer, _ := runtime.GetRunner().SudoCmd("modinfo amdgpu 2>/dev/null | awk -F': ' '/^version:/{print $2}' || true", false, false)
|
||||
rocmVer, _ := runtime.GetRunner().SudoCmd("cat /opt/rocm/.info/version 2>/dev/null || true", false, false)
|
||||
|
||||
if strings.TrimSpace(amdModel) != "" {
|
||||
logger.Infof("AMD GPU: %s", strings.TrimSpace(amdModel))
|
||||
} else {
|
||||
logger.Info("AMD GPU: not detected")
|
||||
}
|
||||
if strings.TrimSpace(drvVer) != "" {
|
||||
logger.Infof("AMDGPU driver %s", strings.TrimSpace(drvVer))
|
||||
} else {
|
||||
logger.Info("AMDGPU driver version: unknown")
|
||||
}
|
||||
if strings.TrimSpace(rocmVer) != "" {
|
||||
logger.Infof("ROCm version: %s", strings.TrimSpace(rocmVer))
|
||||
} else {
|
||||
logger.Info("ROCm version: not installed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -2,19 +2,16 @@ package pipelines
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/util"
|
||||
"github.com/beclab/Olares/cli/pkg/phase"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/cluster"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func ChangeIPPipeline(opt *options.ChangeIPOptions) error {
|
||||
terminusVersion := opt.Version
|
||||
func ChangeIPPipeline() error {
|
||||
terminusVersion := viper.GetString(common.FlagVersion)
|
||||
kubeType := phase.GetKubeType()
|
||||
if terminusVersion == "" {
|
||||
terminusVersion, _ = phase.GetOlaresVersion()
|
||||
@@ -22,29 +19,20 @@ func ChangeIPPipeline(opt *options.ChangeIPOptions) error {
|
||||
|
||||
var arg = common.NewArgument()
|
||||
arg.SetOlaresVersion(terminusVersion)
|
||||
arg.SetBaseDir(opt.BaseDir)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetConsoleLog("changeip.log", true)
|
||||
arg.SetKubeVersion(kubeType)
|
||||
arg.SetMinikubeProfile(opt.MinikubeProfile)
|
||||
arg.SetWSLDistribution(opt.WSLDistribution)
|
||||
if err := arg.LoadMasterHostConfigIfAny(); err != nil {
|
||||
return errors.Wrap(err, "failed to load master host config")
|
||||
}
|
||||
if opt.NewMasterHost != "" {
|
||||
if ip := net.ParseIP(opt.NewMasterHost); !util.IsValidIPv4Addr(ip) {
|
||||
return fmt.Errorf("master host %s is not a valid IPv4 address", opt.NewMasterHost)
|
||||
} else {
|
||||
arg.MasterHost = opt.NewMasterHost
|
||||
}
|
||||
}
|
||||
//only run validation if it's a worker node with master host config set
|
||||
arg.SetMinikubeProfile(viper.GetString(common.FlagMiniKubeProfile))
|
||||
arg.SetWSLDistribution(viper.GetString(common.FlagWSLDistribution))
|
||||
|
||||
// Validate master host config only if it's a worker node with master host set
|
||||
if arg.MasterHost != "" {
|
||||
if err := arg.MasterHostConfig.Validate(); err != nil {
|
||||
return fmt.Errorf("invalid master host config: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -56,5 +44,4 @@ func ChangeIPPipeline(opt *options.ChangeIPOptions) error {
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -3,23 +3,23 @@ package pipelines
|
||||
import (
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/download"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func CheckDownloadInstallationPackage(opts *options.CliDownloadOptions) error {
|
||||
func CheckDownloadInstallationPackage() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
manifest := opts.Manifest
|
||||
manifest := viper.GetString(common.FlagManifest)
|
||||
if manifest == "" {
|
||||
manifest = path.Join(runtime.GetInstallerDir(), "installation.manifest")
|
||||
}
|
||||
|
||||
@@ -4,30 +4,29 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/download"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func DownloadInstallationPackage(opts *options.CliDownloadOptions) error {
|
||||
func DownloadInstallationPackage() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetKubeVersion(opts.KubeType)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetOlaresCDNService(opts.CDNService)
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetOlaresCDNService(viper.GetString(common.FlagCDNService))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok := utils.CheckUrl(arg.OlaresCDNService); !ok {
|
||||
return fmt.Errorf("--cdn-service invalid")
|
||||
return fmt.Errorf("invalid cdn service")
|
||||
}
|
||||
|
||||
manifest := opts.Manifest
|
||||
manifest := viper.GetString(common.FlagManifest)
|
||||
if manifest == "" {
|
||||
manifest = path.Join(runtime.GetInstallerDir(), "installation.manifest")
|
||||
}
|
||||
|
||||
@@ -3,30 +3,29 @@ package pipelines
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/beclab/Olares/cli/cmd/ctl/options"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/phase/download"
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func DownloadInstallationWizard(opts *options.CliDownloadWizardOptions) error {
|
||||
func DownloadInstallationWizard() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetKubeVersion(opts.KubeType)
|
||||
arg.SetOlaresVersion(opts.Version)
|
||||
arg.SetBaseDir(opts.BaseDir)
|
||||
arg.SetOlaresCDNService(opts.CDNService)
|
||||
arg.SetOlaresVersion(viper.GetString(common.FlagVersion))
|
||||
arg.SetBaseDir(viper.GetString(common.FlagBaseDir))
|
||||
arg.SetOlaresCDNService(viper.GetString(common.FlagCDNService))
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ok := utils.CheckUrl(arg.OlaresCDNService); !ok {
|
||||
return fmt.Errorf("--cdn-service invalid")
|
||||
return fmt.Errorf("invalid cdn service")
|
||||
}
|
||||
|
||||
p := download.NewDownloadWizard(runtime, opts.UrlOverride, opts.ReleaseID)
|
||||
p := download.NewDownloadWizard(runtime, viper.GetString(common.FlagURLOverride), viper.GetString(common.FlagReleaseID))
|
||||
if err := p.Start(); err != nil {
|
||||
logger.Errorf("download wizard failed %v", err)
|
||||
return err
|
||||
|
||||
@@ -12,7 +12,7 @@ func DisableGpuNode() error {
|
||||
arg := common.NewArgument()
|
||||
arg.SetConsoleLog("gpudisable.log", true)
|
||||
|
||||
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
|
||||
runtime, err := common.NewKubeRuntime(*arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user