Compare commits

...

236 Commits

Author SHA1 Message Date
hysyeah
738198350f fix: skip nginx reload if configuration has not changed (#2555) 2026-02-25 13:54:09 +08:00
eball
5de7ea01bc fix: skip nginx reload if configuration has not changed 2026-02-25 11:45:13 +08:00
hysyeah
ff7765bcb9 fix: skip invalid expose port (#2434) 2026-01-22 12:00:32 +08:00
wiy
c98c855099 feat(olares-app): update version to v1.8.2 (#2433)
* feat(olares-app): update version to v1.8.2

* feat(olares-app): update version to v1.8.2
2026-01-22 00:06:13 +08:00
hysyeah
4ae552f33f bfl: myapps api add rawAppName (#2432)
* fix: myapps api add rawAppName field

* update bfl api image tag to v0.4.39
2026-01-22 00:05:42 +08:00
hysyeah
f2aad6d9f6 cli: feat amdgpu install (#2430) 2026-01-22 00:05:01 +08:00
dkeven
02bc4fafd5 feat(cli): collect nginx logs stored temporarily in some containers (#2429) 2026-01-22 00:04:29 +08:00
eball
8d34cc995d daemon: modify mDNS registration method (#2427)
daemon: update zeroconf dependency to v0.2.5 and modify mDNS registration method
2026-01-19 23:28:29 +08:00
Yajing
a19e81a4a0 docs: refactor local access guide (#2419)
* docs: refactor local access guide

* Apply suggestions from code review

Co-authored-by: Meow33 <supermonkey03@163.com>

* address comments

---------

Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-19 21:59:08 +08:00
hysyeah
ee3f2a7df2 tapr: add max retry for delete action (#2426)
* tapr: upgrade pod template and image for PGCluster reconciliation (#2213)

* tapr: upgrade pod template and image for PGCluster reconciliation

* fix(ci): specify working directory in github action for tapr (#2215)

---------

Co-authored-by: dkeven <82354774+dkeven@users.noreply.github.com>

* tapr: upgrade pod template and image for PGCluster reconciliation

* fix(kvrocks): update init container image and pull policy configuration (#2331)

* tapr: change kvrocks running as root by default

* fix: add max retry for delete action

* tapr: update middleware-operator image tag to 0.2.31

---------

Co-authored-by: eball <liuy102@hotmail.com>
Co-authored-by: dkeven <82354774+dkeven@users.noreply.github.com>
2026-01-19 20:31:35 +08:00
eball
73ea65b004 hami: revert hami-core latest update (#2424) 2026-01-19 19:26:28 +08:00
wiy
4ef2e7124a feat(olares-app): update olares-app version to v1.7.7 (#2423) 2026-01-19 14:06:43 +08:00
wiy
ef46f91ec7 feat(olares-app): update new version to v1.7.6 (#2422)
fix(share): fixed the error message that appeared after exceeding the upload limit.
2026-01-16 23:57:38 +08:00
hysyeah
0f5a346d86 authelia: fix target url parse method (#2421) 2026-01-16 23:57:12 +08:00
salt
caa799e902 feat: optimize highlight segment order (#2420)
Co-authored-by: ubuntu <you@example.com>
2026-01-16 15:42:12 +08:00
Power-One-2025
2be5f6d108 docs: add lobechat tutorial (#2368)
* docs/feat/add-lobechat-tutorial

* docs/feat/fix-images

* docs/feat/lobechat-fixlink

* docs/feat/iterate-content

* docs/update/more-content

* docs/updaate/refine

* docs/feat/lobechat-refine

* docs/feat/add-lobechat-index

* docs/updates/fix-link

* Update docs/use-cases/lobechat.md

Co-authored-by: Meow33 <supermonkey03@163.com>

* Update docs/use-cases/lobechat.md

Co-authored-by: Meow33 <supermonkey03@163.com>

* Update docs/use-cases/lobechat.md

Co-authored-by: Meow33 <supermonkey03@163.com>

* Update docs/use-cases/lobechat.md

Co-authored-by: Meow33 <supermonkey03@163.com>

* docs/update/address-comments

* Apply suggestions from code review

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/update/address-comment

* docs/update/conflict

* refine edit

* docs/updates/image-size-opt

* docs/update/resize

* Apply suggestions from code review

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/update/add-faq

---------

Co-authored-by: Meow33 <supermonkey03@163.com>
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-15 23:29:06 +08:00
salt
05f3c8ffdc fix: fix meaningless word highlight (#2418)
Co-authored-by: ubuntu <you@example.com>
2026-01-15 19:30:06 +08:00
berg
c0e242b05c settings: update search origin (#2417)
feat: update system frontend version
2026-01-15 19:29:07 +08:00
Power-One-2025
7929e420b1 docs: add stirling-pdf tutorial (#2369) 2026-01-15 16:10:05 +08:00
Power-One-2025
66de213f43 docs/update/image-size-opt 2026-01-15 15:56:25 +08:00
Power-One-2025
2166cec66f docs/update/fixtoc 2026-01-15 15:37:44 +08:00
Power-One-2025
1a0f9727c4 Merge branch 'main' into docs/add-stirling-pdf-tutorial 2026-01-15 11:07:46 +08:00
hysyeah
810253fe94 kubeblocks: skip check pod spec,status image (#2414)
fix: skip check pod spec,status image
2026-01-14 23:57:45 +08:00
wiy
23429a6193 olares-app, login: update version to v1.7.4 (#2413) 2026-01-14 23:57:01 +08:00
salt
49e40f316f fix: fix english highight missing (#2412)
Co-authored-by: ubuntu <you@example.com>
2026-01-14 23:56:37 +08:00
eball
1e7b655826 daemon: handle missing auth token for WebSocket connections (#2411) 2026-01-14 23:56:09 +08:00
dkeven
adea16ce7e feat(gpu): update gpu plugin version to v2.6.8 (#2410) 2026-01-14 23:55:48 +08:00
Power-One-2025
c2222859a5 docs: add PDFMathTranslate tutorial (#2378)
* docs/feat/draft

* docs/update/more-content

* docs/updates/refine

* docs/update/fix-build-conflict

* docs/update/fix-broken-link

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/updates/compress-images

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/update/comments

* docs/update/refine

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/update/comment

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/update/fix-link

* Update docs/use-cases/pdfmathtranslate.md

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>

* docs/update/comment

---------

Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-14 23:17:55 +08:00
yyh
e7dde2ff51 user-service: update mtranserverv2 (#2408)
fix(user-service): update mtranserverv2
2026-01-13 23:57:31 +08:00
lovehunter9
d06c1e8a99 fix: files check disk space for upload link and copy (#2407) 2026-01-13 23:57:01 +08:00
dkeven
131faacce0 feat(cli): sync kubeconfig for the original user invoking sudo (#2406) 2026-01-13 23:56:08 +08:00
Meow33
8133704761 docs: add CLI docs for user, upgrade, and disk commands (#2383)
* docs: add CLI docs for user, upgrade, and disk commands

* docs: update based on comments

* docs: fix typo

* docs: refine formatting and add description for argument

* docs: resolve conflicts
2026-01-13 17:30:57 +08:00
Power-One-2025
09e61aecad docs/update/address-comment 2026-01-12 15:49:11 +08:00
Power-One-2025
bc5fd5fd82 Merge branch 'main' into docs/add-stirling-pdf-tutorial 2026-01-12 15:38:50 +08:00
Power-One-2025
1367355661 docs/update/address-comments 2026-01-12 15:36:38 +08:00
eball
2a506be19a ci: bump version to 1.12.5 (#2405) 2026-01-12 15:00:44 +08:00
Power-One-2025
30195f1513 Update docs/use-cases/stirling-pdf.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-12 14:42:28 +08:00
Power-One-2025
88b140ccc2 Update docs/use-cases/stirling-pdf.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-12 14:42:14 +08:00
Power-One-2025
39947f464c Update docs/use-cases/stirling-pdf.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-12 14:41:31 +08:00
Power-One-2025
698bdf96ed docs: remove outdated environment variables (#2394) 2026-01-12 14:05:52 +08:00
wiy
69e6ac35f8 feat(olares-app): file upload add total_size parameter (#2404)
* feat(olares-app): file upload add total_size parameter

* fix: infisical update

---------

Co-authored-by: aby913 <aby913@163.com>
2026-01-12 14:01:09 +08:00
salt
f41e66b39a feat: search3 upgrade to v0.1.2 for juicefs watch (#2403)
Co-authored-by: ubuntu <you@example.com>
2026-01-12 14:00:32 +08:00
dkeven
1a36faaf6d feat(cli): add upgrader for main line version 1.12.4 (#2402) 2026-01-12 13:59:24 +08:00
Yajing
cbdd08d237 docs: add faqs and refactor help docs (#2376)
* docs: add faqs and refactor help docs

* align zh-cn
2026-01-10 12:56:33 +08:00
dkeven
2fd9d23371 feat(cli): optimize and unify pod readiness check logic (#2393) 2026-01-09 16:10:12 +08:00
hysyeah
f1714534db appservice: delay create nats conn (#2392)
* fix: failed release upgrade

* fix: helm upgrade do not use atomic param and allow upgrade failed release

* fix: delay create nats conn (#2391)

* set appservice image tag and add readiness probe
2026-01-09 15:59:35 +08:00
lovehunter9
9bc66369df fix: files sync reconnection error msg and upload chuck access token (#2390) 2026-01-09 15:22:31 +08:00
Meow33
ba85b0f60d docs/remove outdated env variables 2026-01-09 14:45:07 +08:00
aby913
7c2624d418 market: skip systemenv check in the cloud, add nsfw trigger in settings (#2387)
market: fix systemenv in public, add nsfw trigger in settings
2026-01-08 23:36:40 +08:00
hysyeah
7eb21516d0 authelia,lldap: distinguish error message in firstfactor authentication (#2389) 2026-01-08 23:35:52 +08:00
berg
266aef8616 system frontend: add the NSFW feature (#2388)
* market: fix sync app state on nats, add log levels

* feat: update system frontend to v1.6.42

---------

Co-authored-by: aby913 <aby913@163.com>
2026-01-08 23:35:09 +08:00
aby913
3755bede0c backup: folder set to UID 1000 (#2386)
* backup: backup folder set to UID 1000

* backup: folder set to UID 1000
2026-01-08 23:33:01 +08:00
hysyeah
cca39eed7e appservice: fix inorder nats event (#2384)
* fix: failed release upgrade

* fix: helm upgrade do not use atomic param and allow upgrade failed release

* fix: push all nats event to queue  (#2374)

* fix: push all nats event to queue and via one connection

* fix: wrap yaml decode error

* update appservice image tag to 0.4.74
2026-01-08 23:31:25 +08:00
dkeven
b27b90b9a8 fix(bfl): add backend cluster API handler for stats report (#2382)
* fix(bfl): add backend cluster API handler for stats report (#2381)

* chore(bfl): update image version to v0.4.38
2026-01-08 23:30:37 +08:00
eball
119ec75234 cli: enhance CUDA library handling for WSL with strace detection (#2380) 2026-01-08 23:30:05 +08:00
aby913
8739bfc040 market: fix sync app state on nats, add log levels, nsfw label (#2379)
market: fix sync app state on nats, add log levels
2026-01-08 00:54:34 +08:00
Yajing
6304739725 docs: merge 1.12.3 docs to main (#2377) 2026-01-07 19:25:30 +08:00
yajing wang
f8f452b27f fix formatting 2026-01-07 19:12:03 +08:00
yajing wang
36acf0384d fix conflicts 2026-01-07 17:09:41 +08:00
Meow33
aa5b073b5c docs: update based on comments 2026-01-07 16:58:44 +08:00
Meow33
18dfae6c87 docs: add steam guide zh cn 2026-01-07 16:58:42 +08:00
Meow33
a54445db8b docs: address comments 2026-01-07 16:58:20 +08:00
Meow33
375e2c4f63 Apply suggestions from code review
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:58:20 +08:00
Meow33
c366b56de9 docs: update based on suggestions 2026-01-07 16:58:20 +08:00
Meow33
85d90a36ed docs: update based on suggestions 2026-01-07 16:58:20 +08:00
Meow33
172c5342d8 docs: update file search guide 2026-01-07 16:58:20 +08:00
Yajing
dcc0ab1cd2 Update docs/zh/manual/olares/wise/index.md 2026-01-07 16:58:20 +08:00
Yajing
b078f80b5a fix wording 2026-01-07 16:58:20 +08:00
Meow33
854e25096f docs: update based on comments 2026-01-07 16:58:20 +08:00
Meow33
78949de2b6 docs: update based on comments 2026-01-07 16:58:20 +08:00
Meow33
bd72cb8067 docs: update based on comments 2026-01-07 16:58:20 +08:00
Meow33
3b9f0d33a3 docs: update based on suggestions 2026-01-07 16:58:20 +08:00
Meow33
3e782c6cea Apply suggestions from code review
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:58:20 +08:00
Meow33
28c2979db0 docs: update based on suggestions 2026-01-07 16:58:20 +08:00
Meow33
fc8ade657d docs: update based on comments 2026-01-07 16:58:20 +08:00
Meow33
74c80a9c7e Apply suggestions from code review
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:58:20 +08:00
Meow33
51a06f8964 docs: update relevant docs 2026-01-07 16:58:18 +08:00
Meow33
0c50d93d77 docs: refactor guide for gpu management 2026-01-07 16:57:42 +08:00
Power-One-2025
17b8d2d96e docs/updates/comment 2026-01-07 16:57:42 +08:00
Power-One-2025
5b5e5d289c docs/updates/comment 2026-01-07 16:57:42 +08:00
Power-One-2025
b113f66c4f Update docs/manual/olares/market/clone-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
bbbe3ecf9b docs/update/comment 2026-01-07 16:57:42 +08:00
Power-One-2025
b7ff5db985 docs/update/comments 2026-01-07 16:57:42 +08:00
Power-One-2025
f39e359ef8 Update docs/manual/olares/market/purchase-paid-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
4a80ef6148 Update docs/.vitepress/en.ts
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
c4af7a5783 docs/updates/comment 2026-01-07 16:57:42 +08:00
Power-One-2025
5c498fbe18 Update docs/manual/olares/market/purchase-paid-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
4fbe32b141 docs/update/comment 2026-01-07 16:57:42 +08:00
Power-One-2025
46fc840302 docs/update/address-comments 2026-01-07 16:57:42 +08:00
Power-One-2025
5677026de0 Update docs/manual/olares/market/clone-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
4d95152e0a Update docs/manual/olares/market/clone-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
9560985965 Update docs/manual/olares/market/clone-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
1b6d90c2a5 Update docs/manual/olares/market/purchase-paid-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
2c73b3b7f8 Update docs/manual/olares/market/purchase-paid-apps.md
Co-authored-by: Yajing <110797546+fnalways@users.noreply.github.com>
2026-01-07 16:57:42 +08:00
Power-One-2025
22c52398ed docs/update/fix-comment 2026-01-07 16:57:42 +08:00
Power-One-2025
d1e55515d4 docs/updates/fix-note-style 2026-01-07 16:57:42 +08:00
Power-One-2025
5db251520d docs/updates/fix-comments 2026-01-07 16:57:42 +08:00
Power-One-2025
d2b630c7b4 docs/update/fix-links 2026-01-07 16:57:40 +08:00
Power-One-2025
0debd332a8 docs/updates/fix-toc 2026-01-07 16:54:40 +08:00
Power-One-2025
9a2c58e3fa docs/updates/market-comments-fix 2026-01-07 16:54:38 +08:00
Meow33
b8842cfe61 docs: update based on suggestions 2026-01-07 16:54:02 +08:00
Meow33
70e170b71a docs: update larepass upgrade descriptions 2026-01-07 16:54:02 +08:00
Power-One-2025
e975e4aec8 docs/update/files-index-update 2026-01-07 16:54:02 +08:00
Power-One-2025
9d6d242625 docs/update/refine-images 2026-01-07 16:54:02 +08:00
Power-One-2025
86d7b985a2 docs/update/preview-edit-files 2026-01-07 16:54:01 +08:00
Power-One-2025
31a2b3ee28 docs/updates/add-images 2026-01-07 16:54:01 +08:00
Power-One-2025
9aa7e0b108 docs/update/add-image-share 2026-01-07 16:54:01 +08:00
Power-One-2025
9092f28458 docs/updates/files-comments-fix 2026-01-07 16:54:01 +08:00
Yajing
f925268cd4 fix typo
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:54:01 +08:00
yajing wang
e1c19f7327 update intro & screenshots 2026-01-07 16:54:01 +08:00
Yajing
5e925e0cb6 Apply suggestions
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:54:01 +08:00
yajing wang
6a0885d37d fix lint 2026-01-07 16:54:00 +08:00
yajing wang
3e46af80e1 docs: add play games directly on olares device 2026-01-07 16:53:12 +08:00
yajing wang
74c48b81fb docs: update windows use case 2026-01-07 16:52:03 +08:00
Power-One-2025
56aed6b683 Update docs/zh/manual/olares/settings/gpu-resource.md 2026-01-07 16:52:03 +08:00
Meow33
cbfcf3d3aa docs: update screenshots 2026-01-07 16:52:03 +08:00
Meow33
fd23e52723 docs: update based on suggestions 2026-01-07 16:52:03 +08:00
Meow33
b48368b934 docs: update guide for manage gpu usage 2026-01-07 16:52:03 +08:00
Meow33
ca9ce45353 docs: update based on suggestions 2026-01-07 16:52:03 +08:00
Meow33
fa148969c5 docs: update en version based on suggestions and update translation 2026-01-07 16:52:03 +08:00
Meow33
21c1884bb8 docs: update tutorials for Wise 2026-01-07 16:52:03 +08:00
Meow33
b517d08981 docs: update based on suggestions 2026-01-07 16:52:03 +08:00
Meow33
73e2cd0eb4 docs: update based on suggestions 2026-01-07 16:52:03 +08:00
Meow33
a631db1e9e docs: add guide for search under settings 2026-01-07 16:52:03 +08:00
Meow33
f3b59b9b3e docs: add larepass upgrade restart prompt 2026-01-07 16:52:03 +08:00
Power-One-2025
910bf02b48 Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:52:03 +08:00
Power-One-2025
dcc909a06e Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:52:03 +08:00
Power-One-2025
1238ad01f1 Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:52:03 +08:00
Power-One-2025
77ee176f5e Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:52:03 +08:00
Power-One-2025
1d9c3f7b4a Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:52:03 +08:00
Power-One-2025
8a52737f89 docs/update/refine-description 2026-01-07 16:52:03 +08:00
Power-One-2025
bd7c46a663 docs/update/table-line-wrap 2026-01-07 16:52:03 +08:00
Power-One-2025
9ee4af9040 docs/update/add-faq-resume-app 2026-01-07 16:52:03 +08:00
Power-One-2025
fc86bbadc2 docs/update/image 2026-01-07 16:52:03 +08:00
Power-One-2025
52118b1126 docs/updates/clond-apps-images 2026-01-07 16:52:01 +08:00
Power-One-2025
76be9e82c0 docs/updates/resize-image 2026-01-07 16:51:21 +08:00
Power-One-2025
478d9f28c8 Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
114ed5ad7b Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
c85b23d9a9 Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
fbc61764ca Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
d866966531 Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
d140849d7c Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
679ddb0f8d Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
0ec0a5a4ac Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
74ecf9f73d Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
028c5c7bdb Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
f3ab03becc docs/update/consistency 2026-01-07 16:51:21 +08:00
Power-One-2025
e408da75a4 docs/update/mobile-app-image-style 2026-01-07 16:51:21 +08:00
Power-One-2025
8ffbc82ebd docs/update/formatting-fix-zh 2026-01-07 16:51:21 +08:00
Power-One-2025
304dbf69c5 docs/updates/formatting-fix 2026-01-07 16:51:21 +08:00
Power-One-2025
66b0144b40 docs/update/add-restore-purchased-app 2026-01-07 16:51:21 +08:00
Power-One-2025
e91a76f92f docs/updates/dev-comments 2026-01-07 16:51:21 +08:00
Power-One-2025
45cd406cd4 docs/updates/add-images-paid-app 2026-01-07 16:51:21 +08:00
Power-One-2025
7ef7ae9335 docs/feat/purchase-paid-apps 2026-01-07 16:51:21 +08:00
Power-One-2025
f2f342a28a Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:51:21 +08:00
Power-One-2025
fdca458e4f docs/update/clone-apps 2026-01-07 16:51:21 +08:00
Power-One-2025
b7141373b7 docs/updates/add-note 2026-01-07 16:51:21 +08:00
Power-One-2025
21118c8e95 docs/updates/single-source-for-sync 2026-01-07 16:51:19 +08:00
Power-One-2025
307a6bb502 docs/updates/address comments on share files 2026-01-07 16:50:00 +08:00
Power-One-2025
91ec932c95 Update docs/manual/olares/files/add-edit-download.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:50:00 +08:00
Power-One-2025
a1cb16cfe9 docs/feat/share-files 2026-01-07 16:49:57 +08:00
Power-One-2025
aec5e178b3 docs/update/add-title-level 2026-01-07 16:48:15 +08:00
Power-One-2025
2624ea5dc5 docs/updates/address comment on files sync 2026-01-07 16:48:15 +08:00
Power-One-2025
0d1bae720d Update docs/manual/olares/files/add-edit-download.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:48:15 +08:00
Power-One-2025
96520a8bc3 docs/feature/sync-files-to-local 2026-01-07 16:48:15 +08:00
Power-One-2025
27b9356037 Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:48:15 +08:00
Power-One-2025
c289d5837c Update docs/zh/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:48:15 +08:00
Power-One-2025
e6f9922951 address comment 2026-01-07 16:48:15 +08:00
Power-One-2025
a3ad8ce78c Update market.md 2026-01-07 16:48:15 +08:00
Power-One-2025
c70587062a Update market.md 2026-01-07 16:48:14 +08:00
Power-One-2025
f7306b66dc Update market.md 2026-01-07 16:48:14 +08:00
Power-One-2025
325bfeb90d Update market.md 2026-01-07 16:48:14 +08:00
Power-One-2025
bfc3ca0720 Update docs/manual/olares/market.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 16:48:14 +08:00
Power-One-2025
ef071e43ca docs: new app clone feature to Market 2026-01-07 16:48:14 +08:00
Power-One-2025
7440e85c2e docs/update/address-comments 2026-01-07 14:23:29 +08:00
Power-One-2025
d71747928c Update docs/use-cases/stirling-pdf.md
Co-authored-by: Meow33 <supermonkey03@163.com>
2026-01-07 11:31:48 +08:00
eball
473898a715 daemon: bump zeroconf dependency to v0.2.4 (#2375)
daemon: bump zeroconf dependency to v0.2.4 and increase log verbosity for server events
2026-01-07 00:10:40 +08:00
lovehunter9
637b1839f7 fix: files sync reconnection at pipe client when sending has met broken pipe (#2373) 2026-01-05 23:46:42 +08:00
wiy
1f1c1a8d3b olares-app: update vault add websocket (#2372)
wizard: update qrcode size
2026-01-05 23:46:03 +08:00
dkeven
1ddcc3bd4c fix(gpu): handle scheduler inconsistency and device stuck in unhealthy (#2371) 2026-01-05 23:44:50 +08:00
dkeven
96a2eb524a fix(cli): remove olares name when uninstalling to prepare (#2370) 2026-01-05 23:44:08 +08:00
Power-One-2025
b20d5c0876 docs/feat/stirlingpdf-refine 2026-01-05 14:39:56 +08:00
Power-One-2025
c4fc3198bb docs/feat/stirlingpdf-add-index 2026-01-05 13:42:47 +08:00
Power-One-2025
260b6154f3 docs/feat/stirlingpdf-more 2026-01-05 13:38:33 +08:00
Power-One-2025
ecfcd0d1d8 docs/feat/content-add 2026-01-04 22:29:05 +08:00
eball
be7f3b3c3f daemon: update serial filtering logic to use suffix matching (#2367) 2026-01-04 20:44:41 +08:00
hysyeah
99c6d3860d app-service: app upgrade set tailscale acl (#2362)
* fix: failed release upgrade

* fix: helm upgrade do not use atomic param and allow upgrade failed release

* fix: app upgrade set tailscale acl (#2357)

* fix: increase wait timeout for namespace delete

* fix: update app-service image tag to 0.4.73
2025-12-31 23:58:57 +08:00
berg
9f56cf0f05 login, system frontend: update qrcode size (#2361)
feat: update login version and system frontend version
2025-12-31 23:58:11 +08:00
Yajing
76c8e93822 docs: fix misplaced braces in studio tutorial (#2358) 2025-12-31 21:41:30 +08:00
yajing wang
d38d0d0e1d docs: fix misplaced braces in studio tutorial 2025-12-31 20:59:24 +08:00
hysyeah
65b32c7c41 kubeblocks-addon: fix kubeblocks-addon rabbitmq image pull policy (#2356)
fix: kubeblocks-addon rabbitmq image pull policy
2025-12-31 15:10:26 +08:00
wiy
f6f14e8d9a olares app: update settings create sub-accounts to block domain (#2355) 2025-12-31 15:09:33 +08:00
eball
f8653692b1 daemon: update DID gate URL handling in JWS validation and resolution (#2354) 2025-12-31 13:07:22 +08:00
eball
5264df60cc cli: update ResolveOlaresName and CheckJWS to accept gateUrl parameter (#2352) 2025-12-31 00:11:35 +08:00
berg
1a200ed17c system frontend: update market topic ids (#2351)
feat: update system frontend version
2025-12-30 21:17:53 +08:00
eball
48fdaa5481 daemon: enhance USB monitoring with serial filtering support (#2349)
* daemon: enhance USB monitoring with serial filtering support

* daemon: add check for USB devices with serial before mounting

* daemon: implement FilterBySerial function for USB device filtering
2025-12-30 21:17:15 +08:00
eball
570fe070c9 k3s: update eviction thresholds and image GC settings (#2348)
k3s: update eviction thresholds and image GC settings for improved resource management
2025-12-30 21:16:54 +08:00
lovehunter9
6b18bbd94d fix: files change usb watcher to retry and change sync reconnection to callback (#2342)
* fix: files change usb watcher to retry and change sync reconnection to callback

* fix: create folder and rsync chown to 1000
2025-12-30 21:15:34 +08:00
Yajing
c6836f9859 docs: update nav to reflect the latest changes (#2343) 2025-12-30 17:41:39 +08:00
yajing wang
288869d91d docs: update nav to reflect the latest changes 2025-12-29 20:55:06 +08:00
hysyeah
8ea8a0857e app-service: add helm upgrade timeout (#2339)
* fix: failed release upgrade

* fix: update appservice image tag to 0.4.71

* fix: helm upgrade do not use atomic param and allow upgrade failed release
2025-12-27 14:05:22 +08:00
eball
87674cc5d9 opa: update image validation to exclude alpine and mariadb images (#2337) 2025-12-27 14:04:31 +08:00
berg
11f556e9af system frontend, market backend: verify the update time when the app status is changed. (#2336)
feat: update system frontend version
2025-12-27 14:04:14 +08:00
simon
d2d3195fea download-server: modify ytdlp support domain (#2335)
download
2025-12-27 14:03:45 +08:00
hysyeah
ad3b138284 app-service: fix exposeport upgrade (#2334)
* fix: exposeport upgrade (#2333)

* update appservice tag to 0.4.70
2025-12-26 19:41:14 +08:00
eball
ff609db1aa tapr: change kvrocks to run as root by default (#2332)
* tapr: upgrade pod template and image for PGCluster reconciliation (#2213)

* tapr: upgrade pod template and image for PGCluster reconciliation

* fix(ci): specify working directory in github action for tapr (#2215)

---------

Co-authored-by: dkeven <82354774+dkeven@users.noreply.github.com>

* tapr: upgrade pod template and image for PGCluster reconciliation

* fix(kvrocks): update init container image and pull policy configuration (#2331)

* tapr: change kvrocks running as root by default

---------

Co-authored-by: dkeven <82354774+dkeven@users.noreply.github.com>
2025-12-26 19:40:48 +08:00
dkeven
43c6bff906 feat(cli): collect more logs for K8s resources (#2330) 2025-12-26 15:36:02 +08:00
berg
b28dac652c system fronted, market backend, chart repo: add suspend app function (#2329)
feat: update market version
2025-12-26 14:46:38 +08:00
lovehunter9
fbb5c08227 fix: files sync reconnection (#2327) 2025-12-25 19:05:04 +08:00
dkeven
a04d363597 fix(daemon): update module appservice dependency to fix security issues (#2326) 2025-12-25 17:21:19 +08:00
dkeven
994d2b9b91 fix(cli): update module appservice dependency to fix security issues (#2325) 2025-12-25 17:20:47 +08:00
dependabot[bot]
909b7656fd chore(deps): bump github.com/open-policy-agent/opa from 0.18.0 to 1.4.0 in /infrastructure/kubesphere (#2324)
chore(deps): bump github.com/open-policy-agent/opa

Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 0.18.0 to 1.4.0.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v0.18.0...v1.4.0)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-version: 1.4.0
  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-12-25 14:11:30 +08:00
dependabot[bot]
c61260cb5a chore(deps): bump github.com/docker/docker from 20.10.7+incompatible to 25.0.13+incompatible in /infrastructure/kubesphere (#2323)
chore(deps): bump github.com/docker/docker in /infrastructure/kubesphere

Bumps [github.com/docker/docker](https://github.com/docker/docker) from 20.10.7+incompatible to 25.0.13+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v20.10.7...v25.0.13)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-version: 25.0.13+incompatible
  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-12-25 14:04:15 +08:00
salt
fed1a60c63 chore: keep three days log (#2319)
Co-authored-by: ubuntu <you@example.com>
2025-12-25 13:59:13 +08:00
wiy
7062408f5d fix(olares-app): fix some secret warning (#2320) 2025-12-25 13:58:38 +08:00
dependabot[bot]
583ec7730c chore(deps): bump github.com/emicklei/go-restful from 2.14.3+incompatible to 2.16.0+incompatible in /infrastructure/kubesphere (#2322)
chore(deps): bump github.com/emicklei/go-restful

Bumps [github.com/emicklei/go-restful](https://github.com/emicklei/go-restful) from 2.14.3+incompatible to 2.16.0+incompatible.
- [Release notes](https://github.com/emicklei/go-restful/releases)
- [Changelog](https://github.com/emicklei/go-restful/blob/v3/CHANGES.md)
- [Commits](https://github.com/emicklei/go-restful/compare/v2.14.3...v2.16.0)

---
updated-dependencies:
- dependency-name: github.com/emicklei/go-restful
  dependency-version: 2.16.0+incompatible
  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-12-25 13:58:00 +08:00
dependabot[bot]
e9f3b23ac9 chore(deps): bump golang.org/x/crypto from 0.0.0-20210817164053-32db794688a5 to 0.45.0 in /framework/kube-state-metrics (#2321)
chore(deps): bump golang.org/x/crypto in /framework/kube-state-metrics

Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20210817164053-32db794688a5 to 0.45.0.
- [Commits](https://github.com/golang/crypto/commits/v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-25 13:55:03 +08:00
dkeven
7f09420bdf fix(appservice): update depedencies to fix some vulnerabilities (#2314)
* refactor(appservice): rename go module to fit into the main repo (#2311)

* fix(appservice): update depedencies to fix some vulnerabilities (#2313)
2025-12-25 11:30:55 +08:00
salt
c93869db02 feat: use poppler-utils and catdoc (#2318)
Co-authored-by: ubuntu <you@example.com>
2025-12-25 11:09:09 +08:00
wiy
2f23def478 feat(olares-app): update olares-app version to v1.6.31 (#2317)
* feat(olares-app): update olares-app version to v1.6.31

* feat: update social keys
2025-12-25 00:21:50 +08:00
dkeven
4c5c43982a fix(cli): handle invalid modprobe sys conf when upgrading GPU driver (#2316) 2025-12-25 00:21:18 +08:00
aby913
a2a6c581c2 infisical: secret limit up to 1000 per minute (#2315) 2025-12-25 00:20:43 +08:00
eball
8b1a7e11f5 opa: enhance image trust validation by trimming docker.io prefix (#2308)
* opa: enhance image trust validation by trimming docker.io prefix

* fix: correct typo in image trimming function name in untrusted image checks
2025-12-25 00:20:08 +08:00
dependabot[bot]
2181adb67c chore(deps): bump github.com/gofiber/fiber/v2 from 2.49.2 to 2.52.9 in /platform/tapr (#2309)
chore(deps): bump github.com/gofiber/fiber/v2 in /platform/tapr

Bumps [github.com/gofiber/fiber/v2](https://github.com/gofiber/fiber) from 2.49.2 to 2.52.9.
- [Release notes](https://github.com/gofiber/fiber/releases)
- [Commits](https://github.com/gofiber/fiber/compare/v2.49.2...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-12-24 15:47:43 +08:00
wiy
e1b0bd7875 feat(wizard): remove the option to select an FRP node when activating a sub-account. (#2305)
feat(wizard): remove sub-account select frp node
2025-12-23 23:50:10 +08:00
dkeven
e465a2d8fc feat(bfl): reuse owner's proxy config when activating sub-accounts (#2302)
* feat(bfl): reuse owner's proxy config when activating sub-accounts (#2300)

* bfl: update image version to v0.4.37
2025-12-23 23:49:30 +08:00
eball
70d0ae1ff5 opa: add trusted image for kldtks image repo (#2301) 2025-12-23 23:49:01 +08:00
eball
e52db36045 daemon: improve umount handling for broken USB devices (#2299)
* daemon: improve umount handling for broken USB devices

* fix: update package name from @didvault/app to @olares/app in package-lock.json
2025-12-23 23:48:40 +08:00
hysyeah
1935b1fbb6 app-service: fix entrance policy update by upgrade (#2298)
* fifx: entrance policy update by upgrade

* fix: skip app update if deployment not changed

* fix: update app-service image tag to 0.4.69
2025-12-23 23:48:11 +08:00
salt
5dc69bf80e fix: search3 fix extract doc error, block task (#2296)
Co-authored-by: ubuntu <you@example.com>
2025-12-23 21:03:04 +08:00
wiy
e839d5ae41 feat(olares-app): update olares-app README.md (#2292) 2025-12-23 11:31:13 +08:00
wiy
e89c6f35cc feat(olares-app): update olares-app to fix some bugs (#2293) 2025-12-23 11:29:27 +08:00
hysyeah
c4a7c81777 app-service: feat add deviceName to helm values (#2291)
* feat: add deviceName to helm values (#2289)

* update appservice image to 0.4.68
2025-12-22 21:23:55 +08:00
eball
a69b5d40a9 ci: skip processing vendor files in Olares.yaml (#2290) 2025-12-22 21:23:18 +08:00
eball
bab074cd37 daemon: bump jws sdk version (#2287) 2025-12-22 17:58:55 +08:00
dkeven
afb7d49455 fix(cli): unify node GPU info update logic (#2288) 2025-12-22 17:58:35 +08:00
627 changed files with 9773 additions and 4292 deletions

View File

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

View File

@@ -41,7 +41,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: 1.24.3 go-version: 1.24.11
- name: Install x86_64 cross-compiler - name: Install x86_64 cross-compiler
run: sudo apt-get update && sudo apt-get install -y build-essential run: sudo apt-get update && sudo apt-get install -y build-essential

View File

@@ -42,7 +42,7 @@ jobs:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v3 uses: actions/setup-go@v3
with: with:
go-version: 1.22.1 go-version: 1.24.11
- name: install udev-devel and pcap-devel - name: install udev-devel and pcap-devel
run: | run: |

View File

@@ -17,7 +17,7 @@ jobs:
steps: steps:
- id: generate - id: generate
run: | run: |
v=1.12.4-$(date +"%Y%m%d") v=1.12.5-$(date +"%Y%m%d")
echo "version=$v" >> "$GITHUB_OUTPUT" echo "version=$v" >> "$GITHUB_OUTPUT"
release-id: release-id:

View File

@@ -317,7 +317,7 @@ spec:
chown -R 1000:1000 /uploadstemp && \ chown -R 1000:1000 /uploadstemp && \
chown -R 1000:1000 /appdata chown -R 1000:1000 /appdata
- name: olares-app-init - name: olares-app-init
image: beclab/system-frontend:v1.6.28 image: beclab/system-frontend:v1.8.2
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
command: command:
- /bin/sh - /bin/sh
@@ -439,7 +439,7 @@ spec:
- name: NATS_SUBJECT_VAULT - name: NATS_SUBJECT_VAULT
value: os.vault.{{ .Values.bfl.username}} value: os.vault.{{ .Values.bfl.username}}
- name: user-service - name: user-service
image: beclab/user-service:v0.0.81 image: beclab/user-service:v0.0.82
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- containerPort: 3000 - containerPort: 3000
@@ -1356,6 +1356,17 @@ data:
proxy_set_header Connection '$connection_upgrade'; proxy_set_header Connection '$connection_upgrade';
more_set_headers 'Upgrade: $http_upgrade'; more_set_headers 'Upgrade: $http_upgrade';
} }
location /api/refresh {
add_header Access-Control-Allow-Headers "access-control-allow-headers,access-control-allow-methods,access-control-allow-origin,content-type,x-auth,x-unauth-error,x-authorization";
add_header Access-Control-Allow-Methods "PUT, GET, DELETE, POST, OPTIONS";
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;
proxy_pass http://authelia-backend-svc:9091;
proxy_set_header Host $host;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header X-Frame-Options SAMEORIGIN;
}
location / { location / {
proxy_pass http://headscale-server-svc:8080; proxy_pass http://headscale-server-svc:8080;
proxy_http_version 1.1; proxy_http_version 1.1;

View File

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

View File

@@ -17,4 +17,203 @@ This directory contains the code for system applications, primarily for LarePass
| Settings | A system configuration application. | | Settings | A system configuration application. |
| Dashboard | An app for monitoring system resource usage. | | Dashboard | An app for monitoring system resource usage. |
| Control Hub | The console for Olares, providing precise and autonomous control over the system and its environment. | | Control Hub | The console for Olares, providing precise and autonomous control over the system and its environment. |
| DevBox | A development tool for building and deploying Olares applications. | | Studio | A development tool for building and deploying Olares applications. |
# Local Development Guide
This document describes how to start and develop various sub-projects locally.
## Available Projects
| Project | Command | Port |
|---------|---------|------|
| Desktop | `npm run dev:desktop` | 1090 |
| Files | `npm run dev:files` | 5090 |
| Settings | `npm run dev:settings` | 9000 |
| Market | `npm run dev:market` | 8080 |
| Vault | `npm run dev:vault` | 8090 |
| Wise | `npm run dev:wise` | 8100 |
| Dashboard | `npm run dev:dashboard` | 9003 |
| Control Hub | `npm run dev:hub` | 9002 |
| Share | `npm run dev:share` | 5070 |
| Editor | `npm run dev:editor` | 9100 |
| Preview | `npm run dev:preview` | 9001 |
| Studio | `npm run dev:studio` | 9001 |
## Step 1: Modify Local Hosts File
Projects require access through a specific domain name. You need to configure the local hosts file first.
### macOS / Linux
1. Open terminal and edit the hosts file with administrator privileges:
```bash
sudo vim /etc/hosts
```
Or use the nano editor:
```bash
sudo nano /etc/hosts
```
2. Add the following content at the end of the file:
```
127.0.0.1 test.xxx.olares.com
```
3. Save the file and exit
- vim: Press `ESC`, type `:wq` and press Enter
- nano: Press `Ctrl + O` to save, `Ctrl + X` to exit
### Windows
1. Run Notepad as administrator:
- Search for "Notepad" in the Start menu
- Right-click on "Notepad" and select "Run as administrator"
2. Open the hosts file in Notepad:
- Click `File` -> `Open`
- Paste the path in the filename field: `C:\Windows\System32\drivers\etc\hosts`
- Change file type to "All Files (*.*)"
- Click "Open"
3. Add the following content at the end of the file:
```
127.0.0.1 test.xxx.olares.com
```
4. Save the file (`Ctrl + S`)
5. Flush DNS cache (optional):
- Open Command Prompt (CMD) as administrator
- Run the following command:
```cmd
ipconfig /flushdns
```
## Step 2: Install Dependencies
Run in the project root directory (`olares-app`):
```bash
npm install
```
## Step 3: Configure Environment Variables
Create or edit the `.env` file in the `packages/app` directory and add the following content:
```env
ACCOUNT_DOMAIN=xxx.olares.com
DEV_DOMAIN=test.xxx.olares.com
```
> **Note**:
> - `ACCOUNT_DOMAIN`: Your Olares account domain, used for API proxy
> - `DEV_DOMAIN`: Local development server domain, must match the domain configured in the hosts file
## Step 4: Start the Project
After configuring the `.env` file, run the corresponding command in the `packages/app` directory:
```bash
# Start Desktop
npm run dev:desktop
# Start Files
npm run dev:files
# Start Settings
npm run dev:settings
# Start Market
npm run dev:market
# Start other projects...
npm run dev:<project>
```
## Step 5: Access the Application
After successful startup, visit in your browser (replace port according to the project):
| Project | URL |
|---------|-----|
| Desktop | `https://test.xxx.olares.com:1090` |
| Files | `https://test.xxx.olares.com:5090` |
| Settings | `https://test.xxx.olares.com:9000` |
| Market | `https://test.xxx.olares.com:8080` |
| Vault | `https://test.xxx.olares.com:8090` |
| Wise | `https://test.xxx.olares.com:8100` |
| Dashboard | `https://test.xxx.olares.com:9003` |
| Control Hub | `https://test.xxx.olares.com:9002` |
| Share | `https://test.xxx.olares.com:5070` |
| Editor | `https://test.xxx.olares.com:9100` |
| Preview | `https://test.xxx.olares.com:9001` |
| Studio | `https://test.xxx.olares.com:9001` |
> **Note**: Since a self-signed certificate is used, the browser may display an insecure connection warning. Click "Advanced" and select "Proceed" to continue.
## Environment Variables (.env file)
| Variable | Description | Example |
|----------|-------------|---------|
| `ACCOUNT_DOMAIN` | Account domain (for API proxy) | `xxx.olares.com` |
| `DEV_DOMAIN` | Development server domain | `test.xxx.olares.com` |
## FAQ
### 1. Cannot Access the Application
- Check if the hosts file is configured correctly
- Ensure the development server has started successfully
- Check if the firewall is blocking the corresponding port
### 2. Certificate Error
The development server uses HTTPS. The browser will show a certificate warning on first visit - this is expected behavior.
### 3. API Request Failed
Ensure the `ACCOUNT_DOMAIN` in the `.env` file is set correctly. The proxy configuration relies on this variable to forward requests to the correct backend service.
## Build for Production
```bash
# Build Desktop
npm run build:desktop
# Build Files
npm run build:files
# Build Settings
npm run build:settings
# Build other projects...
npm run build:<project>
```
### Build Output Directory
| Project | Output Directory |
|---------|------------------|
| Desktop | `dist/apps/desktop` |
| Files | `dist/apps/files` |
| Settings | `dist/apps/settings` |
| Market | `dist/apps/market` |
| Vault | `dist/apps/vault` |
| Dashboard | `dist/apps/dashboard` |
| Control Hub | `dist/apps/control-hub` |
| Share | `dist/apps/share` |
| Editor | `dist/apps/editor` |
| Preview | `dist/apps/preview` |
| **Wise** | `dist/spa` |
| **Studio** | `dist/spa` |
> **Note**: Build outputs for Wise and Studio are located in `dist/spa` directory, not under `dist/apps/`.

View File

@@ -1,2 +1,2 @@
DEV_DOMAIN=test.guotest334.olares.cn DEV_DOMAIN=test.xxx.olares.com
ACCOUNT_DOMAIN=guotest334.olares.cn ACCOUNT_DOMAIN=xxx.olares.com

View File

@@ -62,6 +62,8 @@ module.exports = configure(function (ctx) {
env: { env: {
PL_SERVER_URL: process.env.PL_SERVER_URL, PL_SERVER_URL: process.env.PL_SERVER_URL,
VAULT_MOCK_BFL_TOKEN: process.env.VAULT_MOCK_BFL_TOKEN,
VAULT_MOCK_PASSWORD: process.env.VAULT_MOCK_PASSWORD,
PLATFORM: process.env.PLATFORM, PLATFORM: process.env.PLATFORM,
DEV_PLATFORM: process.env.DEV_PLATFORM, DEV_PLATFORM: process.env.DEV_PLATFORM,
APPLICATION_SUB: process.env.APPLICATION_SUB, APPLICATION_SUB: process.env.APPLICATION_SUB,

View File

@@ -107,4 +107,6 @@ export interface NativeAppPlatform extends AppPlatform {
getQuasar(): QVueGlobals | undefined; getQuasar(): QVueGlobals | undefined;
getRouter(): Router | undefined; getRouter(): Router | undefined;
} }

View File

@@ -78,4 +78,16 @@ export interface AppPlatform extends Platform, PlatformExtension {
isTabbarDisplay(): boolean; isTabbarDisplay(): boolean;
userAgent: string; userAgent: string;
socialKeys: {
facebook: {
appId: string;
clientToken: string;
},
google: {
webClientId: string;
iOSClientId: string;
androidClientId: string;
}
}
} }

View File

@@ -9,6 +9,7 @@ import { ClientSchema } from '../../../../globals';
import { i18n } from '../../../../boot/i18n'; import { i18n } from '../../../../boot/i18n';
import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc'; import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc';
import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social'; import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social';
import { getAppPlatform } from 'src/application/platform';
export async function facebookLogin( export async function facebookLogin(
did: string, did: string,
@@ -22,12 +23,8 @@ export async function facebookLogin(
} }
const manifest = stringToBase64(JSON.stringify(schema?.manifest)); const manifest = stringToBase64(JSON.stringify(schema?.manifest));
// await FacebookLogin.initialize({ appId: '549140590110570' });
await LarePassSocialLogin.initialize({ await LarePassSocialLogin.initialize({
facebook: { facebook: getAppPlatform().socialKeys.facebook
appId: '549140590110570',
clientToken: '82fca90b3fa47e9083aa7dba75744ee0'
}
}); });
const FACEBOOK_PERMISSIONS = ['email']; const FACEBOOK_PERMISSIONS = ['email'];

View File

@@ -5,6 +5,7 @@ import { ClientSchema } from '../../../../globals';
import { i18n } from '../../../../boot/i18n'; import { i18n } from '../../../../boot/i18n';
import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc'; import { VCCardInfo, getSubmitApplicationJWS } from 'src/utils/vc';
import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social'; import { LarePassSocialLogin } from 'src/platform/interface/capacitor/plugins/social';
import { getAppPlatform } from 'src/application/platform';
export async function googleLogin( export async function googleLogin(
did: string, did: string,
@@ -22,10 +23,10 @@ export async function googleLogin(
await LarePassSocialLogin.initialize({ await LarePassSocialLogin.initialize({
google: { google: {
webClientId: webClientId:
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms getAppPlatform().socialKeys.google.webClientId,
iOSClientId: iOSClientId:
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS getAppPlatform().socialKeys.google.iOSClientId,
mode: 'online' // replaces grantOfflineAccess mode: 'online'
} }
}); });
await LarePassSocialLogin.logout({ provider: 'google' }); await LarePassSocialLogin.logout({ provider: 'google' });

View File

@@ -45,15 +45,14 @@ export default defineComponent({
const bfl_token = ref<string>(''); const bfl_token = ref<string>('');
if (process.env.PL_SERVER_URL) { if (process.env.PL_SERVER_URL) {
bfl_token.value = bfl_token.value = process.env.VAULT_MOCK_BFL_TOKEN;
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg3NzU0OTQsImlhdCI6MTY3ODc2ODI5NCwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.Yr7OhrQ39OXmesVJldORZ34UsFZpiiCWpssKlRxEOR4';
} }
const url = ref<string>( const url = ref<string>(
base_url + base_url +
'?bfl_token=' + '?bfl_token=' +
bfl_token.value + bfl_token.value +
'&username=liuyu&password=Test123456' `&username=liuyu&password=${process.env.VAULT_MOCK_PASSWORD}`
); );
const { t } = useI18n(); const { t } = useI18n();

View File

@@ -112,7 +112,6 @@ const genOlares = async ({ text, from, to }) => {
const init = { const init = {
headers: { headers: {
'Content-type': 'application/json' 'Content-type': 'application/json'
// 'X-Authorization': 'eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NzMzMjE1MjUsImlhdCI6MTc0MTc4NTUyNSwidXNlcm5hbWUiOiJ5YW5neW9uZ2hlbmciLCJncm91cHMiOlsibGxkYXBfcmVndWxhciJdfQ.V3CHWllD4GETOklamEg-hwhT5DR4lKZGLEgpOULpW_ZXuZ-MTYvOFoZatWVWs6wQjT8IrLHF6leyUI09qsgZuw'
}, },
method: 'POST', method: 'POST',
body: JSON.stringify(params) body: JSON.stringify(params)

View File

@@ -70,4 +70,16 @@ export class SubAppPlatform extends WebPlatform implements AppPlatform {
} }
userAgent = navigator.userAgent; userAgent = navigator.userAgent;
socialKeys = {
facebook: {
appId: '',
clientToken: ''
},
google: {
webClientId: '',
iOSClientId: '',
androidClientId: ''
}
};
} }

View File

@@ -19,10 +19,9 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
]; ];
await LarePassSocialLogin.initialize({ await LarePassSocialLogin.initialize({
google: { google: {
webClientId: webClientId: getAppPlatform().socialKeys.google.webClientId,
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms
iOSClientId: iOSClientId:
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS getAppPlatform().socialKeys.google.iOSClientId,
mode: getAppPlatform().getQuasar()?.platform.is?.android mode: getAppPlatform().getQuasar()?.platform.is?.android
? 'offline' ? 'offline'
: 'online' // replaces grantOfflineAccess : 'online' // replaces grantOfflineAccess
@@ -45,8 +44,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
let clientId = ''; let clientId = '';
if (getAppPlatform().getQuasar()?.platform.is?.android) { if (getAppPlatform().getQuasar()?.platform.is?.android) {
clientId = clientId = getAppPlatform().socialKeys.google.androidClientId;
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com';
response = await axiosInstanceProxy( response = await axiosInstanceProxy(
{ {
baseURL: 'https://cloud-api.jointerminus.com/', baseURL: 'https://cloud-api.jointerminus.com/',
@@ -68,8 +66,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
); );
} }
} else { } else {
clientId = clientId = getAppPlatform().socialKeys.google.iOSClientId;
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com';
} }
const result = { const result = {

View File

@@ -5,6 +5,16 @@ import level from 'level';
const TERMINUS_NAME = process.env.TERMINUS_NAME || 'did'; const TERMINUS_NAME = process.env.TERMINUS_NAME || 'did';
const REFRESH_TOKEN = process.env.REFRESH_TOKEN || '';
const ACCESS_TOKEN = process.env.ACCESS_TOKEN || '';
const SESSION_ID = process.env.SESSION_ID || '';
const BASE32_SECRET = process.env.BASE32_SECRET || ''
const OTP_AUTH_URL = process.env.OPT_AUTH_URL || '';
export interface UserInfo { export interface UserInfo {
olaresId: string; olaresId: string;
wizardStatus: string; wizardStatus: string;
@@ -259,9 +269,8 @@ export class ApiControllers {
const result = { const result = {
status: 'OK', status: 'OK',
data: { data: {
base32_secret: 'Z6JJH64KWRFXPBHTHVPF2XZT6INZEKVTMSLWPIFNKXXS2FSZ3QUQ', base32_secret: BASE32_SECRET,
otpauth_url: otpauth_url: OTP_AUTH_URL
'otpauth://totp/authelia.com:liuyu?algorithm=SHA1&digits=6&issuer=authelia.com&period=30&secret=Z6JJH64KWRFXPBHTHVPF2XZT6INZEKVTMSLWPIFNKXXS2FSZ3QUQ'
} }
}; };
@@ -294,14 +303,6 @@ export class ApiControllers {
const username = request.body['username']; const username = request.body['username'];
const password = request.body['password']; const password = request.body['password'];
// if (password !== '123456') {
// response.set('Content-Type', 'application/json');
// response.status(401).send({
// status: 'Failed'
// });
// return;
// }
if (username != TERMINUS_NAME.split('@')[0]) { if (username != TERMINUS_NAME.split('@')[0]) {
response.set('Content-Type', 'application/json'); response.set('Content-Type', 'application/json');
@@ -314,13 +315,11 @@ export class ApiControllers {
const result = { const result = {
status: 'OK', status: 'OK',
data: { data: {
access_token: access_token: ACCESS_TOKEN,
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE', refresh_token: REFRESH_TOKEN,
refresh_token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
fa2: true, fa2: true,
redirect: '', redirect: '',
session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU' session_id: SESSION_ID
} }
}; };
@@ -334,20 +333,13 @@ export class ApiControllers {
const result: any = { const result: any = {
status: 'OK', status: 'OK',
data: { data: {
access_token: access_token: ACCESS_TOKEN,
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE', refresh_token: REFRESH_TOKEN,
refresh_token:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
fa2: true, fa2: true,
redirect: '/abcd', redirect: '/abcd',
session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU' session_id: SESSION_ID
} }
}; };
// if (request.body.token !== '123456') {
// result = {
// status: 'Failed'
// };
// }
response.set('Content-Type', 'application/json'); response.set('Content-Type', 'application/json');
response.send(result); response.send(result);

View File

@@ -1044,16 +1044,6 @@ export class Controller extends API {
// } // }
// } // }
// {
// @didvault/server: status: 'OK',
// @didvault/server: data: {
// @didvault/server: redirect: '',
// @didvault/server: access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODAyNTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6ImFjY2Vzc190b2tlbiIsInVzZXJuYW1lIjoibGl1eXUifQ.XkgDarLaKOGoeTd-GPKlQgYveq8dhXLt23Npk25s3NE',
// @didvault/server: refresh_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Nzg4ODc0NTYsImlhdCI6MTY3ODg3MzA1NiwiaXNzIjoia3ViZXNwaGVyZSIsInN1YiI6ImxpdXl1IiwidG9rZW5fdHlwZSI6InJlZnJlc2hfdG9rZW4iLCJ1c2VybmFtZSI6ImxpdXl1In0.H2RTrWAsQDsPNhJZ9ymhIKuff-chvXS3GfYNB9iATxg',
// @didvault/server: fa2: true,
// @didvault/server: session_id: 'c_V0aaZ1mxmBl*In$^k^d^oOITFepIkU'
// @didvault/server: }
// @didvault/server: }
// async cert_firstfactor( // async cert_firstfactor(
// username: string, // username: string,
// password: string, // password: string,

View File

@@ -18,7 +18,7 @@ fi
if [[ x"$VERSION" == x"" ]]; then if [[ x"$VERSION" == x"" ]]; then
if [[ "$LOCAL_RELEASE" == "1" ]]; then if [[ "$LOCAL_RELEASE" == "1" ]]; then
ts=$(date +%Y%m%d%H%M%S) ts=$(date +%Y%m%d%H%M%S)
export VERSION="1.12.4-$ts" export VERSION="1.12.5-$ts"
echo "will build and use a local release of Olares with version: $VERSION" echo "will build and use a local release of Olares with version: $VERSION"
echo "" echo ""
else else
@@ -28,7 +28,7 @@ fi
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then 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 "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
echo "for example: VERSION=1.12.4-20241124 bash $0" echo "for example: VERSION=1.12.5-20241124 bash $0"
exit 1 exit 1
fi fi

View File

@@ -158,7 +158,7 @@ export VERSION="#__VERSION__"
if [[ "x${VERSION}" == "x" || "x${VERSION:3}" == "xVERSION__" ]]; then 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 "error: Olares version is unspecified, please set the VERSION env var and rerun this script."
echo "for example: VERSION=1.12.4-20241124 bash $0" echo "for example: VERSION=1.12.5-20241124 bash $0"
exit 1 exit 1
fi fi

View File

@@ -36,6 +36,10 @@ fi
find $BASE_DIR/../ -type f -name Olares.yaml | while read f; do find $BASE_DIR/../ -type f -name Olares.yaml | while read f; do
if [[ "$f" == *"/vendor/"* ]]; then
echo "skip vendor file $f"
continue
fi
echo "Processing $f" echo "Processing $f"
declare -a bins declare -a bins
IFS= IFS=

View File

@@ -0,0 +1,21 @@
package amdgpu
import (
"log"
"github.com/beclab/Olares/cli/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdAmdGpuInstall() *cobra.Command {
cmd := &cobra.Command{
Use: "install",
Short: "Install AMD ROCm stack via amdgpu-install",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.AmdGpuInstall(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -0,0 +1,16 @@
package amdgpu
import "github.com/spf13/cobra"
func NewCmdAmdGpu() *cobra.Command {
cmd := &cobra.Command{
Use: "amdgpu",
Short: "Manage AMD GPU ROCm stack",
}
cmd.AddCommand(NewCmdAmdGpuInstall())
cmd.AddCommand(NewCmdAmdGpuUninstall())
cmd.AddCommand(NewCmdAmdGpuStatus())
return cmd
}

View File

@@ -0,0 +1,21 @@
package amdgpu
import (
"log"
"github.com/beclab/Olares/cli/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdAmdGpuStatus() *cobra.Command {
cmd := &cobra.Command{
Use: "status",
Short: "Show AMD GPU driver and ROCm status",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.AmdGpuStatus(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -0,0 +1,21 @@
package amdgpu
import (
"log"
"github.com/beclab/Olares/cli/pkg/pipelines"
"github.com/spf13/cobra"
)
func NewCmdAmdGpuUninstall() *cobra.Command {
cmd := &cobra.Command{
Use: "uninstall",
Short: "Uninstall AMD ROCm stack via amdgpu-install",
Run: func(cmd *cobra.Command, args []string) {
if err := pipelines.AmdGpuUninstall(); err != nil {
log.Fatalf("error: %v", err)
}
},
}
return cmd
}

View File

@@ -3,19 +3,24 @@ package os
import ( import (
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"context"
"fmt" "fmt"
"io" "io"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"log" "log"
"net" "net"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
ctrl "sigs.k8s.io/controller-runtime"
"strings" "strings"
"time" "time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
ctrl "sigs.k8s.io/controller-runtime"
"github.com/beclab/Olares/cli/pkg/common" "github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/util" "github.com/beclab/Olares/cli/pkg/core/util"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -242,7 +247,6 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
logFile.Close() logFile.Close()
return fmt.Errorf("failed to collect logs for %s: %v", service, err) return fmt.Errorf("failed to collect logs for %s: %v", service, err)
continue
} }
logFile.Close() logFile.Close()
@@ -276,7 +280,7 @@ func collectSystemdLogs(tw *tar.Writer, options *LogCollectOptions) error {
} }
func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error { func collectDmesgLogs(tw *tar.Writer, options *LogCollectOptions) error {
cmd := exec.Command("dmesg") cmd := exec.Command("dmesg -T")
output, err := cmd.Output() output, err := cmd.Output()
if err != nil { if err != nil {
return err return err
@@ -375,49 +379,153 @@ func collectKubernetesLogs(tw *tar.Writer, options *LogCollectOptions) error {
} }
} }
cmd = exec.Command("kubectl", "describe", "pods", "--all-namespaces") resourceTypes := []string{"node", "pod", "statefulset", "deployment", "replicaset", "service", "configmap"}
output, err = tryKubectlCommand(cmd, "describe pods", options)
if err != nil && !options.IgnoreKubeErrors { for _, res := range resourceTypes {
return err cmd = exec.Command("kubectl", "describe", res, "--all-namespaces")
} output, err = tryKubectlCommand(cmd, fmt.Sprintf("describe %s", res), options)
if err == nil { if err != nil && !options.IgnoreKubeErrors {
header := &tar.Header{ return err
Name: "pods-describe.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
} }
if err := tw.WriteHeader(header); err != nil { if err == nil {
return fmt.Errorf("failed to write pods description header: %v", err) header := &tar.Header{
} Name: fmt.Sprintf("%s-describe.txt", res),
if _, err := tw.Write(output); err != nil { Mode: 0644,
return fmt.Errorf("failed to write pods description data: %v", err) Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write %s description header: %v", res, err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write %s description data: %v", res, err)
}
} }
} }
cmd = exec.Command("kubectl", "describe", "node") if err := collectNginxLogsFromLabeledPods(tw); err != nil {
output, err = tryKubectlCommand(cmd, "describe node", options) if !options.IgnoreKubeErrors {
if err != nil && !options.IgnoreKubeErrors { return fmt.Errorf("failed to collect nginx logs from labeled pods: %v", err)
return err
}
if err == nil {
header := &tar.Header{
Name: "node-describe.txt",
Mode: 0644,
Size: int64(len(output)),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write node description header: %v", err)
}
if _, err := tw.Write(output); err != nil {
return fmt.Errorf("failed to write node description data: %v", err)
} }
} }
return nil return nil
} }
func collectNginxLogsFromLabeledPods(tw *tar.Writer) error {
if _, err := util.GetCommand("kubectl"); err != nil {
fmt.Printf("warning: kubectl not found, skipping collecting nginx logs from labeled pods\n")
return nil
}
cfg, err := ctrl.GetConfig()
if err != nil {
return fmt.Errorf("failed to get kubeconfig: %v", err)
}
clientset, err := kubernetes.NewForConfig(cfg)
if err != nil {
return fmt.Errorf("failed to create kube client: %v", err)
}
type selectorSpec struct {
LabelSelector string
ContainerName string
}
selectors := []selectorSpec{
{LabelSelector: "app=l4-bfl-proxy", ContainerName: ""},
{LabelSelector: "tier=bfl", ContainerName: "ingress"},
}
type targetPod struct {
Namespace string
Name string
ContainerName string
}
var targets []targetPod
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
for _, sel := range selectors {
podList, err := clientset.CoreV1().Pods(corev1.NamespaceAll).List(ctx, metav1.ListOptions{LabelSelector: sel.LabelSelector})
if err != nil {
return fmt.Errorf("failed to list pods by label %q: %v", sel.LabelSelector, err)
}
for _, pod := range podList.Items {
targets = append(targets, targetPod{
Namespace: pod.Namespace,
Name: pod.Name,
ContainerName: sel.ContainerName,
})
}
}
if len(targets) == 0 {
return nil
}
// simplest approach: use kubectl cp (it already implements copy via tar over exec)
tempDir, err := os.MkdirTemp("", "olares-nginx-logs-*")
if err != nil {
return fmt.Errorf("failed to create temp directory for nginx logs: %v", err)
}
defer os.RemoveAll(tempDir)
files := []string{"/var/log/nginx/access.log", "/var/log/nginx/error.log"}
for _, target := range targets {
for _, remotePath := range files {
base := filepath.Base(remotePath)
archivePath := filepath.Join("nginx", target.Namespace, target.Name, base)
dest := filepath.Join(tempDir, fmt.Sprintf("%s__%s__%s", target.Namespace, target.Name, base))
err := kubectlCopyFile(target.Namespace, target.Name, target.ContainerName, remotePath, dest)
if err != nil {
return fmt.Errorf("failed to kubectl cp %s/%s:%s: %v", target.Namespace, target.Name, remotePath, err)
}
fi, err := os.Stat(dest)
if err != nil {
return fmt.Errorf("failed to stat copied nginx log %s: %v", dest, err)
}
f, err := os.Open(dest)
if err != nil {
return fmt.Errorf("failed to open copied nginx log %s: %v", dest, err)
}
defer f.Close()
header := &tar.Header{
Name: archivePath,
Mode: 0644,
Size: fi.Size(),
ModTime: time.Now(),
}
if err := tw.WriteHeader(header); err != nil {
return fmt.Errorf("failed to write header for %s: %v", archivePath, err)
}
if _, err := io.CopyN(tw, f, header.Size); err != nil {
return fmt.Errorf("failed to write data for %s: %v", archivePath, err)
}
}
}
return nil
}
func kubectlCopyFile(namespace, pod, container, remotePath, destPath string) error {
args := []string{"-n", namespace, "cp"}
if container != "" {
args = append(args, "-c", container)
}
args = append(args, fmt.Sprintf("%s:%s", pod, remotePath), destPath)
cmd := exec.Command("kubectl", args...)
if out, err := cmd.CombinedOutput(); err != nil {
return fmt.Errorf("kubectl %s failed: %v, output: %s", strings.Join(args, " "), err, strings.TrimSpace(string(out)))
}
return nil
}
func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error { func collectNetworkConfigs(tw *tar.Writer, options *LogCollectOptions) error {
if _, err := util.GetCommand("ip"); err == nil { if _, err := util.GetCommand("ip"); err == nil {
cmd := exec.Command("ip", "address") cmd := exec.Command("ip", "address")

View File

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

View File

@@ -1,6 +1,7 @@
package ctl package ctl
import ( import (
"github.com/beclab/Olares/cli/cmd/ctl/amdgpu"
"github.com/beclab/Olares/cli/cmd/ctl/disk" "github.com/beclab/Olares/cli/cmd/ctl/disk"
"github.com/beclab/Olares/cli/cmd/ctl/gpu" "github.com/beclab/Olares/cli/cmd/ctl/gpu"
"github.com/beclab/Olares/cli/cmd/ctl/node" "github.com/beclab/Olares/cli/cmd/ctl/node"
@@ -33,6 +34,7 @@ func NewDefaultCommand() *cobra.Command {
cmds.AddCommand(os.NewOSCommands()...) cmds.AddCommand(os.NewOSCommands()...)
cmds.AddCommand(node.NewNodeCommand()) cmds.AddCommand(node.NewNodeCommand())
cmds.AddCommand(gpu.NewCmdGpu()) cmds.AddCommand(gpu.NewCmdGpu())
cmds.AddCommand(amdgpu.NewCmdAmdGpu())
cmds.AddCommand(user.NewUserCommand()) cmds.AddCommand(user.NewUserCommand())
cmds.AddCommand(disk.NewDiskCommand()) cmds.AddCommand(disk.NewDiskCommand())

View File

@@ -1,15 +1,16 @@
package user package user
import ( import (
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
"context" "context"
"fmt" "fmt"
"log"
"strings"
"github.com/beclab/Olares/cli/pkg/utils" "github.com/beclab/Olares/cli/pkg/utils"
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
"github.com/pkg/errors" "github.com/pkg/errors"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation"
"log"
"strings"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2" iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
"github.com/spf13/cobra" "github.com/spf13/cobra"

View File

@@ -1,16 +1,17 @@
package user package user
import ( import (
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
"fmt" "fmt"
"os"
"strconv"
"time"
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
iamv1alpha2 "github.com/beclab/api/iam/v1alpha2" iamv1alpha2 "github.com/beclab/api/iam/v1alpha2"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
"os"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"strconv"
"time"
) )
func newUserClientFromKubeConfig(kubeconfig string) (client.Client, error) { func newUserClientFromKubeConfig(kubeconfig string) (client.Client, error) {

View File

@@ -1,27 +1,21 @@
module github.com/beclab/Olares/cli module github.com/beclab/Olares/cli
go 1.24.2 go 1.24.11
toolchain go1.24.6
replace ( replace (
bytetrade.io/web3os/app-service => github.com/beclab/app-service v0.4.41
bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17 bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17
github.com/containers/image/v5 => github.com/containers/image/v5 v5.21.1
github.com/containers/storage => github.com/containers/storage v1.40.0
github.com/estesp/manifest-tool/v2 => github.com/estesp/manifest-tool/v2 v2.0.3 github.com/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 ( require (
bytetrade.io/web3os/app-service v0.0.0-00010101000000-000000000000
bytetrade.io/web3os/backups-sdk v0.0.0-00010101000000-000000000000 bytetrade.io/web3os/backups-sdk v0.0.0-00010101000000-000000000000
github.com/Masterminds/semver/v3 v3.4.0 github.com/Masterminds/semver/v3 v3.4.0
github.com/PaesslerAG/jsonpath v0.1.1 github.com/PaesslerAG/jsonpath v0.1.1
github.com/alecthomas/assert/v2 v2.11.0 github.com/alecthomas/assert/v2 v2.11.0
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70
github.com/beclab/api v0.0.2 github.com/beclab/api v0.0.2
github.com/cavaliergopher/grab/v3 v3.0.1 github.com/cavaliergopher/grab/v3 v3.0.1
github.com/containerd/containerd v1.7.28 github.com/containerd/containerd v1.7.29
github.com/decentralized-identity/web5-go v0.25.0 github.com/decentralized-identity/web5-go v0.25.0
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
github.com/distribution/reference v0.6.0 github.com/distribution/reference v0.6.0
@@ -48,10 +42,10 @@ require (
github.com/syndtr/goleveldb v1.0.0 github.com/syndtr/goleveldb v1.0.0
github.com/tyler-smith/go-bip39 v1.1.0 github.com/tyler-smith/go-bip39 v1.1.0
go.uber.org/zap v1.27.0 go.uber.org/zap v1.27.0
golang.org/x/crypto v0.41.0 golang.org/x/crypto v0.45.0
golang.org/x/sys v0.35.0 golang.org/x/sys v0.38.0
golang.org/x/term v0.34.0 golang.org/x/term v0.37.0
golang.org/x/text v0.28.0 golang.org/x/text v0.31.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.18.6 helm.sh/helm/v3 v3.18.6
@@ -94,9 +88,11 @@ require (
github.com/containerd/platforms v0.2.1 // indirect github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/ttrpc v1.2.7 // indirect github.com/containerd/ttrpc v1.2.7 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect github.com/containers/image/v5 v5.36.1 // indirect
github.com/containers/storage v1.59.1 // indirect
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/ebitengine/purego v0.8.4 // indirect github.com/ebitengine/purego v0.8.4 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect
@@ -174,7 +170,7 @@ require (
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect github.com/opencontainers/runtime-spec v1.2.1 // indirect
github.com/opencontainers/selinux v1.12.0 // indirect github.com/opencontainers/selinux v1.13.1 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
@@ -205,10 +201,11 @@ require (
go.uber.org/multierr v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/net v0.43.0 // indirect golang.org/x/net v0.47.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect golang.org/x/sync v0.18.0 // indirect
golang.org/x/time v0.12.0 // indirect golang.org/x/time v0.12.0 // indirect
golang.org/x/tools/godoc v0.1.0-deprecated // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect

View File

@@ -43,10 +43,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/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 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70 h1:U3z6m0hokD1gzl788BrUdxCbDyAjdOBBXA8ilYgn6VQ=
github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70/go.mod h1:D9wl7y3obLqXMqfubMROMgdxWAwInnKNrFC//d0nyIA=
github.com/beclab/api v0.0.2 h1:aD5RcMie2uqa/FZI7aQBa1F4yVEib8/x3IIZSLiHkBM= github.com/beclab/api v0.0.2 h1:aD5RcMie2uqa/FZI7aQBa1F4yVEib8/x3IIZSLiHkBM=
github.com/beclab/api v0.0.2/go.mod h1:ESZLe8cf4934QFkU6cqbskKfiTyNk67i1qbv/ctS6js= github.com/beclab/api v0.0.2/go.mod h1:ESZLe8cf4934QFkU6cqbskKfiTyNk67i1qbv/ctS6js=
github.com/beclab/app-service v0.4.41 h1:WSIXEqHSAepHweBooPkc+pedVaGGn335RugNwixkciY=
github.com/beclab/app-service v0.4.41/go.mod h1:0vEg3rv/DbR7dYznvTlXNXyYNn+TXNMaxz03GQYRWUQ=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 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 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
@@ -68,8 +68,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c= github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs= github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0= github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= 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= github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
@@ -88,13 +88,17 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/containers/image/v5 v5.36.1 h1:6zpXBqR59UcAzoKpa/By5XekeqFV+htWYfr65+Cgjqo=
github.com/containers/image/v5 v5.36.1/go.mod h1:b4GMKH2z/5t6/09utbse2ZiLK/c72GuGLFdp7K69eA4=
github.com/containers/storage v1.59.1 h1:11Zu68MXsEQGBBd+GadPrHPpWeqjKS8hJDGiAHgIqDs=
github.com/containers/storage v1.59.1/go.mod h1:KoAYHnAjP3/cTsRS+mmWZGkufSY2GACiKQ4V3ZLQnR0=
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -105,16 +109,14 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/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 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU= github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI= github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
@@ -262,6 +264,8 @@ github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
@@ -348,6 +352,8 @@ github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/n
github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/nats-io/nats.go v1.45.0 h1:/wGPbnYXDM0pLKFjZTX+2JOw9TQPoIgTFrUaH97giwA= github.com/nats-io/nats.go v1.45.0 h1:/wGPbnYXDM0pLKFjZTX+2JOw9TQPoIgTFrUaH97giwA=
@@ -368,12 +374,12 @@ github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8= github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U= github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
@@ -502,8 +508,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glB
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0 h1:cMyu9O88joYEaI47CnQkxO1XZdpoTF9fEnW2duIddhw= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.32.0/go.mod h1:6Am3rn7P9TVVeXYG+wtcGE7IE1tsQ+bP3AuWcKt/gOI= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU= go.opentelemetry.io/otel/exporters/prometheus v0.54.0 h1:rFwzp68QMgtzu9PgP3jm9XaMICI6TsofWWPcBDKwlsU=
go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU= go.opentelemetry.io/otel/exporters/prometheus v0.54.0/go.mod h1:QyjcV9qDP6VeK5qPyKETvNjmaaEc7+gqjh4SS0ZYzDU=
go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU= go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU=
@@ -542,8 +548,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-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-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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-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-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -552,8 +558,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -564,8 +570,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-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-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-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
@@ -574,8 +580,8 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-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-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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-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-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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -587,14 +593,14 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -606,8 +612,10 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-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-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.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

133
cli/pkg/amdgpu/tasks.go Normal file
View File

@@ -0,0 +1,133 @@
package amdgpu
import (
"fmt"
"os/exec"
"path"
"path/filepath"
"github.com/beclab/Olares/cli/pkg/common"
cc "github.com/beclab/Olares/cli/pkg/core/common"
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/utils"
"github.com/Masterminds/semver/v3"
"github.com/pkg/errors"
)
// InstallAmdRocmModule installs AMD ROCm stack on supported Ubuntu if AMD GPU is present.
type InstallAmdRocmModule struct {
common.KubeModule
}
func (m *InstallAmdRocmModule) Init() {
m.Name = "InstallAMDGPU"
installAmd := &task.RemoteTask{
Name: "InstallAmdRocm",
Hosts: m.Runtime.GetHostsByRole(common.Master),
Action: &InstallAmdRocm{
// no manifest needed
},
Parallel: false,
Retry: 1,
}
m.Tasks = []task.Interface{
installAmd,
}
}
// InstallAmdRocm installs ROCm using amdgpu-install on Ubuntu 22.04/24.04 for AMD GPUs.
type InstallAmdRocm struct {
common.KubeAction
}
func (t *InstallAmdRocm) Execute(runtime connector.Runtime) error {
si := runtime.GetSystemInfo()
if !si.IsLinux() || !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
return nil
}
amdGPUExists, err := utils.HasAmdIGPU(runtime)
if err != nil {
return err
}
// skip rocm install
if !amdGPUExists {
return nil
}
rocmV, _ := utils.RocmVersion()
min := semver.MustParse("7.1.1")
if rocmV != nil && rocmV.LessThan(min) {
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", rocmV.Original(), min.Original())
}
if rocmV != nil && rocmV.GreaterThan(min) {
logger.Warnf("Warning: detected ROCm version %s great than maximum tested version %s")
return nil
}
if rocmV != nil && rocmV.Equal(min) {
logger.Infof("detected ROCm version %s, skip rocm install...", min.Original())
return nil
}
// ensure python3-setuptools and python3-wheel
_, _ = runtime.GetRunner().SudoCmd("apt-get update", false, true)
checkPkgs := "dpkg -s python3-setuptools python3-wheel >/dev/null 2>&1 || DEBIAN_FRONTEND=noninteractive apt-get install -y python3-setuptools python3-wheel"
if _, err := runtime.GetRunner().SudoCmd(checkPkgs, false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install python3-setuptools and python3-wheel")
}
// ensure amdgpu-install exists
if _, err := exec.LookPath("amdgpu-install"); err != nil {
var debURL string
if si.IsUbuntuVersionEqual(connector.Ubuntu2404) {
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/noble/amdgpu-install_7.1.1.70101-1_all.deb"
} else {
debURL = "https://repo.radeon.com/amdgpu-install/7.1.1/ubuntu/jammy/amdgpu-install_7.1.1.70101-1_all.deb"
}
tmpDeb := path.Join(runtime.GetBaseDir(), cc.PackageCacheDir, "gpu", "amdgpu-install_7.1.1.70101-1_all.deb")
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("install -d -m 0755 %s", filepath.Dir(tmpDeb)), false, true); err != nil {
return err
}
cmd := fmt.Sprintf("sh -c 'wget -O %s %s'", tmpDeb, debURL)
if _, err := runtime.GetRunner().SudoCmd(cmd, false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to download amdgpu-install deb")
}
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("DEBIAN_FRONTEND=noninteractive apt-get install -y %s", tmpDeb), false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install amdgpu-install deb")
}
}
// run installer for rocm usecase
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
}
fmt.Println()
logger.Warn("Warning: To enable ROCm, please reboot your machine after installation.")
return nil
}
type AmdgpuInstallAction struct {
common.KubeAction
}
func (t *AmdgpuInstallAction) Execute(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install -y --usecase=rocm", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install AMD ROCm via amdgpu-install")
}
return nil
}
type AmdgpuUninstallAction struct {
common.KubeAction
}
func (t *AmdgpuUninstallAction) Execute(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("amdgpu-install --uninstall -y", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to uninstall AMD ROCm via amdgpu-install")
}
fmt.Println()
logger.Warn("Warning: Please reboot your machine after uninstall to fully remove ROCm components.")
return nil
}

View File

@@ -81,6 +81,7 @@ func (m *RunPrechecksModule) Init() {
new(NvidiaCardArchChecker), new(NvidiaCardArchChecker),
new(NouveauChecker), new(NouveauChecker),
new(CudaChecker), new(CudaChecker),
new(RocmChecker),
} }
runPreChecks := &task.LocalTask{ runPreChecks := &task.LocalTask{
Name: "RunPrechecks", Name: "RunPrechecks",

View File

@@ -372,6 +372,48 @@ func (c *CudaChecker) Check(runtime connector.Runtime) error {
return nil return nil
} }
// RocmChecker checks AMD ROCm version for AMD GPU on Ubuntu 22.04/24.04 only.
type RocmChecker struct{}
func (r *RocmChecker) Name() string {
return "ROCm"
}
func (r *RocmChecker) Check(runtime connector.Runtime) error {
if !runtime.GetSystemInfo().IsLinux() {
return nil
}
si := runtime.GetSystemInfo()
if !si.IsUbuntu() || !(si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
return nil
}
// detect AMD GPU presence
amdGPUExists, err := utils.HasAmdIGPU(runtime)
if err != nil {
return err
}
// no AMD GPU found, no need to check rocm
if !amdGPUExists {
return nil
}
curV, err := utils.RocmVersion()
if err != nil && !os.IsNotExist(err) {
return err
}
if os.IsNotExist(err) {
return nil
}
min := semver.MustParse("7.1.1")
if curV.LessThan(min) {
return fmt.Errorf("detected ROCm version %s, which is lower than required %s; please uninstall existing ROCm/AMDGPU components before installation with command: olares-cli amdgpu uninstall", curV.Original(), min.Original())
}
return nil
}
////////////////////////////////////////////// //////////////////////////////////////////////
// precheck - task // precheck - task

View File

@@ -287,7 +287,7 @@ func (a *Argument) LoadReleaseInfo() error {
return nil return nil
} }
func (a *Argument) SaveReleaseInfo() error { func (a *Argument) SaveReleaseInfo(withoutName bool) error {
if a.BaseDir == "" { if a.BaseDir == "" {
return errors.New("invalid: empty base directory") return errors.New("invalid: empty base directory")
} }
@@ -300,15 +300,17 @@ func (a *Argument) SaveReleaseInfo() error {
ENV_OLARES_VERSION: a.OlaresVersion, ENV_OLARES_VERSION: a.OlaresVersion,
} }
if a.User != nil && a.User.UserName != "" && a.User.DomainName != "" { if !withoutName {
releaseInfoMap["OLARES_NAME"] = fmt.Sprintf("%s@%s", a.User.UserName, a.User.DomainName) if a.User != nil && a.User.UserName != "" && a.User.DomainName != "" {
} else { releaseInfoMap["OLARES_NAME"] = fmt.Sprintf("%s@%s", a.User.UserName, a.User.DomainName)
if util.IsExist(OlaresReleaseFile) { } else {
// if the user is not set, try to load the user name from the release file if util.IsExist(OlaresReleaseFile) {
envs, err := godotenv.Read(OlaresReleaseFile) // if the user is not set, try to load the user name from the release file
if err == nil { envs, err := godotenv.Read(OlaresReleaseFile)
if userName, ok := envs["OLARES_NAME"]; ok { if err == nil {
releaseInfoMap["OLARES_NAME"] = userName if userName, ok := envs["OLARES_NAME"]; ok {
releaseInfoMap["OLARES_NAME"] = userName
}
} }
} }
} }

View File

@@ -51,10 +51,12 @@ func (d DebianVersion) String() string {
} }
const ( const (
Ubuntu20 UbuntuVersion = "20." Ubuntu20 UbuntuVersion = "20."
Ubuntu22 UbuntuVersion = "22." Ubuntu22 UbuntuVersion = "22."
Ubuntu24 UbuntuVersion = "24." Ubuntu24 UbuntuVersion = "24."
Ubuntu25 UbuntuVersion = "25." Ubuntu25 UbuntuVersion = "25."
Ubuntu2204 UbuntuVersion = "22.04"
Ubuntu2404 UbuntuVersion = "24.04"
Debian9 DebianVersion = "9" Debian9 DebianVersion = "9"
Debian10 DebianVersion = "10" Debian10 DebianVersion = "10"

View File

@@ -86,6 +86,14 @@ func IsDir(path string) bool {
return s.IsDir() return s.IsDir()
} }
func IsExecutable(path string) bool {
info, err := os.Stat(path)
if err != nil {
return false
}
return info.Mode().Perm()&0111 != 0
}
func CountDirFiles(dirName string) int { func CountDirFiles(dirName string) int {
if !IsDir(dirName) { if !IsDir(dirName) {
return 0 return 0

View File

@@ -187,7 +187,7 @@ func (m *InstallPluginModule) Init() {
Prepare: &prepare.PrepareCollection{ Prepare: &prepare.PrepareCollection{
new(common.OnlyFirstMaster), new(common.OnlyFirstMaster),
}, },
Action: new(UpdateNodeLabels), Action: new(UpdateNodeGPUInfo),
Parallel: false, Parallel: false,
Retry: 1, Retry: 1,
} }
@@ -223,23 +223,6 @@ func (m *InstallPluginModule) Init() {
} }
} }
type GetCudaVersionModule struct {
common.KubeModule
}
func (g *GetCudaVersionModule) Init() {
g.Name = "GetCudaVersion"
getCudaVersion := &task.LocalTask{
Name: "GetCudaVersion",
Action: new(GetCudaVersion),
}
g.Tasks = []task.Interface{
getCudaVersion,
}
}
type NodeLabelingModule struct { type NodeLabelingModule struct {
common.KubeModule common.KubeModule
} }
@@ -253,7 +236,7 @@ func (l *NodeLabelingModule) Init() {
new(CudaInstalled), new(CudaInstalled),
new(CurrentNodeInK8s), new(CurrentNodeInK8s),
}, },
Action: new(UpdateNodeLabels), Action: new(UpdateNodeGPUInfo),
Retry: 1, Retry: 1,
} }

View File

@@ -10,7 +10,10 @@ import (
"strings" "strings"
"time" "time"
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
apputils "github.com/beclab/Olares/framework/app-service/pkg/utils"
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/beclab/Olares/cli/pkg/clientset" "github.com/beclab/Olares/cli/pkg/clientset"
"github.com/beclab/Olares/cli/pkg/common" "github.com/beclab/Olares/cli/pkg/common"
@@ -26,7 +29,11 @@ import (
"github.com/pelletier/go-toml" "github.com/pelletier/go-toml"
"github.com/pkg/errors" "github.com/pkg/errors"
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/util/retry" "k8s.io/client-go/util/retry"
) )
@@ -256,6 +263,10 @@ func (t *PatchK3sDriver) Execute(runtime connector.Runtime) error {
return err return err
} }
if _, err := runtime.GetRunner().SudoCmd("apt install -y strace", false, false); err != nil {
return err
}
if _, err := runtime.GetRunner().SudoCmd(dstName, false, false); err != nil { if _, err := runtime.GetRunner().SudoCmd(dstName, false, false); err != nil {
return errors.Wrap(err, "failed to apply CUDA patch for WSL") return errors.Wrap(err, "failed to apply CUDA patch for WSL")
} }
@@ -323,59 +334,11 @@ func (t *CheckGpuStatus) Execute(runtime connector.Runtime) error {
return fmt.Errorf("GPU Container State is Pending") return fmt.Errorf("GPU Container State is Pending")
} }
type GetCudaVersion struct { type UpdateNodeGPUInfo struct {
common.KubeAction common.KubeAction
} }
func (g *GetCudaVersion) Execute(runtime connector.Runtime) error { func (u *UpdateNodeGPUInfo) Execute(runtime connector.Runtime) error {
var nvidiaSmiFile string
var systemInfo = runtime.GetSystemInfo()
switch {
case systemInfo.IsWsl():
nvidiaSmiFile = "/usr/lib/wsl/lib/nvidia-smi"
default:
nvidiaSmiFile = "/usr/bin/nvidia-smi"
}
if !util.IsExist(nvidiaSmiFile) {
logger.Info("nvidia-smi not exists")
return nil
}
var cudaVersion string
res, err := runtime.GetRunner().Cmd(fmt.Sprintf("%s --version", nvidiaSmiFile), false, true)
if err != nil {
logger.Errorf("get cuda version error %v", err)
return nil
}
lines := strings.Split(res, "\n")
if len(lines) == 0 {
return nil
}
for _, line := range lines {
if strings.Contains(line, "CUDA Version") {
parts := strings.Split(line, ":")
if len(parts) != 2 {
break
}
cudaVersion = strings.TrimSpace(parts[1])
}
}
if cudaVersion != "" {
common.SetSystemEnv("OLARES_SYSTEM_CUDA_VERSION", cudaVersion)
}
return nil
}
type UpdateNodeLabels struct {
common.KubeAction
}
func (u *UpdateNodeLabels) Execute(runtime connector.Runtime) error {
client, err := clientset.NewKubeClient() client, err := clientset.NewKubeClient()
if err != nil { if err != nil {
return errors.Wrap(errors.WithStack(err), "kubeclient create error") return errors.Wrap(errors.WithStack(err), "kubeclient create error")
@@ -482,6 +445,85 @@ func UpdateNodeGpuLabel(ctx context.Context, client kubernetes.Interface, driver
} }
} }
if cuda != nil && *cuda != "" {
if err := updateCudaVersionSystemEnv(ctx, *cuda); err != nil {
logger.Errorf("failed to update SystemEnv for CUDA version: %v", err)
return err
}
}
return nil
}
func updateCudaVersionSystemEnv(ctx context.Context, cudaVersion string) error {
envName := "OLARES_SYSTEM_CUDA_VERSION"
common.SetSystemEnv(envName, cudaVersion)
config, err := ctrl.GetConfig()
if err != nil {
return fmt.Errorf("failed to get rest config: %w", err)
}
apix, err := apixclientset.NewForConfig(config)
if err != nil {
return fmt.Errorf("failed to create crd client: %w", err)
}
_, err = apix.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, "systemenvs.sys.bytetrade.io", metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
logger.Debugf("SystemEnv CRD not found, skipping CUDA version update")
return nil
}
return fmt.Errorf("failed to get SystemEnv CRD: %w", err)
}
scheme := kruntime.NewScheme()
if err := v1alpha1.AddToScheme(scheme); err != nil {
return fmt.Errorf("failed to add systemenv scheme: %w", err)
}
c, err := ctrlclient.New(config, ctrlclient.Options{Scheme: scheme})
if err != nil {
return fmt.Errorf("failed to create client: %w", err)
}
resourceName, err := apputils.EnvNameToResourceName(envName)
if err != nil {
return fmt.Errorf("invalid system env name: %s", envName)
}
var existingSystemEnv v1alpha1.SystemEnv
err = c.Get(ctx, types.NamespacedName{Name: resourceName}, &existingSystemEnv)
if err == nil {
if existingSystemEnv.Default != cudaVersion {
existingSystemEnv.Default = cudaVersion
if err := c.Update(ctx, &existingSystemEnv); err != nil {
return fmt.Errorf("failed to update SystemEnv %s: %w", resourceName, err)
}
logger.Infof("Updated SystemEnv %s default to %s", resourceName, cudaVersion)
}
return nil
}
if !apierrors.IsNotFound(err) {
return fmt.Errorf("failed to get SystemEnv %s: %w", resourceName, err)
}
systemEnv := &v1alpha1.SystemEnv{
ObjectMeta: metav1.ObjectMeta{
Name: resourceName,
},
EnvVarSpec: v1alpha1.EnvVarSpec{
EnvName: envName,
Default: cudaVersion,
},
}
if err := c.Create(ctx, systemEnv); err != nil && !apierrors.IsAlreadyExists(err) {
return fmt.Errorf("failed to create SystemEnv %s: %w", resourceName, err)
}
logger.Infof("Created SystemEnv: %s with default %s", envName, cudaVersion)
return nil return nil
} }

View File

@@ -10,17 +10,39 @@ var (
K3sCudaFixValues = template.Must(template.New("cuda_lib_fix.sh").Parse( K3sCudaFixValues = template.Must(template.New("cuda_lib_fix.sh").Parse(
dedent.Dedent(`#!/bin/bash dedent.Dedent(`#!/bin/bash
sh_c="sh -c" sh_c="sh -c"
real_driver=$($sh_c "find /usr/lib/wsl/drivers/ -name libcuda.so.1.1|head -1") real_driver=""
real_nvml=""
# Try to find the real driver path via strace
real_driver_path=$($sh_c "strace -qq -e trace=openat /usr/lib/wsl/lib/nvidia-smi 2>&1|grep '/usr/lib/wsl/drivers'|grep libnvidia-ml.so.1|awk '{print \$2}'|sed 's/[\",]//g'|sed 's/libnvidia-ml.so.1//g'")
if [[ x"$real_driver_path" != x"" ]]; then
real_driver="${real_driver_path}libcuda.so.1.1"
real_nvml="${real_driver_path}libnvidia-ml.so.1"
else
driver_path=$($sh_c "strace -qq -e trace=openat /usr/lib/wsl/lib/nvidia-smi 2>&1|grep '/usr/lib/wsl/'|grep libnvidia-ml.so.1")
if [[ x"$driver_path" != x"" ]]; then
echo "already fixed cuda libs, exit now."
exit 0
fi
fi
if [[ x"$real_driver" == x"" ]]; then
real_driver=$($sh_c "find /usr/lib/wsl/drivers/ -name libcuda.so.1.1|head -1")
real_nvml=$($sh_c "find /usr/lib/wsl/drivers/ -name libnvidia-ml.so.1|head -1")
fi
if [[ x"$real_driver" != x"" ]]; then if [[ x"$real_driver" != x"" ]]; then
$sh_c "ln -s /usr/lib/wsl/lib/libcuda* /usr/lib/x86_64-linux-gnu/"
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so" $sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so"
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1" $sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1"
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1.1" $sh_c "rm -f /usr/lib/x86_64-linux-gnu/libcuda.so.1.1"
$sh_c "rm -f /usr/lib/x86_64-linux-gnu/libnvidia-ml.so.1"
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so" $sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so"
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1" $sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1"
$sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1.1" $sh_c "cp -f $real_driver /usr/lib/wsl/lib/libcuda.so.1.1"
$sh_c "ln -s $real_driver /usr/lib/x86_64-linux-gnu/libcuda.so.1" $sh_c "cp -f $real_nvml /usr/lib/wsl/lib/libnvidia-ml.so.1"
$sh_c "ln -s $real_driver /usr/lib/x86_64-linux-gnu/libcuda.so.1.1" $sh_c "cp -f $real_driver /usr/lib/x86_64-linux-gnu/"
$sh_c "cp -f $real_nvml /usr/lib/x86_64-linux-gnu/"
$sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1.1 /usr/lib/x86_64-linux-gnu/libcuda.so.1"
$sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so" $sh_c "ln -s /usr/lib/x86_64-linux-gnu/libcuda.so.1 /usr/lib/x86_64-linux-gnu/libcuda.so"
fi`), fi`),
)) ))

View File

@@ -36,6 +36,7 @@ import (
"github.com/beclab/Olares/cli/pkg/k3s/templates" "github.com/beclab/Olares/cli/pkg/k3s/templates"
"github.com/beclab/Olares/cli/pkg/manifest" "github.com/beclab/Olares/cli/pkg/manifest"
"github.com/beclab/Olares/cli/pkg/registry" "github.com/beclab/Olares/cli/pkg/registry"
"github.com/beclab/Olares/cli/pkg/storage"
) )
type InstallContainerModule struct { type InstallContainerModule struct {
@@ -470,6 +471,18 @@ func (j *JoinNodesModule) Init() {
Parallel: true, Parallel: true,
} }
createSharedLibDirForWorker := &task.RemoteTask{
Name: "CreateSharedLibDir(k3s)",
Desc: "Create shared lib directory on worker",
Hosts: j.Runtime.GetHostsByRole(common.Worker),
Prepare: &prepare.PrepareCollection{
&kubernetes.NodeInCluster{Not: true},
new(common.OnlyWorker),
},
Action: new(storage.CreateSharedLibDir),
Parallel: true,
}
enableK3s := &task.RemoteTask{ enableK3s := &task.RemoteTask{
Name: "EnableK3sService", Name: "EnableK3sService",
Desc: "Enable k3s service", Desc: "Enable k3s service",
@@ -536,6 +549,7 @@ func (j *JoinNodesModule) Init() {
k3sService, k3sService,
k3sEnv, k3sEnv,
k3sRegistryConfig, k3sRegistryConfig,
createSharedLibDirForWorker,
enableK3s, enableK3s,
copyKubeConfigForMaster, copyKubeConfigForMaster,
syncKubeConfigToWorker, syncKubeConfigToWorker,

View File

@@ -195,13 +195,13 @@ func (g *GenerateK3sService) Execute(runtime connector.Runtime) error {
defaultKubeletArs := map[string]string{ defaultKubeletArs := map[string]string{
"kube-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi", "kube-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
"system-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi", "system-reserved": "cpu=200m,memory=250Mi,ephemeral-storage=1Gi",
"eviction-hard": "memory.available<5%,nodefs.available<10%,imagefs.available<10%", "eviction-hard": "memory.available<5%,nodefs.available<5%,imagefs.available<5%",
"config": "/etc/rancher/k3s/kubelet.config", "config": "/etc/rancher/k3s/kubelet.config",
"containerd": container.DefaultContainerdCRISocket, "containerd": container.DefaultContainerdCRISocket,
"cgroup-driver": "systemd", "cgroup-driver": "systemd",
"runtime-request-timeout": "5m", "runtime-request-timeout": "5m",
"image-gc-high-threshold": "91", "image-gc-high-threshold": "96",
"image-gc-low-threshold": "90", "image-gc-low-threshold": "95",
"housekeeping_interval": "5s", "housekeeping_interval": "5s",
} }
defaultKubeProxyArgs := map[string]string{ defaultKubeProxyArgs := map[string]string{
@@ -397,53 +397,23 @@ type CopyK3sKubeConfig struct {
} }
func (c *CopyK3sKubeConfig) Execute(runtime connector.Runtime) error { func (c *CopyK3sKubeConfig) Execute(runtime connector.Runtime) error {
createConfigDirCmd := "mkdir -p /root/.kube && mkdir -p $HOME/.kube" targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
getKubeConfigCmd := "cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config" if err != nil {
chmodKubeConfigCmd := "chmod 0600 /root/.kube/config" return err
}
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd, chmodKubeConfigCmd}, " && ") cmds := []string{
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil { "mkdir -p /root/.kube",
"cp -f /etc/rancher/k3s/k3s.yaml /root/.kube/config",
"chmod 0600 /root/.kube/config",
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
fmt.Sprintf("cp -f /etc/rancher/k3s/k3s.yaml %s", filepath.Join(targetHome, ".kube", "config")),
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
}
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "copy k3s kube config failed") return errors.Wrap(errors.WithStack(err), "copy k3s kube config failed")
} }
userMkdir := "mkdir -p $HOME/.kube"
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
}
userCopyKubeConfig := "cp -f /etc/rancher/k3s/k3s.yaml $HOME/.kube/config"
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user copy /etc/rancher/k3s/k3s.yaml to $HOME/.kube/config failed")
}
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config 0600 failed")
}
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user id failed")
// }
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
// }
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get user id failed")
}
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get user group id failed")
}
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
}
return nil return nil
} }
@@ -493,59 +463,29 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok { if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
cluster := v.(*K3sStatus) cluster := v.(*K3sStatus)
createConfigDirCmd := "mkdir -p /root/.kube"
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
}
oldServer := "server: https://127.0.0.1:6443" oldServer := "server: https://127.0.0.1:6443"
newServer := fmt.Sprintf("server: https://%s:%d", newServer := fmt.Sprintf("server: https://%s:%d",
s.KubeConf.Cluster.ControlPlaneEndpoint.Domain, s.KubeConf.Cluster.ControlPlaneEndpoint.Domain,
s.KubeConf.Cluster.ControlPlaneEndpoint.Port) s.KubeConf.Cluster.ControlPlaneEndpoint.Port)
newKubeConfig := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1) newKubeConfig := strings.Replace(cluster.KubeConfig, oldServer, newServer, -1)
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config") targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
}
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chmod k3s $HOME/.kube/config failed")
}
userConfigDirCmd := "mkdir -p $HOME/.kube"
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
}
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", newKubeConfig, "$HOME/.kube/config")
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
}
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user id failed")
// }
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
// }
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
if err != nil { if err != nil {
return errors.Wrap(errors.WithStack(err), "get user id failed") return err
} }
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false) cmds := []string{
if err != nil { "mkdir -p /root/.kube",
return errors.Wrap(errors.WithStack(err), "get user group id failed") fmt.Sprintf("echo '%s' > %s", newKubeConfig, "/root/.kube/config"),
"chmod 0600 /root/.kube/config",
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
fmt.Sprintf("echo '%s' > %s", newKubeConfig, targetKubeConfigPath),
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
} }
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId) return errors.Wrap(errors.WithStack(err), "sync kube config failed")
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
} }
} }
return nil return nil

View File

@@ -23,6 +23,7 @@ import (
"github.com/beclab/Olares/cli/pkg/core/prepare" "github.com/beclab/Olares/cli/pkg/core/prepare"
"github.com/beclab/Olares/cli/pkg/core/task" "github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/manifest" "github.com/beclab/Olares/cli/pkg/manifest"
"github.com/beclab/Olares/cli/pkg/storage"
) )
type StatusModule struct { type StatusModule struct {
@@ -243,6 +244,18 @@ func (j *JoinNodesModule) Init() {
Retry: 5, Retry: 5,
} }
createSharedLibDirForWorker := &task.RemoteTask{
Name: "CreateSharedLibDir(k8s)",
Desc: "Create shared lib directory on worker",
Hosts: j.Runtime.GetHostsByRole(common.Worker),
Prepare: &prepare.PrepareCollection{
&NodeInCluster{Not: true},
new(common.OnlyWorker),
},
Action: new(storage.CreateSharedLibDir),
Parallel: true,
}
joinWorkerNode := &task.RemoteTask{ joinWorkerNode := &task.RemoteTask{
Name: "JoinWorkerNode(k8s)", Name: "JoinWorkerNode(k8s)",
Desc: "Join worker node", Desc: "Join worker node",
@@ -323,6 +336,7 @@ func (j *JoinNodesModule) Init() {
j.Tasks = []task.Interface{ j.Tasks = []task.Interface{
generateKubeadmConfig, generateKubeadmConfig,
joinMasterNode, joinMasterNode,
createSharedLibDirForWorker,
joinWorkerNode, joinWorkerNode,
copyKubeConfig, copyKubeConfig,
removeMasterTaint, removeMasterTaint,

View File

@@ -417,51 +417,23 @@ type CopyKubeConfigForControlPlane struct {
} }
func (c *CopyKubeConfigForControlPlane) Execute(runtime connector.Runtime) error { func (c *CopyKubeConfigForControlPlane) Execute(runtime connector.Runtime) error {
createConfigDirCmd := "mkdir -p /root/.kube" targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
getKubeConfigCmd := "cp -f /etc/kubernetes/admin.conf /root/.kube/config" if err != nil {
cmd := strings.Join([]string{createConfigDirCmd, getKubeConfigCmd}, " && ") return err
if _, err := runtime.GetRunner().SudoCmd(cmd, false, false); err != nil { }
cmds := []string{
"mkdir -p /root/.kube",
"cp -f /etc/kubernetes/admin.conf /root/.kube/config",
"chmod 0600 /root/.kube/config",
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
fmt.Sprintf("cp -f /etc/kubernetes/admin.conf %s", filepath.Join(targetHome, ".kube", "config")),
fmt.Sprintf("chmod 0600 %s", filepath.Join(targetHome, ".kube", "config")),
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
}
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "copy kube config failed") return errors.Wrap(errors.WithStack(err), "copy kube config failed")
} }
userMkdir := "mkdir -p $HOME/.kube"
if _, err := runtime.GetRunner().Cmd(userMkdir, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
}
userCopyKubeConfig := "cp -f /etc/kubernetes/admin.conf $HOME/.kube/config"
if _, err := runtime.GetRunner().SudoCmd(userCopyKubeConfig, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user copy /etc/kubernetes/admin.conf to $HOME/.kube/config failed")
}
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 $HOME/.kube/config", false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
}
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user id failed")
// }
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
// }
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get user id failed")
}
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false)
if err != nil {
return errors.Wrap(errors.WithStack(err), "get user group id failed")
}
chownKubeConfig := fmt.Sprintf("chown -R %s:%s $HOME/.kube", userId, userGroupId)
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
}
return nil return nil
} }
@@ -521,53 +493,23 @@ func (s *SyncKubeConfigToWorker) Execute(runtime connector.Runtime) error {
if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok { if v, ok := s.PipelineCache.Get(common.ClusterStatus); ok {
cluster := v.(*KubernetesStatus) cluster := v.(*KubernetesStatus)
createConfigDirCmd := "mkdir -p /root/.kube" targetHome, targetUID, targetGID, err := utils.ResolveSudoUserHomeAndIDs(runtime)
if _, err := runtime.GetRunner().SudoCmd(createConfigDirCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "create .kube dir failed")
}
syncKubeConfigForRootCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config")
if _, err := runtime.GetRunner().SudoCmd(syncKubeConfigForRootCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "sync kube config for root failed")
}
if _, err := runtime.GetRunner().SudoCmd("chmod 0600 /root/.kube/config", false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chmod $HOME/.kube/config failed")
}
userConfigDirCmd := "mkdir -p $HOME/.kube"
if _, err := runtime.GetRunner().Cmd(userConfigDirCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "user mkdir $HOME/.kube failed")
}
syncKubeConfigForUserCmd := fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "$HOME/.kube/config")
if _, err := runtime.GetRunner().Cmd(syncKubeConfigForUserCmd, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "sync kube config for normal user failed")
}
// userId, err := runtime.GetRunner().Cmd("echo $(id -u)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user id failed")
// }
// userGroupId, err := runtime.GetRunner().Cmd("echo $(id -g)", false, false)
// if err != nil {
// return errors.Wrap(errors.WithStack(err), "get user group id failed")
// }
userId, err := runtime.GetRunner().Cmd("echo $SUDO_UID", false, false)
if err != nil { if err != nil {
return errors.Wrap(errors.WithStack(err), "get user id failed") return err
} }
targetKubeConfigPath := filepath.Join(targetHome, ".kube", "config")
userGroupId, err := runtime.GetRunner().Cmd("echo $SUDO_GID", false, false) cmds := []string{
if err != nil { "mkdir -p /root/.kube",
return errors.Wrap(errors.WithStack(err), "get user group id failed") fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, "/root/.kube/config"),
"chmod 0600 /root/.kube/config",
fmt.Sprintf("mkdir -p %s", filepath.Join(targetHome, ".kube")),
fmt.Sprintf("echo '%s' > %s", cluster.KubeConfig, targetKubeConfigPath),
fmt.Sprintf("chmod 0600 %s", targetKubeConfigPath),
fmt.Sprintf("chown -R %s:%s %s", targetUID, targetGID, filepath.Join(targetHome, ".kube")),
} }
if _, err := runtime.GetRunner().SudoCmd(strings.Join(cmds, " && "), false, false); err != nil {
chownKubeConfig := fmt.Sprintf("chown -R %s:%s -R $HOME/.kube", userId, userGroupId) return errors.Wrap(errors.WithStack(err), "sync kube config failed")
if _, err := runtime.GetRunner().SudoCmd(chownKubeConfig, false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "chown user kube config failed")
} }
} }
return nil return nil

View File

@@ -296,8 +296,10 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
"memory": "250Mi", "memory": "250Mi",
}, },
"evictionHard": map[string]string{ "evictionHard": map[string]string{
"memory.available": "5%", "memory.available": "5%",
"pid.available": "10%", "pid.available": "10%",
"nodefs.available": "5%",
"imagefs.available": "5%",
}, },
"evictionSoft": map[string]string{ "evictionSoft": map[string]string{
"memory.available": "10%", "memory.available": "10%",
@@ -309,8 +311,8 @@ func GetKubeletConfiguration(runtime connector.Runtime, kubeConf *common.KubeCon
"evictionPressureTransitionPeriod": "30s", "evictionPressureTransitionPeriod": "30s",
"featureGates": FeatureGatesDefaultConfiguration, "featureGates": FeatureGatesDefaultConfiguration,
"runtimeRequestTimeout": "5m", "runtimeRequestTimeout": "5m",
"imageGCHighThresholdPercent": 91, "imageGCHighThresholdPercent": 96,
"imageGCLowThresholdPercent": 90, "imageGCLowThresholdPercent": 95,
} }
if securityEnhancement { if securityEnhancement {

View File

@@ -111,6 +111,7 @@ func (p *phaseBuilder) phaseInstall() *phaseBuilder {
PhaseFile: common.TerminusStateFileInstalled, PhaseFile: common.TerminusStateFileInstalled,
BaseDir: p.runtime.GetBaseDir(), BaseDir: p.runtime.GetBaseDir(),
}, },
&terminus.WriteReleaseFileModule{WithoutName: true},
) )
} }
return p return p

View File

@@ -58,7 +58,6 @@ func (l *linuxInstallPhaseBuilder) installGpuPlugin() phase {
return []module.Module{ return []module.Module{
&gpu.RestartK3sServiceModule{Skip: !(l.runtime.Arg.Kubetype == common.K3s)}, &gpu.RestartK3sServiceModule{Skip: !(l.runtime.Arg.Kubetype == common.K3s)},
&gpu.InstallPluginModule{Skip: skipGpuPlugin}, &gpu.InstallPluginModule{Skip: skipGpuPlugin},
&gpu.GetCudaVersionModule{},
} }
} }

View File

@@ -3,8 +3,7 @@ package system
import ( import (
"strings" "strings"
"github.com/beclab/Olares/cli/pkg/gpu" "github.com/beclab/Olares/cli/pkg/amdgpu"
"github.com/beclab/Olares/cli/pkg/bootstrap/os" "github.com/beclab/Olares/cli/pkg/bootstrap/os"
"github.com/beclab/Olares/cli/pkg/bootstrap/patch" "github.com/beclab/Olares/cli/pkg/bootstrap/patch"
"github.com/beclab/Olares/cli/pkg/bootstrap/precheck" "github.com/beclab/Olares/cli/pkg/bootstrap/precheck"
@@ -12,6 +11,7 @@ import (
"github.com/beclab/Olares/cli/pkg/container" "github.com/beclab/Olares/cli/pkg/container"
"github.com/beclab/Olares/cli/pkg/core/module" "github.com/beclab/Olares/cli/pkg/core/module"
"github.com/beclab/Olares/cli/pkg/daemon" "github.com/beclab/Olares/cli/pkg/daemon"
"github.com/beclab/Olares/cli/pkg/gpu"
"github.com/beclab/Olares/cli/pkg/images" "github.com/beclab/Olares/cli/pkg/images"
"github.com/beclab/Olares/cli/pkg/k3s" "github.com/beclab/Olares/cli/pkg/k3s"
"github.com/beclab/Olares/cli/pkg/manifest" "github.com/beclab/Olares/cli/pkg/manifest"
@@ -82,6 +82,7 @@ func (l *linuxPhaseBuilder) build() []module.Module {
addModule(&terminus.WriteReleaseFileModule{}). addModule(&terminus.WriteReleaseFileModule{}).
addModule(gpuModuleBuilder(func() []module.Module { addModule(gpuModuleBuilder(func() []module.Module {
return []module.Module{ return []module.Module{
&amdgpu.InstallAmdRocmModule{},
&gpu.InstallDriversModule{ &gpu.InstallDriversModule{
ManifestModule: manifest.ManifestModule{ ManifestModule: manifest.ManifestModule{
Manifest: l.manifestMap, Manifest: l.manifestMap,

101
cli/pkg/pipelines/amdgpu.go Normal file
View File

@@ -0,0 +1,101 @@
package pipelines
import (
"strings"
"github.com/beclab/Olares/cli/pkg/amdgpu"
"github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/action"
"github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/module"
"github.com/beclab/Olares/cli/pkg/core/pipeline"
"github.com/beclab/Olares/cli/pkg/core/task"
)
type singleTaskModule struct {
common.KubeModule
name string
act action.Action
}
func (m *singleTaskModule) Init() {
m.Name = m.name
m.Tasks = []task.Interface{
&task.LocalTask{
Name: m.name,
Action: m.act,
},
}
}
func AmdGpuInstall() error {
arg := common.NewArgument()
arg.SetConsoleLog("amdgpuinstall.log", true)
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
if err != nil {
return err
}
p := &pipeline.Pipeline{
Name: "InstallAMDGPUDrivers",
Runtime: runtime,
Modules: []module.Module{
&amdgpu.InstallAmdRocmModule{},
},
}
return p.Start()
}
func AmdGpuUninstall() error {
arg := common.NewArgument()
arg.SetConsoleLog("amdgpuuninstall.log", true)
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
if err != nil {
return err
}
p := &pipeline.Pipeline{
Name: "UninstallAMDGPUDrivers",
Runtime: runtime,
Modules: []module.Module{
&singleTaskModule{name: "AmdgpuUninstall", act: new(amdgpu.AmdgpuUninstallAction)},
},
}
return p.Start()
}
func AmdGpuStatus() error {
arg := common.NewArgument()
runtime, err := common.NewKubeRuntime(common.AllInOne, *arg)
if err != nil {
return err
}
runtime.SetRunner(
&connector.Runner{
Host: &connector.BaseHost{
Name: common.LocalHost,
Arch: runtime.GetSystemInfo().GetOsArch(),
Os: runtime.GetSystemInfo().GetOsType(),
},
},
)
amdModel, _ := runtime.GetRunner().SudoCmd("lspci | grep -iE 'VGA|3D|Display' | grep -iE 'AMD|ATI' | head -1 || true", false, false)
drvVer, _ := runtime.GetRunner().SudoCmd("modinfo amdgpu 2>/dev/null | awk -F': ' '/^version:/{print $2}' || true", false, false)
rocmVer, _ := runtime.GetRunner().SudoCmd("cat /opt/rocm/.info/version 2>/dev/null || true", false, false)
if strings.TrimSpace(amdModel) != "" {
logger.Infof("AMD GPU: %s", strings.TrimSpace(amdModel))
} else {
logger.Info("AMD GPU: not detected")
}
if strings.TrimSpace(drvVer) != "" {
logger.Infof("AMDGPU driver %s", strings.TrimSpace(drvVer))
} else {
logger.Info("AMDGPU driver version: unknown")
}
if strings.TrimSpace(rocmVer) != "" {
logger.Infof("ROCm version: %s", strings.TrimSpace(rocmVer))
} else {
logger.Info("ROCm version: not installed")
}
return nil
}

View File

@@ -396,3 +396,17 @@ func (t *DeleteTerminusData) Execute(runtime connector.Runtime) error {
return nil return nil
} }
type CreateSharedLibDir struct {
common.KubeAction
}
func (t *CreateSharedLibDir) Execute(runtime connector.Runtime) error {
if runtime.GetSystemInfo().IsDarwin() {
return nil
}
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", OlaresSharedLibDir, OlaresSharedLibDir), false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
}
return nil
}

View File

@@ -74,6 +74,7 @@ func (m *PreparedModule) Init() {
type WriteReleaseFileModule struct { type WriteReleaseFileModule struct {
common.KubeModule common.KubeModule
WithoutName bool
} }
func (m *WriteReleaseFileModule) Init() { func (m *WriteReleaseFileModule) Init() {
@@ -82,7 +83,7 @@ func (m *WriteReleaseFileModule) Init() {
m.Tasks = []task.Interface{ m.Tasks = []task.Interface{
&task.LocalTask{ &task.LocalTask{
Name: "WriteReleaseFile", Name: "WriteReleaseFile",
Action: new(WriteReleaseFile), Action: &WriteReleaseFile{WithoutName: m.WithoutName},
}, },
} }
} }

View File

@@ -10,8 +10,8 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1" "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
apputils "bytetrade.io/web3os/app-service/pkg/utils" apputils "github.com/beclab/Olares/framework/app-service/pkg/utils"
"github.com/beclab/Olares/cli/pkg/core/logger" "github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/storage" "github.com/beclab/Olares/cli/pkg/storage"
@@ -38,12 +38,6 @@ type InstallOsSystem struct {
} }
func (t *InstallOsSystem) Execute(runtime connector.Runtime) error { func (t *InstallOsSystem) Execute(runtime connector.Runtime) error {
if !runtime.GetSystemInfo().IsDarwin() {
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("mkdir -p %s && chown 1000:1000 %s", storage.OlaresSharedLibDir, storage.OlaresSharedLibDir), false, false); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to create shared lib dir")
}
}
config, err := ctrl.GetConfig() config, err := ctrl.GetConfig()
if err != nil { if err != nil {
return err return err
@@ -367,6 +361,11 @@ func (m *InstallOsSystemModule) Init() {
Action: &CreateUserEnvConfigMap{}, Action: &CreateUserEnvConfigMap{},
} }
createSharedLibDir := &task.LocalTask{
Name: "CreateSharedLibDir",
Action: &storage.CreateSharedLibDir{},
}
installOsSystem := &task.LocalTask{ installOsSystem := &task.LocalTask{
Name: "InstallOsSystem", Name: "InstallOsSystem",
Action: &InstallOsSystem{}, Action: &InstallOsSystem{},
@@ -399,6 +398,7 @@ func (m *InstallOsSystemModule) Init() {
m.Tasks = []task.Interface{ m.Tasks = []task.Interface{
applySystemEnv, applySystemEnv,
createUserEnvConfigMap, createUserEnvConfigMap,
createSharedLibDir,
installOsSystem, installOsSystem,
createBackupConfigMap, createBackupConfigMap,
checkSystemService, checkSystemService,

View File

@@ -97,25 +97,8 @@ func (t *CheckKeyPodsRunning) Execute(runtime connector.Runtime) error {
if !strings.HasPrefix(pod.Namespace, "user-") && !strings.HasPrefix(pod.Namespace, "os-") { if !strings.HasPrefix(pod.Namespace, "user-") && !strings.HasPrefix(pod.Namespace, "os-") {
continue continue
} }
if pod.Status.Phase != corev1.PodRunning { if err := utils.AssertPodReady(&pod); err != nil {
return fmt.Errorf("pod %s/%s is not running", pod.Namespace, pod.Name) return err
}
if len(pod.Status.ContainerStatuses) != len(pod.Spec.Containers) {
return fmt.Errorf("pod %s/%s has not started all containers yet", pod.Namespace, pod.Name)
}
for _, cStatus := range pod.Status.ContainerStatuses {
if cStatus.State.Terminated != nil {
if cStatus.State.Terminated.ExitCode != 0 {
return fmt.Errorf("container %s in pod %s/%s is terminated", cStatus.Name, pod.Namespace, pod.Name)
}
continue
}
if cStatus.State.Running == nil {
return fmt.Errorf("container %s in pod %s/%s is not running", cStatus.Name, pod.Namespace, pod.Name)
}
if !cStatus.Ready {
return fmt.Errorf("container %s in pod %s/%s is not ready", cStatus.Name, pod.Namespace, pod.Name)
}
} }
} }
return nil return nil
@@ -126,29 +109,39 @@ type CheckPodsRunning struct {
labels map[string][]string labels map[string][]string
} }
func (c *CheckPodsRunning) Execute(runtime connector.Runtime) error { func (c *CheckPodsRunning) Execute(_ connector.Runtime) error {
if c.labels == nil { if c.labels == nil {
return nil return nil
} }
kubectl, err := util.GetCommand(common.CommandKubectl)
if err != nil {
return errors.Wrap(errors.WithStack(err), "kubectl not found")
}
var ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute) var ctx, cancel = context.WithTimeout(context.Background(), 3*time.Minute)
defer cancel() defer cancel()
kubeConfig, err := ctrl.GetConfig()
if err != nil {
return errors.Wrap(err, "failed to load kubeconfig")
}
kubeClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
return errors.Wrap(err, "failed to create kube client")
}
for ns, labels := range c.labels { for ns, labels := range c.labels {
for _, label := range labels { for _, label := range labels {
var cmd = fmt.Sprintf("%s get pod -n %s -l '%s' -o jsonpath='{.items[*].status.phase}'", kubectl, ns, label) podList, err := kubeClient.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{LabelSelector: label})
phase, err := runtime.GetRunner().SudoCmdContext(ctx, cmd, false, false)
if err != nil { if err != nil {
return fmt.Errorf("pod status invalid, namespace: %s, label: %s, waiting ...", ns, label) return fmt.Errorf("pod status invalid, namespace: %s, label: %s, waiting ...", ns, label)
} }
if phase != "Running" { if podList == nil || len(podList.Items) == 0 {
logger.Infof("pod in namespace: %s, label: %s, current phase: %s, waiting ...", ns, label, phase) return fmt.Errorf("no pod found, namespace: %s, label: %s, waiting ...", ns, label)
return fmt.Errorf("pod is %s, namespace: %s, label: %s, waiting ...", phase, ns, label) }
for i := range podList.Items {
pod := &podList.Items[i]
if err := utils.AssertPodReady(pod); err != nil {
return err
}
} }
} }
} }
@@ -250,13 +243,14 @@ func (t *PrepareFinished) Execute(runtime connector.Runtime) error {
type WriteReleaseFile struct { type WriteReleaseFile struct {
common.KubeAction common.KubeAction
WithoutName bool
} }
func (t *WriteReleaseFile) Execute(runtime connector.Runtime) error { func (t *WriteReleaseFile) Execute(runtime connector.Runtime) error {
if util.IsExist(common.OlaresReleaseFile) { if util.IsExist(common.OlaresReleaseFile) {
logger.Debugf("found existing release file: %s, overriding ...", common.OlaresReleaseFile) logger.Debugf("found existing release file: %s, overriding ...", common.OlaresReleaseFile)
} }
return t.KubeConf.Arg.SaveReleaseInfo() return t.KubeConf.Arg.SaveReleaseInfo(t.WithoutName)
} }
type RemoveReleaseFile struct { type RemoveReleaseFile struct {

View File

@@ -9,6 +9,7 @@ import (
"github.com/beclab/Olares/cli/pkg/core/connector" "github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger" "github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/task" "github.com/beclab/Olares/cli/pkg/core/task"
"github.com/beclab/Olares/cli/pkg/utils"
) )
type WelcomeMessage struct { type WelcomeMessage struct {
@@ -68,6 +69,15 @@ func (t *WelcomeMessage) Execute(runtime connector.Runtime) error {
logger.Infof("Username: %s", t.KubeConf.Arg.User.UserName) logger.Infof("Username: %s", t.KubeConf.Arg.User.UserName)
logger.Infof("Password: %s", t.KubeConf.Arg.User.Password) logger.Infof("Password: %s", t.KubeConf.Arg.User.Password)
fmt.Printf("\n------------------------------------------------\n\n\n\n\n") fmt.Printf("\n------------------------------------------------\n\n\n\n\n")
fmt.Println()
// If AMD GPU on Ubuntu 22.04/24.04, print warning about reboot for ROCm
if si := runtime.GetSystemInfo(); si.IsUbuntu() && (si.IsUbuntuVersionEqual(connector.Ubuntu2204) || si.IsUbuntuVersionEqual(connector.Ubuntu2404)) {
if hasAmd, _ := utils.HasAmdIGPU(runtime); hasAmd {
logger.Warnf("\x1b[31mWarning: To enable ROCm, please reboot your machine after activation.\x1b[0m")
fmt.Println()
}
}
return nil return nil
} }

View File

@@ -5,12 +5,12 @@ import (
"fmt" "fmt"
"time" "time"
v1alpha1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/pkg/common" "github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/connector" "github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger" "github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/task" "github.com/beclab/Olares/cli/pkg/core/task"
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@@ -5,12 +5,12 @@ import (
"fmt" "fmt"
"time" "time"
v1alpha1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/pkg/common" "github.com/beclab/Olares/cli/pkg/common"
"github.com/beclab/Olares/cli/pkg/core/connector" "github.com/beclab/Olares/cli/pkg/core/connector"
"github.com/beclab/Olares/cli/pkg/core/logger" "github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/core/task" "github.com/beclab/Olares/cli/pkg/core/task"
v1alpha1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" apixclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"

View File

@@ -8,36 +8,36 @@ import (
"github.com/beclab/Olares/cli/version" "github.com/beclab/Olares/cli/version"
) )
var version_1_12_3 = semver.MustParse("1.12.3") var version_1_12_4 = semver.MustParse("1.12.4")
type upgrader_1_12_3 struct { type upgrader_1_12_4 struct {
breakingUpgraderBase breakingUpgraderBase
} }
func (u upgrader_1_12_3) Version() *semver.Version { func (u upgrader_1_12_4) Version() *semver.Version {
cliVersion, err := semver.NewVersion(version.VERSION) cliVersion, err := semver.NewVersion(version.VERSION)
// tolerate local dev version // tolerate local dev version
if err != nil { if err != nil {
return version_1_12_3 return version_1_12_4
} }
if samePatchLevelVersion(version_1_12_3, cliVersion) && getReleaseLineOfVersion(cliVersion) == mainLine { if samePatchLevelVersion(version_1_12_4, cliVersion) && getReleaseLineOfVersion(cliVersion) == mainLine {
return cliVersion return cliVersion
} }
return version_1_12_3 return version_1_12_4
} }
func (u upgrader_1_12_3) AddedBreakingChange() bool { func (u upgrader_1_12_4) AddedBreakingChange() bool {
if u.Version().Equal(version_1_12_3) { if u.Version().Equal(version_1_12_4) {
return true return true
} }
return false return false
} }
func (u upgrader_1_12_3) NeedRestart() bool { func (u upgrader_1_12_4) NeedRestart() bool {
return true return true
} }
func (u upgrader_1_12_3) PrepareForUpgrade() []task.Interface { func (u upgrader_1_12_4) PrepareForUpgrade() []task.Interface {
tasks := make([]task.Interface, 0) tasks := make([]task.Interface, 0)
tasks = append(tasks, upgradeKsConfig()...) tasks = append(tasks, upgradeKsConfig()...)
@@ -57,7 +57,7 @@ func (u upgrader_1_12_3) PrepareForUpgrade() []task.Interface {
return tasks return tasks
} }
func (u upgrader_1_12_3) UpgradeSystemComponents() []task.Interface { func (u upgrader_1_12_4) UpgradeSystemComponents() []task.Interface {
pre := []task.Interface{ pre := []task.Interface{
&task.LocalTask{ &task.LocalTask{
Name: "UpgradeL4BFLProxy", Name: "UpgradeL4BFLProxy",
@@ -69,7 +69,7 @@ func (u upgrader_1_12_3) UpgradeSystemComponents() []task.Interface {
return append(pre, u.upgraderBase.UpgradeSystemComponents()...) return append(pre, u.upgraderBase.UpgradeSystemComponents()...)
} }
func (u upgrader_1_12_3) UpdateOlaresVersion() []task.Interface { func (u upgrader_1_12_4) UpdateOlaresVersion() []task.Interface {
var tasks []task.Interface var tasks []task.Interface
tasks = append(tasks, tasks = append(tasks,
&task.LocalTask{ &task.LocalTask{
@@ -88,5 +88,5 @@ func (u upgrader_1_12_3) UpdateOlaresVersion() []task.Interface {
} }
func init() { func init() {
registerMainUpgrader(upgrader_1_12_3{}) registerMainUpgrader(upgrader_1_12_4{})
} }

View File

@@ -3,7 +3,10 @@ package upgrade
import ( import (
"context" "context"
"fmt" "fmt"
"os"
"os/exec"
"path" "path"
"path/filepath"
"strings" "strings"
"time" "time"
@@ -222,6 +225,71 @@ type upgradeGPUDriverIfNeeded struct {
common.KubeAction common.KubeAction
} }
// fixProcModprobePath fixes the /proc/sys/kernel/modprobe path issue that can cause
// nvidia-installer to fail with error:
// "The path to the `modprobe` utility reported by '/proc/sys/kernel/modprobe', ”, differs from
// the path determined by `nvidia-installer`, `/bin/kmod`, and does not appear to point to a
// valid `modprobe` binary."
//
// This function checks if /proc/sys/kernel/modprobe is empty or invalid, and if so,
// writes a valid modprobe path to it.
func fixProcModprobePath() {
const procModprobePath = "/proc/sys/kernel/modprobe"
modprobePaths := []string{
"/sbin/modprobe",
"/usr/sbin/modprobe",
"/bin/modprobe",
"/usr/bin/modprobe",
}
data, err := os.ReadFile(procModprobePath)
if err != nil {
logger.Warnf("failed to read %s: %v", procModprobePath, err)
}
currentPath := strings.TrimSpace(string(data))
// Check if current path is valid (non-empty and executable)
if currentPath != "" {
if util.IsExecutable(currentPath) {
logger.Debugf("%s already contains valid path: %s", procModprobePath, currentPath)
return
}
// in case it's a symlink that resolves to a valid executable
if resolved, err := filepath.EvalSymlinks(currentPath); err == nil && resolved != "" {
if util.IsExecutable(resolved) {
logger.Debugf("%s contains symlink %s -> %s which is valid", procModprobePath, currentPath, resolved)
return
}
}
logger.Warnf("%s contains invalid path: '%s', attempting to fix", procModprobePath, currentPath)
} else {
logger.Warnf("%s is empty, attempting to fix", procModprobePath)
}
if lookPath, err := exec.LookPath("modprobe"); err == nil && lookPath != "" {
modprobePaths = append([]string{lookPath}, modprobePaths...)
}
for _, modprobePath := range modprobePaths {
if !util.IsExecutable(modprobePath) {
continue
}
if err := os.WriteFile(procModprobePath, []byte(modprobePath), 0644); err != nil {
logger.Warnf("failed to write %s to %s: %v", modprobePath, procModprobePath, err)
continue
}
logger.Infof("successfully fixed %s: set to %s", procModprobePath, modprobePath)
return
}
// If we get here, we couldn't fix it, but we log a warning and continue
// The nvidia-installer might still work, or it might fail, but we don't want to block the upgrade
logger.Warnf("could not fix %s, nvidia-installer may fail; continuing anyway", procModprobePath)
}
func (a *upgradeGPUDriverIfNeeded) Execute(runtime connector.Runtime) error { func (a *upgradeGPUDriverIfNeeded) Execute(runtime connector.Runtime) error {
sys := runtime.GetSystemInfo() sys := runtime.GetSystemInfo()
if sys.IsWsl() { if sys.IsWsl() {
@@ -296,6 +364,9 @@ func (a *upgradeGPUDriverIfNeeded) Execute(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends dkms build-essential linux-headers-$(uname -r)", false, true); err != nil { if _, err := runtime.GetRunner().SudoCmd("DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends dkms build-essential linux-headers-$(uname -r)", false, true); err != nil {
return errors.Wrap(errors.WithStack(err), "failed to install kernel build dependencies for NVIDIA runfile") return errors.Wrap(errors.WithStack(err), "failed to install kernel build dependencies for NVIDIA runfile")
} }
fixProcModprobePath()
// install runfile // install runfile
runfile := item.FilePath(runtime.GetBaseDir()) runfile := item.FilePath(runtime.GetBaseDir())
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("chmod +x %s", runfile), false, true); err != nil { if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("chmod +x %s", runfile), false, true); err != nil {

67
cli/pkg/utils/amdgpu.go Normal file
View File

@@ -0,0 +1,67 @@
package utils
import (
"fmt"
"os"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/beclab/Olares/cli/pkg/core/connector"
)
func HasAmdIGPU(execRuntime connector.Runtime) (bool, error) {
// Detect by CPU model names that bundle AMD AI NPU/graphics
targets := []string{
"AMD Ryzen AI Max+ 395",
"AMD Ryzen AI Max 390",
"AMD Ryzen AI Max 385",
"AMD Ryzen AI 9 HX 375",
"AMD Ryzen AI 9 HX 370",
"AMD Ryzen AI 9 365",
}
// try lscpu first: extract 'Model name' field
out, err := execRuntime.GetRunner().SudoCmd("lscpu 2>/dev/null | awk -F': *' '/^Model name/{print $2; exit}' || true", false, false)
if err != nil {
return false, err
}
if out != "" {
lo := strings.ToLower(strings.TrimSpace(out))
for _, t := range targets {
if strings.Contains(lo, strings.ToLower(t)) {
return true, nil
}
}
}
// fallback to /proc/cpuinfo
out, err = execRuntime.GetRunner().SudoCmd("awk -F': *' '/^model name/{print $2; exit}' /proc/cpuinfo 2>/dev/null || true", false, false)
if err != nil {
return false, err
}
if out != "" {
lo := strings.ToLower(strings.TrimSpace(out))
for _, t := range targets {
if strings.Contains(lo, strings.ToLower(t)) {
return true, nil
}
}
}
return false, nil
}
func RocmVersion() (*semver.Version, error) {
const rocmVersionFile = "/opt/rocm/.info/version"
data, err := os.ReadFile(rocmVersionFile)
if err != nil {
// no ROCm installed, nothing to check
if os.IsNotExist(err) {
return nil, err
}
return nil, err
}
curStr := strings.TrimSpace(string(data))
cur, err := semver.NewVersion(curStr)
if err != nil {
return nil, fmt.Errorf("invalid rocm version: %s", curStr)
}
return cur, nil
}

111
cli/pkg/utils/pod.go Normal file
View File

@@ -0,0 +1,111 @@
package utils
import (
"fmt"
corev1 "k8s.io/api/core/v1"
)
func AssertPodReady(pod *corev1.Pod) error {
if pod == nil {
return fmt.Errorf("pod is nil")
}
podKey := fmt.Sprintf("%s/%s", pod.Namespace, pod.Name)
if pod.DeletionTimestamp != nil {
return fmt.Errorf("pod %s is terminating", podKey)
}
if pod.Status.Phase != corev1.PodRunning {
return fmt.Errorf("pod %s is not running (phase=%s)", podKey, pod.Status.Phase)
}
if len(pod.Spec.InitContainers) > 0 {
initStatusByName := make(map[string]corev1.ContainerStatus, len(pod.Status.InitContainerStatuses))
for i := range pod.Status.InitContainerStatuses {
s := pod.Status.InitContainerStatuses[i]
initStatusByName[s.Name] = s
}
for _, ic := range pod.Spec.InitContainers {
s, ok := initStatusByName[ic.Name]
if !ok {
return fmt.Errorf("pod %s has not started init container %s yet", podKey, ic.Name)
}
if t := s.State.Terminated; t != nil {
if t.ExitCode != 0 {
return fmt.Errorf(
"init container %s in pod %s terminated (exitCode=%d, reason=%s, message=%s)",
s.Name, podKey, t.ExitCode, t.Reason, t.Message,
)
}
continue
}
if w := s.State.Waiting; w != nil {
return fmt.Errorf(
"init container %s in pod %s is waiting (reason=%s, message=%s)",
s.Name, podKey, w.Reason, w.Message,
)
}
return fmt.Errorf("pod %s init container %s is still running", podKey, s.Name)
}
}
readyCondFound := false
for i := range pod.Status.Conditions {
cond := pod.Status.Conditions[i]
if cond.Type != corev1.PodReady {
continue
}
readyCondFound = true
if cond.Status != corev1.ConditionTrue {
if cond.Reason != "" || cond.Message != "" {
return fmt.Errorf("pod %s is not ready (reason=%s, message=%s)", podKey, cond.Reason, cond.Message)
}
return fmt.Errorf("pod %s is not ready", podKey)
}
break
}
if !readyCondFound {
return fmt.Errorf("pod %s is not ready (missing Ready condition)", podKey)
}
statusByName := make(map[string]corev1.ContainerStatus, len(pod.Status.ContainerStatuses))
for i := range pod.Status.ContainerStatuses {
s := pod.Status.ContainerStatuses[i]
statusByName[s.Name] = s
}
for _, c := range pod.Spec.Containers {
cStatus, ok := statusByName[c.Name]
if !ok {
return fmt.Errorf("pod %s has not started container %s yet", podKey, c.Name)
}
if t := cStatus.State.Terminated; t != nil {
return fmt.Errorf(
"container %s in pod %s terminated (exitCode=%d, reason=%s, message=%s)",
cStatus.Name,
podKey,
t.ExitCode,
t.Reason,
t.Message,
)
}
if cStatus.State.Running == nil {
if w := cStatus.State.Waiting; w != nil {
return fmt.Errorf(
"container %s in pod %s is waiting (reason=%s, message=%s)",
cStatus.Name,
podKey,
w.Reason,
w.Message,
)
}
return fmt.Errorf("container %s in pod %s is not running", cStatus.Name, podKey)
}
if !cStatus.Ready {
return fmt.Errorf("container %s in pod %s is not ready", cStatus.Name, podKey)
}
}
return nil
}

View File

@@ -321,3 +321,54 @@ func GetBufIOReaderOfTerminalInput() (*bufio.Reader, error) {
} }
return bufio.NewReader(tty), nil return bufio.NewReader(tty), nil
} }
// ResolveSudoUserHomeAndIDs resolves the home directory, uid, and gid for the user
// who invoked sudo. If not running under sudo, it falls back to the current user.
// This is useful for commands that need to operate on the invoking user's home
// directory rather than /root when running with sudo.
func ResolveSudoUserHomeAndIDs(runtime connector.Runtime) (home, uid, gid string, err error) {
uid, err = runtime.GetRunner().Cmd("echo ${SUDO_UID:-}", false, false)
if err != nil {
return "", "", "", errors.Wrap(errors.WithStack(err), "get SUDO_UID failed")
}
gid, err = runtime.GetRunner().Cmd("echo ${SUDO_GID:-}", false, false)
if err != nil {
return "", "", "", errors.Wrap(errors.WithStack(err), "get SUDO_GID failed")
}
uid = strings.TrimSpace(uid)
gid = strings.TrimSpace(gid)
if uid == "" {
uid, err = runtime.GetRunner().Cmd("id -u", false, false)
if err != nil {
return "", "", "", errors.Wrap(errors.WithStack(err), "get current uid failed")
}
gid, err = runtime.GetRunner().Cmd("id -g", false, false)
if err != nil {
return "", "", "", errors.Wrap(errors.WithStack(err), "get current gid failed")
}
uid = strings.TrimSpace(uid)
gid = strings.TrimSpace(gid)
}
home, err = runtime.GetRunner().Cmd(fmt.Sprintf(`getent passwd %s | awk -F: 'NR==1{print $6; exit}'`, uid), false, false)
if err != nil {
home = ""
}
home = strings.TrimSpace(home)
if home == "" {
home, _ = runtime.GetRunner().Cmd(fmt.Sprintf(`awk -F: -v uid=%s '$3==uid {print $6; exit}' /etc/passwd 2>/dev/null`, uid), false, false)
home = strings.TrimSpace(home)
}
if home == "" {
home, err = runtime.GetRunner().Cmd("echo $HOME", false, false)
if err != nil {
return "", "", "", errors.Wrap(errors.WithStack(err), "get HOME failed")
}
home = strings.TrimSpace(home)
}
if home == "" {
return "", "", "", errors.New("resolve user home failed")
}
return home, uid, gid, nil
}

View File

@@ -19,7 +19,6 @@ import (
) )
var ( var (
DIDGateURL = "https://did-gate-v3.bttcdn.com/1.0/name/"
DIDGateTimeout = 10 * time.Second DIDGateTimeout = 10 * time.Second
DIDCachePath = "/var/lib/olares" DIDCachePath = "/var/lib/olares"
) )
@@ -90,7 +89,7 @@ type CheckJWSResult struct {
} }
// resolveDID resolves a DID either from cache or from the DID gate // resolveDID resolves a DID either from cache or from the DID gate
func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) { func ResolveOlaresName(gateUrl, olares_id string) (*didcore.ResolutionResult, error) {
name := strings.Replace(olares_id, "@", ".", -1) name := strings.Replace(olares_id, "@", ".", -1)
// Try to get from cache first // Try to get from cache first
cached, err := getDB().Get([]byte(name), nil) cached, err := getDB().Get([]byte(name), nil)
@@ -105,7 +104,7 @@ func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
client := &http.Client{ client := &http.Client{
Timeout: DIDGateTimeout, Timeout: DIDGateTimeout,
} }
resp, err := client.Get(DIDGateURL + name) resp, err := client.Get(gateUrl + name)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to fetch DID from gate: %w", err) return nil, fmt.Errorf("failed to fetch DID from gate: %w", err)
} }
@@ -135,7 +134,7 @@ func ResolveOlaresName(olares_id string) (*didcore.ResolutionResult, error) {
} }
// CheckJWS verifies a JWS and returns the terminus name, body and kid // CheckJWS verifies a JWS and returns the terminus name, body and kid
func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) { func CheckJWS(gateUrl, jws string, duration int64) (*CheckJWSResult, error) {
var kid string var kid string
var name string var name string
var timestamp int64 var timestamp int64
@@ -198,7 +197,7 @@ func CheckJWS(jws string, duration int64) (*CheckJWSResult, error) {
} }
// Resolve DID // Resolve DID
resolutionResult, err := ResolveOlaresName(name) resolutionResult, err := ResolveOlaresName(gateUrl, name)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to resolve DID: %w", err) return nil, fmt.Errorf("failed to resolve DID: %w", err)
} }

View File

@@ -25,5 +25,5 @@ build-linux-in-docker:
-v $(current_dir):/olaresd \ -v $(current_dir):/olaresd \
-w /olaresd \ -w /olaresd \
-e DEBIAN_FRONTEND=noninteractive \ -e DEBIAN_FRONTEND=noninteractive \
golang:1.24 \ golang:1.24.11 \
sh -c "apt-get -y update; apt-get -y install libudev-dev libpcap-dev; make build-linux" sh -c "apt-get -y update; apt-get -y install libudev-dev libpcap-dev; make build-linux"

View File

@@ -1,11 +1,8 @@
module github.com/beclab/Olares/daemon module github.com/beclab/Olares/daemon
go 1.24.2 go 1.24.11
toolchain go1.24.4
replace ( replace (
bytetrade.io/web3os/app-service => github.com/beclab/app-service v0.4.37
bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17 bytetrade.io/web3os/backups-sdk => github.com/Above-Os/backups-sdk v0.1.17
bytetrade.io/web3os/bfl => github.com/beclab/bfl v0.3.36 bytetrade.io/web3os/bfl => github.com/beclab/bfl v0.3.36
github.com/labstack/echo/v4 => github.com/eball/echo/v4 v4.13.4-patch github.com/labstack/echo/v4 => github.com/eball/echo/v4 v4.13.4-patch
@@ -18,15 +15,15 @@ replace (
) )
require ( require (
bytetrade.io/web3os/app-service v0.0.0-00010101000000-000000000000
bytetrade.io/web3os/bfl v0.0.0-00010101000000-000000000000 bytetrade.io/web3os/bfl v0.0.0-00010101000000-000000000000
github.com/Masterminds/semver/v3 v3.4.0 github.com/Masterminds/semver/v3 v3.4.0
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89 github.com/beclab/Olares/cli v0.0.0-20251230161135-5264df60cc33
github.com/containerd/containerd v1.7.28 github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70
github.com/containerd/containerd v1.7.29
github.com/distribution/distribution/v3 v3.0.0 github.com/distribution/distribution/v3 v3.0.0
github.com/dustin/go-humanize v1.0.1 github.com/dustin/go-humanize v1.0.1
github.com/eball/zeroconf v0.2.2 github.com/eball/zeroconf v0.2.5
github.com/godbus/dbus/v5 v5.1.0 github.com/godbus/dbus/v5 v5.1.0
github.com/gofiber/fiber/v2 v2.52.9 github.com/gofiber/fiber/v2 v2.52.9
github.com/google/gopacket v1.1.19 github.com/google/gopacket v1.1.19
@@ -39,6 +36,7 @@ require (
github.com/libp2p/go-netroute v0.2.2 github.com/libp2p/go-netroute v0.2.2
github.com/mackerelio/go-osstat v0.2.5 github.com/mackerelio/go-osstat v0.2.5
github.com/mdlayher/raw v0.1.0 github.com/mdlayher/raw v0.1.0
github.com/miekg/dns v1.1.55
github.com/muka/network_manager v0.0.0-20200903202308-ae5ede816e07 github.com/muka/network_manager v0.0.0-20200903202308-ae5ede816e07
github.com/nxadm/tail v1.4.11 github.com/nxadm/tail v1.4.11
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58
@@ -52,10 +50,11 @@ require (
github.com/txn2/txeh v1.5.5 github.com/txn2/txeh v1.5.5
github.com/vishvananda/netlink v1.3.0 github.com/vishvananda/netlink v1.3.0
go.opentelemetry.io/otel/trace v1.36.0 go.opentelemetry.io/otel/trace v1.36.0
golang.org/x/crypto v0.41.0 golang.org/x/crypto v0.45.0
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
golang.org/x/sys v0.35.0 golang.org/x/sys v0.38.0
k8s.io/api v0.34.1 k8s.io/api v0.34.1
k8s.io/apiextensions-apiserver v0.34.0
k8s.io/apimachinery v0.34.1 k8s.io/apimachinery v0.34.1
k8s.io/client-go v12.0.0+incompatible k8s.io/client-go v12.0.0+incompatible
k8s.io/cri-api v0.34.1 k8s.io/cri-api v0.34.1
@@ -90,10 +89,11 @@ require (
github.com/containerd/platforms v0.2.1 // indirect github.com/containerd/platforms v0.2.1 // indirect
github.com/containerd/ttrpc v1.2.7 // indirect github.com/containerd/ttrpc v1.2.7 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/cyphar/filepath-securejoin v0.5.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/distribution/reference v0.6.0 // indirect github.com/distribution/reference v0.6.0 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/ebitengine/purego v0.8.4 // indirect github.com/ebitengine/purego v0.8.4 // indirect
github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/emicklei/go-restful/v3 v3.13.0 // indirect
@@ -129,7 +129,6 @@ require (
github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mdlayher/packet v0.0.0-20220221164757-67998ac0ff93 // indirect github.com/mdlayher/packet v0.0.0-20220221164757-67998ac0ff93 // indirect
github.com/mdlayher/socket v0.2.1 // indirect github.com/mdlayher/socket v0.2.1 // indirect
github.com/miekg/dns v1.1.55 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/moby/locker v1.0.1 // indirect github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.5.0 // indirect github.com/moby/spdystream v0.5.0 // indirect
@@ -146,7 +145,7 @@ require (
github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runc v1.3.0 // indirect github.com/opencontainers/runc v1.3.0 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect github.com/opencontainers/runtime-spec v1.2.1 // indirect
github.com/opencontainers/selinux v1.12.0 // indirect github.com/opencontainers/selinux v1.13.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.23.0 // indirect github.com/prometheus/client_golang v1.23.0 // indirect
@@ -181,14 +180,14 @@ require (
go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.27.0 // indirect golang.org/x/mod v0.29.0 // indirect
golang.org/x/net v0.43.0 // indirect golang.org/x/net v0.47.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect golang.org/x/sync v0.18.0 // indirect
golang.org/x/term v0.34.0 // indirect golang.org/x/term v0.37.0 // indirect
golang.org/x/text v0.28.0 // indirect golang.org/x/text v0.31.0 // indirect
golang.org/x/time v0.12.0 // indirect golang.org/x/time v0.12.0 // indirect
golang.org/x/tools v0.36.0 // indirect golang.org/x/tools v0.38.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
@@ -200,7 +199,6 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
howett.net/plist v1.0.0 // indirect howett.net/plist v1.0.0 // indirect
k8s.io/apiextensions-apiserver v0.34.0 // indirect
k8s.io/apiserver v0.34.0 // indirect k8s.io/apiserver v0.34.0 // indirect
k8s.io/component-base v0.34.1 // indirect k8s.io/component-base v0.34.1 // indirect
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect

View File

@@ -24,10 +24,10 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/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 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89 h1:5s9hXV8K3faToQtE9DbiM7O6jt5kIiEsLAaKn6F0UfA= github.com/beclab/Olares/cli v0.0.0-20251230161135-5264df60cc33 h1:WYuUPOT/p26aCDJGJEDai1v7YM6QHiaFDusBVynnbBY=
github.com/beclab/Olares/cli v0.0.0-20251016092744-6241cceceb89/go.mod h1:iEvZxM6PnFxFRppneTzV3hgr2tIxDnsI3dhp4pi7pFg= github.com/beclab/Olares/cli v0.0.0-20251230161135-5264df60cc33/go.mod h1:ixhzBK5XIovsRB5djk44TChsOK4wum2q4y/hZxJKlNw=
github.com/beclab/app-service v0.4.37 h1:gt60wQxgPWMc3oN94TNSdiQAvzqTyCv/OUP93jNSQTY= github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70 h1:U3z6m0hokD1gzl788BrUdxCbDyAjdOBBXA8ilYgn6VQ=
github.com/beclab/app-service v0.4.37/go.mod h1:0vEg3rv/DbR7dYznvTlXNXyYNn+TXNMaxz03GQYRWUQ= github.com/beclab/Olares/framework/app-service v0.0.0-20251225061130-909b7656fd70/go.mod h1:D9wl7y3obLqXMqfubMROMgdxWAwInnKNrFC//d0nyIA=
github.com/beclab/bfl v0.3.36 h1:PgeSPGc+XoONiwFsKq9xX8rqcL4kVM1G/ut0lYYj/js= github.com/beclab/bfl v0.3.36 h1:PgeSPGc+XoONiwFsKq9xX8rqcL4kVM1G/ut0lYYj/js=
github.com/beclab/bfl v0.3.36/go.mod h1:A82u38MxYk1C3Lqnm4iUUK4hBeY9HHIs+xU4V93OnJk= github.com/beclab/bfl v0.3.36/go.mod h1:A82u38MxYk1C3Lqnm4iUUK4hBeY9HHIs+xU4V93OnJk=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -45,8 +45,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c= github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs= github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0= github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0=
github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= 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= github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII=
@@ -65,6 +65,8 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40= github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.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 h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -73,20 +75,20 @@ github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U
github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/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 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM= github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN6UX90KJc4HjyM=
github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU= github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/eball/echo/v4 v4.13.4-patch h1:5w83KQrEqrxhc1BO0BpRBHssC37vFrWualUM27Rt2sg= github.com/eball/echo/v4 v4.13.4-patch h1:5w83KQrEqrxhc1BO0BpRBHssC37vFrWualUM27Rt2sg=
github.com/eball/echo/v4 v4.13.4-patch/go.mod h1:ORgy8LWTq8knpwgaz538rAJMri7WgpoAD6H3zYccn84= github.com/eball/echo/v4 v4.13.4-patch/go.mod h1:ORgy8LWTq8knpwgaz538rAJMri7WgpoAD6H3zYccn84=
github.com/eball/zeroconf v0.2.2 h1:y23X67tLFlU+b35LyM9THXGsdC88IUz803G+mzfeSeE= github.com/eball/zeroconf v0.2.5 h1:RNINVvj8kbm/r4YoqYu/jWD57l5NJmvRUCfbjlIsbJg=
github.com/eball/zeroconf v0.2.2/go.mod h1:eIbIjGYo9sSMaKWLcveHEPRWdyblz7q9ih2R1HnNw5M= github.com/eball/zeroconf v0.2.5/go.mod h1:eIbIjGYo9sSMaKWLcveHEPRWdyblz7q9ih2R1HnNw5M=
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
@@ -287,8 +289,8 @@ github.com/opencontainers/runc v1.3.0 h1:cvP7xbEvD0QQAs0nZKLzkVog2OPZhI/V2w3WmTm
github.com/opencontainers/runc v1.3.0/go.mod h1:9wbWt42gV+KRxKRVVugNP6D5+PQciRbenB4fLVsqGPs= github.com/opencontainers/runc v1.3.0/go.mod h1:9wbWt42gV+KRxKRVVugNP6D5+PQciRbenB4fLVsqGPs=
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8= github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U= github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
@@ -414,8 +416,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-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-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0= golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4= golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
@@ -426,8 +428,8 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -440,8 +442,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-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-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.0.0-20210423184538-5f58ad60dda6/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
@@ -451,8 +453,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-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-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.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-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-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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -472,16 +474,16 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4= golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 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-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -493,8 +495,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-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-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.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -2,8 +2,10 @@ package handlers
import ( import (
"net/http" "net/http"
"net/url"
"github.com/beclab/Olares/cli/pkg/web5/jws" "github.com/beclab/Olares/cli/pkg/web5/jws"
"github.com/beclab/Olares/daemon/pkg/commands"
"github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2"
"k8s.io/klog/v2" "k8s.io/klog/v2"
) )
@@ -14,8 +16,14 @@ func (h *Handlers) ResolveOlaresName(c *fiber.Ctx) error {
klog.Error("olaresName parameter is missing") klog.Error("olaresName parameter is missing")
return h.ErrJSON(c, fiber.StatusBadRequest, "olaresName parameter is required") return h.ErrJSON(c, fiber.StatusBadRequest, "olaresName parameter is required")
} }
klog.Infof("Received olaresName: %s", olaresName) klog.Infof("Received olaresName: %s", olaresName)
result, err := jws.ResolveOlaresName(olaresName)
didServiceURL, err := getDidGateURL()
if err != nil {
return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to get DID gate URL")
}
result, err := jws.ResolveOlaresName(didServiceURL, olaresName)
if err != nil { if err != nil {
klog.Errorf("Failed to resolve DID for %s: %v", olaresName, err) klog.Errorf("Failed to resolve DID for %s: %v", olaresName, err)
return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to resolve DID") return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to resolve DID")
@@ -46,7 +54,11 @@ func (h *Handlers) CheckJWS(c *fiber.Ctx) error {
body.Duration = int64(3 * 60 * 1000) // 3 minutes in milliseconds body.Duration = int64(3 * 60 * 1000) // 3 minutes in milliseconds
} }
result, err := jws.CheckJWS(body.JWS, body.Duration) didServiceURL, err := getDidGateURL()
if err != nil {
return h.ErrJSON(c, fiber.StatusInternalServerError, "Failed to get DID gate URL")
}
result, err := jws.CheckJWS(didServiceURL, body.JWS, body.Duration)
if err != nil { if err != nil {
klog.Errorf("Failed to check JWS: %v", err) klog.Errorf("Failed to check JWS: %v", err)
return h.ErrJSON(c, fiber.StatusBadRequest, "Invalid JWS") return h.ErrJSON(c, fiber.StatusBadRequest, "Invalid JWS")
@@ -54,3 +66,12 @@ func (h *Handlers) CheckJWS(c *fiber.Ctx) error {
return h.OkJSON(c, "success", result) return h.OkJSON(c, "success", result)
} }
func getDidGateURL() (string, error) {
didServiceURL, err := url.JoinPath(commands.OLARES_REMOTE_SERVICE, "/did/1.0/name/")
if err != nil {
klog.Errorf("failed to parse DID gate service URL: %v, Olares remote service: %s", err, commands.OLARES_REMOTE_SERVICE)
return "", err
}
return didServiceURL, nil
}

View File

@@ -43,16 +43,18 @@ func (h *Handlers) getMountedPath(ctx *fiber.Ctx, mutate func(*disk.UsageStat) *
u = mutate(u) u = mutate(u)
} }
res = append(res, &mountedPath{ if u != nil {
*u, res = append(res, &mountedPath{
string(p.Type), *u,
p.Invalid, string(p.Type),
p.IDSerial, p.Invalid,
p.IDSerialShort, p.IDSerial,
p.PartitionUUID, p.IDSerialShort,
p.Device, p.PartitionUUID,
p.ReadOnly, p.Device,
}) p.ReadOnly,
})
}
} }
return h.OkJSON(ctx, "success", res) return h.OkJSON(ctx, "success", res)
@@ -64,7 +66,14 @@ func (h *Handlers) GetMountedPath(ctx *fiber.Ctx) error {
func (h *Handlers) GetMountedPathInCluster(ctx *fiber.Ctx) error { func (h *Handlers) GetMountedPathInCluster(ctx *fiber.Ctx) error {
return h.getMountedPath(ctx, func(us *disk.UsageStat) *disk.UsageStat { return h.getMountedPath(ctx, func(us *disk.UsageStat) *disk.UsageStat {
us.Path = nodePathToClusterPath(us.Path) path := nodePathToClusterPath(us.Path)
if path == us.Path {
// not in cluster path
return nil
}
us.Path = path
return us return us
}) })
} }

View File

@@ -81,7 +81,7 @@ func (s *mDNSServer) StartAll() error {
host: &DNSConfig{Domain: domain}, host: &DNSConfig{Domain: domain},
} }
} }
klog.Info("Intranet mDNS server started") klog.V(8).Info("Intranet mDNS server started")
return nil return nil
} }

View File

@@ -84,8 +84,15 @@ func (p *proxyServer) Start() error {
clientIp = h clientIp = h
} }
} }
if c.IsWebSocket() { if c.IsWebSocket() {
ctx = context.WithValue(ctx, WSKey, true) ctx = context.WithValue(ctx, WSKey, true)
swp := c.Request().Header.Get("Sec-WebSocket-Protocol")
authToken := c.Request().Header.Get("X-Authorization")
if len(authToken) == 0 && len(swp) > 0 {
// handle missing auth token for websocket
c.Request().Header.Set("X-Authorization", swp)
}
} }
r := c.Request().WithContext(ctx) r := c.Request().WithContext(ctx)
if clientIp != "" { if clientIp != "" {
@@ -243,7 +250,7 @@ func (p *proxyServer) customDialContext(d *net.Dialer) func(ctx context.Context,
} }
if isWs { if isWs {
klog.Info("WebSocket connection detected, using upgraded dialer") klog.Info("WebSocket connection detected, using upgraded dialer, ", addr)
return tlsDial(ctx, d, func(ctx context.Context, network, addr string) (net.Conn, error) { return tlsDial(ctx, d, func(ctx context.Context, network, addr string) (net.Conn, error) {
return proxyDial(ctx, d, network, newAddr) return proxyDial(ctx, d, network, newAddr)
}, network, addr, &tls.Config{InsecureSkipVerify: true}) }, network, addr, &tls.Config{InsecureSkipVerify: true})

View File

@@ -147,6 +147,6 @@ func (s *Server) Reload(o *ServerOptions) error {
return fmt.Errorf("reload intranet server with %d errors", len(errs)) return fmt.Errorf("reload intranet server with %d errors", len(errs))
} }
klog.Info("Intranet server reloaded") klog.V(8).Info("Intranet server reloaded")
return nil return nil
} }

View File

@@ -99,7 +99,7 @@ func (s *server) Restart() error {
instanceName = hostname instanceName = hostname
} }
s.server, err = zeroconf.Register(instanceName, s.serviceName, "local.", hostname, s.port, []string{""}, []net.Interface{*iface}) s.server, err = zeroconf.RegisterAll(instanceName, s.serviceName, "local.", hostname, s.port, []string{""}, []net.Interface{*iface}, false, false, false)
if err != nil { if err != nil {
klog.Error("create mdns server error, ", err) klog.Error("create mdns server error, ", err)
return err return err

View File

@@ -79,7 +79,7 @@ func (w *applicationWatcher) Watch(ctx context.Context) {
klog.Error("reload intranet server config error, ", err) klog.Error("reload intranet server config error, ", err)
return return
} }
klog.Info("Intranet server config reloaded") klog.V(8).Info("Intranet server config reloaded")
} else { } else {
// Start the intranet server // Start the intranet server
err = w.intranetServer.Start(o) err = w.intranetServer.Start(o)

View File

@@ -20,6 +20,12 @@ func NewUsbWatcher() *usbWatcher {
return w return w
} }
var UsbSerialKey = struct{}{}
func WithSerial(ctx context.Context, serial string) context.Context {
return context.WithValue(ctx, UsbSerialKey, serial)
}
func (w *usbWatcher) Watch(ctx context.Context) { func (w *usbWatcher) Watch(ctx context.Context) {
retry := 1 retry := 1
devs, err := utils.DetectdUsbDevices(ctx) devs, err := utils.DetectdUsbDevices(ctx)
@@ -55,6 +61,16 @@ func (w *usbWatcher) Watch(ctx context.Context) {
return return
} }
serial := ctx.Value(UsbSerialKey).(string)
if serial != "" {
klog.Info("mount usb device with serial, ", serial)
devs = utils.FilterArray(devs, utils.FilterBySerial(serial))
if len(devs) == 0 {
klog.Info("no usb device found with serial, ", serial)
return
}
}
mountedPath, err := utils.MountUsbDevice(ctx, commands.MOUNT_BASE_DIR, devs) mountedPath, err := utils.MountUsbDevice(ctx, commands.MOUNT_BASE_DIR, devs)
if err != nil { if err != nil {
klog.Error("mount usb error, ", err) klog.Error("mount usb error, ", err)
@@ -80,13 +96,13 @@ func (w *umountWatcher) Watch(ctx context.Context) {
} }
func NewUsbMonitor(ctx context.Context) error { func NewUsbMonitor(ctx context.Context) error {
return utils.MonitorUsbDevice(ctx, func(action string) error { return utils.MonitorUsbDevice(ctx, func(action, serial string) error {
switch action { switch action {
case "add": case "add":
delay := time.NewTimer(2 * time.Second) delay := time.NewTimer(2 * time.Second)
go func() { go func() {
<-delay.C <-delay.C
NewUsbWatcher().Watch(ctx) NewUsbWatcher().Watch(WithSerial(ctx, serial))
}() }()
case "remove": case "remove":
NewUmountWatcher().Watch(ctx) NewUmountWatcher().Watch(ctx)

View File

@@ -119,7 +119,7 @@ func DetectdHddDevices(ctx context.Context) (usbDevs []storageDevice, err error)
return detectdStorageDevices(ctx, "ata") return detectdStorageDevices(ctx, "ata")
} }
func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error { func MonitorUsbDevice(ctx context.Context, cb func(action, serial string) error) error {
filter := &usbmon.ActionFilter{Action: usbmon.ActionAll} filter := &usbmon.ActionFilter{Action: usbmon.ActionAll}
devs, err := usbmon.ListenFiltered(ctx, filter) devs, err := usbmon.ListenFiltered(ctx, filter)
if err != nil { if err != nil {
@@ -137,8 +137,8 @@ func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error {
fmt.Println("Path: " + dev.Path()) fmt.Println("Path: " + dev.Path())
fmt.Println("Vendor: " + dev.Vendor()) fmt.Println("Vendor: " + dev.Vendor())
if cb != nil { if cb != nil && dev.Serial() != "" {
err = cb(dev.Action()) err = cb(dev.Action(), dev.Serial())
if err != nil { if err != nil {
klog.Error("usb action callback error, ", err, ", ", dev.Action()) klog.Error("usb action callback error, ", err, ", ", dev.Action())
} }
@@ -197,6 +197,12 @@ func MountedHddPath(ctx context.Context) ([]string, error) {
return getMountedPath(hdds) return getMountedPath(hdds)
} }
func FilterBySerial(serial string) func(dev storageDevice) bool {
return func(dev storageDevice) bool {
return strings.HasSuffix(serial, dev.IDSerial) || strings.HasSuffix(serial, dev.IDSerialShort)
}
}
func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevice) (mountedPath []string, err error) { func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevice) (mountedPath []string, err error) {
mounter := mountutils.New("") mounter := mountutils.New("")
mountedList, err := mounter.List() mountedList, err := mounter.List()
@@ -267,7 +273,8 @@ func MountUsbDevice(ctx context.Context, mountBaseDir string, dev []storageDevic
if err = mounter.Mount(d.DevPath, mkMountDir, "", []string{"uid=1000", "gid=1000"}); err != nil { if err = mounter.Mount(d.DevPath, mkMountDir, "", []string{"uid=1000", "gid=1000"}); err != nil {
klog.Warning("mount usb error, ", err, ", ", d.DevPath, ", ", mkMountDir) klog.Warning("mount usb error, ", err, ", ", d.DevPath, ", ", mkMountDir)
// clear the empty mount dir // clear the empty mount dir
if err = os.RemoveAll(mkMountDir); err != nil { // do not use remove all, only remove the mount point path, assume it's an empty dir
if err = os.Remove(mkMountDir); err != nil {
klog.Error("remove the mount dir error, ", err) klog.Error("remove the mount dir error, ", err)
} }
@@ -287,7 +294,8 @@ func umountAndRemovePath(ctx context.Context, path string) error {
return err return err
} }
if err = os.RemoveAll(path); err != nil { // do not use remove all, only remove the mount point path, assume it's an empty dir
if err = os.Remove(path); err != nil {
klog.Error("remove mount point error, ", err) klog.Error("remove mount point error, ", err)
} }
@@ -397,6 +405,11 @@ func UmountBrokenMount(ctx context.Context, baseDir string) error {
klog.Infof("broken mountpoint: %v, %v, %v", m.Path, m.Device, r.Reason) klog.Infof("broken mountpoint: %v, %v, %v", m.Path, m.Device, r.Reason)
if err = umountAndRemovePath(ctx, m.Path); err != nil {
return err
}
} else if !isDeviceExists(m.Device) {
klog.Infof("device not exists mountpoint: %v, %v", m.Path, m.Device)
if err = umountAndRemovePath(ctx, m.Path); err != nil { if err = umountAndRemovePath(ctx, m.Path); err != nil {
return err return err
} }
@@ -659,3 +672,16 @@ func checkMount(mountPoint string, timeout time.Duration) result {
} }
return res return res
} }
func isDeviceExists(devicePath string) bool {
if !strings.HasPrefix(devicePath, "/dev") {
return true
}
if strings.HasPrefix(devicePath, "/dev/mapper/") {
return true
}
_, err := os.Stat(devicePath)
return !os.IsNotExist(err)
}

View File

@@ -19,7 +19,7 @@ func DetectdHddDevices(ctx context.Context) (usbDevs []storageDevice, err error)
return return
} }
func MonitorUsbDevice(ctx context.Context, cb func(action string) error) error { func MonitorUsbDevice(ctx context.Context, cb func(action, id string) error) error {
klog.Warning("not implement") klog.Warning("not implement")
return nil return nil
} }
@@ -72,3 +72,9 @@ func MountedPath(ctx context.Context) ([]mountedPath, error) {
klog.Warning("not implement") klog.Warning("not implement")
return nil, nil return nil, nil
} }
func FilterBySerial(serial string) func(dev storageDevice) bool {
return func(dev storageDevice) bool {
return dev.IDSerial == serial || dev.IDSerialShort == serial
}
}

View File

@@ -18,15 +18,14 @@ func ValidateJWS(token string) (bool, string, error) {
klog.Errorf("failed to parse DID gate service URL: %v, Olares remote service: %s", err, commands.OLARES_REMOTE_SERVICE) klog.Errorf("failed to parse DID gate service URL: %v, Olares remote service: %s", err, commands.OLARES_REMOTE_SERVICE)
return false, "", err return false, "", err
} }
jws.DIDGateURL = didServiceURL
// Validate the JWS token with a 20-minute expiration time // Validate the JWS token with a 20-minute expiration time
checkJWS, err := jws.CheckJWS(token, 20*60*1000) checkJWS, err := jws.CheckJWS(didServiceURL, token, 20*60*1000)
if err != nil { if err != nil {
if strings.HasPrefix(err.Error(), "timestamp") { if strings.HasPrefix(err.Error(), "timestamp") {
err = fmt.Errorf("%v, server time: %s", err, time.Now().UTC().Format(time.RFC3339)) err = fmt.Errorf("%v, server time: %s", err, time.Now().UTC().Format(time.RFC3339))
} }
klog.Errorf("failed to check JWS: %v, on %s", err, jws.DIDGateURL) klog.Errorf("failed to check JWS: %v, on %s", err, didServiceURL)
return false, "", err return false, "", err
} }

View File

@@ -25,8 +25,8 @@ import (
"k8s.io/utils/pointer" "k8s.io/utils/pointer"
ctrl "sigs.k8s.io/controller-runtime" ctrl "sigs.k8s.io/controller-runtime"
sysv1 "bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1" sysv1 "github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
"bytetrade.io/web3os/app-service/pkg/generated/clientset/versioned" "github.com/beclab/Olares/framework/app-service/pkg/generated/clientset/versioned"
) )
const ( const (

11
daemon/pkg/utils/utils.go Normal file
View File

@@ -0,0 +1,11 @@
package utils
func FilterArray[T any](items []T, fn func(T) bool) []T {
var filtered []T
for _, item := range items {
if fn(item) {
filtered = append(filtered, item)
}
}
return filtered
}

View File

@@ -6,19 +6,34 @@ const side = {
text: "What is Olares", text: "What is Olares",
link: "/manual/overview", link: "/manual/overview",
items: [ items: [
{ text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" }, // { text: "Compare Olares and NAS", link: "/manual/olares-vs-nas" },
{ text: "Help and support", link: "/manual/help/request-technical-support"} {
// collapsed: true, text: "FAQs",
// items: [ // link: "/manual/help/faqs",
// { text: "FAQs", link: "/manual/help/faqs" }, collapsed: true,
// { items: [
// text: "Request support", {
// link: "/manual/help/request-technical-support", text: "Olares FAQs",
// }, link: "/manual/help/olares",
//{ },
// text: "Troubleshooting Guide", {
// link: "/manual/help/troubleshooting-guide", text: "Installation FAQs",
// }, link: "/manual/help/installation",
},
{
text: "Usage FAQs",
link: "/manual/help/usage",
},
// {
// text: "Request support",
// link: "/manual/help/request-technical-support",
// },
// {
// text: "Troubleshooting",
// link: "/manual/help/troubleshooting",
// },
],
},
], ],
}, },
{ {
@@ -109,7 +124,7 @@ const side = {
link: "/manual/larepass/back-up-mnemonics" link: "/manual/larepass/back-up-mnemonics"
}, },
{ {
text: "Access Olares locally", text: "Access Olares securely",
link: "/manual/get-started/local-access", link: "/manual/get-started/local-access",
}, },
{ {
@@ -127,39 +142,39 @@ const side = {
text: "Manage accounts", text: "Manage accounts",
collapsed: true, collapsed: true,
items: [ items: [
{text: "Create accounts", link:"/manual/larepass/create-account"}, { text: "Create accounts", link: "/manual/larepass/create-account" },
{text: "Back up mnemonics", link: "/manual/larepass/back-up-mnemonics"}, { text: "Back up mnemonics", link: "/manual/larepass/back-up-mnemonics" },
{text: "Manage integrations", link:"/manual/larepass/integrations"}, { text: "Manage integrations", link: "/manual/larepass/integrations" },
], ],
}, },
{text: "Use VPN", link:"/manual/larepass/private-network"}, { text: "Use VPN", link: "/manual/larepass/private-network" },
{ {
text: "Manage device", text: "Manage device",
collapsed: true, collapsed: true,
items: [ items: [
{text: "Activate Olares", link:"/manual/larepass/activate-olares"}, { text: "Activate Olares", link: "/manual/larepass/activate-olares" },
{text: "Manage Olares", link:"/manual/larepass/manage-olares"}, { text: "Manage Olares", link: "/manual/larepass/manage-olares" },
], ],
}, },
{text: "Manage files", link:"/manual/larepass/manage-files"}, { text: "Manage files", link: "/manual/larepass/manage-files" },
// collapsed: true, // collapsed: true,
//items: [ //items: [
// {text: "Common file operations", link:"/manual/larepass/manage-files"}, // {text: "Common file operations", link:"/manual/larepass/manage-files"},
// {text: "Sync and share", link:"/manual/larepass/sync-share"} // {text: "Sync and share", link:"/manual/larepass/sync-share"}
// ] // ]
// }, // },
{ {
text: "Manage passwords", text: "Manage passwords",
collapsed: true, collapsed: true,
items: [ items: [
{text: "Autofill passwords", link: "/manual/larepass/autofill"}, { text: "Autofill passwords", link: "/manual/larepass/autofill" },
{text: "Generate 2FA codes", link: "/manual/larepass/two-factor-verification"}, { text: "Generate 2FA codes", link: "/manual/larepass/two-factor-verification" },
], ],
}, },
{ /*{
text: "Manage knowledge", text: "Manage knowledge",
link: "/manual/larepass/manage-knowledge", link: "/manual/larepass/manage-knowledge",
}, },*/
], ],
}, },
{ {
@@ -168,7 +183,24 @@ const side = {
link: "/manual/olares/", link: "/manual/olares/",
items: [ items: [
{ text: "Desktop", link: "/manual/olares/desktop", }, { text: "Desktop", link: "/manual/olares/desktop", },
{ text: "Market", link: "/manual/olares/market", }, {
text: "Market",
collapsed: true,
items: [
{
text: "Basic operations",
link: "/manual/olares/market/market",
},
{
text: "Clone applications",
link: "/manual/olares/market/clone-apps",
},
{
text: "Manage paid applications",
link: "/manual/olares/market/purchase-paid-apps",
},
],
},
{ {
text: "Files", text: "Files",
collapsed: true, collapsed: true,
@@ -178,18 +210,26 @@ const side = {
text: "Basic file operations", text: "Basic file operations",
link: "/manual/olares/files/add-edit-download", link: "/manual/olares/files/add-edit-download",
}, },
// { // {
// text: "Sync and share", // text: "Sync and share",
// link: "/manual/larepass/sync-share", // link: "/manual/larepass/sync-share",
// }, // },
{
text: "Share files",
link: "/manual/olares/files/share-files",
},
{
text: "Sync files to local",
link: "/manual/olares/files/sync-files",
},
{ {
text: "Mount SMB", text: "Mount SMB",
link: "/manual/olares/files/mount-SMB", link: "/manual/olares/files/mount-SMB",
}, },
{ {
text: "Mount cloud storage", text: "Mount cloud storage",
link: "/manual/olares/files/mount-cloud-storage", link: "/manual/olares/files/mount-cloud-storage",
}, },
], ],
}, },
{ {
@@ -224,17 +264,32 @@ const side = {
text: "Basic operations", text: "Basic operations",
link: "/manual/olares/wise/basics", link: "/manual/olares/wise/basics",
}, },
{ /*{
text: "Get recommendation engine", text: "Get recommendation engine",
link: "/manual/olares/wise/recommend", link: "/manual/olares/wise/recommend",
}, },*/
{ {
text: "Manage your feeds", text: "Manage your feeds",
link: "/manual/olares/wise/subscribe", link: "/manual/olares/wise/subscribe",
}, },
{ {
text: "Organize your knowledge", text: "Manage cookies",
link: "/manual/olares/wise/manage-cookies",
},
{
text: "Organize with filters",
link: "/manual/olares/wise/filter", link: "/manual/olares/wise/filter",
collapsed: true,
items: [
{
text: "Filter syntax",
link: "/manual/olares/wise/filter-syntax-guide",
},
{
text: "Filter example",
link: "/manual/olares/wise/filter-examples",
},
],
}, },
], ],
}, },
@@ -305,16 +360,16 @@ const side = {
link: "/manual/olares/settings/manage-app-env", link: "/manual/olares/settings/manage-app-env",
}, },
], ],
}, },
{ {
text: "Manage integrations", text: "Manage integrations",
link:"/manual/olares/settings/integrations", link: "/manual/olares/settings/integrations",
}, },
{ {
text: "Customize appearance", text: "Customize appearance",
link:"/manual/olares/settings/language-appearance", link: "/manual/olares/settings/language-appearance",
}, },
{text: "Manage VPN", link: "/manual/olares/settings/remote-access",}, { text: "Manage VPN", link: "/manual/olares/settings/remote-access", },
{ {
text: "Configure network", text: "Configure network",
collapsed: true, collapsed: true,
@@ -325,54 +380,59 @@ const side = {
}, },
{ {
text: "Set up hosts file", text: "Set up hosts file",
link:"/manual/olares/settings/set-up-hosts", link: "/manual/olares/settings/set-up-hosts",
}, },
], ],
}, },
{text: "Manage GPU", link: "/manual/olares/settings/gpu-resource"}, { text: "Manage GPU", link: "/manual/olares/settings/gpu-resource" },
{text: "Set video playback", link: "/manual/olares/settings/video"}, { text: "Set video playback", link: "/manual/olares/settings/video" },
{ text: "Manage search rules", link: "/manual/olares/settings/search" },
{ {
text: "Backup and restore", text: "Backup and restore",
collapsed: true, collapsed: true,
items: [ items: [
{text: "Backup", link: "/manual/olares/settings/backup"}, { text: "Backup", link: "/manual/olares/settings/backup" },
{text: "Restore", link: "/manual/olares/settings/restore"}, { text: "Restore", link: "/manual/olares/settings/restore" },
], ],
}, },
{text: "Developer resources", link: "/manual/olares/settings/developer"}, { text: "Developer resources", link: "/manual/olares/settings/developer" },
] ]
}, },
{text: "Dashboard", link: "/manual/olares/resources-usage"}, { text: "Dashboard", link: "/manual/olares/resources-usage" },
{text: "Profile", link: "/manual/olares/profile"}, { text: "Profile", link: "/manual/olares/profile" },
], ],
}, },
{ {
text: "Best practices", text: "Tutorials",
link: "/manual/best-practices/", link: "/manual/best-practices/",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Set up custom domain", text: "Set up custom domain",
link: "/manual/best-practices/set-custom-domain", link: "/manual/best-practices/set-custom-domain",
}, },
{ {
text: "Manage knowledge with Wise", text: "Manage knowledge with Wise",
link: "/manual/best-practices/organize-content", link: "/manual/best-practices/organize-content",
}, },
{ {
text: "Install a multi-node Olares cluster", text: "Install a multi-node Olares cluster",
link: "/manual/best-practices/install-olares-multi-node", link: "/manual/best-practices/install-olares-multi-node",
}, },
{ {
text: "Install Olares on PVE with GPU Passthrough", text: "Install Olares on PVE with GPU Passthrough",
link: "/manual/best-practices/install-olares-gpu-passthrough", link: "/manual/best-practices/install-olares-gpu-passthrough",
}, },
{ {
text: "Expand storage in Olares", text: "Expand storage in Olares",
link: "/manual/best-practices/expand-storage-in-olares", link: "/manual/best-practices/expand-storage-in-olares",
}, },
], {
}, text: "Access Olares locally",
link: "/manual/best-practices/local-access",
},
],
},
{ text: "Glossary", link: "/manual/glossary" }, { text: "Glossary", link: "/manual/glossary" },
], ],
"/space/": [ "/space/": [
@@ -421,83 +481,106 @@ const side = {
}, },
], ],
"/use-cases/": [ "/use-cases/": [
{ {
text: "Use cases", text: "Use cases",
link: "/use-cases/", link: "/use-cases/",
items: [ items: [
{ {
text: "Stable Diffusion", text: "Stable Diffusion",
link: "/use-cases/stable-diffusion", link: "/use-cases/stable-diffusion",
}, },
{ {
text: "ComfyUI", text: "ComfyUI",
link: "/use-cases/comfyui", link: "/use-cases/comfyui",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Manage ComfyUI", text: "Manage ComfyUI",
link: "/use-cases/comfyui-launcher", link: "/use-cases/comfyui-launcher",
}, },
{ {
text: "Use ComfyUI for Krita", text: "Use ComfyUI for Krita",
link: "/use-cases/comfyui-for-krita", link: "/use-cases/comfyui-for-krita",
}, },
] ]
}, },
{ {
text: "Ollama", text: "Ollama",
link: "/use-cases/ollama", link: "/use-cases/ollama",
}, },
{ {
text: "Open WebUI", text: "Open WebUI",
link: "/use-cases/openwebui", link: "/use-cases/openwebui",
}, },
{ {
text: "Perplexica", text: "Perplexica",
link: "/use-cases/perplexica", link: "/use-cases/perplexica",
}, },
{ {
text: "Dify", text: "Dify",
link: "/use-cases/dify", link: "/use-cases/dify",
}, },
{ {
text: "Jellyfin", text: "Jellyfin",
link: "/use-cases/stream-media", link: "/use-cases/stream-media",
}, },
{ {
text: "Steam", text: "Steam",
link: "/use-cases/stream-game", collapsed: true,
}, items: [
{ {
text: "Redroid", text: "Play directly on Olares",
link: "/use-cases/host-cloud-android", link: "/use-cases/play-games-directly",
}, },
{ {
text: "Windows", text: "Stream to other devices",
link: "/use-cases/windows", link: "/use-cases/stream-game",
}, }
{ ]
text: "DeerFlow", },
link: "/use-cases/deerflow", // {
}, // text: "Redroid",
{ // link: "/use-cases/host-cloud-android",
text: "Duix.Avatar", // },
link: "/use-cases/duix-avatar", {
}, text: "Windows",
{ link: "/use-cases/windows",
text: "ACE-Step", },
link: "/use-cases/ace-step", {
}, text: "DeerFlow",
], link: "/use-cases/deerflow",
}, },
], {
text: "Duix.Avatar",
link: "/use-cases/duix-avatar",
},
{
text: "ACE-Step",
link: "/use-cases/ace-step",
},
{
text: "Stirling PDF",
link: "/use-cases/stirling-pdf",
},
{
text: "PDFMathTranslate",
link: "/use-cases/pdfmathtranslate",
},
{
text: "LobeChat",
link: "/use-cases/lobechat",
},
],
},
],
"/developer/": [ "/developer/": [
{ {
text: "Concepts", text: "Concepts",
link: "/developer/concepts/", link: "/developer/concepts/",
items: [ items: [
{ text: "Olares architecture", link: "/developer/concepts/system-architecture" }, { text: "Olares architecture", link: "/developer/concepts/system-architecture" },
{ text: "Olares ID", {
text: "Olares ID",
link: "/developer/concepts/olares-id", link: "/developer/concepts/olares-id",
collapsed: true, collapsed: true,
items: [ items: [
@@ -534,7 +617,7 @@ const side = {
{ text: "Secrets", link: "/developer/concepts/secrets" }, { text: "Secrets", link: "/developer/concepts/secrets" },
], ],
}, },
{ {
text: "Installation deep-dive", text: "Installation deep-dive",
link: "/developer/install/", link: "/developer/install/",
items: [ items: [
@@ -559,74 +642,55 @@ const side = {
link: "/developer/install/cli/olares-cli", link: "/developer/install/cli/olares-cli",
collapsed: true, collapsed: true,
items: [ items: [
{ text: "gpu", link: "/developer/install/cli/gpu" },
{ text: "osinfo", link: "/developer/install/cli/osinfo" },
{ text: "node", link: "/developer/install/cli/node" },
{ {
text: "backups", text: "backups",
link: "/developer/install/cli/backups", link: "/developer/install/cli/backups",
collapsed: true, collapsed: true,
items: [ items: [
{text: "download", link: "/developer/install/cli/backups-download"}, { text: "backup", link: "/developer/install/cli/backups-backup" },
{text: "region", link: "/developer/install/cli/backups-region"}, { text: "download", link: "/developer/install/cli/backups-download" },
{text: "backup", link: "/developer/install/cli/backups-backup"}, { text: "region", link: "/developer/install/cli/backups-region" },
{text: "restore", link: "/developer/install/cli/backups-restore"}, { text: "restore", link: "/developer/install/cli/backups-restore" },
{text: "snapshots", link: "/developer/install/cli/backups-snapshots"}, { text: "snapshots", link: "/developer/install/cli/backups-snapshots" },
], ],
},
{
text: "change-ip",
link: "/developer/install/cli/change-ip",
},
{
text: "download",
link: "/developer/install/cli/download",
}, },
{ text: "change-ip", link: "/developer/install/cli/change-ip" },
{ text: "disk", link: "/developer/install/cli/disk" },
{ text: "download", link: "/developer/install/cli/download" },
{ text: "gpu", link: "/developer/install/cli/gpu" },
{ text: "info", link: "/developer/install/cli/info" }, { text: "info", link: "/developer/install/cli/info" },
{ text: "install", link: "/developer/install/cli/install" },
{ text: "logs", link: "/developer/install/cli/logs" },
{ text: "node", link: "/developer/install/cli/node" },
{ text: "osinfo", link: "/developer/install/cli/osinfo" },
{ text: "precheck", link: "/developer/install/cli/precheck" },
{ text: "prepare", link: "/developer/install/cli/prepare" },
{ text: "release", link: "/developer/install/cli/release" },
{ text: "start", link: "/developer/install/cli/start" },
{ text: "stop", link: "/developer/install/cli/stop" },
{ text: "uninstall", link: "/developer/install/cli/uninstall" },
{ text: "upgrade", link: "/developer/install/cli/upgrade" },
{ {
text: "install", text: "user",
link: "/developer/install/cli/install", link: "/developer/install/cli/user",
}, collapsed: true,
{ items: [
text: "user activate", { text: "activate", link: "/developer/install/cli/user-activate" },
link: "/developer/install/cli/user-activate", { text: "create", link: "/developer/install/cli/user-create" },
}, { text: "delete", link: "/developer/install/cli/user-delete" },
{ { text: "get", link: "/developer/install/cli/user-get" },
text: "logs", { text: "list", link: "/developer/install/cli/user-list" },
link: "/developer/install/cli/logs", { text: "reset-password", link: "/developer/install/cli/user-reset-password" },
}, ],
{
text: "precheck",
link: "/developer/install/cli/precheck",
},
{
text: "prepare",
link: "/developer/install/cli/prepare",
},
{
text: "release",
link: "/developer/install/cli/release",
},
{
text: "start",
link: "/developer/install/cli/start",
},
{
text: "stop",
link: "/developer/install/cli/stop",
},
{
text: "uninstall",
link: "/developer/install/cli/uninstall",
}, },
], ],
}, },
{ {
text: "Olares versioning", text: "Olares versioning",
link: "/developer/install/versioning", link: "/developer/install/versioning",
}, },
], ],
}, },
{ {
text: "Develop Olares apps", text: "Develop Olares apps",
link: "/developer/develop/", link: "/developer/develop/",
@@ -682,43 +746,43 @@ const side = {
// items: [ // items: [
// { // {
// text: "terminus-info", // text: "terminus-info",
// link: "/developer/develop/advanced/terminus-info", // link: "/developer/develop/advanced/terminus-info",
// }, // },
// { // {
// text: "Service provider", // text: "Service provider",
// link: "/developer/develop/advanced/provider", // link: "/developer/develop/advanced/provider",
// }, // },
// { // {
// text: "AI", // text: "AI",
// link: "/developer/develop/advanced/ai", // link: "/developer/develop/advanced/ai",
// }, // },
// { text: "Cookie", link: "/developer/develop/advanced/cookie" }, // { text: "Cookie", link: "/developer/develop/advanced/cookie" },
// { text: "Database", link: "/developer/develop/advanced/database" }, // { text: "Database", link: "/developer/develop/advanced/database" },
// { // {
// text: "Account", // text: "Account",
// link: "/developer/develop/advanced/account", // link: "/developer/develop/advanced/account",
// }, // },
// { // {
// text: "Market", // text: "Market",
// link: "/developer/develop/advanced/market", // link: "/developer/develop/advanced/market",
// }, // },
// { // {
// text: "Websocket", // text: "Websocket",
// link: "/developer/develop/advanced/websocket", // link: "/developer/develop/advanced/websocket",
// }, // },
// { // {
// text: "File upload", // text: "File upload",
// link: "/developer/develop/advanced/file-upload", // link: "/developer/develop/advanced/file-upload",
// }, // },
// { // {
// text: "Secret", // text: "Secret",
// link: "/developer/develop/advanced/secret", // link: "/developer/develop/advanced/secret",
// }, // },
// { // {
// text: "Kubesphere", // text: "Kubesphere",
// link: "/developer/develop/advanced/kubesphere", // link: "/developer/develop/advanced/kubesphere",
// }, // },
// ], // ],
// }, // },
{ {
text: "Submit application", text: "Submit application",
@@ -756,86 +820,86 @@ const side = {
}, },
], ],
}, },
{ {
text: "Develop protocols", text: "Develop protocols",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Contract", text: "Contract",
link: "/developer/contribute/olares-id/contract/contract", link: "/developer/contribute/olares-id/contract/contract",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Architecture", text: "Architecture",
link: "/developer/contribute/olares-id/contract/architecture", link: "/developer/contribute/olares-id/contract/architecture",
}, },
{ {
text: "DID", text: "DID",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Design", text: "Design",
link: "/developer/contribute/olares-id/contract/did/design", link: "/developer/contribute/olares-id/contract/did/design",
}, },
{ {
text: "Official Taggers", text: "Official Taggers",
link: "/developer/contribute/olares-id/contract/did/official-taggers", link: "/developer/contribute/olares-id/contract/did/official-taggers",
}, },
{ {
text: "Release History", text: "Release History",
link: "/developer/contribute/olares-id/contract/did/release-history", link: "/developer/contribute/olares-id/contract/did/release-history",
}, },
{ {
text: "FAQ", text: "FAQ",
link: "/developer/contribute/olares-id/contract/did/faq", link: "/developer/contribute/olares-id/contract/did/faq",
}, },
], ],
}, },
{ {
text: "Reputation", text: "Reputation",
link: "/developer/contribute/olares-id/contract/contract-reputation", link: "/developer/contribute/olares-id/contract/contract-reputation",
}, },
{ {
text: "Manage", text: "Manage",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Contract", text: "Contract",
link: "/developer/contribute/olares-id/contract/manage/contract", link: "/developer/contribute/olares-id/contract/manage/contract",
}, },
{ {
text: "SDK", text: "SDK",
link: "/developer/contribute/olares-id/contract/manage/sdk", link: "/developer/contribute/olares-id/contract/manage/sdk",
}, },
{ {
text: "Environment", text: "Environment",
link: "/developer/contribute/olares-id/contract/manage/environment", link: "/developer/contribute/olares-id/contract/manage/environment",
}, },
], ],
}, },
], ],
}, },
{ {
text: "Verifiable Credential", text: "Verifiable Credential",
link: "/developer/contribute/olares-id/verifiable-credential/overview", link: "/developer/contribute/olares-id/verifiable-credential/overview",
collapsed: true, collapsed: true,
items: [ items: [
{ {
text: "Issuer", text: "Issuer",
link: "/developer/contribute/olares-id/verifiable-credential/issuer", link: "/developer/contribute/olares-id/verifiable-credential/issuer",
}, },
{ {
text: "Verifer", text: "Verifer",
link: "/developer/contribute/olares-id/verifiable-credential/verifer", link: "/developer/contribute/olares-id/verifiable-credential/verifer",
}, },
{ {
text: "Olares", text: "Olares",
link: "/developer/contribute/olares-id/verifiable-credential/olares", link: "/developer/contribute/olares-id/verifiable-credential/olares",
}, },
], ],
}, },
], ],
}, },
], ],
}, },
], ],

View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
const targetUrl = 'https://www.olares.cn/larepass'
</script>
<template>
<a :href="targetUrl" target="_blank" rel="noreferrer" class="app-link">
<slot>LarePass 下载页面</slot>
</a>
</template>

View File

@@ -0,0 +1,9 @@
<script setup lang="ts">
const targetUrl = 'https://www.olares.com/larepass'
</script>
<template>
<a :href="targetUrl" target="_blank" rel="noreferrer" class="app-link">
<slot>LarePass Download page</slot>
</a>
</template>

View File

@@ -14,6 +14,9 @@ import OSTabs from "./components/OStabs.vue";
import VersionSwitcher from "./components/VersionSwitcher.vue"; import VersionSwitcher from "./components/VersionSwitcher.vue";
import _ from "lodash"; import _ from "lodash";
import { redirects } from './redirects'; import { redirects } from './redirects';
import AppLinkGlobal from './components/AppLinkGlobal.vue'
import AppLinkCN from './components/AppLinkCN.vue'
const LANGUAGE_LOCAL_KEY = "language"; const LANGUAGE_LOCAL_KEY = "language";
let isMenuChange = false; let isMenuChange = false;
@@ -27,6 +30,8 @@ enhanceApp({ app, router }: { app: App; router: Router }) {
app.component("FilterableList", FilterableList); app.component("FilterableList", FilterableList);
app.component("OSTabs", OSTabs); app.component("OSTabs", OSTabs);
app.component("VersionSwitcher", VersionSwitcher); app.component("VersionSwitcher", VersionSwitcher);
app.component('AppLinkGlobal', AppLinkGlobal)
app.component('AppLinkCN', AppLinkCN)
router.onBeforeRouteChange = (to: string) => { router.onBeforeRouteChange = (to: string) => {
const path = to.replace(/\.html$/i, ''), const path = to.replace(/\.html$/i, ''),

View File

@@ -6,23 +6,36 @@ const side = {
text: "Olares 是什么?", text: "Olares 是什么?",
link: "/zh/manual/overview", link: "/zh/manual/overview",
items: [ items: [
// { text: "应用场景", link: "/zh/manual/why-olares" }, // { text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" },
//{ text: "功能对比", link: "/zh/manual/feature-overview" }, {
{ text: "比较 Olares 和 NAS", link: "/zh/manual/olares-vs-nas" }, text: "常见问题",
{text: "帮助与支持", link: "/zh/manual/help/request-technical-support",} // link: "/zh/manual/help/faqs",
// collapsed: true, collapsed: true,
// items: [ items: [
// { text: "常见问题", link: "/zh/manual/help/faqs" }, {
// { text: "产品",
// text: "技术支持", link: "/zh/manual/help/olares",
// link: "/zh/manual/help/request-technical-support", },
// }, {
text: "安装激活",
link: "/zh/manual/help/installation",
},
{
text: "使用",
link: "/zh/manual/help/usage",
},
// {
// text: "技术支持",
// link: "/zh/manual/help/request-technical-support",
// },
// { // {
// text: "Troubleshooting Guide", // text: "Troubleshooting Guide",
// link: "/zh/manual/help/troubleshooting-guide", // link: "/zh/manual/help/troubleshooting-guide",
// }, // },
], ],
}, },
],
},
{ {
text: "快速开始", text: "快速开始",
collapsed: false, collapsed: false,
@@ -110,7 +123,7 @@ const side = {
link: "/zh/manual/larepass/back-up-mnemonics", link: "/zh/manual/larepass/back-up-mnemonics",
}, },
{ {
text: "内网访问 Olares", text: "安全访问 Olares",
link: "zh/manual/get-started/local-access", link: "zh/manual/get-started/local-access",
}, },
{ {
@@ -128,39 +141,39 @@ const side = {
text: "管理账户", text: "管理账户",
collapsed: true, collapsed: true,
items: [ items: [
{text: "创建账户", link:"/zh/manual/larepass/create-account"}, { text: "创建账户", link: "/zh/manual/larepass/create-account" },
{text: "备份助记词", link: "/zh/manual/larepass/back-up-mnemonics"}, { text: "备份助记词", link: "/zh/manual/larepass/back-up-mnemonics" },
{text: "管理集成", link:"/zh/manual/larepass/integrations"}, { text: "管理集成", link: "/zh/manual/larepass/integrations" },
], ],
}, },
{text: "使用专用网络", link:"/zh/manual/larepass/private-network"}, { text: "使用专用网络", link: "/zh/manual/larepass/private-network" },
{ {
text: "管理设备", text: "管理设备",
collapsed: true, collapsed: true,
items: [ items: [
{text: "激活 Olares", link:"/zh/manual/larepass/activate-olares"}, { text: "激活 Olares", link: "/zh/manual/larepass/activate-olares" },
{text: "管理 Olares", link:"/zh/manual/larepass/manage-olares"}, { text: "管理 Olares", link: "/zh/manual/larepass/manage-olares" },
], ],
}, },
{text: "管理文件", link:"/zh/manual/larepass/manage-files"}, { text: "管理文件", link: "/zh/manual/larepass/manage-files" },
// collapsed: true, // collapsed: true,
// items: [ // items: [
// {text: "常用文件操作", link:"/zh/manual/larepass/manage-files"}, // {text: "常用文件操作", link:"/zh/manual/larepass/manage-files"},
// {text: "同步与共享", link:"/zh/manual/larepass/sync-share"} // {text: "同步与共享", link:"/zh/manual/larepass/sync-share"}
// ] // ]
// }, // },
{ {
text: "管理密码", text: "管理密码",
collapsed: true, collapsed: true,
items: [ items: [
{text: "自动填充", link: "/zh/manual/larepass/autofill"}, { text: "自动填充", link: "/zh/manual/larepass/autofill" },
{text: "双重验证", link: "/zh/manual/larepass/two-factor-verification"}, { text: "双重验证", link: "/zh/manual/larepass/two-factor-verification" },
], ],
}, },
{ /*{
text: "管理内容", text: "管理内容",
link: "/zh/manual/larepass/manage-knowledge", link: "/zh/manual/larepass/manage-knowledge",
}, },*/
], ],
}, },
{ {
@@ -169,7 +182,24 @@ const side = {
"link": "/zh/manual/olares/", "link": "/zh/manual/olares/",
"items": [ "items": [
{ "text": "桌面", "link": "/zh/manual/olares/desktop" }, { "text": "桌面", "link": "/zh/manual/olares/desktop" },
{ "text": "应用市场", "link": "/zh/manual/olares/market" }, {
"text": "应用市场",
"collapsed": true,
"items": [
{
"text": "基本操作",
"link": "/zh/manual/olares/market/market"
},
{
"text": "管理付费应用",
"link": "/zh/manual/olares/market/purchase-paid-apps"
},
{
"text": "克隆应用",
"link": "/zh/manual/olares/market/clone-apps"
},
],
},
{ {
"text": "文件管理器", "text": "文件管理器",
"collapsed": true, "collapsed": true,
@@ -181,8 +211,16 @@ const side = {
}, },
//{ //{
// "text": "同步与共享", // "text": "同步与共享",
// "link": "/zh/manual/larepass/sync-share" // "link": "/zh/manual/larepass/sync-share"
// }, // },
{
"text": "分享文件",
"link": "/zh/manual/olares/files/share-files"
},
{
"text": "同步文件至本地",
"link": "/zh/manual/olares/files/sync-files"
},
{ {
"text": "挂载 SMB", "text": "挂载 SMB",
"link": "/zh/manual/olares/files/mount-SMB" "link": "/zh/manual/olares/files/mount-SMB"
@@ -225,19 +263,34 @@ const side = {
"text": "基本操作", "text": "基本操作",
"link": "/zh/manual/olares/wise/basics" "link": "/zh/manual/olares/wise/basics"
}, },
{ /*{
"text": "获取推荐引擎", "text": "获取推荐引擎",
"link": "/zh/manual/olares/wise/recommend" "link": "/zh/manual/olares/wise/recommend"
}, },*/
{ {
"text": "管理订阅", "text": "管理订阅",
"link": "/zh/manual/olares/wise/subscribe" "link": "/zh/manual/olares/wise/subscribe"
}, },
{ {
"text": "整理知识", text: "管理 Cookie",
"link": "/zh/manual/olares/wise/filter" link: "/zh/manual/olares/wise/manage-cookies",
} },
] {
"text": "管理知识",
"link": "/zh/manual/olares/wise/filter",
collapsed: true,
items: [
{
"text": "过滤语法参考",
"link": "/zh/manual/olares/wise/filter-syntax-guide"
},
{
"text": "过滤视图示例",
"link": "/zh/manual/olares/wise/filter-examples"
}
],
},
],
}, },
{ {
"text": "控制面板", "text": "控制面板",
@@ -271,7 +324,7 @@ const side = {
"collapsed": true, "collapsed": true,
"link": "/zh/manual/olares/settings/", "link": "/zh/manual/olares/settings/",
"items": [ "items": [
{"text": "我的 Olares", link: "/zh/manual/olares/settings/my-olares"}, { "text": "我的 Olares", link: "/zh/manual/olares/settings/my-olares" },
{ {
"text": "管理用户", "text": "管理用户",
"collapsed": true, "collapsed": true,
@@ -303,16 +356,16 @@ const side = {
link: "/zh/manual/olares/settings/manage-app-env", link: "/zh/manual/olares/settings/manage-app-env",
}, },
], ],
}, },
{ {
"text": "管理集成", "text": "管理集成",
"link":"/zh/manual/olares/settings/integrations", "link": "/zh/manual/olares/settings/integrations",
}, },
{ {
"text": "自定义外观", "text": "自定义外观",
"link":"/zh/manual/olares/settings/language-appearance", "link": "/zh/manual/olares/settings/language-appearance",
}, },
{text: "管理 VPN", link: "/zh/manual/olares/settings/remote-access",}, { text: "管理 VPN", link: "/zh/manual/olares/settings/remote-access", },
{ {
"text": "配置网络", "text": "配置网络",
"collapsed": true, "collapsed": true,
@@ -323,29 +376,30 @@ const side = {
}, },
{ {
"text": "设置 hosts 文件", "text": "设置 hosts 文件",
"link":"/zh/manual/olares/settings/set-up-hosts", "link": "/zh/manual/olares/settings/set-up-hosts",
}, },
], ],
}, },
{text: "管理 GPU", link: "/zh/manual/olares/settings/gpu-resource"}, { text: "管理 GPU", link: "/zh/manual/olares/settings/gpu-resource" },
{text: "视频设置", link: "/zh/manual/olares/settings/video"}, { text: "视频设置", link: "/zh/manual/olares/settings/video" },
{ text: "文件搜索", link: "/zh/manual/olares/settings/search" },
{ {
"text": "备份与恢复", "text": "备份与恢复",
"collapsed": true, "collapsed": true,
"items": [ "items": [
{text: "备份", link: "/zh/manual/olares/settings/backup"}, { text: "备份", link: "/zh/manual/olares/settings/backup" },
{text: "恢复", link: "/zh/manual/olares/settings/restore"}, { text: "恢复", link: "/zh/manual/olares/settings/restore" },
], ],
}, },
{text: "开发者资源", link: "/zh/manual/olares/settings/developer"}, { text: "开发者资源", link: "/zh/manual/olares/settings/developer" },
] ]
}, },
{ "text": "仪表盘", "link": "/zh/manual/olares/resources-usage" }, { "text": "仪表盘", "link": "/zh/manual/olares/resources-usage" },
{ "text": "Profile", "link": "/zh/manual/olares/profile" } { "text": "Profile", "link": "/zh/manual/olares/profile" }
] ]
}, },
{ {
text: "Olares 进阶", text: "教程",
collapsed: true, collapsed: true,
link: "/zh/manual/best-practices/", link: "/zh/manual/best-practices/",
items: [ items: [
@@ -373,6 +427,10 @@ const side = {
text: "在 Olares 中扩展存储空间", text: "在 Olares 中扩展存储空间",
link: "/zh/manual/best-practices/expand-storage-in-olares", link: "/zh/manual/best-practices/expand-storage-in-olares",
}, },
{
text: "本地访问 Olares",
link: "/manual/best-practices/local-access",
},
], ],
}, },
{ text: "术语", link: "/zh/manual/glossary" }, { text: "术语", link: "/zh/manual/glossary" },
@@ -425,7 +483,7 @@ const side = {
], ],
"/zh/use-cases/": [ "/zh/use-cases/": [
{ {
text: "Tutorials & use cases", text: "应用示例",
link: "/zh/use-cases/", link: "/zh/use-cases/",
items: [ items: [
{ {
@@ -469,12 +527,22 @@ const side = {
}, },
{ {
text: "Steam", text: "Steam",
link: "/zh/use-cases/stream-game", collapsed: true,
}, items: [
{ {
text: "Redroid", text: "在 Olares 本机游玩",
link: "/zh/use-cases/host-cloud-android", link: "/zh/use-cases/play-games-directly",
},
{
text: "串流到其他设备",
link: "/zh/use-cases/stream-game",
}
]
}, },
// {
// text: "Redroid",
// link: "/zh/use-cases/host-cloud-android",
// },
], ],
}, },
], ],
@@ -484,7 +552,8 @@ const side = {
link: "/zh/developer/concepts/", link: "/zh/developer/concepts/",
items: [ items: [
{ text: "系统架构", link: "/zh/developer/concepts/system-architecture" }, { text: "系统架构", link: "/zh/developer/concepts/system-architecture" },
{ text: "Olares ID", {
text: "Olares ID",
link: "/zh/developer/concepts/olares-id", link: "/zh/developer/concepts/olares-id",
collapsed: true, collapsed: true,
items: [ items: [
@@ -543,76 +612,56 @@ const side = {
}, },
{ {
text: "Olares CLI", text: "Olares CLI",
collapsed: true,
link: "/zh/developer/install/cli/olares-cli", link: "/zh/developer/install/cli/olares-cli",
collapsed: true,
items: [ items: [
{text: "gpu", link: "/zh/developer/install/cli/gpu"},
{text: "osinfo", link: "/zh/developer/install/cli/osinfo"},
{text: "node", link: "/zh/developer/install/cli/node"},
{ {
text: "backups", text: "backups",
link: "/zh/developer/install/cli/backups", link: "/zh/developer/install/cli/backups",
collapsed: true, collapsed: true,
items: [ items: [
{text: "download", link: "/zh/developer/install/cli/backups-download"}, { text: "backup", link: "/zh/developer/install/cli/backups-backup" },
{text: "region", link: "/zh/developer/install/cli/backups-region"}, { text: "download", link: "/zh/developer/install/cli/backups-download" },
{text: "backup", link: "/zh/developer/install/cli/backups-backup"}, { text: "region", link: "/zh/developer/install/cli/backups-region" },
{text: "restore", link: "/zh/developer/install/cli/backups-restore"}, { text: "restore", link: "/zh/developer/install/cli/backups-restore" },
{text: "snapshots", link: "/zh/developer/install/cli/backups-snapshots"}, { text: "snapshots", link: "/zh/developer/install/cli/backups-snapshots" },
], ],
},
{
text: "change-ip",
link: "/zh/developer/install/cli/change-ip",
},
{
text: "download",
link: "/zh/developer/install/cli/download",
},
{ text: "info", link: "/zh/developer/install/cli/info" },
{
text: "install",
link: "/zh/developer/install/cli/install",
},
{
text: "user activate",
link: "/zh/developer/install/cli/user-activate",
},
{
text: "logs",
link: "/zh/developer/install/cli/logs",
},
{
text: "precheck",
link: "/zh/developer/install/cli/precheck",
},
{
text: "prepare",
link: "/zh/developer/install/cli/prepare",
},
{
text: "release",
link: "/zh/developer/install/cli/release",
},
{
text: "start",
link: "/zh/developer/install/cli/start",
},
{
text: "stop",
link: "/zh/developer/install/cli/stop",
},
{
text: "uninstall",
link: "/zh/developer/install/cli/uninstall",
},
],
},
{
text: "版本说明",
link: "/zh/developer/install/versioning",
}, },
{ text: "change-ip", link: "/zh/developer/install/cli/change-ip" },
{ text: "disk", link: "/zh/developer/install/cli/disk" },
{ text: "download", link: "/zh/developer/install/cli/download" },
{ text: "gpu", link: "/zh/developer/install/cli/gpu" },
{ text: "info", link: "/zh/developer/install/cli/info" },
{ text: "install", link: "/zh/developer/install/cli/install" },
{ text: "logs", link: "/zh/developer/install/cli/logs" },
{ text: "node", link: "/zh/developer/install/cli/node" },
{ text: "osinfo", link: "/zh/developer/install/cli/osinfo" },
{ text: "precheck", link: "/zh/developer/install/cli/precheck" },
{ text: "prepare", link: "/zh/developer/install/cli/prepare" },
{ text: "release", link: "/zh/developer/install/cli/release" },
{ text: "start", link: "/zh/developer/install/cli/start" },
{ text: "stop", link: "/zh/developer/install/cli/stop" },
{ text: "uninstall", link: "/zh/developer/install/cli/uninstall" },
{ text: "upgrade", link: "/zh/developer/install/cli/upgrade" },
{
text: "user",
link: "/zh/developer/install/cli/user",
collapsed: true,
items: [
{ text: "activate", link: "/zh/developer/install/cli/user-activate" },
{ text: "create", link: "/zh/developer/install/cli/user-create" },
{ text: "delete", link: "/zh/developer/install/cli/user-delete" },
{ text: "get", link: "/zh/developer/install/cli/user-get" },
{ text: "list", link: "/zh/developer/install/cli/user-list" },
{ text: "reset-password", link: "/zh/developer/install/cli/user-reset-password" },
],
},
],
},
{
text: "版本说明",
link: "/zh/developer/install/versioning",
},
], ],
}, },
{ {
@@ -654,7 +703,7 @@ const side = {
text: "OlaresManifest", text: "OlaresManifest",
link: "/zh/developer/develop/package/manifest", link: "/zh/developer/develop/package/manifest",
}, },
/*/{ /*{
text: "推荐算法", text: "推荐算法",
link: "/zh/developer/develop/package/recommend", link: "/zh/developer/develop/package/recommend",
},*/ },*/
@@ -664,66 +713,66 @@ const side = {
}, },
], ],
}, },
// { // {
// text: "进阶", // text: "进阶",
// collapsed: true, // collapsed: true,
// items: [ // items: [
// { // {
// text: "terminus-info", // text: "terminus-info",
// link: "/zh/developer/develop/advanced/terminus-info", // link: "/zh/developer/develop/advanced/terminus-info",
// }, // },
// { // {
// text: "Service Provider", // text: "Service Provider",
// link: "/zh/developer/develop/advanced/provider", // link: "/zh/developer/develop/advanced/provider",
// }, // },
// { // {
// text: "AI", // text: "AI",
// link: "/zh/developer/develop/advanced/ai", // link: "/zh/developer/develop/advanced/ai",
// }, // },
// { text: "Cookie", link: "/zh/developer/develop/advanced/cookie" }, // { text: "Cookie", link: "/zh/developer/develop/advanced/cookie" },
// { text: "数据库", link: "/zh/developer/develop/advanced/database" }, // { text: "数据库", link: "/zh/developer/develop/advanced/database" },
// { // {
// text: "账户", // text: "账户",
// link: "/zh/developer/develop/advanced/account", // link: "/zh/developer/develop/advanced/account",
// }, // },
// { // {
// text: "应用市场", // text: "应用市场",
// link: "/zh/developer/develop/advanced/market", // link: "/zh/developer/develop/advanced/market",
// }, // },
// { // {
// text: "Analytic", // text: "Analytic",
// link: "/zh/developer/develop/advanced/analytic", // link: "/zh/developer/develop/advanced/analytic",
// }, // },
// { // {
// text: "Websocket", // text: "Websocket",
// link: "/zh/developer/develop/advanced/websocket", // link: "/zh/developer/develop/advanced/websocket",
// }, // },
// { // {
// text: "文件上传", // text: "文件上传",
// link: "/zh/developer/develop/advanced/file-upload", // link: "/zh/developer/develop/advanced/file-upload",
// }, // },
// { // {
// text: "Rss", // text: "Rss",
// link: "/zh/developer/develop/advanced/rss", // link: "/zh/developer/develop/advanced/rss",
// }, // },
// { // {
// text: "密钥", // text: "密钥",
// link: "/zh/developer/develop/advanced/secret", // link: "/zh/developer/develop/advanced/secret",
// },
// {
// text: "Notification",
// link: "/zh/developer/develop/advanced/notification",
// },
// {
// text: "Frontend",
// link: "/zh/developer/develop/advanced/frontend",
// },
// {
// text: "Kubesphere",
// link: "/zh/developer/develop/advanced/kubesphere",
// },
// ],
// }, // },
// {
// text: "Notification",
// link: "/zh/developer/develop/advanced/notification",
// },
// {
// text: "Frontend",
// link: "/zh/developer/develop/advanced/frontend",
// },
// {
// text: "Kubesphere",
// link: "/zh/developer/develop/advanced/kubesphere",
// },
// ],
// },
{ {
text: "提交应用", text: "提交应用",
collapsed: true, collapsed: true,
@@ -842,8 +891,8 @@ const side = {
}, },
], ],
}, },
], ],
}; };
export const zh = defineConfig({ export const zh = defineConfig({
lang: "zh", lang: "zh",

View File

@@ -122,7 +122,7 @@ The mechanism consists of three procedures
- User - User
[Manage apps in Market](../../manual/olares/market.md)<br> [Manage apps in Market](../../manual/olares/market/market.md)<br>
- Developer - Developer

View File

@@ -17,7 +17,7 @@ outline: [2, 3]
### 1. Develop and test your application ### 1. Develop and test your application
Before submitting an application, please ensure that it has been thoroughly tested on your Olares. Before submitting an application, please ensure that it has been thoroughly tested on your Olares.
- Use Studio's dev-container to test and debug your application in a real online environment. [Learn more about Studio](../tutorial/). - Use Studio's dev-container to test and debug your application in a real online environment. [Learn more about Studio](../tutorial/develop.md).
- Use the [custom installation](../tutorial/package-upload.md) in the Market app for user testing. - Use the [custom installation](../tutorial/package-upload.md) in the Market app for user testing.
### 2. Submit an application ### 2. Submit an application

View File

@@ -92,13 +92,13 @@ This example demonstrates creating a basic web page manually.
``` ```
5. Create a file named `index.js` in `/root/` with the following content: 5. Create a file named `index.js` in `/root/` with the following content:
```js ```js
// Ensure the port matches what you defined // Ensure the port matches what you defined
const express = require('express'); const express = require('express');
const app = express(); const app = express();
app.use(express.static('public/')); app.use(express.static('public/'));
app.listen(8080), function() { app.listen(8080, function() {
console.log('Server is running on port 8080'); console.log('Server is running on port 8080');
}; });
``` ```
6. Create a `public` directory in `/root/` and add an `index.html` file: 6. Create a `public` directory in `/root/` and add an `index.html` file:
```html ```html
@@ -204,15 +204,15 @@ Once deployed, go to **Services** > **Ports**. You can see your new port listed
const express = require('express'); const express = require('express');
const app = express(); const app = express();
app.use(express.static('public/')); app.use(express.static('public/'));
app.listen(8080), function() { app.listen(8080, function() {
console.log('Server is running on port 8080'); console.log('Server is running on port 8080');
}; });
// Add the following // Add the following
const app_new = express(); const app_new = express();
app_new.use(express.static('new/')); app_new.use(express.static('new/'));
app_new.listen(8081), function() { app_new.listen(8081, function() {
console.log('Server is running on port 8081'); console.log('Server is running on port 8081');
}; });
``` ```
2. Create a `new` directory in `/root/` and add an `index.html` file: 2. Create a `new` directory in `/root/` and add an `index.html` file:
```html ```html

View File

@@ -65,7 +65,7 @@ These options apply to all backends:
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}' kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
``` ```
## Example ## Examples
```bash ```bash
# Backup to Tencent COS # Backup to Tencent COS
olares-cli backups backup cos --path /data --repo-name my_repo \ olares-cli backups backup cos --path /data --repo-name my_repo \

View File

@@ -12,7 +12,7 @@ olares-cli backups download [options]
|--------------------|-----------|--------------------------------------------------------|-------------------------|--------------------| |--------------------|-----------|--------------------------------------------------------|-------------------------|--------------------|
| `--download-cdn-url`| | Specifies the CDN URL for downloading the Restic tool. | No | System default URL | | `--download-cdn-url`| | Specifies the CDN URL for downloading the Restic tool. | No | System default URL |
| `--help` | `-h` | Displays help information. | No | N/A | | `--help` | `-h` | Displays help information. | No | N/A |
## Example ## Examples
```bash d ```bash d
# Download Restic using a custom CDN URL # Download Restic using a custom CDN URL
olares-cli backups download --download-cdn-url https://custom-cdn.example.com/restic olares-cli backups download --download-cdn-url https://custom-cdn.example.com/restic

View File

@@ -17,7 +17,7 @@ olares-cli backups region space [options]
1. To retrieve the access token and Olares DID, inspect the payload of the network requests made by the Olares Space web interface after logging in. The `token` field corresponds to the access token, and the `userid` field corresponds to the Olares DID. 1. To retrieve the access token and Olares DID, inspect the payload of the network requests made by the Olares Space web interface after logging in. The `token` field corresponds to the access token, and the `userid` field corresponds to the Olares DID.
## Example ## Examples
```bash ```bash
# Query cloud name and region ID # Query cloud name and region ID
olares-cli backups region space \ olares-cli backups region space \

View File

@@ -69,7 +69,7 @@ These options apply to all backends:
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}' kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
``` ```
## Example ## Examples
```bash ```bash
# Restore the data from Tencent COS # Restore the data from Tencent COS
olares-cli backups restore cos --path /data_restore --repo-name my_repo \ olares-cli backups restore cos --path /data_restore --repo-name my_repo \

View File

@@ -61,7 +61,7 @@ These options apply to all backends:
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}' kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
``` ```
## Example ## Examples
```bash ```bash
# List snapshots for Tencent COS # List snapshots for Tencent COS
olares-cli backups snapshots cos --repo-name my_repo \ olares-cli backups snapshots cos --repo-name my_repo \

View File

@@ -0,0 +1,33 @@
# `disk`
## Synopsis
The `disk` command provides a set of tools to manage storage resources in the Olares system. It is specifically used for managing LVM-based storage configurations.
```bash
olares-cli disk <subcommand>
```
## Subcommands
| Subcommand | Description |
|--|--|
| `extend` | Extends Olares storage capacity on LVM-based installations. |
| `list-unmounted` | Lists unmounted disks. |
## Options
| Name | Shorthand | Usage |
|--|--|--|
| `--help` | `-h` | Displays help information.|
## Examples
```bash
# List all disks that are connected but not mounted
olares-cli disk list-unmounted
# Extend Olares storage by adding newly detected unmounted disks
olares-cli disk extend
```

View File

@@ -32,7 +32,7 @@ olares-cli gpu <subcommand> [options]
| `--version`| `-v` | Specifies the Olares version for GPU drivers and components. <br>Version values follow the format `x.y.z` (e.g., `1.10.0`) or include a build date (e.g., `1.10.0-20241109`).<br> Refer to the [GitHub Releases page](https://github.com/beclab/Olares/releases) for available versions. | No | Current version | | `--version`| `-v` | Specifies the Olares version for GPU drivers and components. <br>Version values follow the format `x.y.z` (e.g., `1.10.0`) or include a build date (e.g., `1.10.0-20241109`).<br> Refer to the [GitHub Releases page](https://github.com/beclab/Olares/releases) for available versions. | No | Current version |
| `--help` | `-h` | Displays help information. | No | N/A | | `--help` | `-h` | Displays help information. | No | N/A |
## Example ## Examples
```bash ```bash
# Install GPU drivers and dependencies to a specific directory # Install GPU drivers and dependencies to a specific directory

View File

@@ -7,7 +7,7 @@ The `info` command displays general information about the installed Olares versi
olares-cli info olares-cli info
``` ```
## Flag ## Options
| Name | Shorthand | Usage | | Name | Shorthand | Usage |
|----------|-----------|---------------------------| |----------|-----------|---------------------------|

View File

@@ -28,7 +28,7 @@ olares-cli logs [option]
| `--output-dir` | | Saves logs to the specified directory. Creates the directory if it does not exist. | No | `./olares-logs` | | `--output-dir` | | Saves logs to the specified directory. Creates the directory if it does not exist. | No | `./olares-logs` |
| `--since` | | Fetches logs newer than a specified relative duration (e.g., `5s`, `2m`, `3h`). | No | `7d` | | `--since` | | Fetches logs newer than a specified relative duration (e.g., `5s`, `2m`, `3h`). | No | `7d` |
## Example ## Examples
```bash ```bash
# Collect all logs with default settings # Collect all logs with default settings
olares-cli logs olares-cli logs

View File

@@ -29,7 +29,7 @@ olares-cli node <subcommand> [options]
| `--version` | `-v` | Specifies the Olares version. <br>Version values follow the format `x.y.z` (e.g., `1.10.0`) or include a build date (e.g., `1.10.0-20241109`).<br> Refer to the [GitHub Releases page](https://github.com/beclab/Olares/releases) for available versions. | No | Current version | | `--version` | `-v` | Specifies the Olares version. <br>Version values follow the format `x.y.z` (e.g., `1.10.0`) or include a build date (e.g., `1.10.0-20241109`).<br> Refer to the [GitHub Releases page](https://github.com/beclab/Olares/releases) for available versions. | No | Current version |
| `--help` | `-h` | Displays help information. | No | N/A | | | `--help` | `-h` | Displays help information. | No | N/A | |
## Example ## Examples
```bash ```bash
# Retrieve system information from a master node at IP 192.168.1.15 # Retrieve system information from a master node at IP 192.168.1.15

View File

@@ -28,12 +28,13 @@ wsl -d Ubuntu
## Syntax ## Syntax
The Olares CLI uses the following syntax: The Olares CLI uses the following syntax:
> `olares-cli command [subcommand] [option]` > `olares-cli command [subcommand] [argument] [options] `
where where
- `command`: Specifies the main operation you want to perform. For example, `olares-cli install`. - `command`: Specifies the main operation you want to perform. For example, `olares-cli install`.
- `subcommand`: Further specifies the task for commands that support additional operations. For example, `wizard` or `component`. - `subcommand`: Further specifies the task for commands that support additional operations. For example, `wizard` or `component`.
- `option`: Optional arguments that modify the behavior of the `command`. Options include flags and options with arguments. - `argument`: Specifies the target resource or input data for the command, typically an ID, name, or file path. For example, in `olares-cli user activate <Olares ID> [options]`, `<Olares ID>` is the argument.
- `options`: Optional arguments that modify the behavior of the `command`. Options include flags and options with arguments.
Olares CLI allows you to temporarily override certain Olares default settings. Each option applies only to the command in which it is used. Olares CLI allows you to temporarily override certain Olares default settings. Each option applies only to the command in which it is used.
@@ -43,21 +44,23 @@ To get detailed help for any command, run `olares-cli help`.
## Available CLI commands ## Available CLI commands
| Operation | Syntax | Description | | Operation | Syntax | Description |
|--------------------|----------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------| |--|--|--|
| `gpu` | `olares-cli gpu <subcommand> [option]` | Manages GPU-related operations. | | `backups` | `olares-cli backups <subcommand> [options]` | Manages backup-related operations. |
| `info` | `olares-cli info <subcommand> [option]` | Displays general information about the operating system of the current device. | | `change-ip` | `olares-cli change-ip [options]` | Changes the IP address of the Olares OS. |
| `node` | `olares-cli node <subcommand> [option]` | Manages node-related operations. | | `disk` | `olares-cli disk <subcommand>` | Manages storage resources in the Olares system. |
| `backups` | `olares-cli backups <subcommand> [option]` | Manages backup-related operations. | | `download` | `olares-cli download <subcommand> [options]` | Downloads specific resources. |
| `change-ip` | `olares-cli change-ip [option]` | Changes the IP address of the Olares OS. | | `gpu` | `olares-cli gpu <subcommand> [options]` | Manages GPU-related operations. |
| `download` | `olares-cli download <subcommand> [option]` | Downloads specific resources. | | `info` | `olares-cli info [options]` | Displays general information about the downloaded Olares OS. |
| `info` | `olares-cli info [option]` | Displays general information about the downloaded Olares OS. | | `install` | `olares-cli install [options]` | Deploys system-level and user-level components of Olares. |
| `install` | `olares-cli install [option]` | Deploys system-level and user-level components of Olares. | | `logs` | `olares-cli logs [options]` | Collects logs from Olares system components for debugging and troubleshooting. |
| `logs` | `olares-cli logs [option]` | Collects logs from Olares system components for debugging and troubleshooting. | | `node` | `olares-cli node <subcommand> [options]` | Manages node-related operations. |
| `precheck` | `olares-cli precheck [option]` | Verifies whether the system environment meets all requirements for Olares installation. | | `osinfo` | `olares-cli osinfo <subcommand> [options]` | Displays general information about the operating system of the current device. |
| `prepare` | `olares-cli prepare [option]` | Prepares the environment for the installation process, including setting up essential services and configurations of Olares. | | `precheck` | `olares-cli precheck [options]` | Verifies whether the system environment meets all requirements for Olares installation. |
| `release` | `olares-cli release [option]` | Packages Olares installation resources for distribution or deployment. | | `prepare` | `olares-cli prepare [options]` | Prepares the environment for the installation process, including setting up essential services and configurations of Olares. |
| `start` | `olares-cli start [option]` | Starts Olares services and components. | | `release` | `olares-cli release [options]` | Packages Olares installation resources for distribution or deployment. |
| `stop` | `olares-cli stop [option]` | Stops Olares services and components. | | `start` | `olares-cli start [options]` | Starts Olares services and components. |
| `uninstall` | `olares-cli uninstall [option]` | Uninstalls Olares completely, or roll back the installation to a specific phase. | | `stop` | `olares-cli stop [options]` | Stops Olares services and components. |
| `uninstall` | `olares-cli uninstall [options]` | Uninstalls Olares completely, or roll back the installation to a specific phase. |
| `upgrade` | `olares-cli upgrade <subcommand> [options]` | Upgrades Olares and checks upgrade readiness and compatibility.|
| `user` | `olares-cli user <subcommand> [options]`| Manages users in the Olares system |

View File

@@ -8,13 +8,13 @@ The `osinfo` command provides detailed information about the operating system of
olares-cli osinfo <subcommand> [options] olares-cli osinfo <subcommand> [options]
``` ```
## Subcommand ## Subcommands
| Subcommand | Description | | Subcommand | Description |
|------------|----------------------------------------------------------------------| |------------|----------------------------------------------------------------------|
| `show` | Prints information about the operating system of the current device. | | `show` | Prints information about the operating system of the current device. |
## Flag ## Options
| Name | Short | Description | | Name | Short | Description |
|--------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |--------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

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