mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-12-23 13:04:42 +00:00
Compare commits
452 Commits
v0.2.5
...
v0.4.4-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e5381710f | ||
|
|
fa62c65526 | ||
|
|
3aea945277 | ||
|
|
4d8ca182cb | ||
|
|
b727606a0a | ||
|
|
428be5f2c2 | ||
|
|
995d67543d | ||
|
|
590beac43a | ||
|
|
e7bf227232 | ||
|
|
eedfdde311 | ||
|
|
38c7b5a569 | ||
|
|
8c0b219621 | ||
|
|
23fc677f30 | ||
|
|
a06508783c | ||
|
|
37fee157dd | ||
|
|
3f1c7098bd | ||
|
|
b11d046c52 | ||
|
|
d6a9ba65ed | ||
|
|
5f1df76dbf | ||
|
|
0cf353c56e | ||
|
|
5dc6297047 | ||
|
|
f26ae2793c | ||
|
|
d7641e1b93 | ||
|
|
37c496fd6a | ||
|
|
cb15c06f7e | ||
|
|
89a0ea34b0 | ||
|
|
d8dd815baa | ||
|
|
a77b5d1954 | ||
|
|
d0fb2f06f5 | ||
|
|
dd8032a8be | ||
|
|
760882e147 | ||
|
|
dfeed76a66 | ||
|
|
28d724731a | ||
|
|
4549d8778b | ||
|
|
05cadaabf3 | ||
|
|
1a0c15208c | ||
|
|
4f5b4b0887 | ||
|
|
cbfe44be61 | ||
|
|
e1bbb998df | ||
|
|
f48cddf924 | ||
|
|
23ce3487e1 | ||
|
|
6246421dae | ||
|
|
f867453573 | ||
|
|
78e7a8b411 | ||
|
|
1aa8fb600b | ||
|
|
7ecfea71ab | ||
|
|
d911d80254 | ||
|
|
9bfe37305c | ||
|
|
94dd2e00c7 | ||
|
|
c5d2cebe92 | ||
|
|
955e8dea07 | ||
|
|
4c7b3a749b | ||
|
|
e86a61596b | ||
|
|
c9617e583f | ||
|
|
dda15b0821 | ||
|
|
50816c68b0 | ||
|
|
c5de0319fb | ||
|
|
78b7c6ce09 | ||
|
|
b420a2d930 | ||
|
|
c67ee1731c | ||
|
|
eaca399ef9 | ||
|
|
e0e9f97764 | ||
|
|
2fefee87fa | ||
|
|
280ad4fcf9 | ||
|
|
538639b623 | ||
|
|
39535d6a38 | ||
|
|
4d977d7a62 | ||
|
|
08c500c434 | ||
|
|
705bf1facb | ||
|
|
aae1802191 | ||
|
|
8e1b9b82c1 | ||
|
|
af440eac55 | ||
|
|
34b4e154a1 | ||
|
|
79db93ec02 | ||
|
|
f8ec3b20cd | ||
|
|
8c7c8dc1ec | ||
|
|
60a141fe25 | ||
|
|
02e712f649 | ||
|
|
7022cf5d29 | ||
|
|
6cf46ce50c | ||
|
|
202c1de570 | ||
|
|
858ab5b124 | ||
|
|
e319975a60 | ||
|
|
5c2c3b5e98 | ||
|
|
a0dc58264a | ||
|
|
717b47ca2c | ||
|
|
f530f69ba5 | ||
|
|
87b190a84b | ||
|
|
10191a1be3 | ||
|
|
59f2ccbeb3 | ||
|
|
076b7198b2 | ||
|
|
eb483a4c5d | ||
|
|
60e81bc781 | ||
|
|
dc8ee89c85 | ||
|
|
c995750312 | ||
|
|
de6ed093a2 | ||
|
|
449e1515d9 | ||
|
|
e6ddb0d849 | ||
|
|
c19e32c6e9 | ||
|
|
94755e221a | ||
|
|
86a3692dad | ||
|
|
45a5567978 | ||
|
|
3190421fd9 | ||
|
|
a7126cac63 | ||
|
|
151aa037bb | ||
|
|
08ed9933ee | ||
|
|
8425011e73 | ||
|
|
96ff550d61 | ||
|
|
85a803d352 | ||
|
|
5def3e5856 | ||
|
|
c768260b1b | ||
|
|
46e146e633 | ||
|
|
1a2f917b30 | ||
|
|
86adfbaef8 | ||
|
|
143af78745 | ||
|
|
7b07f22685 | ||
|
|
c8b6a1c228 | ||
|
|
827fba2164 | ||
|
|
6217009caf | ||
|
|
fbfcc2c43a | ||
|
|
b331c484f5 | ||
|
|
a1fbbf9584 | ||
|
|
3611ec7d09 | ||
|
|
7dedbafc8a | ||
|
|
b7634402bd | ||
|
|
8e025a9836 | ||
|
|
8bfc8178cf | ||
|
|
8343f52137 | ||
|
|
7501833cf9 | ||
|
|
4c917a33a4 | ||
|
|
173997c44b | ||
|
|
76bc6e68ae | ||
|
|
d0fc2cc8cb | ||
|
|
32980f4033 | ||
|
|
28d3ca0ca6 | ||
|
|
3d31ad6689 | ||
|
|
0bb138e39e | ||
|
|
e8db1767e5 | ||
|
|
6b01263252 | ||
|
|
b2a4fafdb4 | ||
|
|
fcfb48d88e | ||
|
|
86380d912d | ||
|
|
87d8be8c61 | ||
|
|
9123974811 | ||
|
|
be50579544 | ||
|
|
91bb0cba6f | ||
|
|
b9946db854 | ||
|
|
9eb650b444 | ||
|
|
84f17b4c4b | ||
|
|
8cff99f726 | ||
|
|
ea166f890b | ||
|
|
d350c3e96f | ||
|
|
ec0d98627d | ||
|
|
fd3cb5b0f0 | ||
|
|
0155dc1877 | ||
|
|
cd79e51f8f | ||
|
|
c6d89f9cb2 | ||
|
|
4b26631374 | ||
|
|
ba742b9fb2 | ||
|
|
57e5a710e0 | ||
|
|
062d95c1eb | ||
|
|
75643287a5 | ||
|
|
6bda9406fb | ||
|
|
be9a010d17 | ||
|
|
3875827b7a | ||
|
|
5338d4662e | ||
|
|
3b9c4b62c5 | ||
|
|
536eac788d | ||
|
|
fc371bf068 | ||
|
|
299b20a087 | ||
|
|
eb31bf5586 | ||
|
|
04d4eacc60 | ||
|
|
60608c5dc7 | ||
|
|
b582e8f53e | ||
|
|
5690ccc1b5 | ||
|
|
13c2967889 | ||
|
|
8a37f9c879 | ||
|
|
96e9284235 | ||
|
|
06f83d3d68 | ||
|
|
438b8a1dd2 | ||
|
|
29e701cb7c | ||
|
|
43cc7596d2 | ||
|
|
11f800d138 | ||
|
|
a58a9e5477 | ||
|
|
5f015e9038 | ||
|
|
3922296d9b | ||
|
|
908a16ace4 | ||
|
|
f7a3863720 | ||
|
|
e94c2ff5c5 | ||
|
|
89487eb5db | ||
|
|
0fb5cab480 | ||
|
|
f210f29ae5 | ||
|
|
7bd5c6a2b4 | ||
|
|
230f1585a3 | ||
|
|
ca967ec59c | ||
|
|
c0b3260a6c | ||
|
|
9ed82cd55e | ||
|
|
381fb85b1d | ||
|
|
2beb1c0d82 | ||
|
|
772c3e0bc0 | ||
|
|
bcda992322 | ||
|
|
8cec47e4db | ||
|
|
87de9cec0a | ||
|
|
6d47d4ff18 | ||
|
|
4bb81e4669 | ||
|
|
c05d837350 | ||
|
|
8908c39969 | ||
|
|
df0f015944 | ||
|
|
46a37f0510 | ||
|
|
6ea3cdb364 | ||
|
|
be80d0cd95 | ||
|
|
296e88d099 | ||
|
|
b61a3db611 | ||
|
|
0f3d3e82f5 | ||
|
|
dd66f73157 | ||
|
|
cbbb907d6a | ||
|
|
ff6cdb6fda | ||
|
|
2eac040875 | ||
|
|
b41d855f73 | ||
|
|
182bc25343 | ||
|
|
12d5e5db03 | ||
|
|
455d226dcd | ||
|
|
f0448cd1b9 | ||
|
|
aff18fa091 | ||
|
|
80c347ac01 | ||
|
|
8113f51cf7 | ||
|
|
4f491fa22f | ||
|
|
3935489d8b | ||
|
|
d14381e6a2 | ||
|
|
42ebd5f325 | ||
|
|
a51bf70b79 | ||
|
|
3787c7bf99 | ||
|
|
ec7f6573ad | ||
|
|
50d68f3f76 | ||
|
|
d9c6a5c875 | ||
|
|
4bace9b16a | ||
|
|
84dfa7f5bf | ||
|
|
582f85c3ba | ||
|
|
7f4562629a | ||
|
|
4776b76b16 | ||
|
|
466350dd21 | ||
|
|
fb39529e8f | ||
|
|
4434ba522b | ||
|
|
aac8fe85ba | ||
|
|
9f938f65b1 | ||
|
|
314dbdab57 | ||
|
|
4ccae3f67f | ||
|
|
9f2e8dae6f | ||
|
|
727aca564b | ||
|
|
70ba4d5e3d | ||
|
|
8d088afcc5 | ||
|
|
34f35bbf20 | ||
|
|
b6f413b9e9 | ||
|
|
091be6d12e | ||
|
|
aefa68d8f8 | ||
|
|
9aed323d8d | ||
|
|
eba607fc53 | ||
|
|
d064f20a04 | ||
|
|
079e431d33 | ||
|
|
cee34ec1c2 | ||
|
|
848ee63386 | ||
|
|
c12c6cc940 | ||
|
|
f31fb22039 | ||
|
|
a5133bdbfa | ||
|
|
1902b2d4f2 | ||
|
|
fc5e351f0b | ||
|
|
7f642a7a4c | ||
|
|
c36a046a15 | ||
|
|
8b2c9486da | ||
|
|
ce5ecfcf84 | ||
|
|
bd1a2f5751 | ||
|
|
d2e0695d73 | ||
|
|
8cd18c3218 | ||
|
|
cc0ba82c92 | ||
|
|
ddca242d23 | ||
|
|
eaa07ba95a | ||
|
|
39a4c29680 | ||
|
|
af6900b1c7 | ||
|
|
9ec43a7691 | ||
|
|
bd85cda9fa | ||
|
|
94eaba6ecb | ||
|
|
e207c9c75f | ||
|
|
81d3293991 | ||
|
|
364fbf01f5 | ||
|
|
87e66aae8a | ||
|
|
3a60db3729 | ||
|
|
d3f78b52fa | ||
|
|
7d67a66d6b | ||
|
|
cb9e1b9dd9 | ||
|
|
dc8282acbb | ||
|
|
cf6103a2b5 | ||
|
|
6f98995e7d | ||
|
|
5cc41fa040 | ||
|
|
cb289f5b8a | ||
|
|
1377d55407 | ||
|
|
06eca38022 | ||
|
|
c47c1e548c | ||
|
|
552ec4849d | ||
|
|
7386a9dce3 | ||
|
|
b2b1daf5ab | ||
|
|
bbc0181e23 | ||
|
|
c23bd3f3a3 | ||
|
|
8a1839c02e | ||
|
|
164bf66190 | ||
|
|
a4c2a4b992 | ||
|
|
e7e82e6ca3 | ||
|
|
574295470e | ||
|
|
b1061f19ad | ||
|
|
bdd9eaca9f | ||
|
|
ec4c672924 | ||
|
|
5d4717de4d | ||
|
|
e2de783152 | ||
|
|
09f68f4034 | ||
|
|
cec83fc048 | ||
|
|
33e1d8a806 | ||
|
|
2a8dafae28 | ||
|
|
a426b56306 | ||
|
|
6202d38bdb | ||
|
|
4626ceb048 | ||
|
|
1e7333118c | ||
|
|
9758436a1e | ||
|
|
ed67e977b7 | ||
|
|
b0b1b5e262 | ||
|
|
2796c37bf6 | ||
|
|
d48e24f652 | ||
|
|
3a8cf593d9 | ||
|
|
0ffa2f901a | ||
|
|
bd73141ddf | ||
|
|
346b0f5d97 | ||
|
|
d4b4b75012 | ||
|
|
cb33ffbb46 | ||
|
|
85188d0b05 | ||
|
|
1e60c26920 | ||
|
|
752134942a | ||
|
|
faf683a02c | ||
|
|
f99f49dd7e | ||
|
|
b0dc30277b | ||
|
|
d91fef0a19 | ||
|
|
6bb044ab04 | ||
|
|
78479f9604 | ||
|
|
8fe893847f | ||
|
|
f506d6ce49 | ||
|
|
5d7c5ba120 | ||
|
|
eedffd7c19 | ||
|
|
0885c1386d | ||
|
|
0297fe67af | ||
|
|
3f53e6f33b | ||
|
|
94d0efdb12 | ||
|
|
1e821d1c10 | ||
|
|
2c80b53ee8 | ||
|
|
c33af66c6e | ||
|
|
9d47874ae3 | ||
|
|
c7b7a30210 | ||
|
|
fde665cd4d | ||
|
|
eaf2341a2a | ||
|
|
d4bed3e5c7 | ||
|
|
fcb2b3f5a5 | ||
|
|
60349c941a | ||
|
|
11bc70a710 | ||
|
|
665766019f | ||
|
|
57cef9624c | ||
|
|
6bd41ad016 | ||
|
|
05425d638f | ||
|
|
bd5a2e35d4 | ||
|
|
123e7e8758 | ||
|
|
1ec3e2e9fb | ||
|
|
0719c3cc0c | ||
|
|
0a4ceb7c4c | ||
|
|
655f59f00a | ||
|
|
5289f471d6 | ||
|
|
59597befb6 | ||
|
|
df2477a12f | ||
|
|
b709abe682 | ||
|
|
d0f3dc806e | ||
|
|
92d085acf9 | ||
|
|
20dbae21c8 | ||
|
|
9258cb4b9e | ||
|
|
d9794851f9 | ||
|
|
1fcb530ff2 | ||
|
|
364d411438 | ||
|
|
0dacc5db12 | ||
|
|
fcbff194d2 | ||
|
|
04e93b0e3c | ||
|
|
2eff7fa8bc | ||
|
|
dd0645ee0f | ||
|
|
c93aa6286e | ||
|
|
bf7b32309f | ||
|
|
cd779448ce | ||
|
|
c3b2c1d599 | ||
|
|
b7949e100f | ||
|
|
80d24570d6 | ||
|
|
539b72a388 | ||
|
|
a7d15a896e | ||
|
|
9796c5aad7 | ||
|
|
892cd99eb3 | ||
|
|
02cb4cd392 | ||
|
|
9213f9e379 | ||
|
|
4473056d5c | ||
|
|
07e96511cd | ||
|
|
ce1dc52bc2 | ||
|
|
d890b16644 | ||
|
|
5737936318 | ||
|
|
33acfababd | ||
|
|
28c1a52171 | ||
|
|
892eef424c | ||
|
|
f3c73ba79b | ||
|
|
c6928c333d | ||
|
|
63c6c2cebb | ||
|
|
6cba025679 | ||
|
|
d25b93c972 | ||
|
|
b14861703c | ||
|
|
32604225ce | ||
|
|
f623b29c38 | ||
|
|
94ae6ee8ec | ||
|
|
5115bf72e1 | ||
|
|
e1a928cd78 | ||
|
|
3977519c43 | ||
|
|
2f87834ac9 | ||
|
|
53335012d8 | ||
|
|
9d6302f7e3 | ||
|
|
20950e2a60 | ||
|
|
0e0e507f8f | ||
|
|
46e14617b6 | ||
|
|
903c73fafb | ||
|
|
42a56df4a5 | ||
|
|
493dc5c032 | ||
|
|
9a73bc2a18 | ||
|
|
55a9acd9f6 | ||
|
|
d060968b7a | ||
|
|
88a7f53130 | ||
|
|
26e5b18a5d | ||
|
|
011ace96f6 | ||
|
|
5c00655d14 | ||
|
|
eb36c262db | ||
|
|
29d1861545 | ||
|
|
3c9b410693 | ||
|
|
4c3b41433b | ||
|
|
1fd13668c0 | ||
|
|
d1ab7261a6 | ||
|
|
0fc65bcb3a | ||
|
|
f1ce8bfd99 | ||
|
|
3f472f1864 | ||
|
|
229d94cae7 | ||
|
|
c28e1bbf93 | ||
|
|
a840029000 | ||
|
|
aad2646cf2 | ||
|
|
ca1f8ad73e | ||
|
|
dea02763a2 | ||
|
|
ea67385a64 | ||
|
|
fa2daa2767 | ||
|
|
fcb906aa85 | ||
|
|
489a617126 |
197
.all-contributorsrc
Normal file
197
.all-contributorsrc
Normal file
@@ -0,0 +1,197 @@
|
||||
{
|
||||
"files": [
|
||||
"README.md"
|
||||
],
|
||||
"imageSize": 100,
|
||||
"badgeTemplate": "<a href=\"#credits\"><img alt=\"All Contributors\" src=\"https://img.shields.io/static/v1?label=All%20Contributors&message=<%= contributors.length %>&color=162453&style=flat-square&logo=Handshake&logoColor=fff\" /></a>",
|
||||
"commit": false,
|
||||
"contributors": [
|
||||
{
|
||||
"login": "jerrykuku",
|
||||
"name": "老竭力",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/9485680?v=4",
|
||||
"profile": "https://github.com/jerrykuku",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc",
|
||||
"ideas",
|
||||
"infra",
|
||||
"maintenance",
|
||||
"platform",
|
||||
"question",
|
||||
"review"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "LinkLeong",
|
||||
"name": "link",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/13556972?v=4",
|
||||
"profile": "https://github.com/LinkLeong",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc",
|
||||
"ideas",
|
||||
"infra",
|
||||
"maintenance",
|
||||
"question",
|
||||
"review"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "tigerinus",
|
||||
"name": "Tiger Wang (王豫)",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/7172560?v=4",
|
||||
"profile": "https://github.com/tigerinus",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc",
|
||||
"ideas",
|
||||
"infra",
|
||||
"maintenance",
|
||||
"mentoring",
|
||||
"security",
|
||||
"question",
|
||||
"review"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Lauren-ED209",
|
||||
"name": "Lauren",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/8243355?v=4",
|
||||
"profile": "https://github.com/Lauren-ED209",
|
||||
"contributions": [
|
||||
"ideas",
|
||||
"fundingFinding",
|
||||
"projectManagement",
|
||||
"question",
|
||||
"test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "JohnGuan",
|
||||
"name": "John Guan",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3358477?v=4",
|
||||
"profile": "https://JohnGuan.Cn",
|
||||
"contributions": [
|
||||
"blog",
|
||||
"content",
|
||||
"doc",
|
||||
"ideas",
|
||||
"eventOrganizing",
|
||||
"mentoring",
|
||||
"question",
|
||||
"review"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "dtaivpp",
|
||||
"name": "David Tippett",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/17506770?v=4",
|
||||
"profile": "https://blog.tippybits.com",
|
||||
"contributions": [
|
||||
"doc",
|
||||
"ideas",
|
||||
"question"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "zarevskaya",
|
||||
"name": "Skaya",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/60230221?v=4",
|
||||
"profile": "https://github.com/zarevskaya",
|
||||
"contributions": [
|
||||
"mentoring",
|
||||
"question",
|
||||
"tutorial",
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "AuthorShin",
|
||||
"name": "AuthorShin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4959043?v=4",
|
||||
"profile": "https://github.com/AuthorShin",
|
||||
"contributions": [
|
||||
"test",
|
||||
"bug",
|
||||
"question",
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "baptiste313",
|
||||
"name": "baptiste313",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/93325157?v=4",
|
||||
"profile": "https://github.com/baptiste313",
|
||||
"contributions": [
|
||||
"translation"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "DrMxrcy",
|
||||
"name": "DrMxrcy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/58747968?v=4",
|
||||
"profile": "https://github.com/DrMxrcy",
|
||||
"contributions": [
|
||||
"test",
|
||||
"ideas",
|
||||
"question"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Joooost",
|
||||
"name": "Joooost",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/12090673?v=4",
|
||||
"profile": "https://github.com/Joooost",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "sio",
|
||||
"name": "Vitaly Potyarkin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/334908?v=4",
|
||||
"profile": "https://potyarkin.ml",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "bearfrieze",
|
||||
"name": "Bjørn Friese",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1023813?v=4",
|
||||
"profile": "https://github.com/bearfrieze",
|
||||
"contributions": [
|
||||
"ideas"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Protektor-Desura",
|
||||
"name": "Protektor",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1195496?v=4",
|
||||
"profile": "https://github.com/Protektor-Desura",
|
||||
"contributions": [
|
||||
"bug",
|
||||
"ideas",
|
||||
"question"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "llwaini",
|
||||
"name": "llwaini",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/59589857?v=4",
|
||||
"profile": "https://github.com/llwaini",
|
||||
"contributions": [
|
||||
"projectManagement",
|
||||
"test",
|
||||
"tutorial"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
"projectName": "CasaOS",
|
||||
"projectOwner": "IceWhaleTech",
|
||||
"repoType": "github",
|
||||
"repoHost": "https://github.com",
|
||||
"skipCi": true
|
||||
}
|
||||
26
.github/ISSUE_TEMPLATE/alpha_bug_report.yml
vendored
Normal file
26
.github/ISSUE_TEMPLATE/alpha_bug_report.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: "[Alpha Only] Bug Report"
|
||||
description: CasaOS Alpha Testing specific bug report form.
|
||||
title: "[Alpha][Bug] "
|
||||
labels: ["alpha", "bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
> If you haven't joined CasaOS Alpha Team yet.
|
||||
> Please join first on [Discord](https://discord.gg/knqAbbBbeX) to be updated on the Alpha test plan and test scope.
|
||||
- type: textarea
|
||||
id: what-happened
|
||||
attributes:
|
||||
label: What happened?
|
||||
description: Also tell us, what did you expect to happen?
|
||||
placeholder: Tell us what you see!
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: screenshots
|
||||
attributes:
|
||||
label: Screenshots
|
||||
description: If applicable, add screenshots to help explain your problem.
|
||||
placeholder: Screenshots would be very helpful!
|
||||
|
||||
46
.github/ISSUE_TEMPLATE/bug_report.md
vendored
46
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,32 +1,64 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
title: '[Bug] '
|
||||
labels: 'bug'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
> A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
> Steps to reproduce the behavior:
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
> A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
> If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
|
||||
```
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
```
|
||||
|
||||
**System Time**
|
||||
|
||||
> Run `timedatectl` and share the output
|
||||
|
||||
```
|
||||
(timedatectl output here)
|
||||
```
|
||||
|
||||
**Logs**
|
||||
|
||||
> Run following command to collect corresponding logs:
|
||||
|
||||
```bash
|
||||
sudo journalctl -xef -u casaos-gateway
|
||||
sudo journalctl -xef -u casaos-user-service
|
||||
sudo journalctl -xef -u casaos-local-storage
|
||||
sudo journalctl -xef -u casaos-app-management
|
||||
sudo journalctl -xef -u casaos.service
|
||||
```
|
||||
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
> Add any other context about the problem here.
|
||||
>
|
||||
> If you are a Zimaboard user, make it explicit with when you got your Zimaboard.
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: App Request
|
||||
url: https://github.com/IceWhaleTech/CasaOS-AppStore/issues/new?assignees=&labels=App+Request&template=app_request.yml&title=%5BApp+Request%5D+AppName
|
||||
about: Request to add an app to the app store.
|
||||
- name: Feature/Enhancement Ideas
|
||||
url: https://github.com/IceWhaleTech/CasaOS/discussions/164
|
||||
about: Have an idea for a new feature/enhancement?
|
||||
- name: Questions, Discussions
|
||||
url: https://github.com/IceWhaleTech/CasaOS/discussions
|
||||
about: Ask questions, propose ideas, or discuss anything related to CasaOS
|
||||
- name: Discord
|
||||
url: https://discord.gg/knqAbbBbeX
|
||||
about: Get help or share great ideas on Discord!
|
||||
15
.github/ISSUE_TEMPLATE/submit-application.md
vendored
15
.github/ISSUE_TEMPLATE/submit-application.md
vendored
@@ -1,15 +0,0 @@
|
||||
---
|
||||
name: Submit application
|
||||
about: Add an app to this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: LinkLeong
|
||||
|
||||
---
|
||||
|
||||
Tested platform
|
||||
e.g. linux/amd64,linux/arm-v7,linux-arm64
|
||||
|
||||
|
||||
|
||||
Please export and upload the configuration file of this application
|
||||
33
.github/workflows/add_issues_to_projects.yml
vendored
Normal file
33
.github/workflows/add_issues_to_projects.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
name: Add Issues To Projects
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
add-issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Generate token
|
||||
id: generate_token
|
||||
uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
|
||||
with:
|
||||
app_id: ${{ secrets.ALPHA_BOT_ID }}
|
||||
private_key: ${{ secrets.ALPHA_BOT_PEM }}
|
||||
|
||||
- name: Add Alpha Bug Issue To project
|
||||
uses: actions/add-to-project@v0.3.0
|
||||
with:
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
project-url: https://github.com/orgs/IceWhaleTech/projects/5
|
||||
labeled: alpha, bug
|
||||
label-operator: AND
|
||||
|
||||
- name: Add App Request Issue To project
|
||||
uses: actions/add-to-project@v0.3.0
|
||||
with:
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
project-url: https://github.com/orgs/IceWhaleTech/projects/8
|
||||
labeled: "App Request"
|
||||
label-operator: AND
|
||||
20
.github/workflows/casa.yml
vendored
20
.github/workflows/casa.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
# env:
|
||||
# GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
submodules: true
|
||||
@@ -64,18 +64,8 @@ jobs:
|
||||
# ln -sf /workdir/casa $GITHUB_WORKSPACE/casa
|
||||
# ls
|
||||
|
||||
- name: Compile glibc
|
||||
run: |
|
||||
wget -q http://ftp.gnu.org/gnu/glibc/glibc-2.30.tar.bz2
|
||||
sudo mkdir /opt/glibc230
|
||||
tar xvfj glibc-2.30.tar.bz2
|
||||
mkdir build
|
||||
cd build
|
||||
../glibc-2.30/configure --prefix=/opt/glibc230 --enable-cet
|
||||
sudo make -j$(($(nproc) + 1))
|
||||
sudo make install
|
||||
|
||||
- name: Set enviroment for github-release
|
||||
- name: Set environment for github-release
|
||||
run: |
|
||||
echo "VERSION=$(cat types/system.go | grep CURRENTVERSION | awk '$2 == "CURRENTVERSION"{print $4}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||
echo "BODY=$(cat types/system.go | grep BODY | awk -F= '{print $2}' | sed 's/"//g')" >>$GITHUB_ENV
|
||||
@@ -83,7 +73,7 @@ jobs:
|
||||
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v2
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
|
||||
@@ -100,7 +90,7 @@ jobs:
|
||||
- name: Build with xgo
|
||||
uses: crazy-max/ghaction-xgo@v1
|
||||
with:
|
||||
xgo_version: latest
|
||||
xgo_version: v0.7.5
|
||||
go_version: ${{ matrix.go_version }}
|
||||
dest: build
|
||||
prefix: casa
|
||||
@@ -108,7 +98,7 @@ jobs:
|
||||
v: true
|
||||
x: false
|
||||
race: false
|
||||
ldflags: -s -w -L /opt/glibc230/lib -extldflags "-static"
|
||||
ldflags: -s -w
|
||||
buildmode: default
|
||||
#
|
||||
# - name: List Files
|
||||
|
||||
26
.github/workflows/codecov.yml
vendored
Normal file
26
.github/workflows/codecov.yml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
name: Collect Code Coverage
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.20"
|
||||
- name: Run coverage
|
||||
run: go test -race -failfast -coverprofile=coverage.txt -covermode=atomic -v ./...
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
15
.github/workflows/demo.yml
vendored
15
.github/workflows/demo.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
# Steps represent a sequence of tasks that will be executed as part of the job
|
||||
steps:
|
||||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Configure AWS credentials from Test account
|
||||
uses: aws-actions/configure-aws-credentials@v1
|
||||
@@ -33,9 +33,10 @@ jobs:
|
||||
|
||||
- name: Get old instance and snapshot name, create new instance name
|
||||
run: |
|
||||
echo "OLD_INSTANCE_SNAPSHOT_NAME=$(aws lightsail get-instance-snapshots | grep '"name": "CasaOS-Demo-Snapshot-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||
echo "NEW_INSTANCE_NAME=CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||
echo "OLD_INSTANCE_SNAPSHOT_NAME=updateto_to_0.4.4-1684926517" >> $GITHUB_ENV
|
||||
echo "OLD_INSTANCE_NAME=$(aws lightsail get-instances | grep '"name": "CasaOS-Demo-[0-9]' | tail -1 | sed 's/ //g' | sed 's/"//g' | sed 's/,//g' | sed 's/name://g')" >> $GITHUB_ENV
|
||||
# echo "OLD_INSTANCE_NAME=CasaOS-Demo-1687680295" >> $GITHUB_ENV
|
||||
echo "NEW_INSTANCE_NAME= CasaOS-Demo-$(date +%s)" >> $GITHUB_ENV
|
||||
|
||||
- name: Create instances from snapshot
|
||||
run: |
|
||||
@@ -43,7 +44,7 @@ jobs:
|
||||
--instance-snapshot-name ${{ env.OLD_INSTANCE_SNAPSHOT_NAME }} \
|
||||
--instance-names ${{ env.NEW_INSTANCE_NAME }} \
|
||||
--availability-zone us-west-2a \
|
||||
--bundle-id large_2_0
|
||||
--bundle-id medium_2_0
|
||||
|
||||
- name: Wait for new instance running
|
||||
run: |
|
||||
@@ -75,5 +76,9 @@ jobs:
|
||||
run: |
|
||||
aws lightsail delete-instance \
|
||||
--instance-name ${{ env.OLD_INSTANCE_NAME }}
|
||||
- name: Demo Reset Error Handling
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"Demo Reset Error"}}' ${{ secrets.SSH_ROBOT_URL }}
|
||||
|
||||
|
||||
|
||||
27
.github/workflows/move_alpha_bug_to_project.yml
vendored
Normal file
27
.github/workflows/move_alpha_bug_to_project.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: Move alpha bug to project
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
|
||||
jobs:
|
||||
track_issue:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Generate token
|
||||
id: generate_token
|
||||
uses: tibdex/github-app-token@36464acb844fc53b9b8b2401da68844f6b05ebb0
|
||||
with:
|
||||
app_id: ${{ secrets.ALPHA_BOT_ID }}
|
||||
private_key: ${{ secrets.ALPHA_BOT_PEM }}
|
||||
|
||||
- name: Add Issue To GitHub Projects Beta
|
||||
uses: actions/add-to-project@v0.1.0
|
||||
with:
|
||||
project-url: https://github.com/orgs/IceWhaleTech/projects/5
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
labeled: alpha, bug
|
||||
label-operator: AND
|
||||
46
.github/workflows/publish_npm.yaml
vendored
Normal file
46
.github/workflows/publish_npm.yaml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: publish npm
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
publish-npm:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
- run: git tag --sort=-creatordate | head -n 1
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: echo "VERSION=$(git tag --sort=-creatordate | head -n 1)" >> $GITHUB_OUTPUT
|
||||
- name: Get commit id
|
||||
id: get_commit_id
|
||||
run: echo "COMMIT_ID=$( git rev-parse --short "$GITHUB_SHA" )" >> $GITHUB_OUTPUT
|
||||
|
||||
- run: echo "${{ steps.get_version.outputs.VERSION }}-${{ steps.get_commit_id.outputs.COMMIT_ID }}"
|
||||
- name: Set version
|
||||
run: |
|
||||
sudo apt-get install jq
|
||||
jq '.version="${{ steps.get_version.outputs.VERSION }}-${{ steps.get_commit_id.outputs.COMMIT_ID }}"' package.json > package.json.new
|
||||
mv package.json.new package.json
|
||||
- name: Generate SDK
|
||||
run: |
|
||||
npm cache clean --force
|
||||
npm install @openapitools/openapi-generator-cli -g
|
||||
- run: npm i
|
||||
- run: npm run start
|
||||
- run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
||||
48
.github/workflows/push_events_to_discord.yml
vendored
Normal file
48
.github/workflows/push_events_to_discord.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
name: Push Events to Discord
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
discussion:
|
||||
types:
|
||||
- created
|
||||
- transferred
|
||||
- answered
|
||||
discussion_comment:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
push-events:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
|
||||
- name: General Discussions & Comments
|
||||
if: ${{ ( github.event_name == 'discussion' || github.event_name == 'discussion_comment' ) && github.event.discussion.category.name == 'General' }}
|
||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||
with:
|
||||
webhook: ${{ secrets.Discord_CasaOS_General_Webhook }}
|
||||
|
||||
- name: App Request Issues & Comments
|
||||
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'App Request') }}
|
||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||
with:
|
||||
webhook: ${{ secrets.Discord_CasaOS_App_Request_Webhook }}
|
||||
|
||||
- name: Bug Issues & Comments
|
||||
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'bug') && !contains(github.event.issue.labels.*.name, 'alpha') }}
|
||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||
with:
|
||||
webhook: ${{ secrets.Discord_CasaOS_Bug_Webhook }}
|
||||
|
||||
- name: Alpha Issues & Comments
|
||||
if: ${{ ( github.event_name == 'issues' || github.event_name == 'issue_comment' ) && contains(github.event.issue.labels.*.name, 'alpha') }}
|
||||
uses: joseph-montanez/forward-event-action@v3.0.0
|
||||
with:
|
||||
webhook: ${{ secrets.Discord_CasaOS_Alpha_Webhook }}
|
||||
92
.github/workflows/push_test_server.yml
vendored
Normal file
92
.github/workflows/push_test_server.yml
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
name: Auto Publish Website
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
-
|
||||
name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: isntall git
|
||||
run: sudo apt install --yes git
|
||||
- name: git global
|
||||
run: sudo git config --global --add safe.directory '*'
|
||||
- name: set version
|
||||
run: sudo git tag v00.00.00-alpha
|
||||
|
||||
- name: Fetch all tags
|
||||
run: sudo git fetch --force --tags
|
||||
|
||||
- name: Get version
|
||||
id: get_version
|
||||
# run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
||||
run: echo "VERSION=$(git describe --abbrev=0 --tags | awk -F- '{print $1}')" >> $GITHUB_ENV
|
||||
|
||||
- name: show version
|
||||
id: show_version
|
||||
# run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
||||
run: echo ${{env.VERSION}}
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: 'stable'
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
version: 1.14.1
|
||||
args: release --rm-dist --snapshot
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GoogleID: ${{ secrets.GoogleID }}
|
||||
GoogleSecret: ${{ secrets.GoogleSecret }}
|
||||
DropboxKey: ${{ secrets.DropboxKey }}
|
||||
DropboxSecret: ${{ secrets.DropboxSecret }}
|
||||
OneDriveID: ${{ secrets.OneDriveID }}
|
||||
OneDriveSecret: ${{ secrets.OneDriveSecret }}
|
||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
|
||||
- name: remove migration file
|
||||
run: sudo find . -type f \( -name '*migration*' \) -delete
|
||||
|
||||
- name: install sshpass
|
||||
run: sudo apt install sshpass --yes
|
||||
|
||||
- name: ZeroTier
|
||||
uses: zerotier/github-action@v1.0.1
|
||||
with:
|
||||
network_id: ${{ secrets.ZEROTIER_NETWORK_ID }}
|
||||
auth_token: ${{ secrets.ZEROTIER_CENTRAL_TOKEN }}
|
||||
|
||||
- name: ping host
|
||||
shell: bash
|
||||
run: |
|
||||
count=10
|
||||
while ! ping -c 1 10.147.18.11 ; do
|
||||
echo "waiting..." ;
|
||||
sleep 1 ;
|
||||
let count=count-1
|
||||
done
|
||||
echo "ping success"
|
||||
|
||||
- name: copy tar to target host
|
||||
shell: bash
|
||||
run: |
|
||||
sshpass -p "${{ secrets.ssh_password }}" scp -r -o StrictHostKeyChecking=no -P 22 ./dist/*.gz root@10.147.18.11:/var/www/download
|
||||
echo "ping success"
|
||||
- name: send message
|
||||
run: |
|
||||
curl -X POST -H "Content-Type: application/json" -d '{"msg_type":"text","content":{"text":"CasaOS updated"}}' ${{ secrets.SSH_ROBOT_URL }}
|
||||
69
.github/workflows/release.yml
vendored
Normal file
69
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: goreleaser
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*.*.*
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Install dependencies for cross-compiling
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt-get --no-install-recommends --yes install \
|
||||
upx libc6-dev-amd64-cross \
|
||||
gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
|
||||
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Fetch all tags
|
||||
run: git fetch --force --tags
|
||||
|
||||
- name: Get version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version: "1.20"
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GoogleID: ${{ secrets.GoogleID }}
|
||||
GoogleSecret: ${{ secrets.GoogleSecret }}
|
||||
DropboxKey: ${{ secrets.DropboxKey }}
|
||||
DropboxSecret: ${{ secrets.DropboxSecret }}
|
||||
OneDriveID: ${{ secrets.OneDriveID }}
|
||||
OneDriveSecret: ${{ secrets.OneDriveSecret }}
|
||||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
|
||||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
|
||||
|
||||
- name: Upload to oss
|
||||
id: upload_to_oss
|
||||
uses: tvrcgo/upload-to-oss@master
|
||||
with:
|
||||
key-id: ${{ secrets.OSS_KEY_ID }}
|
||||
key-secret: ${{ secrets.OSS_KEY_SECRET }}
|
||||
region: oss-cn-shanghai
|
||||
bucket: casaos
|
||||
assets: |
|
||||
dist/checksums.txt:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/checksums.txt
|
||||
dist/linux-arm-7-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm-7-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-arm64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-amd64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-amd64-casaos-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-arm-7-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm-7-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-arm64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-arm64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
dist/linux-amd64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz:/IceWhaleTech/CasaOS/releases/download/${{ steps.get_version.outputs.VERSION }}/linux-amd64-casaos-migration-tool-${{ steps.get_version.outputs.VERSION }}.tar.gz
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -28,8 +28,15 @@ gen
|
||||
/sql/
|
||||
/out/
|
||||
/db/
|
||||
/docs/
|
||||
/conf/conf.ini
|
||||
/conf/conf.conf
|
||||
/conf/conf.json
|
||||
__debug_bin
|
||||
main
|
||||
github.com
|
||||
.all-contributorsrc
|
||||
dist
|
||||
CasaOS
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
|
||||
159
.goreleaser.debug.yaml
Normal file
159
.goreleaser.debug.yaml
Normal file
@@ -0,0 +1,159 @@
|
||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
project_name: casaos
|
||||
before:
|
||||
hooks:
|
||||
- go generate
|
||||
- go run github.com/google/go-licenses@latest check . --disallowed_types=restricted
|
||||
- go mod tidy
|
||||
- go test -race -v ./...
|
||||
|
||||
builds:
|
||||
- id: casaos-amd64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
env:
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- id: casaos-arm64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm64
|
||||
- id: casaos-arm-7
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
env:
|
||||
- CC=arm-linux-gnueabihf-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
- id: casaos-migration-tool-amd64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- id: casaos-migration-tool-arm64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm64
|
||||
- id: casaos-migration-tool-arm-7
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=arm-linux-gnueabihf-gcc
|
||||
gcflags:
|
||||
- all=-N -l
|
||||
ldflags:
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
archives:
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
||||
id: casaos
|
||||
builds:
|
||||
- casaos-amd64
|
||||
- casaos-arm64
|
||||
- casaos-arm-7
|
||||
files:
|
||||
- build/**/*
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}
|
||||
id: casaos-migration-tool
|
||||
builds:
|
||||
- casaos-migration-tool-amd64
|
||||
- casaos-migration-tool-arm64
|
||||
- casaos-migration-tool-arm-7
|
||||
files:
|
||||
- build/sysroot/etc/**/*
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
# release:
|
||||
# github:
|
||||
# owner: IceWhaleTech
|
||||
# name: CasaOS
|
||||
# draft: true
|
||||
# prerelease: auto
|
||||
# mode: replace
|
||||
# name_template: "v{{ .Version }}"
|
||||
release:
|
||||
github:
|
||||
owner: IceWhaleTech
|
||||
name: CasaOS
|
||||
draft: true
|
||||
prerelease: auto
|
||||
mode: replace
|
||||
name_template: "v{{ .Version }}"
|
||||
207
.goreleaser.yaml
Normal file
207
.goreleaser.yaml
Normal file
@@ -0,0 +1,207 @@
|
||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
project_name: casaos
|
||||
before:
|
||||
hooks:
|
||||
- go generate
|
||||
- go run github.com/google/go-licenses@latest check . --disallowed_types=restricted
|
||||
- go mod tidy
|
||||
- go test -race -v ./...
|
||||
|
||||
builds:
|
||||
- id: casaos-amd64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
env:
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- id: casaos-arm64
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm64
|
||||
- id: casaos-arm-7
|
||||
binary: build/sysroot/usr/bin/casaos
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
env:
|
||||
- CC=arm-linux-gnueabihf-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDriveID}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDriveSecret}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
- id: casaos-migration-tool-amd64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=x86_64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
- id: casaos-migration-tool-arm64
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=aarch64-linux-gnu-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm64
|
||||
- id: casaos-migration-tool-arm-7
|
||||
binary: build/sysroot/usr/bin/casaos-migration-tool
|
||||
hooks:
|
||||
post:
|
||||
- upx --best --lzma -v --no-progress "{{ .Path }}"
|
||||
main: ./cmd/migration-tool
|
||||
env:
|
||||
- CC=arm-linux-gnueabihf-gcc
|
||||
ldflags:
|
||||
- -X main.commit={{.Commit}}
|
||||
- -X main.date={{.Date}}
|
||||
- -s
|
||||
- -w
|
||||
- -extldflags "-static"
|
||||
tags:
|
||||
- musl
|
||||
- netgo
|
||||
- osusergo
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- arm
|
||||
goarm:
|
||||
- "7"
|
||||
archives:
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
||||
id: casaos
|
||||
builds:
|
||||
- casaos-amd64
|
||||
- casaos-arm64
|
||||
- casaos-arm-7
|
||||
files:
|
||||
- build/**/*
|
||||
- name_template: >-
|
||||
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}
|
||||
id: casaos-migration-tool
|
||||
builds:
|
||||
- casaos-migration-tool-amd64
|
||||
- casaos-migration-tool-arm64
|
||||
- casaos-migration-tool-arm-7
|
||||
files:
|
||||
- build/sysroot/etc/**/*
|
||||
checksum:
|
||||
name_template: "checksums.txt"
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
# release:
|
||||
# github:
|
||||
# owner: IceWhaleTech
|
||||
# name: CasaOS
|
||||
# draft: true
|
||||
# prerelease: auto
|
||||
# mode: replace
|
||||
# name_template: "v{{ .Version }}"
|
||||
release:
|
||||
github:
|
||||
owner: IceWhaleTech
|
||||
name: CasaOS
|
||||
draft: true
|
||||
prerelease: auto
|
||||
mode: replace
|
||||
name_template: "v{{ .Version }}"
|
||||
616
CHANGELOG.md
Normal file
616
CHANGELOG.md
Normal file
@@ -0,0 +1,616 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
### Removed
|
||||
|
||||
### Security
|
||||
|
||||
## [0.4.3]
|
||||
|
||||
### Added
|
||||
|
||||
- [Disk] Now usb also supports merging to
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
- [File] Solve the installation dependency problem, make the installation more smoothly
|
||||
- [File] Change the default permissions of the sharing folder
|
||||
|
||||
### Fixed
|
||||
|
||||
- [System] Fixed not see wlan iface ([#909](https://github.com/IceWhaleTech/CasaOS/issues/909))
|
||||
- [System] Terminal font issue fix ([#929](https://github.com/IceWhaleTech/CasaOS/issues/929))
|
||||
- [File] Fixed the problem of not being able to launch after mounting
|
||||
|
||||
### Removed
|
||||
|
||||
|
||||
## [0.4.2]
|
||||
|
||||
### Added
|
||||
|
||||
- [App] Increase the display of progress during the installation process
|
||||
- [App] Label whether the current app supports x86 or Pi devices
|
||||
- [App] Support single app version upgrade
|
||||
- [File] Support mounting of Google Drive and Dropbox cloud drives
|
||||
- [System] Support Mint Linux
|
||||
|
||||
### Changed
|
||||
|
||||
- [File] Optimize the download speed of a single file
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Share] Fix the samba permission issue
|
||||
- [Disk] Fix the problem of disk mount point plus 1 after upgrade ([#770](https://github.com/IceWhaleTech/CasaOS/issues/770))
|
||||
- [File] Fix the problem of file permission change caused by modifying files in casaos ([#829](https://github.com/IceWhaleTech/CasaOS/issues/829))
|
||||
- [Share] Fix the problem of files being deleted due to samba uninstallation failure ([#843](https://github.com/IceWhaleTech/CasaOS/issues/843))
|
||||
|
||||
|
||||
|
||||
## [0.4.1] - 2023-1-19
|
||||
|
||||
|
||||
### Added
|
||||
- [Disk] Added disk merging feature in storage management (beta) that allows for multiple disks to be merged into a single storage space
|
||||
- [System] Added option for startpage.com search engine
|
||||
- [APP] Added app cloning feature in the app's context menu.
|
||||
### Changed
|
||||
- [APP] Improved app installation process, including display of the installation process, checks for successful installation, and prompts
|
||||
- [System] Binary sizes are 40%~60% smaller (thanks to upx)
|
||||
- [App] Optimization of install and update for certain country.
|
||||
- [All] Lots of bug fixes
|
||||
|
||||
## [0.4.0] - 2022-12-13
|
||||
### Added
|
||||
|
||||
- [Developer] Included `casaos-cli` command tool for debugging
|
||||
- [Developer] Added message bus for events and actions - Use `casaos-cli message-bus` to manage.
|
||||
- [Disk] Disk notification in Dashboard
|
||||
- [System] Restart/shutdown directly from CasaOS Dashboard
|
||||
### Changed
|
||||
|
||||
- [General] CasaOS new logo!
|
||||
- [App] Redesign of Featured App
|
||||
- [App] Now you can choose to delete userdata along with app uninstallation
|
||||
|
||||
### Security
|
||||
|
||||
- [System] Fixed a shell injection issue for better security
|
||||
|
||||
### Fixed
|
||||
|
||||
- [System] Re-instate default zone0 for CPU Temp ([#694](https://github.com/IceWhaleTech/CasaOS/issues/694))
|
||||
- [Disk] Fixed storage name with extra `-1` after rebooting ([#698](https://github.com/IceWhaleTech/CasaOS/issues/698))
|
||||
- [Disk] Fixed disk check so it does not impact disk going into idle ([#704](https://github.com/IceWhaleTech/CasaOS/issues/704))
|
||||
|
||||
## [0.3.8] 2022-11-21
|
||||
|
||||
### Added
|
||||
- [System] Add system announcement
|
||||
- [App] Allow to turn off the display of "Existing Docker Apps" in the settings.
|
||||
|
||||
### Changed
|
||||
- [System] Improve the feedback function, you can submit feedback in the bottom right corner of WebUI.
|
||||
|
||||
### Fixed
|
||||
- [System] Fix CPU Temp for other platforms ([#661](https://github.com/IceWhaleTech/CasaOS/issues/661))
|
||||
|
||||
## [0.3.7.1] 2022-11-04
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix memory leak issue ([#658](https://github.com/IceWhaleTech/CasaOS/issues/658)[#646](https://github.com/IceWhaleTech/CasaOS/issues/646))
|
||||
- Solve the problem of local application import failure ([#490](https://github.com/IceWhaleTech/CasaOS/issues/490))
|
||||
|
||||
## [0.3.7] 2022-10-28
|
||||
|
||||
### Added
|
||||
- [Storage] Disk merge (Beta), you can merge multiple disks into a single storage space (currently you need to enable this feature from the command line)
|
||||
|
||||
### Changed
|
||||
- [Files] Changed the cache file storage location, now the file upload size is not limited by the system disk capacity.
|
||||
- [Scripts] Updated installation and upgrade scripts to support more Debian-based Linux distributions.
|
||||
- [Engineering] Refactored Local Storage into a standalone service as part of CasaOS modularization.
|
||||
|
||||
### Fixed
|
||||
- [Apps] App list update mechanism improved, now you can see the latest apps in App Store immediately.
|
||||
- [Storage] Fixed a lot of known issues
|
||||
|
||||
### Added
|
||||
- [Storage] Disk merge (Beta), you can merge multiple disks into a single storage space (currently you need to enable this feature from the command line)
|
||||
|
||||
### Changed
|
||||
- [Files] Changed the cache file storage location, now the file upload size is not limited by the system disk capacity.
|
||||
- [Scripts] Updated installation and upgrade scripts to support more Debian-based Linux distributions.
|
||||
- [Engineering] Refactored Local Storage into a standalone service as part of CasaOS modularization.
|
||||
|
||||
### Fixed
|
||||
- [Apps] App list update mechanism improved, now you can see the latest apps in App Store immediately.
|
||||
- [Storage] Fixed a lot of known issues
|
||||
|
||||
|
||||
## [0.3.6] - 2022-09-06
|
||||
|
||||
### Added
|
||||
- [System] Added power and temperature info to performance widget (Intel)
|
||||
- [Apps] Custom links can be added to Apps section
|
||||
|
||||
### Fixed
|
||||
- [Apps] Fixed the problem of not being able to modify some App settings ([#510](https://github.com/IceWhaleTech/CasaOS/issues/510))
|
||||
|
||||
### Changed
|
||||
- [System] Architecture optimization. Improved performance.
|
||||
|
||||
## [0.3.5] - 2022-08-23
|
||||
|
||||
### Added
|
||||
|
||||
- [File] Mount the shared samba
|
||||
- [File] File sharing via Samba
|
||||
- [System] You can share casaos on Twitter, facebook, reddit
|
||||
|
||||
### Changed
|
||||
|
||||
- [Disk] Support for mounting existing data disks
|
||||
|
||||
### Fixed
|
||||
|
||||
- [App] fixed uninstalling imported docker container apps results in wiping ALL your config data from them ([#360](https://github.com/IceWhaleTech/CasaOS/issues/360))
|
||||
|
||||
## [0.3.4] - 2022-07-29(UTC)
|
||||
|
||||
### Added
|
||||
|
||||
- SSH adds port-side options and prompts for connection status. ([#286](https://github.com/IceWhaleTech/CasaOS/issues/286))
|
||||
|
||||
### Changed
|
||||
|
||||
- Normalize all routes
|
||||
- Application names now support spaces ([#211](https://github.com/IceWhaleTech/CasaOS/issues/211))
|
||||
|
||||
### Removed
|
||||
|
||||
- Removed casaos connect
|
||||
|
||||
### Security
|
||||
|
||||
- Adjustment of authentication method
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed storage format and remove password error issues ([#344](https://github.com/IceWhaleTech/CasaOS/issues/344) [#357](https://github.com/IceWhaleTech/CasaOS/issues/357))
|
||||
|
||||
## [0.3.3] - 2022-07-08(UTC)
|
||||
|
||||
### Added
|
||||
|
||||
- [System]Add interface call log
|
||||
- Adding Developing file ([#311](https://github.com/IceWhaleTech/CasaOS/pull/311))
|
||||
- [App] add new tips for app section.
|
||||
- [System] UI Configurable function modules: support turning off the search bar and recommended apps module in the settings.
|
||||
- [System] Custom wallpapers: two new preset wallpapers, support for custom uploads, support for setting images from Files as wallpapers, Also support right click on dashboard to change wallpaper.
|
||||
|
||||
### Changed
|
||||
|
||||
- [App] Cache app store index and category data
|
||||
- [System] casaos master program adapted to FHS standards
|
||||
- [App] Update casaos icons.
|
||||
- [System] Update translation.
|
||||
|
||||
### Removed
|
||||
|
||||
- [System] Remove upnp function module
|
||||
- [System] Remove ddns function module
|
||||
- [System] Remove search function module
|
||||
- [System] Remove zerotier function module
|
||||
- [System] Remove task function module
|
||||
- [System] Remove file share function module
|
||||
|
||||
### Fixed
|
||||
|
||||
- [Disk] Fixed hard drive won't hibernate problem ([#202](https://github.com/IceWhaleTech/CasaOS/issues/202))
|
||||
- [File] Fixed the backspace key that causes the folder to rewind ([#252](https://github.com/IceWhaleTech/CasaOS/issues/252))
|
||||
- [App] Fixed app logo is not loading when imported. ([#320](https://github.com/IceWhaleTech/CasaOS/issues/320))
|
||||
|
||||
## [0.3.2.1] - 2022-06-16(UTC)
|
||||
|
||||
### Changed
|
||||
|
||||
- [System] Adjusted the display style.
|
||||
|
||||
### Fixed
|
||||
|
||||
- [System] Fixed the issue of widgets displaying wrongly on mobile devices.
|
||||
- [App] Fix the problem of application opening failure on non-80 ports ([#283](https://github.com/IceWhaleTech/CasaOS/issues/283) [#280](https://github.com/IceWhaleTech/CasaOS/issues/280))
|
||||
- [System] Modify port failure problem ([#282](https://github.com/IceWhaleTech/CasaOS/issues/282))
|
||||
- [App]Modify environment variables disappearing problem([#284](https://github.com/IceWhaleTech/CasaOS/issues/284))
|
||||
- [System]Fix no update alert([#278](https://github.com/IceWhaleTech/CasaOS/issues/278))
|
||||
- [System] Fixed some bugs of application cpu usage and memory staging([#272](https://github.com/IceWhaleTech/CasaOS/issues/272))
|
||||
- [App] Fixed plex and HA network mode error issues ([#299](https://github.com/IceWhaleTech/CasaOS/issues/299))
|
||||
- [App] Fix application terminal not working ([#266](https://github.com/IceWhaleTech/CasaOS/issues/266))
|
||||
|
||||
## [0.3.2] - 2022-06-10
|
||||
|
||||
### Added
|
||||
|
||||
- [Files] Files can now be selected multiple files and downloaded, deleted, moved, etc.
|
||||
- [Apps] Support to modify the application opening address.([#204](https://github.com/IceWhaleTech/CasaOS/issues/204))
|
||||
|
||||
### Changed
|
||||
|
||||
- [Apps] Hide the display of non-essential environment variables in the application.([#196](https://github.com/IceWhaleTech/CasaOS/issues/196))
|
||||
- [System] Network, disk, cpu, memory, etc. information is modified to be pushed via socket.
|
||||
- [System] Optimize opening speed.([#214](https://github.com/IceWhaleTech/CasaOS/issues/214))
|
||||
- [Language] Update language pack [zarevskaya](https://github.com/zarevskaya) [patrickhilker](https://github.com/patrickhilker)
|
||||
- [System] Interface path adjustment
|
||||
|
||||
### Removed
|
||||
|
||||
- [Files] Remove the online preview function of PDF files
|
||||
|
||||
### Fixed
|
||||
|
||||
- [System] Fixed the problem that sync data cannot submit the device ID ([#68](https://github.com/IceWhaleTech/CasaOS/issues/68))
|
||||
- [Files] Fixed the code editor center alignment display problem.([#210](https://github.com/IceWhaleTech/CasaOS/issues/210))
|
||||
- [Files] Fixed the problem of wrong name when downloading files.([#240](https://github.com/IceWhaleTech/CasaOS/issues/240))
|
||||
- [System] Fixed the network display as a negative number problem.([#224](https://github.com/IceWhaleTech/CasaOS/issues/224))
|
||||
- [System] Fixed the problem of wireless network card traffic display.([#222](https://github.com/IceWhaleTech/CasaOS/issues/222))
|
||||
|
||||
|
||||
## [0.3.1.1] - 2022-05-17
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the data loss problem when importing local applications
|
||||
|
||||
## [0.3.1] - 2022-05-16
|
||||
|
||||
### Added
|
||||
|
||||
- CasaConnect and file add image thumbnail function
|
||||
- Import of docker applications
|
||||
- List support custom sorting function
|
||||
- CasaConnect gives priority to LAN connections
|
||||
- USB auto-mount switch (Raspberry Pi is off by default)
|
||||
- Application custom installation supports Docker Compose configuration import in YAML format
|
||||
- You will see the new version changelog from the next version
|
||||
- Added live preview for icons in custom installed applications
|
||||
|
||||
### Changed
|
||||
|
||||
- Application data is no longer saved to the database
|
||||
- Optimize app store speed issues
|
||||
- Optimize the way WebUI is filled in
|
||||
- Image preview has been completely upgraded and now supports switching between all images in the same folder, as well as dragging, zooming, rotating and resetting.
|
||||
- Added color levels to the CPU and RAM charts
|
||||
- Optimized the display of the Connect friends list right-click menu
|
||||
- Change the initial display directory to /DATA
|
||||
|
||||
### Removed
|
||||
|
||||
- Historical Application Data
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed the problem that some Docker CLI commands failed to import
|
||||
- Fix the problem that the application is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as application name
|
||||
- Fix Pi-hole installation failure
|
||||
- Fixed the issue that the app could not be updated using WatchTower
|
||||
- Fixed the problem that the task status was lost after closing Files when there was an upload task
|
||||
|
||||
## [0.3.0] - 2022-04-08
|
||||
|
||||
### Added
|
||||
|
||||
- Add CasaConnect function, now you can share private files peer-to-peer with your friends.
|
||||
- Add a widget for network traffic monitoring.
|
||||
- 12 new popular apps added to App Center
|
||||
|
||||
### Changed
|
||||
|
||||
- Updated the sidebar of Files.
|
||||
- Updated the initial directory of Files to the Root directory.
|
||||
- Armbian 22.02 armhf/arm64/amd64 platform tests passed [@igorpecovnik ](https://github.com/igorpecovnik)
|
||||
- Elementary OS 6.1 Jólnir amd64 platform tests passed [@alvarosamudio ](https://github.com/alvarosamudio)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix an issue in Files where the backspace button would trigger a return to the previous level of the directory when creating a folder.
|
||||
- Fix the display problem of application list in CPU widget.
|
||||
- Fix the problem that the ipv6 of the application cannot be opened
|
||||
|
||||
### Removed
|
||||
|
||||
- Interfaces related to "zerotier"
|
||||
|
||||
## [0.2.10] - 2022-03-10
|
||||
|
||||
### Added
|
||||
|
||||
- Added CasaOS own file manager, now you can browse, upload, download files from the system, even edit code online, preview photos and videos through it. It will appear in the first position of Apps.
|
||||
- Added CPU core count display and memory capacity display.
|
||||
|
||||
### Changed
|
||||
|
||||
- Optimized the rendering performance of the home page.
|
||||
- Optimized the internationalization display of the time widget.
|
||||
- Show the icon of the stopped application as gray.
|
||||
- Unify the animation of the drop-down menu.
|
||||
- Optimize the display of the application drop-down menu.
|
||||
- Replaced the default font to optimize the display.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the problem of failed to create storage space
|
||||
|
||||
## [0.2.9] - 2022-02-18
|
||||
|
||||
### Added
|
||||
|
||||
- Add a simple notification function
|
||||
|
||||
### Changed
|
||||
|
||||
- Custom installation of new parameters(Capabilities,Hostname,Privileged)
|
||||
- Update front-end translation [@SemVer](https://github.com/zarevskaya) [@koboldMaki](https://github.com/koboldMaki) [@sgastol](https://github.com/sgastol) [@delki8](https://github.com/delki8)
|
||||
|
||||
- Modify the default location and name of the usb mount
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the problem of being indexed by search engines
|
||||
- Fix some style display issues
|
||||
- Solve hard drive can't be formatted, can't finish adding storage
|
||||
|
||||
## [0.2.8] - 2022-01-30
|
||||
|
||||
### Added
|
||||
|
||||
- Add USB disk device display
|
||||
|
||||
### Changed
|
||||
|
||||
- Update translation [@baptiste313](https://github.com/baptiste313) [@thueske](https://github.com/thueske)
|
||||
- Compatible with more types of drives
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the language initialization bug
|
||||
- Fix the problem that the login page could not be displayed
|
||||
- Fix missing translated content
|
||||
|
||||
## [0.2.7] - 2022.01.26
|
||||
|
||||
### Changed
|
||||
|
||||
- Apply multilingual support
|
||||
|
||||
### Security
|
||||
|
||||
- Fix an injectable execution bug
|
||||
|
||||
## [0.2.6] - 2022.01.26
|
||||
|
||||
### Added
|
||||
|
||||
- Add a bug report panel.
|
||||
- App Store apps start supporting multiple languages
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix a disk that cannot be formatted under certain circumstances
|
||||
|
||||
## [0.2.5] - 2022.01.24
|
||||
|
||||
### Added
|
||||
|
||||
- Storage Manager
|
||||
|
||||
### Changed
|
||||
|
||||
- Update Disk widget
|
||||
- Update language files [@ImOstrovskiy](https://github.com/ImOstrovskiy) [@baptiste313](https://github.com/baptiste313)
|
||||
|
||||
### Fixed
|
||||
|
||||
- File synchronization issues
|
||||
- Fix the app store classification problem
|
||||
|
||||
## [0.2.4] - 2021.12.30
|
||||
|
||||
### Changed
|
||||
|
||||
- Brand new App Store
|
||||
- Optimize request method
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix Sync panel width display error.
|
||||
- Fix App panel width display error.
|
||||
|
||||
## [0.2.3] - 2021.12.11
|
||||
|
||||
### Added
|
||||
|
||||
- Add detailed CPU and memory statistics.
|
||||
- Add the multi-language function and add Chinese translation.
|
||||
- Add the function to modify the search engine.
|
||||
- Add the function of modifying the WebUI port
|
||||
|
||||
### Changed
|
||||
|
||||
- Update update script
|
||||
- Preprocessing usb automounting
|
||||
|
||||
### Fixed
|
||||
|
||||
- Volume path problem when customizing the installation of applications
|
||||
- Fix Cpu and Ram usage display error
|
||||
- Fix translation errors
|
||||
- Fixed an error when importing and exporting appfile.
|
||||
|
||||
## [0.2.2] - 2021.12.02
|
||||
|
||||
### Changed
|
||||
|
||||
- UI adjustment
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the problem of data display error when manually installing apps
|
||||
- Fix some spelling problems
|
||||
- Fix the bug of synchronization module
|
||||
|
||||
## [0.2.1] - 2021.11.25
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix Sync display error
|
||||
- Fix Sync Downoad url error
|
||||
- Fix Smart Block display error
|
||||
- Fix widgets settings dispaly error
|
||||
- Fix application installation path error
|
||||
|
||||
## [0.2.0] - 2021.11.25
|
||||
|
||||
### Added
|
||||
|
||||
- Add sync function
|
||||
|
||||
|
||||
## [0.1.11] - 2021.11.10
|
||||
|
||||
### Changed
|
||||
|
||||
- Adaptation of cell phone terminals
|
||||
- Optimize user experience
|
||||
- Replaced the default background
|
||||
- Optimized the display performance and fixed some bugs
|
||||
|
||||
### Fixed
|
||||
|
||||
- Resolve application installation path errors
|
||||
|
||||
## [0.1.10] - 2021.11.04
|
||||
|
||||
### Added
|
||||
|
||||
- Add application terminal
|
||||
- Add application logs
|
||||
- Add system logs
|
||||
- Add App Store for installation
|
||||
|
||||
## [0.1.9] - 2021.11.01 [YANKED]
|
||||
|
||||
## [0.1.8] - 2021.10.27
|
||||
|
||||
### Added
|
||||
|
||||
- Add system terminal
|
||||
- Add the ability to modify the user name and password
|
||||
|
||||
### Changed
|
||||
|
||||
- Experience optimization
|
||||
- Improve single user management function
|
||||
- Fixed Disk widget display error
|
||||
- Fixed Username display error after change
|
||||
- Adaptation for mobile access
|
||||
|
||||
## [0.1.7] - 2021.10.22
|
||||
|
||||
### Added
|
||||
|
||||
- Add user authentication module, Login page and initialization page.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix the problem that the application could not start after the system restarted.
|
||||
- Home storage space data display exception
|
||||
- Script override causes application loss after installation
|
||||
- Fix docker network error
|
||||
|
||||
## [0.1.6] - 2021.10.19
|
||||
|
||||
### Added
|
||||
|
||||
- Add app icon auto-fill via docker image name.
|
||||
- Add a file selector for app install.
|
||||
|
||||
### Changed
|
||||
|
||||
- Modify import reminder.
|
||||
- Optimize the application installation process
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed an issue with the app were it would disappear when the app was modified.
|
||||
- Fixed device selector default dir to /dev
|
||||
|
||||
## [0.1.5] - 2021.10.15
|
||||
|
||||
### Added
|
||||
|
||||
- Add CPU RAM Status with widget
|
||||
- Add Disk Info with widget
|
||||
- Realize automatic loading of widgets
|
||||
|
||||
### Changed
|
||||
|
||||
- Enhance the Docker cli import experience and automatically fill in the folders that need to be mounted
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove Weather widget.
|
||||
|
||||
### Fixed
|
||||
|
||||
- AppFile upload does not pass verification
|
||||
- The setting menu of the app is displayed abnormally when the browser window is too narrow
|
||||
- The port is occupied and the program cannot start
|
||||
- Fix display bugs when windows size less than 1024px
|
||||
|
||||
## [0.1.4] - 2021.09.30
|
||||
|
||||
### Added
|
||||
|
||||
- Import and export of application configuration files
|
||||
- Automatic parsing of docker commands
|
||||
|
||||
### Changed
|
||||
|
||||
- Improve the program release process
|
||||
- Application installation process UX/UI optimization
|
||||
|
||||
### Fixed
|
||||
|
||||
- Authentication failure during the operation, resulting in the need to re-login
|
||||
|
||||
## [0.1.3] - 2021.09.29 [YANKED]
|
||||
|
||||
## [0.1.2] - 2021.09.28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Application modification and new creation failure issues
|
||||
|
||||
## [0.1.1] - 2021.09.27
|
||||
|
||||
## [0.1.0] - 2021.09.26
|
||||
|
||||
### Added
|
||||
|
||||
- Application Center
|
||||
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
wiki@casaos.io.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
33
DEVELOPING.md
Normal file
33
DEVELOPING.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# CasaOS Development
|
||||
Here we will describe the steps required to setup a development environment with CasaOS.
|
||||
|
||||
- [Setting up development environment](#setting-up-development-environment)
|
||||
- [Pre-requisites](#pre-requisites)
|
||||
- [1. Fork the Repo](#1.-fork-the-repo)
|
||||
- [2. Clone the repo down](#2.-clone-the-repo-down)
|
||||
- [3. Install dependencies](#3.-install-dependencies)
|
||||
|
||||
|
||||
## Setting up a development environment
|
||||
In this section we will walk you through the general process of setting up your development environment to get started.
|
||||
|
||||
### Pre-requisites
|
||||
The following must be installed in order to get started. The details of how to install them is outside the scope of this doc, but generally they should be able to be installed with your systems package manager (apt, yum, brew, choco, etc).
|
||||
- Go > v1.17.0
|
||||
- yarn
|
||||
- node.js
|
||||
|
||||
### 1. Fork the Repo
|
||||
[Fork the repo](https://docs.github.com/en/get-started/quickstart/fork-a-repo) onto your own GitHub account for developing.
|
||||
|
||||
### 2. Clone the repo down
|
||||
1. Navigate into your go workspace (check with `go env GOPATH`).
|
||||
2. Navigate to the appropriate path for github. It should look something like this: `<path from GOPATH>/github.com/<GitHub Username>/`. If it doesn't exist create it.
|
||||
3. Clone down the repo with the following: `git clone --recurse-submodules --remote-submodules https://github.com/<your GitHub Username>/CasaOS.git`
|
||||
|
||||
### 3. Install dependencies
|
||||
1. `cd UI`
|
||||
2. `yarn install`
|
||||
3. `yarn build`
|
||||
4. `cd ..`
|
||||
5. `go get`
|
||||
234
README.md
234
README.md
@@ -1,86 +1,224 @@
|
||||
# CasaOS - A simple, easy-to-use, elegant open-source Home Cloud system.
|
||||
# CasaOS - Your Personal Cloud
|
||||
<!-- Readme i18n links -->
|
||||
<!-- > English | [中文](#) | [Français](#) -->
|
||||
|
||||

|
||||
<p align="center">
|
||||
<!-- CasaOS Banner -->
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_dark_night_800x300.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800x300.png">
|
||||
<img alt="CasaOS" src="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800x300.png">
|
||||
</picture>
|
||||
<br/>
|
||||
<i>Connect with the community, establish autonomy, reduce the cost of SaaS, and MAXIMIZE the potential for a personalized copilot.</i>
|
||||
<br/>
|
||||
<br/>
|
||||
<!-- CasaOS Badges -->
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS" target="_blank">
|
||||
<img alt="CasaOS Version" src="https://img.shields.io/github/v/release/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=CasaOS" />
|
||||
</a>
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS/blob/main/LICENSE" target="_blank">
|
||||
<img alt="CasaOS License" src="https://img.shields.io/github/license/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=License" />
|
||||
</a>
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS/pulls" target="_blank">
|
||||
<img alt="CasaOS Pull Requests" src="https://img.shields.io/github/issues-pr/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=PRs" />
|
||||
</a>
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS/issues" target="_blank">
|
||||
<img alt="CasaOS Issues" src="https://img.shields.io/github/issues/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=Issues" />
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/IceWhaleTech/CasaOS" >
|
||||
<img src="https://codecov.io/gh/IceWhaleTech/CasaOS/branch/main/graph/badge.svg?token=l9uMKGlkxM"/>
|
||||
</a>
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS/stargazers" target="_blank">
|
||||
<img alt="CasaOS Stargazers" src="https://img.shields.io/github/stars/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=Stars" />
|
||||
</a>
|
||||
<!-- <a href="https://github.com/IceWhaleTech/CasaOS/releases" target="_blank">
|
||||
<img alt="CasaOS Downloads" src="https://img.shields.io/github/downloads/IceWhaleTech/CasaOS/total?color=162453&style=flat-square" />
|
||||
</a> -->
|
||||
<br/>
|
||||
<!-- CasaOS Community -->
|
||||
<a href="https://discord.gg/knqAbbBbeX" target="_blank">
|
||||
<img alt="IceWhale Discord" src="https://img.shields.io/discord/884667213326463016?color=162453&style=flat-square&label=Discord&logo=discord&logoColor=fff" />
|
||||
</a>
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS/discussions" target="_blank">
|
||||
<img alt="CasaOS GitHub Discussions" src="https://img.shields.io/github/discussions/IceWhaleTech/CasaOS?color=162453&style=flat-square&label=Discussions&logo=github" />
|
||||
</a>
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
||||
<a href="#credits"><img alt="All Contributors" src="https://img.shields.io/static/v1?label=All%20Contributors&message=15&color=162453&style=flat-square&logo=Handshake&logoColor=fff" /></a>
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
<br/>
|
||||
<!-- CasaOS Links -->
|
||||
<a href="https://www.casaos.io" target="_blank">Website</a> |
|
||||
<a href="http://demo.casaos.io" target="_blank">Demo</a> |
|
||||
<a href="https://github.com/IceWhaleTech/CasaOS" target="_blank">GitHub</a>
|
||||
<br/>
|
||||
<br/>
|
||||
<!-- CasaOS Snapshots -->
|
||||
<kbd>
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="snapshot-dark.jpg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="snapshot-light.jpg">
|
||||
<img alt="CasaOS Snapshot" src="snapshot-light.jpg">
|
||||
</picture>
|
||||
</kbd>
|
||||
</p>
|
||||
|
||||
[](https://github.com/IceWhaleTech/CasaOS)
|
||||
[](https://github.com/IceWhaleTech/CasaOS/pulls)
|
||||
[](https://github.com/IceWhaleTech/CasaOS/issues)
|
||||
[](https://github.com/IceWhaleTech/CasaOS/stargazers)
|
||||
[](https://discord.gg/knqAbbBbeX)
|
||||
## Why do you need Personal Cloud?
|
||||
|
||||
CasaOS is an open-source Home Cloud system based on the Docker ecosystem and designed for home scenarios. It is committed to building the world's most simple, easy-to-use, and elegant Home Cloud system.
|
||||
In 2020, the team noticed three important trends:
|
||||
- The cost of computing power and storage was decreasing fast.
|
||||
- A part of cloud computing was moving towards edge computing.
|
||||
- The issue of consumer data asset ownership and attribution had been ignored.
|
||||
|
||||
IceWhale team believes that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
||||
Based on these trends, the team proposed a thought experiment internally: what if personal clouds were available under $100 in next five years? This personal cloud would provide a low-cost data collaboration solution as a personal data center, storing and managing data for creators and small organizations. A distributed collaborative computing network can be formed by personal servers located around the world. It could also control and connect all smart devices, providing cross-ecosystem local intelligent services.
|
||||
|
||||

|
||||

|
||||
Furthermore, the personal cloud could combine personal data to train personalized AI assistants. The idea is that this technology would be an effective way to solve the issue of consumer data asset ownership and , as well as provide a more affordable and efficient computing solution for individuals and small organizations.
|
||||
|
||||
> If you think what we are doing is valuable. Please **give us a star ⭐** and **fork it 🤞**!
|
||||
|
||||
## Features
|
||||
|
||||
- Friendly UI designed for home scenarios
|
||||
- No code, no forms, intuitive, design for humanity
|
||||
- Multiple hardware and base system support
|
||||
- ZimaBoard, NUC, RPi, old computers, whatever is available.
|
||||
- Selected apps in the app store, one-click installation
|
||||
- Nextcloud, HomeAssistant, AdGuard, Jellyfin, *arr and more!
|
||||
- Easily install numerous Docker apps
|
||||
- Over 100,000 apps from the Docker ecosystem can be easily installed
|
||||
- Elegant drive and file management
|
||||
- What you see is what you get. No technical background required.
|
||||
- Well-designed system/app widgets
|
||||
- What you care about, at a glance. Resource usage, app status, and more!
|
||||
|
||||
## Getting Started
|
||||
|
||||
> ⚠️ Note:
|
||||
>
|
||||
> CasaOS is still in the early development stage and may vary significantly with the final release. Feel free to test run and share your feedback in the [Discord server](https://discord.gg/knqAbbBbeX)!
|
||||
CasaOS fully supports ZimaBoard, Intel NUC, and Raspberry Pi. Also, more computers and development boards and fully compatible with Ubuntu, Debian, Raspberry Pi OS, and CentOS with one-liner installation.
|
||||
|
||||
### Hardware Compatibility
|
||||
|
||||
- amd64 / x86-64
|
||||
- arm64
|
||||
- armv7
|
||||
|
||||
### System Compatibility
|
||||
|
||||
Official Support
|
||||
- Debian 12 (✅ Tested, Recommended)
|
||||
- Ubuntu Server 20.04 (✅ Tested)
|
||||
- Raspberry Pi OS (✅ Tested)
|
||||
|
||||
Community Support
|
||||
- Elementary 6.1 (✅ Tested)
|
||||
- Armbian 22.04 (✅ Tested)
|
||||
- Alpine (🚧 Not Fully Tested Yet)
|
||||
- OpenWrt (🚧 Not Fully Tested Yet)
|
||||
- ArchLinux (🚧 Not Fully Tested Yet)
|
||||
|
||||
### Quick Setup CasaOS
|
||||
|
||||
Fresh install a system from the list below and run the this command:
|
||||
Freshly install a system from the list above and run this command:
|
||||
|
||||
```sh
|
||||
wget -qO- https://get.icewhale.io/casaos.sh | bash
|
||||
wget -qO- https://get.casaos.io | sudo bash
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```sh
|
||||
curl -fsSL https://get.icewhale.io/casaos.sh | bash
|
||||
curl -fsSL https://get.casaos.io | sudo bash
|
||||
```
|
||||
|
||||
### Uninstall CasaOS
|
||||
|
||||
|
||||
v0.3.3 or newer
|
||||
|
||||
```sh
|
||||
curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | bash
|
||||
casaos-uninstall
|
||||
```
|
||||
|
||||
### System Compatibility
|
||||
|
||||
- Ubuntu Server 20.04 amd64 (✅ Recommend, Tested)
|
||||
- Raspberry Pi Lite OS aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
||||
- Debian 11 amd64 (⚠️ Not Fully Tested Yet)
|
||||
- OpenWrt 21.02 amd64 (⚠️ Not Fully Tested Yet)
|
||||
- OpenWrt 21.02 aarch64/arm64 (⚠️ Not Fully Tested Yet)
|
||||
|
||||
|
||||
## Key Features
|
||||
|
||||
- UI designed for home scenarios - simple, elegant, and easy-to-use
|
||||
- Quick Docker app installation with only three steps, plus automatic management
|
||||
- App Store for Home Cloud 🚧
|
||||
- Home data/digital asset management 🚧
|
||||
- Smart home manager 🚧
|
||||
|
||||
🚧 is under development.
|
||||
|
||||
We are actively moving forward with development, and you are more than welcome to share any idea with us!
|
||||
Before v0.3.3
|
||||
|
||||
```sh
|
||||
curl -fsSL https://get.icewhale.io/casaos-uninstall.sh | sudo bash
|
||||
```
|
||||
|
||||
## Community
|
||||
|
||||
The word Casa comes from the Spanish word for "home". Project CasaOS originated as a pre-installed system for crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
||||
The word Casa comes from the Spanish word for "home". Project CasaOS originated as a pre-installed system for the crowdfunded product [ZimaBoard](https://www.zimaboard.com) on Kickstarter.
|
||||
|
||||
After looking at many systems and software on the market, the team found no server system designed for home scenarios, sadly true.
|
||||
|
||||
So, we set out to build this open source project to develop CasaOS with our own hands, everyone in the community, and you.
|
||||
So, we set out to build this open-source project to develop CasaOS with our own hands, everyone in the community, and you.
|
||||
|
||||
> A warm welcome for you to share and discuss your great ideas in the [Discord server](https://discord.gg/knqAbbBbeX)!
|
||||
We believe that through community-driven collaborative innovation and open communication with global developers, we can reshape the digital home experience like never before.
|
||||
|
||||
**A warm welcome for you to get help or share great ideas in the [Discord](https://discord.gg/knqAbbBbeX)!**
|
||||
|
||||
[](https://discord.gg/knqAbbBbeX)
|
||||
|
||||
## Contributing
|
||||
|
||||
CasaOS is a community-driven open source project and the people involved are CasaOS users. That means CasaOS will always need contributions from community members just like you!
|
||||
|
||||
- See <https://wiki.casaos.io/en/contribute> for ways of contributing to CasaOS
|
||||
- See <https://wiki.casaos.io/en/contribute/development> if you want to be involved in code contribution specifically
|
||||
|
||||
## Donate
|
||||
<p ><a href="https://www.buymeacoffee.com/icewhaletech"> <img align="center" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="bappi2097" target="_blank" /></a></p>
|
||||
|
||||
|
||||
## Maintainers
|
||||
- Jerry Liu
|
||||
- Link Liang
|
||||
- Ober Zhang
|
||||
- Zyaire Ann
|
||||
- John Guan
|
||||
- Right here, waiting for YOU!
|
||||
## Credits
|
||||
|
||||
Many thanks to everyone who has helped CasaOS so far!
|
||||
|
||||
Everyone's contribution is greatly appreciated. ([Emoji Key](https://allcontributors.org/docs/en/emoji-key))
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/jerrykuku"><img src="https://avatars.githubusercontent.com/u/9485680?v=4?s=100" width="100px;" alt=""/><br /><sub><b>老竭力</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=jerrykuku" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=jerrykuku" title="Documentation">📖</a> <a href="#ideas-jerrykuku" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-jerrykuku" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-jerrykuku" title="Maintenance">🚧</a> <a href="#platform-jerrykuku" title="Packaging/porting to new platform">📦</a> <a href="#question-jerrykuku" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3Ajerrykuku" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/LinkLeong"><img src="https://avatars.githubusercontent.com/u/13556972?v=4?s=100" width="100px;" alt=""/><br /><sub><b>link</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=LinkLeong" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=LinkLeong" title="Documentation">📖</a> <a href="#ideas-LinkLeong" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-LinkLeong" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-LinkLeong" title="Maintenance">🚧</a> <a href="#question-LinkLeong" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3ALinkLeong" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/tigerinus"><img src="https://avatars.githubusercontent.com/u/7172560?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tiger Wang (王豫)</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=tigerinus" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=tigerinus" title="Documentation">📖</a> <a href="#ideas-tigerinus" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-tigerinus" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#maintenance-tigerinus" title="Maintenance">🚧</a> <a href="#mentoring-tigerinus" title="Mentoring">🧑🏫</a> <a href="#security-tigerinus" title="Security">🛡️</a> <a href="#question-tigerinus" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3Atigerinus" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://github.com/Lauren-ED209"><img src="https://avatars.githubusercontent.com/u/8243355?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lauren</b></sub></a><br /><a href="#ideas-Lauren-ED209" title="Ideas, Planning, & Feedback">🤔</a> <a href="#fundingFinding-Lauren-ED209" title="Funding Finding">🔍</a> <a href="#projectManagement-Lauren-ED209" title="Project Management">📆</a> <a href="#question-Lauren-ED209" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=Lauren-ED209" title="Tests">⚠️</a></td>
|
||||
<td align="center"><a href="https://JohnGuan.Cn"><img src="https://avatars.githubusercontent.com/u/3358477?v=4?s=100" width="100px;" alt=""/><br /><sub><b>John Guan</b></sub></a><br /><a href="#blog-JohnGuan" title="Blogposts">📝</a> <a href="#content-JohnGuan" title="Content">🖋</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=JohnGuan" title="Documentation">📖</a> <a href="#ideas-JohnGuan" title="Ideas, Planning, & Feedback">🤔</a> <a href="#eventOrganizing-JohnGuan" title="Event Organizing">📋</a> <a href="#mentoring-JohnGuan" title="Mentoring">🧑🏫</a> <a href="#question-JohnGuan" title="Answering Questions">💬</a> <a href="https://github.com/IceWhaleTech/CasaOS/pulls?q=is%3Apr+reviewed-by%3AJohnGuan" title="Reviewed Pull Requests">👀</a></td>
|
||||
<td align="center"><a href="https://blog.tippybits.com"><img src="https://avatars.githubusercontent.com/u/17506770?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Tippett</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=dtaivpp" title="Documentation">📖</a> <a href="#ideas-dtaivpp" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-dtaivpp" title="Answering Questions">💬</a></td>
|
||||
<td align="center"><a href="https://github.com/zarevskaya"><img src="https://avatars.githubusercontent.com/u/60230221?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Skaya</b></sub></a><br /><a href="#mentoring-zarevskaya" title="Mentoring">🧑🏫</a> <a href="#question-zarevskaya" title="Answering Questions">💬</a> <a href="#tutorial-zarevskaya" title="Tutorials">✅</a> <a href="#translation-zarevskaya" title="Translation">🌍</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/AuthorShin"><img src="https://avatars.githubusercontent.com/u/4959043?v=4?s=100" width="100px;" alt=""/><br /><sub><b>AuthorShin</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=AuthorShin" title="Tests">⚠️</a> <a href="https://github.com/IceWhaleTech/CasaOS/issues?q=author%3AAuthorShin" title="Bug reports">🐛</a> <a href="#question-AuthorShin" title="Answering Questions">💬</a> <a href="#ideas-AuthorShin" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/baptiste313"><img src="https://avatars.githubusercontent.com/u/93325157?v=4?s=100" width="100px;" alt=""/><br /><sub><b>baptiste313</b></sub></a><br /><a href="#translation-baptiste313" title="Translation">🌍</a></td>
|
||||
<td align="center"><a href="https://github.com/DrMxrcy"><img src="https://avatars.githubusercontent.com/u/58747968?v=4?s=100" width="100px;" alt=""/><br /><sub><b>DrMxrcy</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=DrMxrcy" title="Tests">⚠️</a> <a href="#ideas-DrMxrcy" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-DrMxrcy" title="Answering Questions">💬</a></td>
|
||||
<td align="center"><a href="https://github.com/Joooost"><img src="https://avatars.githubusercontent.com/u/12090673?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joooost</b></sub></a><br /><a href="#ideas-Joooost" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://potyarkin.ml"><img src="https://avatars.githubusercontent.com/u/334908?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vitaly Potyarkin</b></sub></a><br /><a href="#ideas-sio" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/bearfrieze"><img src="https://avatars.githubusercontent.com/u/1023813?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bjørn Friese</b></sub></a><br /><a href="#ideas-bearfrieze" title="Ideas, Planning, & Feedback">🤔</a></td>
|
||||
<td align="center"><a href="https://github.com/Protektor-Desura"><img src="https://avatars.githubusercontent.com/u/1195496?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Protektor</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/issues?q=author%3AProtektor-Desura" title="Bug reports">🐛</a> <a href="#ideas-Protektor-Desura" title="Ideas, Planning, & Feedback">🤔</a> <a href="#question-Protektor-Desura" title="Answering Questions">💬</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/llwaini"><img src="https://avatars.githubusercontent.com/u/59589857?v=4?s=100" width="100px;" alt=""/><br /><sub><b>llwaini</b></sub></a><br /><a href="#projectManagement-llwaini" title="Project Management">📆</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=llwaini" title="Tests">⚠️</a> <a href="#tutorial-llwaini" title="Tutorials">✅</a></td>
|
||||
<td align="center"><a href="https://github.com/CorrectRoadH"><img src="https://avatars.githubusercontent.com/u/29306285?v=4?s=100" width="100px;" alt=""/><br /><sub><b>CorrectRoadH</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=correctroadh" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=correctroadh" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://github.com/zhanghengxin"><img src="https://avatars.githubusercontent.com/u/24197448?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zhanghengxin</b></sub></a><br /><a href="https://github.com/IceWhaleTech/CasaOS/commits?author=zhanghengxin" title="Code">💻</a> <a href="https://github.com/IceWhaleTech/CasaOS/commits?author=zhanghengxin" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!
|
||||
|
||||
## Changelog
|
||||
|
||||
Detailed changes for each release are documented in the [release notes](https://github.com/IceWhaleTech/CasaOS/releases).
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<a href="https://dashboard.trackgit.com/token/l5q8egi92tfhlxd70l2l">
|
||||
<img src="https://us-central1-trackgit-analytics.cloudfunctions.net/token/ping/l5q8egi92tfhlxd70l2l" alt="trackgit-views" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
9
SECURITY.md
Normal file
9
SECURITY.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
CasaOS is currently under active development. Support is limited before CasaOS reaches v1.0.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you see any vulnerabiility, email us at wiki@casaos.io
|
||||
1
UI
1
UI
Submodule UI deleted from f3088b6354
235
api/casaos/openapi.yaml
Normal file
235
api/casaos/openapi.yaml
Normal file
@@ -0,0 +1,235 @@
|
||||
openapi: 3.0.3
|
||||
|
||||
info:
|
||||
title: CasaOS API
|
||||
version: v2
|
||||
description: |
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_dark_night_800px.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800px.png">
|
||||
<img alt="CasaOS" src="https://raw.githubusercontent.com/IceWhaleTech/logo/main/casaos/casaos_banner_twilight_blue_800px.png">
|
||||
</picture>
|
||||
|
||||
CasaOS API provides miscellaneous methods for different scenarios.
|
||||
|
||||
For issues and discussions, please visit the [GitHub repository](https://github.com/IceWhaleTech/CasaOS) or join [our Discord](https://discord.gg/knqAbbBbeX).
|
||||
|
||||
servers:
|
||||
- url: /v2/casaos
|
||||
|
||||
tags:
|
||||
- name: Health methods
|
||||
description: |-
|
||||
(TODO)
|
||||
- name: File methods
|
||||
description: |-
|
||||
(TODO)
|
||||
|
||||
x-tagGroups:
|
||||
- name: Methods
|
||||
tags:
|
||||
- Health methods
|
||||
|
||||
security:
|
||||
- access_token: []
|
||||
|
||||
paths:
|
||||
/health/services:
|
||||
get:
|
||||
tags:
|
||||
- Health methods
|
||||
summary: Get service status
|
||||
description: |-
|
||||
Get running status of each `casaos-*` service.
|
||||
operationId: getHealthServices
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetHealthServicesOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/health/ports:
|
||||
get:
|
||||
tags:
|
||||
- Health methods
|
||||
summary: Get port in use
|
||||
operationId: getHealthPorts
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetHealthPortsOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
/health/logs:
|
||||
get:
|
||||
tags:
|
||||
- Health methods
|
||||
summary: Get log
|
||||
operationId: getHealthlogs
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
content:
|
||||
application/octet-stream:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/file/test:
|
||||
get:
|
||||
tags:
|
||||
- File methods
|
||||
summary: Test file methods
|
||||
description: |-
|
||||
Test file methods.
|
||||
operationId: getFileTest
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ResponseOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
/zt/info:
|
||||
get:
|
||||
tags:
|
||||
- Zerotier methods
|
||||
summary: Get Zerotier info
|
||||
description: |-
|
||||
Get Zerotier info.
|
||||
operationId: getZerotierInfo
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetZTInfoOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
/zt/{network_id}/status:
|
||||
put:
|
||||
tags:
|
||||
- Zerotier methods
|
||||
summary: Set Zerotier network status
|
||||
description: |-
|
||||
Set Zerotier network status.
|
||||
operationId: setZerotierNetworkStatus
|
||||
parameters:
|
||||
- name: network_id
|
||||
in: path
|
||||
description: network id
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
enum:
|
||||
- online
|
||||
- offline
|
||||
type: string
|
||||
example: "online"
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/GetZTInfoOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
access_token:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: Authorization
|
||||
|
||||
responses:
|
||||
ResponseOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BaseResponse"
|
||||
|
||||
ResponseInternalServerError:
|
||||
description: Internal Server Error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/BaseResponse"
|
||||
|
||||
GetHealthServicesOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/BaseResponse"
|
||||
- properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/HealthServices"
|
||||
|
||||
GetHealthPortsOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: "#/components/schemas/BaseResponse"
|
||||
- properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/HealthPorts"
|
||||
GetZTInfoOK:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ZTInfo"
|
||||
|
||||
|
||||
schemas:
|
||||
BaseResponse:
|
||||
properties:
|
||||
message:
|
||||
readOnly: true
|
||||
description: message returned by server side if there is any
|
||||
type: string
|
||||
example: ""
|
||||
|
||||
HealthServices:
|
||||
properties:
|
||||
running:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: "casaos-gateway.service"
|
||||
not_running:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
example: "casaos.service"
|
||||
|
||||
HealthPorts:
|
||||
properties:
|
||||
tcp:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
example: 80
|
||||
x-go-name: TCP
|
||||
udp:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
example: 53
|
||||
x-go-name: UDP
|
||||
ZTInfo:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
example: "1234567890"
|
||||
name:
|
||||
type: string
|
||||
example: "CasaOS"
|
||||
status:
|
||||
type: string
|
||||
example: "online"
|
||||
24
api/index.html
Normal file
24
api/index.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>CasaOS | Developers</title>
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<redoc spec-url='casaos/openapi.yaml' expandResponses='all' jsonSampleExpandLevel='all'></redoc>
|
||||
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"> </script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
194
build/scripts/migration/script.d/03-migrate-casaos.sh
Normal file
194
build/scripts/migration/script.d/03-migrate-casaos.sh
Normal file
@@ -0,0 +1,194 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# functions
|
||||
__info() {
|
||||
echo -e "🟩 ${1}"
|
||||
}
|
||||
|
||||
__info_done() {
|
||||
echo -e "✅ ${1}"
|
||||
}
|
||||
|
||||
__warning() {
|
||||
echo -e "🟨 ${1}"
|
||||
}
|
||||
|
||||
__error() {
|
||||
echo "🟥 ${1}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
__is_version_gt() {
|
||||
test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"
|
||||
}
|
||||
__normalize_version() {
|
||||
local version
|
||||
if [ "${1::1}" = "v" ]; then
|
||||
version="${1:1}"
|
||||
else
|
||||
version="${1}"
|
||||
fi
|
||||
|
||||
echo "$version"
|
||||
}
|
||||
|
||||
__is_migration_needed() {
|
||||
local version1
|
||||
local version2
|
||||
|
||||
version1=$(__normalize_version "${1}")
|
||||
version2=$(__normalize_version "${2}")
|
||||
|
||||
if [ "${version1}" = "${version2}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "CURRENT_VERSION_NOT_FOUND" = "${version1}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "LEGACY_WITHOUT_VERSION" = "${version1}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
__is_version_gt "${version2}" "${version1}"
|
||||
}
|
||||
|
||||
__get_download_domain(){
|
||||
local region
|
||||
# Use ipconfig.io/country and https://ifconfig.io/country_code to get the country code
|
||||
region=$(curl --connect-timeout 2 -s ipconfig.io/country || echo "")
|
||||
if [ "${region}" = "" ]; then
|
||||
region=$(curl --connect-timeout 2 -s https://ifconfig.io/country_code || echo "")
|
||||
fi
|
||||
if [[ "${region}" = "China" ]] || [[ "${region}" = "CN" ]]; then
|
||||
echo "https://casaos.oss-cn-shanghai.aliyuncs.com/"
|
||||
else
|
||||
echo "https://github.com/"
|
||||
fi
|
||||
}
|
||||
|
||||
DOWNLOAD_DOMAIN=$(__get_download_domain)
|
||||
|
||||
BUILD_PATH=$(dirname "${BASH_SOURCE[0]}")/../../..
|
||||
SOURCE_ROOT=${BUILD_PATH}/sysroot
|
||||
|
||||
APP_NAME="casaos"
|
||||
|
||||
# check if migration is needed
|
||||
SOURCE_BIN_PATH=${SOURCE_ROOT}/usr/bin
|
||||
SOURCE_BIN_FILE=${SOURCE_BIN_PATH}/${APP_NAME}
|
||||
|
||||
CURRENT_BIN_PATH=/usr/bin
|
||||
CURRENT_BIN_PATH_LEGACY=/usr/local/bin
|
||||
CURRENT_BIN_FILE=${CURRENT_BIN_PATH}/${APP_NAME}
|
||||
CURRENT_BIN_FILE_LEGACY=$(realpath -e ${CURRENT_BIN_PATH_LEGACY}/${APP_NAME} || which ${APP_NAME} || echo CURRENT_BIN_FILE_LEGACY_NOT_FOUND)
|
||||
|
||||
SOURCE_VERSION="$(${SOURCE_BIN_FILE} -v)"
|
||||
CURRENT_VERSION="$(${CURRENT_BIN_FILE} -v || ${CURRENT_BIN_FILE_LEGACY} -v || (stat "${CURRENT_BIN_FILE_LEGACY}" >/dev/null && echo LEGACY_WITHOUT_VERSION) || echo CURRENT_VERSION_NOT_FOUND)"
|
||||
|
||||
__info_done "CURRENT_VERSION: ${CURRENT_VERSION}"
|
||||
__info_done "SOURCE_VERSION: ${SOURCE_VERSION}"
|
||||
|
||||
NEED_MIGRATION=$(__is_migration_needed "${CURRENT_VERSION}" "${SOURCE_VERSION}" && echo "true" || echo "false")
|
||||
|
||||
if [ "${NEED_MIGRATION}" = "false" ]; then
|
||||
__info_done "Migration is not needed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ARCH="unknown"
|
||||
|
||||
case $(uname -m) in
|
||||
x86_64)
|
||||
ARCH="amd64"
|
||||
;;
|
||||
aarch64)
|
||||
ARCH="arm64"
|
||||
;;
|
||||
armv7l)
|
||||
ARCH="arm-7"
|
||||
;;
|
||||
*)
|
||||
__error "Unsupported architecture"
|
||||
;;
|
||||
esac
|
||||
|
||||
__info "ARCH: ${ARCH}"
|
||||
|
||||
MIGRATION_SERVICE_DIR=${1}
|
||||
|
||||
if [ -z "${MIGRATION_SERVICE_DIR}" ]; then
|
||||
MIGRATION_SERVICE_DIR=${BUILD_PATH}/scripts/migration/service.d/${APP_NAME}
|
||||
fi
|
||||
MIGRATION_LIST_FILE=${MIGRATION_SERVICE_DIR}/migration.list
|
||||
MIGRATION_PATH=()
|
||||
|
||||
CURRENT_VERSION_FOUND="false"
|
||||
|
||||
# a VERSION_PAIR looks like "v0.3.5 <url>"
|
||||
#
|
||||
# - "v0.3.5" is the current version installed on this host
|
||||
# - "<url>" is the url of the migration tool
|
||||
while read -r VERSION_PAIR; do
|
||||
if [ -z "${VERSION_PAIR}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# obtain "v0.3.5" from "v0.3.5 v0.3.6-alpha2"
|
||||
VER1=$(echo "${VERSION_PAIR}" | cut -d' ' -f1)
|
||||
|
||||
# obtain "<url>" from "v0.3.5 <url>"
|
||||
URL=$(eval echo "${VERSION_PAIR}" | cut -d' ' -f2)
|
||||
|
||||
if [ "${CURRENT_VERSION}" = "${VER1// /}" ] || [ "${CURRENT_VERSION}" = "LEGACY_WITHOUT_VERSION" ]; then
|
||||
CURRENT_VERSION_FOUND="true"
|
||||
fi
|
||||
|
||||
if [ "${CURRENT_VERSION_FOUND}" = "true" ]; then
|
||||
MIGRATION_PATH+=("${URL// /}")
|
||||
fi
|
||||
done <"${MIGRATION_LIST_FILE}"
|
||||
|
||||
if [ ${#MIGRATION_PATH[@]} -eq 0 ]; then
|
||||
__warning "No migration path found from ${CURRENT_VERSION} to ${SOURCE_VERSION}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
pushd "${MIGRATION_SERVICE_DIR}"
|
||||
|
||||
{
|
||||
for URL in "${MIGRATION_PATH[@]}"; do
|
||||
MIGRATION_TOOL_FILE=$(basename "${URL}")
|
||||
|
||||
if [ -f "${MIGRATION_TOOL_FILE}" ]; then
|
||||
__info "Migration tool ${MIGRATION_TOOL_FILE} exists. Skip downloading."
|
||||
continue
|
||||
fi
|
||||
|
||||
__info "Dowloading ${URL}..."
|
||||
curl -fsSL -o "${MIGRATION_TOOL_FILE}" -O "${URL}"
|
||||
done
|
||||
} || {
|
||||
popd
|
||||
__error "Failed to download migration tools"
|
||||
}
|
||||
|
||||
{
|
||||
for URL in "${MIGRATION_PATH[@]}"; do
|
||||
MIGRATION_TOOL_FILE=$(basename "${URL}")
|
||||
__info "Extracting ${MIGRATION_TOOL_FILE}..."
|
||||
tar zxvf "${MIGRATION_TOOL_FILE}" || __error "Failed to extract ${MIGRATION_TOOL_FILE}"
|
||||
|
||||
MIGRATION_TOOL_PATH=build/sysroot/usr/bin/${APP_NAME}-migration-tool
|
||||
__info "Running ${MIGRATION_TOOL_PATH}..."
|
||||
${MIGRATION_TOOL_PATH}
|
||||
done
|
||||
} || {
|
||||
popd
|
||||
__error "Failed to extract and run migration tools"
|
||||
}
|
||||
|
||||
popd
|
||||
3
build/scripts/migration/service.d/casaos/migration.list
Normal file
3
build/scripts/migration/service.d/casaos/migration.list
Normal file
@@ -0,0 +1,3 @@
|
||||
LEGACY_WITHOUT_VERSION ${DOWNLOAD_DOMAIN}IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz
|
||||
v0.3.5 ${DOWNLOAD_DOMAIN}IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz
|
||||
v0.3.5.1 ${DOWNLOAD_DOMAIN}IceWhaleTech/CasaOS/releases/download/v0.3.6/linux-${ARCH}-casaos-migration-tool-v0.3.6.tar.gz
|
||||
56
build/scripts/setup/script.d/03-setup-casaos.sh
Executable file
56
build/scripts/setup/script.d/03-setup-casaos.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
BUILD_PATH=$(dirname "${BASH_SOURCE[0]}")/../../..
|
||||
|
||||
APP_NAME_SHORT=casaos
|
||||
|
||||
__get_setup_script_directory_by_os_release() {
|
||||
pushd "$(dirname "${BASH_SOURCE[0]}")/../service.d/${APP_NAME_SHORT}" >/dev/null
|
||||
|
||||
{
|
||||
# shellcheck source=/dev/null
|
||||
{
|
||||
source /etc/os-release
|
||||
{
|
||||
pushd "${ID}"/"${VERSION_CODENAME}" >/dev/null
|
||||
} || {
|
||||
pushd "${ID}" >/dev/null
|
||||
} || {
|
||||
[[ -n ${ID_LIKE} ]] && for ID in ${ID_LIKE}; do
|
||||
pushd "${ID}" >/dev/null && break
|
||||
done
|
||||
} || {
|
||||
echo "Unsupported OS: ${ID} ${VERSION_CODENAME} (${ID_LIKE})"
|
||||
exit 1
|
||||
}
|
||||
|
||||
pwd
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
} || {
|
||||
echo "Unsupported OS: unknown"
|
||||
exit 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
popd >/dev/null
|
||||
}
|
||||
|
||||
SETUP_SCRIPT_DIRECTORY=$(__get_setup_script_directory_by_os_release)
|
||||
SETUP_SCRIPT_FILENAME="setup-${APP_NAME_SHORT}.sh"
|
||||
|
||||
SETUP_SCRIPT_FILEPATH="${SETUP_SCRIPT_DIRECTORY}/${SETUP_SCRIPT_FILENAME}"
|
||||
|
||||
{
|
||||
echo "🟩 Running ${SETUP_SCRIPT_FILENAME}..."
|
||||
$BASH "${SETUP_SCRIPT_FILEPATH}" "${BUILD_PATH}"
|
||||
} || {
|
||||
echo "🟥 ${SETUP_SCRIPT_FILENAME} failed."
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "✅ ${SETUP_SCRIPT_FILENAME} finished."
|
||||
40
build/scripts/setup/service.d/casaos/arch/setup-casaos.sh
Normal file
40
build/scripts/setup/service.d/casaos/arch/setup-casaos.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
###
|
||||
# @Author: LinkLeong link@icewhale.org
|
||||
# @Date: 2022-08-25 11:41:22
|
||||
# @LastEditors: LinkLeong
|
||||
# @LastEditTime: 2022-08-31 17:54:17
|
||||
# @FilePath: /CasaOS/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh
|
||||
# @Description:
|
||||
|
||||
# @Website: https://www.casaos.io
|
||||
# Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
###
|
||||
|
||||
set -e
|
||||
|
||||
APP_NAME="casaos"
|
||||
|
||||
# copy config files
|
||||
CONF_PATH=/etc/casaos
|
||||
OLD_CONF_PATH=/etc/casaos.conf
|
||||
CONF_FILE=${CONF_PATH}/${APP_NAME}.conf
|
||||
CONF_FILE_SAMPLE=${CONF_PATH}/${APP_NAME}.conf.sample
|
||||
|
||||
|
||||
if [ -f "${OLD_CONF_PATH}" ]; then
|
||||
echo "copy old conf"
|
||||
cp "${OLD_CONF_PATH}" "${CONF_FILE}"
|
||||
fi
|
||||
if [ ! -f "${CONF_FILE}" ]; then
|
||||
echo "Initializing config file..."
|
||||
cp -v "${CONF_FILE_SAMPLE}" "${CONF_FILE}"
|
||||
fi
|
||||
|
||||
rm -rf /etc/systemd/system/casaos.service # remove old service file
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# enable service (without starting)
|
||||
echo "Enabling service..."
|
||||
systemctl enable --force --no-ask-password "${APP_NAME}.service"
|
||||
@@ -0,0 +1 @@
|
||||
../setup-casaos.sh
|
||||
40
build/scripts/setup/service.d/casaos/debian/setup-casaos.sh
Normal file
40
build/scripts/setup/service.d/casaos/debian/setup-casaos.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
###
|
||||
# @Author: LinkLeong link@icewhale.org
|
||||
# @Date: 2022-08-25 11:41:22
|
||||
# @LastEditors: LinkLeong
|
||||
# @LastEditTime: 2022-08-31 17:54:17
|
||||
# @FilePath: /CasaOS/build/scripts/setup/service.d/casaos/debian/setup-casaos.sh
|
||||
# @Description:
|
||||
|
||||
# @Website: https://www.casaos.io
|
||||
# Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
###
|
||||
|
||||
set -e
|
||||
|
||||
APP_NAME="casaos"
|
||||
|
||||
# copy config files
|
||||
CONF_PATH=/etc/casaos
|
||||
OLD_CONF_PATH=/etc/casaos.conf
|
||||
CONF_FILE=${CONF_PATH}/${APP_NAME}.conf
|
||||
CONF_FILE_SAMPLE=${CONF_PATH}/${APP_NAME}.conf.sample
|
||||
|
||||
|
||||
if [ -f "${OLD_CONF_PATH}" ]; then
|
||||
echo "copy old conf"
|
||||
cp "${OLD_CONF_PATH}" "${CONF_FILE}"
|
||||
fi
|
||||
if [ ! -f "${CONF_FILE}" ]; then
|
||||
echo "Initializing config file..."
|
||||
cp -v "${CONF_FILE_SAMPLE}" "${CONF_FILE}"
|
||||
fi
|
||||
|
||||
rm -rf /etc/systemd/system/casaos.service # remove old service file
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
# enable service (without starting)
|
||||
echo "Enabling service..."
|
||||
systemctl enable --force --no-ask-password "${APP_NAME}.service"
|
||||
@@ -0,0 +1 @@
|
||||
../setup-casaos.sh
|
||||
1
build/scripts/setup/service.d/casaos/ubuntu/setup-casaos.sh
Symbolic link
1
build/scripts/setup/service.d/casaos/ubuntu/setup-casaos.sh
Symbolic link
@@ -0,0 +1 @@
|
||||
../debian/setup-casaos.sh
|
||||
22
build/sysroot/etc/casaos/casaos.conf.sample
Normal file
22
build/sysroot/etc/casaos/casaos.conf.sample
Normal file
@@ -0,0 +1,22 @@
|
||||
[app]
|
||||
PAGE_SIZE = 10
|
||||
RuntimeRootPath = runtime/
|
||||
LogPath = /var/log/casaos/
|
||||
LogSaveName = log
|
||||
LogFileExt = log
|
||||
DateStrFormat = 20060102
|
||||
DateTimeFormat = 2006-01-02 15:04:05
|
||||
TimeFormat = 15:04:05
|
||||
DateFormat = 2006-01-02
|
||||
DBPath = /var/lib/casaos
|
||||
ShellPath = /usr/share/casaos/shell
|
||||
UserDataPath = /var/lib/casaos/conf
|
||||
|
||||
[server]
|
||||
RunMode = release
|
||||
ServerApi = https://api.casaos.io/casaos-api
|
||||
Handshake = socket.casaos.io
|
||||
Token =
|
||||
USBAutoMount =
|
||||
|
||||
[system]
|
||||
13
build/sysroot/usr/lib/systemd/system/casaos.service
Normal file
13
build/sysroot/usr/lib/systemd/system/casaos.service
Normal file
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
After=casaos-message-bus.service
|
||||
After=rclone.service
|
||||
Description=CasaOS Main Service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/casaos -c /etc/casaos/casaos.conf
|
||||
PIDFile=/var/run/casaos/casaos.pid
|
||||
Restart=always
|
||||
Type=notify
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
12
build/sysroot/usr/lib/systemd/system/rclone.service
Normal file
12
build/sysroot/usr/lib/systemd/system/rclone.service
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=rclone
|
||||
|
||||
[Service]
|
||||
ExecStartPre=/usr/bin/mkdir -p /var/run/rclone
|
||||
ExecStartPre=/usr/bin/rm -f /var/run/rclone/rclone.sock
|
||||
ExecStart=/usr/bin/rclone rcd --rc-addr unix:///var/run/rclone/rclone.sock --rc-no-auth --rc-allow-origin "*"
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
###
|
||||
# @Author: LinkLeong link@icewhale.org
|
||||
# @Date: 2022-11-15 15:51:44
|
||||
# @LastEditors: LinkLeong
|
||||
# @LastEditTime: 2022-11-15 15:53:37
|
||||
# @FilePath: /CasaOS/build/sysroot/usr/share/casaos/cleanup/script.d/03-cleanup-casaos.sh
|
||||
# @Description:
|
||||
# @Website: https://www.casaos.io
|
||||
# Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
###
|
||||
|
||||
set -e
|
||||
|
||||
readonly APP_NAME_SHORT=casaos
|
||||
|
||||
__get_setup_script_directory_by_os_release() {
|
||||
pushd "$(dirname "${BASH_SOURCE[0]}")/../service.d/${APP_NAME_SHORT}" &>/dev/null
|
||||
|
||||
{
|
||||
# shellcheck source=/dev/null
|
||||
{
|
||||
source /etc/os-release
|
||||
{
|
||||
pushd "${ID}"/"${VERSION_CODENAME}" &>/dev/null
|
||||
} || {
|
||||
pushd "${ID}" &>/dev/null
|
||||
} || {
|
||||
[[ -n ${ID_LIKE} ]] && for ID in ${ID_LIKE}; do
|
||||
pushd "${ID}" >/dev/null && break
|
||||
done
|
||||
} || {
|
||||
echo "Unsupported OS: ${ID} ${VERSION_CODENAME} (${ID_LIKE})"
|
||||
exit 1
|
||||
}
|
||||
|
||||
pwd
|
||||
|
||||
popd &>/dev/null
|
||||
|
||||
} || {
|
||||
echo "Unsupported OS: unknown"
|
||||
exit 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
popd &>/dev/null
|
||||
}
|
||||
|
||||
SETUP_SCRIPT_DIRECTORY=$(__get_setup_script_directory_by_os_release)
|
||||
|
||||
readonly SETUP_SCRIPT_DIRECTORY
|
||||
readonly SETUP_SCRIPT_FILENAME="cleanup-${APP_NAME_SHORT}.sh"
|
||||
readonly SETUP_SCRIPT_FILEPATH="${SETUP_SCRIPT_DIRECTORY}/${SETUP_SCRIPT_FILENAME}"
|
||||
|
||||
echo "🟩 Running ${SETUP_SCRIPT_FILENAME}..."
|
||||
$SHELL "${SETUP_SCRIPT_FILEPATH}" "${BUILD_PATH}"
|
||||
@@ -0,0 +1,204 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
readonly CASA_SERVICES=(
|
||||
"casaos.service"
|
||||
"devmon@devmon.service"
|
||||
)
|
||||
|
||||
readonly CASA_EXEC=casaos
|
||||
readonly CASA_CONF=/etc/casaos/casaos.conf
|
||||
readonly CASA_URL=/var/run/casaos/casaos.url
|
||||
readonly CASA_SERVICE_USR=/usr/lib/systemd/system/casaos.service
|
||||
readonly CASA_SERVICE_LIB=/lib/systemd/system/casaos.service
|
||||
readonly CASA_SERVICE_ETC=/etc/systemd/system/casaos.service
|
||||
|
||||
# Old Casa Files
|
||||
readonly CASA_PATH=/casaOS
|
||||
readonly CASA_CONF_PATH_OLD=/etc/casaos.conf
|
||||
|
||||
readonly aCOLOUR=(
|
||||
'\e[38;5;154m' # green | Lines, bullets and separators
|
||||
'\e[1m' # Bold white | Main descriptions
|
||||
'\e[90m' # Grey | Credits
|
||||
'\e[91m' # Red | Update notifications Alert
|
||||
'\e[33m' # Yellow | Emphasis
|
||||
)
|
||||
|
||||
Show() {
|
||||
# OK
|
||||
if (($1 == 0)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} OK $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# FAILED
|
||||
elif (($1 == 1)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]}FAILED$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# INFO
|
||||
elif (($1 == 2)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} INFO $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# NOTICE
|
||||
elif (($1 == 3)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]}NOTICE$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
fi
|
||||
}
|
||||
|
||||
Warn() {
|
||||
echo -e "${aCOLOUR[3]}$1$COLOUR_RESET"
|
||||
}
|
||||
|
||||
trap 'onCtrlC' INT
|
||||
onCtrlC() {
|
||||
echo -e "${COLOUR_RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Detecting_CasaOS() {
|
||||
if [[ ! -x "$(command -v ${CASA_EXEC})" ]]; then
|
||||
Show 2 "CasaOS is not detected, exit the script."
|
||||
exit 1
|
||||
else
|
||||
Show 0 "This script will delete the containers you no longer use, and the CasaOS configuration files."
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_Container() {
|
||||
if [[ ${UNINSTALL_ALL_CONTAINER} == true && "$(docker ps -aq)" != "" ]]; then
|
||||
Show 2 "Start deleting containers."
|
||||
docker stop "$(docker ps -aq)" || Show 1 "Failed to stop all containers."
|
||||
docker rm "$(docker ps -aq)" || Show 1 "Failed to delete all containers."
|
||||
fi
|
||||
}
|
||||
|
||||
Remove_Images() {
|
||||
if [[ ${REMOVE_IMAGES} == "all" && "$(docker images -q)" != "" ]]; then
|
||||
Show 2 "Start deleting all images."
|
||||
docker rmi "$(docker images -q)" || Show 1 "Failed to delete all images."
|
||||
elif [[ ${REMOVE_IMAGES} == "unuse" && "$(docker images -q)" != "" ]]; then
|
||||
Show 2 "Start deleting unuse images."
|
||||
docker image prune -af || Show 1 "Failed to delete unuse images."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Uninstall_Casaos() {
|
||||
|
||||
for SERVICE in "${CASA_SERVICES[@]}"; do
|
||||
Show 2 "Stopping ${SERVICE}..."
|
||||
systemctl disable --now "${SERVICE}" || Show 3 "Failed to disable ${SERVICE}"
|
||||
done
|
||||
|
||||
# Remove Service file
|
||||
if [[ -f ${CASA_SERVICE_USR} ]]; then
|
||||
rm -rvf ${CASA_SERVICE_USR}
|
||||
fi
|
||||
|
||||
if [[ -f ${CASA_SERVICE_LIB} ]]; then
|
||||
rm -rvf ${CASA_SERVICE_LIB}
|
||||
fi
|
||||
|
||||
if [[ -f ${CASA_SERVICE_ETC} ]]; then
|
||||
rm -rvf ${CASA_SERVICE_ETC}
|
||||
fi
|
||||
|
||||
# Old Casa Files
|
||||
if [[ -d ${CASA_PATH} ]]; then
|
||||
rm -rvf ${CASA_PATH} || Show 1 "Failed to delete legacy CasaOS files."
|
||||
fi
|
||||
|
||||
if [[ -f ${CASA_CONF_PATH_OLD} ]]; then
|
||||
rm -rvf ${CASA_CONF_PATH_OLD}
|
||||
fi
|
||||
|
||||
# New Casa Files
|
||||
if [[ ${REMOVE_APP_DATA} = true ]]; then
|
||||
rm -rvf /DATA/AppData || Show 1 "Failed to delete AppData."
|
||||
fi
|
||||
|
||||
rm -rvf "$(which ${CASA_EXEC})" || Show 3 "Failed to remove ${CASA_EXEC}"
|
||||
rm -rvf ${CASA_CONF} || Show 3 "Failed to remove ${CASA_CONF}"
|
||||
rm -rvf ${CASA_URL} || Show 3 "Failed to remove ${CASA_URL}"
|
||||
|
||||
rm -rvf /var/lib/casaos/app_category.json
|
||||
rm -rvf /var/lib/casaos/app_list.json
|
||||
rm -rvf /var/lib/casaos/docker_root
|
||||
}
|
||||
|
||||
Detecting_CasaOS
|
||||
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want delete all containers? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
UNINSTALL_ALL_CONTAINER=true
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
UNINSTALL_ALL_CONTAINER=false
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ${UNINSTALL_ALL_CONTAINER} == true ]]; then
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want delete all images? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
REMOVE_IMAGES="all"
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
REMOVE_IMAGES="none"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want delete all AppData of CasaOS? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
REMOVE_APP_DATA=true
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
REMOVE_APP_DATA=false
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want to delete all images that are not used by the container? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
REMOVE_IMAGES="unuse"
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
REMOVE_IMAGES="none"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
Uninstall_Container
|
||||
Remove_Images
|
||||
Uninstall_Casaos
|
||||
@@ -0,0 +1 @@
|
||||
../cleanup-casaos.sh
|
||||
@@ -0,0 +1,204 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
readonly CASA_SERVICES=(
|
||||
"casaos.service"
|
||||
"devmon@devmon.service"
|
||||
)
|
||||
|
||||
readonly CASA_EXEC=casaos
|
||||
readonly CASA_CONF=/etc/casaos/casaos.conf
|
||||
readonly CASA_URL=/var/run/casaos/casaos.url
|
||||
readonly CASA_SERVICE_USR=/usr/lib/systemd/system/casaos.service
|
||||
readonly CASA_SERVICE_LIB=/lib/systemd/system/casaos.service
|
||||
readonly CASA_SERVICE_ETC=/etc/systemd/system/casaos.service
|
||||
|
||||
# Old Casa Files
|
||||
readonly CASA_PATH=/casaOS
|
||||
readonly CASA_CONF_PATH_OLD=/etc/casaos.conf
|
||||
|
||||
readonly aCOLOUR=(
|
||||
'\e[38;5;154m' # green | Lines, bullets and separators
|
||||
'\e[1m' # Bold white | Main descriptions
|
||||
'\e[90m' # Grey | Credits
|
||||
'\e[91m' # Red | Update notifications Alert
|
||||
'\e[33m' # Yellow | Emphasis
|
||||
)
|
||||
|
||||
Show() {
|
||||
# OK
|
||||
if (($1 == 0)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} OK $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# FAILED
|
||||
elif (($1 == 1)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]}FAILED$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# INFO
|
||||
elif (($1 == 2)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} INFO $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# NOTICE
|
||||
elif (($1 == 3)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]}NOTICE$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
fi
|
||||
}
|
||||
|
||||
Warn() {
|
||||
echo -e "${aCOLOUR[3]}$1$COLOUR_RESET"
|
||||
}
|
||||
|
||||
trap 'onCtrlC' INT
|
||||
onCtrlC() {
|
||||
echo -e "${COLOUR_RESET}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Detecting_CasaOS() {
|
||||
if [[ ! -x "$(command -v ${CASA_EXEC})" ]]; then
|
||||
Show 2 "CasaOS is not detected, exit the script."
|
||||
exit 1
|
||||
else
|
||||
Show 0 "This script will delete the containers you no longer use, and the CasaOS configuration files."
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_Container() {
|
||||
if [[ ${UNINSTALL_ALL_CONTAINER} == true && "$(docker ps -aq)" != "" ]]; then
|
||||
Show 2 "Start deleting containers."
|
||||
docker stop "$(docker ps -aq)" || Show 1 "Failed to stop all containers."
|
||||
docker rm "$(docker ps -aq)" || Show 1 "Failed to delete all containers."
|
||||
fi
|
||||
}
|
||||
|
||||
Remove_Images() {
|
||||
if [[ ${REMOVE_IMAGES} == "all" && "$(docker images -q)" != "" ]]; then
|
||||
Show 2 "Start deleting all images."
|
||||
docker rmi "$(docker images -q)" || Show 1 "Failed to delete all images."
|
||||
elif [[ ${REMOVE_IMAGES} == "unuse" && "$(docker images -q)" != "" ]]; then
|
||||
Show 2 "Start deleting unuse images."
|
||||
docker image prune -af || Show 1 "Failed to delete unuse images."
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Uninstall_Casaos() {
|
||||
|
||||
for SERVICE in "${CASA_SERVICES[@]}"; do
|
||||
Show 2 "Stopping ${SERVICE}..."
|
||||
systemctl disable --now "${SERVICE}" || Show 3 "Failed to disable ${SERVICE}"
|
||||
done
|
||||
|
||||
# Remove Service file
|
||||
if [[ -f ${CASA_SERVICE_USR} ]]; then
|
||||
rm -rvf ${CASA_SERVICE_USR}
|
||||
fi
|
||||
|
||||
if [[ -f ${CASA_SERVICE_LIB} ]]; then
|
||||
rm -rvf ${CASA_SERVICE_LIB}
|
||||
fi
|
||||
|
||||
if [[ -f ${CASA_SERVICE_ETC} ]]; then
|
||||
rm -rvf ${CASA_SERVICE_ETC}
|
||||
fi
|
||||
|
||||
# Old Casa Files
|
||||
if [[ -d ${CASA_PATH} ]]; then
|
||||
rm -rvf ${CASA_PATH} || Show 1 "Failed to delete legacy CasaOS files."
|
||||
fi
|
||||
|
||||
if [[ -f ${CASA_CONF_PATH_OLD} ]]; then
|
||||
rm -rvf ${CASA_CONF_PATH_OLD}
|
||||
fi
|
||||
|
||||
# New Casa Files
|
||||
if [[ ${REMOVE_APP_DATA} = true ]]; then
|
||||
rm -rvf /DATA/AppData || Show 1 "Failed to delete AppData."
|
||||
fi
|
||||
|
||||
rm -rvf "$(which ${CASA_EXEC})" || Show 3 "Failed to remove ${CASA_EXEC}"
|
||||
rm -rvf ${CASA_CONF} || Show 3 "Failed to remove ${CASA_CONF}"
|
||||
rm -rvf ${CASA_URL} || Show 3 "Failed to remove ${CASA_URL}"
|
||||
|
||||
rm -rvf /var/lib/casaos/app_category.json
|
||||
rm -rvf /var/lib/casaos/app_list.json
|
||||
rm -rvf /var/lib/casaos/docker_root
|
||||
}
|
||||
|
||||
Detecting_CasaOS
|
||||
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want delete all containers? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
UNINSTALL_ALL_CONTAINER=true
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
UNINSTALL_ALL_CONTAINER=false
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ${UNINSTALL_ALL_CONTAINER} == true ]]; then
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want delete all images? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
REMOVE_IMAGES="all"
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
REMOVE_IMAGES="none"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want delete all AppData of CasaOS? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
REMOVE_APP_DATA=true
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
REMOVE_APP_DATA=false
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
else
|
||||
while true; do
|
||||
echo -n -e " ${aCOLOUR[4]}Do you want to delete all images that are not used by the container? Y/n :${COLOUR_RESET}"
|
||||
read -r input
|
||||
case $input in
|
||||
[yY][eE][sS] | [yY])
|
||||
REMOVE_IMAGES="unuse"
|
||||
break
|
||||
;;
|
||||
[nN][oO] | [nN])
|
||||
REMOVE_IMAGES="none"
|
||||
break
|
||||
;;
|
||||
*)
|
||||
Warn " Invalid input..."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
|
||||
Uninstall_Container
|
||||
Remove_Images
|
||||
Uninstall_Casaos
|
||||
@@ -0,0 +1 @@
|
||||
../debian/cleanup-casaos.sh
|
||||
@@ -0,0 +1 @@
|
||||
../../debian/bullseye/cleanup-casaos.sh
|
||||
3
build/sysroot/usr/share/casaos/shell/assist.sh
Normal file
3
build/sysroot/usr/share/casaos/shell/assist.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
105
build/sysroot/usr/share/casaos/shell/delete-old-service.sh
Normal file
105
build/sysroot/usr/share/casaos/shell/delete-old-service.sh
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
###
|
||||
# @Author: LinkLeong link@icewhale.com
|
||||
# @Date: 2022-06-30 10:08:33
|
||||
# @LastEditors: LinkLeong
|
||||
# @LastEditTime: 2022-07-01 11:17:54
|
||||
# @FilePath: /CasaOS/shell/delete-old-service.sh
|
||||
# @Description:
|
||||
###
|
||||
|
||||
((EUID)) && sudo_cmd="sudo"
|
||||
|
||||
# SYSTEM INFO
|
||||
readonly UNAME_M="$(uname -m)"
|
||||
|
||||
# CasaOS PATHS
|
||||
readonly CASA_REPO=IceWhaleTech/CasaOS
|
||||
readonly CASA_UNZIP_TEMP_FOLDER=/tmp/casaos
|
||||
readonly CASA_BIN=casaos
|
||||
readonly CASA_BIN_PATH=/usr/bin/casaos
|
||||
readonly CASA_CONF_PATH=/etc/casaos.conf
|
||||
readonly CASA_SERVICE_PATH=/etc/systemd/system/casaos.service
|
||||
readonly CASA_HELPER_PATH=/usr/share/casaos/shell/
|
||||
readonly CASA_USER_CONF_PATH=/var/lib/casaos/conf/
|
||||
readonly CASA_DB_PATH=/var/lib/casaos/db/
|
||||
readonly CASA_TEMP_PATH=/var/lib/casaos/temp/
|
||||
readonly CASA_LOGS_PATH=/var/log/casaos/
|
||||
readonly CASA_PACKAGE_EXT=".tar.gz"
|
||||
readonly CASA_RELEASE_API="https://api.github.com/repos/${CASA_REPO}/releases"
|
||||
readonly CASA_OPENWRT_DOCS="https://github.com/IceWhaleTech/CasaOS-OpenWrt"
|
||||
|
||||
readonly COLOUR_RESET='\e[0m'
|
||||
readonly aCOLOUR=(
|
||||
'\e[38;5;154m' # green | Lines, bullets and separators
|
||||
'\e[1m' # Bold white | Main descriptions
|
||||
'\e[90m' # Grey | Credits
|
||||
'\e[91m' # Red | Update notifications Alert
|
||||
'\e[33m' # Yellow | Emphasis
|
||||
)
|
||||
|
||||
Target_Arch=""
|
||||
Target_Distro="debian"
|
||||
Target_OS="linux"
|
||||
Casa_Tag=""
|
||||
|
||||
|
||||
#######################################
|
||||
# Custom printing function
|
||||
# Globals:
|
||||
# None
|
||||
# Arguments:
|
||||
# $1 0:OK 1:FAILED 2:INFO 3:NOTICE
|
||||
# message
|
||||
# Returns:
|
||||
# None
|
||||
#######################################
|
||||
|
||||
Show() {
|
||||
# OK
|
||||
if (($1 == 0)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} OK $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# FAILED
|
||||
elif (($1 == 1)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[3]}FAILED$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# INFO
|
||||
elif (($1 == 2)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[0]} INFO $COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
# NOTICE
|
||||
elif (($1 == 3)); then
|
||||
echo -e "${aCOLOUR[2]}[$COLOUR_RESET${aCOLOUR[4]}NOTICE$COLOUR_RESET${aCOLOUR[2]}]$COLOUR_RESET $2"
|
||||
fi
|
||||
}
|
||||
|
||||
Warn() {
|
||||
echo -e "${aCOLOUR[3]}$1$COLOUR_RESET"
|
||||
}
|
||||
|
||||
# 0 Check_exist
|
||||
Check_Exist() {
|
||||
#Create Dir
|
||||
Show 2 "Create Folders."
|
||||
${sudo_cmd} mkdir -p ${CASA_HELPER_PATH}
|
||||
${sudo_cmd} mkdir -p ${CASA_LOGS_PATH}
|
||||
${sudo_cmd} mkdir -p ${CASA_USER_CONF_PATH}
|
||||
${sudo_cmd} mkdir -p ${CASA_DB_PATH}
|
||||
${sudo_cmd} mkdir -p ${CASA_TEMP_PATH}
|
||||
|
||||
|
||||
Show 2 "Start cleaning up the old version."
|
||||
|
||||
${sudo_cmd} rm -rf /usr/lib/systemd/system/casaos.service
|
||||
|
||||
${sudo_cmd} rm -rf /lib/systemd/system/casaos.service
|
||||
|
||||
${sudo_cmd} rm -rf /usr/local/bin/${CASA_BIN}
|
||||
|
||||
#Clean
|
||||
if [[ -d "/casaOS" ]]; then
|
||||
${sudo_cmd} rm -rf /casaOS
|
||||
fi
|
||||
Show 0 "Clearance completed."
|
||||
|
||||
$sudo_cmd systemctl restart ${CASA_BIN}
|
||||
}
|
||||
Check_Exist
|
||||
@@ -25,14 +25,14 @@ GetNetCard() {
|
||||
fi
|
||||
else
|
||||
if [ -d "/sys/devices/virtual/net" ] && [ -d "/sys/class/net" ]; then
|
||||
ls /sys/class/net/ | grep -v "$(ls /sys/devices/virtual/net/)"
|
||||
ls /sys/class/net/ | grep -v "$(ls /sys/devices/virtual/net/)" -w
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
GetTimeZone(){
|
||||
timedatectl | grep "Time zone" | awk '{print $3}'
|
||||
timedatectl | grep "Time zone" | awk '{printf $3}'
|
||||
}
|
||||
|
||||
#查看网卡状态
|
||||
@@ -66,20 +66,6 @@ GetLocalJoinNetworks() {
|
||||
zerotier-cli listnetworks -j
|
||||
}
|
||||
|
||||
#移除挂载点,删除已挂在的文件夹
|
||||
UMountPorintAndRemoveDir() {
|
||||
DEVICE=$1
|
||||
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
|
||||
if [[ -z ${MOUNT_POINT} ]]; then
|
||||
${log} "Warning: ${DEVICE} is not mounted"
|
||||
else
|
||||
umount -l ${DEVICE}
|
||||
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
|
||||
/bin/rmdir "${MOUNT_POINT}"
|
||||
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
|
||||
fi
|
||||
}
|
||||
|
||||
#格式化fat32磁盘
|
||||
#param 需要格式化的目录 /dev/sda1
|
||||
#param 格式
|
||||
@@ -89,11 +75,11 @@ FormatDisk() {
|
||||
elif [ "$2" == "ntfs" ]; then
|
||||
mkfs.ntfs $1
|
||||
elif [ "$2" == "ext4" ]; then
|
||||
mkfs.ext4 -F $1
|
||||
mkfs.ext4 -m 1 -F $1
|
||||
elif [ "$2" == "exfat" ]; then
|
||||
mkfs.exfat $1
|
||||
else
|
||||
mkfs.ext4 -F $1
|
||||
mkfs.ext4 -m 1 -F $1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -117,13 +103,11 @@ AddPartition() {
|
||||
parted -s $1 mklabel gpt
|
||||
|
||||
parted -s $1 mkpart primary ext4 0 100%
|
||||
|
||||
mkfs.ext4 $11
|
||||
P=`lsblk -r $1 | sort | grep part | head -n 1 | awk '{print $1}'`
|
||||
mkfs.ext4 -m 1 -F /dev/${P}
|
||||
|
||||
partprobe $1
|
||||
|
||||
# mount $11 $2
|
||||
|
||||
}
|
||||
|
||||
#磁盘类型
|
||||
@@ -137,31 +121,27 @@ GetPlugInDisk() {
|
||||
fdisk -l | grep 'Disk' | grep 'sd' | awk -F , '{print substr($1,11,3)}'
|
||||
}
|
||||
|
||||
#获取磁盘状态
|
||||
#param 磁盘路径
|
||||
GetDiskHealthState() {
|
||||
smartctl -H $1 | grep "SMART Health Status" | awk -F ":" '{print$2}'
|
||||
}
|
||||
|
||||
|
||||
#获取磁盘字节数量和扇区数量
|
||||
#param 磁盘路径 /dev/sda
|
||||
#result bytes
|
||||
#result sectors
|
||||
GetDiskSizeAndSectors() {
|
||||
fdisk $1 -l | grep "/dev/sda:" | awk -F, 'BEGIN {OFS="\n"}{print $2,$3}' | awk '{print $1}'
|
||||
fdisk $1 -l | grep "$1:" | awk -F, 'BEGIN {OFS="\n"}{print $2,$3}' | awk '{print $1}'
|
||||
}
|
||||
|
||||
#获取磁盘分区数据扇区
|
||||
#param 磁盘路径 /dev/sda
|
||||
#result start,end,sectors
|
||||
GetPartitionSectors() {
|
||||
fdisk $1 -l | grep "/dev/sda[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
|
||||
fdisk $1 -l | grep "$1[1-9]" | awk 'BEGIN{OFS=","}{print $1,$2,$3,$4}'
|
||||
}
|
||||
|
||||
#检查没有使用的挂载点删除文件夹
|
||||
AutoRemoveUnuseDir() {
|
||||
DIRECTORY="/mnt/"
|
||||
dir=$(ls -l $DIRECTORY | awk '/^d/ {print $NF}')
|
||||
DIRECTORY="/DATA/"
|
||||
dir=$(ls -l $DIRECTORY | grep "USB_Storage_sd[a-z][0-9]" | awk '/^d/ {print $NF}')
|
||||
for i in $dir; do
|
||||
|
||||
path="$DIRECTORY$i"
|
||||
@@ -188,7 +168,7 @@ do_mount() {
|
||||
DEVBASE=$1
|
||||
DEVICE="${DEVBASE}"
|
||||
# See if this drive is already mounted, and if so where
|
||||
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
|
||||
MOUNT_POINT=$(lsblk -o name,mountpoint | grep ${DEVICE} | awk '{print $2}')
|
||||
|
||||
if [ -n "${MOUNT_POINT}" ]; then
|
||||
${log} "Warning: ${DEVICE} is already mounted at ${MOUNT_POINT}"
|
||||
@@ -249,9 +229,13 @@ do_umount() {
|
||||
if [[ -z ${MOUNT_POINT} ]]; then
|
||||
${log} "Warning: ${DEVICE} is not mounted"
|
||||
else
|
||||
/bin/kill -9 $(lsof ${MOUNT_POINT})
|
||||
umount -l ${DEVICE}
|
||||
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
|
||||
/bin/rmdir "${MOUNT_POINT}"
|
||||
if [ "`ls -A ${MOUNT_POINT}`" = "" ]; then
|
||||
/bin/rm -fr "${MOUNT_POINT}"
|
||||
fi
|
||||
|
||||
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
|
||||
fi
|
||||
|
||||
@@ -329,3 +313,47 @@ TarFolder() {
|
||||
#查看固定文件夹大小
|
||||
du -sh /DATA
|
||||
}
|
||||
|
||||
USB_Start_Auto() {
|
||||
((EUID)) && sudo_cmd="sudo"
|
||||
$sudo_cmd systemctl enable devmon@devmon
|
||||
$sudo_cmd systemctl start devmon@devmon
|
||||
}
|
||||
|
||||
USB_Stop_Auto() {
|
||||
((EUID)) && sudo_cmd="sudo"
|
||||
$sudo_cmd systemctl stop devmon@devmon
|
||||
$sudo_cmd systemctl disable devmon@devmon
|
||||
$sudo_cmd udevil clean
|
||||
}
|
||||
|
||||
GetDeviceTree(){
|
||||
cat /proc/device-tree/model
|
||||
}
|
||||
|
||||
# restart samba service
|
||||
RestartSMBD(){
|
||||
$sudo_cmd systemctl restart smbd
|
||||
}
|
||||
|
||||
# edit user password $1:username
|
||||
EditSmabaUserPassword(){
|
||||
$sudo_cmd smbpasswd $1
|
||||
}
|
||||
|
||||
AddSmabaUser(){
|
||||
$sudo_cmd useradd $1
|
||||
$sudo_cmd smbpasswd -a $1 <<EOF
|
||||
$2
|
||||
$2
|
||||
EOF
|
||||
}
|
||||
|
||||
# $1:username $2:host $3:share $4:port $5:mountpoint $6:password
|
||||
MountCIFS(){
|
||||
$sudo_cmd mount -t cifs -o username=$1,password=$6,port=$4 //$2/$3 $5
|
||||
}
|
||||
|
||||
UDEVILUmount(){
|
||||
$sudo_cmd udevil umount -f $1
|
||||
}
|
||||
12
build/sysroot/usr/share/casaos/shell/update.sh
Normal file
12
build/sysroot/usr/share/casaos/shell/update.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
###
|
||||
# @Author: LinkLeong link@icewhale.com
|
||||
# @Date: 2022-06-30 10:08:33
|
||||
# @LastEditors: LinkLeong
|
||||
# @LastEditTime: 2022-09-01 22:33:06
|
||||
# @FilePath: /CasaOS/build/sysroot/usr/share/casaos/shell/update.sh
|
||||
# @Description:
|
||||
###
|
||||
|
||||
|
||||
curl -fsSL https://raw.githubusercontent.com/IceWhaleTech/get/main/update.sh | bash
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
# copy to /casaOS/util/shell path
|
||||
# chmod 755
|
||||
@@ -12,7 +12,7 @@ DEVBASE=$2
|
||||
DEVICE="/dev/${DEVBASE}"
|
||||
|
||||
# See if this drive is already mounted, and if so where
|
||||
MOUNT_POINT=$(mount | grep ${DEVICE} | awk '{ print $3 }')
|
||||
MOUNT_POINT=$(lsblk -l -p -o name,mountpoint | grep ${DEVICE} | awk '{print $2}')
|
||||
|
||||
do_mount() {
|
||||
|
||||
@@ -31,9 +31,9 @@ do_mount() {
|
||||
# Figure out a mount point to use
|
||||
# LABEL=${ID_FS_LABEL}
|
||||
LABEL=${DEVBASE}
|
||||
if grep -q " /mnt/casa_${LABEL} " /etc/mtab; then
|
||||
if grep -q " /DATA/USB_Storage_${LABEL} " /etc/mtab; then
|
||||
# Already in use, make a unique one
|
||||
LABEL+="-${DEVBASE}"
|
||||
LABEL+="_${DEVBASE}"
|
||||
fi
|
||||
DEV_LABEL="${LABEL}"
|
||||
|
||||
@@ -42,12 +42,29 @@ do_mount() {
|
||||
DEV_LABEL="${DEVBASE}"
|
||||
fi
|
||||
|
||||
MOUNT_POINT="/mnt/casa_${DEV_LABEL}"
|
||||
|
||||
MOUNT_POINT="/DATA/USB_Storage_${DEV_LABEL}"
|
||||
|
||||
${log} "Mount point: ${MOUNT_POINT}"
|
||||
|
||||
mkdir -p ${MOUNT_POINT}
|
||||
|
||||
|
||||
# MOUNT_POINT="/DATA/USB_Storage1"
|
||||
# arr=("/DATA/USB_Storage1" "/DATA/USB_Storage2" "/DATA/USB_Storage3" "/DATA/USB_Storage4" "/DATA/USB_Storage5" "/DATA/USB_Storage6" "/DATA/USB_Storage7" "/DATA/USB_Storage8" "/DATA/USB_Storage9" "/DATA/USB_Storage10" "/DATA/USB_Storage11" "/DATA/USB_Storage12")
|
||||
# for folder in ${arr[@]}; do
|
||||
# #如果文件夹不存在,创建文件夹
|
||||
# if [ ! -d "$folder" ]; then
|
||||
# mkdir -p ${folder}
|
||||
# MOUNT_POINT=$folder
|
||||
# break
|
||||
# fi
|
||||
# done
|
||||
|
||||
# ${log} "Mount point: ${MOUNT_POINT}"
|
||||
|
||||
|
||||
|
||||
# # Global mount options
|
||||
# OPTS="rw,relatime"
|
||||
#
|
||||
@@ -95,9 +112,12 @@ do_umount() {
|
||||
if [[ -z ${MOUNT_POINT} ]]; then
|
||||
${log} "Warning: ${DEVICE} is not mounted"
|
||||
else
|
||||
#/bin/kill -9 $(lsof ${MOUNT_POINT})
|
||||
umount -l ${DEVICE}
|
||||
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
|
||||
/bin/rmdir "${MOUNT_POINT}"
|
||||
if [ "`ls -A ${MOUNT_POINT}`" = "" ]; then
|
||||
/bin/rm -fr "${MOUNT_POINT}"
|
||||
fi
|
||||
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
|
||||
fi
|
||||
|
||||
28
cmd/message-bus-docgen/main.go
Normal file
28
cmd/message-bus-docgen/main.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS-Common/external"
|
||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func main() {
|
||||
eventTypes := lo.Map(common.EventTypes, func(item message_bus.EventType, index int) external.EventType {
|
||||
return external.EventType{
|
||||
Name: item.Name,
|
||||
SourceID: item.SourceID,
|
||||
PropertyTypeList: lo.Map(
|
||||
item.PropertyTypeList, func(item message_bus.PropertyType, index int) external.PropertyType {
|
||||
return external.PropertyType{
|
||||
Name: item.Name,
|
||||
Description: item.Description,
|
||||
Example: item.Example,
|
||||
}
|
||||
},
|
||||
),
|
||||
}
|
||||
})
|
||||
|
||||
external.PrintEventTypesAsMarkdown(common.SERVICENAME, common.VERSION, eventTypes)
|
||||
}
|
||||
37
cmd/migration-tool/log.go
Normal file
37
cmd/migration-tool/log.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
DebugMode bool
|
||||
|
||||
_debug *log.Logger
|
||||
_info *log.Logger
|
||||
_error *log.Logger
|
||||
}
|
||||
|
||||
func NewLogger() *Logger {
|
||||
return &Logger{
|
||||
DebugMode: false,
|
||||
_debug: log.New(os.Stdout, "DEBUG: ", 0),
|
||||
_info: log.New(os.Stdout, "", 0),
|
||||
_error: log.New(os.Stderr, "ERROR: ", 0),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Debug(format string, v ...interface{}) {
|
||||
if l.DebugMode {
|
||||
l._debug.Printf(format, v...)
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Logger) Info(format string, v ...interface{}) {
|
||||
l._info.Printf(format, v...)
|
||||
}
|
||||
|
||||
func (l *Logger) Error(format string, v ...interface{}) {
|
||||
l._error.Printf(format, v...)
|
||||
}
|
||||
128
cmd/migration-tool/main.go
Normal file
128
cmd/migration-tool/main.go
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.org
|
||||
* @Date: 2022-08-23 18:09:11
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-08-31 14:17:51
|
||||
* @FilePath: /CasaOS/cmd/migration-tool/main.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
interfaces "github.com/IceWhaleTech/CasaOS-Common"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/systemctl"
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
casaosServiceName = "casaos.service"
|
||||
)
|
||||
|
||||
var (
|
||||
commit = "private build"
|
||||
date = "private build"
|
||||
|
||||
_logger *Logger
|
||||
sqliteDB *gorm.DB
|
||||
|
||||
configFlag = ""
|
||||
dbFlag = ""
|
||||
)
|
||||
|
||||
func init() {
|
||||
versionFlag := flag.Bool("v", false, "version")
|
||||
debugFlag := flag.Bool("d", true, "debug")
|
||||
forceFlag := flag.Bool("f", true, "force")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *versionFlag {
|
||||
fmt.Println("v" + common.VERSION)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
println("git commit:", commit)
|
||||
println("build date:", date)
|
||||
|
||||
_logger = NewLogger()
|
||||
|
||||
if os.Getuid() != 0 {
|
||||
_logger.Info("Root privileges are required to run this program.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *debugFlag {
|
||||
_logger.DebugMode = true
|
||||
}
|
||||
|
||||
if !*forceFlag {
|
||||
serviceEnabled, err := systemctl.IsServiceEnabled(casaosServiceName)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if serviceEnabled {
|
||||
_logger.Info("%s is already enabled. If migration is still needed, try with -f.", casaosServiceName)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
config.InitSetup(configFlag, "")
|
||||
|
||||
if len(dbFlag) == 0 {
|
||||
dbFlag = config.AppInfo.DBPath + "/db"
|
||||
}
|
||||
|
||||
sqliteDB = sqlite.GetDb(dbFlag)
|
||||
// gredis.GetRedisConn(config.RedisInfo),
|
||||
|
||||
service.MyService = service.NewService(sqliteDB, "")
|
||||
}
|
||||
|
||||
func main() {
|
||||
migrationTools := []interfaces.MigrationTool{
|
||||
// nothing to migrate from last version
|
||||
}
|
||||
|
||||
var selectedMigrationTool interfaces.MigrationTool
|
||||
|
||||
// look for the right migration tool matching current version
|
||||
for _, tool := range migrationTools {
|
||||
migrationNeeded, err := tool.IsMigrationNeeded()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if migrationNeeded {
|
||||
selectedMigrationTool = tool
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if selectedMigrationTool == nil {
|
||||
_logger.Error("selectedMigrationTool is null")
|
||||
return
|
||||
}
|
||||
|
||||
if err := selectedMigrationTool.PreMigrate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := selectedMigrationTool.Migrate(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := selectedMigrationTool.PostMigrate(); err != nil {
|
||||
_logger.Error("Migration succeeded, but post-migration failed: %s", err)
|
||||
}
|
||||
}
|
||||
27
cmd/migration-tool/migration_dummy.go
Normal file
27
cmd/migration-tool/migration_dummy.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
interfaces "github.com/IceWhaleTech/CasaOS-Common"
|
||||
)
|
||||
|
||||
type migrationTool struct{}
|
||||
|
||||
func (u *migrationTool) IsMigrationNeeded() (bool, error) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (u *migrationTool) PreMigrate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *migrationTool) Migrate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (u *migrationTool) PostMigrate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewMigrationDummy() interfaces.MigrationTool {
|
||||
return &migrationTool{}
|
||||
}
|
||||
326
codegen/casaos_api.go
Normal file
326
codegen/casaos_api.go
Normal file
@@ -0,0 +1,326 @@
|
||||
// Package codegen provides primitives to interact with the openapi HTTP API.
|
||||
//
|
||||
// Code generated by github.com/deepmap/oapi-codegen version v1.12.4 DO NOT EDIT.
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/deepmap/oapi-codegen/pkg/runtime"
|
||||
"github.com/getkin/kin-openapi/openapi3"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
Access_tokenScopes = "access_token.Scopes"
|
||||
)
|
||||
|
||||
// Defines values for SetZerotierNetworkStatusJSONBodyStatus.
|
||||
const (
|
||||
Offline SetZerotierNetworkStatusJSONBodyStatus = "offline"
|
||||
Online SetZerotierNetworkStatusJSONBodyStatus = "online"
|
||||
)
|
||||
|
||||
// BaseResponse defines model for BaseResponse.
|
||||
type BaseResponse struct {
|
||||
// Message message returned by server side if there is any
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// HealthPorts defines model for HealthPorts.
|
||||
type HealthPorts struct {
|
||||
TCP *[]int `json:"tcp,omitempty"`
|
||||
UDP *[]int `json:"udp,omitempty"`
|
||||
}
|
||||
|
||||
// HealthServices defines model for HealthServices.
|
||||
type HealthServices struct {
|
||||
NotRunning *[]string `json:"not_running,omitempty"`
|
||||
Running *[]string `json:"running,omitempty"`
|
||||
}
|
||||
|
||||
// ZTInfo defines model for ZTInfo.
|
||||
type ZTInfo struct {
|
||||
Id *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Status *string `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// GetHealthPortsOK defines model for GetHealthPortsOK.
|
||||
type GetHealthPortsOK struct {
|
||||
Data *HealthPorts `json:"data,omitempty"`
|
||||
|
||||
// Message message returned by server side if there is any
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// GetHealthServicesOK defines model for GetHealthServicesOK.
|
||||
type GetHealthServicesOK struct {
|
||||
Data *HealthServices `json:"data,omitempty"`
|
||||
|
||||
// Message message returned by server side if there is any
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// GetZTInfoOK defines model for GetZTInfoOK.
|
||||
type GetZTInfoOK = ZTInfo
|
||||
|
||||
// ResponseInternalServerError defines model for ResponseInternalServerError.
|
||||
type ResponseInternalServerError = BaseResponse
|
||||
|
||||
// ResponseOK defines model for ResponseOK.
|
||||
type ResponseOK = BaseResponse
|
||||
|
||||
// SetZerotierNetworkStatusJSONBody defines parameters for SetZerotierNetworkStatus.
|
||||
type SetZerotierNetworkStatusJSONBody struct {
|
||||
Status *SetZerotierNetworkStatusJSONBodyStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// SetZerotierNetworkStatusJSONBodyStatus defines parameters for SetZerotierNetworkStatus.
|
||||
type SetZerotierNetworkStatusJSONBodyStatus string
|
||||
|
||||
// SetZerotierNetworkStatusJSONRequestBody defines body for SetZerotierNetworkStatus for application/json ContentType.
|
||||
type SetZerotierNetworkStatusJSONRequestBody SetZerotierNetworkStatusJSONBody
|
||||
|
||||
// ServerInterface represents all server handlers.
|
||||
type ServerInterface interface {
|
||||
// Test file methods
|
||||
// (GET /file/test)
|
||||
GetFileTest(ctx echo.Context) error
|
||||
// Get log
|
||||
// (GET /health/logs)
|
||||
GetHealthlogs(ctx echo.Context) error
|
||||
// Get port in use
|
||||
// (GET /health/ports)
|
||||
GetHealthPorts(ctx echo.Context) error
|
||||
// Get service status
|
||||
// (GET /health/services)
|
||||
GetHealthServices(ctx echo.Context) error
|
||||
// Get Zerotier info
|
||||
// (GET /zt/info)
|
||||
GetZerotierInfo(ctx echo.Context) error
|
||||
// Set Zerotier network status
|
||||
// (PUT /zt/{network_id}/status)
|
||||
SetZerotierNetworkStatus(ctx echo.Context, networkId string) error
|
||||
}
|
||||
|
||||
// ServerInterfaceWrapper converts echo contexts to parameters.
|
||||
type ServerInterfaceWrapper struct {
|
||||
Handler ServerInterface
|
||||
}
|
||||
|
||||
// GetFileTest converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetFileTest(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetFileTest(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetHealthlogs converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetHealthlogs(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetHealthlogs(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetHealthPorts converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetHealthPorts(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetHealthPorts(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetHealthServices converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetHealthServices(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetHealthServices(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetZerotierInfo converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetZerotierInfo(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetZerotierInfo(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetZerotierNetworkStatus converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) SetZerotierNetworkStatus(ctx echo.Context) error {
|
||||
var err error
|
||||
// ------------- Path parameter "network_id" -------------
|
||||
var networkId string
|
||||
|
||||
err = runtime.BindStyledParameterWithLocation("simple", false, "network_id", runtime.ParamLocationPath, ctx.Param("network_id"), &networkId)
|
||||
if err != nil {
|
||||
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter network_id: %s", err))
|
||||
}
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.SetZerotierNetworkStatus(ctx, networkId)
|
||||
return err
|
||||
}
|
||||
|
||||
// This is a simple interface which specifies echo.Route addition functions which
|
||||
// are present on both echo.Echo and echo.Group, since we want to allow using
|
||||
// either of them for path registration
|
||||
type EchoRouter interface {
|
||||
CONNECT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
DELETE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
GET(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
HEAD(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
OPTIONS(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PATCH(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
POST(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
PUT(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
TRACE(path string, h echo.HandlerFunc, m ...echo.MiddlewareFunc) *echo.Route
|
||||
}
|
||||
|
||||
// RegisterHandlers adds each server route to the EchoRouter.
|
||||
func RegisterHandlers(router EchoRouter, si ServerInterface) {
|
||||
RegisterHandlersWithBaseURL(router, si, "")
|
||||
}
|
||||
|
||||
// Registers handlers, and prepends BaseURL to the paths, so that the paths
|
||||
// can be served under a prefix.
|
||||
func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL string) {
|
||||
|
||||
wrapper := ServerInterfaceWrapper{
|
||||
Handler: si,
|
||||
}
|
||||
|
||||
router.GET(baseURL+"/file/test", wrapper.GetFileTest)
|
||||
router.GET(baseURL+"/health/logs", wrapper.GetHealthlogs)
|
||||
router.GET(baseURL+"/health/ports", wrapper.GetHealthPorts)
|
||||
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
||||
router.GET(baseURL+"/zt/info", wrapper.GetZerotierInfo)
|
||||
router.PUT(baseURL+"/zt/:network_id/status", wrapper.SetZerotierNetworkStatus)
|
||||
|
||||
}
|
||||
|
||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"H4sIAAAAAAAC/8xX72/bNhD9VwhuH5pBsbxk3ToB/dAfaxoUW4Ilw4bGhktLZ4mNRKp3pyRuoP99oCjb",
|
||||
"sq386pqhn2xRp7v3Hnnk47WMbVFaA4ZJRtcSgUprCJqHA+C3oHLOji0yHb1zY7E1DIbdX1WWuY4Va2vC",
|
||||
"j2SNG6M4g0I1b/P8aCajs2v5PcJMRvK7cFUq9HEUvlQEf7Y1ZR1cyxJtCcjaI0gUN8luS9GBKOu6Htd1",
|
||||
"HcgEKEZdOmwykkfvZB2s6JwAXugYvnFGC5R3knp/emhm9oFkbqvvE8obay7oHRoGNCp3SAF/Q7T41TCs",
|
||||
"y7iNZFFb+OLCV++A+4p63IXFqVIHbbJmlte+iDbXQAFEKm1erCdqXwgErtBAIqZzQZ4f6QSEngnOAEFo",
|
||||
"EsrMZSDhShVlDjKSMpAIKjky+VxGjBUEkuele0OM2qQeeLdZtnBxXLofzVA0z8vkz4bLZNowpNAo3Y4o",
|
||||
"ROWgXO2mdteowo2dvjp2EVVyQ8Kn+w9M+Nfr4y6BZW9scTCWJ1gZ4xj3lpaxImVpQD6F3JJpA0cdyPvk",
|
||||
"200Vw6Wa3z+vY9N22hYLnazX+HFv/6enP//y7NdhX16vUTf+lSJ1dNIXS6y42mBgTa5ND+IGIkFcoeb5",
|
||||
"iVvdHp2KYyCasD2Hpou0W7sZqARQLtDIFxVnFvXnpuFWuVWp30HLXrfc15tgVA2H+3GpY64QmgcYGSGE",
|
||||
"8C/IVhiDKCDR6vlIPikRZoC0G9vc4m7TgxCJROH5zkgKwpiAn49kxlxSFIaoLgep5qyaVgTYbg+D2Bbh",
|
||||
"YQx/ZyqHU4izMLepDQulTeint/2ZTJUxgBOXfmJ0mvHk2XBYXg1Kk47kl4LNXaJHRMuXuikxmeYV3A5Y",
|
||||
"F6lQuYPgl5AH9f8j8mjCjVUwMh6VeHF8KEq0FzoBEoWmGPJcGbAViQI4swmJmUWR6NkMEAwLisEo1JYG",
|
||||
"Lssbi0ITVeC20UQkmuKKSFtDgShzUATiQpNmt9uKswPNb6upQCgtabY4Hz9ZqOGV2KbvYe4Ii+Kj1Uac",
|
||||
"2QrFa02xxWT1deIHBmkanptPL6bTl1P4Z2cwatpFc6eTHWEZyAtA8k1yseea2ZZgVKllJPcHw8G+DGSp",
|
||||
"OGt6NJzpHEIGas6+FHi70U6BWLiwhWYD2aTEpmUPExk5d/FGO07EzfnSMYd7w+FN5+YyLuwcxnUgnz7k",
|
||||
"kz5z0exHVVEonPfhd7KplGR0Jt90h8fuuzBrTg63MqkjyRZff8A0Uf2Mb7AUNmbgXWIEVaxbi5nFQrGM",
|
||||
"5FQbh7z3YO7zWV9ZrwNgkdu0o5Ln2q9TufAItwvlrcSXrI2t28XjMHY8hDaiIrgnc+qYi97GcWlbTyD8",
|
||||
"eSrsTICKM/GhdQM/fBBtmt6m2nAx/0m+zm3mcRRsibRU7xLxM4eLc/1G8d4DWtaAwkX2CrSIaOzRF8qz",
|
||||
"vBc9jixrJDqqLMe3dLk2wJcWzyc6qcOVESurHplOuhXa79oZ2BbsZCXYHz70ZDFXpUJVAANSc3NdL7LI",
|
||||
"qxMZeBfnzo+Vh1vhbebgU6URksXtYrXBbW5nYx8MxC9tMn/QNWzdBnfMqqkKJ+7SqtrZrPk3Du5jZJcj",
|
||||
"dvoRYm6t7be2qm6Z8zvWV8enN9O87tDPxm5K/EXSL4MKcxnJ8GKv9WXSBbQFNhfJk9Oj10c7q0Wx0fV1",
|
||||
"cNcHa2exK3S1yyo9QFuVvl4b9/vWKb61wYzrfwMAAP//9tkexLESAAA=",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
// or error if failed to decode
|
||||
func decodeSpec() ([]byte, error) {
|
||||
zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, ""))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error base64 decoding spec: %s", err)
|
||||
}
|
||||
zr, err := gzip.NewReader(bytes.NewReader(zipped))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
_, err = buf.ReadFrom(zr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decompressing spec: %s", err)
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var rawSpec = decodeSpecCached()
|
||||
|
||||
// a naive cached of a decoded swagger spec
|
||||
func decodeSpecCached() func() ([]byte, error) {
|
||||
data, err := decodeSpec()
|
||||
return func() ([]byte, error) {
|
||||
return data, err
|
||||
}
|
||||
}
|
||||
|
||||
// Constructs a synthetic filesystem for resolving external references when loading openapi specifications.
|
||||
func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error) {
|
||||
var res = make(map[string]func() ([]byte, error))
|
||||
if len(pathToFile) > 0 {
|
||||
res[pathToFile] = rawSpec
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// GetSwagger returns the Swagger specification corresponding to the generated code
|
||||
// in this file. The external references of Swagger specification are resolved.
|
||||
// The logic of resolving external references is tightly connected to "import-mapping" feature.
|
||||
// Externally referenced files must be embedded in the corresponding golang packages.
|
||||
// Urls can be supported but this task was out of the scope.
|
||||
func GetSwagger() (swagger *openapi3.T, err error) {
|
||||
var resolvePath = PathToRawSpec("")
|
||||
|
||||
loader := openapi3.NewLoader()
|
||||
loader.IsExternalRefsAllowed = true
|
||||
loader.ReadFromURIFunc = func(loader *openapi3.Loader, url *url.URL) ([]byte, error) {
|
||||
var pathToFile = url.String()
|
||||
pathToFile = path.Clean(pathToFile)
|
||||
getSpec, ok := resolvePath[pathToFile]
|
||||
if !ok {
|
||||
err1 := fmt.Errorf("path not found: %s", pathToFile)
|
||||
return nil, err1
|
||||
}
|
||||
return getSpec()
|
||||
}
|
||||
var specData []byte
|
||||
specData, err = rawSpec()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
swagger, err = loader.LoadFromData(specData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
2254
codegen/message_bus/api.go
Normal file
2254
codegen/message_bus/api.go
Normal file
File diff suppressed because it is too large
Load Diff
8
common/constants.go
Normal file
8
common/constants.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package common
|
||||
|
||||
const (
|
||||
SERVICENAME = "casaos"
|
||||
VERSION = "0.4.4.2"
|
||||
BODY = " "
|
||||
RANW_NAME = "IceWhale-RemoteAccess"
|
||||
)
|
||||
12
common/message.go
Normal file
12
common/message.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
|
||||
)
|
||||
|
||||
// devtype -> action -> event
|
||||
var EventTypes = []message_bus.EventType{
|
||||
{Name: "casaos:system:utilization", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||
{Name: "casaos:file:recover", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||
{Name: "casaos:file:operate", SourceID: SERVICENAME, PropertyTypeList: []message_bus.PropertyType{}},
|
||||
}
|
||||
25
conf/conf.conf.sample
Normal file
25
conf/conf.conf.sample
Normal file
@@ -0,0 +1,25 @@
|
||||
[app]
|
||||
PAGE_SIZE = 10
|
||||
RuntimeRootPath = runtime/
|
||||
LogPath = /var/log/casaos/
|
||||
LogSaveName = log
|
||||
LogFileExt = log
|
||||
DateStrFormat = 20060102
|
||||
DateTimeFormat = 2006-01-02 15:04:05
|
||||
TimeFormat = 15:04:05
|
||||
DateFormat = 2006-01-02
|
||||
DBPath = /var/lib/casaos
|
||||
ShellPath = /usr/share/casaos/shell
|
||||
UserDataPath = /var/lib/casaos/conf
|
||||
|
||||
[server]
|
||||
RunMode = release
|
||||
ServerApi = https://api.casaos.io/casaos-api
|
||||
Handshake = socket.casaos.io
|
||||
Token =
|
||||
USBAutoMount =
|
||||
|
||||
[system]
|
||||
|
||||
[common]
|
||||
RuntimePath=/var/run/casaos
|
||||
@@ -1,42 +0,0 @@
|
||||
[app]
|
||||
PAGE_SIZE = 10
|
||||
RuntimeRootPath = runtime/
|
||||
LogSavePath = /casaOS/logs/server/
|
||||
LogSaveName = log
|
||||
LogFileExt = log
|
||||
DateStrFormat = 20060102
|
||||
DateTimeFormat = 2006-01-02 15:04:05
|
||||
TimeFormat = 15:04:05
|
||||
DateFormat = 2006-01-02
|
||||
ProjectPath = /casaOS/server
|
||||
|
||||
|
||||
[server]
|
||||
HttpPort = 8089
|
||||
RunMode = release
|
||||
ServerApi = https://api.casaos.zimaboard.com
|
||||
|
||||
[user]
|
||||
UserName = admin
|
||||
PWD = zimaboard
|
||||
Email = user@gmail.com
|
||||
Description = description
|
||||
Initialized = false
|
||||
Token = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImVyZXJlIiwicGFzc3dvcmQiOiJhZHNmZGYiLCJleHAiOjE2MjQwMDU0ODEsImlzcyI6Imdpbi1ibG9nIn0.JNsCccZuFCwlSMLJg62iOIB2xymk_k7xGa11xhZ07bc
|
||||
|
||||
[zerotier]
|
||||
UserName = user
|
||||
PWD = pwd
|
||||
Token = yBKYyavr2RdFAIVN7iTpzlsB1o6CqTgm
|
||||
|
||||
[redis]
|
||||
Host = 127.0.0.1:6379
|
||||
Password =
|
||||
MaxIdle = 30
|
||||
MaxActive = 30
|
||||
IdleTimeout = 200
|
||||
|
||||
[system]
|
||||
ConfigStr =
|
||||
WidgetList =
|
||||
|
||||
13
drivers/all.go
Normal file
13
drivers/all.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package drivers
|
||||
|
||||
import (
|
||||
_ "github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||
_ "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||
_ "github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||
)
|
||||
|
||||
// All do nothing,just for import
|
||||
// same as _ import
|
||||
func All() {
|
||||
|
||||
}
|
||||
30
drivers/base/client.go
Normal file
30
drivers/base/client.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
var NoRedirectClient *resty.Client
|
||||
var RestyClient = NewRestyClient()
|
||||
var HttpClient = &http.Client{}
|
||||
var UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36"
|
||||
var DefaultTimeout = time.Second * 30
|
||||
|
||||
func init() {
|
||||
NoRedirectClient = resty.New().SetRedirectPolicy(
|
||||
resty.RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
}),
|
||||
)
|
||||
NoRedirectClient.SetHeader("user-agent", UserAgent)
|
||||
}
|
||||
|
||||
func NewRestyClient() *resty.Client {
|
||||
return resty.New().
|
||||
SetHeader("user-agent", UserAgent).
|
||||
SetRetryCount(3).
|
||||
SetTimeout(DefaultTimeout)
|
||||
}
|
||||
12
drivers/base/types.go
Normal file
12
drivers/base/types.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package base
|
||||
|
||||
import "github.com/go-resty/resty/v2"
|
||||
|
||||
type Json map[string]interface{}
|
||||
|
||||
type TokenResp struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
type ReqCallback func(req *resty.Request)
|
||||
103
drivers/dropbox/drive.go
Normal file
103
drivers/dropbox/drive.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package dropbox
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Dropbox struct {
|
||||
model.StorageA
|
||||
Addition
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
func (d *Dropbox) Config() driver.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func (d *Dropbox) GetAddition() driver.Additional {
|
||||
return &d.Addition
|
||||
}
|
||||
|
||||
func (d *Dropbox) Init(ctx context.Context) error {
|
||||
if len(d.RefreshToken) == 0 {
|
||||
d.getRefreshToken()
|
||||
}
|
||||
return d.refreshToken()
|
||||
}
|
||||
|
||||
func (d *Dropbox) Drop(ctx context.Context) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dropbox) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
||||
files, err := d.getFiles(dir.GetID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
|
||||
return fileToObj(src), nil
|
||||
})
|
||||
}
|
||||
|
||||
func (d *Dropbox) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||
url := "https://content.dropboxapi.com/2/files/download"
|
||||
link := model.Link{
|
||||
URL: url,
|
||||
Method: http.MethodPost,
|
||||
Header: http.Header{
|
||||
"Authorization": []string{"Bearer " + d.AccessToken},
|
||||
"Dropbox-API-Arg": []string{`{"path": "` + file.GetPath() + `"}`},
|
||||
},
|
||||
}
|
||||
return &link, nil
|
||||
}
|
||||
func (d *Dropbox) GetUserInfo(ctx context.Context) (string, error) {
|
||||
url := "https://api.dropboxapi.com/2/users/get_current_account"
|
||||
user := UserInfo{}
|
||||
resp, err := d.request(url, http.MethodPost, func(req *resty.Request) {
|
||||
req.SetHeader("Content-Type", "")
|
||||
}, &user)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
logger.Info("resp", zap.Any("resp", string(resp)))
|
||||
return user.Email, nil
|
||||
}
|
||||
func (d *Dropbox) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dropbox) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dropbox) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dropbox) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||
return errors.New("not support")
|
||||
}
|
||||
|
||||
func (d *Dropbox) Remove(ctx context.Context, obj model.Obj) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||
return nil
|
||||
}
|
||||
func (d *Dropbox) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||
return "", "", "", nil
|
||||
}
|
||||
|
||||
var _ driver.Driver = (*Dropbox)(nil)
|
||||
24
drivers/dropbox/meta.go
Normal file
24
drivers/dropbox/meta.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package dropbox
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
)
|
||||
|
||||
const ICONURL = "./img/driver/Dropbox.svg"
|
||||
|
||||
type Addition struct {
|
||||
driver.RootID
|
||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
||||
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
Name: "Dropbox",
|
||||
OnlyProxy: true,
|
||||
DefaultRoot: "root",
|
||||
}
|
||||
88
drivers/dropbox/types.go
Normal file
88
drivers/dropbox/types.go
Normal file
@@ -0,0 +1,88 @@
|
||||
package dropbox
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type UserInfo struct {
|
||||
AccountID string `json:"account_id"`
|
||||
Name struct {
|
||||
GivenName string `json:"given_name"`
|
||||
Surname string `json:"surname"`
|
||||
FamiliarName string `json:"familiar_name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
AbbreviatedName string `json:"abbreviated_name"`
|
||||
} `json:"name"`
|
||||
Email string `json:"email"`
|
||||
EmailVerified bool `json:"email_verified"`
|
||||
Disabled bool `json:"disabled"`
|
||||
Country string `json:"country"`
|
||||
Locale string `json:"locale"`
|
||||
ReferralLink string `json:"referral_link"`
|
||||
IsPaired bool `json:"is_paired"`
|
||||
AccountType struct {
|
||||
Tag string `json:".tag"`
|
||||
} `json:"account_type"`
|
||||
RootInfo struct {
|
||||
Tag string `json:".tag"`
|
||||
RootNamespaceID string `json:"root_namespace_id"`
|
||||
HomeNamespaceID string `json:"home_namespace_id"`
|
||||
} `json:"root_info"`
|
||||
}
|
||||
type TokenError struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDescription string `json:"error_description"`
|
||||
}
|
||||
type File struct {
|
||||
Tag string `json:".tag"`
|
||||
Name string `json:"name"`
|
||||
PathLower string `json:"path_lower"`
|
||||
PathDisplay string `json:"path_display"`
|
||||
ID string `json:"id"`
|
||||
ClientModified time.Time `json:"client_modified,omitempty"`
|
||||
ServerModified time.Time `json:"server_modified,omitempty"`
|
||||
Rev string `json:"rev,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
IsDownloadable bool `json:"is_downloadable,omitempty"`
|
||||
ContentHash string `json:"content_hash,omitempty"`
|
||||
}
|
||||
|
||||
type Files struct {
|
||||
Files []File `json:"entries"`
|
||||
Cursor string `json:"cursor"`
|
||||
HasMore bool `json:"has_more"`
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Error struct {
|
||||
Errors []struct {
|
||||
Domain string `json:"domain"`
|
||||
Reason string `json:"reason"`
|
||||
Message string `json:"message"`
|
||||
LocationType string `json:"location_type"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
}
|
||||
|
||||
func fileToObj(f File) *model.ObjThumb {
|
||||
logger.Info("dropbox file", zap.Any("file", f))
|
||||
obj := &model.ObjThumb{
|
||||
Object: model.Object{
|
||||
ID: f.ID,
|
||||
Name: f.Name,
|
||||
Size: int64(f.Size),
|
||||
Modified: f.ClientModified,
|
||||
IsFolder: f.Tag == "folder",
|
||||
Path: f.PathDisplay,
|
||||
},
|
||||
Thumbnail: model.Thumbnail{},
|
||||
}
|
||||
return obj
|
||||
}
|
||||
116
drivers/dropbox/util.go
Normal file
116
drivers/dropbox/util.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package dropbox
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
app_key = "private build"
|
||||
app_secret = "private build"
|
||||
)
|
||||
|
||||
func (d *Dropbox) getRefreshToken() error {
|
||||
url := "https://api.dropbox.com/oauth2/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenError
|
||||
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
|
||||
SetFormData(map[string]string{
|
||||
"code": d.Code,
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "https://cloudoauth.files.casaos.app",
|
||||
}).SetBasicAuth(d.Addition.AppKey, d.Addition.AppSecret).SetHeader("Content-Type", "application/x-www-form-urlencoded").Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf(e.Error)
|
||||
}
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
return nil
|
||||
|
||||
}
|
||||
func (d *Dropbox) refreshToken() error {
|
||||
url := "https://api.dropbox.com/oauth2/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenError
|
||||
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
|
||||
SetFormData(map[string]string{
|
||||
"refresh_token": d.RefreshToken,
|
||||
"grant_type": "refresh_token",
|
||||
}).SetBasicAuth(d.Addition.AppKey, d.Addition.AppSecret).SetHeader("Content-Type", "application/x-www-form-urlencoded").Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf(e.Error)
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
return nil
|
||||
|
||||
}
|
||||
func (d *Dropbox) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||
req := base.RestyClient.R()
|
||||
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
|
||||
req.SetHeader("Content-Type", "application/json")
|
||||
if callback != nil {
|
||||
callback(req)
|
||||
}
|
||||
if resp != nil {
|
||||
req.SetResult(resp)
|
||||
}
|
||||
var e Error
|
||||
req.SetError(&e)
|
||||
res, err := req.Execute(method, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.Error.Code != 0 {
|
||||
if e.Error.Code == 401 {
|
||||
err = d.refreshToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.request(url, method, callback, resp)
|
||||
}
|
||||
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
|
||||
}
|
||||
return res.Body(), nil
|
||||
}
|
||||
func (d *Dropbox) getFiles(path string) ([]File, error) {
|
||||
|
||||
res := make([]File, 0)
|
||||
var resp Files
|
||||
body := base.Json{
|
||||
"limit": 2000,
|
||||
"path": path,
|
||||
}
|
||||
|
||||
_, err := d.request("https://api.dropboxapi.com/2/files/list_folder", http.MethodPost, func(req *resty.Request) {
|
||||
req.SetBody(body)
|
||||
}, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res = append(res, resp.Files...)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
func GetConfig() Dropbox {
|
||||
dp := Dropbox{}
|
||||
dp.RootFolderID = ""
|
||||
dp.AuthUrl = "https://www.dropbox.com/oauth2/authorize?client_id=" + app_key + "&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"
|
||||
dp.AppKey = app_key
|
||||
dp.AppSecret = app_secret
|
||||
dp.Icon = "./img/driver/Dropbox.svg"
|
||||
return dp
|
||||
}
|
||||
186
drivers/google_drive/drive.go
Normal file
186
drivers/google_drive/drive.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package google_drive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type GoogleDrive struct {
|
||||
model.StorageA
|
||||
Addition
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Config() driver.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) GetAddition() driver.Additional {
|
||||
return &d.Addition
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Init(ctx context.Context) error {
|
||||
if d.ChunkSize == 0 {
|
||||
d.ChunkSize = 5
|
||||
}
|
||||
if len(d.RefreshToken) == 0 {
|
||||
d.getRefreshToken()
|
||||
}
|
||||
return d.refreshToken()
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Drop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) {
|
||||
files, err := d.getFiles(dir.GetID())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
|
||||
return fileToObj(src), nil
|
||||
})
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||
url := fmt.Sprintf("https://www.googleapis.com/drive/v3/files/%s?includeItemsFromAllDrives=true&supportsAllDrives=true", file.GetID())
|
||||
_, err := d.request(url, http.MethodGet, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
link := model.Link{
|
||||
Method: http.MethodGet,
|
||||
URL: url + "&alt=media",
|
||||
Header: http.Header{
|
||||
"Authorization": []string{"Bearer " + d.AccessToken},
|
||||
},
|
||||
}
|
||||
return &link, nil
|
||||
}
|
||||
func (d *GoogleDrive) GetUserInfo(ctx context.Context) (string, error) {
|
||||
url := "https://content.googleapis.com/drive/v3/about?fields=user"
|
||||
user := UserInfo{}
|
||||
resp, err := d.request(url, http.MethodGet, nil, &user)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
logger.Info("resp", zap.Any("resp", resp))
|
||||
return user.User.EmailAddress, nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||
return "", "", "", nil
|
||||
}
|
||||
func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||
data := base.Json{
|
||||
"name": dirName,
|
||||
"parents": []string{parentDir.GetID()},
|
||||
"mimeType": "application/vnd.google-apps.folder",
|
||||
}
|
||||
_, err := d.request("https://www.googleapis.com/drive/v3/files", http.MethodPost, func(req *resty.Request) {
|
||||
req.SetBody(data)
|
||||
}, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Move(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||
query := map[string]string{
|
||||
"addParents": dstDir.GetID(),
|
||||
"removeParents": "root",
|
||||
}
|
||||
url := "https://www.googleapis.com/drive/v3/files/" + srcObj.GetID()
|
||||
_, err := d.request(url, http.MethodPatch, func(req *resty.Request) {
|
||||
req.SetQueryParams(query)
|
||||
}, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Rename(ctx context.Context, srcObj model.Obj, newName string) error {
|
||||
data := base.Json{
|
||||
"name": newName,
|
||||
}
|
||||
url := "https://www.googleapis.com/drive/v3/files/" + srcObj.GetID()
|
||||
_, err := d.request(url, http.MethodPatch, func(req *resty.Request) {
|
||||
req.SetBody(data)
|
||||
}, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Copy(ctx context.Context, srcObj, dstDir model.Obj) error {
|
||||
return errors.New("not support")
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Remove(ctx context.Context, obj model.Obj) error {
|
||||
url := "https://www.googleapis.com/drive/v3/files/" + obj.GetID()
|
||||
_, err := d.request(url, http.MethodDelete, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||
obj := stream.GetOld()
|
||||
var (
|
||||
e Error
|
||||
url string
|
||||
data base.Json
|
||||
res *resty.Response
|
||||
err error
|
||||
)
|
||||
if obj != nil {
|
||||
url = fmt.Sprintf("https://www.googleapis.com/upload/drive/v3/files/%s?uploadType=resumable&supportsAllDrives=true", obj.GetID())
|
||||
data = base.Json{}
|
||||
} else {
|
||||
data = base.Json{
|
||||
"name": stream.GetName(),
|
||||
"parents": []string{dstDir.GetID()},
|
||||
}
|
||||
url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable&supportsAllDrives=true"
|
||||
}
|
||||
req := base.NoRedirectClient.R().
|
||||
SetHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + d.AccessToken,
|
||||
"X-Upload-Content-Type": stream.GetMimetype(),
|
||||
"X-Upload-Content-Length": strconv.FormatInt(stream.GetSize(), 10),
|
||||
}).
|
||||
SetError(&e).SetBody(data).SetContext(ctx)
|
||||
if obj != nil {
|
||||
res, err = req.Patch(url)
|
||||
} else {
|
||||
res, err = req.Post(url)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if e.Error.Code != 0 {
|
||||
if e.Error.Code == 401 {
|
||||
err = d.refreshToken()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.Put(ctx, dstDir, stream, up)
|
||||
}
|
||||
return fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
|
||||
}
|
||||
putUrl := res.Header().Get("location")
|
||||
if stream.GetSize() < d.ChunkSize*1024*1024 {
|
||||
_, err = d.request(putUrl, http.MethodPut, func(req *resty.Request) {
|
||||
req.SetHeader("Content-Length", strconv.FormatInt(stream.GetSize(), 10)).SetBody(stream.GetReadCloser())
|
||||
}, nil)
|
||||
} else {
|
||||
err = d.chunkUpload(ctx, stream, putUrl)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var _ driver.Driver = (*GoogleDrive)(nil)
|
||||
26
drivers/google_drive/meta.go
Normal file
26
drivers/google_drive/meta.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package google_drive
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
)
|
||||
|
||||
const ICONURL = "./img/driver/GoogleDrive.svg"
|
||||
|
||||
type Addition struct {
|
||||
driver.RootID
|
||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||
ClientID string `json:"client_id" required:"true" default:"" omit:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true" default:"" omit:"true"`
|
||||
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
Name: "GoogleDrive",
|
||||
OnlyProxy: true,
|
||||
DefaultRoot: "root",
|
||||
}
|
||||
77
drivers/google_drive/types.go
Normal file
77
drivers/google_drive/types.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package google_drive
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type UserInfo struct {
|
||||
User struct {
|
||||
Kind string `json:"kind"`
|
||||
DisplayName string `json:"displayName"`
|
||||
PhotoLink string `json:"photoLink"`
|
||||
Me bool `json:"me"`
|
||||
PermissionID string `json:"permissionId"`
|
||||
EmailAddress string `json:"emailAddress"`
|
||||
} `json:"user"`
|
||||
}
|
||||
|
||||
type TokenError struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDescription string `json:"error_description"`
|
||||
}
|
||||
|
||||
type Files struct {
|
||||
NextPageToken string `json:"nextPageToken"`
|
||||
Files []File `json:"files"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
MimeType string `json:"mimeType"`
|
||||
ModifiedTime time.Time `json:"modifiedTime"`
|
||||
Size string `json:"size"`
|
||||
ThumbnailLink string `json:"thumbnailLink"`
|
||||
ShortcutDetails struct {
|
||||
TargetId string `json:"targetId"`
|
||||
TargetMimeType string `json:"targetMimeType"`
|
||||
} `json:"shortcutDetails"`
|
||||
}
|
||||
|
||||
func fileToObj(f File) *model.ObjThumb {
|
||||
log.Debugf("google file: %+v", f)
|
||||
size, _ := strconv.ParseInt(f.Size, 10, 64)
|
||||
obj := &model.ObjThumb{
|
||||
Object: model.Object{
|
||||
ID: f.Id,
|
||||
Name: f.Name,
|
||||
Size: size,
|
||||
Modified: f.ModifiedTime,
|
||||
IsFolder: f.MimeType == "application/vnd.google-apps.folder",
|
||||
},
|
||||
Thumbnail: model.Thumbnail{},
|
||||
}
|
||||
if f.MimeType == "application/vnd.google-apps.shortcut" {
|
||||
obj.ID = f.ShortcutDetails.TargetId
|
||||
obj.IsFolder = f.ShortcutDetails.TargetMimeType == "application/vnd.google-apps.folder"
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Error struct {
|
||||
Errors []struct {
|
||||
Domain string `json:"domain"`
|
||||
Reason string `json:"reason"`
|
||||
Message string `json:"message"`
|
||||
LocationType string `json:"location_type"`
|
||||
Location string `json:"location"`
|
||||
}
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
}
|
||||
167
drivers/google_drive/util.go
Normal file
167
drivers/google_drive/util.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package google_drive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils"
|
||||
"github.com/go-resty/resty/v2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
client_id = "private build"
|
||||
client_secret = "private build"
|
||||
)
|
||||
|
||||
// do others that not defined in Driver interface
|
||||
|
||||
func (d *GoogleDrive) getRefreshToken() error {
|
||||
url := "https://www.googleapis.com/oauth2/v4/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenError
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
|
||||
SetFormData(map[string]string{
|
||||
"client_id": d.ClientID,
|
||||
"client_secret": d.ClientSecret,
|
||||
"code": d.Code,
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "https://cloudoauth.files.casaos.app",
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf(e.Error)
|
||||
}
|
||||
d.RefreshToken = resp.RefreshToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) refreshToken() error {
|
||||
url := "https://www.googleapis.com/oauth2/v4/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenError
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).
|
||||
SetFormData(map[string]string{
|
||||
"client_id": d.ClientID,
|
||||
"client_secret": d.ClientSecret,
|
||||
"refresh_token": d.RefreshToken,
|
||||
"grant_type": "refresh_token",
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debug(res.String())
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf(e.Error)
|
||||
}
|
||||
d.AccessToken = resp.AccessToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||
req := base.RestyClient.R()
|
||||
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
|
||||
req.SetQueryParam("includeItemsFromAllDrives", "true")
|
||||
req.SetQueryParam("supportsAllDrives", "true")
|
||||
if callback != nil {
|
||||
callback(req)
|
||||
}
|
||||
if resp != nil {
|
||||
req.SetResult(resp)
|
||||
}
|
||||
var e Error
|
||||
req.SetError(&e)
|
||||
res, err := req.Execute(method, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.Error.Code != 0 {
|
||||
if e.Error.Code == 401 {
|
||||
err = d.refreshToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.request(url, method, callback, resp)
|
||||
}
|
||||
return nil, fmt.Errorf("%s: %v", e.Error.Message, e.Error.Errors)
|
||||
}
|
||||
return res.Body(), nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) getFiles(id string) ([]File, error) {
|
||||
pageToken := "first"
|
||||
res := make([]File, 0)
|
||||
for pageToken != "" {
|
||||
if pageToken == "first" {
|
||||
pageToken = ""
|
||||
}
|
||||
var resp Files
|
||||
orderBy := "folder,name,modifiedTime desc"
|
||||
if d.OrderBy != "" {
|
||||
orderBy = d.OrderBy + " " + d.OrderDirection
|
||||
}
|
||||
query := map[string]string{
|
||||
"orderBy": orderBy,
|
||||
"fields": "files(id,name,mimeType,size,modifiedTime,thumbnailLink,shortcutDetails),nextPageToken",
|
||||
"pageSize": "1000",
|
||||
"q": fmt.Sprintf("'%s' in parents and trashed = false", id),
|
||||
//"includeItemsFromAllDrives": "true",
|
||||
//"supportsAllDrives": "true",
|
||||
"pageToken": pageToken,
|
||||
}
|
||||
_, err := d.request("https://www.googleapis.com/drive/v3/files", http.MethodGet, func(req *resty.Request) {
|
||||
req.SetQueryParams(query)
|
||||
}, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pageToken = resp.NextPageToken
|
||||
res = append(res, resp.Files...)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.FileStreamer, url string) error {
|
||||
var defaultChunkSize = d.ChunkSize * 1024 * 1024
|
||||
var finish int64 = 0
|
||||
for finish < stream.GetSize() {
|
||||
if utils.IsCanceled(ctx) {
|
||||
return ctx.Err()
|
||||
}
|
||||
chunkSize := stream.GetSize() - finish
|
||||
if chunkSize > defaultChunkSize {
|
||||
chunkSize = defaultChunkSize
|
||||
}
|
||||
_, err := d.request(url, http.MethodPut, func(req *resty.Request) {
|
||||
req.SetHeaders(map[string]string{
|
||||
"Content-Length": strconv.FormatInt(chunkSize, 10),
|
||||
"Content-Range": fmt.Sprintf("bytes %d-%d/%d", finish, finish+chunkSize-1, stream.GetSize()),
|
||||
}).SetBody(io.LimitReader(stream.GetReadCloser(), chunkSize)).SetContext(ctx)
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
finish += chunkSize
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func GetConfig() GoogleDrive {
|
||||
config := GoogleDrive{}
|
||||
config.ClientID = client_id
|
||||
config.ClientSecret = client_secret
|
||||
config.RootFolderID = "root"
|
||||
config.AuthUrl = "https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=" + client_id + "&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"
|
||||
config.Icon = "./img/driver/GoogleDrive.svg"
|
||||
|
||||
return config
|
||||
}
|
||||
70
drivers/onedrive/drive.go
Normal file
70
drivers/onedrive/drive.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type Onedrive struct {
|
||||
model.StorageA
|
||||
Addition
|
||||
AccessToken string
|
||||
}
|
||||
|
||||
func (d *Onedrive) Config() driver.Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetAddition() driver.Additional {
|
||||
return &d.Addition
|
||||
}
|
||||
func (d *Onedrive) Init(ctx context.Context) error {
|
||||
if d.ChunkSize < 1 {
|
||||
d.ChunkSize = 5
|
||||
}
|
||||
if len(d.RefreshToken) == 0 {
|
||||
return d.getRefreshToken()
|
||||
}
|
||||
return d.refreshToken()
|
||||
}
|
||||
func (d *Onedrive) GetUserInfo(ctx context.Context) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
func (d *Onedrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||
url := d.GetMetaUrl(false, "/")
|
||||
user := Info{}
|
||||
resp, err := d.Request(url, http.MethodGet, nil, &user)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
|
||||
logger.Info("resp", zap.Any("resp", resp))
|
||||
return user.LastModifiedBy.User.DisplayName, user.ParentReference.DriveID, user.ParentReference.DriveType, nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) GetSpaceSize(ctx context.Context) (used string, total string, err error) {
|
||||
host := onedriveHostMap[d.Region]
|
||||
url := fmt.Sprintf("%s/v1.0/me/drive/quota", host.Api)
|
||||
size := About{}
|
||||
resp, err := d.Request(url, http.MethodGet, nil, &size)
|
||||
if err != nil {
|
||||
return used, total, err
|
||||
}
|
||||
logger.Info("resp", zap.Any("resp", resp))
|
||||
used = strconv.Itoa(size.Used)
|
||||
total = strconv.Itoa(size.Total)
|
||||
return
|
||||
}
|
||||
func (d *Onedrive) Drop(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ driver.Driver = (*Onedrive)(nil)
|
||||
69
drivers/onedrive/meta.go
Normal file
69
drivers/onedrive/meta.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
)
|
||||
|
||||
const ICONURL = "./img/driver/OneDrive.svg"
|
||||
|
||||
type Host struct {
|
||||
Oauth string
|
||||
Api string
|
||||
}
|
||||
|
||||
type TokenErr struct {
|
||||
Error string `json:"error"`
|
||||
ErrorDescription string `json:"error_description"`
|
||||
}
|
||||
|
||||
type RespErr struct {
|
||||
Error struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
} `json:"error"`
|
||||
}
|
||||
type Addition struct {
|
||||
Region string `json:"region" type:"select" required:"true" options:"global,cn,us,de" default:"global"`
|
||||
IsSharepoint bool `json:"is_sharepoint"`
|
||||
ClientID string `json:"client_id" required:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true"`
|
||||
RedirectUri string `json:"redirect_uri" required:"true" default:""`
|
||||
RefreshToken string `json:"refresh_token" required:"true"`
|
||||
SiteId string `json:"site_id"`
|
||||
ChunkSize int64 `json:"chunk_size" type:"number" default:"5"`
|
||||
RootFolderID string `json:"root_folder_id"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||
Icon string `json:"icon" type:"string" default:""`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
type About struct {
|
||||
Total int `json:"total"`
|
||||
Used int `json:"used"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
LastModifiedBy struct {
|
||||
Application struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
ID string `json:"id"`
|
||||
} `json:"application"`
|
||||
Device struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"device"`
|
||||
User struct {
|
||||
DisplayName string `json:"displayName"`
|
||||
ID string `json:"id"`
|
||||
} `json:"user"`
|
||||
} `json:"lastModifiedBy"`
|
||||
ParentReference struct {
|
||||
DriveID string `json:"driveId"`
|
||||
DriveType string `json:"driveType"`
|
||||
} `json:"parentReference"`
|
||||
}
|
||||
|
||||
var config = driver.Config{
|
||||
Name: "Onedrive",
|
||||
LocalSort: true,
|
||||
DefaultRoot: "/",
|
||||
}
|
||||
182
drivers/onedrive/util.go
Normal file
182
drivers/onedrive/util.go
Normal file
@@ -0,0 +1,182 @@
|
||||
package onedrive
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var (
|
||||
client_id = "private build"
|
||||
client_secret = "private build"
|
||||
)
|
||||
var onedriveHostMap = map[string]Host{
|
||||
"global": {
|
||||
Oauth: "https://login.microsoftonline.com",
|
||||
Api: "https://graph.microsoft.com",
|
||||
},
|
||||
"cn": {
|
||||
Oauth: "https://login.chinacloudapi.cn",
|
||||
Api: "https://microsoftgraph.chinacloudapi.cn",
|
||||
},
|
||||
"us": {
|
||||
Oauth: "https://login.microsoftonline.us",
|
||||
Api: "https://graph.microsoft.us",
|
||||
},
|
||||
"de": {
|
||||
Oauth: "https://login.microsoftonline.de",
|
||||
Api: "https://graph.microsoft.de",
|
||||
},
|
||||
}
|
||||
|
||||
func EncodePath(path string, all ...bool) string {
|
||||
seg := strings.Split(path, "/")
|
||||
toReplace := []struct {
|
||||
Src string
|
||||
Dst string
|
||||
}{
|
||||
{Src: "%", Dst: "%25"},
|
||||
{"%", "%25"},
|
||||
{"?", "%3F"},
|
||||
{"#", "%23"},
|
||||
}
|
||||
for i := range seg {
|
||||
if len(all) > 0 && all[0] {
|
||||
seg[i] = url.PathEscape(seg[i])
|
||||
} else {
|
||||
for j := range toReplace {
|
||||
seg[i] = strings.ReplaceAll(seg[i], toReplace[j].Src, toReplace[j].Dst)
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings.Join(seg, "/")
|
||||
}
|
||||
func (d *Onedrive) GetMetaUrl(auth bool, path string) string {
|
||||
host := onedriveHostMap[d.Region]
|
||||
path = EncodePath(path, true)
|
||||
if auth {
|
||||
return host.Oauth
|
||||
}
|
||||
if d.IsSharepoint {
|
||||
if path == "/" || path == "\\" {
|
||||
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root", host.Api, d.SiteId)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root:%s:", host.Api, d.SiteId, path)
|
||||
}
|
||||
} else {
|
||||
if path == "/" || path == "\\" {
|
||||
return fmt.Sprintf("%s/v1.0/me/drive/root", host.Api)
|
||||
} else {
|
||||
return fmt.Sprintf("%s/v1.0/me/drive/root:%s:", host.Api, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Onedrive) refreshToken() error {
|
||||
var err error
|
||||
for i := 0; i < 3; i++ {
|
||||
err = d._refreshToken()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (d *Onedrive) getRefreshToken() error {
|
||||
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenErr
|
||||
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||
"grant_type": "authorization_code",
|
||||
"client_id": d.ClientID,
|
||||
"client_secret": d.ClientSecret,
|
||||
"code": d.Code,
|
||||
"redirect_uri": d.RedirectUri,
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf("%s", e.ErrorDescription)
|
||||
}
|
||||
if resp.RefreshToken == "" {
|
||||
return errors.New("refresh token is empty")
|
||||
}
|
||||
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) _refreshToken() error {
|
||||
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||
var resp base.TokenResp
|
||||
var e TokenErr
|
||||
|
||||
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": d.ClientID,
|
||||
"client_secret": d.ClientSecret,
|
||||
"redirect_uri": d.RedirectUri,
|
||||
"refresh_token": d.RefreshToken,
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||
if e.Error != "" {
|
||||
return fmt.Errorf("%s", e.ErrorDescription)
|
||||
}
|
||||
if resp.RefreshToken == "" {
|
||||
return errors.New("refresh token is empty")
|
||||
}
|
||||
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Onedrive) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||
req := base.RestyClient.R()
|
||||
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
|
||||
if callback != nil {
|
||||
callback(req)
|
||||
}
|
||||
if resp != nil {
|
||||
req.SetResult(resp)
|
||||
}
|
||||
var e RespErr
|
||||
req.SetError(&e)
|
||||
res, err := req.Execute(method, url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if e.Error.Code != "" {
|
||||
if e.Error.Code == "InvalidAuthenticationToken" {
|
||||
err = d.refreshToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return d.Request(url, method, callback, resp)
|
||||
}
|
||||
return nil, errors.New(e.Error.Message)
|
||||
}
|
||||
return res.Body(), nil
|
||||
}
|
||||
|
||||
func GetConfig() Onedrive {
|
||||
config := Onedrive{}
|
||||
config.ClientID = client_id
|
||||
config.ClientSecret = client_secret
|
||||
config.RootFolderID = "/"
|
||||
config.AuthUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + client_id + "&response_type=code&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=offline_access+files.readwrite.all&state=${HOST}%2Fv1%2Frecover%2FOnedrive"
|
||||
config.Icon = "./img/driver/OneDrive.svg"
|
||||
config.Region = "global"
|
||||
config.RedirectUri = "https://cloudoauth.files.casaos.app"
|
||||
|
||||
return config
|
||||
}
|
||||
192
go.mod
192
go.mod
@@ -1,72 +1,138 @@
|
||||
module github.com/IceWhaleTech/CasaOS
|
||||
|
||||
go 1.16
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.5.0 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.22 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.7.0
|
||||
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.1 // indirect
|
||||
github.com/containerd/containerd v1.5.7
|
||||
github.com/containerd/continuity v0.2.0 // indirect
|
||||
github.com/docker/docker v20.10.7+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
|
||||
github.com/gin-contrib/gzip v0.0.2 // indirect
|
||||
github.com/gin-gonic/gin v1.7.2
|
||||
github.com/go-ini/ini v1.62.0
|
||||
github.com/go-ole/go-ole v1.2.5 // indirect
|
||||
github.com/go-openapi/spec v0.20.4 // indirect
|
||||
github.com/go-playground/validator/v10 v10.6.1 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/gomodule/redigo v1.8.5
|
||||
github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
|
||||
github.com/IceWhaleTech/CasaOS-Common v0.4.7-alpha4
|
||||
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
|
||||
github.com/deckarep/golang-set/v2 v2.3.0
|
||||
github.com/deepmap/oapi-codegen v1.12.4
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20221012082141-d21ac8e2de85
|
||||
github.com/getkin/kin-openapi v0.115.0
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-gonic/gin v1.9.0
|
||||
github.com/glebarez/sqlite v1.7.0
|
||||
github.com/go-ini/ini v1.67.0
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/gomodule/redigo v1.8.9
|
||||
github.com/google/go-github/v36 v36.0.0
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/jinzhu/copier v0.3.2
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/klauspost/compress v1.13.6 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/opencontainers/selinux v1.8.5 // indirect
|
||||
github.com/googollee/go-socket.io v1.7.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/h2non/filetype v1.1.3
|
||||
github.com/hirochachacha/go-smb2 v1.1.0
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/maruel/natural v1.1.0
|
||||
github.com/mholt/archiver/v3 v3.5.1
|
||||
github.com/mileusna/useragent v1.2.1
|
||||
github.com/moby/sys/mount v0.3.3
|
||||
github.com/moby/sys/mountinfo v0.6.2
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prestonTao/upnp v0.0.0-20150206124352-f4370df5e109
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/robfig/cron v1.2.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/samber/lo v1.38.1
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/shirou/gopsutil/v3 v3.21.5
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/smartystreets/assertions v1.2.0 // indirect
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/swaggo/gin-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.7.3
|
||||
github.com/tidwall/gjson v1.10.2
|
||||
github.com/tidwall/sjson v1.2.3
|
||||
github.com/tklauser/go-sysconf v0.3.6 // indirect
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||
golang.org/x/mod v0.5.0 // indirect
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f
|
||||
golang.org/x/sys v0.0.0-20211020174200-9d6173849985 // indirect
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
golang.org/x/tools v0.1.7 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 // indirect
|
||||
google.golang.org/grpc v1.41.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
gorm.io/driver/sqlite v1.1.5
|
||||
gorm.io/gorm v1.21.15
|
||||
github.com/shirou/gopsutil/v3 v3.23.2
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
go.uber.org/goleak v1.2.1
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.8.0
|
||||
golang.org/x/oauth2 v0.6.0
|
||||
golang.org/x/sync v0.1.0
|
||||
golang.org/x/sys v0.7.0
|
||||
gorm.io/gorm v1.24.6
|
||||
gotest.tools v2.2.0+incompatible
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/bytedance/sonic v1.8.5 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
|
||||
github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
|
||||
github.com/dsoprea/go-utility/v2 v2.0.0-20221003172846-a3e1774ef349 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/geoffgarside/ber v1.1.0 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.0 // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.12.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/godbus/dbus/v5 v5.1.0 // indirect
|
||||
github.com/gofrs/uuid v4.4.0+incompatible // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
|
||||
github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/invopop/yaml v0.2.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.16.5 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.3 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20230110061619-bbe2e5e100de // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
|
||||
github.com/nwaples/rardecode v1.1.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.7 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.17 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
github.com/ulikunitz/xz v0.5.11 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||
golang.org/x/image v0.6.0 // indirect
|
||||
golang.org/x/net v0.9.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.22.3 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/sqlite v1.21.0 // indirect
|
||||
)
|
||||
|
||||
18
interfaces/migrationTool.go
Normal file
18
interfaces/migrationTool.go
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.org
|
||||
* @Date: 2022-08-24 17:37:36
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-08-24 17:38:48
|
||||
* @FilePath: /CasaOS/interfaces/migrationTool.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package interfaces
|
||||
|
||||
type MigrationTool interface {
|
||||
IsMigrationNeeded() (bool, error)
|
||||
PostMigrate() error
|
||||
Migrate() error
|
||||
PreMigrate() error
|
||||
}
|
||||
43
internal/conf/config.go
Normal file
43
internal/conf/config.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package conf
|
||||
|
||||
type Database struct {
|
||||
Type string `json:"type" env:"DB_TYPE"`
|
||||
Host string `json:"host" env:"DB_HOST"`
|
||||
Port int `json:"port" env:"DB_PORT"`
|
||||
User string `json:"user" env:"DB_USER"`
|
||||
Password string `json:"password" env:"DB_PASS"`
|
||||
Name string `json:"name" env:"DB_NAME"`
|
||||
DBFile string `json:"db_file" env:"DB_FILE"`
|
||||
TablePrefix string `json:"table_prefix" env:"DB_TABLE_PREFIX"`
|
||||
SSLMode string `json:"ssl_mode" env:"DB_SSL_MODE"`
|
||||
}
|
||||
|
||||
type Scheme struct {
|
||||
Https bool `json:"https" env:"HTTPS"`
|
||||
CertFile string `json:"cert_file" env:"CERT_FILE"`
|
||||
KeyFile string `json:"key_file" env:"KEY_FILE"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
Enable bool `json:"enable" env:"LOG_ENABLE"`
|
||||
Name string `json:"name" env:"LOG_NAME"`
|
||||
MaxSize int `json:"max_size" env:"MAX_SIZE"`
|
||||
MaxBackups int `json:"max_backups" env:"MAX_BACKUPS"`
|
||||
MaxAge int `json:"max_age" env:"MAX_AGE"`
|
||||
Compress bool `json:"compress" env:"COMPRESS"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Force bool `json:"force" env:"FORCE"`
|
||||
Address string `json:"address" env:"ADDR"`
|
||||
Port int `json:"port" env:"PORT"`
|
||||
SiteURL string `json:"site_url" env:"SITE_URL"`
|
||||
Cdn string `json:"cdn" env:"CDN"`
|
||||
JwtSecret string `json:"jwt_secret" env:"JWT_SECRET"`
|
||||
TokenExpiresIn int `json:"token_expires_in" env:"TOKEN_EXPIRES_IN"`
|
||||
Database Database `json:"database"`
|
||||
Scheme Scheme `json:"scheme"`
|
||||
TempDir string `json:"temp_dir" env:"TEMP_DIR"`
|
||||
BleveDir string `json:"bleve_dir" env:"BLEVE_DIR"`
|
||||
Log LogConfig `json:"log"`
|
||||
}
|
||||
72
internal/conf/const.go
Normal file
72
internal/conf/const.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package conf
|
||||
|
||||
const (
|
||||
TypeString = "string"
|
||||
TypeSelect = "select"
|
||||
TypeBool = "bool"
|
||||
TypeText = "text"
|
||||
TypeNumber = "number"
|
||||
)
|
||||
|
||||
const (
|
||||
// site
|
||||
VERSION = "version"
|
||||
ApiUrl = "api_url"
|
||||
BasePath = "base_path"
|
||||
SiteTitle = "site_title"
|
||||
Announcement = "announcement"
|
||||
AllowIndexed = "allow_indexed"
|
||||
|
||||
Logo = "logo"
|
||||
Favicon = "favicon"
|
||||
MainColor = "main_color"
|
||||
|
||||
// preview
|
||||
TextTypes = "text_types"
|
||||
AudioTypes = "audio_types"
|
||||
VideoTypes = "video_types"
|
||||
ImageTypes = "image_types"
|
||||
ProxyTypes = "proxy_types"
|
||||
ProxyIgnoreHeaders = "proxy_ignore_headers"
|
||||
AudioAutoplay = "audio_autoplay"
|
||||
VideoAutoplay = "video_autoplay"
|
||||
|
||||
// global
|
||||
HideFiles = "hide_files"
|
||||
CustomizeHead = "customize_head"
|
||||
CustomizeBody = "customize_body"
|
||||
LinkExpiration = "link_expiration"
|
||||
SignAll = "sign_all"
|
||||
PrivacyRegs = "privacy_regs"
|
||||
OcrApi = "ocr_api"
|
||||
FilenameCharMapping = "filename_char_mapping"
|
||||
|
||||
// index
|
||||
SearchIndex = "search_index"
|
||||
AutoUpdateIndex = "auto_update_index"
|
||||
IndexPaths = "index_paths"
|
||||
IgnorePaths = "ignore_paths"
|
||||
|
||||
// aria2
|
||||
Aria2Uri = "aria2_uri"
|
||||
Aria2Secret = "aria2_secret"
|
||||
|
||||
// single
|
||||
Token = "token"
|
||||
IndexProgress = "index_progress"
|
||||
|
||||
//Github
|
||||
GithubClientId = "github_client_id"
|
||||
GithubClientSecrets = "github_client_secrets"
|
||||
GithubLoginEnabled = "github_login_enabled"
|
||||
)
|
||||
|
||||
const (
|
||||
UNKNOWN = iota
|
||||
FOLDER
|
||||
//OFFICE
|
||||
VIDEO
|
||||
AUDIO
|
||||
TEXT
|
||||
IMAGE
|
||||
)
|
||||
30
internal/conf/var.go
Normal file
30
internal/conf/var.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package conf
|
||||
|
||||
import "regexp"
|
||||
|
||||
var (
|
||||
BuiltAt string
|
||||
GoVersion string
|
||||
GitAuthor string
|
||||
GitCommit string
|
||||
Version string = "dev"
|
||||
WebVersion string
|
||||
)
|
||||
|
||||
var (
|
||||
Conf *Config
|
||||
)
|
||||
|
||||
var SlicesMap = make(map[string][]string)
|
||||
var FilenameCharMap = make(map[string]string)
|
||||
var PrivacyReg []*regexp.Regexp
|
||||
|
||||
var (
|
||||
// StoragesLoaded loaded success if empty
|
||||
StoragesLoaded = false
|
||||
)
|
||||
var (
|
||||
RawIndexHtml string
|
||||
ManageHtml string
|
||||
IndexHtml string
|
||||
)
|
||||
25
internal/driver/config.go
Normal file
25
internal/driver/config.go
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* @Author: a624669980@163.com a624669980@163.com
|
||||
* @Date: 2022-12-13 11:05:05
|
||||
* @LastEditors: a624669980@163.com a624669980@163.com
|
||||
* @LastEditTime: 2022-12-13 11:05:13
|
||||
* @FilePath: /drive/internal/driver/config.go
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
package driver
|
||||
|
||||
type Config struct {
|
||||
Name string `json:"name"`
|
||||
LocalSort bool `json:"local_sort"`
|
||||
OnlyLocal bool `json:"only_local"`
|
||||
OnlyProxy bool `json:"only_proxy"`
|
||||
NoCache bool `json:"no_cache"`
|
||||
NoUpload bool `json:"no_upload"`
|
||||
NeedMs bool `json:"need_ms"` // if need get message from user, such as validate code
|
||||
DefaultRoot string `json:"default_root"`
|
||||
CheckStatus bool
|
||||
}
|
||||
|
||||
func (c Config) MustProxy() bool {
|
||||
return c.OnlyProxy || c.OnlyLocal
|
||||
}
|
||||
133
internal/driver/driver.go
Normal file
133
internal/driver/driver.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package driver
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
)
|
||||
|
||||
type Driver interface {
|
||||
Meta
|
||||
Reader
|
||||
User
|
||||
//Writer
|
||||
//Other
|
||||
}
|
||||
|
||||
type Meta interface {
|
||||
Config() Config
|
||||
// GetStorage just get raw storage, no need to implement, because model.Storage have implemented
|
||||
GetStorage() *model.StorageA
|
||||
SetStorage(model.StorageA)
|
||||
// GetAddition Additional is used for unmarshal of JSON, so need return pointer
|
||||
GetAddition() Additional
|
||||
// Init If already initialized, drop first
|
||||
Init(ctx context.Context) error
|
||||
Drop(ctx context.Context) error
|
||||
}
|
||||
|
||||
type Other interface {
|
||||
Other(ctx context.Context, args model.OtherArgs) (interface{}, error)
|
||||
}
|
||||
|
||||
type Reader interface {
|
||||
// List files in the path
|
||||
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
||||
// if identify files by id, need to set ID with corresponding id
|
||||
// List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
||||
// Link get url/filepath/reader of file
|
||||
// Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
||||
}
|
||||
type User interface {
|
||||
// GetRoot get root directory of user
|
||||
GetUserInfo(ctx context.Context) (string, error)
|
||||
GetInfo(ctx context.Context) (string, string, string, error)
|
||||
}
|
||||
|
||||
type Getter interface {
|
||||
GetRoot(ctx context.Context) (model.Obj, error)
|
||||
}
|
||||
|
||||
//type Writer interface {
|
||||
// Mkdir
|
||||
// Move
|
||||
// Rename
|
||||
// Copy
|
||||
// Remove
|
||||
// Put
|
||||
//}
|
||||
|
||||
type Mkdir interface {
|
||||
MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error
|
||||
}
|
||||
|
||||
type Move interface {
|
||||
Move(ctx context.Context, srcObj, dstDir model.Obj) error
|
||||
}
|
||||
|
||||
type Rename interface {
|
||||
Rename(ctx context.Context, srcObj model.Obj, newName string) error
|
||||
}
|
||||
|
||||
type Copy interface {
|
||||
Copy(ctx context.Context, srcObj, dstDir model.Obj) error
|
||||
}
|
||||
|
||||
type Remove interface {
|
||||
Remove(ctx context.Context, obj model.Obj) error
|
||||
}
|
||||
|
||||
type Put interface {
|
||||
Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up UpdateProgress) error
|
||||
}
|
||||
|
||||
//type WriteResult interface {
|
||||
// MkdirResult
|
||||
// MoveResult
|
||||
// RenameResult
|
||||
// CopyResult
|
||||
// PutResult
|
||||
// Remove
|
||||
//}
|
||||
|
||||
type MkdirResult interface {
|
||||
MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error)
|
||||
}
|
||||
|
||||
type MoveResult interface {
|
||||
Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error)
|
||||
}
|
||||
|
||||
type RenameResult interface {
|
||||
Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error)
|
||||
}
|
||||
|
||||
type CopyResult interface {
|
||||
Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error)
|
||||
}
|
||||
|
||||
type PutResult interface {
|
||||
Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up UpdateProgress) (model.Obj, error)
|
||||
}
|
||||
|
||||
type UpdateProgress func(percentage int)
|
||||
|
||||
type Progress struct {
|
||||
Total int64
|
||||
Done int64
|
||||
up UpdateProgress
|
||||
}
|
||||
|
||||
func (p *Progress) Write(b []byte) (n int, err error) {
|
||||
n = len(b)
|
||||
p.Done += int64(n)
|
||||
p.up(int(float64(p.Done) / float64(p.Total) * 100))
|
||||
return
|
||||
}
|
||||
|
||||
func NewProgress(total int64, up UpdateProgress) *Progress {
|
||||
return &Progress{
|
||||
Total: total,
|
||||
up: up,
|
||||
}
|
||||
}
|
||||
56
internal/driver/item.go
Normal file
56
internal/driver/item.go
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* @Author: a624669980@163.com a624669980@163.com
|
||||
* @Date: 2022-12-13 11:05:47
|
||||
* @LastEditors: a624669980@163.com a624669980@163.com
|
||||
* @LastEditTime: 2022-12-13 11:05:54
|
||||
* @FilePath: /drive/internal/driver/item.go
|
||||
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||
*/
|
||||
package driver
|
||||
|
||||
type Additional interface{}
|
||||
|
||||
type Select string
|
||||
|
||||
type Item struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Default string `json:"default"`
|
||||
Options string `json:"options"`
|
||||
Required bool `json:"required"`
|
||||
Help string `json:"help"`
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Common []Item `json:"common"`
|
||||
Additional []Item `json:"additional"`
|
||||
Config Config `json:"config"`
|
||||
}
|
||||
|
||||
type IRootPath interface {
|
||||
GetRootPath() string
|
||||
}
|
||||
|
||||
type IRootId interface {
|
||||
GetRootId() string
|
||||
}
|
||||
|
||||
type RootPath struct {
|
||||
RootFolderPath string `json:"root_folder_path"`
|
||||
}
|
||||
|
||||
type RootID struct {
|
||||
RootFolderID string `json:"root_folder_id" omit:"true"`
|
||||
}
|
||||
|
||||
func (r RootPath) GetRootPath() string {
|
||||
return r.RootFolderPath
|
||||
}
|
||||
|
||||
func (r *RootPath) SetRootPath(path string) {
|
||||
r.RootFolderPath = path
|
||||
}
|
||||
|
||||
func (r RootID) GetRootId() string {
|
||||
return r.RootFolderID
|
||||
}
|
||||
6
internal/op/const.go
Normal file
6
internal/op/const.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package op
|
||||
|
||||
const (
|
||||
WORK = "work"
|
||||
RootName = "root"
|
||||
)
|
||||
173
internal/op/driver.go
Normal file
173
internal/op/driver.go
Normal file
@@ -0,0 +1,173 @@
|
||||
package op
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/internal/conf"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type New func() driver.Driver
|
||||
|
||||
var driverNewMap = map[string]New{}
|
||||
var driverInfoMap = map[string][]driver.Item{} //driver.Info{}
|
||||
|
||||
func RegisterDriver(driver New) {
|
||||
// log.Infof("register driver: [%s]", config.Name)
|
||||
tempDriver := driver()
|
||||
tempConfig := tempDriver.Config()
|
||||
registerDriverItems(tempConfig, tempDriver.GetAddition())
|
||||
driverNewMap[tempConfig.Name] = driver
|
||||
}
|
||||
|
||||
func GetDriverNew(name string) (New, error) {
|
||||
n, ok := driverNewMap[name]
|
||||
if !ok {
|
||||
return nil, errors.Errorf("no driver named: %s", name)
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func GetDriverNames() []string {
|
||||
var driverNames []string
|
||||
for k := range driverInfoMap {
|
||||
driverNames = append(driverNames, k)
|
||||
}
|
||||
return driverNames
|
||||
}
|
||||
|
||||
// func GetDriverInfoMap() map[string]driver.Info {
|
||||
// return driverInfoMap
|
||||
// }
|
||||
func GetDriverInfoMap() map[string][]driver.Item {
|
||||
return driverInfoMap
|
||||
}
|
||||
func registerDriverItems(config driver.Config, addition driver.Additional) {
|
||||
// log.Debugf("addition of %s: %+v", config.Name, addition)
|
||||
tAddition := reflect.TypeOf(addition)
|
||||
for tAddition.Kind() == reflect.Pointer {
|
||||
tAddition = tAddition.Elem()
|
||||
}
|
||||
//mainItems := getMainItems(config)
|
||||
additionalItems := getAdditionalItems(tAddition, config.DefaultRoot)
|
||||
driverInfoMap[config.Name] = additionalItems
|
||||
// driver.Info{
|
||||
// Common: mainItems,
|
||||
// Additional: additionalItems,
|
||||
// Config: config,
|
||||
// }
|
||||
}
|
||||
|
||||
func getMainItems(config driver.Config) []driver.Item {
|
||||
items := []driver.Item{{
|
||||
Name: "mount_path",
|
||||
Type: conf.TypeString,
|
||||
Required: true,
|
||||
Help: "",
|
||||
}, {
|
||||
Name: "order",
|
||||
Type: conf.TypeNumber,
|
||||
Help: "use to sort",
|
||||
}, {
|
||||
Name: "remark",
|
||||
Type: conf.TypeText,
|
||||
}}
|
||||
if !config.NoCache {
|
||||
items = append(items, driver.Item{
|
||||
Name: "cache_expiration",
|
||||
Type: conf.TypeNumber,
|
||||
Default: "30",
|
||||
Required: true,
|
||||
Help: "The cache expiration time for this storage",
|
||||
})
|
||||
}
|
||||
if !config.OnlyProxy && !config.OnlyLocal {
|
||||
items = append(items, []driver.Item{{
|
||||
Name: "web_proxy",
|
||||
Type: conf.TypeBool,
|
||||
}, {
|
||||
Name: "webdav_policy",
|
||||
Type: conf.TypeSelect,
|
||||
Options: "302_redirect,use_proxy_url,native_proxy",
|
||||
Default: "302_redirect",
|
||||
Required: true,
|
||||
},
|
||||
}...)
|
||||
} else {
|
||||
items = append(items, driver.Item{
|
||||
Name: "webdav_policy",
|
||||
Type: conf.TypeSelect,
|
||||
Default: "native_proxy",
|
||||
Options: "use_proxy_url,native_proxy",
|
||||
Required: true,
|
||||
})
|
||||
}
|
||||
items = append(items, driver.Item{
|
||||
Name: "down_proxy_url",
|
||||
Type: conf.TypeText,
|
||||
})
|
||||
if config.LocalSort {
|
||||
items = append(items, []driver.Item{{
|
||||
Name: "order_by",
|
||||
Type: conf.TypeSelect,
|
||||
Options: "name,size,modified",
|
||||
}, {
|
||||
Name: "order_direction",
|
||||
Type: conf.TypeSelect,
|
||||
Options: "asc,desc",
|
||||
}}...)
|
||||
}
|
||||
items = append(items, driver.Item{
|
||||
Name: "extract_folder",
|
||||
Type: conf.TypeSelect,
|
||||
Options: "front,back",
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
func getAdditionalItems(t reflect.Type, defaultRoot string) []driver.Item {
|
||||
var items []driver.Item
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
|
||||
field := t.Field(i)
|
||||
if field.Type.Kind() == reflect.Struct {
|
||||
items = append(items, getAdditionalItems(field.Type, defaultRoot)...)
|
||||
continue
|
||||
}
|
||||
tag := field.Tag
|
||||
ignore, ok1 := tag.Lookup("ignore")
|
||||
name, ok2 := tag.Lookup("json")
|
||||
if (ok1 && ignore == "true") || !ok2 {
|
||||
continue
|
||||
}
|
||||
if tag.Get("omit") == "true" {
|
||||
continue
|
||||
}
|
||||
item := driver.Item{
|
||||
Name: name,
|
||||
Type: strings.ToLower(field.Type.Name()),
|
||||
Default: tag.Get("default"),
|
||||
Options: tag.Get("options"),
|
||||
Required: tag.Get("required") == "true",
|
||||
Help: tag.Get("help"),
|
||||
}
|
||||
if tag.Get("type") != "" {
|
||||
item.Type = tag.Get("type")
|
||||
}
|
||||
if item.Name == "root_folder_id" || item.Name == "root_folder_path" {
|
||||
if item.Default == "" {
|
||||
item.Default = defaultRoot
|
||||
}
|
||||
item.Required = item.Default != ""
|
||||
}
|
||||
// set default type to string
|
||||
if item.Type == "" {
|
||||
item.Type = "string"
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
return items
|
||||
}
|
||||
109
internal/op/hook.go
Normal file
109
internal/op/hook.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package op
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/conf"
|
||||
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||
"github.com/IceWhaleTech/CasaOS/model"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Obj
|
||||
type ObjsUpdateHook = func(parent string, objs []model.Obj)
|
||||
|
||||
var (
|
||||
ObjsUpdateHooks = make([]ObjsUpdateHook, 0)
|
||||
)
|
||||
|
||||
func RegisterObjsUpdateHook(hook ObjsUpdateHook) {
|
||||
ObjsUpdateHooks = append(ObjsUpdateHooks, hook)
|
||||
}
|
||||
|
||||
func HandleObjsUpdateHook(parent string, objs []model.Obj) {
|
||||
for _, hook := range ObjsUpdateHooks {
|
||||
hook(parent, objs)
|
||||
}
|
||||
}
|
||||
|
||||
// Setting
|
||||
type SettingItemHook func(item *model.SettingItem) error
|
||||
|
||||
var settingItemHooks = map[string]SettingItemHook{
|
||||
conf.VideoTypes: func(item *model.SettingItem) error {
|
||||
conf.SlicesMap[conf.VideoTypes] = strings.Split(item.Value, ",")
|
||||
return nil
|
||||
},
|
||||
conf.AudioTypes: func(item *model.SettingItem) error {
|
||||
conf.SlicesMap[conf.AudioTypes] = strings.Split(item.Value, ",")
|
||||
return nil
|
||||
},
|
||||
conf.ImageTypes: func(item *model.SettingItem) error {
|
||||
conf.SlicesMap[conf.ImageTypes] = strings.Split(item.Value, ",")
|
||||
return nil
|
||||
},
|
||||
conf.TextTypes: func(item *model.SettingItem) error {
|
||||
conf.SlicesMap[conf.TextTypes] = strings.Split(item.Value, ",")
|
||||
return nil
|
||||
},
|
||||
conf.ProxyTypes: func(item *model.SettingItem) error {
|
||||
conf.SlicesMap[conf.ProxyTypes] = strings.Split(item.Value, ",")
|
||||
return nil
|
||||
},
|
||||
conf.ProxyIgnoreHeaders: func(item *model.SettingItem) error {
|
||||
conf.SlicesMap[conf.ProxyIgnoreHeaders] = strings.Split(item.Value, ",")
|
||||
return nil
|
||||
},
|
||||
conf.PrivacyRegs: func(item *model.SettingItem) error {
|
||||
regStrs := strings.Split(item.Value, "\n")
|
||||
regs := make([]*regexp.Regexp, 0, len(regStrs))
|
||||
for _, regStr := range regStrs {
|
||||
reg, err := regexp.Compile(regStr)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
regs = append(regs, reg)
|
||||
}
|
||||
conf.PrivacyReg = regs
|
||||
return nil
|
||||
},
|
||||
conf.FilenameCharMapping: func(item *model.SettingItem) error {
|
||||
var json = jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
err := json.UnmarshalFromString(item.Value, &conf.FilenameCharMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.Info("filename char mapping", zap.Any("FilenameCharMap", conf.FilenameCharMap))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func RegisterSettingItemHook(key string, hook SettingItemHook) {
|
||||
settingItemHooks[key] = hook
|
||||
}
|
||||
|
||||
func HandleSettingItemHook(item *model.SettingItem) (hasHook bool, err error) {
|
||||
if hook, ok := settingItemHooks[item.Key]; ok {
|
||||
return true, hook(item)
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Storage
|
||||
type StorageHook func(typ string, storage driver.Driver)
|
||||
|
||||
var storageHooks = make([]StorageHook, 0)
|
||||
|
||||
func CallStorageHooks(typ string, storage driver.Driver) {
|
||||
for _, hook := range storageHooks {
|
||||
hook(typ, storage)
|
||||
}
|
||||
}
|
||||
|
||||
func RegisterStorageHook(hook StorageHook) {
|
||||
storageHooks = append(storageHooks, hook)
|
||||
}
|
||||
36
internal/sign/sign.go
Normal file
36
internal/sign/sign.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/sign"
|
||||
)
|
||||
|
||||
var once sync.Once
|
||||
var instance sign.Sign
|
||||
|
||||
func Sign(data string) string {
|
||||
|
||||
return NotExpired(data)
|
||||
|
||||
}
|
||||
|
||||
func WithDuration(data string, d time.Duration) string {
|
||||
once.Do(Instance)
|
||||
return instance.Sign(data, time.Now().Add(d).Unix())
|
||||
}
|
||||
|
||||
func NotExpired(data string) string {
|
||||
once.Do(Instance)
|
||||
return instance.Sign(data, 0)
|
||||
}
|
||||
|
||||
func Verify(data string, sign string) error {
|
||||
once.Do(Instance)
|
||||
return instance.Verify(data, sign)
|
||||
}
|
||||
|
||||
func Instance() {
|
||||
instance = sign.NewHMACSign([]byte("token"))
|
||||
}
|
||||
216
main.go
216
main.go
@@ -1,38 +1,92 @@
|
||||
//go:generate bash -c "mkdir -p codegen && go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 -generate types,server,spec -package codegen api/casaos/openapi.yaml > codegen/casaos_api.go"
|
||||
//go:generate bash -c "mkdir -p codegen/message_bus && go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.12.4 -generate types,client -package message_bus https://raw.githubusercontent.com/IceWhaleTech/CasaOS-MessageBus/main/api/message_bus/openapi.yaml > codegen/message_bus/api.go"
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/model"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||
|
||||
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/common"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/cache"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/config"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
|
||||
loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
"github.com/IceWhaleTech/CasaOS/route"
|
||||
"github.com/IceWhaleTech/CasaOS/service"
|
||||
"github.com/coreos/go-systemd/daemon"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/robfig/cron"
|
||||
"github.com/robfig/cron/v3"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
const LOCALHOST = "127.0.0.1"
|
||||
|
||||
var sqliteDB *gorm.DB
|
||||
|
||||
var configFlag = flag.String("c", "", "config address")
|
||||
var (
|
||||
commit = "private build"
|
||||
date = "private build"
|
||||
|
||||
var showUserInfo = flag.Bool("show-user-info", false, "show user info")
|
||||
//go:embed api/index.html
|
||||
_docHTML string
|
||||
|
||||
//go:embed api/casaos/openapi.yaml
|
||||
_docYAML string
|
||||
|
||||
//go:embed build/sysroot/etc/casaos/casaos.conf.sample
|
||||
_confSample string
|
||||
|
||||
configFlag = flag.String("c", "", "config address")
|
||||
dbFlag = flag.String("db", "", "db path")
|
||||
versionFlag = flag.Bool("v", false, "version")
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.Parse()
|
||||
config.InitSetup(*configFlag)
|
||||
config.UpdateSetup()
|
||||
loger2.LogSetup()
|
||||
sqliteDB = sqlite.GetDb(config.AppInfo.ProjectPath)
|
||||
//gredis.GetRedisConn(config.RedisInfo),
|
||||
service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
|
||||
if *versionFlag {
|
||||
fmt.Println("v" + common.VERSION)
|
||||
return
|
||||
}
|
||||
|
||||
println("git commit:", commit)
|
||||
println("build date:", date)
|
||||
|
||||
config.InitSetup(*configFlag, _confSample)
|
||||
|
||||
logger.LogInit(config.AppInfo.LogPath, config.AppInfo.LogSaveName, config.AppInfo.LogFileExt)
|
||||
if len(*dbFlag) == 0 {
|
||||
*dbFlag = config.AppInfo.DBPath + "/db"
|
||||
}
|
||||
|
||||
sqliteDB = sqlite.GetDb(*dbFlag)
|
||||
// gredis.GetRedisConn(config.RedisInfo),
|
||||
|
||||
service.MyService = service.NewService(sqliteDB, config.CommonInfo.RuntimePath)
|
||||
|
||||
service.Cache = cache.Init()
|
||||
|
||||
service.GetCPUThermalZone()
|
||||
|
||||
route.InitFunction()
|
||||
|
||||
//service.MyService.System().GenreateSystemEntry()
|
||||
///
|
||||
//service.MountLists = make(map[string]*mountlib.MountPoint)
|
||||
//configfile.Install()
|
||||
}
|
||||
|
||||
// @title casaOS API
|
||||
@@ -47,36 +101,130 @@ func init() {
|
||||
// @name Authorization
|
||||
// @BasePath /v1
|
||||
func main() {
|
||||
if *showUserInfo {
|
||||
fmt.Println("CasaOS User Info")
|
||||
fmt.Println("UserName:" + config.UserInfo.UserName)
|
||||
fmt.Println("Password:" + config.UserInfo.PWD)
|
||||
if *versionFlag {
|
||||
return
|
||||
}
|
||||
//model.Setup()
|
||||
//gredis.Setup()
|
||||
r := route.InitRouter()
|
||||
//service.SyncTask(sqliteDB)
|
||||
cron2 := cron.New() //创建一个cron实例
|
||||
//执行定时任务(每5秒执行一次)
|
||||
err := cron2.AddFunc("0 0 0 1/1 * *", func() {
|
||||
//service.UpdataDDNSList(mysqldb)
|
||||
//service.SyncTask(sqliteDB)
|
||||
})
|
||||
v1Router := route.InitV1Router()
|
||||
|
||||
v2Router := route.InitV2Router()
|
||||
v2DocRouter := route.InitV2DocRouter(_docHTML, _docYAML)
|
||||
v3File := route.InitFile()
|
||||
mux := &util_http.HandlerMultiplexer{
|
||||
HandlerMap: map[string]http.Handler{
|
||||
"v1": v1Router,
|
||||
"v2": v2Router,
|
||||
"v3": v3File,
|
||||
"doc": v2DocRouter,
|
||||
},
|
||||
}
|
||||
|
||||
crontab := cron.New(cron.WithSeconds())
|
||||
if _, err := crontab.AddFunc("@every 5s", route.SendAllHardwareStatusBySocket); err != nil {
|
||||
logger.Error("add crontab error", zap.Error(err))
|
||||
}
|
||||
|
||||
crontab.Start()
|
||||
defer crontab.Stop()
|
||||
|
||||
listener, err := net.Listen("tcp", net.JoinHostPort(LOCALHOST, "0"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
panic(err)
|
||||
}
|
||||
routers := []string{
|
||||
"/v1/sys",
|
||||
"/v1/port",
|
||||
"/v1/file",
|
||||
"/v1/folder",
|
||||
"/v1/batch",
|
||||
"/v1/image",
|
||||
"/v1/samba",
|
||||
"/v1/notify",
|
||||
"/v1/driver",
|
||||
"/v1/cloud",
|
||||
"/v1/recover",
|
||||
"/v1/other",
|
||||
"/v1/zt",
|
||||
"/v1/test",
|
||||
route.V2APIPath,
|
||||
route.V2DocPath,
|
||||
route.V3FilePath,
|
||||
}
|
||||
for _, apiPath := range routers {
|
||||
err = service.MyService.Gateway().CreateRoute(&model.Route{
|
||||
Path: apiPath,
|
||||
Target: "http://" + listener.Addr().String(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("err", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
//启动/关闭
|
||||
cron2.Start()
|
||||
defer cron2.Stop()
|
||||
// register at message bus
|
||||
for i := 0; i < 10; i++ {
|
||||
response, err := service.MyService.MessageBus().RegisterEventTypesWithResponse(context.Background(), common.EventTypes)
|
||||
if err != nil {
|
||||
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.Error(err))
|
||||
}
|
||||
if response != nil && response.StatusCode() != http.StatusOK {
|
||||
logger.Error("error when trying to register one or more event types - some event type will not be discoverable", zap.String("status", response.Status()), zap.String("body", string(response.Body)))
|
||||
}
|
||||
if response.StatusCode() == http.StatusOK {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
go func() {
|
||||
time.Sleep(time.Second * 2)
|
||||
// v0.3.6
|
||||
if config.ServerInfo.HttpPort != "" {
|
||||
changePort := model.ChangePortRequest{}
|
||||
changePort.Port = config.ServerInfo.HttpPort
|
||||
err := service.MyService.Gateway().ChangePort(&changePort)
|
||||
if err == nil {
|
||||
config.Cfg.Section("server").Key("HttpPort").SetValue("")
|
||||
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
urlFilePath := filepath.Join(config.CommonInfo.RuntimePath, "casaos.url")
|
||||
if err := file.CreateFileAndWriteContent(urlFilePath, "http://"+listener.Addr().String()); err != nil {
|
||||
logger.Error("error when creating address file", zap.Error(err),
|
||||
zap.Any("address", listener.Addr().String()),
|
||||
zap.Any("filepath", urlFilePath),
|
||||
)
|
||||
}
|
||||
|
||||
// run any script that needs to be executed
|
||||
scriptDirectory := filepath.Join(constants.DefaultConfigPath, "start.d")
|
||||
command.ExecuteScripts(scriptDirectory)
|
||||
|
||||
if supported, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil {
|
||||
logger.Error("Failed to notify systemd that casaos main service is ready", zap.Any("error", err))
|
||||
} else if supported {
|
||||
logger.Info("Notified systemd that casaos main service is ready")
|
||||
} else {
|
||||
logger.Info("This process is not running as a systemd service.")
|
||||
}
|
||||
// http.HandleFunc("/v1/file/test", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// //http.ServeFile(w, r, r.URL.Path[1:])
|
||||
// http.ServeFile(w, r, "/DATA/test.img")
|
||||
// })
|
||||
// go http.ListenAndServe(":8081", nil)
|
||||
|
||||
s := &http.Server{
|
||||
Addr: fmt.Sprintf(":%v", config.ServerInfo.HttpPort),
|
||||
Handler: r,
|
||||
ReadTimeout: 60 * time.Second,
|
||||
WriteTimeout: 60 * time.Second,
|
||||
MaxHeaderBytes: 1 << 20,
|
||||
Handler: mux,
|
||||
ReadHeaderTimeout: 5 * time.Second, // fix G112: Potential slowloris attack (see https://github.com/securego/gosec)
|
||||
}
|
||||
s.ListenAndServe()
|
||||
|
||||
logger.Info("CasaOS main service is listening...", zap.Any("address", listener.Addr().String()))
|
||||
// defer service.MyService.Storage().UnmountAllStorage()
|
||||
err = s.Serve(listener) // not using http.serve() to fix G114: Use of net/http serve function that has no support for setting timeouts (see https://github.com/securego/gosec)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func Cors() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
method := c.Request.Method
|
||||
//origin := c.Request.Header.Get("Origin") //请求头部
|
||||
//if origin != "" {
|
||||
//接收客户端发送的origin (重要!)
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
//服务器支持的所有跨域请求的方法
|
||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
|
||||
//允许跨域设置可以返回其他子段,可以自定义字段
|
||||
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language")
|
||||
// 允许浏览器(客户端)可以解析的头部 (重要)
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
|
||||
//设置缓存时间
|
||||
c.Header("Access-Control-Max-Age", "172800")
|
||||
//允许客户端传递校验信息比如 cookie (重要)
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
c.Set("content-type", "application/json")
|
||||
//}
|
||||
|
||||
//允许类型校验
|
||||
if method == "OPTIONS" {
|
||||
c.JSON(http.StatusOK, "ok!")
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}()
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
106
model/app.go
106
model/app.go
@@ -1,106 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ServerAppList struct {
|
||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Tagline string `json:"tagline"`
|
||||
Tags Strings `gorm:"type:json" json:"tags"`
|
||||
Icon string `json:"icon"`
|
||||
ScreenshotLink Strings `gorm:"type:json" json:"screenshot_link"`
|
||||
Category string `json:"category"`
|
||||
CategoryFont string `json:"category_font"`
|
||||
PortMap string `json:"port_map"`
|
||||
ImageVersion string `json:"image_version"`
|
||||
Tip string `json:"tip"`
|
||||
Envs EnvArray `json:"envs"`
|
||||
Ports PortArray `json:"ports"`
|
||||
Volumes PathArray `json:"volumes"`
|
||||
Devices PathArray `json:"devices"`
|
||||
NetworkModel string `json:"network_model"`
|
||||
Image string `json:"image"`
|
||||
Index string `json:"index"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
State string `json:"state"`
|
||||
Author string `json:"author"`
|
||||
MinMemory int `json:"min_memory"`
|
||||
MinDisk int `json:"min_disk"`
|
||||
MaxMemory uint64 `json:"max_memory"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Healthy string `json:"healthy"`
|
||||
Plugins Strings `json:"plugins"`
|
||||
Origin string `json:"origin"`
|
||||
Type int `json:"type"`
|
||||
Developer string `json:"developer"`
|
||||
}
|
||||
|
||||
type Ports struct {
|
||||
ContainerPort uint `json:"container_port"`
|
||||
CommendPort int `json:"commend_port"`
|
||||
Desc string `json:"desc"`
|
||||
Type int `json:"type"` // 1:必选 2:可选 3:默认值不必显示 4:系统处理 5:container内容也可编辑
|
||||
}
|
||||
|
||||
type Volume struct {
|
||||
ContainerPath string `json:"container_path"`
|
||||
Path string `json:"path"`
|
||||
Desc string `json:"desc"`
|
||||
Type int `json:"type"` // 1:必选 2:可选 3:默认值不必显示 4:系统处理 5:container内容也可编辑
|
||||
}
|
||||
|
||||
type Envs struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
Desc string `json:"desc"`
|
||||
Type int `json:"type"` // 1:必选 2:可选 3:默认值不必显示 4:系统处理 5:container内容也可编辑
|
||||
}
|
||||
|
||||
type Devices struct {
|
||||
ContainerPath string `json:"container_path"`
|
||||
Path string `json:"path"`
|
||||
Desc string `json:"desc"`
|
||||
Type int `json:"type"` // 1:必选 2:可选 3:默认值不必显示 4:系统处理 5:container内容也可编辑
|
||||
}
|
||||
|
||||
type configures struct {
|
||||
TcpPorts []Ports `json:"tcp_ports"`
|
||||
UdpPorts []Ports `json:"udp_ports"`
|
||||
Envs []Envs `json:"envs"`
|
||||
Volumes []Volume `json:"volumes"`
|
||||
Devices []Devices `json:"devices"`
|
||||
}
|
||||
|
||||
/****************使gorm支持[]string结构*******************/
|
||||
type Strings []string
|
||||
|
||||
func (c Strings) Value() (driver.Value, error) {
|
||||
b, err := json.Marshal(c)
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
func (c *Strings) Scan(input interface{}) error {
|
||||
return json.Unmarshal(input.([]byte), c)
|
||||
}
|
||||
|
||||
/****************使gorm支持[]string结构*******************/
|
||||
|
||||
/****************使gorm支持[]string结构*******************/
|
||||
type MapStrings []map[string]string
|
||||
|
||||
func (c MapStrings) Value() (driver.Value, error) {
|
||||
b, err := json.Marshal(c)
|
||||
return string(b), err
|
||||
}
|
||||
|
||||
func (c *MapStrings) Scan(input interface{}) error {
|
||||
return json.Unmarshal(input.([]byte), c)
|
||||
}
|
||||
|
||||
/****************使gorm支持[]string结构*******************/
|
||||
39
model/args.go
Normal file
39
model/args.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ListArgs struct {
|
||||
ReqPath string
|
||||
}
|
||||
|
||||
type LinkArgs struct {
|
||||
IP string
|
||||
Header http.Header
|
||||
Type string
|
||||
}
|
||||
|
||||
type Link struct {
|
||||
URL string `json:"url"`
|
||||
Header http.Header `json:"header"` // needed header
|
||||
Data io.ReadCloser // return file reader directly
|
||||
Status int // status maybe 200 or 206, etc
|
||||
FilePath *string // local file, return the filepath
|
||||
Expiration *time.Duration // url expiration time
|
||||
Method string `json:"method"` // http method
|
||||
}
|
||||
|
||||
type OtherArgs struct {
|
||||
Obj Obj
|
||||
Method string
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type FsOtherArgs struct {
|
||||
Path string `json:"path" form:"path"`
|
||||
Method string `json:"method" form:"method"`
|
||||
Data interface{} `json:"data" form:"data"`
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package model
|
||||
|
||||
type ServerCategoryList struct {
|
||||
Id uint `gorm:"column:id;primary_key" json:"id"`
|
||||
//CreatedAt time.Time `json:"created_at"`
|
||||
//
|
||||
//UpdatedAt time.Time `json:"updated_at"`
|
||||
Font string `json:"font"`
|
||||
Name string `json:"name"`
|
||||
Count uint `json:"count"`
|
||||
}
|
||||
6
model/common.go
Normal file
6
model/common.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
type PageResp struct {
|
||||
Content interface{} `json:"content"`
|
||||
Total int64 `json:"total"`
|
||||
}
|
||||
20
model/connections.go
Normal file
20
model/connections.go
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.org
|
||||
* @Date: 2022-07-27 10:30:43
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-08-04 20:06:04
|
||||
* @FilePath: /CasaOS/model/connections.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package model
|
||||
|
||||
type Connections struct {
|
||||
ID uint `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
MountPoint string `json:"mount_point"`
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package model
|
||||
|
||||
type LSBLKModel struct {
|
||||
Name string `json:"name"`
|
||||
FsType string `json:"fstype"`
|
||||
Size uint64 `json:"size"`
|
||||
FSSize string `json:"fssize"`
|
||||
Path string `json:"path"`
|
||||
Model string `json:"model"` //设备标识符
|
||||
RM bool `json:"rm"` //是否为可移动设备
|
||||
RO bool `json:"ro"` //是否为只读设备
|
||||
State string `json:"state"`
|
||||
PhySec int `json:"phy-sec"` //物理扇区大小
|
||||
Type string `json:"type"`
|
||||
Vendor string `json:"vendor"` //供应商
|
||||
Rev string `json:"rev"` //修订版本
|
||||
FSAvail string `json:"fsavail"` //可用空间
|
||||
FSUse string `json:"fsuse%"` //已用百分比
|
||||
MountPoint string `json:"mountpoint"`
|
||||
Format string `json:"format"`
|
||||
Health string `json:"health"`
|
||||
HotPlug bool `json:"hotplug"`
|
||||
FSUsed string `json:"fsused"`
|
||||
Tran string `json:"tran"`
|
||||
MinIO uint64 `json:"min-io"`
|
||||
UsedPercent float64 `json:"used_percent"`
|
||||
Serial string `json:"serial"`
|
||||
Children []LSBLKModel `json:"children"`
|
||||
//详情特有
|
||||
StartSector uint64 `json:"start_sector,omitempty"`
|
||||
EndSector uint64 `json:"end_sector,omitempty"`
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package model
|
||||
|
||||
type DockerStatsModel struct {
|
||||
Icon string `json:"icon"`
|
||||
Title string `json:"title"`
|
||||
Data interface{} `json:"data"`
|
||||
Pre interface{} `json:"pre"`
|
||||
}
|
||||
7
model/drive.go
Normal file
7
model/drive.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package model
|
||||
|
||||
type Drive struct {
|
||||
Name string `json:"name"`
|
||||
Icon string `json:"icon"`
|
||||
AuthUrl string `json:"auth_url"`
|
||||
}
|
||||
33
model/file.go
Normal file
33
model/file.go
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* @Author: LinkLeong link@icewhale.com
|
||||
* @Date: 2022-05-20 16:27:12
|
||||
* @LastEditors: LinkLeong
|
||||
* @LastEditTime: 2022-06-09 18:18:46
|
||||
* @FilePath: /CasaOS/model/file.go
|
||||
* @Description:
|
||||
* @Website: https://www.casaos.io
|
||||
* Copyright (c) 2022 by icewhale, All Rights Reserved.
|
||||
*/
|
||||
package model
|
||||
|
||||
type FileOperate struct {
|
||||
Type string `json:"type" binding:"required"`
|
||||
Item []FileItem `json:"item" binding:"required"`
|
||||
TotalSize int64 `json:"total_size"`
|
||||
ProcessedSize int64 `json:"processed_size"`
|
||||
To string `json:"to" binding:"required"`
|
||||
Style string `json:"style"`
|
||||
Finished bool `json:"finished"`
|
||||
}
|
||||
|
||||
type FileItem struct {
|
||||
From string `json:"from" binding:"required"`
|
||||
Finished bool `json:"finished"`
|
||||
Size int64 `json:"size"`
|
||||
ProcessedSize int64 `json:"processed_size"`
|
||||
}
|
||||
|
||||
type FileUpdate struct {
|
||||
FilePath string `json:"path" binding:"required"`
|
||||
FileContent string `json:"content" binding:"required"`
|
||||
}
|
||||
6
model/heart.go
Normal file
6
model/heart.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
type CasaOSHeart struct {
|
||||
UuId string `json:"uuid"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type TcpPorts struct {
|
||||
Desc string `json:"desc"`
|
||||
ContainerPort int `json:"container_port"`
|
||||
}
|
||||
type UdpPorts struct {
|
||||
Desc string `json:"desc"`
|
||||
ContainerPort int `json:"container_port"`
|
||||
}
|
||||
|
||||
/*******************使用gorm支持json************************************/
|
||||
|
||||
type PortMap struct {
|
||||
ContainerPort string `json:"container"`
|
||||
CommendPort string `json:"host"`
|
||||
Protocol string `json:"protocol"`
|
||||
Desc string `json:"desc"`
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
type PortArray []PortMap
|
||||
|
||||
// Value 实现方法
|
||||
func (p PortArray) Value() (driver.Value, error) {
|
||||
return json.Marshal(p)
|
||||
}
|
||||
|
||||
// Scan 实现方法
|
||||
func (p *PortArray) Scan(input interface{}) error {
|
||||
return json.Unmarshal(input.([]byte), p)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*******************使用gorm支持json************************************/
|
||||
|
||||
type Env struct {
|
||||
Name string `json:"container"`
|
||||
Value string `json:"host"`
|
||||
Desc string `json:"desc"`
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
type JSON json.RawMessage
|
||||
|
||||
type EnvArray []Env
|
||||
|
||||
// Value 实现方法
|
||||
func (p EnvArray) Value() (driver.Value, error) {
|
||||
return json.Marshal(p)
|
||||
//return .MarshalJSON()
|
||||
}
|
||||
|
||||
// Scan 实现方法
|
||||
func (p *EnvArray) Scan(input interface{}) error {
|
||||
return json.Unmarshal(input.([]byte), p)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
/*******************使用gorm支持json************************************/
|
||||
|
||||
type PathMap struct {
|
||||
ContainerPath string `json:"container"`
|
||||
Path string `json:"host"`
|
||||
Type int `json:"type"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
type PathArray []PathMap
|
||||
|
||||
// Value 实现方法
|
||||
func (p PathArray) Value() (driver.Value, error) {
|
||||
return json.Marshal(p)
|
||||
}
|
||||
|
||||
// Scan 实现方法
|
||||
func (p *PathArray) Scan(input interface{}) error {
|
||||
return json.Unmarshal(input.([]byte), p)
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
//type PostData struct {
|
||||
// Envs EnvArrey `json:"envs,omitempty"`
|
||||
// Udp PortArrey `json:"udp_ports"`
|
||||
// Tcp PortArrey `json:"tcp_ports"`
|
||||
// Volumes PathArrey `json:"volumes"`
|
||||
// Devices PathArrey `json:"devices"`
|
||||
// Port string `json:"port,omitempty"`
|
||||
// PortMap string `json:"port_map"`
|
||||
// CpuShares int64 `json:"cpu_shares,omitempty"`
|
||||
// Memory int64 `json:"memory,omitempty"`
|
||||
// Restart string `json:"restart,omitempty"`
|
||||
// EnableUPNP bool `json:"enable_upnp"`
|
||||
// Label string `json:"label"`
|
||||
// Position bool `json:"position"`
|
||||
//}
|
||||
|
||||
type CustomizationPostData struct {
|
||||
Origin string `json:"origin"`
|
||||
NetworkModel string `json:"network_model"`
|
||||
Index string `json:"index"`
|
||||
Icon string `json:"icon"`
|
||||
Image string `json:"image"`
|
||||
Envs EnvArray `json:"envs"`
|
||||
Ports PortArray `json:"ports"`
|
||||
Volumes PathArray `json:"volumes"`
|
||||
Devices PathArray `json:"devices"`
|
||||
//Port string `json:"port,omitempty"`
|
||||
PortMap string `json:"port_map"`
|
||||
CpuShares int64 `json:"cpu_shares"`
|
||||
Memory int64 `json:"memory"`
|
||||
Restart string `json:"restart"`
|
||||
EnableUPNP bool `json:"enable_upnp"`
|
||||
Label string `json:"label"`
|
||||
Description string `json:"description"`
|
||||
Position bool `json:"position"`
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
type IOCountersStat struct {
|
||||
Name string `json:"name"` // interface name
|
||||
BytesSent uint64 `json:"bytesSent"` // number of bytes sent
|
||||
@@ -15,5 +13,5 @@ type IOCountersStat struct {
|
||||
Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving
|
||||
Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending
|
||||
State string `json:"state"`
|
||||
DateTime time.Time `json:"date_time"`
|
||||
Time int64 `json:"time"`
|
||||
}
|
||||
|
||||
6
model/notify.go
Normal file
6
model/notify.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package model
|
||||
|
||||
type NotifyMssage struct {
|
||||
Type string `json:"type"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user