Compare commits

...

98 Commits

Author SHA1 Message Date
eball
e260499b2c Merge branch 'feat-add-olaresname-document-query' of github.com:beclab/olares into feat-add-olaresname-document-query
* 'feat-add-olaresname-document-query' of github.com:beclab/olares:
  feat(daemon):  Added an interface for querying the olaresName document and verifying the validity of the JWS.
2025-08-27 15:06:24 +08:00
eball
53c59271c8 fix: import module 2025-08-27 15:05:54 +08:00
Peng Peng
749cafb554 feat(daemon): Added an interface for querying the olaresName document and verifying the validity of the JWS. 2025-08-27 14:59:02 +08:00
eball
34318ee303 cli: Rename resolveDID to ResolveOlaresName (#1757) 2025-08-27 14:57:43 +08:00
hysyeah
1537ff9613 fix: restrict user-service nats permission (#1755) 2025-08-27 01:24:44 +08:00
Peng Peng
014038d959 feat(daemon): Added an interface for querying the olaresName document and verifying the validity of the JWS. 2025-08-26 23:36:43 +08:00
Peng Peng
d8d858be63 feat: notification support application status change and system pressure change (#1753) 2025-08-26 21:51:27 +08:00
dkeven
ade0f4b77b fix(cli): explicitly set locale in etcd backup service (#1752) 2025-08-26 21:50:49 +08:00
eball
b401eb8485 authelia: support default subdomains of system frontend (#1749) 2025-08-26 01:13:46 +08:00
yyh
97768f082c fix(system-frontend): update system-frontend (#1748) 2025-08-26 00:46:19 +08:00
lovehunter9
d60f44e178 fix: files parse form bug & remove seahub & replace nginx for seafile (#1747)
* fix: files parse form bug & remove seahub & replace nginx for seafile

* ci: copy sync to cloud

---------

Co-authored-by: aby913 <aby913@163.com>
2025-08-26 00:45:47 +08:00
0x7fffff92
037de51e98 feat: support basic iGPU functions (#1746)
Co-authored-by: 0x7fffff92 <0x7fffff92@example.com>
2025-08-25 21:17:01 +08:00
berg
3feff71488 system frontend: update version to v1.4.12 (#1742)
feat: update system frontend version to v1.4.12

Co-authored-by: qq815776412 <815776412@qq.com>
2025-08-25 21:16:37 +08:00
lovehunter9
a7368d4a78 feat: files hertz-thrift recons: all apis replaced (#1741)
feat: hertz-thrift recons: all apis replaced
2025-08-23 02:47:41 +08:00
hysyeah
c8ad615891 app-service,bfl,auth: merge multiple applications into one (#1740)
* app-service,bfl,auth: merge multiple applications into one

* fix: rename system app
2025-08-23 02:46:33 +08:00
aby913
2af5ca1494 ci(files): upload files to cloud (#1738) 2025-08-22 16:52:35 +08:00
berg
2870ba8510 system frontend: update system-frontend, chart repo and market backend version (#1737)
feat: update system-frontend, chart repo and market backend version
2025-08-22 00:17:48 +08:00
eball
245e794075 olaresd: add node pressure status (#1735) 2025-08-22 00:11:21 +08:00
dkeven
55c04e26d6 refactor(upgrade): remove path cmd & add spec/viable cmd for upgrade (#1734) 2025-08-22 00:10:39 +08:00
wiy
bf1911e3b4 feat(system-frontend): market support multi-source and fix some bugs (#1733)
feat: market support multi-source

Co-authored-by: icebergtsn <zyh2433219116@gmail.com>
2025-08-21 00:28:58 +08:00
0x7fffff92
a3b709ef0c fix: play failed for some special characters (#1732)
Co-authored-by: 0x7fffff92 <0x7fffff92@example.com>
2025-08-21 00:27:57 +08:00
dkeven
15335e8114 feat(cli): adjust local release command for release id (#1731) 2025-08-21 00:27:12 +08:00
eball
82ed4be5af notifications: remove redundant notification service (#1725) 2025-08-21 00:24:04 +08:00
dkeven
dab5a26b2b fix(ci): correct input source of release version in workflow (#1730) 2025-08-20 11:59:05 +08:00
dkeven
959a32b68f fix(ci): add missing param for release_id when uploading package (#1729) 2025-08-20 11:09:10 +08:00
hysyeah
c5215471b7 lldap: add some auth log (#1728) 2025-08-20 00:23:45 +08:00
dkeven
226eaeb9e7 chore(ci): remove unused md5 render step in release workflow (#1727) 2025-08-19 21:08:50 +08:00
0x7fffff92
9b85411fce feat: add cors (#1726)
Co-authored-by: 0x7fffff92 <0x7fffff92@example.com>
2025-08-19 20:12:43 +08:00
dkeven
053a0d1b8e feat(ci): differentiate multiple releases of the same version (#1724) 2025-08-19 19:54:04 +08:00
eball
aa34dc4412 authelia: add priority class to auth frontend (#1723) 2025-08-19 16:02:26 +08:00
aby913
54155edbbf ci(files): paste task refactor (#1722)
ci: paste task
2025-08-19 00:57:06 +08:00
eball
a776efa62e fix: bump hami core version (#1721) 2025-08-19 00:56:42 +08:00
Calvin W.
ada4d129f6 docs: fix format issues and add notes for domain (#1720) 2025-08-18 21:52:47 +08:00
dkeven
dfb7c5bcc4 feat(cli): add option to skip collecting logs from kube-apiserver (#1719) 2025-08-18 21:46:51 +08:00
Peng Peng
a5b9696d16 feat(docs): update storage requirement (#1717)
feat: update storage requirement
2025-08-16 18:49:29 +08:00
wiy
1870859034 feat(system-frontend): fix system-frontend some bugs (#1715)
* feat(user-service): add /alluser/namespaces api

* feat(system-frontend): release system-frontend new version

---------

Co-authored-by: yyh <24493052+yongheng2016@users.noreply.github.com>
2025-08-16 01:22:23 +08:00
hysyeah
25854d1b14 ks,l4,bfl: remove unused code and vendor dir (#1714) 2025-08-16 01:21:34 +08:00
aby913
cfb4bf93be ci: cloud preview and download, code trimming (#1712)
* ci: cloud preview and download, code trimming

* ci: remove unused drives

* style: remove old watcher and external_watcher

---------

Co-authored-by: lovehunter9 <wangrx07@aliyun.com>
2025-08-16 01:20:55 +08:00
wiy
1571bd82d9 feat(vault-server): update vault support org (#1713) 2025-08-15 00:37:01 +08:00
hysyeah
324456b653 app-service, authelia: fix myapps app sort and authelia ttlcache panic bug (#1711) 2025-08-15 00:36:30 +08:00
Sai
b64e2bd19e feat:Improve the speed of market processing applications (#1710)
Improve the speed of market processing applications
2025-08-15 00:36:07 +08:00
lovehunter9
b49b59e07c fix: cloud move delete and fix a bug because of mkdir for copy and upload (#1708) 2025-08-14 01:00:09 +08:00
dkeven
5dcb0ee7e9 fix(cli): skip failed & deleting users when upgrading (#1705) 2025-08-14 00:59:39 +08:00
dkeven
37b9afe7d5 fix(manifest): add missing condition for sharedlib vol in files (#1704) 2025-08-14 00:59:00 +08:00
Calvin W.
9219fca0ad docs: update custom domain binding for apps (#1706) 2025-08-13 21:31:01 +08:00
wiy
9dd72f2c42 feat(system-frontend): update system-frontend new version (#1702) 2025-08-13 00:13:15 +08:00
hysyeah
9227d9f04e authelia,lldap: group operation api and event publish (#1701)
* authelia,lldap: group operation api and event publish

* fix: add env for os.groups
2025-08-13 00:12:33 +08:00
aby913
41e701b929 ci(files): fix sync rename and copy, cloud copy and integration (#1700) 2025-08-13 00:11:26 +08:00
aby913
7503eb7f42 ci(files): rename, create file and copy with rclone (#1698)
* ci(files): rename, create file and copy with rclone

* feat: sync rename, batch copy & move, copy/move

---------

Co-authored-by: lovehunter9 <wangrx07@aliyun.com>
2025-08-12 00:31:03 +08:00
wiy
0b84f278af feat(system-frontend): update system-frontend and wizard new version (#1697) 2025-08-12 00:30:38 +08:00
hysyeah
62cec2de53 fix: remove values for redis (#1696) 2025-08-12 00:30:07 +08:00
dkeven
ad183f05ce chore: get rid of unused values & ops related to ks redis (#1695) 2025-08-12 00:29:28 +08:00
CobraSoftware
8dea896a28 feat(testing‑mode): allow installation on unsupported OS + ignore build artifacts (#1673)
This commit included updated code to add a
developer mode allowing installation on an
unsupported os. Some of the code was made
by Chatgpt.

Co-authored-by: Cobra Software <crane-tiny-parcel@duck.com>
2025-08-11 11:32:40 +08:00
dependabot[bot]
b62a264c38 chore(deps): bump dompurify and mermaid in /docs (#1694)
Bumps [dompurify](https://github.com/cure53/DOMPurify) to 3.2.6 and updates ancestor dependency [mermaid](https://github.com/mermaid-js/mermaid). These dependencies need to be updated together.


Updates `dompurify` from 3.1.6 to 3.2.6
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.1.6...3.2.6)

Updates `mermaid` from 10.9.3 to 11.9.0
- [Release notes](https://github.com/mermaid-js/mermaid/releases)
- [Commits](https://github.com/mermaid-js/mermaid/compare/v10.9.3...mermaid@11.9.0)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.2.6
  dependency-type: indirect
- dependency-name: mermaid
  dependency-version: 11.9.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-09 15:07:47 +08:00
hysyeah
a030b047b4 app-service, l4, bfl: support creator cli (#1693) 2025-08-09 00:22:29 +08:00
eball
86083ce63c authelia: send the cookie of an ephemeral user to subdomain (#1692) 2025-08-09 00:22:07 +08:00
dkeven
ab0ba8fde6 feat(cli): add commands to manage users (#1691) 2025-08-08 21:27:21 +08:00
hysyeah
a6c44cf29e app-service, cli: queued request; remove ks redis (#1690)
* app-service, cli: queued request; remove ks redis

* fix: omit redis deploy

* fix: rm redis secret from ks-apiserver
2025-08-08 01:48:31 +08:00
Calvin W.
dda43a49ae docs: fix link on dochome and remove dev badge (#1689) 2025-08-07 12:20:06 +08:00
lovehunter9
cad4c09cd4 feat: seahub init and old username migration (#1688) 2025-08-07 01:30:48 +08:00
Sai
0a39b03fbb fix: update check condition for failed task in chart repo (#1686)
update check condition for failed task
2025-08-06 20:44:21 +08:00
dependabot[bot]
b1c525d0dc chore(deps): bump github.com/gofiber/fiber/v2 from 2.52.5 to 2.52.9 in /daemon (#1684)
chore(deps): bump github.com/gofiber/fiber/v2 in /daemon

Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.52.5 to 2.52.9.
- [Release notes](https://github.com/gofiber/fiber/releases)
- [Commits](https://github.com/gofiber/fiber/compare/v2.52.5...v2.52.9)

---
updated-dependencies:
- dependency-name: github.com/gofiber/fiber/v2
  dependency-version: 2.52.9
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-06 20:43:49 +08:00
Calvin W.
2b45ef7bcf docs: expose other installation methods (#1685)
* docs: expose other installation methods

* fix case in manifest
2025-08-06 14:59:05 +08:00
aby913
060d57a2b9 ci: integrate rclone, seahub replace (#1683)
* feat: files replace seahub part 1

* ci(files): integrate rclone, seahub part replace

---------

Co-authored-by: lovehunter9 <wangrx07@aliyun.com>
2025-08-06 11:02:31 +08:00
hysyeah
496ed1c6fb fix: sync users group error (#1682) 2025-08-05 21:40:17 +08:00
dkeven
4c912e1485 chore(cli): remove any call to ulimit that has no effect (#1680) 2025-08-05 21:26:38 +08:00
dkeven
c313982033 fix(ci): copy built script to correct path (#1681) 2025-08-05 17:18:14 +08:00
dkeven
83e070761c fix(cli): create symlink to sysconf if none exists (#1679) 2025-08-05 15:44:42 +08:00
salt
beed97f704 feat: refactor based on fileparam (#1675)
Co-authored-by: ubuntu <you@example.com>
2025-08-05 11:06:40 +08:00
berg
116fa8df72 system-frontend: update system frontend version to v1.3.126 (#1678)
feat: update system frontend version to v1.3.126
2025-08-05 11:06:17 +08:00
hysyeah
7fa1f093ed app-service: set concurrent downloads to 1 (#1677)
app-service: set concurent downloads to 1
2025-08-04 21:57:15 +08:00
Sai
65ca835684 fix: entrance url matching error in market (#1676)
fix URL matching error
2025-08-04 15:53:29 +08:00
eball
fd4b0e3a92 daemon: fix checking if ip changed bug (#1674)
* daemon: fix checking if ip changed bug

* fix: check master ip bug
2025-08-04 13:31:08 +08:00
berg
1ec300360c system frontend: update version to v1.3.124 (#1672)
* feat: update system frontend to v1.3.124

* feat(dashboard): update hami webui request to user-service

---------

Co-authored-by: qq815776412 <815776412@qq.com>
2025-08-02 00:00:55 +08:00
hysyeah
fc0781580e fix: v2 upgrade and cs chart render (#1671)
fix: v2 upgrade; cs chart render
2025-08-01 20:40:15 +08:00
Calvin W.
88bff41d83 docs: add a note for custom domain hosting (#1669) 2025-08-01 20:29:28 +08:00
dkeven
7d758befde fix(cli): lift the constraint on version level in upgrade (#1666) 2025-08-01 19:48:14 +08:00
eball
a8e074bec1 daemon: fix recreate download-cert job bug (#1668) 2025-08-01 16:05:51 +08:00
Sai
12302696c8 fix: nats message concurrent (#1667)
fix nats message concurrent
2025-08-01 14:33:14 +08:00
eball
3edef07ebe authelia: ignore error when app policies reloading (#1665) 2025-08-01 00:47:14 +08:00
wiy
170492b733 feat(system-frontend): release new version to fix some bugs (#1664) 2025-07-31 23:08:08 +08:00
hysyeah
b5f2d4baa5 fix: use new files api to delete app cache dir (#1659)
* fix: use new files api to delete app cache dir

* fix: user create pending;entrance state update missing
2025-07-31 23:04:31 +08:00
dkeven
358dc9a957 fix(cli): installation on MacOS using minikube (#1661) 2025-07-31 22:37:06 +08:00
dkeven
c6cf22f3a2 fix(ci): correct path to release joincluster script (#1660) 2025-07-31 22:35:17 +08:00
eball
cd6d502f4a cli: add a command of olares-cli to show full system info (#1658)
* feat: add show all info

* fix: add a wsl info

* Update main.go
2025-07-31 22:32:40 +08:00
Calvin W.
0b05f33f52 docs: update Market doc with latest enhancements (#1662) 2025-07-31 22:28:37 +08:00
Calvin W.
995f03ea7b docs: hide sync and cloud storage feature for optimization (#1663) 2025-07-31 22:28:22 +08:00
aby913
c4ed5c6d15 fix(backup): check wise installed (#1656) 2025-07-31 16:50:25 +08:00
hysyeah
992a2bd343 app-service: fix downloading limit;user create failed bug (#1657) 2025-07-31 16:49:52 +08:00
wiy
f8205f0b7a wizard,login: fix compare olares version error (#1655) 2025-07-31 14:13:16 +08:00
Sai
121a8009ea fix: nats upversion to 1.44.0 for market (#1654)
nats upversion to 1.44.0
2025-07-31 13:58:21 +08:00
dkeven
d6dff36e35 feat(upgrade): lift constraint in version.hint (#1653) 2025-07-31 12:40:48 +08:00
berg
8913e10e7b feat(system-frontend): update system-frontend new version (#1652)
* feat(system-frontend): update system-frontend new version

* feat(user-service): add cookie provider

---------

Co-authored-by: qq815776412 <815776412@qq.com>
2025-07-31 00:12:18 +08:00
dkeven
faa655f928 feat(cli): fallback target to current cli version for both release line (#1651) 2025-07-31 00:10:01 +08:00
Sai
df6d9c440d fix: market render chart for multiple admin (#1650)
fix multiple admin
2025-07-31 00:07:44 +08:00
eball
1f2fd0619f ci: bump version to 1.12.1 (#1648) 2025-07-30 21:30:35 +08:00
Calvin W.
9dbb52dedc docs: batch update images and outdated info for Settings (#1649)
* docs: batch update images and outdated info for Settings

* fix links
2025-07-30 21:20:29 +08:00
Calvin W.
a08c8129ab docs: update dashboard doc for 1.12 (#1618)
* docs: update dashboard doc for 1.12

* update latest UI screenshots for dashboards
2025-07-30 21:20:17 +08:00
223 changed files with 3742 additions and 2582 deletions

View File

@@ -59,7 +59,7 @@ jobs:
steps:
- id: generate
run: |
v=1.12.0-$(echo $RANDOM$RANDOM)
v=1.12.1-$(echo $RANDOM$RANDOM)
echo "version=$v" >> "$GITHUB_OUTPUT"
upload-cli:

View File

@@ -10,6 +10,8 @@ on:
type: string
repository:
type: string
release-id:
type: string
workflow_dispatch:
inputs:
version:
@@ -19,6 +21,8 @@ on:
type: string
repository:
type: string
release-id:
type: string
jobs:
goreleaser:
runs-on: ubuntu-22.04
@@ -53,6 +57,7 @@ jobs:
version: v1.18.2
args: release --clean
env:
OLARES_RELEASE_ID: ${{ inputs.release-id }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload to S3
@@ -61,6 +66,6 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
run: |
cd cli/output && for file in *.tar.gz; do
cd cli/output && for file in $(ls *.tar.gz | grep -v no-release-id); do
aws s3 cp "$file" s3://terminus-os-install${{ secrets.REPO_PATH }}${file} --acl=public-read
done

View File

@@ -10,6 +10,8 @@ on:
type: string
repository:
type: string
release-id:
type: string
workflow_dispatch:
inputs:
version:
@@ -19,6 +21,8 @@ on:
type: string
repository:
type: string
release-id:
type: string
jobs:
goreleaser:
@@ -52,6 +56,8 @@ jobs:
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v3.1.0
env:
OLARES_RELEASE_ID: ${{ inputs.release-id }}
with:
distribution: goreleaser
workdir: './daemon'
@@ -64,6 +70,6 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: 'us-east-1'
run: |
cd daemon/output && for file in *.tar.gz; do
cd daemon/output && for file in $(ls *.tar.gz | grep -v no-release-id); do
aws s3 cp "$file" s3://terminus-os-install${{ secrets.REPO_PATH }}${file} --acl=public-read
done

View File

@@ -17,22 +17,36 @@ jobs:
steps:
- id: generate
run: |
v=1.12.0-$(date +"%Y%m%d")
v=1.12.1-$(date +"%Y%m%d")
echo "version=$v" >> "$GITHUB_OUTPUT"
release-id:
runs-on: ubuntu-latest
outputs:
id: ${{ steps.generate.outputs.id }}
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3
- id: generate
run: |
hash=$(git rev-parse --short=7 HEAD)
echo "id=$hash" >> "$GITHUB_OUTPUT"
release-cli:
needs: daily-version
needs: [daily-version, release-id]
uses: ./.github/workflows/release-cli.yaml
secrets: inherit
with:
version: ${{ needs.daily-version.outputs.version }}
release-id: ${{ needs.release-id.outputs.id }}
release-daemon:
needs: daily-version
needs: [daily-version, release-id]
uses: ./.github/workflows/release-daemon.yaml
secrets: inherit
with:
version: ${{ needs.daily-version.outputs.version }}
release-id: ${{ needs.release-id.outputs.id }}
push-images:
runs-on: ubuntu-22.04
@@ -64,7 +78,7 @@ jobs:
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf linux/arm64
push-deps:
needs: [daily-version, release-daemon]
needs: [daily-version, release-id, release-daemon]
runs-on: ubuntu-latest
steps:
@@ -77,12 +91,13 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ needs.daily-version.outputs.version }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
run: |
bash build/deps-manifest.sh && bash build/upload-deps.sh
push-deps-arm64:
needs: [daily-version, release-daemon]
needs: [daily-version, release-id, release-daemon]
runs-on: [self-hosted, linux, ARM64]
steps:
@@ -95,6 +110,7 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ needs.daily-version.outputs.version }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
run: |
export PATH=$PATH:/usr/local/bin:/home/ubuntu/.local/bin
@@ -102,10 +118,8 @@ jobs:
upload-package:
needs: [daily-version, push-images, push-images-arm64, push-deps, push-deps-arm64]
needs: [daily-version, release-id, push-images, push-images-arm64, push-deps, push-deps-arm64]
runs-on: ubuntu-latest
outputs:
md5sum: ${{ steps.upload.outputs.md5sum }}
steps:
- name: 'Checkout source code'
@@ -113,7 +127,7 @@ jobs:
- name: Package installer
run: |
bash build/build.sh ${{ needs.daily-version.outputs.version }}
bash build/build.sh ${{ needs.daily-version.outputs.version }} ${{ needs.release-id.outputs.id }}
- name: Upload to S3
id: upload
@@ -125,27 +139,22 @@ jobs:
md5sum install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz > install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz --acl=public-read && \
echo "md5sum=$(awk '{print $1}' install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt)" >> "$GITHUB_OUTPUT"
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.${{ needs.release-id.outputs.id }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ needs.daily-version.outputs.version }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ needs.daily-version.outputs.version }}.${{ needs.release-id.outputs.id }}.tar.gz --acl=public-read
release:
needs: [daily-version, upload-package, release-cli]
needs: [daily-version, upload-package, release-cli, release-id]
runs-on: ubuntu-latest
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3
- name: Update checksum
uses: eball/write-tag-to-version-file@latest
with:
filename: 'build/base-package/install.sh'
placeholder: '#__MD5SUM__'
tag: ${{ needs.upload-package.outputs.md5sum }}
- name: Package installer
run: |
bash build/build.sh ${{ needs.daily-version.outputs.version }}
bash build/build.sh ${{ needs.daily-version.outputs.version }} ${{ needs.release-id.outputs.id }}
- name: 'Archives'
run: |

View File

@@ -10,18 +10,36 @@ on:
jobs:
release-id:
runs-on: ubuntu-latest
outputs:
id: ${{ steps.generate.outputs.id }}
steps:
- name: 'Checkout source code'
uses: actions/checkout@v3
with:
ref: ${{ github.event.inputs.tags }}
- id: generate
run: |
hash=$(git rev-parse --short=7 HEAD)
echo "id=$hash" >> "$GITHUB_OUTPUT"
release-cli:
needs: [release-id]
uses: ./.github/workflows/release-cli.yaml
secrets: inherit
with:
version: ${{ github.event.inputs.tags }}
release-id: ${{ needs.release-id.outputs.id }}
ref: ${{ github.event.inputs.tags }}
release-daemon:
needs: [release-id]
uses: ./.github/workflows/release-daemon.yaml
secrets: inherit
with:
version: ${{ github.event.inputs.tags }}
release-id: ${{ needs.release-id.outputs.id }}
ref: ${{ github.event.inputs.tags }}
push:
@@ -60,7 +78,7 @@ jobs:
bash build/image-manifest.sh && bash build/upload-images.sh .manifest/images.mf linux/arm64
push-deps:
needs: [release-daemon]
needs: [release-daemon, release-id]
runs-on: ubuntu-latest
steps:
@@ -73,12 +91,13 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ github.event.inputs.tags }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
run: |
bash build/deps-manifest.sh && bash build/upload-deps.sh
push-deps-arm64:
needs: [release-daemon]
needs: [release-daemon, release-id]
runs-on: [self-hosted, linux, ARM64]
steps:
@@ -91,6 +110,7 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_DEFAULT_REGION: "us-east-1"
VERSION: ${{ github.event.inputs.tags }}
RELEASE_ID: ${{ needs.release-id.outputs.id }}
REPO_PATH: '${{ secrets.REPO_PATH }}'
run: |
export PATH=$PATH:/usr/local/bin:/home/ubuntu/.local/bin
@@ -98,7 +118,7 @@ jobs:
upload-package:
needs: [push, push-arm64, push-deps, push-deps-arm64, release-daemon]
needs: [push, push-arm64, push-deps, push-deps-arm64, release-daemon, release-id]
runs-on: ubuntu-latest
steps:
@@ -109,7 +129,7 @@ jobs:
- name: Package installer
run: |
bash build/build.sh ${{ github.event.inputs.tags }}
bash build/build.sh ${{ github.event.inputs.tags }} ${{ needs.release-id.outputs.id }}
- name: Upload to S3
env:
@@ -121,9 +141,12 @@ jobs:
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.tar.gz --acl=public-read
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.md5sum.txt --acl=public-read && \
aws s3 cp install-wizard-v${{ github.event.inputs.tags }}.tar.gz s3://terminus-os-install${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.tar.gz --acl=public-read
release:
runs-on: ubuntu-latest
needs: [upload-package, release-cli]
needs: [upload-package, release-cli, release-id]
steps:
- name: 'Checkout source code'
@@ -139,7 +162,7 @@ jobs:
- name: Get checksum
id: vars
run: |
echo "version_md5sum=$(curl -sSfL https://dc3p1870nn3cj.cloudfront.net${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.md5sum.txt|awk '{print $1}')" >> $GITHUB_OUTPUT
echo "version_md5sum=$(curl -sSfL https://dc3p1870nn3cj.cloudfront.net${{ secrets.REPO_PATH }}install-wizard-v${{ github.event.inputs.tags }}.${{ needs.release-id.outputs.id }}.md5sum.txt|awk '{print $1}')" >> $GITHUB_OUTPUT
- name: Update checksum
uses: eball/write-tag-to-version-file@latest
@@ -150,14 +173,14 @@ jobs:
- name: Package installer
run: |
bash build/build.sh ${{ github.event.inputs.tags }}
bash build/build.sh ${{ github.event.inputs.tags }} ${{ needs.release-id.outputs.id }}
- name: 'Archives'
run: |
cp .dist/install-wizard/install.sh build/base-package
cp build/base-package/install.sh build/base-package/publicInstaller.sh
cp build/base-package/install.sh build/base-package/publicInstaller.latest
cp .dist/install-wizard/install.ps1 build/insbase-packagetaller
cp .dist/install-wizard/install.ps1 build/base-package
cp build/base-package/install.ps1 build/base-package/publicInstaller.latest.ps1
cp .dist/install-wizard/joincluster.sh build/base-package
@@ -174,7 +197,7 @@ jobs:
build/base-package/publicInstaller.latest.ps1
build/base-package/install.ps1
build/base-package/publicAddnode.sh
build/instbase-packagealler/joincluster.sh
build/base-package/joincluster.sh
build/base-package/version.hint
build/base-package/publicRestoreInstaller.sh
prerelease: true

3
.gitignore vendored
View File

@@ -36,4 +36,5 @@ daemon/bin
docs/.vitepress/dist/
docs/.vitepress/cache/
node_modules
.idea/
.idea/
cli/olares-cli*

View File

@@ -78,7 +78,7 @@ metadata:
namespace: {{ .Release.Namespace }}
spec:
selector:
app: system-frontend
app: olares-app
type: ClusterIP
ports:
- protocol: TCP
@@ -93,7 +93,7 @@ metadata:
namespace: {{ .Release.Namespace }}
spec:
selector:
app: system-frontend
app: olares-app
type: ClusterIP
ports:
- protocol: TCP
@@ -110,7 +110,7 @@ metadata:
spec:
type: ClusterIP
selector:
app: system-frontend
app: olares-app
ports:
- name: "profile-editor"
protocol: TCP
@@ -128,7 +128,7 @@ metadata:
namespace: user-space-{{ .Values.bfl.username }}
spec:
selector:
app: system-frontend
app: olares-app
type: ClusterIP
ports:
- protocol: TCP
@@ -143,7 +143,7 @@ metadata:
namespace: {{ .Release.Namespace }}
spec:
selector:
app: system-frontend
app: olares-app
type: ClusterIP
ports:
- protocol: TCP
@@ -171,7 +171,7 @@ metadata:
namespace: user-space-{{ .Values.bfl.username }}
spec:
selector:
app: system-frontend
app: olares-app
type: ClusterIP
ports:
- protocol: TCP
@@ -187,7 +187,7 @@ metadata:
spec:
type: ClusterIP
selector:
app: system-frontend
app: olares-app
ports:
- protocol: TCP
port: 80
@@ -200,7 +200,7 @@ metadata:
namespace: {{ .Release.Namespace }}
spec:
selector:
app: system-frontend
app: olares-app
type: ClusterIP
ports:
- protocol: TCP
@@ -216,7 +216,7 @@ metadata:
spec:
type: ClusterIP
selector:
app: system-frontend
app: olares-app
ports:
- protocol: TCP
port: 80
@@ -225,36 +225,36 @@ spec:
apiVersion: apps/v1
kind: Deployment
metadata:
name: system-frontend-deployment
name: olares-app-deployment
namespace: {{ .Release.Namespace }}
labels:
app: system-frontend
applications.app.bytetrade.io/name: system-frontend
app: olares-app
applications.app.bytetrade.io/name: olares-app
applications.app.bytetrade.io/owner: '{{ .Values.bfl.username }}'
applications.app.bytetrade.io/group: 'true'
applications.app.bytetrade.io/author: bytetrade.io
annotations:
applications.app.bytetrade.io/icon: '{"dashboard":"https://file.bttcdn.com/appstore/dashboard/icon.png","control-hub":"https://file.bttcdn.com/appstore/control-hub/icon.png","profile":"https://file.bttcdn.com/appstore/profile/icon.png","headscale": "https://file.bttcdn.com/appstore/headscale/icon.png","settings": "https://file.bttcdn.com/appstore/settings/icon.png","files":"https://file.bttcdn.com/appstore/files/icon.png","vault":"https://file.bttcdn.com/appstore/vault/icon.png","market":"https://file.bttcdn.com/appstore/appstore/icon.png"}'
applications.app.bytetrade.io/title: '{"dashboard": "Dashboard","control-hub":"Control Hub","profile":"Profile","headscale":"Headscale","settings":"Settings","files":"Files","vault":"Vault","market":"Market"}'
applications.app.bytetrade.io/version: '{"dashboard": "0.0.1","control-hub":"0.0.1","profile":"0.0.1","headscale":"0.0.1","settings":"0.0.1","files":"0.0.1","vault":"0.0.1","market":"0.0.1"}'
applications.app.bytetrade.io/policies: '{"dashboard":{"policies":[{"entranceName":"dashboard","uriRegex":"/js/script.js", "level":"public"},{"entranceName":"dashboard","uriRegex":"/js/api/send", "level":"public"}]}}'
applications.app.bytetrade.io/entrances: '{"dashboard":[{"name":"dashboard","host":"dashboard-service","port":80,"title":"Dashboard","windowPushState":true}],"control-hub":[{"name":"control-hub","host":"control-hub-service","port":80,"title":"Control Hub","windowPushState":true}],"profile":[{"name":"profile", "host":"profile-service", "port":80,"title":"Profile","windowPushState":true}],"headscale":[{"name":"headscale", "host":"headscale-svc", "port":80,"title":"Headscale","invisible": true}],"settings":[{"name":"settings", "host":"settings-service", "port":80,"title":"Settings"}],"files":[{"name":"files", "host":"files-fe-service", "port":80,"title":"Files","windowPushState":true}],"vault":[{"name":"vault", "host":"vault-service", "port":80,"title":"Vault","windowPushState":true}],"market":[{"name":"appstore", "host":"appstore-fe-service", "port":80,"title":"Market","windowPushState":true}]}'
applications.app.bytetrade.io/default-thirdlevel-domains: '[{"appName": "olares-app","entranceName":"dashboard","thirdLevelDomain":"dashboard"},{"appName":"olares-app","entranceName":"control-hub","thirdLevelDomain":"control-hub"},{"appName":"olares-app","entranceName":"files","thirdLevelDomain":"files"},{"appName": "olares-app","entranceName":"vault","thirdLevelDomain":"vault"},{"appName":"olares-app","entranceName":"headscale","thirdLevelDomain":"headscale"},{"appName":"olares-app","entranceName":"settings","thirdLevelDomain":"settings"},{"appName": "olares-app","entranceName":"market","thirdLevelDomain":"market"},{"appName":"olares-app","entranceName":"profile","thirdLevelDomain":"profile"}]'
applications.app.bytetrade.io/icon: https://file.bttcdn.com/appstore/dashboard/icon.png
applications.app.bytetrade.io/title: 'Olares Apps'
applications.app.bytetrade.io/version: '0.0.1'
applications.app.bytetrade.io/policies: '{"policies":[{"entranceName":"dashboard","uriRegex":"/js/script.js", "level":"public"},{"entranceName":"dashboard","uriRegex":"/js/api/send", "level":"public"}]}'
applications.app.bytetrade.io/entrances: '[{"name":"files", "host":"files-fe-service", "port":80,"title":"Files","windowPushState":true,"icon":"https://file.bttcdn.com/appstore/files/icon.png"},{"name":"vault", "host":"vault-service", "port":80,"title":"Vault","windowPushState":true,"icon":"https://file.bttcdn.com/appstore/vault/icon.png"},{"name":"market", "host":"appstore-fe-service", "port":80,"title":"Market","windowPushState":true,"icon":"https://file.bttcdn.com/appstore/appstore/icon.png"},{"name":"settings", "host":"settings-service", "port":80,"title":"Settings","icon":"https://file.bttcdn.com/appstore/settings/icon.png"},{"name":"profile", "host":"profile-service", "port":80,"title":"Profile","windowPushState":true,"icon":"https://file.bttcdn.com/appstore/profile/icon.png"},{"name":"dashboard","host":"dashboard-service","port":80,"title":"Dashboard","windowPushState":true,"icon":"https://file.bttcdn.com/appstore/dashboard/icon.png"},{"name":"control-hub","host":"control-hub-service","port":80,"title":"Control Hub","windowPushState":true,"icon":"https://file.bttcdn.com/appstore/control-hub/icon.png"},{"name":"headscale", "host":"headscale-svc", "port":80,"title":"Headscale","invisible": true,"icon":"https://file.bttcdn.com/appstore/headscale/icon.png"}]'
spec:
replicas: 1
selector:
matchLabels:
app: system-frontend
app: olares-app
template:
metadata:
labels:
app: system-frontend
app: olares-app
io.bytetrade.app: "true"
annotations:
{{ if .Values.telemetry }}
instrumentation.opentelemetry.io/inject-nodejs: "olares-instrumentation"
instrumentation.opentelemetry.io/nodejs-container-names: "user-service"
instrumentation.opentelemetry.io/inject-nginx: "olares-instrumentation"
instrumentation.opentelemetry.io/inject-nginx-container-names: "system-frontend"
instrumentation.opentelemetry.io/inject-nginx-container-names: "olares-app"
{{ end }}
spec:
priorityClassName: "system-cluster-critical"
@@ -332,8 +332,8 @@ spec:
value: "{{ $pg_password | b64dec }}"
- name: PGDB
value: user_space_{{ .Values.bfl.username }}_cloud_drive_integration
- name: system-frontend-init
image: beclab/system-frontend:v1.3.116
- name: olares-app-init
image: beclab/system-frontend:v1.4.13
imagePullPolicy: IfNotPresent
command:
- /bin/sh
@@ -369,7 +369,7 @@ spec:
- debug
- -c
- /etc/envoy/envoy.yaml
- name: system-frontend
- name: olares-app
image: beclab/docker-nginx-headers-more:ubuntu-v0.1.0
imagePullPolicy: IfNotPresent
ports:
@@ -400,10 +400,10 @@ spec:
mountPath: /www
- name: wise-download-dir
mountPath: /data/Home
- name: system-frontend-nginx-config
- name: olares-app-nginx-config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
- name: system-frontend-nginx-config
- name: olares-app-nginx-config
mountPath: /etc/nginx/conf.d/headscale.conf
subPath: headscale.conf
env:
@@ -455,7 +455,7 @@ spec:
- name: NATS_SUBJECT_VAULT
value: os.vault.{{ .Values.bfl.username}}
- name: user-service
image: beclab/user-service:v0.0.41
image: beclab/user-service:v0.0.45
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3000
@@ -624,9 +624,9 @@ spec:
hostPath:
type: Directory
path: '{{ .Values.userspace.appCache}}'
- name: system-frontend-nginx-config
- name: olares-app-nginx-config
configMap:
name: system-frontend-nginx-config
name: olares-app-nginx-config
items:
- key: nginx.conf
path: nginx.conf
@@ -1211,6 +1211,8 @@ spec:
uri: /api/account/all
- name: POST
uri: /api/cookie/retrieve
- name: POST
uri: /api/cookie
status:
state: active
---
@@ -1996,7 +1998,7 @@ metadata:
kind: ConfigMap
apiVersion: v1
metadata:
name: system-frontend-nginx-config
name: olares-app-nginx-config
namespace: {{ .Release.Namespace }}
annotations:
kubesphere.io/creator: bytetrade.io
@@ -2110,43 +2112,43 @@ spec:
key: nats_password
name: user-service-nats-secret
subjects:
- name: "files.*"
- name: files.{{ .Values.bfl.username }}
permission:
pub: allow
sub: allow
- name: "notification.*"
- name: notification.{{ .Values.bfl.username }}
permission:
pub: allow
sub: allow
- name: "search.*"
- name: search.{{ .Values.bfl.username }}
permission:
pub: allow
sub: allow
- name: "seahub.*"
- name: seahub.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow
- name: "vault.*"
- name: vault.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow
- name: "application.*"
- name: application.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow
- name: "knowledge.*"
- name: knowledge.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow
- name: "market.*"
- name: market.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow
- name: "backup.*"
- name: backup.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow
- name: "intent.*"
- name: intent.{{ .Values.bfl.username }}
permission:
sub: allow
pub: allow

View File

@@ -44,5 +44,3 @@ os:
dashboard:
appKey: '${ks[0]}'
appSecret: test
kubesphere:
redis_password: ""

View File

@@ -29,7 +29,7 @@ spec:
containers:
- name: wizard
image: beclab/wizard:v1.3.111
image: beclab/wizard:v1.4.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80

View File

@@ -34,5 +34,3 @@ os:
appstore:
appKey: '${ks[0]}'
appSecret: test
kubesphere:
redis_password: ""

View File

@@ -2,6 +2,7 @@ $currentPath = Get-Location
$architecture = $env:PROCESSOR_ARCHITECTURE
$downloadCdnUrlFromEnv = $env:DOWNLOAD_CDN_URL
$version = "#__VERSION__"
$releaseID = "#__RELEASE_ID__"
$downloadUrl = "https://dc3p1870nn3cj.cloudfront.net"
function Test-Wait {
@@ -49,7 +50,11 @@ if (-Not (Test-Path $CLI_PROGRAM_PATH)) {
}
$CLI_VERSION = "$version"
$CLI_FILE = "olares-cli-v{0}_windows_{1}.tar.gz" -f $CLI_VERSION, $arch
if (-not [string]::IsNullOrEmpty($releaseID) -and $releaseID.Substring(0,3) -ne "#__") {
$CLI_FILE = "olares-cli-v{0}_windows_{1}.{2}.tar.gz" -f $CLI_VERSION, $arch, $releaseID
} else {
$CLI_FILE = "olares-cli-v{0}_windows_{1}.tar.gz" -f $CLI_VERSION, $arch
}
$CLI_URL = "{0}/{1}" -f $downloadUrl, $CLI_FILE
$CLI_PATH = "{0}{1}" -f $CLI_PROGRAM_PATH, $CLI_FILE

View File

@@ -10,7 +10,7 @@ function command_exists() {
if [[ x"$VERSION" == x"" ]]; then
if [[ "$LOCAL_RELEASE" == "1" ]]; then
ts=$(date +%Y%m%d%H%M%S)
export VERSION="1.12.0-$ts"
export VERSION="1.12.1-$ts"
echo "will build and use a local release of Olares with version: $VERSION"
echo ""
else
@@ -20,7 +20,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.0-20241124 bash $0"
echo "for example: VERSION=1.12.1-20241124 bash $0"
exit 1
fi
@@ -74,9 +74,15 @@ if [ -z ${cdn_url} ]; then
cdn_url="https://dc3p1870nn3cj.cloudfront.net"
fi
CLI_FILE="olares-cli-v${VERSION}_linux_${ARCH}.tar.gz"
RELEASE_ID="#__RELEASE_ID__"
if [[ $RELEASE_ID == "" || "${RELEASE_ID:3}" == "RELEASE_ID__" ]]; then
RELEASE_ID_SUFFIX=""
else
RELEASE_ID_SUFFIX=".$RELEASE_ID"
fi
CLI_FILE="olares-cli-v${VERSION}_linux_${ARCH}${RELEASE_ID_SUFFIX}.tar.gz"
if [[ x"$os_type" == x"Darwin" ]]; then
CLI_FILE="olares-cli-v${VERSION}_darwin_${ARCH}.tar.gz"
CLI_FILE="olares-cli-v${VERSION}_darwin_${ARCH}${RELEASE_ID_SUFFIX}.tar.gz"
fi
if [[ "$LOCAL_RELEASE" == "1" ]]; then
@@ -159,7 +165,10 @@ else
fi
echo "downloading installation wizard..."
echo ""
$sh_c "$INSTALL_OLARES_CLI download wizard $PARAMS $KUBE_PARAM $CDN"
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"
if [[ $? -ne 0 ]]; then
echo "error: failed to download installation wizard"
exit 1

View File

@@ -149,7 +149,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.0-20241124 bash $0"
echo "for example: VERSION=1.12.1-20241124 bash $0"
exit 1
fi
@@ -165,7 +165,13 @@ fi
set_master_host_ssh_options
CLI_FILE="olares-cli-v${VERSION}_linux_${ARCH}.tar.gz"
RELEASE_ID="#__RELEASE_ID__"
if [[ $RELEASE_ID == "" || "${RELEASE_ID:3}" == "RELEASE_ID__" ]]; then
RELEASE_ID_SUFFIX=""
else
RELEASE_ID_SUFFIX=".$RELEASE_ID"
fi
CLI_FILE="olares-cli-v${VERSION}_linux_${ARCH}${RELEASE_ID_SUFFIX}.tar.gz"
if command_exists olares-cli && [[ "$(olares-cli -v | awk '{print $3}')" == "$VERSION" ]]; then
INSTALL_OLARES_CLI=$(which olares-cli)
@@ -225,7 +231,10 @@ else
echo "downloading installation wizard..."
echo ""
$sh_c "$INSTALL_OLARES_CLI download wizard $PARAMS $CDN"
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"
if [[ $? -ne 0 ]]; then
echo "error: failed to download installation wizard"
exit 1

View File

@@ -1,2 +1,2 @@
upgrade:
minVersion: 1.12.0-1
minVersion: 1.12.0-0

View File

@@ -1,5 +1,3 @@
kubesphere:
redis_password: ""
backup:
bucket: "${BACKUP_CLUSTER_BUCKET}"
key_prefix: "${BACKUP_KEY_PREFIX}"

View File

@@ -54,6 +54,7 @@ def main():
manifest_file = args.manifest_file
version = os.environ.get("VERSION", "")
release_id = os.environ.get("RELEASE_ID", "")
repo_path = os.environ.get("REPO_PATH", "/")
manifest_amd64_data = {}
manifest_arm64_data = {}
@@ -70,6 +71,9 @@ def main():
if version:
line = line.replace("#__VERSION__", version)
if release_id:
line = line.replace("#__RELEASE_ID_SUFFIX__", "."+release_id)
# Replace repo path
if repo_path:
line = line.replace("#__REPO_PATH__", repo_path)

View File

@@ -46,6 +46,13 @@ while read line; do
done < components
sed -i "s/#__VERSION__/${VERSION}/g" $manifest_file
if [[ ! -z "$RELEASE_ID" ]]; then
RELEASE_ID_SUFFIX=".$RELEASE_ID"
else
RELEASE_ID_SUFFIX=""
fi
sed -i "s/#__RELEASE_ID_SUFFIX__/${RELEASE_ID_SUFFIX}/g" $manifest_file
path="${REPO_PATH:-/}"
sed -i "s|#__REPO_PATH__|${path}|g" $manifest_file

View File

@@ -4,6 +4,7 @@ BASE_DIR=$(dirname $(realpath -s $0))
rm -rf ${BASE_DIR}/../.dist
DIST_PATH="${BASE_DIR}/../.dist/install-wizard"
export VERSION=$1
export RELEASE_ID=$2
# vendor replace
@@ -59,6 +60,12 @@ else
VERSION="debug"
fi
if [ ! -z $RELEASE_ID ]; then
sh -c "$SED 's/#__RELEASE_ID__/${RELEASE_ID}/' install.sh"
sh -c "$SED 's/#__RELEASE_ID__/${RELEASE_ID}/' install.ps1"
sh -c "$SED 's/#__RELEASE_ID__/${RELEASE_ID}/' joincluster.sh"
fi
$TAR --exclude=wizard/tools --exclude=.git -zcvf ${BASE_DIR}/../install-wizard-${VERSION}.tar.gz .
popd

View File

@@ -92,5 +92,13 @@ find $BASE_DIR/../ -type f -name Olares.yaml | while read f; do
done
sed -i "s/#__VERSION__/${VERSION}/g" ${manifest}
if [[ ! -z "$RELEASE_ID" ]]; then
RELEASE_ID_SUFFIX=".$RELEASE_ID"
else
RELEASE_ID_SUFFIX=""
fi
sed -i "s/#__RELEASE_ID_SUFFIX__/${RELEASE_ID_SUFFIX}/g" ${manifest}
path="${REPO_PATH:-/}"
sed -i "s|#__REPO_PATH__|${path}|g" ${manifest}

View File

@@ -37,8 +37,15 @@ builds:
{{- end }}
dist: ./output
archives:
- id: olares-cli
- id: without-release-id
name_template: "{{ .ProjectName }}-v{{ .Version }}_{{ .Os }}_{{ .Arch }}"
- id: with-release-id
name_template: >-
{{- if index .Env "OLARES_RELEASE_ID" }}
{{- .ProjectName }}-v{{ .Version }}_{{ .Os }}_{{ .Arch }}.{{ .Env.OLARES_RELEASE_ID }}
{{- else }}
{{- .ProjectName }}-v{{ .Version }}_{{ .Os }}_{{ .Arch }}.no-release-id
{{- end }}
checksum:
name_template: "checksums.txt"
release:

View File

@@ -10,6 +10,7 @@ type CliDownloadWizardOptions struct {
KubeType string
BaseDir string
DownloadCdnUrl string
ReleaseID string
UrlOverride string
}
@@ -23,6 +24,7 @@ func (o *CliDownloadWizardOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.KubeType, "kube", "k3s", "Set kube type, e.g., k3s or k8s")
cmd.Flags().StringVar(&o.DownloadCdnUrl, "download-cdn-url", "", "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 {

View File

@@ -5,16 +5,19 @@ import (
"compress/gzip"
"fmt"
"io"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"log"
"net"
"os"
"os/exec"
"path/filepath"
ctrl "sigs.k8s.io/controller-runtime"
"strings"
"time"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/util"
"github.com/spf13/cobra"
)
@@ -30,14 +33,57 @@ type LogCollectOptions struct {
Components []string
// Whether to ignore errors from kubectl commands
IgnoreKubeErrors bool
// Skip retrieving logs from kube-apiserver
SkipKubeAPISserver bool
}
var servicesToCollectLogs = []string{"k3s", "containerd", "olaresd", "kubelet", "juicefs", "redis", "minio", "etcd", "NetworkManager"}
// setSkipIfK8sNotReachable checks if the Kubernetes API server port is reachable
// and automatically sets skip-kube-apiserver to true if not reachable
func setSkipIfK8sNotReachable(options *LogCollectOptions) {
// if the env is not set explicitly by user
// fallback to k3s config path as it's a non-standard path
if os.Getenv(clientcmd.RecommendedConfigPathEnvVar) == "" {
os.Setenv(clientcmd.RecommendedConfigPathEnvVar, "/etc/rancher/k3s/k3s.yaml")
}
config, err := ctrl.GetConfig()
if err != nil {
fmt.Printf("Warning: failed to get kubeconfig: %v\n", err)
fmt.Println("Automatically setting skip-kube-apiserver option")
options.SkipKubeAPISserver = true
return
}
url, _, err := rest.DefaultServerUrlFor(config)
if err != nil {
fmt.Printf("Warning: failed to parse server url in kubeconfig: %v\n", err)
fmt.Println("Automatically setting skip-kube-apiserver option")
options.SkipKubeAPISserver = true
return
}
timeout := config.Timeout
if timeout == 0 {
timeout = 5 * time.Second
}
conn, err := net.DialTimeout("tcp", url.Host, timeout)
if err != nil {
fmt.Printf("Warning: Kubernetes API server at %s is not reachable: %v\n", config.Host, err)
fmt.Println("Automatically setting skip-kube-apiserver option")
options.SkipKubeAPISserver = true
return
}
conn.Close()
}
func collectLogs(options *LogCollectOptions) error {
if os.Getuid() != 0 {
return fmt.Errorf("os: please run as root")
}
if !options.SkipKubeAPISserver {
setSkipIfK8sNotReachable(options)
}
if err := os.MkdirAll(options.OutputDir, 0755); err != nil {
return fmt.Errorf("failed to create output directory: %v", err)
}
@@ -296,13 +342,21 @@ func collectKubernetesLogs(tw *tar.Writer, options *LogCollectOptions) error {
}
}
if options.SkipKubeAPISserver {
return nil
}
if _, err := util.GetCommand("kubectl"); err != nil {
fmt.Printf("warning: kubectl not found, skipping collecting cluster info from kube-apiserver\n")
return nil
}
cmd := exec.Command("kubectl", "get", "pods", "--all-namespaces", "-o", "wide")
output, err := tryKubectlCommand(cmd, "get pods", options)
var cmd *exec.Cmd
var output []byte
var err error
cmd = exec.Command("kubectl", "get", "pods", "--all-namespaces", "-o", "wide")
output, err = tryKubectlCommand(cmd, "get pods", options)
if err != nil && !options.IgnoreKubeErrors {
return err
}
@@ -517,7 +571,8 @@ func NewCmdLogs() *cobra.Command {
cmd.Flags().IntVar(&options.MaxLines, "max-lines", options.MaxLines, "Maximum number of lines to collect per log source, to limit the log file size")
cmd.Flags().StringVar(&options.OutputDir, "output-dir", options.OutputDir, "Directory to store collected logs, will be created if not existing")
cmd.Flags().StringSliceVar(&options.Components, "components", nil, "Specific components (systemd service) to collect logs from (comma-separated). If empty, collects from all Olares-related components that can be found")
cmd.Flags().BoolVar(&options.IgnoreKubeErrors, "ignore-kube-errors", options.IgnoreKubeErrors, "Continue collecting logs even if kubectl commands fail, e.g., when kube-apiserver is not reachable")
cmd.Flags().BoolVar(&options.IgnoreKubeErrors, "ignore-kube-errors", options.IgnoreKubeErrors, "Continue collecting logs even if kubectl commands fail")
cmd.Flags().BoolVar(&options.SkipKubeAPISserver, "skip-kube-apiserver", options.SkipKubeAPISserver, "Skip retrieving logs from kube-apiserver, it's automatically set if apiserver is not reachable. To tolerate other cases, set the ignore-kube-errors")
return cmd
}

View File

@@ -49,7 +49,7 @@ func NewCmdRelease() *cobra.Command {
}
if version == "" {
version = fmt.Sprintf("1.12.0-%s", time.Now().Format("20060102150405"))
version = fmt.Sprintf("1.12.1-%s", time.Now().Format("20060102150405"))
fmt.Printf("--version unspecified, using: %s\n", version)
time.Sleep(1 * time.Second)
}

View File

@@ -1,15 +1,10 @@
package os
import (
"os/exec"
"github.com/spf13/cobra"
)
func NewOSCommands() []*cobra.Command {
_ = exec.Command("/bin/bash", "-c", "ulimit -u 65535").Run()
_ = exec.Command("/bin/bash", "-c", "ulimit -n 65535").Run()
return []*cobra.Command{
NewCmdPrecheck(),
NewCmdRootDownload(),

View File

@@ -8,11 +8,10 @@ import (
"github.com/beclab/Olares/cli/pkg/phase"
"github.com/beclab/Olares/cli/pkg/pipelines"
"github.com/beclab/Olares/cli/pkg/upgrade"
"github.com/pkg/errors"
"github.com/beclab/Olares/cli/version"
"github.com/spf13/cobra"
"log"
"os"
"slices"
)
type UpgradeOsOptions struct {
@@ -37,50 +36,61 @@ func NewCmdUpgradeOs() *cobra.Command {
},
}
o.UpgradeOptions.AddFlags(cmd)
cmd.AddCommand(NewCmdCurrentVersionUpgradeSpec())
cmd.AddCommand(NewCmdUpgradeViable())
cmd.AddCommand(NewCmdUpgradePrecheck())
cmd.AddCommand(NewCmdGetUpgradePath())
return cmd
}
func NewCmdGetUpgradePath() *cobra.Command {
var baseVersionStr string
var latestFirst bool
func NewCmdCurrentVersionUpgradeSpec() *cobra.Command {
cmd := &cobra.Command{
Use: "path",
Short: "Get the upgrade path (required intermediate versions) from base version to the latest upgradable version (as known to this release of olares-cli)",
Use: "spec",
Aliases: []string{"current-spec"},
Short: fmt.Sprintf("Get the upgrade spec of the current olares-cli version (%s)", version.VERSION),
RunE: func(cmd *cobra.Command, args []string) error {
spec, err := upgrade.CurrentVersionSpec()
if err != nil {
return err
}
jsonOutput, _ := json.MarshalIndent(spec, "", " ")
fmt.Println(string(jsonOutput))
return nil
},
}
return cmd
}
func NewCmdUpgradeViable() *cobra.Command {
var baseVersionStr string
cmd := &cobra.Command{
Use: "viable",
Short: fmt.Sprintf("Determine whether upgrade can be directly performed upon the base version (to %s)", version.VERSION),
RunE: func(cmd *cobra.Command, args []string) error {
var baseVersion *semver.Version
var err error
if baseVersionStr == "" {
var err error
baseVersionStr, err = phase.GetOlaresVersion()
if err != nil {
return errors.New("failed to get current Olares version, please specify the base version explicitly")
return err
}
}
baseVersion, err = semver.NewVersion(baseVersionStr)
baseVersion, err := semver.NewVersion(baseVersionStr)
if err != nil {
return fmt.Errorf("invalid base version: %v", err)
return fmt.Errorf("invalid base version '%s': %v", baseVersionStr, err)
}
path, err := upgrade.GetUpgradePathFor(baseVersion, nil)
cliVersion, err := semver.NewVersion(version.VERSION)
if err != nil {
return fmt.Errorf("invalid cli version '%s': %v", version.VERSION, err)
}
err = upgrade.Check(baseVersion, cliVersion)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
if latestFirst {
slices.Reverse(path)
}
encoder := json.NewEncoder(cmd.OutOrStdout())
encoder.SetIndent("", " ")
return encoder.Encode(path)
fmt.Printf("upgrade from %s to %s is viable\n", baseVersion, cliVersion)
return nil
},
}
cmd.Flags().StringVarP(&baseVersionStr, "base-version", "b", baseVersionStr, "base version to be upgraded, defaults to the current Olares version if inside Olares cluster")
cmd.Flags().BoolVar(&latestFirst, "latest-first", true, "sort versions to put recent ones in the front")
cmd.Flags().StringVarP(&baseVersionStr, "base", "b", "", "base version, defaults to the current Olares system's version")
return cmd
}

View File

@@ -3,6 +3,7 @@ package osinfo
import (
"fmt"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/spf13/cobra"
)
@@ -14,6 +15,7 @@ func NewCmdInfo() *cobra.Command {
Long: "help for printing info",
}
infoCmd.AddCommand(showInfoCommand())
infoCmd.AddCommand(showAllCommand())
return infoCmd
}
@@ -37,3 +39,17 @@ OS_INFO=%s
}
return cmd
}
func showAllCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "showall",
Short: "Print full os information",
Long: "help for printing os info",
Run: func(cmd *cobra.Command, args []string) {
arg := common.NewArgument()
arg.SystemInfo.Print()
},
}
return cmd
}

View File

@@ -5,6 +5,7 @@ import (
"github.com/beclab/Olares/cli/cmd/ctl/node"
"github.com/beclab/Olares/cli/cmd/ctl/os"
"github.com/beclab/Olares/cli/cmd/ctl/osinfo"
"github.com/beclab/Olares/cli/cmd/ctl/user"
"github.com/beclab/Olares/cli/version"
"github.com/spf13/cobra"
)
@@ -31,6 +32,7 @@ func NewDefaultCommand() *cobra.Command {
cmds.AddCommand(os.NewOSCommands()...)
cmds.AddCommand(node.NewNodeCommand())
cmds.AddCommand(gpu.NewCmdGpu())
cmds.AddCommand(user.NewUserCommand())
return cmds
}

192
cli/cmd/ctl/user/create.go Normal file
View File

@@ -0,0 +1,192 @@
package user
import (
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
"context"
"fmt"
"github.com/beclab/Olares/cli/pkg/utils"
"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"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type createUserOptions struct {
name string
displayName string
domain string
role string
resourceLimit
password string
description string
kubeConfig string
}
func NewCmdCreateUser() *cobra.Command {
o := &createUserOptions{}
cmd := &cobra.Command{
Use: "create {name}",
Aliases: []string{"add", "new"},
Short: "create a new user",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
o.name = args[0]
if err := o.Validate(); err != nil {
log.Fatal(err)
}
if err := o.Run(); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func (o *createUserOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.displayName, "display-name", "", "display name (optional)")
cmd.Flags().StringVar(&o.domain, "domain", "", "domain (optional, defaults to the Olares system's domain)")
cmd.Flags().StringVarP(&o.role, "role", "r", "normal", "owner role (optional, one of owner, admin, normal)")
cmd.Flags().StringVarP(&o.memoryLimit, "memory-limit", "m", defaultMemoryLimit, "memory limit (optional)")
cmd.Flags().StringVarP(&o.cpuLimit, "cpu-limit", "c", defaultCPULimit, "cpu limit (optional)")
cmd.Flags().StringVarP(&o.password, "password", "p", "", "initial password (optional)")
cmd.Flags().StringVar(&o.description, "description", "", "user description (optional)")
cmd.Flags().StringVar(&o.kubeConfig, "kubeconfig", "", "path to kubeconfig file (optional)")
}
func (o *createUserOptions) Validate() error {
if o.name == "" {
return fmt.Errorf("name is required")
}
if errs := validation.IsDNS1123Subdomain(o.name); len(errs) > 0 {
return fmt.Errorf("invalid name: %s", strings.Join(errs, ","))
}
if o.domain != "" {
if errs := validation.IsDNS1123Subdomain(o.domain); len(errs) > 0 {
return fmt.Errorf("invalid domain: %s", strings.Join(errs, ","))
}
if len(strings.Split(o.domain, ".")) < 2 {
return errors.New("invalid domain: should be a domain with at least two segments separated by dots")
}
for _, label := range strings.Split(o.domain, ".") {
if errs := validation.IsDNS1123Label(label); len(errs) > 0 {
return fmt.Errorf("invalid domain: %s", strings.Join(errs, ","))
}
}
}
if o.role != "" {
if o.role != roleOwner && o.role != roleAdmin && o.role != roleNormal {
return fmt.Errorf("invalid role: should be one of owner, admin, or normal")
}
}
if err := validateResourceLimit(o.resourceLimit); err != nil {
return err
}
return nil
}
func (o *createUserOptions) Run() error {
ctx := context.Background()
userClient, err := newUserClientFromKubeConfig(o.kubeConfig)
if err != nil {
return err
}
if o.memoryLimit == "" {
o.memoryLimit = defaultMemoryLimit
}
if o.cpuLimit == "" {
o.cpuLimit = defaultCPULimit
}
if o.domain == "" {
var system v1alpha1.Terminus
err := userClient.Get(ctx, types.NamespacedName{Name: systemObjectName}, &system)
if err != nil {
return fmt.Errorf("failed to get system info: %v", err)
}
o.domain = system.Spec.Settings[systemObjectDomainKey]
}
var userList iamv1alpha2.UserList
err = userClient.List(ctx, &userList)
if err != nil {
return fmt.Errorf("failed to list users to set creator: %w", err)
}
var owners []iamv1alpha2.User
for _, user := range userList.Items {
if role, ok := user.Annotations[annotationKeyRole]; ok && role == roleOwner {
owners = append(owners, user)
}
}
if len(owners) > 1 {
fmt.Printf("Warning: multiple owners found\n")
}
if o.role == roleOwner && len(owners) > 0 {
return fmt.Errorf("an owner '%s' already exists", owners[0].Name)
}
if o.password == "" {
password, passwordEncrypted, err := utils.GenerateEncryptedPassword(8)
if err != nil {
return fmt.Errorf("error generating password: %v", err)
}
log.Println("generated initial password:", password)
o.password = passwordEncrypted
} else {
o.password = utils.MD5(o.password + "@Olares2025")
}
olaresName := fmt.Sprintf("%s@%s", o.name, o.domain)
user := &iamv1alpha2.User{
TypeMeta: metav1.TypeMeta{
APIVersion: iamv1alpha2.SchemeGroupVersion.String(),
Kind: iamv1alpha2.ResourceKindUser,
},
ObjectMeta: metav1.ObjectMeta{
Name: o.name,
Annotations: map[string]string{
"bytetrade.io/creator": creatorCLI,
annotationKeyRole: o.role,
"bytetrade.io/is-ephemeral": "true",
"bytetrade.io/terminus-name": olaresName,
"bytetrade.io/launcher-auth-policy": "two_factor",
"bytetrade.io/launcher-access-level": "1",
annotationKeyMemoryLimit: o.memoryLimit,
annotationKeyCPULimit: o.cpuLimit,
"iam.kubesphere.io/sync-to-lldap": "true",
"iam.kubesphere.io/synced-to-lldap": "false",
},
},
Spec: iamv1alpha2.UserSpec{
DisplayName: o.displayName,
Email: olaresName,
InitialPassword: o.password,
Description: o.description,
},
}
if o.role == roleOwner || o.role == roleAdmin {
user.Spec.Groups = append(user.Spec.Groups, lldapGroupAdmin)
}
err = userClient.Create(ctx, user)
if err != nil {
return fmt.Errorf("failed to create user: %w", err)
}
fmt.Printf("User '%s' created successfully\n", o.name)
return nil
}

View File

@@ -0,0 +1,81 @@
package user
import (
"context"
"fmt"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"log"
)
type deleteUserOptions struct {
name string
kubeConfig string
}
func NewCmdDeleteUser() *cobra.Command {
o := &deleteUserOptions{}
cmd := &cobra.Command{
Use: "delete {name}",
Short: "delete an existing user",
Aliases: []string{"d", "del", "rm", "remove"},
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
o.name = args[0]
if err := o.Validate(); err != nil {
log.Fatal(err)
}
if err := o.Run(); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func (o *deleteUserOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.kubeConfig, "kubeconfig", "", "path to kubeconfig file")
}
func (o *deleteUserOptions) Validate() error {
if o.name == "" {
return fmt.Errorf("name is required")
}
return nil
}
func (o *deleteUserOptions) Run() error {
ctx := context.Background()
userClient, err := newUserClientFromKubeConfig(o.kubeConfig)
if err != nil {
return err
}
var user iamv1alpha2.User
err = userClient.Get(ctx, types.NamespacedName{Name: o.name}, &user)
if err != nil {
if errors.IsNotFound(err) {
return fmt.Errorf("user '%s' not found", o.name)
}
return fmt.Errorf("failed to get user: %w", err)
}
if user.Status.State == "Creating" {
return fmt.Errorf("user '%s' is under creation", o.name)
}
if role, ok := user.Annotations[annotationKeyRole]; ok && role == roleOwner {
return fmt.Errorf("cannot delete user '%s' with role '%s' ", o.name, role)
}
err = userClient.Delete(ctx, &user)
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("failed to delete user: %w", err)
}
fmt.Printf("User '%s' deleted successfully\n", o.name)
return nil
}

84
cli/cmd/ctl/user/get.go Normal file
View File

@@ -0,0 +1,84 @@
package user
import (
"context"
"encoding/json"
"fmt"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"log"
)
type getUserOptions struct {
name string
kubeConfig string
output string
noHeaders bool
}
func NewCmdGetUser() *cobra.Command {
o := &getUserOptions{}
cmd := &cobra.Command{
Use: "get {name}",
Short: "get user details",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
o.name = args[0]
if err := o.Validate(); err != nil {
log.Fatal(err)
}
if err := o.Run(); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func (o *getUserOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.kubeConfig, "kubeconfig", "", "path to kubeconfig file")
cmd.Flags().StringVarP(&o.output, "output", "o", "table", "output format (table, json)")
cmd.Flags().BoolVar(&o.noHeaders, "no-headers", false, "disable headers")
}
func (o *getUserOptions) Validate() error {
if o.name == "" {
return fmt.Errorf("name is required")
}
return nil
}
func (o *getUserOptions) Run() error {
ctx := context.Background()
userClient, err := newUserClientFromKubeConfig(o.kubeConfig)
if err != nil {
return err
}
var user iamv1alpha2.User
err = userClient.Get(ctx, types.NamespacedName{Name: o.name}, &user)
if err != nil {
if errors.IsNotFound(err) {
return fmt.Errorf("user '%s' not found", o.name)
}
return fmt.Errorf("failed to get user: %w", err)
}
info := convertUserObjectToUserInfo(user)
if o.output == "json" {
jsonOutput, _ := json.MarshalIndent(info, "", " ")
fmt.Println(string(jsonOutput))
} else {
if !o.noHeaders {
printUserTableHeaders()
}
printUserTableRow(info)
}
return nil
}

182
cli/cmd/ctl/user/list.go Normal file
View File

@@ -0,0 +1,182 @@
package user
import (
"context"
"encoding/json"
"fmt"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/util/sets"
"log"
"slices"
"sort"
"strings"
)
var sortFuncs = map[string]func(users []iamv1alpha2.User, i, j int) bool{
"name": func(users []iamv1alpha2.User, i, j int) bool {
return strings.Compare(users[i].Name, users[j].Name) == -1
},
"role": func(users []iamv1alpha2.User, i, j int) bool {
return strings.Compare(users[i].Annotations[annotationKeyRole], users[j].Annotations[annotationKeyRole]) == -1
},
"create-time": func(users []iamv1alpha2.User, i, j int) bool {
return users[i].CreationTimestamp.Before(&users[j].CreationTimestamp)
},
"memory": func(users []iamv1alpha2.User, i, j int) bool {
iMemoryStr, ok := users[i].Annotations[annotationKeyMemoryLimit]
if !ok || iMemoryStr == "" {
return false
}
jMemoryStr, ok := users[j].Annotations[annotationKeyMemoryLimit]
if !ok || jMemoryStr == "" {
return true
}
iMemory, err := resource.ParseQuantity(iMemoryStr)
if err != nil {
fmt.Printf("Warning: invalid memory limit '%s' is set on user '%s'\n", iMemoryStr, users[i].Name)
return false
}
jMemory, err := resource.ParseQuantity(jMemoryStr)
if err != nil {
fmt.Printf("Warning: invalid memory limit '%s' is set on user '%s'\n", jMemoryStr, users[j].Name)
return true
}
return iMemory.Cmp(jMemory) == -1
},
"cpu": func(users []iamv1alpha2.User, i, j int) bool {
iCPUStr, ok := users[i].Annotations[annotationKeyCPULimit]
if !ok || iCPUStr == "" {
return false
}
jCPUStr, ok := users[j].Annotations[annotationKeyCPULimit]
if !ok || jCPUStr == "" {
return true
}
iCPU, err := resource.ParseQuantity(iCPUStr)
if err != nil {
fmt.Printf("Warning: invalid cpu limit '%s' is set on user '%s'", iCPUStr, users[i].Name)
return false
}
jCPU, err := resource.ParseQuantity(jCPUStr)
if err != nil {
fmt.Printf("Warning: invalid cpu limit '%s' is set on user '%s'", jCPUStr, users[j].Name)
return true
}
return iCPU.Cmp(jCPU) == -1
},
}
var sortAliases = map[string]sets.Set[string]{
"name": sets.New[string]("n", "N", "Name"),
"role": sets.New[string]("r", "R", "Role"),
"create-time": sets.New[string]("creation", "created", "created-at", "createdat", "createtime"),
"cpu": sets.New[string]("c", "C", "CPU"),
"memory": sets.New[string]("m", "M", "Memory"),
}
func getSortFunc(sortBy string) func(users []iamv1alpha2.User, i, j int) bool {
if f, ok := sortFuncs[sortBy]; ok {
return f
}
for origin, sortAlias := range sortAliases {
if sortAlias.Has(sortBy) {
return sortFuncs[origin]
}
}
return nil
}
type listUsersOptions struct {
kubeConfig string
output string
noHeaders bool
sortBys []string
reverse bool
}
func NewCmdListUsers() *cobra.Command {
o := &listUsersOptions{}
cmd := &cobra.Command{
Use: "list",
Aliases: []string{"ls", "l"},
Short: "list all users",
Run: func(cmd *cobra.Command, args []string) {
if err := o.Validate(); err != nil {
log.Fatal(err)
}
if err := o.Run(); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func (o *listUsersOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(&o.kubeConfig, "kubeconfig", "", "path to kubeconfig file")
cmd.Flags().StringVarP(&o.output, "output", "o", "table", "output format (table, json)")
cmd.Flags().BoolVar(&o.noHeaders, "no-headers", false, "disable headers")
cmd.Flags().StringSliceVar(&o.sortBys, "sort", []string{}, "sort output order by (name, role, create-time, memory, cpu)")
cmd.Flags().BoolVarP(&o.reverse, "reverse", "r", false, "reverse order")
}
func (o *listUsersOptions) Validate() error {
for _, sortBy := range o.sortBys {
f := getSortFunc(sortBy)
if f == nil {
return fmt.Errorf("unknown sort option: %s", sortBy)
}
}
return nil
}
func (o *listUsersOptions) Run() error {
ctx := context.Background()
userClient, err := newUserClientFromKubeConfig(o.kubeConfig)
if err != nil {
return err
}
var userList iamv1alpha2.UserList
err = userClient.List(ctx, &userList)
if err != nil {
return fmt.Errorf("failed to list users: %w", err)
}
for _, sortBy := range o.sortBys {
sort.SliceStable(userList.Items, func(i, j int) bool {
f := getSortFunc(sortBy)
if f == nil {
log.Fatalf("unkown sort option: %s", sortBy)
}
return f(userList.Items, i, j)
})
}
if o.reverse {
slices.Reverse(userList.Items)
}
users := make([]userInfo, 0, len(userList.Items))
for _, user := range userList.Items {
users = append(users, convertUserObjectToUserInfo(user))
}
if o.output == "json" {
jsonOutput, _ := json.MarshalIndent(users, "", " ")
fmt.Println(string(jsonOutput))
} else {
if !o.noHeaders {
printUserTableHeaders()
}
for _, user := range users {
printUserTableRow(user)
}
}
return nil
}

16
cli/cmd/ctl/user/root.go Normal file
View File

@@ -0,0 +1,16 @@
package user
import "github.com/spf13/cobra"
func NewUserCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "user",
Short: "user management operations",
}
cmd.AddCommand(NewCmdCreateUser())
cmd.AddCommand(NewCmdDeleteUser())
cmd.AddCommand(NewCmdListUsers())
cmd.AddCommand(NewCmdGetUser())
// cmd.AddCommand(NewCmdUpdateUserLimits())
return cmd
}

43
cli/cmd/ctl/user/types.go Normal file
View File

@@ -0,0 +1,43 @@
package user
type resourceLimit struct {
memoryLimit string
cpuLimit string
}
type userInfo struct {
UID string `json:"uid"`
Name string `json:"name"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
Email string `json:"email"`
State string `json:"state"`
LastLoginTime *int64 `json:"last_login_time"`
CreationTimestamp int64 `json:"creation_timestamp"`
Avatar string `json:"avatar"`
TerminusName string `json:"terminusName"`
WizardComplete bool `json:"wizard_complete"`
Roles []string `json:"roles"`
MemoryLimit string `json:"memory_limit"`
CpuLimit string `json:"cpu_limit"`
}
var (
annotationKeyRole = "bytetrade.io/owner-role"
annotationKeyMemoryLimit = "bytetrade.io/user-memory-limit"
annotationKeyCPULimit = "bytetrade.io/user-cpu-limit"
roleOwner = "owner"
roleAdmin = "admin"
roleNormal = "normal"
creatorCLI = "cli"
lldapGroupAdmin = "lldap_admin"
defaultMemoryLimit = "3G"
defaultCPULimit = "1"
systemObjectName = "terminus"
systemObjectDomainKey = "domainName"
)

View File

@@ -0,0 +1,97 @@
package user
import (
"context"
"fmt"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
"github.com/spf13/cobra"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"log"
)
type updateUserLimitsOptions struct {
name string
resourceLimit
kubeConfig string
}
func NewCmdUpdateUserLimits() *cobra.Command {
o := &updateUserLimitsOptions{}
cmd := &cobra.Command{
Use: "update-limits {name}",
Aliases: []string{"update-limit", "ulimit", "ulimits"},
Short: "update user resource limits",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
o.name = args[0]
if err := o.Validate(); err != nil {
log.Fatal(err)
}
if err := o.Run(); err != nil {
log.Fatal(err)
}
},
}
o.AddFlags(cmd)
return cmd
}
func (o *updateUserLimitsOptions) AddFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&o.memoryLimit, "memory-limit", "m", "", "memory limit")
cmd.Flags().StringVarP(&o.cpuLimit, "cpu-limit", "c", "", "cpu limit")
cmd.Flags().StringVar(&o.kubeConfig, "kubeconfig", "", "path to kubeconfig file")
}
func (o *updateUserLimitsOptions) Validate() error {
if o.name == "" {
return fmt.Errorf("user name is required")
}
if o.memoryLimit == "" && o.cpuLimit == "" {
return fmt.Errorf("one of memory limit or cpu limit is required")
}
if err := validateResourceLimit(o.resourceLimit); err != nil {
return err
}
return nil
}
func (o *updateUserLimitsOptions) Run() error {
ctx := context.Background()
userClient, err := newUserClientFromKubeConfig(o.kubeConfig)
if err != nil {
return err
}
var user iamv1alpha2.User
err = userClient.Get(ctx, types.NamespacedName{Name: o.name}, &user)
if err != nil {
if errors.IsNotFound(err) {
return fmt.Errorf("user '%s' not found", o.name)
}
return fmt.Errorf("failed to get user: %w", err)
}
if user.Annotations == nil {
user.Annotations = make(map[string]string)
}
if o.memoryLimit != "" {
user.Annotations[annotationKeyMemoryLimit] = o.memoryLimit
}
if o.cpuLimit != "" {
user.Annotations[annotationKeyCPULimit] = o.cpuLimit
}
err = userClient.Update(ctx, &user)
if err != nil {
return fmt.Errorf("failed to update user: %w", err)
}
fmt.Printf("User '%s' resource limits updated successfully\n", o.name)
return nil
}

120
cli/cmd/ctl/user/utils.go Normal file
View File

@@ -0,0 +1,120 @@
package user
import (
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
"fmt"
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) {
if kubeconfig == "" {
kubeconfig = os.Getenv("KUBECONFIG")
if kubeconfig == "" {
kubeconfig = clientcmd.RecommendedHomeFile
}
}
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
return nil, fmt.Errorf("failed to get kubeconfig: %w", err)
}
scheme := runtime.NewScheme()
if err := iamv1alpha2.AddToScheme(scheme); err != nil {
return nil, fmt.Errorf("failed to add user scheme: %w", err)
}
if err := v1alpha1.AddToScheme(scheme); err != nil {
return nil, fmt.Errorf("failed to add system scheme: %w", err)
}
userClient, err := client.New(config, client.Options{Scheme: scheme})
if err != nil {
return nil, fmt.Errorf("failed to create user client: %w", err)
}
return userClient, nil
}
func validateResourceLimit(limit resourceLimit) error {
if limit.memoryLimit != "" {
memLimit, err := resource.ParseQuantity(limit.memoryLimit)
if err != nil {
return fmt.Errorf("invalid memory limit: %v", err)
}
minMemLimit, _ := resource.ParseQuantity(defaultMemoryLimit)
if memLimit.Cmp(minMemLimit) < 0 {
return fmt.Errorf("invalid memory limit: %s is less than minimum required: %s", memLimit.String(), minMemLimit.String())
}
}
if limit.cpuLimit != "" {
cpuLimit, err := resource.ParseQuantity(limit.cpuLimit)
if err != nil {
return fmt.Errorf("invalid cpu limit: %v", err)
}
minCPULimit, _ := resource.ParseQuantity(defaultCPULimit)
if cpuLimit.Cmp(minCPULimit) < 0 {
return fmt.Errorf("invalid cpu limit: %s is less than minimum required: %s", cpuLimit.String(), minCPULimit.String())
}
}
return nil
}
func convertUserObjectToUserInfo(user iamv1alpha2.User) userInfo {
info := userInfo{
UID: string(user.UID),
Name: user.Name,
DisplayName: user.Spec.DisplayName,
Description: user.Spec.Description,
Email: user.Spec.Email,
State: string(user.Status.State),
CreationTimestamp: user.CreationTimestamp.Unix(),
}
if user.Annotations != nil {
if role, ok := user.Annotations[annotationKeyRole]; ok {
info.Roles = []string{role}
}
if terminusName, ok := user.Annotations["bytetrade.io/terminus-name"]; ok {
info.TerminusName = terminusName
}
if avatar, ok := user.Annotations["bytetrade.io/avatar"]; ok {
info.Avatar = avatar
}
if memoryLimit, ok := user.Annotations[annotationKeyMemoryLimit]; ok {
info.MemoryLimit = memoryLimit
}
if cpuLimit, ok := user.Annotations[annotationKeyCPULimit]; ok {
info.CpuLimit = cpuLimit
}
}
if user.Status.LastLoginTime != nil {
lastLogin := user.Status.LastLoginTime.Unix()
info.LastLoginTime = &lastLogin
}
return info
}
func printUserTableHeaders() {
fmt.Printf("%-20s %-10s %-10s %-30s %-10s %-10s %-10s\n", "NAME", "ROLE", "STATE", "CREATE TIME", "ACTIVATED", "MEMORY", "CPU")
}
func printUserTableRow(info userInfo) {
role := roleNormal
if len(info.Roles) > 0 {
role = info.Roles[0]
}
fmt.Printf("%-20s %-10s %-10s %-30s %-10s %-10s %-10s\n",
info.Name, role, info.State, time.Unix(info.CreationTimestamp, 0).Format(time.RFC3339), strconv.FormatBool(info.WizardComplete), info.MemoryLimit, info.CpuLimit)
}

View File

@@ -1,16 +1,12 @@
package main
import (
"os"
"os/exec"
"github.com/beclab/Olares/cli/cmd/ctl"
"os"
)
func main() {
cmd := ctl.NewDefaultCommand()
_ = exec.Command("/bin/bash", "-c", "ulimit -u 65535").Run()
_ = exec.Command("/bin/bash", "-c", "ulimit -n 65535").Run()
if err := cmd.Execute(); err != nil {
// fmt.Println(err)

View File

@@ -5,62 +5,67 @@ go 1.24.0
toolchain go1.24.3
replace (
bytetrade.io/web3os/app-service => github.com/beclab/app-service v0.2.33
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/ocicrypt => github.com/containers/ocicrypt v1.1.10
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.3.0
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/api v0.0.0-20250805111305-08be8f53edf0
github.com/cavaliergopher/grab/v3 v3.0.1
github.com/containerd/containerd v1.7.27
github.com/containerd/containerd v1.7.28
github.com/decentralized-identity/web5-go v0.25.0
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
github.com/distribution/reference v0.6.0
github.com/dominodatalab/os-release v0.0.0-20190522011736-bcdb4a3e3c2f
github.com/go-playground/validator/v10 v10.22.0
github.com/go-playground/validator/v10 v10.27.0
github.com/google/uuid v1.6.0
github.com/jmoiron/sqlx v1.4.0
github.com/joho/godotenv v1.5.1
github.com/libp2p/go-netroute v0.2.2
github.com/lithammer/dedent v1.1.0
github.com/mattn/go-sqlite3 v1.14.22
github.com/mitchellh/mapstructure v1.5.0
github.com/mattn/go-sqlite3 v1.14.30
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
github.com/pkg/errors v0.9.1
github.com/pkg/sftp v1.13.6
github.com/pkg/sftp v1.10.1
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
github.com/schollz/progressbar/v3 v3.17.1
github.com/shirou/gopsutil/v4 v4.25.2
github.com/schollz/progressbar/v3 v3.18.0
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.6
github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.0
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.39.0
golang.org/x/term v0.32.0
golang.org/x/text v0.26.0
golang.org/x/crypto v0.40.0
golang.org/x/sys v0.34.0
golang.org/x/term v0.33.0
golang.org/x/text v0.27.0
gopkg.in/yaml.v2 v2.4.0
helm.sh/helm/v3 v3.18.4
k8s.io/api v0.33.2
k8s.io/apimachinery v0.33.2
k8s.io/cli-runtime v0.33.2
k8s.io/client-go v0.33.2
k8s.io/kubectl v0.33.2
k8s.io/api v0.33.3
k8s.io/apimachinery v0.33.3
k8s.io/cli-runtime v0.33.3
k8s.io/client-go v0.33.3
k8s.io/klog/v2 v2.130.1
k8s.io/kubectl v0.33.3
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
sigs.k8s.io/controller-runtime v0.21.0
sigs.k8s.io/kustomize/kyaml v0.19.0
sigs.k8s.io/yaml v1.4.0
sigs.k8s.io/kustomize/kyaml v0.20.1
sigs.k8s.io/yaml v1.5.0
)
require (
@@ -80,7 +85,6 @@ require (
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/bshuster-repo/logrus-logstash-hook v1.0.2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
@@ -101,15 +105,19 @@ require (
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-resty/resty/v2 v2.16.5 // indirect
@@ -129,15 +137,19 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/huandu/xstrings v1.5.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/lib/pq v1.10.9 // indirect
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
@@ -147,7 +159,7 @@ require (
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect
github.com/moby/sys/mountinfo v0.7.1 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/sys/signal v0.7.0 // indirect
github.com/moby/sys/user v0.3.0 // indirect
@@ -177,8 +189,8 @@ require (
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/smartystreets/goconvey v1.8.1 // indirect
github.com/spf13/cast v1.7.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
@@ -191,21 +203,25 @@ require (
go.opentelemetry.io/otel v1.33.0 // indirect
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/trace v1.33.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/oauth2 v0.28.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/time v0.9.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.3 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/time v0.12.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/protobuf v1.36.5 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.33.2 // indirect
k8s.io/apiserver v0.33.2 // indirect
k8s.io/component-base v0.33.2 // indirect
k8s.io/component-helpers v0.33.2 // indirect
k8s.io/component-base v0.33.3 // indirect
k8s.io/component-helpers v0.33.3 // indirect
k8s.io/cri-api v0.27.1 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
@@ -214,19 +230,3 @@ require (
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
)
require (
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/spf13/pflag v1.0.6
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/sys v0.33.0
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.130.1
)

View File

@@ -20,8 +20,8 @@ github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM=
@@ -43,13 +43,16 @@ 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/api v0.0.0-20250805111305-08be8f53edf0 h1:U8AFy37epib5ya5By0gHAWVRT+BetExFkmGTjkhZCoY=
github.com/beclab/api v0.0.0-20250805111305-08be8f53edf0/go.mod h1:1tq7ut9hrjgYWTh6UTth0xPRa7Ags0VJvUmbr4GuJuM=
github.com/beclab/app-service v0.2.33 h1:fsv9sTL7guTdU8z8sO5KIxxd1N5K+Rp4zORRebs+wmI=
github.com/beclab/app-service v0.2.33/go.mod h1:Gpp5e2XPU/nHufT7ZBsRMZrYxpFbI6R4AEiKine+RhI=
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=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/bshuster-repo/logrus-logstash-hook v1.0.2 h1:JYRWo+QGnQdedgshosug9hxpPYTB9oJ1ZZD3fY31alU=
github.com/bshuster-repo/logrus-logstash-hook v1.0.2/go.mod h1:HgYntJprnHSPaF9VPPPLP1L5S1vMWxRfa1J+vzDrDTw=
github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4=
github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
@@ -65,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 v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII=
github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0=
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c=
github.com/containerd/containerd v1.7.28/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=
@@ -86,6 +89,7 @@ github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3H
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.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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=
@@ -96,10 +100,10 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decentralized-identity/web5-go v0.25.0 h1:7QcWuIXHybscmoQ6eoEcDGdbQSPqHIJ4WAo7FBbntIE=
github.com/decentralized-identity/web5-go v0.25.0/go.mod h1:fzRcApHJZmekJXwjdbG8tYSFxdyZjyjUEmfh92mdhwY=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
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/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=
@@ -130,8 +134,8 @@ github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI=
@@ -143,8 +147,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
@@ -158,10 +162,12 @@ github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
@@ -170,8 +176,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao=
github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/go-resty/resty/v2 v2.16.5 h1:hBKqmWrr7uRc3euHVqmh1HTHcKn99Smr7o5spptdhTM=
github.com/go-resty/resty/v2 v2.16.5/go.mod h1:hkJtXbA2iKHzJheXYvQ8snQES5ZLGKMwQ07xAwp/fiA=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
@@ -254,7 +260,6 @@ github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvH
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@@ -278,8 +283,11 @@ github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zt
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
@@ -302,16 +310,20 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
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.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.30 h1:bVreufq3EAIG1Quvws73du3/QgdeZ3myglJlrzSYYCY=
github.com/mattn/go-sqlite3 v1.14.30/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ=
@@ -320,16 +332,16 @@ 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.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
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=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
@@ -357,16 +369,19 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
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/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
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=
@@ -381,10 +396,11 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v
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=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
github.com/pkg/sftp v1.10.1 h1:VasscCm72135zRysgrJDKsntdmPN+OuU3+nnHYA9wyc=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -420,17 +436,16 @@ github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7
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=
github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/schollz/progressbar/v3 v3.17.1 h1:bI1MTaoQO+v5kzklBjYNRQLoVpe0zbyRZNK6DFkVC5U=
github.com/schollz/progressbar/v3 v3.17.1/go.mod h1:RzqpnsPQNjUyIgdglUjRLgD7sVnxN1wpmBMV+UiEbL4=
github.com/schollz/progressbar/v3 v3.18.0 h1:uXdoHABRFmNIjUfte/Ex7WtuyVslrw2wVPQmCN62HpA=
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shirou/gopsutil/v4 v4.25.2 h1:NMscG3l2CqtWFS86kj3vP7soOczqrQYIEhO/pMvvQkk=
github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA=
github.com/shirou/gopsutil/v4 v4.25.7 h1:bNb2JuqKuAu3tRlPv5piSmBZyMfecwQ+t/ILq+1JqVM=
github.com/shirou/gopsutil/v4 v4.25.7/go.mod h1:XV/egmwJtd3ZQjBpJVY5kndsiOO4IRqy9TQnmm6VP7U=
github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
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=
@@ -450,6 +465,7 @@ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -459,10 +475,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -476,7 +492,6 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
@@ -533,13 +548,16 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
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.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
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=
@@ -548,9 +566,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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
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=
@@ -561,57 +578,44 @@ 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.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
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=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
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=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -621,9 +625,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
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=
@@ -659,20 +662,20 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -682,30 +685,30 @@ helm.sh/helm/v3 v3.18.4 h1:pNhnHM3nAmDrxz6/UC+hfjDY4yeDATQCka2/87hkZXQ=
helm.sh/helm/v3 v3.18.4/go.mod h1:WVnwKARAw01iEdjpEkP7Ii1tT1pTPYfM1HsakFKM3LI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY=
k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs=
k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
k8s.io/apiextensions-apiserver v0.33.2 h1:6gnkIbngnaUflR3XwE1mCefN3YS8yTD631JXQhsU6M8=
k8s.io/apiextensions-apiserver v0.33.2/go.mod h1:IvVanieYsEHJImTKXGP6XCOjTwv2LUMos0YWc9O+QP8=
k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
k8s.io/apiserver v0.33.2 h1:KGTRbxn2wJagJowo29kKBp4TchpO1DRO3g+dB/KOJN4=
k8s.io/apiserver v0.33.2/go.mod h1:9qday04wEAMLPWWo9AwqCZSiIn3OYSZacDyu/AcoM/M=
k8s.io/cli-runtime v0.33.2 h1:koNYQKSDdq5AExa/RDudXMhhtFasEg48KLS2KSAU74Y=
k8s.io/cli-runtime v0.33.2/go.mod h1:gnhsAWpovqf1Zj5YRRBBU7PFsRc6NkEkwYNQE+mXL88=
k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E=
k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo=
k8s.io/component-base v0.33.2 h1:sCCsn9s/dG3ZrQTX/Us0/Sx2R0G5kwa0wbZFYoVp/+0=
k8s.io/component-base v0.33.2/go.mod h1:/41uw9wKzuelhN+u+/C59ixxf4tYQKW7p32ddkYNe2k=
k8s.io/component-helpers v0.33.2 h1:AjCtYzst11NV8ensxV/2LEEXRwctqS7Bs44bje9Qcnw=
k8s.io/component-helpers v0.33.2/go.mod h1:PsPpiCk74n8pGWp1d6kjK/iSKBTyQfIacv02BNkMenU=
k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA=
k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo=
k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA=
k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4=
k8s.io/component-helpers v0.33.3 h1:fjWVORSQfI0WKzPeIFSju/gMD9sybwXBJ7oPbqQu6eM=
k8s.io/component-helpers v0.33.3/go.mod h1:7iwv+Y9Guw6X4RrnNQOyQlXcvJrVjPveHVqUA5dm31c=
k8s.io/cri-api v0.27.1 h1:KWO+U8MfI9drXB/P4oU9VchaWYOlwDglJZVHWMpTT3Q=
k8s.io/cri-api v0.27.1/go.mod h1:+Ts/AVYbIo04S86XbTD73UPp/DkTiYxtsFeOFEu32L0=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
k8s.io/kubectl v0.33.2 h1:7XKZ6DYCklu5MZQzJe+CkCjoGZwD1wWl7t/FxzhMz7Y=
k8s.io/kubectl v0.33.2/go.mod h1:8rC67FB8tVTYraovAGNi/idWIK90z2CHFNMmGJZJ3KI=
k8s.io/kubectl v0.33.3 h1:r/phHvH1iU7gO/l7tTjQk2K01ER7/OAJi8uFHHyWSac=
k8s.io/kubectl v0.33.3/go.mod h1:euj2bG56L6kUGOE/ckZbCoudPwuj4Kud7BR0GzyNiT0=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
oras.land/oras-go/v2 v2.6.0 h1:X4ELRsiGkrbeox69+9tzTu492FMUu7zJQW6eJU+I2oc=
@@ -716,12 +719,13 @@ sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/kustomize/api v0.19.0 h1:F+2HB2mU1MSiR9Hp1NEgoU2q9ItNOaBJl0I4Dlus5SQ=
sigs.k8s.io/kustomize/api v0.19.0/go.mod h1:/BbwnivGVcBh1r+8m3tH1VNxJmHSk1PzP5fkP6lbL1o=
sigs.k8s.io/kustomize/kyaml v0.19.0 h1:RFge5qsO1uHhwJsu3ipV7RNolC7Uozc0jUBC/61XSlA=
sigs.k8s.io/kustomize/kyaml v0.19.0/go.mod h1:FeKD5jEOH+FbZPpqUghBP8mrLjJ3+zD3/rf9NNu1cwY=
sigs.k8s.io/kustomize/kyaml v0.20.1 h1:PCMnA2mrVbRP3NIB6v9kYCAc38uvFLVs8j/CD567A78=
sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po=
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=

View File

@@ -166,6 +166,15 @@ func (c *ConfigureOSModule) Init() {
Parallel: true,
}
symlinkSysconf := &task.RemoteTask{
Name: "SymlinkSysconf",
Desc: "Create symbolic link to sysconf if non-existing",
Hosts: c.Runtime.GetAllHosts(),
Prepare: &kubernetes.NodeInCluster{Not: true},
Action: new(SymLinkSysconf),
Parallel: true,
}
ConfigureNtpServer := &task.RemoteTask{
Name: "ConfigureNtpServer",
Desc: "configure the ntp server for each node",
@@ -191,6 +200,7 @@ func (c *ConfigureOSModule) Init() {
initOS,
GenerateScript,
ExecScript,
symlinkSysconf,
ConfigureNtpServer,
configureSwap,
}

View File

@@ -371,6 +371,35 @@ func (n *NodeExecScript) Execute(runtime connector.Runtime) error {
return nil
}
type SymLinkSysconf struct {
common.KubeAction
}
func (a *SymLinkSysconf) Execute(runtime connector.Runtime) error {
sysconfPath := "/etc/sysctl.conf"
sysconfSymLinkPath := "/etc/sysctl.d/99-sysctl.conf"
linkExists, err := runtime.GetRunner().FileExist(sysconfSymLinkPath)
if err != nil {
return fmt.Errorf("failed to check if %s exists", sysconfSymLinkPath)
}
if linkExists {
return nil
}
sysconfDir := filepath.Dir(sysconfSymLinkPath)
dirExists, err := runtime.GetRunner().DirExist(sysconfDir)
if err != nil {
return fmt.Errorf("failed to check if %s exists", sysconfDir)
}
if !dirExists {
err = runtime.GetRunner().MkDir(sysconfDir)
if err != nil {
return err
}
}
_, err = runtime.GetRunner().SudoCmd(fmt.Sprintf("ln -s %s %s", sysconfPath, sysconfSymLinkPath), true, false)
return err
}
var (
etcdFiles = []string{
"/usr/local/bin/etcd",

View File

@@ -152,9 +152,6 @@ update-alternatives --set arptables /usr/sbin/arptables-legacy >/dev/null 2>&1 |
update-alternatives --set ebtables /usr/sbin/ebtables-legacy >/dev/null 2>&1 || true
for i in $(systemctl list-unit-files --no-legend --no-pager -l | grep --color=never -o .*.slice | grep kubepod); do sudo systemctl stop $i; done
ulimit -u 65535
ulimit -n 65535
`)))
func GenerateHosts(runtime connector.ModuleRuntime, kubeConf *common.KubeConf) []string {

View File

@@ -75,7 +75,22 @@ func (t *SystemSupportCheck) Name() string {
}
func (t *SystemSupportCheck) Check(runtime connector.Runtime) error {
return runtime.GetSystemInfo().IsSupport()
err := runtime.GetSystemInfo().IsSupport()
if err == nil {
return nil
}
// Interactive warning instead of outright failure
fmt.Printf("%v Use at your own risk, would you like to continue? (Y/N): ", err)
reader, err := utils.GetBufIOReaderOfTerminalInput()
if err != nil {
return fmt.Errorf("could not read terminal input: %v", err)
}
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(input)
if !strings.HasPrefix("yes", strings.ToLower(input)) {
return err
}
return nil
}
type RequiredPortsCheck struct{}

View File

@@ -333,8 +333,10 @@ var TerminusGlobalEnvs = map[string]interface{}{
"FRP_LIST_URL": "https://terminus-frp.snowinning.com",
"TAILSCALE_CONTROLPLANE_URL": "https://controlplane.snowinning.com",
"OLARES_ROOT_DIR": "/olares",
ENV_DOWNLOAD_CDN_URL: cc.DownloadUrl,
ENV_MARKET_PROVIDER: "appstore-server-prod.bttcdn.com",
// the default value used by kubeadm
"COREDNS_SVC": "10.96.0.10",
ENV_DOWNLOAD_CDN_URL: cc.DownloadUrl,
ENV_MARKET_PROVIDER: "appstore-server-prod.bttcdn.com",
}
const (

View File

@@ -302,6 +302,8 @@ func (s *SystemInfo) Print() {
fmt.Printf("fs info, fs: %s, zfsmount: %s\n", s.FsInfo.Type, s.FsInfo.DefaultZfsPrefixName)
fmt.Printf("mem info, total: %s, free: %s\n", util.FormatBytes(int64(s.MemoryInfo.Total)), util.FormatBytes(int64(s.MemoryInfo.Free)))
fmt.Printf("cgroup info, cpu: %d, mem: %d\n", s.CgroupInfo.CpuEnabled, s.CgroupInfo.MemoryEnabled)
fmt.Printf("oic: %t\n", s.IsOIC)
fmt.Printf("in wsl: %t\n", s.IsWsl())
}
func GetSystemInfo() *SystemInfo {

View File

@@ -30,6 +30,7 @@ var (
dedent.Dedent(`[Unit]
Description=Backup ETCD
[Service]
Environment=LANG=C
Type=oneshot
ExecStart={{ .ScriptPath }}
`)))

View File

@@ -21,11 +21,9 @@ import (
_ "compress/bzip2"
"context"
"fmt"
cliversion "github.com/beclab/Olares/cli/version"
"io"
"math"
"net/http"
"net/url"
"os"
"os/exec"
"path"
@@ -329,12 +327,6 @@ func NewKubeBinary(name, arch, osType, osVersion, osPlatformFamily, version, pre
component.Url = fmt.Sprintf("https://github.com/fqrouter/conntrack-tools/archive/refs/tags/conntrack-tools-%s.tar.gz", version)
component.CheckSum = false
component.BaseDir = filepath.Join(prePath, component.Type)
case installwizard:
component.Type = WIZARD
component.FileName = fmt.Sprintf("install-wizard-v%s.tar.gz", version)
component.Url, _ = url.JoinPath(component.getDownloadMirrors(downloadMirrors), cliversion.VENDOR_REPO_PATH, fmt.Sprintf("install-wizard-v%s.tar.gz", version))
component.CheckSum = false
component.BaseDir = filepath.Join(prePath, fmt.Sprintf("v%s", version))
case cudakeyring: // + gpu
if strings.Contains(osVersion, "24.") {
version = "1.1"
@@ -387,7 +379,7 @@ func NewKubeBinary(name, arch, osType, osVersion, osPlatformFamily, version, pre
return component
}
func (b *KubeBinary) getDownloadMirrors(downloadMirrors string) string {
func (b *KubeBinary) GetDownloadMirrors(downloadMirrors string) string {
if downloadMirrors == "" {
return common.DownloadUrl
}

View File

@@ -108,22 +108,24 @@ func (t *LoadImages) Execute(runtime connector.Runtime) (reserr error) {
loadParm = "--no-unpack"
}
parsedRef, err := reference.ParseNormalizedNamed(imageRepoTag)
if err != nil {
logger.Warnf("parse image name %s error: %v, skip importing", imageRepoTag, err)
continue
}
if runtime.RemoteHost().GetOs() == common.Darwin {
loadCmd = fmt.Sprintf("%s -p %s ssh --native-ssh=false 'sudo ctr -n k8s.io i import --index-name %s -'", minikubepath, minikubeprofile, parsedRef)
if HasSuffixI(imgFileName, ".tar.gz", ".tgz") {
loadCmd = fmt.Sprintf("gunzip -c %s | %s -p %s image load -", imageFileName, minikubepath, minikubeprofile)
loadCmd = fmt.Sprintf("gunzip -c %s | ", imageFileName) + loadCmd
} else {
loadCmd = fmt.Sprintf("%s -p %s image load %s", minikubepath, minikubeprofile, imageFileName)
loadCmd = fmt.Sprintf("cat %s | ", imageFileName) + loadCmd
}
} else {
switch containerManager {
case "crio":
loadCmd = "ctr" // not implement
case "containerd":
parsedRef, err := reference.ParseNormalizedNamed(imageRepoTag)
if err != nil {
logger.Warnf("parse image name %s error: %v, skip importing", imageRepoTag, err)
continue
}
if HasSuffixI(imgFileName, ".tar.gz", ".tgz") {
loadCmd = fmt.Sprintf("gunzip -c %s | ctr -n k8s.io images import --index-name %s %s -", imageFileName, parsedRef, loadParm)
} else {

View File

@@ -50,7 +50,7 @@ func (t *CreateMiniKubeCluster) Execute(runtime connector.Runtime) error {
}
}
logger.Infof("creating minikube cluster %s ...", t.KubeConf.Arg.MinikubeProfile)
cmd = fmt.Sprintf("%s start -p '%s' --kubernetes-version=v1.22.10 --container-runtime=containerd --network-plugin=cni --cni=calico --cpus='4' --memory='8g' --ports=30180:30180,443:443,80:80", minikube, t.KubeConf.Arg.MinikubeProfile)
cmd = fmt.Sprintf("%s start -p '%s' --kubernetes-version=v1.33.3 --container-runtime=containerd --network-plugin=cni --cni=calico --cpus='4' --memory='8g' --ports=30180:30180,443:443,80:80", minikube, t.KubeConf.Arg.MinikubeProfile)
if _, err := runtime.GetRunner().Cmd(cmd, false, true); err != nil {
return errors.Wrap(err, "failed to create minikube cluster")
}

File diff suppressed because one or more lines are too long

View File

@@ -59,14 +59,7 @@ securityContext: {}
# Kubernetes Version shows in KubeSphere console
# kube_version: "v1.19.4" # ! 这里要替换下
env:
- name: KUBESPHERE_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: auth
tolerations:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: CriticalAddonsOnly

View File

@@ -32,7 +32,7 @@ spec:
- command:
- ks-apiserver
- --logtostderr=true
image: beclab/ks-apiserver:0.0.21
image: beclab/ks-apiserver:0.0.22
imagePullPolicy: {{ .Values.image.pullPolicy }}
name: ks-apiserver
ports:
@@ -49,10 +49,6 @@ spec:
{{- if .Values.apiserver.extraVolumeMounts }}
{{- toYaml .Values.apiserver.extraVolumeMounts | nindent 8 }}
{{- end }}
env:
{{- if .Values.env }}
{{- toYaml .Values.env | nindent 8 }}
{{- end }}
livenessProbe:
failureThreshold: 8
httpGet:

View File

@@ -58,14 +58,7 @@ securityContext: {}
# Kubernetes Version shows in KubeSphere console
# kube_version: "v1.19.4" # ! 这里要替换下
env:
- name: KUBESPHERE_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: auth
tolerations:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: CriticalAddonsOnly

View File

@@ -1,23 +0,0 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

View File

@@ -1,15 +0,0 @@
apiVersion: v2
appVersion: 5.0.14
name: redis
description: A Helm chart for redis
version: 0.2.0
kubeVersion: ">=1.17.0-0"
home: https://github.com/kubernetes-csi/external-snapshotter
sources:
- https://github.com/kubesphere/helm-charts
keywords:
- redis
maintainers:
- name: aby913
email: aby913@gmail.com

View File

@@ -1,136 +0,0 @@
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: redis-pvc
namespace: kubesphere-system
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.persistentVolume.size }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: redis
tier: database
version: {{ .Values.version }}
name: redis
namespace: kubesphere-system
spec:
replicas: 1
selector:
matchLabels:
app: redis
tier: database
template:
metadata:
labels:
app: redis
tier: database
version: {{ .Values.version }}
spec:
initContainers:
- name: init
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ['sh', '-c', 'cat /tmp/redis/redis.conf | sed "s/REDIS_PASSWORD/$KUBESPHERE_REDIS_PASSWORD/" > /data/redis.conf']
volumeMounts:
- mountPath: /data
name: redis-pvc
subPath: redis-data
- name: redis-config
mountPath: "/tmp/redis"
readOnly: true
env:
- name: KUBESPHERE_REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: auth
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: IfNotPresent
name: redis
args: ["/data/redis.conf"]
volumeMounts:
- mountPath: /data
name: redis-pvc
subPath: redis-data
ports:
- containerPort: 6379
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 1000Mi
requests:
cpu: 20m
memory: 100Mi
volumes:
- name: redis-pvc
persistentVolumeClaim:
claimName: redis-pvc
- name: redis-config
configMap:
name: redis-configmap
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: node-role.kubernetes.io/master
operator: In
values:
- ""
nodeSelector: {}
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
- key: CriticalAddonsOnly
operator: Exists
---
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-configmap
namespace: kubesphere-system
labels:
app: redis
tier: database
version: {{ .Values.version }}
data:
redis.conf: |
requirepass REDIS_PASSWORD
masterauth REDIS_PASSWORD
---
apiVersion: v1
kind: Service
metadata:
labels:
app: redis
tier: database
name: redis
namespace: kubesphere-system
spec:
ports:
- name: redis
port: 6379
protocol: TCP
targetPort: 6379
selector:
app: redis
tier: database
sessionAffinity: None
type: ClusterIP

View File

@@ -1,263 +0,0 @@
## Configure resource requests and limits
## ref: http://kubernetes.io/docs/user-guide/compute-resources/
##
version: redis-4.0
image:
repository: redis
tag: 5.0.14-alpine
pullPolicy: IfNotPresent
## replicas number for each component
replicas: 3
## Kubernetes priorityClass name for the redis-ha-server pod
# priorityClassName: ""
## Custom labels for the redis pod
labels: {}
## Pods Service Account
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
serviceAccount:
## Specifies whether a ServiceAccount should be created
##
create: true
## The name of the ServiceAccount to use.
## If not set and create is true, a name is generated using the redis-ha.fullname template
# name:
## Enables a HA Proxy for better LoadBalancing / Sentinel Master support. Automatically proxies to Redis master.
## Recommend for externally exposed Redis clusters.
## ref: https://cbonte.github.io/haproxy-dconv/1.9/intro.html
haproxy:
enabled: true
# Enable if you want a dedicated port in haproxy for redis-slaves
readOnly:
enabled: false
port: 6380
replicas: 3
image:
repository: haproxy
tag: 2.0.25-alpine
pullPolicy: IfNotPresent
annotations: {}
resources: {}
## Kubernetes priorityClass name for the haproxy pod
# priorityClassName: ""
## Service type for HAProxy
##
service:
type: ClusterIP
loadBalancerIP:
annotations: {}
serviceAccount:
create: true
## Prometheus metric exporter for HAProxy.
##
exporter:
image:
repository: quay.io/prometheus/haproxy-exporter
tag: v0.9.0
enabled: false
port: 9101
init:
resources: {}
timeout:
connect: 10s
server: 360s
client: 360s
securityContext:
runAsUser: 1000
fsGroup: 1000
runAsNonRoot: true
## Role Based Access
## Ref: https://kubernetes.io/docs/admin/authorization/rbac/
##
rbac:
create: true
sysctlImage:
enabled: false
command: []
registry: docker.io
repository: bitnami/minideb
tag: latest
pullPolicy: Always
mountHostSys: false
## Use an alternate scheduler, e.g. "stork".
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
# schedulerName:
## Redis specific configuration options
redis:
port: 6379
masterGroupName: mymaster
config:
## Additional redis conf options can be added below
## For all available options see http://download.redis.io/redis-stable/redis.conf
min-replicas-to-write: 1
min-replicas-max-lag: 5 # Value in seconds
maxmemory: "0" # Max memory to use for each redis instance. Default is unlimited.
maxmemory-policy: "volatile-lru" # Max memory policy to use for each redis instance. Default is volatile-lru.
# Determines if scheduled RDB backups are created. Default is false.
# Please note that local (on-disk) RDBs will still be created when re-syncing with a new slave. The only way to prevent this is to enable diskless replication.
save: "900 1"
# When enabled, directly sends the RDB over the wire to slaves, without using the disk as intermediate storage. Default is false.
repl-diskless-sync: "yes"
rdbcompression: "yes"
rdbchecksum: "yes"
## Custom redis.conf files used to override default settings. If this file is
## specified then the redis.config above will be ignored.
# customConfig: |-
# Define configuration here
resources: {}
# requests:
# memory: 200Mi
# cpu: 100m
# limits:
# memory: 700Mi
## Sentinel specific configuration options
sentinel:
port: 26379
quorum: 2
config:
## Additional sentinel conf options can be added below. Only options that
## are expressed in the format simialar to 'sentinel xxx mymaster xxx' will
## be properly templated.
## For available options see http://download.redis.io/redis-stable/sentinel.conf
down-after-milliseconds: 10000
## Failover timeout value in milliseconds
failover-timeout: 180000
parallel-syncs: 5
## Custom sentinel.conf files used to override default settings. If this file is
## specified then the sentinel.config above will be ignored.
# customConfig: |-
# Define configuration here
resources: {}
# requests:
# memory: 200Mi
# cpu: 100m
# limits:
# memory: 200Mi
securityContext:
runAsUser: 1000
fsGroup: 1000
runAsNonRoot: true
## Node labels, affinity, and tolerations for pod assignment
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature
## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
nodeSelector: {}
tolerations: []
## Whether the Redis server pods should be forced to run on separate nodes.
## This is accomplished by setting their AntiAffinity with requiredDuringSchedulingIgnoredDuringExecution as opposed to preferred.
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature
##
hardAntiAffinity: true
## Additional affinities to add to the Redis server pods.
##
## Example:
## nodeAffinity:
## preferredDuringSchedulingIgnoredDuringExecution:
## - weight: 50
## preference:
## matchExpressions:
## - key: spot
## operator: NotIn
## values:
## - "true"
##
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
additionalAffinities:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: node-role.kubernetes.io/master
operator: In
values:
- ""
## Override all other affinity settings for the Redis server pods with a string.
affinity: |
# Prometheus exporter specific configuration options
exporter:
enabled: false
image: oliver006/redis_exporter
tag: v0.31.0
pullPolicy: IfNotPresent
# prometheus port & scrape path
port: 9121
scrapePath: /metrics
# cpu/memory resource limits/requests
resources: {}
# Additional args for redis exporter
extraArgs: {}
podDisruptionBudget: {}
# maxUnavailable: 1
# minAvailable: 1
## Configures redis with AUTH (requirepass & masterauth conf params)
auth: true
# redisPassword:
## Use existing secret containing key `authKey` (ignores redisPassword)
existingSecret: redis-secret
## Defines the key holding the redis password in existing secret.
authKey: auth
persistentVolume:
enabled: true
## redis-ha data Persistent Volume Storage Class
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
accessModes:
- ReadWriteOnce
size: 2Gi
annotations: {}
init:
resources: {}
# To use a hostPath for data, set persistentVolume.enabled to false
# and define hostPath.path.
# Warning: this might overwrite existing folders on the host system!
hostPath:
## path is evaluated as template so placeholders are replaced
# path: "/data/redis"
# if chown is true, an init-container with root permissions is launched to
# change the owner of the hostPath folder to the user defined in the
# security context
chown: true

View File

@@ -39,7 +39,7 @@ func NewDarwinClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
&kubesphere.DeployMiniKubeModule{},
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
&ksplugins.DeployKsPluginsModule{},
&ksplugins.DeployRedisModule{},
//&ksplugins.DeployRedisModule{},
&ksplugins.CreateKubeSphereSecretModule{},
&ksplugins.DeployKsCoreConfigModule{}, // ks-core-config
&ksplugins.CreateMonitorDashboardModule{},
@@ -98,7 +98,7 @@ func NewK3sCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled}, //
&ksplugins.DeployKsPluginsModule{},
&ksplugins.DeployRedisModule{},
//&ksplugins.DeployRedisModule{},
&ksplugins.CreateKubeSphereSecretModule{},
&ksplugins.DeployKsCoreConfigModule{}, // ks-core-config
&ksplugins.CreateMonitorDashboardModule{},
@@ -161,7 +161,7 @@ func NewCreateClusterPhase(runtime *common.KubeRuntime, manifestMap manifest.Ins
&storage.DeployLocalVolumeModule{Skip: skipLocalStorage},
&kubesphere.DeployModule{Skip: !runtime.Cluster.KubeSphere.Enabled},
&ksplugins.DeployKsPluginsModule{},
&ksplugins.DeployRedisModule{},
//&ksplugins.DeployRedisModule{},
&ksplugins.CreateKubeSphereSecretModule{},
&ksplugins.DeployKsCoreConfigModule{}, // ! ks-core-config
&ksplugins.CreateMonitorDashboardModule{},

View File

@@ -8,11 +8,11 @@ import (
"github.com/beclab/Olares/cli/pkg/terminus"
)
func NewDownloadWizard(runtime *common.KubeRuntime, urlOverride string) *pipeline.Pipeline {
func NewDownloadWizard(runtime *common.KubeRuntime, urlOverride, releaseID string) *pipeline.Pipeline {
m := []module.Module{
&precheck.GreetingsModule{},
&terminus.InstallWizardDownloadModule{Version: runtime.Arg.OlaresVersion, DownloadCdnUrl: runtime.Arg.DownloadCdnUrl, UrlOverride: urlOverride},
&terminus.InstallWizardDownloadModule{Version: runtime.Arg.OlaresVersion, DownloadCdnUrl: runtime.Arg.DownloadCdnUrl, UrlOverride: urlOverride, ReleaseID: releaseID},
}
return &pipeline.Pipeline{

View File

@@ -26,7 +26,7 @@ func DownloadInstallationWizard(opts *options.CliDownloadWizardOptions) error {
return fmt.Errorf("--download-cdn-url invalid")
}
p := download.NewDownloadWizard(runtime, opts.UrlOverride)
p := download.NewDownloadWizard(runtime, opts.UrlOverride, opts.ReleaseID)
if err := p.Start(); err != nil {
logger.Errorf("download wizard failed %v", err)
return err

View File

@@ -4,7 +4,7 @@ import (
"fmt"
"github.com/beclab/Olares/cli/pkg/upgrade"
"github.com/beclab/Olares/cli/pkg/utils"
"os"
"github.com/beclab/Olares/cli/version"
"path"
"github.com/beclab/Olares/cli/cmd/ctl/options"
@@ -29,34 +29,19 @@ func UpgradeOlaresPipeline(opts *options.UpgradeOptions) error {
return fmt.Errorf("error parsing current Olares version: %v", err)
}
// validate the expected version is non-empty before the NewArgument() call
// as it will fall back to load the current olares release
// should only be and defaults to the current cli version
// this argument is for backwards-compatibility with older olaresd
if opts.Version == "" {
return errors.New("target version is required")
opts.Version = version.VERSION
}
targetVersion, err := utils.ParseOlaresVersionString(opts.Version)
if err != nil {
return fmt.Errorf("error parsing target Olares version: %v", err)
}
upgradePath, err := upgrade.GetUpgradePathFor(currentVersion, targetVersion)
if err != nil {
if err := upgrade.Check(currentVersion, targetVersion); err != nil {
return err
}
if len(upgradePath) > 1 {
fmt.Printf("unable to upgrade from %s to %s directly,\n", currentVersion, targetVersion)
if len(upgradePath) == 2 {
fmt.Printf("please upgrade to %s first!\n", upgradePath[0])
} else {
line := "please upgrade sequentially to:"
for _, u := range upgradePath[:len(upgradePath)-1] {
line += fmt.Sprintf(" %s", u)
}
line += " first!"
fmt.Println(line)
}
os.Exit(1)
}
arg := common.NewArgument()
arg.SetBaseDir(opts.BaseDir)

View File

@@ -276,17 +276,17 @@ func (m *Manager) scan() error {
return nil
}
func (m *Manager) getLatestDailyBuildTag() (string, error) {
func (m *Manager) getLatestDailyBuildTagAndCommit() (string, string, error) {
cmd := exec.Command("git", "tag", "-l")
cmd.Dir = m.olaresRepoRoot
output, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("failed to get git tags: %v", err)
return "", "", fmt.Errorf("failed to get git tags: %v", err)
}
tags := strings.Split(strings.TrimSpace(string(output)), "\n")
if len(tags) == 0 || (len(tags) == 1 && tags[0] == "") {
return "", fmt.Errorf("no git tags found")
return "", "", fmt.Errorf("no git tags found")
}
var dailyTags []string
@@ -300,7 +300,7 @@ func (m *Manager) getLatestDailyBuildTag() (string, error) {
}
if len(dailyTags) == 0 {
return "", fmt.Errorf("no daily build tags found")
return "", "", fmt.Errorf("no daily build tags found")
}
sort.Slice(dailyTags, func(i, j int) bool {
@@ -314,7 +314,13 @@ func (m *Manager) getLatestDailyBuildTag() (string, error) {
}
return iv.LessThan(jv)
})
return dailyTags[len(dailyTags)-1], nil
tag := dailyTags[len(dailyTags)-1]
parseCommitCMD := exec.Command("git", "rev-parse", "--short=7", tag)
commitSHA, err := parseCommitCMD.CombinedOutput()
if err != nil {
return "", "", fmt.Errorf("failed to parse git commit: %v", err)
}
return tag, strings.TrimSpace(string(commitSHA)), nil
}
// Helper function to patch extracted image name
@@ -350,7 +356,7 @@ func (m *Manager) patchComponent(component BinaryOutput) (BinaryOutput, error) {
return component, nil
}
latestDailyBuildTag, err := m.getLatestDailyBuildTag()
latestDailyBuildTag, latestDailyBuildCommit, err := m.getLatestDailyBuildTagAndCommit()
if err != nil {
return BinaryOutput{}, fmt.Errorf("failed to get latest daily build tag (required to replace olaresd version): %v", err)
}
@@ -360,6 +366,11 @@ func (m *Manager) patchComponent(component BinaryOutput) (BinaryOutput, error) {
component.Name = strings.ReplaceAll(component.Name, "#__VERSION__", latestDailyBuildTag)
component.AMD64 = strings.ReplaceAll(component.AMD64, "#__VERSION__", latestDailyBuildTag)
component.ARM64 = strings.ReplaceAll(component.ARM64, "#__VERSION__", latestDailyBuildTag)
releaseIDSuffix := fmt.Sprintf(".%s", latestDailyBuildCommit)
component.Name = strings.ReplaceAll(component.Name, "#__RELEASE_ID_SUFFIX__", releaseIDSuffix)
component.AMD64 = strings.ReplaceAll(component.AMD64, "#__RELEASE_ID_SUFFIX__", releaseIDSuffix)
component.ARM64 = strings.ReplaceAll(component.ARM64, "#__RELEASE_ID_SUFFIX__", releaseIDSuffix)
return component, nil
}

View File

@@ -82,10 +82,10 @@ func (u *PrepareAppValues) Execute(runtime connector.Runtime) error {
defer cancel()
ns := fmt.Sprintf("user-space-%s", u.KubeConf.Arg.User.UserName)
redisPassword, err := getRedisPassword(client, runtime)
if err != nil {
return err
}
//redisPassword, err := getRedisPassword(client, runtime)
//if err != nil {
// return err
//}
bfDocUrl, _ := getDocUrl(ctx, runtime)
bflNodeName, err := getBflPod(ctx, ns, client, runtime)
@@ -131,9 +131,9 @@ func (u *PrepareAppValues) Execute(runtime connector.Runtime) error {
"gpu": gpuType,
"fs_type": fsType,
"os": appValues,
"kubesphere": map[string]interface{}{
"redis_password": redisPassword,
},
//"kubesphere": map[string]interface{}{
// "redis_password": redisPassword,
//},
common.HelmValuesKeyTerminusGlobalEnvs: common.TerminusGlobalEnvs,
common.HelmValuesKeyOlaresRootFSPath: storage.OlaresRootDir,
}

View File

@@ -34,6 +34,7 @@ type InstallWizardDownloadModule struct {
Version string
DownloadCdnUrl string
UrlOverride string
ReleaseID string
}
func (m *InstallWizardDownloadModule) Init() {
@@ -44,6 +45,7 @@ func (m *InstallWizardDownloadModule) Init() {
Version: m.Version,
DownloadCdnUrl: m.DownloadCdnUrl,
UrlOverride: m.UrlOverride,
ReleaseID: m.ReleaseID,
},
Retry: 1,
}

View File

@@ -27,27 +27,12 @@ type InstallOsSystem struct {
}
func (t *InstallOsSystem) Execute(runtime connector.Runtime) error {
kubectl, err := util.GetCommand(common.CommandKubectl)
if err != nil {
return errors.Wrap(errors.WithStack(err), "kubectl not found")
}
if !runtime.GetSystemInfo().IsDarwin() {
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", storage.OlaresSharedLibDir, storage.OlaresSharedLibDir), false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
}
}
var cmd = fmt.Sprintf("%s get secret -n kubesphere-system redis-secret -o jsonpath='{.data.auth}' |base64 -d", kubectl)
redisPwd, err := runtime.GetRunner().SudoCmd(cmd, false, false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get redis secret error")
}
if redisPwd == "" {
return fmt.Errorf("redis secret not found")
}
config, err := ctrl.GetConfig()
if err != nil {
return err
@@ -61,7 +46,6 @@ func (t *InstallOsSystem) Execute(runtime connector.Runtime) error {
defer cancel()
vals := map[string]interface{}{
"kubesphere": map[string]interface{}{"redis_password": redisPwd},
"backup": map[string]interface{}{
"bucket": t.KubeConf.Arg.Storage.BackupClusterBucket,
"key_prefix": t.KubeConf.Arg.Storage.StoragePrefix,

View File

@@ -158,6 +158,7 @@ type Download struct {
BaseDir string
DownloadCdnUrl string
UrlOverride string
ReleaseID string
}
func (t *Download) Execute(runtime connector.Runtime) error {
@@ -165,21 +166,27 @@ func (t *Download) Execute(runtime connector.Runtime) error {
return errors.New("unknown version to download")
}
var osArch = runtime.GetSystemInfo().GetOsArch()
var osType = runtime.GetSystemInfo().GetOsType()
var osVersion = runtime.GetSystemInfo().GetOsVersion()
var osPlatformFamily = runtime.GetSystemInfo().GetOsPlatformFamily()
var baseDir = runtime.GetBaseDir()
var prePath = path.Join(baseDir, "versions")
var wizard = files.NewKubeBinary("install-wizard", osArch, osType, osVersion, osPlatformFamily, t.Version, prePath, t.DownloadCdnUrl)
var stem string
if t.ReleaseID != "" {
stem = fmt.Sprintf("install-wizard-v%s.%s", t.Version, t.ReleaseID)
} else {
stem = fmt.Sprintf("install-wizard-v%s", t.Version)
}
wizard := &files.KubeBinary{
ID: "install-wizard",
Type: files.WIZARD,
BaseDir: filepath.Join(runtime.GetBaseDir(), "versions", fmt.Sprintf("v%s", t.Version)),
FileName: fmt.Sprintf("%s.tar.gz", stem),
}
if t.UrlOverride == "" {
md5URL, _ := url.JoinPath(t.DownloadCdnUrl, version.VENDOR_REPO_PATH, fmt.Sprintf("install-wizard-v%s.md5sum.txt", t.Version))
md5URL, _ := url.JoinPath(wizard.GetDownloadMirrors(t.DownloadCdnUrl), version.VENDOR_REPO_PATH, fmt.Sprintf("%s.md5sum.txt", stem))
var fetchMd5 = fmt.Sprintf("curl -sSfL %s |awk '{print $1}'", md5URL)
md5sum, err := runtime.GetRunner().Cmd(fetchMd5, false, false)
if err != nil {
return errors.New("get md5sum failed")
}
wizard.Url, _ = url.JoinPath(wizard.GetDownloadMirrors(t.DownloadCdnUrl), version.VENDOR_REPO_PATH, fmt.Sprintf("%s.tar.gz", stem))
wizard.CheckMd5Sum = true
wizard.Md5sum = md5sum
} else {

View File

@@ -12,7 +12,7 @@ import (
)
type upgrader_1_12_0_20250702 struct {
upgraderBase
breakingUpgraderBase
}
func (u upgrader_1_12_0_20250702) Version() *semver.Version {

View File

@@ -10,7 +10,7 @@ import (
)
type upgrader_1_12_0_20250723 struct {
upgraderBase
breakingUpgraderBase
}
func (u upgrader_1_12_0_20250723) Version() *semver.Version {

View File

@@ -19,7 +19,7 @@ import (
)
type upgrader_1_12_0_20250730 struct {
upgraderBase
breakingUpgraderBase
}
func (u upgrader_1_12_0_20250730) Version() *semver.Version {

37
cli/pkg/upgrade/1_12_1.go Normal file
View File

@@ -0,0 +1,37 @@
package upgrade
import (
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/version"
)
var version_12_1_1 = semver.MustParse("1.12.1")
type upgrader_1_12_1 struct {
breakingUpgraderBase
}
func (u upgrader_1_12_1) Version() *semver.Version {
cliVersion, err := semver.NewVersion(version.VERSION)
// tolerate local dev version
if err != nil {
return version_12_1_1
}
if samePatchLevelVersion(version_12_1_1, cliVersion) && getReleaseLineOfVersion(cliVersion) == mainLine {
return cliVersion
}
return version_12_1_1
}
func (u upgrader_1_12_1) AddedBreakingChange() bool {
if u.Version().Equal(version_12_1_1) {
// if this version introduced breaking change
return true
}
if u.Version().Equal(semver.MustParse("1.12.1-alpha.2")) {
// if this alpha version introduced more breaking change
// halfway through release
return true
}
return false
}

View File

@@ -0,0 +1,43 @@
package upgrade
import (
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/apis/kubekey/v1alpha2"
"github.com/beclab/Olares/cli/pkg/core/action"
"github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/core/util"
"github.com/beclab/Olares/cli/pkg/etcd/templates"
"github.com/beclab/Olares/cli/pkg/terminus"
"path/filepath"
)
type upgrader_1_12_1_20250826 struct {
breakingUpgraderBase
}
func (u upgrader_1_12_1_20250826) Version() *semver.Version {
return semver.MustParse("1.12.1-20250826")
}
func (u upgrader_1_12_1_20250826) PrepareForUpgrade() []task.Interface {
preTasks := []task.Interface{
&task.LocalTask{
Name: "UpdateBackupETCDService",
Action: &action.Template{
Name: "GenerateBackupETCDService",
Template: templates.BackupETCDService,
Dst: filepath.Join("/etc/systemd/system/", templates.BackupETCDService.Name()),
Data: util.Data{
"ScriptPath": filepath.Join(v1alpha2.DefaultEtcdBackupScriptDir, templates.EtcdBackupScript.Name()),
},
},
},
&task.LocalTask{
Name: "ReloadBackupETCDService",
Action: &terminus.SystemctlCommand{
DaemonReloadPreExec: true,
},
},
}
return append(preTasks, u.upgraderBase.PrepareForUpgrade()...)
}

View File

@@ -5,8 +5,11 @@ import (
"fmt"
"github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/terminus"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
kruntime "k8s.io/apimachinery/pkg/runtime"
"os"
"path"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
"time"
"github.com/beclab/Olares/cli/pkg/common"
@@ -15,12 +18,18 @@ import (
"github.com/beclab/Olares/cli/pkg/utils"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/kubernetes"
metadataclient "k8s.io/client-go/metadata"
ctrl "sigs.k8s.io/controller-runtime"
)
type breakingUpgraderBase struct {
upgraderBase
}
func (u breakingUpgraderBase) AddedBreakingChange() bool {
return true
}
// upgraderBase is the general-purpose upgrader implementation
// for upgrading across versions without any breaking changes.
// Other implementations of breakingUpgrader,
@@ -28,6 +37,10 @@ import (
// should use this as a base for injecting and/or rewriting specific tasks as needed
type upgraderBase struct{}
func (u upgraderBase) AddedBreakingChange() bool {
return false
}
func (u upgraderBase) PrepareForUpgrade() []task.Interface {
return []task.Interface{
&task.LocalTask{
@@ -129,29 +142,37 @@ func (p *prepareUserInfoForUpgrade) Execute(runtime connector.Runtime) error {
if err != nil {
return fmt.Errorf("failed to get rest config: %s", err)
}
// we only need user's metadata, this avoids the dependency on kubesphere's module
metadataClient, err := metadataclient.NewForConfig(config)
scheme := kruntime.NewScheme()
err = iamv1alpha2.AddToScheme(scheme)
if err != nil {
return fmt.Errorf("failed to get metadata client: %s", err)
return fmt.Errorf("failed to add user scheme: %s", err)
}
userGVR := schema.GroupVersionResource{
Group: "iam.kubesphere.io",
Version: "v1alpha2",
Resource: "users",
userClient, err := ctrlclient.New(config, ctrlclient.Options{Scheme: scheme})
if err != nil {
return fmt.Errorf("failed to create client: %s", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
users, err := metadataClient.Resource(userGVR).List(ctx, metav1.ListOptions{})
var userList iamv1alpha2.UserList
err = userClient.List(ctx, &userList)
if err != nil {
return fmt.Errorf("failed to list users: %s", err)
}
var usersToUpgrade []metav1.PartialObjectMetadata
var usersToUpgrade []iamv1alpha2.User
var adminUser string
client, err := kubernetes.NewForConfig(config)
if err != nil {
return fmt.Errorf("failed to create kubernetes client: %s", err)
}
for _, user := range users.Items {
for _, user := range userList.Items {
if user.Status.State == "Failed" {
logger.Infof("skipping user %s that failed to be created", user.Name)
continue
}
if user.Status.State == "Deleting" || user.DeletionTimestamp != nil {
logger.Infof("skipping user %s that's being deleted", user.Name)
continue
}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
defer cancel()
_, err := client.CoreV1().Namespaces().Get(ctx, fmt.Sprintf("user-space-%s", user.Name), metav1.GetOptions{})
@@ -197,7 +218,7 @@ func (u *upgradeUserComponents) Execute(runtime connector.Runtime) error {
if !ok {
return fmt.Errorf("no users to upgrade found in cache")
}
users := usersCache.([]metav1.PartialObjectMetadata)
users := usersCache.([]iamv1alpha2.User)
adminUserCache, ok := u.PipelineCache.Get(common.CacheUpgradeAdminUser)
if !ok {
return fmt.Errorf("no admin user to upgrade found in cache")

View File

@@ -15,6 +15,7 @@ type upgrader interface {
UpgradeSystemComponents() []task.Interface
UpdateOlaresVersion() []task.Interface
PostUpgrade() []task.Interface
AddedBreakingChange() bool
}
type breakingUpgrader interface {

View File

@@ -5,26 +5,75 @@ import (
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/pkg/utils"
"github.com/beclab/Olares/cli/version"
"sort"
"strconv"
"strings"
)
type VersionSpec struct {
Version string `json:"version"`
Major uint64 `json:"major"`
Minor uint64 `json:"minor"`
Patch uint64 `json:"patch"`
ReleaseType string `json:"releaseType"`
ReleaseNum int `json:"releaseNum"`
PreRelease bool `json:"prerelease"`
AddedBreakingChange bool `json:"addedBreakingChange"`
MinimumUpgradableVersions MinimumVersionConstraints `json:"minimumUpgradableVersions"`
}
type VersionConstraints map[string]*semver.Version
type MinimumVersionConstraints VersionConstraints
func (c MinimumVersionConstraints) SatisfiedBy(base *semver.Version) (bool, error) {
if base == nil {
return false, nil
}
var minVersion *semver.Version
prerelease := base.Prerelease()
if prerelease == "" {
minVersion = c[releaseTypeStable]
} else {
prereleaseType, _, err := parsePrereleaseVersion(prerelease)
if err != nil {
return false, fmt.Errorf("invalid version '%s': %v", base, err)
}
minVersion = c[prereleaseType]
}
return minVersion != nil && minVersion.LessThanEqual(base), nil
}
type releaseLine string
var (
mainLine = releaseLine("main")
dailyLine = releaseLine("daily")
// the versions when current upgrade framework is introduced
minUpgradableStableVersion = semver.MustParse("1.12.0")
minUpgradableDailyVersion = semver.MustParse("1.12.0-0")
releaseTypeStable = "stable"
releaseTypeDaily = "daily"
releaseTypeRC = "rc"
releaseTypeBeta = "beta"
releaseTypeAlpha = "alpha"
prereleaseSep = "."
dailyUpgraders = []breakingUpgrader{
upgrader_1_12_0_20250702{},
upgrader_1_12_0_20250723{},
upgrader_1_12_0_20250730{},
upgrader_1_12_1_20250826{},
}
mainUpgraders = []breakingUpgrader{
upgrader_1_12_1{},
}
mainUpgraders = []breakingUpgrader{}
)
func getReleaseLineOfVersion(v *semver.Version) releaseLine {
preRelease := v.Prerelease()
mainLinePrereleasePrefixes := []string{"alpha", "beta", "rc"}
mainLinePrereleasePrefixes := []string{releaseTypeRC, releaseTypeBeta, releaseTypeAlpha}
if preRelease == "" {
return mainLine
}
@@ -36,114 +85,42 @@ func getReleaseLineOfVersion(v *semver.Version) releaseLine {
return dailyLine
}
func check(base *semver.Version, target *semver.Version) error {
func Check(base *semver.Version, target *semver.Version) error {
if base == nil {
return fmt.Errorf("base version is nil")
}
baseReleaseLine := getReleaseLineOfVersion(base)
cliVersion, err := utils.ParseOlaresVersionString(version.VERSION)
if err != nil {
return fmt.Errorf("invalid olares-cli version :\"%s\"", version.VERSION)
}
cliReleaseLine := getReleaseLineOfVersion(cliVersion)
if baseReleaseLine != cliReleaseLine {
return fmt.Errorf("incompatible base release line: %s and olares-cli release line: %s", baseReleaseLine, cliReleaseLine)
}
if target != nil {
if !target.GreaterThan(base) {
return fmt.Errorf("base version: %s, target version: %s, no need to upgrade", base, target)
}
targetReleaseLine := getReleaseLineOfVersion(target)
if targetReleaseLine != baseReleaseLine {
return fmt.Errorf("unable to upgrade to %s on %s release line from %s on %s release line", target, targetReleaseLine, base, baseReleaseLine)
}
switch targetReleaseLine {
case mainLine:
if !sameMajorLevelVersion(base, target) {
return fmt.Errorf("upgrade on %s rlease line can only be performed across same major level version", baseReleaseLine)
}
case dailyLine:
if !samePatchLevelVersion(base, target) {
return fmt.Errorf("upgrade on %s rlease line can only be performed across same patch version", baseReleaseLine)
}
}
if target.GreaterThan(cliVersion) {
return fmt.Errorf("target version: %s, cli version: %s, please upgrade olares-cli first!", target, cliVersion)
if !target.Equal(cliVersion) {
return fmt.Errorf("target version: %s is not the same with cli version: %s", target, cliVersion)
}
}
if base.GreaterThan(cliVersion) {
return fmt.Errorf("base version: %s, cli version: %s, please upgrade olares-cli first!", base, cliVersion)
currentVersionSpec, err := CurrentVersionSpec()
if err != nil {
return fmt.Errorf("failed to get current version's upgrade spec: %v", err)
}
satisfied, err := currentVersionSpec.MinimumUpgradableVersions.SatisfiedBy(base)
if err != nil {
return err
}
if !satisfied {
return fmt.Errorf("cannot upgrade to version '%s' from '%s': version constraints not satified: %v", target, base, currentVersionSpec.MinimumUpgradableVersions)
}
return nil
}
func GetUpgradePathFor(base *semver.Version, target *semver.Version) ([]*semver.Version, error) {
if err := check(base, target); err != nil {
return nil, err
}
var path []*semver.Version
var releaseLineUpgraders []breakingUpgrader
var versionFilter func(v *semver.Version) bool
switch getReleaseLineOfVersion(base) {
case mainLine:
releaseLineUpgraders = mainUpgraders
versionFilter = func(v *semver.Version) bool {
if !v.GreaterThan(base) {
return false
}
if !sameMajorLevelVersion(v, base) {
return false
}
if target != nil && !v.LessThan(target) {
return false
}
return true
}
case dailyLine:
if target == nil {
cliVersion, err := utils.ParseOlaresVersionString(version.VERSION)
if err != nil {
return path, fmt.Errorf("invalid olares-cli version :\"%s\"", version.VERSION)
}
if getReleaseLineOfVersion(cliVersion) == dailyLine && samePatchLevelVersion(cliVersion, base) && cliVersion.GreaterThan(base) {
target = cliVersion
}
}
releaseLineUpgraders = dailyUpgraders
versionFilter = func(v *semver.Version) bool {
if !v.GreaterThan(base) {
return false
}
if !samePatchLevelVersion(v, base) {
return false
}
if target != nil && !v.LessThan(target) {
return false
}
return true
}
}
for _, u := range releaseLineUpgraders {
v := u.Version()
if versionFilter(v) {
path = append(path, v)
}
}
if target != nil {
path = append(path, target)
}
return path, nil
}
func getUpgraderByVersion(target *semver.Version) upgrader {
for _, upgraders := range [][]breakingUpgrader{
dailyUpgraders,
@@ -159,10 +136,110 @@ func getUpgraderByVersion(target *semver.Version) upgrader {
return upgraderBase{}
}
func parsePrereleaseVersion(prereleaseVersion string) (string, int, error) {
if !strings.Contains(prereleaseVersion, prereleaseSep) {
n, err := strconv.Atoi(prereleaseVersion)
if err != nil {
return "", 0, fmt.Errorf("invalid prereleaseVersion: %s", prereleaseVersion)
}
return releaseTypeDaily, n, nil
}
parts := strings.Split(prereleaseVersion, prereleaseSep)
if len(parts) != 2 {
return "", 0, fmt.Errorf("invalid prereleaseVersion: %s", prereleaseVersion)
}
tStr, nStr := parts[0], parts[1]
if tStr != releaseTypeRC && tStr != releaseTypeBeta && tStr != releaseTypeAlpha {
return "", 0, fmt.Errorf("invalid prereleaseVersion: %s", prereleaseVersion)
}
n, err := strconv.Atoi(nStr)
if err != nil {
return "", 0, fmt.Errorf("invalid prereleaseVersion: %s", prereleaseVersion)
}
return tStr, n, nil
}
func formatPrereleaseVersion(releaseType string, releaseNum int) string {
if releaseType == releaseTypeDaily {
return strconv.Itoa(releaseNum)
}
return fmt.Sprintf("%s%s%s", releaseType, prereleaseSep, strconv.Itoa(releaseNum))
}
func CurrentVersionSpec() (spec *VersionSpec, err error) {
v, err := semver.NewVersion(version.VERSION)
if err != nil {
return nil, fmt.Errorf("current version '%s' is invalid: %v", version.VERSION, err)
}
spec = &VersionSpec{}
spec.Version, spec.Major, spec.Minor, spec.Patch = v.Original(), v.Major(), v.Minor(), v.Patch()
if v.Prerelease() != "" {
spec.PreRelease = true
spec.ReleaseType, spec.ReleaseNum, err = parsePrereleaseVersion(v.Prerelease())
if err != nil {
return nil, err
}
} else {
spec.ReleaseType = releaseTypeStable
}
u := getUpgraderByVersion(v)
spec.AddedBreakingChange = u.AddedBreakingChange()
if spec.ReleaseType == releaseTypeDaily {
lastBreakingVersion := getLastBreakingVersion(dailyUpgraders, v)
if lastBreakingVersion == nil {
lastBreakingVersion = minUpgradableDailyVersion
}
spec.MinimumUpgradableVersions = MinimumVersionConstraints{releaseTypeDaily: lastBreakingVersion}
} else {
lastBreakingVersion := getLastBreakingVersion(mainUpgraders, v)
if lastBreakingVersion == nil {
lastBreakingVersion = minUpgradableStableVersion
}
// all mainline release types support upgrade from stable release
spec.MinimumUpgradableVersions = MinimumVersionConstraints{
releaseTypeStable: semver.New(lastBreakingVersion.Major(), lastBreakingVersion.Minor(), lastBreakingVersion.Patch(), "", ""),
}
switch spec.ReleaseType {
// both stable and rc release types support upgrade from stable/rc release
case releaseTypeStable, releaseTypeRC:
spec.MinimumUpgradableVersions[releaseTypeRC] = semver.New(lastBreakingVersion.Major(), lastBreakingVersion.Minor(), lastBreakingVersion.Patch(), formatPrereleaseVersion(releaseTypeRC, 0), "")
case releaseTypeAlpha:
// alpha release type supports upgrade from the last alpha release
// if it exists
// and no breaking change is added to the current version
if !spec.AddedBreakingChange && spec.ReleaseNum > 0 {
spec.MinimumUpgradableVersions[releaseTypeAlpha] = semver.New(spec.Major, spec.Minor, spec.Patch, formatPrereleaseVersion(releaseTypeAlpha, spec.ReleaseNum-1), "")
}
}
}
return spec, nil
}
func getLastBreakingVersion(upgraders []breakingUpgrader, current *semver.Version) *semver.Version {
sort.Slice(upgraders, func(i, j int) bool {
return upgraders[i].Version().LessThan(upgraders[j].Version())
})
for i := len(upgraders) - 1; i >= 0; i-- {
if !upgraders[i].AddedBreakingChange() {
continue
}
if upgraders[i].Version().GreaterThanEqual(current) {
continue
}
return upgraders[i].Version()
}
return nil
}
func samePatchLevelVersion(a, b *semver.Version) bool {
return a.Major() == b.Major() && a.Minor() == b.Minor() && a.Patch() == b.Patch()
}
func sameMinorLevelVersion(a, b *semver.Version) bool {
return a.Major() == b.Major() && a.Minor() == b.Minor()
}
func sameMajorLevelVersion(a, b *semver.Version) bool {
return a.Major() == b.Major()
}

View File

@@ -77,7 +77,7 @@ type CheckJWSResult struct {
}
// resolveDID resolves a DID either from cache or from the DID gate
func resolveDID(olares_id string) (*didcore.ResolutionResult, error) {
func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
name := strings.Replace(olares_id, "@", ".", -1)
// Try to get from cache first
cached, err := db.Get([]byte(name), nil)
@@ -184,18 +184,18 @@ func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) {
}
// Resolve DID
resolutionResult, err := resolveDID(name)
resolutionResult, err := ResolveOlaresName(name)
if err != nil {
return nil, fmt.Errorf("failed to resolve DID: %w", err)
}
// Verify DID matches
if resolutionResult.Document.ID != kid {
sid := resolutionResult.Document.ID + resolutionResult.Document.VerificationMethod[0].ID
if sid != kid {
return nil, fmt.Errorf("DID does not match: expected %s, got % s", sid, kid)
}
}
sid := resolutionResult.Document.ID + resolutionResult.Document.VerificationMethod[0].ID
if sid != kid {
return nil, fmt.Errorf("DID does not match: expected %s, got % s", sid, kid)
}
}
// Get verification method
if len(resolutionResult.Document.VerificationMethod) == 0 || resolutionResult.Document.VerificationMethod[0].PublicKeyJwk == nil {
return nil, fmt.Errorf("invalid DID document: missing verification method")

View File

@@ -29,7 +29,15 @@ builds:
{{- end }}
dist: output
archives:
- name_template: "olaresd-v{{ .Version }}-{{ .Os }}-{{ .Arch }}"
- id: without-release-id
name_template: "{{ .ProjectName }}-v{{ .Version }}-{{ .Os }}-{{ .Arch }}"
- id: with-release-id
name_template: >-
{{- if index .Env "OLARES_RELEASE_ID" }}
{{- .ProjectName }}-v{{ .Version }}-{{ .Os }}-{{ .Arch }}.{{ .Env.OLARES_RELEASE_ID }}
{{- else }}
{{- .ProjectName }}-v{{ .Version }}-{{ .Os }}-{{ .Arch }}.no-release-id
{{- end }}
files:
- none*
checksum:

View File

@@ -4,6 +4,6 @@ output:
binaries:
-
id: olaresd
name: olaresd-v#__VERSION__.tar.gz
amd64: https://dc3p1870nn3cj.cloudfront.net#__REPO_PATH__olaresd-v#__VERSION__-linux-amd64.tar.gz
arm64: https://dc3p1870nn3cj.cloudfront.net#__REPO_PATH__olaresd-v#__VERSION__-linux-arm64.tar.gz
name: olaresd-v#__VERSION__#__RELEASE_ID_SUFFIX__.tar.gz
amd64: https://dc3p1870nn3cj.cloudfront.net#__REPO_PATH__olaresd-v#__VERSION__-linux-amd64#__RELEASE_ID_SUFFIX__.tar.gz
arm64: https://dc3p1870nn3cj.cloudfront.net#__REPO_PATH__olaresd-v#__VERSION__-linux-arm64#__RELEASE_ID_SUFFIX__.tar.gz

View File

@@ -18,15 +18,15 @@ replace (
require (
bytetrade.io/web3os/app-service v0.0.0-00010101000000-000000000000
bytetrade.io/web3os/bfl v0.0.0-00010101000000-000000000000
github.com/Masterminds/semver/v3 v3.3.0
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-20250715142112-cd6c89f724b5
github.com/containerd/containerd v1.7.27
github.com/beclab/Olares/cli v0.0.0-20250827065743-34318ee3039b
github.com/containerd/containerd v1.7.28
github.com/distribution/distribution/v3 v3.0.0
github.com/dustin/go-humanize v1.0.1
github.com/eball/zeroconf v0.2.1
github.com/godbus/dbus/v5 v5.1.0
github.com/gofiber/fiber/v2 v2.52.5
github.com/gofiber/fiber/v2 v2.52.9
github.com/hirochachacha/go-smb2 v1.1.0
github.com/jaypipes/ghw v0.13.0
github.com/jochenvg/go-udev v0.0.0-20171110120927-d6b62d56d37b
@@ -41,15 +41,15 @@ require (
github.com/pkg/errors v0.9.1
github.com/rubiojr/go-usbmon v0.0.0-20240513072523-d5cbf336b315
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/shirou/gopsutil/v4 v4.25.2
github.com/shirou/gopsutil/v4 v4.25.7
github.com/sirupsen/logrus v1.9.3
github.com/spf13/pflag v1.0.6
github.com/txn2/txeh v1.5.5
go.opentelemetry.io/otel/trace v1.33.0
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
golang.org/x/sys v0.33.0
k8s.io/api v0.33.0
k8s.io/apimachinery v0.33.0
golang.org/x/sys v0.34.0
k8s.io/api v0.33.3
k8s.io/apimachinery v0.33.3
k8s.io/client-go v12.0.0+incompatible
k8s.io/cri-api v0.31.0
k8s.io/cri-client v0.31.0
@@ -67,7 +67,7 @@ require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.11.7 // indirect
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
@@ -83,7 +83,7 @@ require (
github.com/containerd/ttrpc v1.2.7 // indirect
github.com/containerd/typeurl/v2 v2.1.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/ebitengine/purego v0.8.4 // indirect
@@ -151,8 +151,8 @@ require (
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tinygo-org/cbgo v0.0.4 // indirect
github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/tklauser/go-sysconf v0.3.15 // indirect
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.51.0 // indirect
github.com/valyala/tcplisten v1.0.0 // indirect
@@ -168,31 +168,32 @@ require (
go.opentelemetry.io/otel/metric v1.33.0 // indirect
go.opentelemetry.io/otel/sdk v1.33.0 // indirect
go.opentelemetry.io/proto/otlp v1.4.0 // indirect
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.28.0 // indirect
golang.org/x/sync v0.14.0 // indirect
golang.org/x/term v0.31.0 // indirect
golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.9.0 // indirect
golang.org/x/tools v0.26.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/mod v0.26.0 // indirect
golang.org/x/net v0.42.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/term v0.33.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.34.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect
google.golang.org/grpc v1.68.1 // indirect
google.golang.org/protobuf v1.36.5 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
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.33.0 // indirect
k8s.io/apiserver v0.33.0 // indirect
k8s.io/component-base v0.33.0 // indirect
k8s.io/apiextensions-apiserver v0.33.2 // indirect
k8s.io/apiserver v0.33.2 // indirect
k8s.io/component-base v0.33.3 // indirect
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/randfill v1.0.0 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
sigs.k8s.io/yaml v1.5.0 // indirect
)

View File

@@ -6,8 +6,8 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59MxjQVfjXsBpLy+dbd2/ELV5ofnUkUZBvWSC85sheA=
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ=
@@ -18,14 +18,14 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
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-20250715142112-cd6c89f724b5 h1:1wWOAV6O3D4cFaGCB3I0YTFjzYYWPj8FjnIVCvmNVZc=
github.com/beclab/Olares/cli v0.0.0-20250715142112-cd6c89f724b5/go.mod h1:fJ/f0348rB+ssDIvsaPh0tPQmdFbtwY4R0qkfQuGXw0=
github.com/beclab/Olares/cli v0.0.0-20250827065743-34318ee3039b h1:zCRpC1/9EsHWR1k0SXgdbThorTGlM9FV8vYi3KyE5fg=
github.com/beclab/Olares/cli v0.0.0-20250827065743-34318ee3039b/go.mod h1:KYFBcl+UK9UvKnclBqZsqlQVjXz3NWs/Dyver1GksPw=
github.com/beclab/app-service v0.2.33 h1:fsv9sTL7guTdU8z8sO5KIxxd1N5K+Rp4zORRebs+wmI=
github.com/beclab/app-service v0.2.33/go.mod h1:Gpp5e2XPU/nHufT7ZBsRMZrYxpFbI6R4AEiKine+RhI=
github.com/beclab/bfl v0.3.36 h1:PgeSPGc+XoONiwFsKq9xX8rqcL4kVM1G/ut0lYYj/js=
@@ -45,8 +45,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII=
github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0=
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c=
github.com/containerd/containerd v1.7.28/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=
@@ -67,10 +67,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
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=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y=
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8=
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/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=
@@ -124,8 +124,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
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.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -311,8 +311,8 @@ github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b h1:du3zG5fd8
github.com/saltosystems/winrt-go v0.0.0-20240509164145-4f7860a3bd2b/go.mod h1:CIltaIm7qaANUIvzr0Vmz71lmQMAIbGJ7cvgzX7FMfA=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v4 v4.25.2 h1:NMscG3l2CqtWFS86kj3vP7soOczqrQYIEhO/pMvvQkk=
github.com/shirou/gopsutil/v4 v4.25.2/go.mod h1:34gBYJzyqCDT11b6bMHP0XCvWeU3J61XRT7a2EmCRTA=
github.com/shirou/gopsutil/v4 v4.25.7 h1:bNb2JuqKuAu3tRlPv5piSmBZyMfecwQ+t/ILq+1JqVM=
github.com/shirou/gopsutil/v4 v4.25.7/go.mod h1:XV/egmwJtd3ZQjBpJVY5kndsiOO4IRqy9TQnmm6VP7U=
github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -339,10 +339,10 @@ github.com/tinygo-org/cbgo v0.0.4 h1:3D76CRYbH03Rudi8sEgs/YO0x3JIMdyq8jlQtk/44fU
github.com/tinygo-org/cbgo v0.0.4/go.mod h1:7+HgWIHd4nbAz0ESjGlJ1/v9LDU1Ox8MGzP9mah/fLk=
github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899 h1:/DyaXDEWMqoVUVEJVJIlNk1bXTbFs8s3Q4GdPInSKTQ=
github.com/tinygo-org/pio v0.0.0-20231216154340-cd888eb58899/go.mod h1:LU7Dw00NJ+N86QkeTGjMLNkYcEYMor6wTDpTCu0EaH8=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
github.com/txn2/txeh v1.5.5 h1:UN4e/lCK5HGw/gGAi2GCVrNKg0GTCUWs7gs5riaZlz4=
github.com/txn2/txeh v1.5.5/go.mod h1:qYzGG9kCzeVEI12geK4IlanHWY8X4uy/I3NcW7mk8g4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
@@ -385,12 +385,16 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
@@ -401,8 +405,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.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
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=
@@ -415,19 +419,19 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
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=
@@ -446,20 +450,18 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
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=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -469,8 +471,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
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=
@@ -506,8 +508,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@@ -530,16 +532,16 @@ howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
k8s.io/api v0.31.0 h1:b9LiSjR2ym/SzTOlfMHm1tr7/21aD7fSkqgD/CVJBCo=
k8s.io/api v0.31.0/go.mod h1:0YiFF+JfFxMM6+1hQei8FY8M7s1Mth+z/q7eF1aJkTE=
k8s.io/apiextensions-apiserver v0.33.0 h1:d2qpYL7Mngbsc1taA4IjJPRJ9ilnsXIrndH+r9IimOs=
k8s.io/apiextensions-apiserver v0.33.0/go.mod h1:VeJ8u9dEEN+tbETo+lFkwaaZPg6uFKLGj5vyNEwwSzc=
k8s.io/apiextensions-apiserver v0.33.2 h1:6gnkIbngnaUflR3XwE1mCefN3YS8yTD631JXQhsU6M8=
k8s.io/apiextensions-apiserver v0.33.2/go.mod h1:IvVanieYsEHJImTKXGP6XCOjTwv2LUMos0YWc9O+QP8=
k8s.io/apimachinery v0.31.0 h1:m9jOiSr3FoSSL5WO9bjm1n6B9KROYYgNZOb4tyZ1lBc=
k8s.io/apimachinery v0.31.0/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
k8s.io/apiserver v0.33.0 h1:QqcM6c+qEEjkOODHppFXRiw/cE2zP85704YrQ9YaBbc=
k8s.io/apiserver v0.33.0/go.mod h1:EixYOit0YTxt8zrO2kBU7ixAtxFce9gKGq367nFmqI8=
k8s.io/apiserver v0.33.2 h1:KGTRbxn2wJagJowo29kKBp4TchpO1DRO3g+dB/KOJN4=
k8s.io/apiserver v0.33.2/go.mod h1:9qday04wEAMLPWWo9AwqCZSiIn3OYSZacDyu/AcoM/M=
k8s.io/client-go v0.31.0 h1:QqEJzNjbN2Yv1H79SsS+SWnXkBgVu4Pj3CJQgbx0gI8=
k8s.io/client-go v0.31.0/go.mod h1:Y9wvC76g4fLjmU0BA+rV+h2cncoadjvjjkkIGoTLcGU=
k8s.io/component-base v0.33.0 h1:Ot4PyJI+0JAD9covDhwLp9UNkUja209OzsJ4FzScBNk=
k8s.io/component-base v0.33.0/go.mod h1:aXYZLbw3kihdkOPMDhWbjGCO6sg+luw554KP51t8qCU=
k8s.io/component-base v0.33.3 h1:mlAuyJqyPlKZM7FyaoM/LcunZaaY353RXiOd2+B5tGA=
k8s.io/component-base v0.33.3/go.mod h1:ktBVsBzkI3imDuxYXmVxZ2zxJnYTZ4HAsVj9iF09qp4=
k8s.io/cri-api v0.31.0 h1:6o0XrhWlc1/zseGCh+aMScdXCg5nT6KCGdyx7HQkSKo=
k8s.io/cri-api v0.31.0/go.mod h1:Po3TMAYH/+KrZabi7QiwQI4a692oZcUOUThd/rqwxrI=
k8s.io/cri-client v0.31.0 h1:lu+Fq1h9GYIJO0PiWX1tH5KEhbD4H52grWss4CVMlqc=
@@ -561,7 +563,8 @@ sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=
tinygo.org/x/bluetooth v0.10.0 h1:42n8qj2tuF5AfdbAUR2Nv45EhtVmbDFH6UoWnt6lzZQ=
tinygo.org/x/bluetooth v0.10.0/go.mod h1:t/Vm2a/rslsBoqFQKCBsWQw/cmRicQq+8Tl3tj5RCRI=

View File

@@ -0,0 +1,63 @@
package handlers
import (
"github.com/beclab/Olares/cli/pkg/web5/jws"
"github.com/gofiber/fiber/v2"
"k8s.io/klog/v2"
)
func (h *Handlers) ResolveOlaresName(c *fiber.Ctx) error {
olaresName := c.Params("olaresName")
if olaresName == "" {
klog.Error("olaresName parameter is missing")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "olaresName parameter is required",
})
}
klog.Infof("Received olaresName: %s", olaresName)
result, err := jws.ResolveOlaresName(olaresName)
if err != nil {
klog.Errorf("Failed to resolve DID for %s: %v", olaresName, err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"error": "Failed to resolve DID",
})
}
return c.Status(fiber.StatusOK).JSON(result)
}
func (h *Handlers) CheckJWS(c *fiber.Ctx) error {
// Get JWS from request body
// Parse request body
var body struct {
JWS string `json:"jws"`
Duration int64 `json:"duration"` // in milliseconds
}
if err := c.BodyParser(&body); err != nil {
klog.Errorf("Failed to parse request body: %v", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid request body format",
})
}
if body.JWS == "" {
klog.Error("JWS is missing in request body")
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "JWS is required in request body",
})
}
if body.Duration == 0 {
body.Duration = int64(3 * 60 * 1000) // 3 minutes in milliseconds
}
result, err := jws.CheckJWS(body.JWS, body.Duration)
if err != nil {
klog.Errorf("Failed to check JWS: %v", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"error": "Invalid JWS",
})
}
return c.Status(fiber.StatusOK).JSON(result)
}

View File

@@ -20,6 +20,8 @@ func init() {
system.Get("/mounted-hdd-incluster", handlers.RequireLocal(handlers.GetMountedHddInCluster))
system.Get("/mounted-smb-incluster", handlers.RequireLocal(handlers.GetMountedSmbInCluster))
system.Get("/mounted-path-incluster", handlers.RequireLocal(handlers.GetMountedPathInCluster))
system.Get("/1.0/name/:olaresName", handlers.RequireLocal(handlers.ResolveOlaresName))
system.Post("/checkjws", handlers.RequireLocal(handlers.CheckJWS))
klog.V(8).Info("system handlers initialized")
}

View File

@@ -67,7 +67,7 @@ func (u *userCertWatcher) Watch(ctx context.Context) {
}
// Check if the certificate will expire within 10 days
if expiredTime.Before(time.Now().Add(10 * 24 * time.Hour)) {
if expiredTime.Before(time.Now().Add(5 * 24 * time.Hour)) {
klog.Info("user cert expired, ", user.GetName())
err = createOrUpdateJob(ctx, kubeClient, namespace)
if err != nil {
@@ -90,14 +90,16 @@ func createOrUpdateJob(ctx context.Context, kubeClient kubernetes.Interface, nam
}
} else {
// check the existing job
if currentJob.Status.Succeeded == 0 || currentJob.Status.Failed > 0 {
if currentJob.Status.Active > 0 {
klog.Info("job is still running, skip creating a new one")
return nil
}
// If the job exists and has completed, delete it before creating a new one
klog.Info("delete existing job: ", currentJob.Name)
err = kubeClient.BatchV1().Jobs(namespace).Delete(ctx, currentJob.Name, metav1.DeleteOptions{})
err = kubeClient.BatchV1().Jobs(namespace).
Delete(ctx, currentJob.Name,
metav1.DeleteOptions{PropagationPolicy: ptr.To(metav1.DeletePropagationBackground)})
if err != nil {
return fmt.Errorf("failed to delete job: %w", err)
}
@@ -131,7 +133,7 @@ var jobDownloadUserCert = batchv1.Job{
"--header",
"X-FROM-CRONJOB: true",
"-qSO -",
"http://bfl.user-space-pengpeng9/bfl/backend/v1/re-download-cert",
"http://bfl/bfl/backend/v1/re-download-cert",
},
},
},

View File

@@ -199,8 +199,7 @@ var downloadPhases = []upgradePhase{
}
var upgradePhases = []upgradePhase{
{upgrade.NewVersionCompatibilityCheck, 0, 5},
{upgrade.NewPreCheck, 5, 5},
{upgrade.NewPreCheck, 0, 10},
{upgrade.NewInstallCLI, 10, 10},
{upgrade.NewInstallOlaresd, 20, 10},
{upgrade.NewImportImages, 30, 30},

View File

@@ -78,6 +78,8 @@ type state struct {
FRPEnable string `json:"frpEnable"`
ContainerMode *string `json:"containerMode,omitempty"`
Pressure []utils.NodePressure `json:"pressures,omitempty"`
}
var CurrentState state
@@ -340,6 +342,18 @@ func CheckCurrentStatus(ctx context.Context) error {
return err
}
pressure, err := utils.GetNodesPressure(ctx, kubeClient)
if err != nil {
klog.Error("get nodes pressure error, ", err)
} else {
// update node pressure of current node
if p, ok := pressure[*CurrentState.HostName]; ok && len(p) == 0 {
CurrentState.Pressure = p
} else {
CurrentState.Pressure = nil
}
}
if CurrentState.InstallFinishedTime != nil {
CurrentState.InstalledTime = pointer.Int64(CurrentState.InstallFinishedTime.Unix())
} else {

View File

@@ -5,12 +5,13 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/Masterminds/semver/v3"
"os"
"os/exec"
"strconv"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/daemon/pkg/cli"
"github.com/beclab/Olares/daemon/pkg/commands"
"github.com/beclab/Olares/daemon/pkg/utils"
@@ -182,7 +183,7 @@ func (t *UpgradeTarget) IsValidRequest() error {
if CurrentState.TerminusVersion != nil {
current, err := semver.NewVersion(*CurrentState.TerminusVersion)
if err != nil {
return fmt.Errorf("invalid current version %s: %v", CurrentState.TerminusVersion, err)
return fmt.Errorf("invalid current version %s: %v", *CurrentState.TerminusVersion, err)
}
if !current.LessThan(&t.Version) {
return fmt.Errorf("target version should be greater than current version: %s", current)

View File

@@ -13,30 +13,29 @@ import (
type Operations string
const (
Install Operations = "install"
Initialize Operations = "initialize"
ChangeIp Operations = "changeIp"
Uninstall Operations = "uninstall"
CreateUpgradeTarget Operations = "createUpgradeTarget"
RemoveUpgradeTarget Operations = "removeUpgradeTarget"
DownloadCLI Operations = "downloadCLI"
DownloadWizard Operations = "downloadWizard"
VersionCompatibilityCheck Operations = "versionCompatibilityCheck"
UpgradePreCheck Operations = "PreCheck"
DownloadSpaceCheck Operations = "downloadSpaceCheck"
DownloadComponent Operations = "downloadComponent"
ImportImages Operations = "importImages"
InstallOlaresd Operations = "installOlaresd"
Upgrade Operations = "upgrade"
InstallCLI Operations = "installCLI"
Reboot Operations = "reboot"
Shutdown Operations = "shutdown"
ConnectWifi Operations = "connectWifi"
ChangeHost Operations = "changeHost"
UmountUsb Operations = "umountUsb"
CollectLogs Operations = "collectLogs"
MountSmb Operations = "mountSmb"
UmountSmb Operations = "umountSmb"
Install Operations = "install"
Initialize Operations = "initialize"
ChangeIp Operations = "changeIp"
Uninstall Operations = "uninstall"
CreateUpgradeTarget Operations = "createUpgradeTarget"
RemoveUpgradeTarget Operations = "removeUpgradeTarget"
DownloadCLI Operations = "downloadCLI"
DownloadWizard Operations = "downloadWizard"
UpgradePreCheck Operations = "PreCheck"
DownloadSpaceCheck Operations = "downloadSpaceCheck"
DownloadComponent Operations = "downloadComponent"
ImportImages Operations = "importImages"
InstallOlaresd Operations = "installOlaresd"
Upgrade Operations = "upgrade"
InstallCLI Operations = "installCLI"
Reboot Operations = "reboot"
Shutdown Operations = "shutdown"
ConnectWifi Operations = "connectWifi"
ChangeHost Operations = "changeHost"
UmountUsb Operations = "umountUsb"
CollectLogs Operations = "collectLogs"
MountSmb Operations = "mountSmb"
UmountSmb Operations = "umountSmb"
)
func (p Operations) Stirng() string {

View File

@@ -14,74 +14,13 @@ import (
"runtime"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/daemon/pkg/commands"
"github.com/beclab/Olares/daemon/pkg/utils"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/klog/v2"
)
type versionCompatibilityCheck struct {
commands.Operation
}
var _ commands.Interface = &versionCompatibilityCheck{}
func NewVersionCompatibilityCheck() commands.Interface {
return &versionCompatibilityCheck{
Operation: commands.Operation{
Name: commands.VersionCompatibilityCheck,
},
}
}
func (i *versionCompatibilityCheck) Execute(ctx context.Context, p any) (res any, err error) {
target, ok := p.(state.UpgradeTarget)
if !ok {
err = errors.New("invalid param")
return
}
dynamicClient, err := utils.GetDynamicClient()
if err != nil {
return nil, fmt.Errorf("error getting kubernetes client: %v", err)
}
olaresVersion, err := utils.GetTerminusVersion(ctx, dynamicClient)
if err != nil {
return nil, fmt.Errorf("error getting olares version: %v", err)
}
currentVersion, err := semver.NewVersion(*olaresVersion)
if err != nil {
return nil, fmt.Errorf("error parsing current olares version %s: %v", *olaresVersion, err)
}
versionHintFile := filepath.Join(commands.TERMINUS_BASE_DIR, "versions", "v"+target.Version.Original(), "version.hint")
content, err := os.ReadFile(versionHintFile)
if err != nil {
return nil, fmt.Errorf("error reading version hint file %s: %v", versionHintFile, err)
}
versionHint := make(map[string]map[string]string)
if err := yaml.Unmarshal(content, &versionHint); err != nil {
return nil, fmt.Errorf("error parsing version hint file %s: %v", versionHintFile, err)
}
upgradeField, ok := versionHint["upgrade"]
if !ok {
return nil, fmt.Errorf("no upgrade field found in version hint file %s, content: %s", versionHintFile, content)
}
minVersionStr, ok := upgradeField["minVersion"]
if !ok || minVersionStr == "" {
return nil, fmt.Errorf("no minVersion field found in version hint file %s, content: %s", versionHintFile, content)
}
minVersion, err := semver.NewVersion(minVersionStr)
if err != nil {
return nil, fmt.Errorf("error parsing minVersion: %s in version hint file %s: %v", minVersionStr, versionHintFile, err)
}
if currentVersion.LessThan(minVersion) {
return nil, fmt.Errorf("minVersion %s is greater than current version %s", minVersionStr, *olaresVersion)
}
return newExecutionRes(true, nil), nil
}
type preCheck struct {
commands.Operation
}

View File

@@ -5,6 +5,8 @@ package utils
import (
"fmt"
"io"
"log"
"strings"
"github.com/jaypipes/ghw"
@@ -13,7 +15,7 @@ import (
)
func GetGpuInfo() (*string, error) {
gpu, err := ghw.GPU()
gpu, err := ghw.GPU(ghw.WithAlerter(log.New(io.Discard, "", 0))) // discard warnings
if err != nil {
klog.Errorf("Error getting GPU info: %v", err)
return nil, err

View File

@@ -140,6 +140,11 @@ func IsIpChanged(ctx context.Context, installed bool) (bool, error) {
return false, err
}
masterIpFromETCD, err := MasterNodeIp(installed)
if err != nil {
return false, err
}
for _, ip := range ips {
hostIps, err := nets.LookupHostIps()
if err != nil {
@@ -148,10 +153,19 @@ func IsIpChanged(ctx context.Context, installed bool) (bool, error) {
for _, hostIp := range hostIps {
if hostIp == ip.IP {
klog.V(8).Info("host ip is the same as internal ip of interface, ", hostIp, ", ", ip.IP)
if !installed {
// terminus not installed
return false, nil
if masterIpFromETCD == "" {
return false, nil
}
if masterIpFromETCD == ip.IP {
return false, nil
}
return true, nil
}
kubeClient, err := GetKubeClient()
@@ -162,8 +176,18 @@ func IsIpChanged(ctx context.Context, installed bool) (bool, error) {
_, nodeIp, nodeRole, err := GetThisNodeName(ctx, kubeClient)
if err != nil {
klog.Error("get this node name error, ", err)
return false, nil
klog.Warning("get this node name error, ", err, ", try to compare with etcd ip")
if masterIpFromETCD == "" {
klog.Info("master node ip not found, mybe it's a worker node")
return false, nil
}
if masterIpFromETCD == ip.IP {
return false, nil
}
klog.Info("master node ip from etcd is not the same as internal ip of interface, ", masterIpFromETCD, ", ", hostIp, ", ", ip.IP)
return true, nil
}
@@ -176,12 +200,13 @@ func IsIpChanged(ctx context.Context, installed bool) (bool, error) {
return false, nil
}
klog.Info("get node ip, ", nodeIp, ", ", hostIp, ", ", ip.IP)
klog.Info("node is master and node ip is not the same as internal ip of interface, ", nodeIp, ", ", hostIp, ", ", ip.IP)
return true, nil
}
}
}
} // end for host ips
} // end for interface ips
klog.Info("no host ip is the same as internal ip of interface, ", ips)
return true, nil
}
@@ -491,3 +516,22 @@ func GetUserspacePvcHostPath(ctx context.Context, user string, client kubernetes
return hostpath, nil
}
func GetNodesPressure(ctx context.Context, client kubernetes.Interface) (map[string][]NodePressure, error) {
nodes, err := client.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
if err != nil {
klog.Error("list nodes error, ", err)
return nil, err
}
status := make(map[string][]NodePressure)
for _, node := range nodes.Items {
for _, condition := range node.Status.Conditions {
if condition.Type != corev1.NodeReady && condition.Status == corev1.ConditionTrue {
status[node.Name] = append(status[node.Name], NodePressure{Type: condition.Type, Message: condition.Message})
}
}
}
return status, nil
}

View File

@@ -1,6 +1,9 @@
package utils
import "k8s.io/apimachinery/pkg/runtime/schema"
import (
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
)
var (
UserSchemeGroupVersion = schema.GroupVersion{Group: "iam.kubesphere.io", Version: "v1alpha2"}
@@ -11,3 +14,8 @@ var (
Resource: "users",
}
)
type NodePressure struct {
Type corev1.NodeConditionType `json:"type"`
Message string `json:"message"`
}

View File

@@ -68,14 +68,13 @@ const side = {
{text: "Manage Olares", link:"/manual/larepass/manage-olares"},
],
},
{
text: "Manage files",
collapsed: true,
items: [
{text: "Common file operations", link:"/manual/larepass/manage-files"},
{text: "Sync and share", link:"/manual/larepass/sync-share"}
]
},
{text: "Manage files", link:"/manual/larepass/manage-files"},
// collapsed: true,
//items: [
// {text: "Common file operations", link:"/manual/larepass/manage-files"},
// {text: "Sync and share", link:"/manual/larepass/sync-share"}
// ]
// },
{
text: "Manage passwords",
collapsed: true,
@@ -106,17 +105,17 @@ const side = {
text: "Basic file operations",
link: "/manual/olares/files/add-edit-download",
},
{
text: "Sync and share",
link: "/manual/larepass/sync-share",
},
// {
// text: "Sync and share",
// link: "/manual/larepass/sync-share",
// },
{
text: "Mount SMB",
link: "/manual/olares/files/mount-SMB",
},
{text: "Mount cloud storage",
link: "/manual/olares/files/mount-cloud-storage",
},
// {text: "Mount cloud storage",
// link: "/manual/olares/files/mount-cloud-storage",
// },
],
},
{
@@ -512,47 +511,47 @@ const side = {
text: "Olares versioning",
link: "/developer/install/versioning",
},
],
},
// {
// text: "Additional installations",
// link: "/developer/install/additional-installations",
// collapsed: true,
// items: [
// { text: "Linux (via Docker)", link: "/developer/install/linux-via-docker-compose"},
// {
// text: "macOS",
// collapsed: true,
// items: [
// {
// text: "Using the script (recommended)",
// link: "/developer/install/mac",
// },
// {
// text: "Using Docker image",
// link: "/developer/install/mac-via-docker-image",
// },
// ],
// },
// {
// text: "Windows (WSL 2)",
// collapsed: true,
// items: [
// {
// text: "Using the script (recommended)",
// link: "/developer/install/windows",
// },
// {
// text: "Using Docker image",
// link: "/developer/install/windows-via-docker-image",
// },
// ],
// },
// { text: "PVE", link: "/developer/install/pve" },
// { text: "LXC", link: "/developer/install/lxc" },
// { text: "Raspberry Pi", link: "/developer/install/raspberry-pi" },
// ],
// },
{
text: "Additional installations",
link: "/developer/install/additional-installations",
collapsed: true,
items: [
{ text: "Linux (via Docker)", link: "/developer/install/linux-via-docker-compose"},
{
text: "macOS",
collapsed: true,
items: [
{
text: "Using the script (recommended)",
link: "/developer/install/mac",
},
{
text: "Using Docker image",
link: "/developer/install/mac-via-docker-image",
},
],
},
{
text: "Windows (WSL 2)",
collapsed: true,
items: [
{
text: "Using the script (recommended)",
link: "/developer/install/windows",
},
{
text: "Using Docker image",
link: "/developer/install/windows-via-docker-image",
},
],
},
{ text: "PVE", link: "/developer/install/pve" },
{ text: "LXC", link: "/developer/install/lxc" },
{ text: "Raspberry Pi", link: "/developer/install/raspberry-pi" },
],
},
],
},
{
text: "Develop Olares app",
link: "/developer/develop/",

View File

@@ -70,14 +70,13 @@ const side = {
{text: "管理 Olares", link:"/zh/manual/larepass/manage-olares"},
],
},
{
text: "管理文件",
collapsed: true,
items: [
{text: "常用文件操作", link:"/zh/manual/larepass/manage-files"},
{text: "同步与共享", link:"/zh/manual/larepass/sync-share"}
]
},
{text: "管理文件", link:"/zh/manual/larepass/manage-files"},
// collapsed: true,
// items: [
// {text: "常用文件操作", link:"/zh/manual/larepass/manage-files"},
// {text: "同步与共享", link:"/zh/manual/larepass/sync-share"}
// ]
// },
{
text: "管理密码",
collapsed: true,
@@ -108,18 +107,18 @@ const side = {
"text": "基本文件操作",
"link": "/zh/manual/olares/files/add-edit-download"
},
{
"text": "同步与共享",
"link": "/zh/manual/larepass/sync-share"
},
//{
// "text": "同步与共享",
// "link": "/zh/manual/larepass/sync-share"
// },
{
"text": "挂载 SMB",
"link": "/zh/manual/olares/files/mount-SMB"
},
{
"text": "挂载云存储",
"link": "/zh/manual/olares/files/mount-cloud-storage"
}
// {
// "text": "挂载云存储",
// "link": "/zh/manual/olares/files/mount-cloud-storage"
// }
]
},
{
@@ -518,45 +517,45 @@ const side = {
text: "版本说明",
link: "/zh/developer/install/versioning",
},
// {
// text: "其他安装方式",
// link: "/zh/developer/install/additional-installations",
// collapsed: true,
// items: [
// { text: "LinuxDocker 镜像)", link: "/zh/developer/install/linux-via-docker-compose" },
// {
// text: "macOS",
// collapsed: true,
// items: [
// {
// text: "使用脚本(推荐)",
// link: "/zh/developer/install/mac",
// },
// {
// text: "使用 Docker 镜像",
// link: "/zh/developer/install/mac-via-docker-image",
// },
// ],
// },
// {
// text: "Windows (WSL 2)",
// collapsed: true,
// items: [
// {
// text: "使用脚本(推荐)",
// link: "/zh/developer/install/windows",
// },
// {
// text: "使用 Docker 镜像",
// link: "/zh/developer/install/windows-via-docker-image",
// },
// ],
// },
// { text: "PVE", link: "/zh/developer/install/pve" },
// { text: "LXC", link: "/zh/developer/install/lxc" },
// { text: "树莓派", link: "/zh/developer/install/raspberry-pi" },
// ],
// },
{
text: "其他安装方式",
link: "/zh/developer/install/additional-installations",
collapsed: true,
items: [
{ text: "LinuxDocker 镜像)", link: "/zh/developer/install/linux-via-docker-compose" },
{
text: "macOS",
collapsed: true,
items: [
{
text: "使用脚本(推荐)",
link: "/zh/developer/install/mac",
},
{
text: "使用 Docker 镜像",
link: "/zh/developer/install/mac-via-docker-image",
},
],
},
{
text: "Windows (WSL 2)",
collapsed: true,
items: [
{
text: "使用脚本(推荐)",
link: "/zh/developer/install/windows",
},
{
text: "使用 Docker 镜像",
link: "/zh/developer/install/windows-via-docker-image",
},
],
},
{ text: "PVE", link: "/zh/developer/install/pve" },
{ text: "LXC", link: "/zh/developer/install/lxc" },
{ text: "树莓派", link: "/zh/developer/install/raspberry-pi" },
],
},
],
},
{

View File

@@ -119,10 +119,10 @@ As Olares evolves, the configuration specification of `OlaresManifest.yaml` may
Developers can use 1-3 digit version numbers to indicate the application's configuration version. Here are some examples of valid versions:
```Yaml
OlaresManifest.yaml.version: 1
OlaresManifest.yaml.version: 1.1.0
OlaresManifest.yaml.version: '2.2'
OlaresManifest.yaml.version: "3.0.122"
olaresManifest.version: 1
olaresManifest.version: 1.1.0
olaresManifest.version: '2.2'
olaresManifest.version: "3.0.122"
```
## Metadata

View File

@@ -10,4 +10,5 @@ This section provides in-depth information, command references, and instructions
- [Olares Home introduction](olares-home.md): Understand the structure of the base installation directory.
- [Olares environment variables reference](environment-variables.md): Find the right environment variables for you to customize the installation.
- [Olares CLI reference](./index.md): Uses the Olares CLI for advanced customization and troubleshooting during installation.
- [Olares versioning](versioning.md): Learn versioning rules, release types, branch management practices, and upgrade guidelines of Olares.
- [Olares versioning](versioning.md): Learn versioning rules, release types, branch management practices, and upgrade guidelines of Olares.
- [Additional installations](additional-installations.md): Try Olares on Docker, macOS, Windows, and PVE, and Raspberry Pi.

View File

@@ -15,11 +15,15 @@ Make sure your device meets the following requirements.
- CPU: At least 4 cores
- RAM: At least 8GB of available memory
- Storage: At least 64GB of available space (SSD recommended)
- Storage: At least 150GB of available SSD storage.
- Supported systems:
- Ubuntu 20.04 LTS or later
- Debian 11 or later
::: warning SSD required
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
:::
:::info Version compatibility
While these specific versions are confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
:::
@@ -53,6 +57,70 @@ cd ~/olares-config
:::
3. Save the `docker-compose.yaml` file.
Here is the updated and properly formatted Markdown content for installing GPU drivers and the NVIDIA Container Toolkit, ready to be included in your installation guide:
## Install GPU dependencies (for GPU-enabled machines)
1. Install GPU drivers for your system:
```bash
curl -o /tmp/keyring.deb -L https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/cuda-keyring_1.1-1_all.deb && \
sudo dpkg -i --force-all /tmp/keyring.deb
sudo apt update
sudo apt install nvidia-kernel-open-570
sudo apt install nvidia-driver-570
````
2. Install the NVIDIA Container Toolkit to enable Docker to access your GPU.
a. Configure the repository:
```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/nvidia-container-toolkit.list
sudo apt-get update
```
b. Install the toolkit and restart docker:
```bash
sudo apt-get install -y nvidia-container-toolkit
sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker
```
c. Verify the installation:
```bash
sudo docker run --rm --runtime=nvidia --gpus all ubuntu nvidia-smi
```
If successful, you should see output similar to the following:
```
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 570.169 Driver Version: 570.169 CUDA Version: 12.8 |
|-----------------------------------------+------------------------+----------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA GeForce RTX 4070 ... Off | 00000000:01:00.0 Off | N/A |
| N/A 41C P8 1W / 80W | 32MiB / 8188MiB | 0% Default |
| | | N/A |
+-----------------------------------------+------------------------+----------------------+
```
## Set up environment variables and start container
1. In the `olares-config` directory, use the following command to set the environment variables and start the Olares services:
@@ -122,7 +190,7 @@ To uninstall the container:
docker compose down
```
<!--@include: ./reusables.md{35,39}-->
<!--@include: ./reusables.md{39,43}-->

View File

@@ -8,17 +8,20 @@ LXC (Linux Containers) is a lightweight virtualization method that runs applicat
Currently, Olares on LXC has certain limitations. We recommend using it only for development or testing purposes.
:::
<!--@include: ./reusables.md{41,47}-->
<!--@include: ./reusables.md{45,51}-->
## System requirements
Make sure your device meets the following requirements.
- CPU: At least 4 cores
- RAM: At least 8GB of available memory
- Storage: At least 64GB of available space (SSD recommended)
- Storage: At least 150GB of available SSD storage.
- Supported systems:
- PVE 8.2.2
- Linux container: Debian 12 (for existing LXC containers on PVE)
::: warning SSD required
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
:::
:::info Version compatibility
While the specific versions are confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
@@ -144,10 +147,10 @@ To install Olares on an existing LXC container, skip to step 2 directly. Make su
Run the following installation command inside the LXC container:
<!--@include: ./reusables.md{4,33}-->
<!--@include: ./reusables.md{5,37}-->
<!--@include: ./activate-olares.md-->
<!--@include: ./log-in-to-olares.md-->
<!--@include: ./reusables.md{35,39}-->
<!--@include: ./reusables.md{39,43}-->

View File

@@ -13,7 +13,7 @@ Currently, Olares on Mac has certain limitations including:
We recommend using it only for development or testing purposes.
:::
<!--@include: ./reusables.md{41,47}-->
<!--@include: ./reusables.md{45,51}-->
## System requirements
Make sure your device meets the following requirements.
@@ -21,7 +21,10 @@ Make sure your device meets the following requirements.
- Architecture: AMD64 or ARM64
- CPU: At least 4 cores
- RAM: At least 8GB of available memory
- Storage: At least 64GB of available space (SSD recommended)
- Storage: At least 150GB of available SSD storage.
::: warning SSD required
The installation will fail if an HDD (mechanical hard drive) is used instead of an SSD.
:::
## Before you begin
Before you begin, ensure the following:
@@ -97,4 +100,4 @@ The `--rm` flag automatically deletes the container after it stops. If this happ
<!--@include: ./manage-olares-container.md-->
<!--@include: ./reusables.md{35,39}-->
<!--@include: ./reusables.md{39,43}-->

View File

@@ -12,14 +12,17 @@ Olares on Mac has certain limitations including:
We recommend using it only for development or testing purposes.
:::
<!--@include: ./reusables.md{41,47}-->
<!--@include: ./reusables.md{45,51}-->
## System compatibility
Make sure your Mac meets the following requirements.
- Architecture: X86-64 or ARM64
- RAM: 8 GB or above (available memory)
- Storage: 90 GB or above (available disk space)
- Storage: 150 GB or above of available space on SSD
- MacOS: Monterey (12) or later
::: warning SSD required
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
:::
## Before you begin
Ensure you have the following installed:
@@ -40,10 +43,10 @@ Ensure you have the following installed:
## Install Olares
In terminal, run the following command:
<!--@include: ./reusables.md{4,33}-->
<!--@include: ./reusables.md{4,37}-->
<!--@include: ./activate-olares.md-->
<!--@include: ./log-in-to-olares.md-->
<!--@include: ./reusables.md{35,39}-->
<!--@include: ./reusables.md{39,43}-->

View File

@@ -8,16 +8,20 @@ Proxmox Virtual Environment (PVE) is an open-source virtualization platform base
Currently, Olares on PVE has certain limitations. We recommend using it only for development or testing purposes.
:::
<!--@include: ./reusables.md{41,47}-->
<!--@include: ./reusables.md{45,51}-->
## System requirements
Make sure your device meets the following requirements.
- CPU: At least 4 cores
- RAM: At least 8GB of available memory
- Storage: At least 64GB of available space (SSD recommended)
- Storage: At least 150GB of available SSD storage.
- Supported Systems: PVE 8.2.2
::: warning SSD required
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
:::
:::info Version compatibility
While the specific version is confirmed to work, the process may still work on other versions. Adjustments may be necessary depending on your environment. If you meet any issues with these platforms, feel free to raise an issue on [GitHub](https://github.com/beclab/Olares/issues/new).
:::
@@ -26,10 +30,10 @@ While the specific version is confirmed to work, the process may still work on o
In PVE CLI, run the following command:
<!--@include: ./reusables.md{4,33}-->
<!--@include: ./reusables.md{5,37}-->
<!--@include: ./activate-olares.md-->
<!--@include: ./log-in-to-olares.md-->
<!--@include: ./reusables.md{35,39}-->
<!--@include: ./reusables.md{39,43}-->

View File

@@ -7,13 +7,17 @@ This guide explains how to install Olares on a Raspberry Pi.
:::warning Not recommended for production use
Currently, Olares on Raspberry Pi has certain limitations. We recommend using it only for development or testing purposes.
:::
<!--@include: ./reusables.md{41,47}-->
<!--@include: ./reusables.md{45,51}-->
## System requirements
Make sure your Raspbian device meets the following requirements.
- Hardware: Raspberry Pi 4B or Raspberry Pi 5 with 8GB memory
- Operating system: Raspbian 12
- Storage: 64GB (SSD recommended)
- Storage: At least 150GB of available SSD storage.
::: warning SSD required
The installation will likely fail if an HDD (mechanical hard drive) is used instead of an SSD.
:::
## Set up system environment
1. Configure the Raspbian environment to enable necessary features:
@@ -38,4 +42,4 @@ Run the following command:
<!--@include: ./log-in-to-olares.md-->
<!--@include: ./reusables.md{35,39}-->
<!--@include: ./reusables.md{39,43}-->

View File

@@ -42,10 +42,10 @@ You're almost ready to start using Olares! Before diving in, it's crucial to ens
- [Back up your mnemonic phrase](/manual/larepass/back-up-mnemonics.md)
:::info Having trouble with installation?
::: info Having trouble with installation?
If you encounter issues during the installation process, feel free to [submit a GitHub Issue](https://github.com/beclab/Olares/issues/new). Please include the following information when submitting:
- The platform or environment you're using (e.g., Ubuntu, Docker, WSL, etc.).
- The installation method (script installation or Docker image).
- Detailed error information (including logs, error messages, or screenshots).
:::
:::

Some files were not shown because too many files have changed in this diff Show More