Compare commits
14 Commits
daemon/cho
...
cli/fix/ap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bad6e8bc0 | ||
|
|
2181adb67c | ||
|
|
e1b0bd7875 | ||
|
|
e465a2d8fc | ||
|
|
70d0ae1ff5 | ||
|
|
e52db36045 | ||
|
|
1935b1fbb6 | ||
|
|
5dc69bf80e | ||
|
|
e839d5ae41 | ||
|
|
e89c6f35cc | ||
|
|
c4a7c81777 | ||
|
|
a69b5d40a9 | ||
|
|
bab074cd37 | ||
|
|
afb7d49455 |
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
|
||||
|
||||
@@ -317,7 +317,7 @@ spec:
|
||||
chown -R 1000:1000 /uploadstemp && \
|
||||
chown -R 1000:1000 /appdata
|
||||
- name: olares-app-init
|
||||
image: beclab/system-frontend:v1.6.28
|
||||
image: beclab/system-frontend:v1.6.30
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
@@ -1356,6 +1356,17 @@ data:
|
||||
proxy_set_header Connection '$connection_upgrade';
|
||||
more_set_headers 'Upgrade: $http_upgrade';
|
||||
}
|
||||
location /api/refresh {
|
||||
add_header Access-Control-Allow-Headers "access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,content-type,x-auth,x-unauth-error,x-authorization";
|
||||
add_header Access-Control-Allow-Methods "PUT, GET, DELETE, POST, OPTIONS";
|
||||
add_header Access-Control-Allow-Origin $http_origin;
|
||||
add_header Access-Control-Allow-Credentials true;
|
||||
proxy_pass http://authelia-backend-svc:9091;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-real-ip $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
}
|
||||
location / {
|
||||
proxy_pass http://headscale-server-svc:8080;
|
||||
proxy_http_version 1.1;
|
||||
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: wizard
|
||||
image: beclab/wizard:v1.6.5
|
||||
image: beclab/wizard:v1.6.30
|
||||
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
|
||||
|
||||
@@ -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,15 +1,16 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/utils"
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"os"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func newUserClientFromKubeConfig(kubeconfig string) (client.Client, error) {
|
||||
|
||||
33
cli/go.mod
33
cli/go.mod
@@ -1,27 +1,21 @@
|
||||
module github.com/beclab/Olares/cli
|
||||
|
||||
go 1.24.2
|
||||
|
||||
toolchain go1.24.6
|
||||
go 1.24.11
|
||||
|
||||
replace (
|
||||
bytetrade.io/web3os/app-service => github.com/beclab/app-service v0.4.41
|
||||
bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17
|
||||
github.com/containers/image/v5 => github.com/containers/image/v5 v5.21.1
|
||||
github.com/containers/storage => github.com/containers/storage v1.40.0
|
||||
github.com/estesp/manifest-tool/v2 => github.com/estesp/manifest-tool/v2 v2.0.3
|
||||
github.com/opencontainers/image-spec => github.com/opencontainers/image-spec v1.1.0
|
||||
)
|
||||
|
||||
require (
|
||||
bytetrade.io/web3os/app-service v0.0.0-00010101000000-000000000000
|
||||
bytetrade.io/web3os/backups-sdk v0.0.0-00010101000000-000000000000
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/PaesslerAG/jsonpath v0.1.1
|
||||
github.com/alecthomas/assert/v2 v2.11.0
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70
|
||||
github.com/beclab/api v0.0.2
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1
|
||||
github.com/containerd/containerd v1.7.28
|
||||
github.com/containerd/containerd v1.7.29
|
||||
github.com/decentralized-identity/web5-go v0.25.0
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
|
||||
github.com/distribution/reference v0.6.0
|
||||
@@ -48,10 +42,10 @@ require (
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.1.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.41.0
|
||||
golang.org/x/sys v0.35.0
|
||||
golang.org/x/term v0.34.0
|
||||
golang.org/x/text v0.28.0
|
||||
golang.org/x/crypto v0.45.0
|
||||
golang.org/x/sys v0.38.0
|
||||
golang.org/x/term v0.37.0
|
||||
golang.org/x/text v0.31.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
helm.sh/helm/v3 v3.18.6
|
||||
@@ -94,9 +88,11 @@ require (
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/containers/image/v5 v5.36.1 // indirect
|
||||
github.com/containers/storage v1.59.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
@@ -174,7 +170,7 @@ require (
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.2.1 // indirect
|
||||
github.com/opencontainers/selinux v1.12.0 // indirect
|
||||
github.com/opencontainers/selinux v1.13.1 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
@@ -205,10 +201,11 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/time v0.12.0 // indirect
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
|
||||
|
||||
72
cli/go.sum
72
cli/go.sum
@@ -43,10 +43,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70 h1:U3z6m0hokD1gzl788BrUdxCbDyAjdOBBXA8ilYgn6VQ=
|
||||
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70/go.mod h1:D9wl7y3obLqXMqfubMROMgdxWAwInnKNrFC//d0nyIA=
|
||||
github.com/beclab/api v0.0.2 h1:aD5RcMie2uqa/FZI7aQBa1F4yVEib8/x3IIZSLiHkBM=
|
||||
github.com/beclab/api v0.0.2/go.mod h1:ESZLe8cf4934QFkU6cqbskKfiTyNk67i1qbv/ctS6js=
|
||||
github.com/beclab/app-service v0.4.41 h1:WSIXEqHSAepHweBooPkc+pedVaGGn335RugNwixkciY=
|
||||
github.com/beclab/app-service v0.4.41/go.mod h1:0vEg3rv/DbR7dYznvTlXNXyYNn+TXNMaxz03GQYRWUQ=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
@@ -68,8 +68,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
|
||||
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
|
||||
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c=
|
||||
github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
|
||||
github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
|
||||
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
|
||||
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc=
|
||||
github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
|
||||
@@ -88,13 +88,17 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
|
||||
github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
|
||||
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
|
||||
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
|
||||
github.com/containers/image/v5 v5.36.1 h1:6zpXBqR59UcAzoKpa/By5XekeqFV+htWYfr65+Cgjqo=
|
||||
github.com/containers/image/v5 v5.36.1/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4=
|
||||
github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs=
|
||||
github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
|
||||
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
@@ -105,16 +109,14 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
|
||||
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=
|
||||
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
|
||||
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
|
||||
@@ -262,6 +264,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
@@ -348,6 +352,8 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n
|
||||
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/nats-io/nats.go v1.45.0 h1:/wGPbnYXDM0pLKFjZTX+2JOw9TQPoIgTFrUaH97giwA=
|
||||
@@ -368,12 +374,12 @@ github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
|
||||
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
|
||||
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
|
||||
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
|
||||
github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
|
||||
github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
|
||||
@@ -502,8 +508,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glB
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU=
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU=
|
||||
@@ -542,8 +548,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -552,8 +558,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -564,8 +570,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
||||
@@ -574,8 +580,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -587,14 +593,14 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
|
||||
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -606,8 +612,10 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
|
||||
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
|
||||
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
@@ -323,59 +330,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 +441,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
|
||||
}
|
||||
|
||||
|
||||
@@ -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{},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apputils "bytetrade.io/web3os/app-service/pkg/utils"
|
||||
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apputils "github.com/beclab/Olares/framework/app-service/pkg/utils"
|
||||
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/storage"
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1alpha1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
@@ -5,12 +5,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
v1alpha1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
"github.com/Masterminds/semver/v3"
|
||||
"github.com/beclab/Olares/cli/pkg/common"
|
||||
"github.com/beclab/Olares/cli/pkg/core/connector"
|
||||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||||
"github.com/beclab/Olares/cli/pkg/core/task"
|
||||
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
@@ -22,7 +22,7 @@ require (
|
||||
bytetrade.io/web3os/bfl v0.0.0-00010101000000-000000000000
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
|
||||
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89
|
||||
github.com/beclab/Olares/cli v0.0.0-20251219153848-63d422037cf9
|
||||
github.com/containerd/containerd v1.7.28
|
||||
github.com/distribution/distribution/v3 v3.0.0
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
@@ -39,6 +39,7 @@ require (
|
||||
github.com/libp2p/go-netroute v0.2.2
|
||||
github.com/mackerelio/go-osstat v0.2.5
|
||||
github.com/mdlayher/raw v0.1.0
|
||||
github.com/miekg/dns v1.1.55
|
||||
github.com/muka/network_manager v0.0.0-20200903202308-ae5ede816e07
|
||||
github.com/nxadm/tail v1.4.11
|
||||
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
|
||||
@@ -56,6 +57,7 @@ require (
|
||||
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
|
||||
golang.org/x/sys v0.35.0
|
||||
k8s.io/api v0.34.1
|
||||
k8s.io/apiextensions-apiserver v0.34.0
|
||||
k8s.io/apimachinery v0.34.1
|
||||
k8s.io/client-go v12.0.0+incompatible
|
||||
k8s.io/cri-api v0.34.1
|
||||
@@ -129,7 +131,6 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/mdlayher/packet v0.0.0-20220221164757-67998ac0ff93 // indirect
|
||||
github.com/mdlayher/socket v0.2.1 // indirect
|
||||
github.com/miekg/dns v1.1.55 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
@@ -200,7 +201,6 @@ require (
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
howett.net/plist v1.0.0 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.34.0 // indirect
|
||||
k8s.io/apiserver v0.34.0 // indirect
|
||||
k8s.io/component-base v0.34.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
|
||||
|
||||
@@ -24,8 +24,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89 h1:5s9hXV8K3faToQtE9DbiM7O6jt5kIiEsLAaKn6F0UfA=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89/go.mod h1:iEvZxM6PnFxFRppneTzV3hgr2tIxDnsI3dhp4pi7pFg=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251219153848-63d422037cf9 h1:YNHfPra2FqsKJ5mAxSWNVIK6VyWygRyZiNwfPqiFxlg=
|
||||
github.com/beclab/Olares/cli v0.0.0-20251219153848-63d422037cf9/go.mod h1:cYPcuju2yRSp9BQjIN/CC495dDOOvVoL42r/gvFlutk=
|
||||
github.com/beclab/app-service v0.4.37 h1:gt60wQxgPWMc3oN94TNSdiQAvzqTyCv/OUP93jNSQTY=
|
||||
github.com/beclab/app-service v0.4.37/go.mod h1:0vEg3rv/DbR7dYznvTlXNXyYNn+TXNMaxz03GQYRWUQ=
|
||||
github.com/beclab/bfl v0.3.36 h1:PgeSPGc+XoONiwFsKq9xX8rqcL4kVM1G/ut0lYYj/js=
|
||||
|
||||
@@ -43,16 +43,18 @@ func (h *Handlers) getMountedPath(ctx *fiber.Ctx, mutate func(*disk.UsageStat) *
|
||||
u = mutate(u)
|
||||
}
|
||||
|
||||
res = append(res, &mountedPath{
|
||||
*u,
|
||||
string(p.Type),
|
||||
p.Invalid,
|
||||
p.IDSerial,
|
||||
p.IDSerialShort,
|
||||
p.PartitionUUID,
|
||||
p.Device,
|
||||
p.ReadOnly,
|
||||
})
|
||||
if u != nil {
|
||||
res = append(res, &mountedPath{
|
||||
*u,
|
||||
string(p.Type),
|
||||
p.Invalid,
|
||||
p.IDSerial,
|
||||
p.IDSerialShort,
|
||||
p.PartitionUUID,
|
||||
p.Device,
|
||||
p.ReadOnly,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return h.OkJSON(ctx, "success", res)
|
||||
@@ -64,7 +66,14 @@ func (h *Handlers) GetMountedPath(ctx *fiber.Ctx) error {
|
||||
|
||||
func (h *Handlers) GetMountedPathInCluster(ctx *fiber.Ctx) error {
|
||||
return h.getMountedPath(ctx, func(us *disk.UsageStat) *disk.UsageStat {
|
||||
us.Path = nodePathToClusterPath(us.Path)
|
||||
path := nodePathToClusterPath(us.Path)
|
||||
if path == us.Path {
|
||||
// not in cluster path
|
||||
return nil
|
||||
}
|
||||
|
||||
us.Path = path
|
||||
|
||||
return us
|
||||
})
|
||||
}
|
||||
|
||||
@@ -267,7 +267,8 @@ func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevic
|
||||
if err = mounter.Mount(d.DevPath, mkMountDir, "", []string{"uid=1000", "gid=1000"}); err != nil {
|
||||
klog.Warning("mount usb error, ", err, ", ", d.DevPath, ", ", mkMountDir)
|
||||
// clear the empty mount dir
|
||||
if err = os.RemoveAll(mkMountDir); err != nil {
|
||||
// do not use remove all, only remove the mount point path, assume it's an empty dir
|
||||
if err = os.Remove(mkMountDir); err != nil {
|
||||
klog.Error("remove the mount dir error, ", err)
|
||||
}
|
||||
|
||||
@@ -287,7 +288,8 @@ func umountAndRemovePath(ctx context.Context, path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.RemoveAll(path); err != nil {
|
||||
// do not use remove all, only remove the mount point path, assume it's an empty dir
|
||||
if err = os.Remove(path); err != nil {
|
||||
klog.Error("remove mount point error, ", err)
|
||||
}
|
||||
|
||||
@@ -397,6 +399,11 @@ func UmountBrokenMount(ctx context.Context, baseDir string) error {
|
||||
|
||||
klog.Infof("broken mountpoint: %v, %v, %v", m.Path, m.Device, r.Reason)
|
||||
|
||||
if err = umountAndRemovePath(ctx, m.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !isDeviceExists(m.Device) {
|
||||
klog.Infof("device not exists mountpoint: %v, %v", m.Path, m.Device)
|
||||
if err = umountAndRemovePath(ctx, m.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -659,3 +666,16 @@ func checkMount(mountPoint string, timeout time.Duration) result {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func isDeviceExists(devicePath string) bool {
|
||||
if !strings.HasPrefix(devicePath, "/dev") {
|
||||
return true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(devicePath, "/dev/mapper/") {
|
||||
return true
|
||||
}
|
||||
|
||||
_, err := os.Stat(devicePath)
|
||||
return !os.IsNotExist(err)
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ spec:
|
||||
priorityClassName: "system-cluster-critical"
|
||||
containers:
|
||||
- name: app-service
|
||||
image: beclab/app-service:0.4.67
|
||||
image: beclab/app-service:0.4.69
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
@@ -228,6 +228,8 @@ spec:
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: status.hostIP
|
||||
- name: OLARESD_HOST
|
||||
value: $(HOSTIP):18088
|
||||
volumeMounts:
|
||||
- mountPath: /charts
|
||||
name: charts-store
|
||||
|
||||
@@ -376,6 +376,14 @@ func (r *ApplicationReconciler) createApplication(ctx context.Context, req ctrl.
|
||||
|
||||
func (r *ApplicationReconciler) updateApplication(ctx context.Context, req ctrl.Request,
|
||||
deployment client.Object, app *appv1alpha1.Application, name string) error {
|
||||
// Skip update if triggered by app modification (not deployment change)
|
||||
if app.Annotations != nil {
|
||||
if lastVersion := app.Annotations[deploymentResourceVersionAnnotation]; lastVersion == deployment.GetResourceVersion() {
|
||||
klog.Infof("skip updateApplication: deployment %s not changed, triggered by app modification", deployment.GetName())
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
appCopy := app.DeepCopy()
|
||||
appNames := getAppName(deployment)
|
||||
isMultiApp := len(appNames) > 1
|
||||
@@ -406,7 +414,7 @@ func (r *ApplicationReconciler) updateApplication(ctx context.Context, req ctrl.
|
||||
} else {
|
||||
appid = appv1alpha1.AppName(name).GetAppID()
|
||||
}
|
||||
_, sharedEntrances := r.getAppSettings(ctx, name, appid, owner, deployment, isMultiApp, entrancesMap[name])
|
||||
settings, sharedEntrances := r.getAppSettings(ctx, name, appid, owner, deployment, isMultiApp, entrancesMap[name])
|
||||
|
||||
appCopy.Spec.Name = name
|
||||
appCopy.Spec.Namespace = deployment.GetNamespace()
|
||||
@@ -415,7 +423,21 @@ func (r *ApplicationReconciler) updateApplication(ctx context.Context, req ctrl.
|
||||
appCopy.Spec.Icon = icon
|
||||
appCopy.Spec.SharedEntrances = sharedEntrances
|
||||
appCopy.Spec.Ports = servicePortsMap[name]
|
||||
appCopy.Spec.Entrances = entrancesMap[name]
|
||||
|
||||
// Merge entrances: preserve authLevel from existing, update other fields
|
||||
appCopy.Spec.Entrances = mergeEntrances(app.Spec.Entrances, entrancesMap[name])
|
||||
|
||||
if appCopy.Spec.Settings == nil {
|
||||
appCopy.Spec.Settings = make(map[string]string)
|
||||
}
|
||||
if settings["defaultThirdLevelDomainConfig"] != "" {
|
||||
appCopy.Spec.Settings["defaultThirdLevelDomainConfig"] = settings["defaultThirdLevelDomainConfig"]
|
||||
}
|
||||
|
||||
if incomingPolicy := settings[applicationSettingsPolicyKey]; incomingPolicy != "" {
|
||||
existingPolicy := appCopy.Spec.Settings[applicationSettingsPolicyKey]
|
||||
appCopy.Spec.Settings[applicationSettingsPolicyKey] = mergePolicySettings(existingPolicy, incomingPolicy)
|
||||
}
|
||||
|
||||
if tailScale != nil {
|
||||
appCopy.Spec.TailScale = *tailScale
|
||||
@@ -436,6 +458,13 @@ func (r *ApplicationReconciler) updateApplication(ctx context.Context, req ctrl.
|
||||
}
|
||||
}
|
||||
|
||||
// Record deployment resourceVersion to detect app-only modifications
|
||||
if appCopy.Annotations == nil {
|
||||
appCopy.Annotations = make(map[string]string)
|
||||
}
|
||||
klog.Infof("deploymentname: %s, version: %v", deployment.GetName(), deployment.GetResourceVersion())
|
||||
appCopy.Annotations[deploymentResourceVersionAnnotation] = deployment.GetResourceVersion()
|
||||
|
||||
err = r.Patch(ctx, appCopy, client.MergeFrom(app))
|
||||
if err != nil {
|
||||
klog.Infof("update spec failed %v", err)
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
appv1alpha1 "bytetrade.io/web3os/app-service/api/app.bytetrade.io/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
applicationSettingsPolicyKey = "policy"
|
||||
namespaceFinalizer = "finalizers.bytetrade.io/namespaces"
|
||||
userFinalizer = "finalizers.bytetrade.io/users"
|
||||
creator = "bytetrade.io/creator"
|
||||
applicationSettingsPolicyKey = "policy"
|
||||
namespaceFinalizer = "finalizers.bytetrade.io/namespaces"
|
||||
userFinalizer = "finalizers.bytetrade.io/users"
|
||||
creator = "bytetrade.io/creator"
|
||||
deploymentResourceVersionAnnotation = "bytetrade.io/deployment-resource-version"
|
||||
)
|
||||
|
||||
type applicationSettingsSubPolicy struct {
|
||||
@@ -20,3 +27,59 @@ type applicationSettingsPolicy struct {
|
||||
OneTime bool `json:"one_time"`
|
||||
Duration int32 `json:"valid_duration"`
|
||||
}
|
||||
|
||||
// mergeEntrances merges new entrances with existing ones.
|
||||
// Preserves authLevel from existing entrances, other fields are updated from new entrances.
|
||||
func mergeEntrances(existing, incoming []appv1alpha1.Entrance) []appv1alpha1.Entrance {
|
||||
if len(existing) == 0 {
|
||||
return incoming
|
||||
}
|
||||
|
||||
existingByName := make(map[string]*appv1alpha1.Entrance, len(existing))
|
||||
for i := range existing {
|
||||
existingByName[existing[i].Name] = &existing[i]
|
||||
}
|
||||
|
||||
merged := make([]appv1alpha1.Entrance, 0, len(incoming))
|
||||
for _, entry := range incoming {
|
||||
if old, exists := existingByName[entry.Name]; exists {
|
||||
entry.AuthLevel = old.AuthLevel
|
||||
}
|
||||
merged = append(merged, entry)
|
||||
}
|
||||
|
||||
return merged
|
||||
}
|
||||
|
||||
func mergePolicySettings(existingPolicy, incomingPolicy string) string {
|
||||
if incomingPolicy == "" {
|
||||
return existingPolicy
|
||||
}
|
||||
if existingPolicy == "" {
|
||||
return incomingPolicy
|
||||
}
|
||||
|
||||
var existing, incoming map[string]applicationSettingsPolicy
|
||||
if err := json.Unmarshal([]byte(existingPolicy), &existing); err != nil {
|
||||
return incomingPolicy
|
||||
}
|
||||
if err := json.Unmarshal([]byte(incomingPolicy), &incoming); err != nil {
|
||||
return existingPolicy
|
||||
}
|
||||
|
||||
merged := make(map[string]applicationSettingsPolicy, len(incoming))
|
||||
for name, incomingEntry := range incoming {
|
||||
if existingEntry, exists := existing[name]; exists {
|
||||
incomingEntry.DefaultPolicy = existingEntry.DefaultPolicy
|
||||
incomingEntry.SubPolicies = existingEntry.SubPolicies
|
||||
}
|
||||
merged[name] = incomingEntry
|
||||
}
|
||||
|
||||
result, err := json.Marshal(merged)
|
||||
if err != nil {
|
||||
return existingPolicy
|
||||
}
|
||||
|
||||
return string(result)
|
||||
}
|
||||
|
||||
303
framework/app-service/controllers/types_test.go
Normal file
303
framework/app-service/controllers/types_test.go
Normal file
@@ -0,0 +1,303 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
appv1alpha1 "bytetrade.io/web3os/app-service/api/app.bytetrade.io/v1alpha1"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("mergeEntrances", func() {
|
||||
It("should return incoming when existing is empty", func() {
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 8080, AuthLevel: "public"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(nil, incoming)
|
||||
|
||||
Expect(result).To(Equal(incoming))
|
||||
})
|
||||
|
||||
It("should return incoming when existing is empty slice", func() {
|
||||
existing := []appv1alpha1.Entrance{}
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 8080, AuthLevel: "public"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(existing, incoming)
|
||||
|
||||
Expect(result).To(Equal(incoming))
|
||||
})
|
||||
|
||||
It("should preserve authLevel from existing entrances", func() {
|
||||
existing := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "old-svc", Port: 80, AuthLevel: "private"},
|
||||
}
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "new-svc", Port: 8080, AuthLevel: "public"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(existing, incoming)
|
||||
|
||||
Expect(result).To(HaveLen(1))
|
||||
Expect(result[0].Name).To(Equal("web"))
|
||||
Expect(result[0].Host).To(Equal("new-svc"))
|
||||
Expect(result[0].Port).To(Equal(int32(8080)))
|
||||
Expect(result[0].AuthLevel).To(Equal("private")) // preserved from existing
|
||||
})
|
||||
|
||||
It("should update other fields from incoming", func() {
|
||||
existing := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "old-svc", Port: 80, AuthLevel: "private", Title: "Old Title", Icon: "old-icon"},
|
||||
}
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "new-svc", Port: 8080, AuthLevel: "public", Title: "New Title", Icon: "new-icon"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(existing, incoming)
|
||||
|
||||
Expect(result).To(HaveLen(1))
|
||||
Expect(result[0].Host).To(Equal("new-svc"))
|
||||
Expect(result[0].Port).To(Equal(int32(8080)))
|
||||
Expect(result[0].Title).To(Equal("New Title"))
|
||||
Expect(result[0].Icon).To(Equal("new-icon"))
|
||||
Expect(result[0].AuthLevel).To(Equal("private")) // preserved
|
||||
})
|
||||
|
||||
It("should handle new entrance not in existing", func() {
|
||||
existing := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 80, AuthLevel: "private"},
|
||||
}
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 80, AuthLevel: "public"},
|
||||
{Name: "api", Host: "api-svc", Port: 3000, AuthLevel: "public"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(existing, incoming)
|
||||
|
||||
Expect(result).To(HaveLen(2))
|
||||
// web entrance preserves authLevel
|
||||
Expect(result[0].Name).To(Equal("web"))
|
||||
Expect(result[0].AuthLevel).To(Equal("private"))
|
||||
// api entrance uses incoming authLevel (no existing)
|
||||
Expect(result[1].Name).To(Equal("api"))
|
||||
Expect(result[1].AuthLevel).To(Equal("public"))
|
||||
})
|
||||
|
||||
It("should handle removed entrance from existing", func() {
|
||||
existing := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 80, AuthLevel: "private"},
|
||||
{Name: "api", Host: "api-svc", Port: 3000, AuthLevel: "private"},
|
||||
}
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 80, AuthLevel: "public"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(existing, incoming)
|
||||
|
||||
Expect(result).To(HaveLen(1))
|
||||
Expect(result[0].Name).To(Equal("web"))
|
||||
Expect(result[0].AuthLevel).To(Equal("private"))
|
||||
})
|
||||
|
||||
It("should handle multiple entrances correctly", func() {
|
||||
existing := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-svc", Port: 80, AuthLevel: "private"},
|
||||
{Name: "admin", Host: "admin-svc", Port: 9000, AuthLevel: "internal"},
|
||||
}
|
||||
incoming := []appv1alpha1.Entrance{
|
||||
{Name: "web", Host: "web-new", Port: 8080, AuthLevel: "public"},
|
||||
{Name: "admin", Host: "admin-new", Port: 9090, AuthLevel: "public"},
|
||||
{Name: "api", Host: "api-svc", Port: 3000, AuthLevel: "public"},
|
||||
}
|
||||
|
||||
result := mergeEntrances(existing, incoming)
|
||||
|
||||
Expect(result).To(HaveLen(3))
|
||||
// web: authLevel preserved
|
||||
Expect(result[0].Name).To(Equal("web"))
|
||||
Expect(result[0].Host).To(Equal("web-new"))
|
||||
Expect(result[0].AuthLevel).To(Equal("private"))
|
||||
// admin: authLevel preserved
|
||||
Expect(result[1].Name).To(Equal("admin"))
|
||||
Expect(result[1].Host).To(Equal("admin-new"))
|
||||
Expect(result[1].AuthLevel).To(Equal("internal"))
|
||||
// api: new entrance, uses incoming authLevel
|
||||
Expect(result[2].Name).To(Equal("api"))
|
||||
Expect(result[2].AuthLevel).To(Equal("public"))
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("mergePolicySettings", func() {
|
||||
It("should return existing when incoming is empty", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, "")
|
||||
|
||||
Expect(result).To(Equal(existing))
|
||||
})
|
||||
|
||||
It("should return incoming when existing is empty", func() {
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","one_time":false,"sub_policies":[{"one_time":true,"policy":"one_factor","uri":"/api/send","valid_duration":0}],"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings("", incoming)
|
||||
|
||||
Expect(result).To(Equal(incoming))
|
||||
})
|
||||
|
||||
It("should preserve default_policy from existing", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"private","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(resultPolicy["calibreweb-svc"].DefaultPolicy).To(Equal("private"))
|
||||
})
|
||||
|
||||
It("should preserve sub_policies from existing", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"system","sub_policies":[{"uri":"/api/send","policy":"one_factor","one_time":true,"valid_duration":0}],"one_time":false,"valid_duration":0}}`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":[{"uri":"/api/new","policy":"two_factor","one_time":false,"valid_duration":3600}],"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// sub_policies preserved from existing
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies[0].URI).To(Equal("/api/send"))
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies[0].Policy).To(Equal("one_factor"))
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies[0].OneTime).To(BeTrue())
|
||||
})
|
||||
|
||||
It("should preserve both default_policy and sub_policies from existing", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"public","sub_policies":[{"uri":"/api/send","policy":"one_factor","one_time":true,"valid_duration":0}],"one_time":false,"valid_duration":0}}`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":[{"uri":"/api/new","policy":"two_factor","one_time":false,"valid_duration":3600}],"one_time":true,"valid_duration":1800}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// default_policy preserved from existing
|
||||
Expect(resultPolicy["calibreweb-svc"].DefaultPolicy).To(Equal("public"))
|
||||
// sub_policies preserved from existing
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies[0].URI).To(Equal("/api/send"))
|
||||
// other fields use incoming
|
||||
Expect(resultPolicy["calibreweb-svc"].OneTime).To(BeTrue())
|
||||
Expect(resultPolicy["calibreweb-svc"].Duration).To(Equal(int32(1800)))
|
||||
})
|
||||
|
||||
It("should preserve null sub_policies from existing", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":[{"uri":"/api/send","policy":"one_factor","one_time":true,"valid_duration":0}],"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// sub_policies preserved as null from existing
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies).To(BeNil())
|
||||
})
|
||||
|
||||
It("should add new entrance policy with incoming values", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"private","sub_policies":[{"uri":"/old","policy":"one_factor","one_time":false,"valid_duration":0}],"one_time":false,"valid_duration":0}}`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0},"api-svc":{"default_policy":"public","sub_policies":[{"uri":"/api","policy":"two_factor","one_time":true,"valid_duration":3600}],"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// existing entry: preserved default_policy and sub_policies
|
||||
Expect(resultPolicy["calibreweb-svc"].DefaultPolicy).To(Equal("private"))
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["calibreweb-svc"].SubPolicies[0].URI).To(Equal("/old"))
|
||||
// new entry: uses incoming values
|
||||
Expect(resultPolicy).To(HaveKey("api-svc"))
|
||||
Expect(resultPolicy["api-svc"].DefaultPolicy).To(Equal("public"))
|
||||
Expect(resultPolicy["api-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["api-svc"].SubPolicies[0].URI).To(Equal("/api"))
|
||||
})
|
||||
|
||||
It("should delete entrance policy not in incoming", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0},"api-svc":{"default_policy":"public","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(resultPolicy).To(HaveKey("calibreweb-svc"))
|
||||
Expect(resultPolicy).NotTo(HaveKey("api-svc"))
|
||||
})
|
||||
|
||||
It("should handle add, preserve, and delete together", func() {
|
||||
existing := `{
|
||||
"web-svc":{"default_policy":"private","sub_policies":[{"uri":"/web","policy":"one_factor","one_time":false,"valid_duration":0}],"one_time":false,"valid_duration":0},
|
||||
"admin-svc":{"default_policy":"internal","sub_policies":[{"uri":"/admin","policy":"two_factor","one_time":true,"valid_duration":3600}],"one_time":false,"valid_duration":0},
|
||||
"legacy-svc":{"default_policy":"public","sub_policies":null,"one_time":false,"valid_duration":0}
|
||||
}`
|
||||
incoming := `{
|
||||
"web-svc":{"default_policy":"system","sub_policies":null,"one_time":true,"valid_duration":1800},
|
||||
"admin-svc":{"default_policy":"system","sub_policies":[{"uri":"/new","policy":"one_factor","one_time":false,"valid_duration":0}],"one_time":false,"valid_duration":0},
|
||||
"api-svc":{"default_policy":"system","sub_policies":[{"uri":"/api","policy":"one_factor","one_time":false,"valid_duration":0}],"one_time":false,"valid_duration":0}
|
||||
}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
var resultPolicy map[string]applicationSettingsPolicy
|
||||
err := json.Unmarshal([]byte(result), &resultPolicy)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// web-svc: default_policy and sub_policies preserved, other fields from incoming
|
||||
Expect(resultPolicy["web-svc"].DefaultPolicy).To(Equal("private"))
|
||||
Expect(resultPolicy["web-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["web-svc"].SubPolicies[0].URI).To(Equal("/web"))
|
||||
Expect(resultPolicy["web-svc"].OneTime).To(BeTrue())
|
||||
Expect(resultPolicy["web-svc"].Duration).To(Equal(int32(1800)))
|
||||
// admin-svc: default_policy and sub_policies preserved
|
||||
Expect(resultPolicy["admin-svc"].DefaultPolicy).To(Equal("internal"))
|
||||
Expect(resultPolicy["admin-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["admin-svc"].SubPolicies[0].URI).To(Equal("/admin"))
|
||||
Expect(resultPolicy["admin-svc"].SubPolicies[0].Policy).To(Equal("two_factor"))
|
||||
// api-svc: new entry, uses incoming values
|
||||
Expect(resultPolicy).To(HaveKey("api-svc"))
|
||||
Expect(resultPolicy["api-svc"].DefaultPolicy).To(Equal("system"))
|
||||
Expect(resultPolicy["api-svc"].SubPolicies).To(HaveLen(1))
|
||||
Expect(resultPolicy["api-svc"].SubPolicies[0].URI).To(Equal("/api"))
|
||||
// legacy-svc: deleted (not in incoming)
|
||||
Expect(resultPolicy).NotTo(HaveKey("legacy-svc"))
|
||||
})
|
||||
|
||||
It("should return incoming when existing JSON is invalid", func() {
|
||||
existing := `invalid json`
|
||||
incoming := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
Expect(result).To(Equal(incoming))
|
||||
})
|
||||
|
||||
It("should return existing when incoming JSON is invalid", func() {
|
||||
existing := `{"calibreweb-svc":{"default_policy":"system","sub_policies":null,"one_time":false,"valid_duration":0}}`
|
||||
incoming := `invalid json`
|
||||
|
||||
result := mergePolicySettings(existing, incoming)
|
||||
|
||||
Expect(result).To(Equal(existing))
|
||||
})
|
||||
})
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"bytetrade.io/web3os/app-service/api/app.bytetrade.io/v1alpha1"
|
||||
"bytetrade.io/web3os/app-service/pkg/appcfg"
|
||||
@@ -258,6 +258,13 @@ func (h *HelmOps) SetValues() (values map[string]interface{}, err error) {
|
||||
|
||||
klog.Infof("values[node]: %#v", values["nodes"])
|
||||
|
||||
deviceName, err := utils.GetDeviceName()
|
||||
if err != nil {
|
||||
klog.Errorf("failed to get deviceName %v", err)
|
||||
return values, err
|
||||
}
|
||||
|
||||
values["deviceName"] = deviceName
|
||||
return values, err
|
||||
}
|
||||
|
||||
@@ -296,7 +303,7 @@ func (h *HelmOps) getInstalledApps(ctx context.Context) (installed bool, app []*
|
||||
func (h *HelmOps) AddEnvironmentVariables(values map[string]interface{}) error {
|
||||
values[constants.OlaresEnvHelmValuesKey] = make(map[string]interface{})
|
||||
appEnv, err := h.client.AppClient.SysV1alpha1().AppEnvs(h.app.Namespace).Get(h.ctx, apputils.FormatAppEnvName(h.app.AppName, h.app.OwnerName), metav1.GetOptions{})
|
||||
if errors.IsNotFound(err) {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
@@ -181,6 +181,14 @@ func (p *DownloadingApp) exec(ctx context.Context) error {
|
||||
}
|
||||
values["nodes"] = nodeInfo
|
||||
|
||||
deviceName, err := utils.GetDeviceName()
|
||||
if err != nil {
|
||||
klog.Errorf("failed to get deviceName %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
values["deviceName"] = deviceName
|
||||
|
||||
refs, err := p.getRefsForImageManager(appConfig, values)
|
||||
if err != nil {
|
||||
klog.Errorf("get image refs from resources failed %v", err)
|
||||
|
||||
@@ -235,6 +235,14 @@ func (p *UpgradingApp) exec(ctx context.Context) error {
|
||||
}
|
||||
values["nodes"] = nodeInfo
|
||||
|
||||
deviceName, err := utils.GetDeviceName()
|
||||
if err != nil {
|
||||
klog.Errorf("failed to get deviceName %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
values["deviceName"] = deviceName
|
||||
|
||||
refs, err := p.getRefsForImageManager(appConfig, values)
|
||||
if err != nil {
|
||||
klog.Errorf("get image refs from resources failed %v", err)
|
||||
|
||||
@@ -4,8 +4,11 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -399,3 +402,69 @@ func GetNodeInfo(ctx context.Context) (ret []api.NodeInfo, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type SystemStatusResponse struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data struct {
|
||||
TerminusdState string `json:"terminusdState"`
|
||||
TerminusState string `json:"terminusState"`
|
||||
TerminusName string `json:"terminusName"`
|
||||
TerminusVersion string `json:"terminusVersion"`
|
||||
InstalledTime int64 `json:"installedTime"`
|
||||
InitializedTime int64 `json:"initializedTime"`
|
||||
OlaresdVersion string `json:"olaresdVersion"`
|
||||
DeviceName string `json:"device_name"`
|
||||
HostName string `json:"host_name"`
|
||||
OsType string `json:"os_type"`
|
||||
OsArch string `json:"os_arch"`
|
||||
OsInfo string `json:"os_info"`
|
||||
OsVersion string `json:"os_version"`
|
||||
CpuInfo string `json:"cpu_info"`
|
||||
GpuInfo string `json:"gpu_info"`
|
||||
Memory string `json:"memory"`
|
||||
Disk string `json:"disk"`
|
||||
WifiConnected bool `json:"wifiConnected"`
|
||||
WiredConnected bool `json:"wiredConnected"`
|
||||
HostIp string `json:"hostIp"`
|
||||
ExternalIp string `json:"externalIp"`
|
||||
InstallingState string `json:"installingState"`
|
||||
InstallingProgress string `json:"installingProgress"`
|
||||
UninstallingState string `json:"uninstallingState"`
|
||||
UninstallingProgress string `json:"uninstallingProgress"`
|
||||
UpgradingTarget string `json:"upgradingTarget"`
|
||||
UpgradingRetryNum int `json:"upgradingRetryNum"`
|
||||
UpgradingState string `json:"upgradingState"`
|
||||
UpgradingStep string `json:"upgradingStep"`
|
||||
UpgradingProgress string `json:"upgradingProgress"`
|
||||
UpgradingError string `json:"upgradingError"`
|
||||
UpgradingDownloadState string `json:"upgradingDownloadState"`
|
||||
UpgradingDownloadStep string `json:"upgradingDownloadStep"`
|
||||
UpgradingDownloadProgress string `json:"upgradingDownloadProgress"`
|
||||
UpgradingDownloadError string `json:"upgradingDownloadError"`
|
||||
CollectingLogsState string `json:"collectingLogsState"`
|
||||
CollectingLogsError string `json:"collectingLogsError"`
|
||||
DefaultFrpServer string `json:"defaultFrpServer"`
|
||||
FrpEnable string `json:"frpEnable"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
func GetDeviceName() (string, error) {
|
||||
url := fmt.Sprintf("http://%s/system/status", os.Getenv("OLARESD_HOST"))
|
||||
var result SystemStatusResponse
|
||||
client := resty.New()
|
||||
resp, err := client.R().SetResult(&result).Get(url)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to send request to olaresd %v", err)
|
||||
return "", err
|
||||
}
|
||||
if resp.StatusCode() != http.StatusOK {
|
||||
klog.Errorf("failed to get system status from olaresd %v", err)
|
||||
return "", errors.New(string(resp.Body()))
|
||||
}
|
||||
if result.Code != http.StatusOK {
|
||||
return "", fmt.Errorf("not exepcted result code: %v,message: %v", result.Code, result.Message)
|
||||
}
|
||||
klog.Infof("getDeviceName: %#v", result.Data)
|
||||
return result.Data.DeviceName, nil
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ spec:
|
||||
name: check-auth
|
||||
containers:
|
||||
- name: auth-front
|
||||
image: beclab/login:v1.6.26
|
||||
image: beclab/login:v1.6.30
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -266,7 +266,7 @@ spec:
|
||||
|
||||
containers:
|
||||
- name: api
|
||||
image: beclab/bfl:v0.4.36
|
||||
image: beclab/bfl:v0.4.37
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
|
||||
@@ -243,11 +243,34 @@ func (h *Handler) handleActivate(req *restful.Request, resp *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
// for owner user, use the reverse proxy config from the payload
|
||||
// for non-owner user, reuse the owner's reverse proxy config
|
||||
isOwner := userOp.GetUserAnnotation(user, constants.UserAnnotationOwnerRole) == constants.RoleOwner
|
||||
|
||||
reverseProxyConf := &ReverseProxyConfig{}
|
||||
if payload.FRP.Host != "" {
|
||||
reverseProxyConf.EnableFRP = true
|
||||
reverseProxyConf.FRPServer = payload.FRP.Host
|
||||
reverseProxyConf.FRPAuthMethod = FRPAuthMethodJWS
|
||||
if isOwner {
|
||||
if payload.FRP.Host != "" {
|
||||
reverseProxyConf.EnableFRP = true
|
||||
reverseProxyConf.FRPServer = payload.FRP.Host
|
||||
reverseProxyConf.FRPAuthMethod = FRPAuthMethodJWS
|
||||
}
|
||||
} else {
|
||||
ownerUser, ownerErr := userOp.GetOwnerUser()
|
||||
if ownerErr != nil {
|
||||
err = fmt.Errorf("activate system: failed to get owner user for reverse proxy config: %v", ownerErr)
|
||||
klog.Error(err)
|
||||
response.HandleError(resp, err)
|
||||
return
|
||||
}
|
||||
ownerNamespace := fmt.Sprintf(constants.UserspaceNameFormat, ownerUser.Name)
|
||||
ownerConf, ownerConfErr := GetReverseProxyConfigFromNamespace(ctx, ownerNamespace)
|
||||
if ownerConfErr != nil {
|
||||
err = fmt.Errorf("activate system: failed to get owner's reverse proxy config: %v", ownerConfErr)
|
||||
klog.Error(err)
|
||||
response.HandleError(resp, err)
|
||||
return
|
||||
}
|
||||
reverseProxyConf = ownerConf
|
||||
}
|
||||
// no matter whether the reverse proxy is enabled, we need to persist the configuration
|
||||
// so that the configuration can be fetched by the frontend
|
||||
|
||||
@@ -549,7 +549,11 @@ func (conf *ReverseProxyConfig) generateReverseProxyConfigMapData() map[string]s
|
||||
}
|
||||
|
||||
func GetReverseProxyConfig(ctx context.Context) (*ReverseProxyConfig, error) {
|
||||
configData, err := k8sutil.GetConfigMapData(ctx, constants.Namespace, constants.ReverseProxyConfigMapName)
|
||||
return GetReverseProxyConfigFromNamespace(ctx, constants.Namespace)
|
||||
}
|
||||
|
||||
func GetReverseProxyConfigFromNamespace(ctx context.Context, namespace string) (*ReverseProxyConfig, error) {
|
||||
configData, err := k8sutil.GetConfigMapData(ctx, namespace, constants.ReverseProxyConfigMapName)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error getting configmap")
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ spec:
|
||||
command:
|
||||
- /samba_share
|
||||
- name: files
|
||||
image: beclab/files-server:v0.2.140
|
||||
image: beclab/files-server:v0.2.141
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: true
|
||||
|
||||
@@ -140,7 +140,7 @@ spec:
|
||||
name: check-chart-repo
|
||||
containers:
|
||||
- name: appstore-backend
|
||||
image: beclab/market-backend:v0.6.10
|
||||
image: beclab/market-backend:v0.6.12
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 81
|
||||
|
||||
@@ -240,7 +240,7 @@ spec:
|
||||
value: os_framework_search3
|
||||
containers:
|
||||
- name: search3
|
||||
image: beclab/search3:v0.0.96
|
||||
image: beclab/search3:v0.0.97
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
@@ -301,7 +301,7 @@ spec:
|
||||
priorityClassName: "system-cluster-critical"
|
||||
containers:
|
||||
- name: search3monitor
|
||||
image: beclab/search3monitor:v0.0.96
|
||||
image: beclab/search3monitor:v0.0.97
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
|
||||
@@ -64,7 +64,7 @@ spec:
|
||||
operator: Exists
|
||||
containers:
|
||||
- name: search3-validation
|
||||
image: beclab/search3validation:v0.0.96
|
||||
image: beclab/search3validation:v0.0.97
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8443
|
||||
|
||||
@@ -252,6 +252,7 @@ data:
|
||||
not startswith(container.image, "ghcr.io/coder/coder:v2.19.0")
|
||||
not startswith(container.image, "apecloud/")
|
||||
not startswith(container.image, "docker.io/apecloud/")
|
||||
not startswith(container.image, "kldtks/")
|
||||
}
|
||||
|
||||
is_root_user(ctx) if {
|
||||
|
||||
@@ -14,7 +14,7 @@ require (
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/gofiber/contrib/websocket v1.2.2
|
||||
github.com/gofiber/fiber/v2 v2.49.2
|
||||
github.com/gofiber/fiber/v2 v2.52.9
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/jmoiron/sqlx v1.3.5
|
||||
@@ -50,7 +50,7 @@ require (
|
||||
require (
|
||||
github.com/Azure/azure-pipeline-go v0.2.3 // indirect
|
||||
github.com/Azure/azure-storage-blob-go v0.15.0 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/aws/aws-sdk-go v1.50.8 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
@@ -93,7 +93,7 @@ require (
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-ieproxy v0.0.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/minio/crc64nvme v1.0.2 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go v6.0.14+incompatible // indirect
|
||||
@@ -123,7 +123,7 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.50.0 // indirect
|
||||
github.com/valyala/fasthttp v1.51.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
|
||||
@@ -40,8 +40,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alessio/shellescape v1.2.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/apecloud/kubeblocks v1.0.0 h1:ditcH7RNZyDiWiHP1V7IuXWHdcBJv3/X5N89Qlz+xew=
|
||||
github.com/apecloud/kubeblocks v1.0.0/go.mod h1:Mk5xRLm2MpxoTNZKEdDcrIY3I1EpokQBU3Q9Zwse8MI=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
@@ -221,8 +221,8 @@ github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/gofiber/contrib/websocket v1.2.2 h1:6lygrypMM0LqfPUC8N5MZ5apsU9/3K/NJULrIVpS8FU=
|
||||
github.com/gofiber/contrib/websocket v1.2.2/go.mod h1:QPOQ5qazfR/oz7FZD4p5PO9B8TaxjAnaUG/xpbFI1r4=
|
||||
github.com/gofiber/fiber/v2 v2.49.2 h1:ONEN3/Vc+dUCxxDgZZwpqvhISgHqb+bu+isBiEyKEQs=
|
||||
github.com/gofiber/fiber/v2 v2.49.2/go.mod h1:gNsKnyrmfEWFpJxQAV0qvW6l70K1dZGno12oLtukcts=
|
||||
github.com/gofiber/fiber/v2 v2.52.9 h1:YjKl5DOiyP3j0mO61u3NTmK7or8GzzWzCFzkboyP5cw=
|
||||
github.com/gofiber/fiber/v2 v2.52.9/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||
@@ -393,8 +393,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
@@ -598,8 +598,8 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M=
|
||||
github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
|
||||
github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
|
||||
github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||
|
||||
Reference in New Issue
Block a user