Compare commits

...

234 Commits

Author SHA1 Message Date
dkeven
1fca5a10c7 feat(gpu): supports dynamic detection of hot plugged-in GPUs 2026-01-22 17:16:20 +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
628 changed files with 9773 additions and 4292 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -70,4 +70,16 @@ export class SubAppPlatform extends WebPlatform implements AppPlatform {
}
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({
google: {
webClientId:
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com', // Use Web Client ID for all platforms
webClientId: getAppPlatform().socialKeys.google.webClientId,
iOSClientId:
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com', // for iOS
getAppPlatform().socialKeys.google.iOSClientId,
mode: getAppPlatform().getQuasar()?.platform.is?.android
? 'offline'
: 'online' // replaces grantOfflineAccess
@@ -45,8 +44,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
let clientId = '';
if (getAppPlatform().getQuasar()?.platform.is?.android) {
clientId =
'343424174381-cprm1j3a6da1bbprra97oc34lap3j0mp.apps.googleusercontent.com';
clientId = getAppPlatform().socialKeys.google.androidClientId;
response = await axiosInstanceProxy(
{
baseURL: 'https://cloud-api.jointerminus.com/',
@@ -68,8 +66,7 @@ export class GoogleAuthService extends OperateIntegrationAuth<GoogleIntegrationA
);
}
} else {
clientId =
'343424174381-vrtlie7g85jcso7c98c4vavo17qoied7.apps.googleusercontent.com';
clientId = getAppPlatform().socialKeys.google.iOSClientId;
}
const result = {

View File

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

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(
// username: string,
// password: string,

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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(NouveauChecker),
new(CudaChecker),
new(RocmChecker),
}
runPreChecks := &task.LocalTask{
Name: "RunPrechecks",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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
}
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 {
common.KubeModule
WithoutName bool
}
func (m *WriteReleaseFileModule) Init() {
@@ -82,7 +83,7 @@ func (m *WriteReleaseFileModule) Init() {
m.Tasks = []task.Interface{
&task.LocalTask{
Name: "WriteReleaseFile",
Action: new(WriteReleaseFile),
Action: &WriteReleaseFile{WithoutName: m.WithoutName},
},
}
}

View File

@@ -10,8 +10,8 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
"bytetrade.io/web3os/app-service/api/sys.bytetrade.io/v1alpha1"
apputils "bytetrade.io/web3os/app-service/pkg/utils"
"github.com/beclab/Olares/framework/app-service/api/sys.bytetrade.io/v1alpha1"
apputils "github.com/beclab/Olares/framework/app-service/pkg/utils"
"github.com/beclab/Olares/cli/pkg/core/logger"
"github.com/beclab/Olares/cli/pkg/storage"
@@ -38,12 +38,6 @@ type InstallOsSystem struct {
}
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()
if err != nil {
return err
@@ -367,6 +361,11 @@ func (m *InstallOsSystemModule) Init() {
Action: &CreateUserEnvConfigMap{},
}
createSharedLibDir := &task.LocalTask{
Name: "CreateSharedLibDir",
Action: &storage.CreateSharedLibDir{},
}
installOsSystem := &task.LocalTask{
Name: "InstallOsSystem",
Action: &InstallOsSystem{},
@@ -399,6 +398,7 @@ func (m *InstallOsSystemModule) Init() {
m.Tasks = []task.Interface{
applySystemEnv,
createUserEnvConfigMap,
createSharedLibDir,
installOsSystem,
createBackupConfigMap,
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-") {
continue
}
if pod.Status.Phase != corev1.PodRunning {
return fmt.Errorf("pod %s/%s is not running", pod.Namespace, pod.Name)
}
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)
}
if err := utils.AssertPodReady(&pod); err != nil {
return err
}
}
return nil
@@ -126,29 +109,39 @@ type CheckPodsRunning struct {
labels map[string][]string
}
func (c *CheckPodsRunning) Execute(runtime connector.Runtime) error {
func (c *CheckPodsRunning) Execute(_ connector.Runtime) error {
if c.labels == 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)
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 _, label := range labels {
var cmd = fmt.Sprintf("%s get pod -n %s -l '%s' -o jsonpath='{.items[*].status.phase}'", kubectl, ns, label)
phase, err := runtime.GetRunner().SudoCmdContext(ctx, cmd, false, false)
podList, err := kubeClient.CoreV1().Pods(ns).List(ctx, metav1.ListOptions{LabelSelector: label})
if err != nil {
return fmt.Errorf("pod status invalid, namespace: %s, label: %s, waiting ...", ns, label)
}
if phase != "Running" {
logger.Infof("pod in namespace: %s, label: %s, current phase: %s, waiting ...", ns, label, phase)
return fmt.Errorf("pod is %s, namespace: %s, label: %s, waiting ...", phase, ns, label)
if podList == nil || len(podList.Items) == 0 {
return fmt.Errorf("no pod found, namespace: %s, label: %s, waiting ...", 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 {
common.KubeAction
WithoutName bool
}
func (t *WriteReleaseFile) Execute(runtime connector.Runtime) error {
if util.IsExist(common.OlaresReleaseFile) {
logger.Debugf("found existing release file: %s, overriding ...", common.OlaresReleaseFile)
}
return t.KubeConf.Arg.SaveReleaseInfo()
return t.KubeConf.Arg.SaveReleaseInfo(t.WithoutName)
}
type RemoveReleaseFile struct {

View File

@@ -9,6 +9,7 @@ import (
"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"
)
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("Password: %s", t.KubeConf.Arg.User.Password)
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
}

View File

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

View File

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

View File

@@ -8,36 +8,36 @@ import (
"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
}
func (u upgrader_1_12_3) Version() *semver.Version {
func (u upgrader_1_12_4) Version() *semver.Version {
cliVersion, err := semver.NewVersion(version.VERSION)
// tolerate local dev version
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 version_1_12_3
return version_1_12_4
}
func (u upgrader_1_12_3) AddedBreakingChange() bool {
if u.Version().Equal(version_1_12_3) {
func (u upgrader_1_12_4) AddedBreakingChange() bool {
if u.Version().Equal(version_1_12_4) {
return true
}
return false
}
func (u upgrader_1_12_3) NeedRestart() bool {
func (u upgrader_1_12_4) NeedRestart() bool {
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 = append(tasks, upgradeKsConfig()...)
@@ -57,7 +57,7 @@ func (u upgrader_1_12_3) PrepareForUpgrade() []task.Interface {
return tasks
}
func (u upgrader_1_12_3) UpgradeSystemComponents() []task.Interface {
func (u upgrader_1_12_4) UpgradeSystemComponents() []task.Interface {
pre := []task.Interface{
&task.LocalTask{
Name: "UpgradeL4BFLProxy",
@@ -69,7 +69,7 @@ func (u upgrader_1_12_3) UpgradeSystemComponents() []task.Interface {
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
tasks = append(tasks,
&task.LocalTask{
@@ -88,5 +88,5 @@ func (u upgrader_1_12_3) UpdateOlaresVersion() []task.Interface {
}
func init() {
registerMainUpgrader(upgrader_1_12_3{})
registerMainUpgrader(upgrader_1_12_4{})
}

View File

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

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

@@ -84,8 +84,15 @@ func (p *proxyServer) Start() error {
clientIp = h
}
}
if c.IsWebSocket() {
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)
if clientIp != "" {
@@ -243,7 +250,7 @@ func (p *proxyServer) customDialContext(d *net.Dialer) func(ctx context.Context,
}
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 proxyDial(ctx, d, network, newAddr)
}, 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))
}
klog.Info("Intranet server reloaded")
klog.V(8).Info("Intranet server reloaded")
return nil
}

View File

@@ -99,7 +99,7 @@ func (s *server) Restart() error {
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 {
klog.Error("create mdns server error, ", err)
return err

View File

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

View File

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

View File

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

View File

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

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)
return false, "", err
}
jws.DIDGateURL = didServiceURL
// Validate the JWS token with a 20-minute expiration time
checkJWS, err := jws.CheckJWS(token, 20*60*1000)
checkJWS, err := jws.CheckJWS(didServiceURL, token, 20*60*1000)
if err != nil {
if strings.HasPrefix(err.Error(), "timestamp") {
err = fmt.Errorf("%v, server time: %s", err, time.Now().UTC().Format(time.RFC3339))
}
klog.Errorf("failed to check JWS: %v, on %s", err, jws.DIDGateURL)
klog.Errorf("failed to check JWS: %v, on %s", err, didServiceURL)
return false, "", err
}

View File

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

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

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

View File

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

View File

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

View File

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

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:
```js
// Ensure the port matches what you defined
const express = require('express');
const app = express();
app.use(express.static('public/'));
app.listen(8080), function() {
console.log('Server is running on port 8080');
};
// Ensure the port matches what you defined
const express = require('express');
const app = express();
app.use(express.static('public/'));
app.listen(8080, function() {
console.log('Server is running on port 8080');
});
```
6. Create a `public` directory in `/root/` and add an `index.html` file:
```html
@@ -204,15 +204,15 @@ Once deployed, go to **Services** > **Ports**. You can see your new port listed
const express = require('express');
const app = express();
app.use(express.static('public/'));
app.listen(8080), function() {
console.log('Server is running on port 8080');
};
app.listen(8080, function() {
console.log('Server is running on port 8080');
});
// Add the following
const app_new = express();
app_new.use(express.static('new/'));
app_new.listen(8081), function() {
console.log('Server is running on port 8081');
};
app_new.listen(8081, function() {
console.log('Server is running on port 8081');
});
```
2. Create a `new` directory in `/root/` and add an `index.html` file:
```html

View File

@@ -65,7 +65,7 @@ These options apply to all backends:
kubectl get terminus -o jsonpath='{.items[*].metadata.labels.bytetrade\.io/cluster-id}'
```
## Example
## Examples
```bash
# Backup to Tencent COS
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 |
| `--help` | `-h` | Displays help information. | No | N/A |
## Example
## Examples
```bash d
# Download Restic using a custom CDN URL
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.
## Example
## Examples
```bash
# Query cloud name and region ID
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}'
```
## Example
## Examples
```bash
# Restore the data from Tencent COS
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}'
```
## Example
## Examples
```bash
# List snapshots for Tencent COS
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 |
| `--help` | `-h` | Displays help information. | No | N/A |
## Example
## Examples
```bash
# 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
```
## Flag
## Options
| 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` |
| `--since` | | Fetches logs newer than a specified relative duration (e.g., `5s`, `2m`, `3h`). | No | `7d` |
## Example
## Examples
```bash
# Collect all logs with default settings
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 |
| `--help` | `-h` | Displays help information. | No | N/A | |
## Example
## Examples
```bash
# Retrieve system information from a master node at IP 192.168.1.15

View File

@@ -28,12 +28,13 @@ wsl -d Ubuntu
## Syntax
The Olares CLI uses the following syntax:
> `olares-cli command [subcommand] [option]`
> `olares-cli command [subcommand] [argument] [options] `
where
- `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`.
- `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.
@@ -43,21 +44,23 @@ To get detailed help for any command, run `olares-cli help`.
## Available CLI commands
| Operation | Syntax | Description |
|--------------------|----------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------|
| `gpu` | `olares-cli gpu <subcommand> [option]` | Manages GPU-related operations. |
| `info` | `olares-cli info <subcommand> [option]` | Displays general information about the operating system of the current device. |
| `node` | `olares-cli node <subcommand> [option]` | Manages node-related operations. |
| `backups` | `olares-cli backups <subcommand> [option]` | Manages backup-related operations. |
| `change-ip` | `olares-cli change-ip [option]` | Changes the IP address of the Olares OS. |
| `download` | `olares-cli download <subcommand> [option]` | Downloads specific resources. |
| `info` | `olares-cli info [option]` | Displays general information about the downloaded Olares OS. |
| `install` | `olares-cli install [option]` | Deploys system-level and user-level components of Olares. |
| `logs` | `olares-cli logs [option]` | Collects logs from Olares system components for debugging and troubleshooting. |
| `precheck` | `olares-cli precheck [option]` | Verifies whether the system environment meets all requirements for Olares installation. |
| `prepare` | `olares-cli prepare [option]` | Prepares the environment for the installation process, including setting up essential services and configurations of Olares. |
| `release` | `olares-cli release [option]` | Packages Olares installation resources for distribution or deployment. |
| `start` | `olares-cli start [option]` | Starts Olares services and components. |
| `stop` | `olares-cli stop [option]` | Stops Olares services and components. |
| `uninstall` | `olares-cli uninstall [option]` | Uninstalls Olares completely, or roll back the installation to a specific phase. |
| Operation | Syntax | Description |
|--|--|--|
| `backups` | `olares-cli backups <subcommand> [options]` | Manages backup-related operations. |
| `change-ip` | `olares-cli change-ip [options]` | Changes the IP address of the Olares OS. |
| `disk` | `olares-cli disk <subcommand>` | Manages storage resources in the Olares system. |
| `download` | `olares-cli download <subcommand> [options]` | Downloads specific resources. |
| `gpu` | `olares-cli gpu <subcommand> [options]` | Manages GPU-related operations. |
| `info` | `olares-cli info [options]` | Displays general information about the downloaded Olares OS. |
| `install` | `olares-cli install [options]` | Deploys system-level and user-level components of Olares. |
| `logs` | `olares-cli logs [options]` | Collects logs from Olares system components for debugging and troubleshooting. |
| `node` | `olares-cli node <subcommand> [options]` | Manages node-related operations. |
| `osinfo` | `olares-cli osinfo <subcommand> [options]` | Displays general information about the operating system of the current device. |
| `precheck` | `olares-cli precheck [options]` | Verifies whether the system environment meets all requirements for Olares installation. |
| `prepare` | `olares-cli prepare [options]` | Prepares the environment for the installation process, including setting up essential services and configurations of Olares. |
| `release` | `olares-cli release [options]` | Packages Olares installation resources for distribution or deployment. |
| `start` | `olares-cli start [options]` | Starts Olares services and components. |
| `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]
```
## Subcommand
## Subcommands
| Subcommand | Description |
|------------|----------------------------------------------------------------------|
| `show` | Prints information about the operating system of the current device. |
## Flag
## Options
| Name | Short | Description |
|--------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|

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