mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
Compare commits
2704 commits
debian/4.3
...
dev
Author | SHA1 | Date | |
---|---|---|---|
|
a5049a8a13 | ||
|
6e84e3532a | ||
|
917cf251fb | ||
|
8a5f2808a1 | ||
68f35831e7 | |||
b91e9dd8f4 | |||
38b39ebaea | |||
ef17082768 | |||
e3ddb1dc4d | |||
|
5b37936d11 | ||
|
e82d20aa7b | ||
|
aff885e6b7 | ||
|
7a04462ccd | ||
|
606e246ec4 | ||
|
e3e8b903c7 | ||
|
488f563b45 | ||
|
3d4804be68 | ||
|
d4f774ad72 | ||
|
d8ab3e68a9 | ||
|
71b50549f5 | ||
|
a40874c305 | ||
|
9223d30a83 | ||
|
5ad9962757 | ||
|
4dfcc13a3f | ||
|
e11b61f49e | ||
|
243a34d2d5 | ||
|
ca2572d00b | ||
|
518c3bbbe2 | ||
|
9517b26c63 | ||
|
a6785d34bc | ||
|
7c79060467 | ||
|
007c13ce42 | ||
|
2102242a61 | ||
|
c409888a4b | ||
|
c14ebc8be4 | ||
|
9b0553580b | ||
|
bc2ed45e9d | ||
|
a76cd05e87 | ||
|
eb14e404d6 | ||
|
aae24614c4 | ||
|
51787a2f8b | ||
|
c5953b5420 | ||
|
4afff118e4 | ||
|
6113fde48a | ||
|
b734e2ea89 | ||
|
0a44d7cea4 | ||
|
5d3280c0fd | ||
|
8dc521a528 | ||
|
2e70143da2 | ||
|
3095496fe9 | ||
|
586d1c7f63 | ||
|
d63c61e0df | ||
|
4248b27b26 | ||
|
0f662d069c | ||
|
7ca710685e | ||
|
31d10079c7 | ||
|
980777ebf1 | ||
|
436826abf9 | ||
|
477fa63f46 | ||
|
9a6f7dac3b | ||
|
498006cab6 | ||
|
2f186b6f7f | ||
|
5708776df6 | ||
|
abdbb7efcd | ||
|
658ef88e47 | ||
|
4d5cc62540 | ||
|
f88e4cacdf | ||
|
36b9188aec | ||
|
c104dc6449 | ||
|
938e400865 | ||
|
de9980f31e | ||
|
f02d4a4376 | ||
|
92f4a605b8 | ||
|
df320a44cf | ||
|
6733526bee | ||
|
d0df3caed4 | ||
|
9083a5cc3d | ||
|
764fe6a7ba | ||
|
200f0272d5 | ||
|
9915559c40 | ||
|
760256f85d | ||
|
684c3d9b2c | ||
|
90c4034908 | ||
|
3deffdbd57 | ||
|
9f6f5f92fb | ||
|
e88ba3428c | ||
|
fe524dd866 | ||
|
65ea34d7cb | ||
|
d766f7cdda | ||
|
423e79bd57 | ||
|
44529b6d92 | ||
|
f4727d3cb6 | ||
|
8705dfcf5c | ||
|
ad98a10fa8 | ||
|
d376677db6 | ||
|
8b56983171 | ||
|
2d3dddc51a | ||
|
c861ef2ae6 | ||
|
53427e8c14 | ||
|
e5d74d420d | ||
|
cd30a2acc0 | ||
|
9e1b0561e3 | ||
|
843771ea05 | ||
|
ddf3e32c1c | ||
|
6d21e9fced | ||
|
d881d1a505 | ||
|
ebaecfcbd6 | ||
|
eeee096f3a | ||
|
fc168c54a1 | ||
|
b010219814 | ||
|
67c5edc40e | ||
|
437189d8c1 | ||
|
b2492ffc3d | ||
|
34861f906d | ||
|
a7edbc0cc7 | ||
|
b1d1f9f907 | ||
|
c90a691448 | ||
|
f6c270e1d2 | ||
|
3d53cf0467 | ||
|
7ee1734265 | ||
|
179daf68df | ||
|
57b4e240e1 | ||
|
bfbc7035dd | ||
|
239819b6da | ||
|
357896cd55 | ||
|
ded4892b9e | ||
|
9721685001 | ||
|
8395b066bc | ||
|
ac4ff0fc2d | ||
|
04101862ac | ||
|
0242ecd0e7 | ||
|
6e5c555e37 | ||
|
ebcf3c79ff | ||
|
f11f11973b | ||
|
67d6baa151 | ||
|
97bb6bde09 | ||
|
ca59886303 | ||
|
a8fd6afeee | ||
|
a5868733d7 | ||
|
079cdc2624 | ||
|
4232fc7c4b | ||
|
845a14bfe1 | ||
|
73e0d6c271 | ||
|
14312a9ec4 | ||
|
8a65053a59 | ||
|
64c8d9e853 | ||
|
22201863a1 | ||
|
bb20020c5a | ||
|
771a4b3446 | ||
|
beeddc7819 | ||
|
0907411efc | ||
|
d71d8fe7b3 | ||
|
9e8c7e704e | ||
|
85c5c04b15 | ||
|
a0bc7926c4 | ||
|
27ccd2918e | ||
|
588742f31b | ||
|
4112deda0c | ||
|
1e70577d23 | ||
|
623bd151d6 | ||
|
d87fe9fb4c | ||
|
bf8271e383 | ||
|
818fd78a3d | ||
|
eb012de188 | ||
|
725b41d2a3 | ||
|
85239f74f6 | ||
|
0b438eab02 | ||
|
3c992c894a | ||
|
a97c82d1c2 | ||
|
566213ecd5 | ||
|
5fb54936ba | ||
|
0b5c5a5f4d | ||
|
e8c171fd83 | ||
|
0bffcbae76 | ||
|
fbe42f1867 | ||
|
7121ed6836 | ||
|
e339006c69 | ||
|
a66890ddd8 | ||
|
e54e99bfb7 | ||
|
ab8e0e6619 | ||
|
401ccf69c7 | ||
|
e5bc94b9cf | ||
|
9c22d36c6f | ||
|
b266e398ff | ||
|
c8a18129df | ||
|
8be726b993 | ||
b96c530d2b | |||
bb25c6b15d | |||
|
a735a6d296 | ||
49961145ca | |||
b289de3eca | |||
26fba087d6 | |||
|
f6fbd69c39 | ||
|
1bb81e8f69 | ||
|
0f34d7e10f | ||
|
2763e04012 | ||
90d4cd99b9 | |||
f344cb037b | |||
|
c694ea2cbc | ||
|
772e772b24 | ||
|
b5e6f02d7d | ||
|
30286bc811 | ||
|
62f7e022ff | ||
|
ffde5cbf87 | ||
|
c6aec680b9 | ||
|
395dc6b843 | ||
|
fe8fcaefef | ||
|
d6aa310c21 | ||
|
5fcb1c6188 | ||
|
22d8c0c70a | ||
|
8de0a4cdcb | ||
|
6f73a82a2d | ||
|
ab742e55bb | ||
|
5d15c00d92 | ||
|
9a5aff9715 | ||
|
3e20cdd59e | ||
|
2edb6ad625 | ||
|
41ca422210 | ||
|
e55c914974 | ||
|
7c7e763a74 | ||
|
0f85ddbcff | ||
|
131760e30c | ||
|
7e55a791b6 | ||
|
2640dd3171 | ||
|
4e3f30ef82 | ||
|
bc3e36abb3 | ||
|
92807afb16 | ||
|
1ed56952e6 | ||
|
6b77e19bbd | ||
|
50034aabdd | ||
|
ef622ffe4d | ||
|
40a3205add | ||
|
7b0383f865 | ||
|
0783af306d | ||
|
36b3b00166 | ||
|
e75b4b3b3b | ||
|
1c62960e25 | ||
|
1e1409c7d7 | ||
|
fcaa366e91 | ||
|
f2b5f0f22c | ||
|
4b43d8d99d | ||
|
636c9e563e | ||
|
c0bccc3ac9 | ||
|
9727765ecf | ||
|
5ef0c84c0f | ||
|
c965f13f50 | ||
|
20741c63aa | ||
|
a48bfa67de | ||
|
3f973669fc | ||
|
a18d5f26f2 | ||
|
c2271ab731 | ||
|
eee84c5f66 | ||
|
6ed167bfaf | ||
|
eaf00103dd | ||
|
ff78f3ada7 | ||
|
fcbb971792 | ||
|
dbf579b7b4 | ||
|
e5b575901a | ||
|
d47c87e57d | ||
|
28603da4f1 | ||
|
c2d69f7f84 | ||
|
a349fc0334 | ||
|
3e1c9ebaf7 | ||
|
1ab3a79d39 | ||
|
44bbc34967 | ||
|
7b2959a3eb | ||
|
1dfc47d1d7 | ||
|
9cd7c86641 | ||
|
ef68485c5f | ||
|
656ff823a9 | ||
|
ae3018cdd0 | ||
|
8b8768fd77 | ||
|
75d7042974 | ||
|
3b26ccc2a5 | ||
|
3608c5678c | ||
|
d9d404a5b2 | ||
8846381d47 | |||
650481a58a | |||
|
87eedc2a36 | ||
|
feb9a095b3 | ||
|
997388dc79 | ||
|
9982a77582 | ||
|
2a7fefaecb | ||
|
7347b08e49 | ||
|
6851d740f7 | ||
|
2d26935079 | ||
|
094cd9ddd6 | ||
|
29ae71acad | ||
|
c9b76fde35 | ||
|
e3bebeac98 | ||
|
ed426f05ba | ||
|
2af4c157d9 | ||
|
0aad13cd2f | ||
|
2895d4d99b | ||
|
1fb80e5d24 | ||
|
30467f8bc3 | ||
|
d8c3ff4c8a | ||
|
0e4495f11e | ||
|
2b1f74268f | ||
|
5f6df6a859 | ||
|
b3409729a6 | ||
|
9298738d06 | ||
|
262453f132 | ||
|
d4857834f3 | ||
|
3942ea12ae | ||
|
a2ac77fa91 | ||
|
6ee40ac06a | ||
|
f26565d6de | ||
|
2e05b0894b | ||
|
18092db1c8 | ||
|
ecb82ec693 | ||
|
31ae5d1eaa | ||
|
be3df69326 | ||
|
7caf7e8b3e | ||
|
e558513609 | ||
|
3d728d90ce | ||
|
0bd69e5622 | ||
|
1b5074d857 | ||
|
dd8db1883a | ||
|
06c8fbc881 | ||
|
a25033bba5 | ||
|
2f933b5bf2 | ||
|
90dfccf278 | ||
|
b1b3c6eff8 | ||
|
2ee8d93f67 | ||
|
6605df6eb2 | ||
|
41b958113a | ||
e0a9bafde2 | |||
|
eab36d069d | ||
|
b47aedc932 | ||
|
f22c6ec3e9 | ||
|
d9b9aa1884 | ||
e12d79390f | |||
|
b8a1a3a660 | ||
|
6b6580a919 | ||
|
11e2b6d63c | ||
|
218bf107fb | ||
|
ec354d443d | ||
|
8f8070983d | ||
|
bd43a4504e | ||
|
156f9e54ba | ||
|
5a6a8e6c73 | ||
|
800f93d12e | ||
|
3584e6a5b1 | ||
|
50a4d08add | ||
|
d501131b34 | ||
|
66f667e48a | ||
|
47b2a5695f | ||
|
66508d5fd6 | ||
|
a8cd94d3db | ||
|
b4b420d694 | ||
|
fca26ead78 | ||
|
eb8ce2088b | ||
|
8c376c2ae4 | ||
|
0c319cbeba | ||
|
c5815fb1ef | ||
|
480366d5a1 | ||
|
50eea8fc14 | ||
|
4dc59049ef | ||
|
d1e1fd5e35 | ||
|
8c3ca4a0f4 | ||
|
0ceb77ec34 | ||
|
a123149bef | ||
|
8ad3a3bc6f | ||
|
2a6a8af0f7 | ||
|
fa848ff1c4 | ||
|
1b2d13f96a | ||
|
14ba98a232 | ||
|
29d6dd685a | ||
|
51d1011c47 | ||
259c7ac4a7 | |||
|
4d5ae9d32c | ||
|
05a02221b9 | ||
|
576e35321f | ||
|
f2f8b3e319 | ||
|
cbc68afea4 | ||
|
6e2b36d957 | ||
|
ef7da9e70f | ||
|
9b6ccb7b1f | ||
|
0273ee34b1 | ||
|
67477473e8 | ||
|
0eda746af5 | ||
|
701828bf45 | ||
|
307ed10c41 | ||
|
c9324772f2 | ||
|
d2d0af27cf | ||
|
697a33574b | ||
f0727ebdb4 | |||
|
8117f438d4 | ||
|
5c461d6058 | ||
|
eb8db04629 | ||
|
727b0e093a | ||
|
c6bda180b4 | ||
|
b439a0f7b5 | ||
|
9a09680b6e | ||
|
984300422e | ||
|
2bd76986a8 | ||
dd394e94dc | |||
5676a72750 | |||
|
c836d88b9a | ||
|
3a1c8287b4 | ||
|
c6a7d3a591 | ||
|
fef411e1ca | ||
|
75b267dc42 | ||
|
c4c0210dc1 | ||
|
b67d4621fc | ||
|
fb32842c89 | ||
|
88d221c52e | ||
|
f5dc382888 | ||
|
893e1230ef | ||
|
23038ea62b | ||
|
cca2962b11 | ||
841f6500b5 | |||
e6b676df5b | |||
|
d77b646971 | ||
5e6c3433ee | |||
|
ab892be38b | ||
|
064fa32a39 | ||
2d23798283 | |||
|
65abffa1ce | ||
|
4a9a3ba138 | ||
|
80f07a9974 | ||
|
6835a664c7 | ||
|
346f42643b | ||
|
7c1b07ee0f | ||
|
88684c7937 | ||
|
84a7b23e8a | ||
|
70f5154130 | ||
|
3a500d8457 | ||
|
a240fb2316 | ||
|
f895724a25 | ||
|
8b59e315bf | ||
|
b79ff15d32 | ||
|
6b577bdd23 | ||
|
94c12c6409 | ||
|
1b03058858 | ||
|
422e02244d | ||
|
365d0b25af | ||
|
aa6634fd22 | ||
|
0915a6a70b | ||
|
4a74a7c51d | ||
|
6e13a4db1b | ||
|
b914ad9093 | ||
|
084ecd6578 | ||
|
204800e878 | ||
|
06dc3da3f4 | ||
af2a56012f | |||
|
55cfc46cdd | ||
|
e3282f2329 | ||
|
2047d536be | ||
|
c1b3c3f785 | ||
|
1e47a1438b | ||
|
7011b1c879 | ||
5d3131b494 | |||
a2bc8c4f38 | |||
|
12764652b0 | ||
|
6aa9d05372 | ||
|
84d1a6bcca | ||
|
259c596e12 | ||
|
3b8a91efe6 | ||
|
110dffeb7f | ||
|
d5e054fe80 | ||
|
71dabfea6c | ||
|
14a8445375 | ||
|
0a5dd1b099 | ||
|
437f21ed5a | ||
|
f6d38bebee | ||
|
9b7b265cbf | ||
|
ad6c75652c | ||
|
30046784a0 | ||
|
f798236a3a | ||
|
44840603b5 | ||
|
7f52988671 | ||
|
89e24eb258 | ||
|
76c54ebdea | ||
|
48c673478d | ||
|
c2c27a01fc | ||
|
1c7e139c74 | ||
|
c459ddabbd | ||
|
3010066190 | ||
|
cc3c5fc4f0 | ||
|
1a24d32e98 | ||
|
6e1980279c | ||
|
12ea021e3a | ||
|
a333907d97 | ||
|
498b8d9c43 | ||
|
915788d53f | ||
|
2744fed552 | ||
|
00477594d6 | ||
|
c2e39a533f | ||
|
675650f057 | ||
|
f1906fe473 | ||
|
5b58500965 | ||
|
c81f1611c6 | ||
|
b5884fe1ed | ||
|
e9f074188a | ||
|
a6d1fa5a7a | ||
|
3ad7e900ab | ||
|
21a157e2e7 | ||
|
80af05cb64 | ||
|
029c7f66c3 | ||
|
e93f17fcf9 | ||
|
14bcdd5bdc | ||
|
fa2e133c6e | ||
|
08055003f5 | ||
|
2b71b57b1a | ||
|
8aeba11ab8 | ||
|
eb8b1d1787 | ||
|
c992f1f583 | ||
|
950c75ad5d | ||
|
5ce76e72f5 | ||
|
ab5c2759d3 | ||
|
bceaac0a75 | ||
|
25e842aef7 | ||
|
955d78ddf1 | ||
|
63a629200b | ||
|
684a593304 | ||
|
70e9b2946b | ||
|
32b3843135 | ||
|
8158aaf5aa | ||
|
e6623bb76b | ||
|
2a90233961 | ||
|
69dce7a0b4 | ||
|
2ab2c20b42 | ||
|
d74c3af1f7 | ||
|
82c682d6d1 | ||
|
552507007a | ||
|
1f52c46c9b | ||
|
344f2b5256 | ||
|
e04f040a79 | ||
|
537699ca90 | ||
|
5e4e59a133 | ||
|
a665f2550c | ||
|
a5560c3035 | ||
|
7d0d82ae01 | ||
|
22b30c79c0 | ||
|
bf5b2ae532 | ||
|
29c597ed8e | ||
|
1e3fd2989a | ||
|
a3ab7c9199 | ||
|
85f83af862 | ||
|
7bc6fef22c | ||
|
ff6b6954aa | ||
|
835303200d | ||
|
38b1c53f8a | ||
|
383fd6f5d4 | ||
|
a733ea45c3 | ||
|
ba0ad78df5 | ||
|
0864014ea1 | ||
|
1fbc47834e | ||
|
c8c4af8ee4 | ||
|
93b6ec0276 | ||
|
73fc554840 | ||
|
f326cb9799 | ||
|
69e6a7aaa5 | ||
|
b79395dfe0 | ||
|
1ec2e21936 | ||
|
52e12ed1f0 | ||
|
f1bb218959 | ||
|
9df575962b | ||
|
88db6373e1 | ||
|
79bc5a671c | ||
|
03b8a7ff8e | ||
|
bc5355b706 | ||
|
645502f59c | ||
|
58c9d146a6 | ||
|
6c9ef1baa7 | ||
|
aaebb89771 | ||
|
bc42f2da22 | ||
|
6103f20b7d | ||
|
874108deaf | ||
|
eae8099130 | ||
|
75c815c355 | ||
|
0c960099d0 | ||
|
587c29fc65 | ||
|
941c8f05df | ||
|
c863b78196 | ||
|
4a77687ff9 | ||
|
499a4817b4 | ||
|
527a3d788d | ||
|
da7753cb85 | ||
|
80e09abc88 | ||
|
2a56c70591 | ||
|
4271fbbf91 | ||
|
82092639eb | ||
|
b1d222d099 | ||
|
3cfdff3dd3 | ||
|
8067aa057e | ||
|
eb3401a74f | ||
|
362746c1fd | ||
|
9cb2fe7d86 | ||
|
f34f999cac | ||
|
7d0006181d | ||
|
6661e9b586 | ||
|
104c418627 | ||
|
4da76ebc82 | ||
|
a61505e692 | ||
|
3984bbb953 | ||
|
b82630b085 | ||
|
104e10bb08 | ||
|
9155cb6c08 | ||
|
716606c50f | ||
|
93c723d2d9 | ||
|
ef39d77b8f | ||
|
a0e168fa5b | ||
|
adab80e00b | ||
|
30a4fe1646 | ||
|
c955550a2f | ||
|
45e3f6b1a2 | ||
|
f9d3ae1084 | ||
|
3073a0527b | ||
|
6bf16002f5 | ||
|
3beb3a2bd7 | ||
|
5434037185 | ||
|
2b111c0d0a | ||
|
1bde5f5be8 | ||
|
a8e709810b | ||
|
cc3e683492 | ||
|
2137ddbb11 | ||
|
cbe13831a0 | ||
|
4edb247ae3 | ||
|
b388ca7f43 | ||
|
a104c08eb3 | ||
|
00dc340b49 | ||
|
415e444f13 | ||
|
0c8706366e | ||
|
006318effa | ||
|
c9d570e6a1 | ||
|
0ab27873a3 | ||
|
b3f12d8937 | ||
|
7630b154a3 | ||
|
5914317aeb | ||
|
38d0f29fc6 | ||
|
7e6cbd292b | ||
|
47076eca4e | ||
|
0f4c2ba64c | ||
|
e8ad12de24 | ||
|
c512425bd9 | ||
|
261e225e4f | ||
|
349eef899d | ||
|
8f6df354b8 | ||
|
df49295836 | ||
|
105f4dc515 | ||
|
4eac31e888 | ||
|
30679c0c57 | ||
|
56d949bb9e | ||
|
4759ff66a7 | ||
|
609819ade8 | ||
|
5c00fdf976 | ||
|
e01c7dcb00 | ||
|
e6c4f2e077 | ||
|
345ad8c31a | ||
|
6a84564cdc | ||
|
a735f68cc9 | ||
|
349d219a57 | ||
|
4ebe1edf00 | ||
|
eaa6b2efc5 | ||
c5e9cec933 | |||
|
99d23f6235 | ||
|
023207f0b6 | ||
|
734e910241 | ||
|
8906c896cb | ||
|
b8b8eb14f4 | ||
|
da5181f057 | ||
|
3f735ef3c1 | ||
|
c827877387 | ||
|
412bb40bf2 | ||
|
a533cdd741 | ||
|
1a876a80c2 | ||
|
613f41dae9 | ||
|
ac02ca812d | ||
|
1d9cbde627 | ||
|
fa64652681 | ||
|
707180da43 | ||
|
ec4b1e9f96 | ||
|
cfee750e32 | ||
|
61df4add8c | ||
|
f130f4fc56 | ||
|
c695aa549a | ||
|
37e14269c8 | ||
|
5c741190e3 | ||
|
080aae9ab2 | ||
|
58e8e9e5a1 | ||
|
077b745d60 | ||
|
b69cbd33ed | ||
|
4e33bf271e | ||
|
55b601369d | ||
|
582dc2d4f0 | ||
|
9d9c68f4bf | ||
|
d730edef52 | ||
|
1fe0ea5062 | ||
|
e81e6fb92c | ||
|
97c2fe3d49 | ||
|
5301018490 | ||
|
1a95dd500f | ||
|
3f467182cc | ||
|
8120ac2b3f | ||
|
00698cc2fd | ||
|
3574a7792d | ||
|
820a79c238 | ||
8727e74eab | |||
|
fc12cb198c | ||
|
4ed5e1ba20 | ||
|
339cdcd82c | ||
|
c2af17667b | ||
|
9819560518 | ||
|
1ce606d469 | ||
|
05f7c3a3b7 | ||
|
fc691270f6 | ||
|
491588bb88 | ||
|
54ad8dd2cb | ||
|
0f3c92a15b | ||
|
a44ea14141 | ||
|
8ca59703c5 | ||
|
7a819d33ae | ||
|
bfe3eb21bd | ||
|
7f13ea7d65 | ||
|
43c0c3310a | ||
|
a52b64d2f5 | ||
|
4f9e69df01 | ||
|
890fcee05b | ||
|
699500dbb0 | ||
|
bd0edd0e4e | ||
|
c93d770d4a | ||
|
f53d09c3a2 | ||
c8f0f131fd | |||
|
b920b82f4e | ||
|
6fdcf03e92 | ||
|
b424ae01c1 | ||
|
aab80f9ecc | ||
|
b2c3c70742 | ||
|
1c083845e7 | ||
|
6c3290d8bf | ||
|
0ed6769fcf | ||
|
f12ed69b7b | ||
|
8952d69e05 | ||
|
57a0e8b8f8 | ||
|
155418409e | ||
|
609c3911d3 | ||
|
6fa59bfd5c | ||
|
ca354cd827 | ||
|
a729c78379 | ||
|
4284cd5d10 | ||
|
5daf33f58e | ||
|
308ed0e174 | ||
|
4ce101b5c6 | ||
|
83df4d9ff0 | ||
|
5738526349 | ||
|
770fdb6861 | ||
fb2ca1f27d | |||
7981653c23 | |||
dc8f51e2f8 | |||
|
c0337bf1ef | ||
|
830d7b47e0 | ||
|
64c616076f | ||
|
8e3e788842 | ||
|
9489d200b2 | ||
|
54a6a1b3d2 | ||
|
207ebbb27f | ||
|
fa848c376f | ||
|
0a7b5fb0ba | ||
|
457289d6ca | ||
|
33774ce625 | ||
|
63d1b5f7fa | ||
|
2828b76364 | ||
|
169c921444 | ||
|
f436057d27 | ||
|
38db30cd70 | ||
|
857a285b5a | ||
|
8c475d0a7b | ||
|
fe3416aa02 | ||
|
570184ac1e | ||
|
59875cae23 | ||
|
267968074b | ||
|
4897f72974 | ||
|
7a82f6e4b9 | ||
|
04f326528f | ||
|
fff8b2d95a | ||
|
ff4c1433d2 | ||
|
207c0ff1ab | ||
|
93606e1132 | ||
|
4bfe2c96f5 | ||
|
ce0cbc5fed | ||
|
5746b94dff | ||
|
da20964044 | ||
|
9a7731aa4e | ||
|
b06484fede | ||
|
300c999a5a | ||
|
38469accee | ||
|
50c00c60bc | ||
|
61defdb4c1 | ||
|
02e6346bc5 | ||
|
8ee5aade72 | ||
|
8cb6a5649b | ||
|
f56f235705 | ||
|
917b2961d2 | ||
|
1131e76f4c | ||
|
8cfc929f25 | ||
|
157f8c8121 | ||
|
24cb534719 | ||
|
d35eceb17b | ||
|
bfb7dda42e | ||
|
4eef918e40 | ||
|
5547208be4 | ||
|
c4c4af6e62 | ||
|
6fdfd81cbb | ||
|
022fed7787 | ||
|
238c1ac4d3 | ||
|
9c6be3ffd6 | ||
|
1d1cbedf3a | ||
|
b719563c7e | ||
|
4f4dfdb7f7 | ||
|
75e6afaf5c | ||
|
9c33d9e74f | ||
|
00d7f1a208 | ||
|
ae70eebc13 | ||
|
5d77843cd9 | ||
|
16146913b0 | ||
|
e3ee8dfa8e | ||
|
54bc79ed58 | ||
|
74fd75ea33 | ||
|
62779ee266 | ||
|
22b4a947ca | ||
|
e6e58ec269 | ||
|
379b6922ad | ||
|
a2faa8add9 | ||
|
662998a1ab | ||
|
23cdf91b01 | ||
|
dc362dd636 | ||
|
a69b80972e | ||
|
96e99459e6 | ||
|
2bf2956b3d | ||
|
5019f9e3b3 | ||
|
075095b4d7 | ||
|
6a8693fa44 | ||
|
022870be9b | ||
|
f003565074 | ||
|
6f1a00922a | ||
|
e8700bfe7b | ||
|
19c4202ff4 | ||
|
f4d8ada368 | ||
|
6385b402f7 | ||
|
179b600621 | ||
|
a83fbc1bc9 | ||
|
463296e88c | ||
|
58a539bf7d | ||
|
c6633873ba | ||
|
3e53f90f3e | ||
|
a457f8dbcb | ||
|
bb097fedca | ||
|
253a042314 | ||
|
c019f7f24a | ||
|
4a7b2b2cbf | ||
|
ca1e088f29 | ||
|
0f109db6ca | ||
|
125af4670f | ||
|
53ffe3c1c0 | ||
|
82affd2984 | ||
|
2e4f2e8e3a | ||
|
cd079459b9 | ||
|
2e86bae4ef | ||
|
e9802ce2dc | ||
|
dd161e8d63 | ||
|
fc68f769f9 | ||
|
97c2cdc593 | ||
|
65843bda6d | ||
|
67e28567ff | ||
|
322fc3b712 | ||
|
cbb85f8c3b | ||
|
5110cd0800 | ||
|
b54a71b0cf | ||
|
df1f3149ea | ||
|
ec6bf12a74 | ||
|
920fe527f4 | ||
|
e1aeacbc49 | ||
|
79e41a1e4b | ||
|
3dfab89c1f | ||
|
ffa8eb38ed | ||
|
6f3b194944 | ||
|
51d8608b40 | ||
|
52951239c5 | ||
|
f895f99d21 | ||
|
65d2571072 | ||
|
dcafac1913 | ||
|
79e620ef42 | ||
|
fde05c0ac2 | ||
|
0b05143745 | ||
|
b0fe49ae83 | ||
|
73a144fa46 | ||
|
ee4d94d382 | ||
|
07daa68770 | ||
|
32376cf18f | ||
|
576992899c | ||
|
f08d5562ff | ||
|
c4b3068d3a | ||
|
f46dc30783 | ||
|
927a17cf30 | ||
|
5eecfcae67 | ||
|
9fdbc5532f | ||
|
d716746f28 | ||
|
b0f9934f08 | ||
|
0d88978c2a | ||
|
7f5b8a538f | ||
|
d2113b243e | ||
|
465f6da5cd | ||
|
4fda8ed49f | ||
|
53bc30b9fb | ||
|
fd17b5b036 | ||
|
e446255648 | ||
|
2d54be6e8d | ||
|
e1ceb084c3 | ||
|
363f8f13a3 | ||
|
6b5c9a2a8b | ||
|
e5225ba543 | ||
|
dd93df45e6 | ||
|
1eb208db23 | ||
|
781f924e30 | ||
|
ced222eaa5 | ||
|
92924385db | ||
|
6e63b6fc53 | ||
|
036119d9ba | ||
|
4b582f72df | ||
|
7cf18e69a3 | ||
|
419a32bf15 | ||
|
606335a474 | ||
|
373dabbcb0 | ||
|
a81d688dc1 | ||
|
972e98d66f | ||
|
5bb36ee060 | ||
|
91a564c3d1 | ||
|
e1fabc4448 | ||
|
dd73c7ba59 | ||
|
a81a548f76 | ||
|
d2107278a7 | ||
|
d44b09cf12 | ||
|
f3eef43d02 | ||
|
e695c89ad0 | ||
|
72d7f237a4 | ||
|
7c1c147a74 | ||
|
81f269fc29 | ||
|
ba2159de73 | ||
|
dfc51ed7c5 | ||
|
1927875924 | ||
|
432a9ab544 | ||
|
f408dcbe7d | ||
|
7e18e8c9ec | ||
|
961dc5a6ee | ||
|
e1d0146f8b | ||
|
e1dcbee2a7 | ||
|
6b24412910 | ||
|
c0c0fcaf54 | ||
|
89ffe624f6 | ||
|
14040b8fd2 | ||
|
4a1b7c30ba | ||
|
875566915c | ||
|
739e02eaf8 | ||
|
5b726bb8c0 | ||
|
af93524c36 | ||
|
0d0740826d | ||
|
ee953fe2c2 | ||
|
3f0a23105e | ||
|
392695535e | ||
|
76481dae22 | ||
|
48c81a4175 | ||
|
9c3895300f | ||
|
e0a1f8ba0b | ||
|
798a5469eb | ||
|
b98ac21a06 | ||
|
4152cb0dd1 | ||
|
7924bb2b28 | ||
|
fd7136446e | ||
|
3957b10e92 | ||
|
36a17dfdbd | ||
|
dc0fa8c4ac | ||
|
7d2ecc358e | ||
|
42d74bfa3d | ||
|
6f48cbc4a7 | ||
|
5c4493ce96 | ||
|
f571aff93c | ||
|
510e82fa22 | ||
|
e87ee09b3e | ||
|
bcd2550fdd | ||
|
b2aaefe0e6 | ||
|
f47d496183 | ||
|
fb4693be39 | ||
|
f9850a2264 | ||
|
d69c196fe4 | ||
|
4da98e74ae | ||
|
460e39a2f0 | ||
|
19eb48b6e7 | ||
|
29338f79bc | ||
|
48ee78afa2 | ||
|
8242cab735 | ||
|
6278c68586 | ||
|
84984ad89a | ||
|
18336b01dc | ||
|
2f982e26a9 | ||
|
e1569f962b | ||
|
313a16476a | ||
|
1222c47620 | ||
|
e6f134bc91 | ||
|
fcf263242e | ||
|
8a27045d78 | ||
|
bc42fd7ab2 | ||
|
69339f8d0e | ||
8caff6a9dc | |||
|
1087c800a6 | ||
|
d42c99835a | ||
|
cec0dfe158 | ||
|
fee5375dc4 | ||
|
9cebd2e3fe | ||
|
f3faac87f8 | ||
|
db7ab2a98b | ||
|
e649c092a3 | ||
|
daf51e94bd | ||
|
1552944fdd | ||
|
1300585eda | ||
|
bb9db08e29 | ||
|
cacd43e147 | ||
|
5fa58f19ce | ||
|
a47e491869 | ||
|
ed1b5e567b | ||
|
4b4ce9aef6 | ||
|
cc167cd92c | ||
|
21c7c41812 | ||
|
f046c291e5 | ||
|
db9aa8e6c7 | ||
|
b5068ad007 | ||
|
751930043f | ||
|
a508684740 | ||
|
df523cdbf0 | ||
|
e8dd243218 | ||
|
2b65913b89 | ||
|
072dabaf70 | ||
|
425670bcfb | ||
|
68a4f2b4bc | ||
|
d27e9a9eea | ||
|
3bb32dc1e4 | ||
|
06826b4fc0 | ||
|
097cba4b56 | ||
|
d698c4c3de | ||
|
ecc4c2bd1c | ||
|
e59a4f849a | ||
|
8fa823b414 | ||
|
7eb10c3729 | ||
|
7b5c3d2e6e | ||
|
a7bc6513af | ||
|
ed315b7c7a | ||
|
1fa325099f | ||
|
fb79a04698 | ||
|
3ce6505abe | ||
|
74f4c1660c | ||
|
ea24fca91f | ||
|
47da68f076 | ||
|
487ccdd339 | ||
|
a7350a7eae | ||
|
d5cc3dc13d | ||
|
328d9276f0 | ||
|
667612619b | ||
|
4df7e4681d | ||
|
8fbdd228ab | ||
|
8b71ebc40f | ||
|
a129adef20 | ||
|
76bf9044c4 | ||
|
63760680f8 | ||
|
0282670458 | ||
|
15160425c9 | ||
|
d94ed2be9e | ||
|
510b3979e6 | ||
|
380e2d23aa | ||
|
c1f0ac04c7 | ||
|
fe5c73b4ed | ||
|
e87f8ef93a | ||
|
ba32078180 | ||
|
1c7d427be0 | ||
|
67687b7cff | ||
|
fe2761da4a | ||
|
dc99febe4c | ||
|
c439c47d67 | ||
|
e4a0ad35ce | ||
|
f0f89d8f2a | ||
|
5f4c83a4eb | ||
|
07636fe21e | ||
|
9c238f00c3 | ||
|
9e8e0497dd | ||
|
5351698230 | ||
|
4261317e49 | ||
|
f9fd379997 | ||
|
91497afbfe | ||
|
b4254c40e6 | ||
|
bc30805c7d | ||
|
9a585f03c6 | ||
|
c98b17f22b | ||
|
5f08fbed44 | ||
|
f92316325e | ||
|
c96b378d3e | ||
|
749f0c5b1f | ||
|
2ab0fa34c3 | ||
|
04edce8948 | ||
|
109375c83f | ||
|
e14a12272d | ||
|
fb9e892019 | ||
|
58614add79 | ||
|
59a2c96921 | ||
|
cbef40798c | ||
|
e2da51b9a3 | ||
|
c98da124b2 | ||
|
789b1b2af9 | ||
|
81360723cc | ||
|
d67e231678 | ||
|
d641659bf3 | ||
|
e2ea7ad7a0 | ||
|
b489d8bd99 | ||
|
8ca756dbd3 | ||
|
f9deb1d835 | ||
|
4380a50166 | ||
|
aa5b3dfa77 | ||
|
aa43e6c22b | ||
|
57be208238 | ||
|
1cc8924669 | ||
|
6bd8da807e | ||
|
fa26574b51 | ||
|
a66fccbd5b | ||
|
88ea5f0a90 | ||
|
58cd08e60d | ||
|
021099aa1e | ||
|
9a4267ffa4 | ||
|
ec82facff6 | ||
|
bee218e560 | ||
|
8c25aa9b9f | ||
|
f79cfcc067 | ||
|
b688944d11 | ||
|
478291766e | ||
|
d8cb2139a9 | ||
|
9c6a7fdf04 | ||
|
17e0a11547 | ||
|
b5f3662627 | ||
|
d5469b77c5 | ||
|
a15bad7b83 | ||
|
74213c6ce9 | ||
|
a16a164e20 | ||
|
4e799bfbc3 | ||
|
85a4b78e49 | ||
|
14bf2ee48b | ||
|
821aedefa7 | ||
|
4b46f32201 | ||
|
306c5e0e10 | ||
|
63981aacf9 | ||
|
8b1184f11b | ||
|
2d03176c7f | ||
|
f8c1e7c168 | ||
|
8e6178a863 | ||
|
f4b7906811 | ||
|
eacb7016e2 | ||
|
af0cd78fcc | ||
|
af77e0b62f | ||
|
db1710a0a9 | ||
|
df6bb22820 | ||
|
70149fe41d | ||
|
38381b8149 | ||
|
26ca9e5c69 | ||
|
c211b75279 | ||
|
1b2fa91ff0 | ||
|
b2596f3287 | ||
|
3656c19918 | ||
|
a95d10e50c | ||
|
f9a7016931 | ||
|
eabde600be | ||
|
eaf7a2904c | ||
|
13ac9dade6 | ||
|
5b58e0e60c | ||
|
7491dd4c50 | ||
|
69518b5417 | ||
|
b9f166e525 | ||
|
ab1149b1e7 | ||
|
c2ba4a90e7 | ||
|
cc058024a3 | ||
|
89d139e47a | ||
|
98c7b60311 | ||
|
4971127b9c | ||
|
1392080ed7 | ||
|
7c8f5261cb | ||
|
bccfa7f26e | ||
|
ce37d097ad | ||
|
340fa78751 | ||
|
738d0679da | ||
|
cb32423236 | ||
|
0d524220e5 | ||
|
ebc9e645fc | ||
|
acb359bdbf | ||
|
0a937ab0bd | ||
|
4102d626e5 | ||
|
091f7de827 | ||
|
8731f77aa9 | ||
|
756b0930c2 | ||
|
8e66e672d3 | ||
|
130bd4def2 | ||
|
d3fb090d4f | ||
|
4f11e8fe34 | ||
|
bb30b43814 | ||
|
6fe0ed919d | ||
|
3469440ec3 | ||
|
729868429a | ||
|
9f211d39f9 | ||
|
030d876329 | ||
|
74180ded22 | ||
|
d04f2085de | ||
|
59607ab33a | ||
|
c24c0a2ae1 | ||
|
9b1f4c9e1b | ||
|
76ff5b1844 | ||
|
28610669ed | ||
|
48bde23a0d | ||
|
8701d8ec62 | ||
|
8188c28167 | ||
|
c48d9ec483 | ||
|
f0751aff17 | ||
|
276cf11c4d | ||
|
7636b486c0 | ||
|
8ac74ea866 | ||
|
e03f609e9b | ||
|
7631d380fb | ||
|
94689cea12 | ||
|
ca59e0052c | ||
|
e9c474c1bd | ||
|
433d37b3af | ||
|
eb6d9df92f | ||
|
53588dcce7 | ||
|
e926e5ecaa | ||
|
df7f0ee969 | ||
|
1a089647b5 | ||
|
b40c0de33c | ||
|
e458d8813e | ||
|
97c0128c22 | ||
|
20e8805e3b | ||
|
324366a728 | ||
|
a3df78fe7e | ||
|
0c520e828e | ||
|
5d17782115 | ||
|
9d214fd3c6 | ||
|
404746c125 | ||
|
8ce5bb2412 | ||
|
e05df676dc | ||
|
128d7ebfe2 | ||
|
6210d07c24 | ||
|
41c9d9d8e3 | ||
|
ad63e5d383 | ||
|
943b9ff89f | ||
|
139e54a2e5 | ||
|
309c868f8c | ||
|
c13d627302 | ||
|
f91f87a1be | ||
|
bef4809f94 | ||
|
bab27014d9 | ||
|
79c9a7b294 | ||
|
aa50526ccd | ||
|
90b8e78eff | ||
|
8724329738 | ||
|
127c241c9a | ||
|
232d38f221 | ||
|
4fd10b5a1d | ||
|
1dc8b75315 | ||
|
d725b45428 | ||
|
888593ad22 | ||
|
4dfff20140 | ||
|
df6a2a2cd2 | ||
|
b887545c3e | ||
|
c300e023ef | ||
|
e1d62a1910 | ||
|
95b80b056f | ||
|
f436b890d6 | ||
|
ec4c2684f7 | ||
|
63f0f08421 | ||
|
2b70ccbf40 | ||
|
890b8e8082 | ||
|
290d627faf | ||
|
848adf89c8 | ||
|
2a16f289ea | ||
|
5a24cac788 | ||
|
16aa09174d | ||
|
61b5bb02f4 | ||
|
16bae924e8 | ||
|
343065eb5d | ||
|
93d011704f | ||
|
2389884e85 | ||
|
56c4740274 | ||
|
50f86af51a | ||
|
13d50f4f9a | ||
|
e6ae389297 | ||
|
93aeee8029 | ||
|
32ea7f17cd | ||
|
6da884418c | ||
|
12f1b95a6f | ||
|
d3ec5d055f | ||
|
ce7227c078 | ||
|
771b801ece | ||
|
18e034df8a | ||
|
8a43b04614 | ||
|
d123fd7674 | ||
|
475c93d582 | ||
|
58ac633d80 | ||
|
97b69e7c69 | ||
|
35427c8f28 | ||
|
069b782f07 | ||
|
13c4687c7b | ||
|
a06bb9ae82 | ||
|
6c3ecd2048 | ||
|
39141fbb6d | ||
|
aa585963c0 | ||
|
60b21795b8 | ||
|
0c4a006a4f | ||
|
e24ddd299e | ||
|
8fd7547528 | ||
|
7be7eb1154 | ||
|
0ab20b733b | ||
|
ab8a6b940f | ||
|
1d1a3756ba | ||
|
aa9bc47aa6 | ||
|
135dbec8b6 | ||
|
80d8d9b3c3 | ||
|
d0ca120eb0 | ||
|
9bd4344f25 | ||
|
bf070f1763 | ||
|
013aff3d0c | ||
|
0da6370d62 | ||
|
258e28f703 | ||
|
a154e811db | ||
|
658940079d | ||
|
a4fa6e07d0 | ||
|
dd6d083904 | ||
|
6b38a1b546 | ||
|
e974f30ba1 | ||
|
a1e2237fbb | ||
|
eb396fdb13 | ||
|
ea2b0d0c51 | ||
|
48e488f89e | ||
|
024db62a1d | ||
|
6520d82e4d | ||
|
2eb7da0603 | ||
|
00b411d18d | ||
|
63a95c28d6 | ||
|
106cb0a6fd | ||
|
edf8ec1944 | ||
|
fa7f7f77b9 | ||
|
e0bdb605ee | ||
|
e78b62448b | ||
|
8247a649e7 | ||
|
a80734d240 | ||
|
91a3e79eaf | ||
|
add0dbb864 | ||
|
e39c89e087 | ||
|
cb505b578b | ||
|
1e5203426b | ||
|
480b84b350 | ||
|
b5b69e952d | ||
|
29c6564f09 | ||
|
0f24846e0b | ||
|
170eaf5d74 | ||
|
ca0db0ec58 | ||
|
387f57d630 | ||
|
71042f0860 | ||
|
c179d4b88f | ||
|
9f686a115f | ||
|
b7c5913683 | ||
|
8241e26fc2 | ||
|
07f287f680 | ||
|
f742bdf832 | ||
|
4dee434e71 | ||
|
a035024666 | ||
|
fb54da2e35 | ||
|
8485ebc75a | ||
|
3bbba640e9 | ||
|
9459aed65e | ||
|
476908bdc2 | ||
|
0e787acb5d | ||
|
b06a3053f6 | ||
|
634fd6e7fc | ||
|
ce5d4ca637 | ||
|
c255fe2495 | ||
|
2107a84852 | ||
|
13d4e16e7d | ||
|
3f2dbe8754 | ||
|
9b7668dab0 | ||
|
ba4f192557 | ||
|
f2e01e7a4a | ||
|
cdae5ad111 | ||
|
ca3fb85286 | ||
|
d32fd89aea | ||
|
4a3cfd994f | ||
|
dd49ed2154 | ||
|
98fe846886 | ||
|
80b38d0e8a | ||
|
2b2d49a504 | ||
|
1c95bcff09 | ||
|
8090acb158 | ||
|
3110460a40 | ||
|
a9ac55e4a5 | ||
|
e7d5d3942e | ||
|
b9dc371a1c | ||
|
82ec26b0d5 | ||
|
6372bd3d4e | ||
|
9f60913bf8 | ||
|
7c4c3188e4 | ||
|
895ce755bc | ||
|
f91920699d | ||
|
3577956c06 | ||
|
7e9678622a | ||
|
dabf86be77 | ||
|
7ac6471b00 | ||
|
9004cc7615 | ||
|
0826a54189 | ||
|
c2c0a66cdf | ||
|
314d27bec1 | ||
|
452ba8bb9a | ||
|
daa9eb1cab | ||
|
8d2a0cf72d | ||
|
480f7a43ef | ||
|
b943c69c8b | ||
|
ade92e431d | ||
|
971b1b044e | ||
|
c990cee630 | ||
|
456b8857ef | ||
|
7dd2b41eef | ||
|
90aa55599d | ||
|
0eef27c86f | ||
|
2d024557a5 | ||
|
82d30f02e2 | ||
|
26e539fea6 | ||
|
396b0f4ef2 | ||
|
7ff19b78b5 | ||
|
56d3b4762b | ||
|
b8f87e372d | ||
|
78036b555e | ||
|
d698908cca | ||
|
31bc4d4f43 | ||
|
76f7577a50 | ||
|
de8859f78b | ||
|
c48055157d | ||
|
fd4ab9620c | ||
|
36205a7b4c | ||
|
c299841194 | ||
|
e28d8a9fe5 | ||
|
54ecbd5131 | ||
|
ed9630c47b | ||
|
dafdf1c4ba | ||
|
cba36d2cf5 | ||
|
94b1338dc6 | ||
|
3c6ab69ae6 | ||
|
908fa10357 | ||
|
0d279baa2c | ||
|
087030ac7f | ||
|
ec22c2ad1f | ||
|
12d4c16309 | ||
|
b29ee31c7a | ||
|
c444dee4fe | ||
|
e00d60b049 | ||
|
5a412ce93c | ||
|
a5de20d757 | ||
|
27305fe3fc | ||
|
a568c7eecd | ||
|
ece8d65601 | ||
|
bf07cd6c47 | ||
|
a658336476 | ||
|
312ded8873 | ||
|
7addad59f0 | ||
|
48eeae4e1b | ||
|
71be74ffe2 | ||
|
be5b1c1b69 | ||
|
b41d623ed4 | ||
|
95f98a9c68 | ||
|
285200a2c7 | ||
|
13be9af65f | ||
|
36b0f58993 | ||
|
f1c7c3d237 | ||
|
e73209b7c4 | ||
|
f17e5df173 | ||
|
17d8700000 | ||
|
edd187eb90 | ||
|
5db49173f9 | ||
|
2b6465d36d | ||
|
394907ff0d | ||
|
4615d7b7b8 | ||
|
28256f39de | ||
|
20804cb0b5 | ||
|
e82849492b | ||
|
1a07839b5f | ||
|
28e4b45806 | ||
|
c4c78f5daa | ||
|
f4b396219c | ||
|
029c3b7686 | ||
|
ea20b1581d | ||
|
1e0fe76672 | ||
|
8859038a41 | ||
|
27d6106259 | ||
|
7ceda87692 | ||
|
4c17220764 | ||
|
25c10166cf | ||
|
f21fbed2f7 | ||
|
683421719f | ||
|
b37d4baf64 | ||
|
37b424e968 | ||
|
f258eab6c2 | ||
|
b9be18c781 | ||
|
a6db52b7b4 | ||
|
ab2d10b99d | ||
|
a21567b27d | ||
|
e7a0e65903 | ||
|
dd33476fac | ||
|
f2eef6eefe | ||
|
9bf2b0b546 | ||
|
cddfafaa55 | ||
|
61a6d5bbac | ||
|
faa74c4063 | ||
|
c10ef82578 | ||
|
b06d7c41ac | ||
|
02abcd41f9 | ||
|
e54bf2ed67 | ||
|
95173e5bde | ||
|
946c0bcf7d | ||
|
0ac8e66acf | ||
|
7a35a3a671 | ||
|
3d6a1876d4 | ||
|
d0d0d3e0da | ||
|
2f1ddb1edf | ||
|
eacb1dc0e6 | ||
|
f124747fc6 | ||
|
94205baf15 | ||
|
d2ae1f7841 | ||
|
724361cdda | ||
|
40328c13e6 | ||
|
84d254de0b | ||
|
b3e56ce763 | ||
|
bb6f8ef41c | ||
|
e9b5ec90a4 | ||
|
82cb549daf | ||
|
7d9984c109 | ||
|
5d0ce8d2a8 | ||
|
ba60ece609 | ||
|
6d4659a782 | ||
|
df8f14eec6 | ||
|
ed77bcc29a | ||
|
4775b40b95 | ||
|
8ab28849a1 | ||
|
a50e73dc0f | ||
|
d7ee1c23f3 | ||
|
fa2ef3e7ec | ||
|
d4f4117f72 | ||
|
66d99e7fcb | ||
|
cf2e7e1295 | ||
|
94e3c7b756 | ||
|
7c0bd231ed | ||
|
59405ef4c6 | ||
|
c565c2f328 | ||
|
31794008c9 | ||
|
a480e937d2 | ||
|
47b9b8b520 | ||
|
b3940f199e | ||
|
34628d450f | ||
|
80a060dd94 | ||
|
19b0835030 | ||
|
c38aba740c | ||
|
d2417c33de | ||
|
19aa6fcbef | ||
|
3a8ae5be86 | ||
|
ea5c88ca98 | ||
|
57c36a668d | ||
|
70a2251588 | ||
|
a7946cf0e2 | ||
|
65f0b80ffa | ||
|
50bec12ec6 | ||
|
830d5024be | ||
|
0bfd3d752f | ||
|
fa19006d26 | ||
|
25f7764dab | ||
|
9cd349a5aa | ||
|
eafe9a04f2 | ||
|
24f25e0033 | ||
|
75cb3cb2bd | ||
|
7e88230cd1 | ||
|
186e61903a | ||
|
15dd9a6115 | ||
|
b47d2c7476 | ||
|
744f963508 | ||
|
6de36183d3 | ||
|
08521882ca | ||
|
83bdfab255 | ||
|
12672a4a20 | ||
|
e1eec72cc9 | ||
|
4d211335ed | ||
|
700154ceb6 | ||
|
968687b512 | ||
|
6ae9108dec | ||
|
b17e00c31e | ||
|
d4d739bbe2 | ||
|
92608c6ee3 | ||
|
8d9605161c | ||
|
34b191582a | ||
|
807c1b3794 | ||
|
3ff2d46889 | ||
|
1cb5e43e7e | ||
|
4b9e26b974 | ||
|
46d6fab07b | ||
|
73cf0be3fd | ||
|
9ac7c32393 | ||
|
3a172582be | ||
|
d254fb1b05 | ||
|
0b4852a327 | ||
|
328d967ca8 | ||
|
59fc2ddba4 | ||
|
fff6e7b5af | ||
|
19d3dd8c9a | ||
|
479c45b9a3 | ||
|
58f0c8bf04 | ||
|
5c9d690fe3 | ||
|
321c9befec | ||
|
ab23742b28 | ||
|
435bbcf679 | ||
|
cecfe96f01 | ||
|
a9692afa1e | ||
|
7af98055f6 | ||
|
49231bf7cb | ||
|
22651b2c3f | ||
|
47c0479ccf | ||
|
e2a1accb27 | ||
|
8e3168cfbc | ||
|
7492aa8437 | ||
|
df31d4cb84 | ||
|
9a7af38d01 | ||
|
61b65cbf25 | ||
|
cc4e6d23d5 | ||
|
8eed073c63 | ||
|
e06b6eb829 | ||
|
aefe27ace9 | ||
|
94f21ea20e | ||
|
36d2456a87 | ||
|
0f9d938853 | ||
|
f49c121b8c | ||
|
30a18a4ec0 | ||
|
1202d11fd5 | ||
|
a5a2a15351 | ||
|
867632d355 | ||
|
e8963d3473 | ||
|
70bf38ce25 | ||
|
080988d20e | ||
|
dc5fbd5555 | ||
|
dcf4b85b21 | ||
|
d766e74a6a | ||
|
f096a14189 | ||
|
2d3546247a | ||
|
ae5941116d | ||
|
21c72ad1c5 | ||
|
dda5095157 | ||
|
af1c1d8c02 | ||
|
7372dc2079 | ||
|
a54e976e21 | ||
|
d0faf8a64a | ||
|
c4432b7823 | ||
|
cdcd967eb1 | ||
|
ea3826fb8d | ||
|
cbaa26f472 | ||
|
f405bfb613 | ||
|
d3d18c5ff2 | ||
|
e202df4793 | ||
|
727bef92e5 | ||
|
c45c0a98f2 | ||
|
56de320a9a | ||
|
eeec30d78c | ||
|
70a8225b1d | ||
|
4aaa88968a | ||
|
9bd981620c | ||
|
68c6e58e9c | ||
|
afdc2ad5b4 | ||
|
ad1748fa52 | ||
|
07d61a83ae | ||
|
079c3fab00 | ||
|
a772153b64 | ||
|
5fc75d063c | ||
|
ac6d68711c | ||
|
5063e12835 | ||
|
c50f3771da | ||
|
d6952046fc | ||
|
4f5cc166e2 | ||
|
fb7b780833 | ||
|
c255c03193 | ||
|
3574e5a9bc | ||
|
a5ac82e25a | ||
|
db30e9dd49 | ||
|
3bf144686f | ||
|
fea3ba1270 | ||
|
9a6ae7814b | ||
|
6b74f897fd | ||
|
8ac760c2a9 | ||
|
5394790f91 | ||
|
cd43c8bd0d | ||
|
372a602378 | ||
|
ac1251a94b | ||
|
6c40b0cc9a | ||
|
a2f82aba12 | ||
|
8e4ddc00dc | ||
|
f3750598e3 | ||
|
0026de50f9 | ||
|
80cff4bfb6 | ||
|
0a24ceec5e | ||
|
6f640c08a6 | ||
|
0b5d7bb899 | ||
|
f952c4bcf7 | ||
|
79274846f3 | ||
|
2ddf4f5153 | ||
|
6c52c91fe0 | ||
|
485c6bb295 | ||
|
5dfd2e2688 | ||
|
749ddc238f | ||
|
92a4c033b1 | ||
|
c695d059f5 | ||
|
2d196f7b95 | ||
|
4d403ec86d | ||
|
b27908a454 | ||
|
1971495f45 | ||
|
7c05df05b7 | ||
|
55baa2aa4a | ||
|
cd3bd89857 | ||
|
db0e2ef3b2 | ||
|
5cfa0d3be8 | ||
|
556e75ef08 | ||
|
933603ae1e | ||
|
78a4cbacd1 | ||
|
85b501c9eb | ||
|
472e925077 | ||
|
2bf161e522 | ||
|
0adff31dcb | ||
|
86e45f9cbc | ||
|
6f03bb62ce | ||
|
fc8f433573 | ||
|
dbd0981b25 | ||
|
9c308b1b4b | ||
|
5d608766e1 | ||
|
aaa3a901d0 | ||
|
581fe631fd | ||
|
42bcd5e6d3 | ||
|
928c8694b1 | ||
|
c5ab620673 | ||
|
e32fe7aa41 | ||
|
4822afb9d6 | ||
|
b9036abcbc | ||
|
3e8b05b971 | ||
|
bd7081baf2 | ||
|
f03b992c6a | ||
|
e64e5b9c14 | ||
|
2b3ec3ace8 | ||
|
5347c6afeb | ||
|
a355f48580 | ||
|
5addb2f68f | ||
|
403efe4873 | ||
|
4b9c7922a7 | ||
|
e968e748b6 | ||
|
fe2ae7d591 | ||
|
43b7a1a9a0 | ||
|
1fe507651b | ||
|
5cfbcd4c49 | ||
|
0930548640 | ||
|
3079f2f708 | ||
|
ef742124ea | ||
|
b30962a44f | ||
|
435084c20b | ||
|
4d025010c4 | ||
|
73a7f93740 | ||
|
23b83b5ef7 | ||
|
551095aa70 | ||
|
19ca6f9855 | ||
|
f920ca7d6b | ||
|
6f500c2145 | ||
|
6171379cfb | ||
|
5b3f0440be | ||
|
0252a6fd53 | ||
|
caf1534ce6 | ||
|
1a543fe416 | ||
|
96233ea600 | ||
|
81b90d79cb | ||
|
7b7c5f0b13 | ||
|
d848837bc6 | ||
|
77471c4140 | ||
|
6001b0f7af | ||
|
65d001c835 | ||
|
031e7c482e | ||
|
e2838455e0 | ||
|
d1d203726b | ||
|
fe4f8b4d5e | ||
|
a1795364b7 | ||
|
463d76f867 | ||
|
702156554a | ||
|
1c06fd5017 | ||
|
6295374fdb | ||
|
e4df838d9d | ||
|
6fe8c1ad8f | ||
|
35ab8a7c98 | ||
|
85b6d8554d | ||
|
d7067c0b22 | ||
|
ae73e94c3e | ||
|
6512bbf70c | ||
|
aad576fdd0 | ||
|
18f64ce80b | ||
|
f1003939a9 | ||
|
3d4909bbf5 | ||
|
d236113e40 | ||
|
9a3d65c313 | ||
|
35bac35bb0 | ||
|
37c2f941de | ||
|
acb0993bc9 | ||
|
87447def38 | ||
|
2199d60732 | ||
|
70927d5e04 | ||
|
14fb1cfd8d | ||
|
3644937fff | ||
|
0838d443a1 | ||
|
0dc08c8f8c | ||
|
40ad8ce25e | ||
|
c39f0ae3bc | ||
|
47543b19b7 | ||
|
90e3f3235c | ||
|
b7bea608f6 | ||
|
784e454633 | ||
|
09e3cab52c | ||
|
68e2d01a85 | ||
|
b0fd7ff856 | ||
|
a289e4809d | ||
|
f8b9563ac4 | ||
|
5af946dbfe | ||
|
51f95c8a5c | ||
|
9bc82d6b5f | ||
|
df2a261d32 | ||
|
7e8aa0a67d | ||
|
6294e1aa4f | ||
|
b0411d5da9 | ||
|
8f7a996800 | ||
|
18e4b010f0 | ||
|
59dbeac5be | ||
|
6a914fb2b5 | ||
|
e51cdd987c | ||
|
d0a0a8a9c9 | ||
|
96d40556dd | ||
|
7695dede06 | ||
|
102c6225ce | ||
|
fc14f64821 | ||
|
98bd15ebf2 | ||
|
f6057d2572 | ||
|
1d98604e88 | ||
|
3758611d13 | ||
|
888f1d8e55 | ||
|
1037508fb5 | ||
|
a2d0a1445d | ||
|
a2ac2005b5 | ||
|
dd59a85554 | ||
|
d01885ee06 | ||
|
762aa937fd | ||
|
8e1e29bbd4 | ||
|
a179b3dbf0 | ||
|
3c586159d2 | ||
|
38234c9501 | ||
|
6f9e209315 | ||
|
0d2cb690b3 | ||
|
02b3a138b6 | ||
|
f6970ba403 | ||
|
487ef303d8 | ||
|
4cb075d0eb | ||
|
f3eafb1b33 | ||
|
c469757af9 | ||
|
a92ed9afc1 | ||
|
68b4d30986 | ||
|
74e745a291 | ||
|
28d0b6d891 | ||
|
ebe41411ad | ||
|
7bd5857b3c | ||
|
564c2de815 | ||
|
0610a1808b | ||
|
e9190a6bd6 | ||
|
4faeabefa2 | ||
|
b77e811402 | ||
|
f4cb20f081 | ||
|
6f0478b383 | ||
|
e1cbe21cd1 | ||
|
24f28ef87a | ||
|
796a00f692 | ||
|
c3eb455b5b | ||
|
7601492081 | ||
|
503b90316f | ||
|
f4219791a1 | ||
|
b5fabc871b | ||
|
c0ceb66ad4 | ||
|
a0d19d88e6 | ||
|
efe0e60182 | ||
|
b49e1bad53 | ||
|
9b5478ee63 | ||
|
c4b6dc2399 | ||
|
b9bb2e4de5 | ||
|
36f910ed28 | ||
|
66d416a37a | ||
|
8951eb38bc | ||
|
86e13b06a4 | ||
|
995ea0ca94 | ||
|
190c1302b1 | ||
|
f5d94509a1 | ||
|
907a1fa2bb | ||
|
d87a0e3c83 | ||
|
53ecde1967 | ||
|
ef5e2beb77 | ||
|
3f8982b75a | ||
|
a3cd1d1121 | ||
|
b5a2e9f2b9 | ||
|
1aeb3da962 | ||
|
530bf04af5 | ||
|
ae92a0b8ea | ||
|
c88af25949 | ||
|
a497d986a1 | ||
|
97fd8f0c9b | ||
|
6a594d0e1d | ||
|
2469b67515 | ||
|
04ef48f9f2 | ||
|
18e041c405 | ||
|
9ef7ac7117 | ||
|
3706ba3121 | ||
|
4a1b31bac4 | ||
|
a2d4abc1f8 | ||
|
b306df2c3b | ||
|
ec271043cd | ||
|
a2dfec499d | ||
|
b0cc65aff6 | ||
|
56755ae8a3 | ||
|
016f5a418c | ||
|
d9446d125e | ||
|
ddf2f36166 | ||
|
efa80304d2 | ||
|
26665b231a | ||
|
f443631292 | ||
|
3614715c31 | ||
|
b08a31caee | ||
|
d283c900f4 | ||
|
9eb123f8b1 | ||
|
87f0eff955 | ||
|
75e96a42ff | ||
|
d03abcc73c | ||
|
18ea57a8cc | ||
|
8d1c75e732 | ||
|
030927cf03 | ||
|
71e9981c1a | ||
|
415ed60227 | ||
|
f6a80e118e | ||
|
1246fcf8f6 | ||
|
4e39c70123 | ||
|
c8031acee7 | ||
|
df045a56ae | ||
|
0a66d039c2 | ||
|
633a1fbffe | ||
|
02fcbd9792 | ||
|
e68fc821cf | ||
|
8d84c91e03 | ||
|
3cb1a41aa8 | ||
|
7a928ba5ad | ||
|
337f4accee | ||
|
46e36240a2 | ||
|
0505de301d | ||
|
7684e219a9 | ||
|
27e5031ad7 | ||
|
af637362f7 | ||
|
42d893e1e7 | ||
|
3cf4bec763 | ||
|
9ce2bf98ab | ||
|
da7efd73cf | ||
|
b3d28bf85d | ||
|
77c2f5dcd6 | ||
|
d161da039a | ||
|
71ad719aaf | ||
|
f7fc609abe | ||
|
61175392ed | ||
|
625eb79ca3 | ||
|
3f0b19d17d | ||
|
98506d6a73 | ||
|
d2a6dcd41a | ||
|
31aacb3361 | ||
|
c7a907bdc9 | ||
|
771922da76 | ||
|
273f0fed77 | ||
|
64e35815db | ||
|
5d90971b58 | ||
|
016e0e105b | ||
|
18442b2449 | ||
|
a45d199896 | ||
|
5d26fec9a5 | ||
|
5fd74577c4 | ||
|
7403d4679f | ||
|
ab747f0aee | ||
|
18f33417ef | ||
|
899342057d | ||
|
87abbe678d | ||
|
fa207ebaff | ||
|
324c03e6ae | ||
|
025df08ac0 | ||
|
d642d8507d | ||
|
8cef37d704 | ||
|
8a9ed1ed7a | ||
|
c3d63ca667 | ||
|
5c6356459c | ||
|
bb87891cb6 | ||
|
4251976c48 | ||
|
a4fca12ebf | ||
|
5f265d0c16 | ||
|
0a737c4e9b | ||
|
1d84e07988 | ||
|
3b8e49dc64 | ||
|
51804925f6 | ||
|
80015a728c | ||
|
ad9b6661c2 | ||
|
a401a000e4 | ||
|
2b63058b45 | ||
|
f83a357d33 | ||
|
5a3911c65f | ||
|
e94b7197f2 | ||
|
bcdb36b7b2 | ||
|
ebc24362b2 | ||
|
4496996c34 | ||
|
7fa67b2b22 | ||
|
92467b5e59 | ||
|
26c6827601 | ||
|
66901e4f73 | ||
|
133d8b60c1 | ||
|
0ed05e221a | ||
|
92a751ed84 | ||
|
df4af20b6a | ||
|
03eaad4a32 | ||
|
5535896efa | ||
|
ed865dd3c0 | ||
|
fded695b45 | ||
|
73ed031661 | ||
|
7f45b3890e | ||
|
9482373e90 | ||
|
ce0362eef8 | ||
|
76238db4bb | ||
|
5d685cebf0 | ||
|
cae7e5b5af | ||
|
91b5618743 | ||
|
5494ce5def | ||
|
7c97045fb6 | ||
|
d3c213892f | ||
|
470bc79d97 | ||
|
a7baea3070 | ||
|
e29e9ca3f9 | ||
|
d7e87b34c7 | ||
|
0022abe896 | ||
|
dc1f5725d0 | ||
|
9d39a2c0b4 | ||
|
f6cd35d94b | ||
|
cb5aa7006a | ||
|
7c28edd255 | ||
|
6d8a18e71b | ||
|
f705d81e17 | ||
|
fdaf9fc098 | ||
|
9b307d02c6 | ||
|
da622915b1 | ||
|
d868d290c1 | ||
|
b195cf50ad | ||
|
f6cb2075f0 | ||
|
898091d210 | ||
|
1cf7c72721 | ||
|
ddcc114d0c | ||
|
30e926f92c | ||
|
d63caa7776 | ||
|
d531f8e085 | ||
|
22fc36e16e | ||
|
3fea05c4d6 | ||
|
cdd5790808 | ||
|
b7b4dbfcdf | ||
|
fc0266a62e | ||
|
3e4b88322d | ||
|
a440afe8eb | ||
|
2e9c4f991e | ||
|
1ce13d631d | ||
|
2d223c9158 | ||
|
31bbc026fd | ||
|
6da5c21cff | ||
|
fdca9e1041 | ||
|
129f5cce95 | ||
|
e21c114b70 | ||
|
bbc6dcc50b | ||
|
4f303de7a4 | ||
|
7deb3b3492 | ||
|
5f2785c6c9 | ||
|
eb3c391624 | ||
|
863843a1cf | ||
|
f015767f50 | ||
|
02103c07a3 | ||
|
0084ce757c | ||
|
731f07817b | ||
|
f67eaef90b | ||
|
a2a1eefbed | ||
|
ba061a49e4 | ||
|
0b5c96e249 | ||
|
06db6f7e04 | ||
|
9e44b33401 | ||
|
940af74c2d | ||
|
01dfb778e9 | ||
|
bc3521fd04 | ||
|
7117c61bbf | ||
|
3bd427afab | ||
|
840bed5222 | ||
|
986b42fc1d | ||
|
e4c631c171 | ||
|
cf6eaf364d | ||
|
ac60516638 | ||
|
dd51adcd3f | ||
|
0903460fc4 | ||
|
e58aaa6db6 | ||
|
ab37617f91 | ||
|
273c10f17d | ||
|
11684675d7 | ||
|
fbfcec4873 | ||
|
9a11a93a3f | ||
|
40fbc8d1ea | ||
|
1506146450 | ||
|
ee29d2e476 | ||
|
02a4a5fecf | ||
|
882c024bc8 | ||
|
576e8e16b5 | ||
|
4f2a111470 | ||
|
fdca22ca5b | ||
|
4a9080bdfd | ||
|
f9afc19ed4 | ||
|
686c372baf | ||
|
5067be6bb7 | ||
|
83d0fd421c | ||
|
bf181aaa90 | ||
|
5e69c670bb | ||
|
ab4cb2c29d | ||
|
ae996b80f8 | ||
|
206401855a | ||
|
921b4d9b77 | ||
|
fe0b320397 | ||
|
60883773f6 | ||
|
8895aee7a3 | ||
|
ea0c8e9162 | ||
|
745aae208b | ||
|
98cfd0909b | ||
|
638a3e8b1c | ||
|
62613baad5 | ||
|
19ed83100d | ||
|
d9e326f2cd | ||
|
2ccb0c8db6 | ||
|
8b1333a837 | ||
|
8a0a33a0de | ||
|
4155aa7486 | ||
|
017313eda5 | ||
|
af343ed6ce | ||
|
660c77d0d5 | ||
|
866d3dbd07 | ||
|
100cd2fdd4 | ||
|
bd0f7a536a | ||
|
d600cdf366 | ||
|
976b4ad298 | ||
|
b32bc3a034 | ||
|
9902d191aa | ||
|
ddd10f630c | ||
|
106e1fa801 | ||
|
dd6c8976f8 | ||
|
3675daf26d | ||
|
158dc7ae14 | ||
|
cc5649cfb2 | ||
|
ea5bfd1693 | ||
|
6f5bb03b2d | ||
|
76661a3e6c | ||
|
3d54adf8df | ||
|
437c967098 | ||
|
d05f192a4f | ||
|
9c804d1ca2 | ||
|
3bc92abe36 | ||
|
d5fcc38281 | ||
|
61d7ba1e40 | ||
|
a3417d9864 | ||
|
ce93067229 | ||
|
481aac5f80 | ||
|
4a871943b8 | ||
|
398f882ac2 | ||
|
209c8d9016 | ||
|
b928dd1222 | ||
|
19769d8348 | ||
|
c4d188200c | ||
|
607a22de00 | ||
|
dcb01a249b | ||
|
2d92c93af1 | ||
|
0bad639b3d | ||
|
fbadceb72a | ||
|
2bf3fed6e6 | ||
|
6563ebb1ca | ||
|
133ba3f14f | ||
|
f0bf8dd1fd | ||
|
eb747cc15e | ||
|
1d782b3a66 | ||
|
2156fb402b | ||
|
f3349d4b3d | ||
|
6428417aa0 | ||
|
35c5015db2 | ||
|
3fd14a420e | ||
|
b6085fef8d | ||
|
1af8f9969b | ||
|
c0e9b3ba8e | ||
|
3f9fd91334 | ||
|
d4007484f3 | ||
|
2d0f229a2a | ||
|
d68bc4c0d4 | ||
|
ccc83412c9 | ||
|
57a8cb6e1a | ||
|
5ca18c53f9 | ||
|
c749c44110 | ||
|
c34bd72ef6 | ||
|
244b31f07f | ||
|
8810561825 | ||
|
1bcaa934ee | ||
|
e4369274fa | ||
|
7a5d6d67e6 | ||
|
3ba8846807 | ||
|
90b914e478 | ||
|
c60a27ae75 | ||
|
1e1b0ddbbb | ||
|
8995019e74 | ||
|
6fc6a2ba4c | ||
|
1693c83181 | ||
|
8bddd5fb4b | ||
|
b7530ab230 | ||
|
b136a4ab9a | ||
|
06f1c03c4b | ||
|
cb795dd32d | ||
|
15a060bfbf | ||
|
ec41b697dc | ||
|
4d814126b0 | ||
|
726e0467e9 | ||
|
4359aad89f | ||
|
859a091fae | ||
|
7c09142953 | ||
|
8296e35435 | ||
|
1b047ba049 | ||
|
a07328c99d | ||
|
85ddb4a8a0 | ||
|
ca54e3a61d | ||
|
700f671527 | ||
|
5736aadd10 | ||
|
3bb8ca2e21 | ||
|
756e3b292b | ||
|
1386466d7e | ||
|
fb53a69dd0 | ||
|
756f561ddd | ||
|
33bf3b2a3a | ||
|
58b11e8198 | ||
|
f53e6af698 | ||
|
5e87f7d479 | ||
|
93ed8efb17 | ||
|
b79cbd466c | ||
|
5d64954ada | ||
|
e157a94de9 | ||
|
04909c9c58 | ||
|
e85660acf2 | ||
|
df87baf38b | ||
|
a6c64b78d6 | ||
|
d11f32141e | ||
|
f13eec176c | ||
|
0a0350f509 | ||
|
dddc92949c | ||
|
4db5da1fbe | ||
|
7e0f280b69 | ||
|
0b17cf754d | ||
|
114d070dc2 | ||
|
6d7e77b360 | ||
|
266e890c46 | ||
|
676973a18e | ||
|
8828e1d8e2 | ||
|
0b132252c4 | ||
|
bd6afe27ee | ||
|
0f307d1fa7 | ||
|
086a3d4fda | ||
|
680811eeff | ||
|
f3837bae79 | ||
|
d216d06c8c | ||
|
0ff9818ebf | ||
|
c99729d062 | ||
|
a51738f1c3 | ||
|
ab0b66425c | ||
|
ca8940b860 | ||
|
1d3bd602eb | ||
|
31d3719b48 | ||
|
b13956c5ec | ||
|
08be0ee020 | ||
|
8c7d57b486 | ||
|
2308dea140 | ||
|
8769ab231d | ||
|
3c02fb7d4a | ||
|
de6844250f | ||
|
f9e15ff8a3 | ||
|
e4863830c9 | ||
|
d8a9243532 | ||
|
05a459d4df | ||
|
6316b94af4 | ||
|
8939ba66d3 | ||
|
d6a6ca1db4 | ||
|
83dfc0590d | ||
|
d28f725762 | ||
|
67a293e03b | ||
|
3de3205648 | ||
|
f2b95e5fbe | ||
|
ab5580cb11 | ||
|
9ae7ec5930 | ||
|
f0a01ba25d | ||
|
97e17bbddb | ||
|
0a59f86329 | ||
|
e1ffe57282 | ||
|
adb0e67b25 | ||
|
e46fe6b77b | ||
|
7377798385 | ||
|
74e73c470f | ||
|
bf6252ac1d | ||
|
16946372cc | ||
|
3ca302b85d | ||
|
345e50ae00 | ||
|
bccff1b442 | ||
|
3a85b5201a | ||
|
d88e4b0d45 | ||
|
f92c11edaf | ||
|
d79e3618de | ||
|
c9606d353b | ||
|
fc3834bff5 | ||
|
49b444e480 | ||
|
9cb97640b9 | ||
|
d9873e085d | ||
|
9486931674 | ||
|
740eaa43ae | ||
|
377558b54e | ||
|
27f8809a2c | ||
|
67cce15d02 | ||
|
99fd7f628e | ||
|
4b78e8e327 | ||
|
dcf1a892bf | ||
|
9b89f66bba | ||
|
07396b8b34 | ||
|
6d4220e9a0 | ||
|
71e73c7cf2 | ||
|
981c7b5649 | ||
|
fde01fafd7 | ||
|
8836fdeeaa | ||
|
68fffd7c6d | ||
|
3543821df0 | ||
|
9ed5b66bb4 | ||
|
fb01202f8d | ||
|
dfa021fbf7 | ||
|
2f7ec5b368 | ||
|
5565e6c55c | ||
|
d23b54422b | ||
|
d5008bc656 | ||
|
5d0f8021b8 | ||
|
9a3a208809 | ||
|
cc65217f58 | ||
|
5b30347dfa | ||
|
4571c5b22f | ||
|
cb7bfe7a66 | ||
|
ac47710584 | ||
|
e2da7e406b | ||
|
98167e35e5 | ||
|
2843c3b2a3 | ||
|
f8eb6f8e0d | ||
|
b9159dacbc | ||
|
409cd48b42 | ||
|
b9060da750 | ||
|
3779b9203a | ||
|
cf97136237 | ||
|
7ee5565a83 | ||
|
d6bbdfa5f4 | ||
|
11b7e5c0f8 | ||
|
9ef3a1bfff | ||
|
30983a4efd | ||
|
140e50253f | ||
|
e109f34a6b | ||
|
61a01f5c81 | ||
|
d07cf83d93 | ||
|
9c1f3c4be8 | ||
|
981fca64e2 | ||
|
7920cc6280 | ||
|
1725da45d4 | ||
|
383e540ee0 | ||
|
7e887829f6 | ||
|
c74929fc42 | ||
|
1e61883b2f | ||
|
89dda11b56 | ||
|
7373971573 | ||
|
1bbe3441d8 | ||
|
deda909eba | ||
|
019839dbf9 | ||
|
ecb8419ee0 | ||
|
ac5718c666 | ||
|
6ea3272828 | ||
|
c2c0358781 | ||
|
2612df97d0 | ||
|
b80158befe | ||
|
938d08134e | ||
|
011c2059a5 | ||
|
5479befabb | ||
|
8bc23e6f59 | ||
|
b68e99b2c0 | ||
|
13fb471f29 | ||
|
33d4dc9749 | ||
|
55963bef23 | ||
|
71f456286a | ||
|
9354227a4e | ||
|
08efbbb904 | ||
|
4e560a9395 | ||
|
f322783d15 | ||
|
6dbca18f97 | ||
|
d196f0be34 | ||
|
4c6786e8af | ||
|
0f9560ffe0 | ||
|
b1fe61ed68 | ||
|
d81b85a49a | ||
|
3fe44ee73b | ||
|
4cb8c91475 | ||
|
9126beffc2 | ||
|
b84c1c24b4 | ||
|
ea6500ebfd | ||
|
a118a5a132 | ||
|
8af721993b | ||
|
04a92e547d | ||
|
23d58c1217 | ||
|
fedcf6dabb | ||
|
66cd35d304 | ||
|
767b5c3d7e | ||
|
6cae524910 | ||
|
6315166749 | ||
|
af1937c596 | ||
|
c4d2654dc5 | ||
|
d657356ffa | ||
|
1c404252f0 | ||
|
cc7fe09efa | ||
|
aba7e3fba3 | ||
|
dbc8852730 | ||
|
80805b3bc6 | ||
|
e0e93dd29e | ||
|
39d28af963 | ||
|
fb85030bc3 | ||
|
ca71d37447 | ||
|
d28e2a03ad | ||
|
b63136da52 | ||
|
b59348fffe | ||
|
bbcbc411ea | ||
|
7aa840a956 | ||
|
b0f756b1a8 | ||
|
beadea5305 | ||
|
26b837b085 | ||
|
b7121502d6 | ||
|
9cfbbd122b | ||
|
79c70b7629 | ||
|
607fad2105 | ||
|
2b3138ef80 | ||
|
24f8faca67 | ||
|
b5e04df398 | ||
|
fa163cbc2e | ||
|
17ad3c8581 | ||
|
3cc1a0a59d | ||
|
0973301b0f | ||
|
4a377bbf23 | ||
|
816c503d3a | ||
|
8321642a34 | ||
|
017de77405 | ||
|
620da53fe7 | ||
|
e12a0153bb | ||
|
63a84f5398 | ||
|
bd8fe6d4db | ||
|
05b93aaaf1 | ||
|
b552b792df | ||
|
e98ba46e4b | ||
|
fa9365d5fa | ||
|
dfc37a48c3 | ||
|
364a3bc70a | ||
|
858370dced | ||
|
ddb1f86f23 | ||
|
adb029eb98 | ||
|
fc0cf79123 | ||
|
270c2eb9c0 | ||
|
ef44abae6e | ||
|
acd96f1382 | ||
|
c177a6797e | ||
|
e6a2f8ca00 | ||
|
7cb96c6652 | ||
|
bbe0486935 | ||
|
2cc09aca91 | ||
|
f92c88aff7 | ||
|
de149975d2 | ||
|
94bf107838 | ||
|
2f38639a2e | ||
|
509ba1e8a2 | ||
|
76b9838bfd | ||
|
6ecc3cc4ae | ||
|
f8004570ab | ||
|
76abbf03d7 | ||
|
94346e8892 | ||
|
bd04779e40 | ||
|
dce411e0e6 | ||
|
a063b63d1c | ||
|
3570f592f5 | ||
|
377ccd8acf | ||
|
7112deb167 | ||
|
c4b83459b8 | ||
|
a615528c7f | ||
|
77058ab356 | ||
|
ad56275801 | ||
|
6aaf47493d | ||
|
4fc6db6317 | ||
|
f49f03d11e | ||
|
f0d77deea4 | ||
|
b35f27d580 | ||
|
4decdfc07c | ||
|
4315045e4a | ||
|
cdcd38f06f | ||
|
e84bd3a1c1 | ||
|
05c69ed9fa | ||
|
7c8ded3275 | ||
|
c3ef8ad3c7 | ||
|
b6250c0094 | ||
|
77d74eba06 | ||
|
4d8ca7aaad | ||
|
10699e5de0 | ||
|
da1b0aa041 | ||
|
c27f13230c | ||
|
59c2788621 | ||
|
fbf85fa0ba | ||
|
cc1230c5de | ||
|
0fc209acfb | ||
|
8a3a6d7fe9 | ||
|
6cc7978b4a | ||
|
451ee7a8ae | ||
|
8abd843fdd | ||
|
c4732b776e | ||
|
107bd854eb | ||
|
83f7721fdd | ||
|
e3015765b3 | ||
|
dc426510f5 | ||
|
b617c799d0 | ||
|
a124bbc790 | ||
|
71a08c09ea | ||
|
d1ab1f674e | ||
|
1b198e12f6 | ||
|
4106ed669e | ||
|
00d535a620 | ||
|
c8d4e4853b | ||
|
47f3c00d0c | ||
|
8eaa701230 | ||
|
613fc67bd1 | ||
|
bc71e18cba | ||
|
94ac15e4de | ||
|
7ebe92163d | ||
|
55937a933e | ||
|
6622a9f264 | ||
|
8feb63be0c | ||
|
9488b419c3 | ||
|
34b7e667a7 | ||
|
76075909c9 | ||
|
73da37f152 | ||
|
7206be0020 | ||
|
35927e32bb | ||
|
2bd1df0659 | ||
|
c6df391a9a | ||
|
45584b44a6 | ||
|
d831ccef4c | ||
|
bfa5092c10 | ||
|
f43e567bf0 | ||
|
6854f23cca | ||
|
dc4341f98c | ||
|
514fa9f1a2 | ||
|
a399675f60 | ||
|
10e00b3318 | ||
|
9c28c07af4 | ||
|
799609c7a8 | ||
|
a792ed6e41 | ||
|
33d3db62b2 | ||
|
23b8418ee6 | ||
|
124dc158fc | ||
|
bc9a9414a2 | ||
|
7bfa15d471 | ||
|
16dba79a39 | ||
|
26e6b4a414 | ||
|
01ff6c932c | ||
|
467c04f382 | ||
|
f824d9e0ea | ||
|
5af6f34307 | ||
|
fef6b2dc46 | ||
|
42e86a80c5 | ||
|
6b9ac717de | ||
|
cbb6e9a367 | ||
|
a16edfc526 | ||
|
ced9670eba | ||
|
abcaaa8054 | ||
|
094c5f0807 | ||
|
8d5e69566b | ||
|
244287bdd0 | ||
|
e19330b0c2 | ||
|
248d7f5678 | ||
|
ebf9d522e0 | ||
|
05f25fa85f | ||
|
5de9e4fe6a | ||
|
fca4cc7d3b | ||
|
fff1a8a4d6 | ||
|
744729713d | ||
|
810534c661 | ||
|
6a437c0b4f | ||
|
eb14a2220f | ||
|
0a750b7b61 | ||
|
c571516c68 | ||
|
b953ae9dd4 | ||
|
8a71fae732 | ||
|
3084359155 | ||
|
56f7cd87ec | ||
|
b46a94a41d | ||
|
4ccd718183 | ||
|
82f28efaaf | ||
|
2282d0df61 | ||
|
00bd7f16a5 | ||
|
93f1ab2b34 | ||
|
144126f56a | ||
|
4dc53d5a8e | ||
|
93cc48ca68 | ||
|
44c972f2dd | ||
|
b2ebcda6fb | ||
|
859b3b6f12 | ||
|
fe6d9c2617 | ||
|
8da35ca4c8 | ||
|
0b4aa81f8c | ||
|
480875f676 | ||
|
e3d862dc15 | ||
|
fe6ebe8e66 | ||
|
56ac85af37 | ||
|
953eb0cc1d | ||
|
54a7f7a570 | ||
|
b677157924 | ||
|
7411abde24 | ||
|
8375ef7d5b | ||
|
38ea29afd1 | ||
|
bf21f9d0f2 | ||
|
3591a01fdb | ||
|
f597bfe556 | ||
|
2318ffc493 | ||
|
a6c72566a5 | ||
|
9bcb7e0b9e | ||
|
ae08698253 | ||
|
1247c5b5ee | ||
|
47cef90efd | ||
|
4218e6e0f0 | ||
|
70bff61749 | ||
|
996a399f94 | ||
|
16b0411ea9 | ||
|
29532696a9 | ||
|
713612a689 | ||
|
a274b6a8fc | ||
|
f1644ee1d2 | ||
|
624ce3462b | ||
|
ebf5eb70ca | ||
|
20b5843b42 | ||
|
0843d35cc5 | ||
|
82812bac2f | ||
|
17b726f6f3 | ||
|
653d7e8127 | ||
|
870bece358 | ||
|
c32305234c | ||
|
f6857625de | ||
|
0d8b8f6ca3 | ||
|
e22c683c34 | ||
|
8952c0d7ea | ||
|
43ef4f4a29 | ||
|
43d924252f | ||
|
a24ea4dafa | ||
|
8e25895cbf | ||
|
7b7595c476 | ||
|
fd3a10489d | ||
|
918d462946 | ||
|
11a638ed70 | ||
|
b233c7c08c | ||
|
4e2e54676a | ||
|
24211a90bc | ||
|
da57653a01 | ||
|
d6baad6f45 | ||
|
473bff6e5d | ||
|
c794e63f67 | ||
|
ba2428d9b9 | ||
|
5046e49c8b | ||
|
cb129e2bf1 | ||
|
e2a3a0bedf | ||
|
91d3d15c32 | ||
|
1051dbb3cc | ||
|
3fa96fc91b | ||
|
7ff1ce5432 | ||
|
8aae994720 | ||
|
b7703c32a1 | ||
|
a27a4c26df | ||
|
c70420438a | ||
|
1f284d74c4 | ||
|
0659667590 | ||
|
ffea5e4048 | ||
|
70174af974 | ||
|
726f4605d2 | ||
|
876ce48837 | ||
|
ad6d31ce81 | ||
|
dbf19b585c | ||
|
1fb42bb8af | ||
|
4432d28c09 |
391 changed files with 36497 additions and 15958 deletions
24
.codeclimate.yml
Normal file
24
.codeclimate.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
version: "2"
|
||||||
|
plugins:
|
||||||
|
duplication:
|
||||||
|
enabled: true
|
||||||
|
config:
|
||||||
|
languages:
|
||||||
|
python:
|
||||||
|
python_version: 3
|
||||||
|
shellcheck:
|
||||||
|
enabled: true
|
||||||
|
pep8:
|
||||||
|
enabled: true
|
||||||
|
fixme:
|
||||||
|
enabled: true
|
||||||
|
sonar-python:
|
||||||
|
enabled: true
|
||||||
|
config:
|
||||||
|
tests_patterns:
|
||||||
|
- bin/*
|
||||||
|
- data/**
|
||||||
|
- doc/*
|
||||||
|
- src/**
|
||||||
|
- tests/**
|
|
@ -1,2 +1,2 @@
|
||||||
[report]
|
[report]
|
||||||
omit=src/yunohost/tests/*,src/yunohost/vendor/*,/usr/lib/moulinette/yunohost/*
|
omit=src/tests/*,src/vendor/*,/usr/lib/moulinette/yunohost/*,/usr/lib/python3/dist-packages/yunohost/tests/*,/usr/lib/python3/dist-packages/yunohost/vendor/*
|
||||||
|
|
30
.github/workflows/autoblack.yml
vendored
Normal file
30
.github/workflows/autoblack.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
name: Check / auto apply Black
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "dev" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
black:
|
||||||
|
name: Check / auto apply black
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Check files using the black formatter
|
||||||
|
uses: psf/black@stable
|
||||||
|
id: black
|
||||||
|
with:
|
||||||
|
options: "."
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v6
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
title: "Format Python code with Black"
|
||||||
|
commit-message: ":art: Format Python code with Black"
|
||||||
|
body: |
|
||||||
|
This pull request uses the [psf/black](https://github.com/psf/black) formatter.
|
||||||
|
base: ${{ github.head_ref }} # Creates pull request onto pull request or commit branch
|
||||||
|
branch: actions/black
|
42
.github/workflows/codeql.yml
vendored
Normal file
42
.github/workflows/codeql.yml
vendored
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "dev" ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ "dev" ]
|
||||||
|
paths-ignore:
|
||||||
|
- 'src/tests/**'
|
||||||
|
schedule:
|
||||||
|
- cron: '43 12 * * 3'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'python' ]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
queries: security-extended,security-and-quality
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
39
.github/workflows/n_updater.yml
vendored
Normal file
39
.github/workflows/n_updater.yml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# This workflow allows GitHub Actions to automagically update YunoHost NodeJS helper whenever a new release of n is detected.
|
||||||
|
name: Check for new n releases
|
||||||
|
on:
|
||||||
|
# Allow to manually trigger the workflow
|
||||||
|
workflow_dispatch:
|
||||||
|
# Run it every day at 5:00 UTC
|
||||||
|
schedule:
|
||||||
|
- cron: '0 5 * * *'
|
||||||
|
jobs:
|
||||||
|
updater:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Fetch the source code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Run the updater script
|
||||||
|
id: run_updater
|
||||||
|
run: |
|
||||||
|
# Download n
|
||||||
|
wget https://raw.githubusercontent.com/tj/n/master/bin/n --output-document=helpers/vendor/n/n
|
||||||
|
|
||||||
|
echo "VERSION=$(sed -n 's/^VERSION=\"\(.*\)\"/\1/p' < helpers/vendor/n/n)" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v6
|
||||||
|
id: cpr
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
commit-message: Update n to ${{ env.VERSION }}
|
||||||
|
committer: 'yunohost-bot <yunohost-bot@users.noreply.github.com>'
|
||||||
|
author: 'yunohost-bot <yunohost-bot@users.noreply.github.com>'
|
||||||
|
signoff: false
|
||||||
|
base: dev
|
||||||
|
branch: ci-auto-update-n-${{ env.VERSION }}
|
||||||
|
delete-branch: true
|
||||||
|
title: 'Upgrade n to ${{ env.VERSION }}'
|
||||||
|
body: |
|
||||||
|
Upgrade `n` to ${{ env.VERSION }}
|
||||||
|
draft: false
|
11
.gitignore
vendored
11
.gitignore
vendored
|
@ -31,7 +31,14 @@ pip-log.txt
|
||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
|
|
||||||
# moulinette lib
|
# moulinette lib
|
||||||
src/yunohost/locales
|
src/locales
|
||||||
|
|
||||||
# Test
|
# Test
|
||||||
src/yunohost/tests/apps
|
src/tests/apps
|
||||||
|
|
||||||
|
# Tmp/local doc stuff
|
||||||
|
doc/bash-completion.sh
|
||||||
|
doc/bash_completion.d
|
||||||
|
doc/openapi.js
|
||||||
|
doc/openapi.json
|
||||||
|
doc/swagger
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- install
|
- install
|
||||||
- tests
|
- test
|
||||||
- lint
|
- lint
|
||||||
- doc
|
- doc
|
||||||
- translation
|
- translation
|
||||||
|
@ -13,20 +13,43 @@ default:
|
||||||
# All jobs are interruptible by default
|
# All jobs are interruptible by default
|
||||||
interruptible: true
|
interruptible: true
|
||||||
|
|
||||||
|
code_quality:
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_TAG # Only for tags
|
||||||
|
|
||||||
|
|
||||||
|
code_quality_html:
|
||||||
|
extends: code_quality
|
||||||
|
variables:
|
||||||
|
REPORT_FORMAT: html
|
||||||
|
artifacts:
|
||||||
|
paths: [gl-code-quality-report.html]
|
||||||
|
rules:
|
||||||
|
- if: $CI_COMMIT_TAG # Only for tags
|
||||||
|
|
||||||
|
|
||||||
# see: https://docs.gitlab.com/ee/ci/yaml/#switch-between-branch-pipelines-and-merge-request-pipelines
|
# see: https://docs.gitlab.com/ee/ci/yaml/#switch-between-branch-pipelines-and-merge-request-pipelines
|
||||||
workflow:
|
workflow:
|
||||||
rules:
|
rules:
|
||||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event" # If we move to gitlab one day
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event" # If we move to gitlab one day
|
||||||
- if: $CI_PIPELINE_SOURCE == "external_pull_request_event" # For github PR
|
- if: $CI_PIPELINE_SOURCE == "external_pull_request_event" # For github PR
|
||||||
- if: $CI_COMMIT_TAG # For tags
|
- if: $CI_COMMIT_TAG # For tags
|
||||||
- if: $CI_COMMIT_REF_NAME == "ci-format-dev" # Ignore black formatting branch created by the CI
|
- if: $CI_COMMIT_REF_NAME == "ci-format-$CI_DEFAULT_BRANCH" # Ignore black formatting branch created by the CI
|
||||||
|
when: never
|
||||||
|
- if: $CI_COMMIT_REF_NAME == "actions/black" # Ignore black formatting branch created by the CI
|
||||||
when: never
|
when: never
|
||||||
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push" # If it's not the default branch and if it's a push, then do not trigger a build
|
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "push" # If it's not the default branch and if it's a push, then do not trigger a build
|
||||||
when: never
|
when: never
|
||||||
- when: always
|
- when: always
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
YNH_BUILD_DIR: "ynh-build"
|
GIT_CLONE_PATH: '$CI_BUILDS_DIR/$CI_COMMIT_SHA/$CI_JOB_ID'
|
||||||
|
YNH_SOURCE: "https://github.com/yunohost"
|
||||||
|
YNH_DEBIAN: "bullseye"
|
||||||
|
YNH_SKIP_DIAGNOSIS_DURING_UPGRADE: "true"
|
||||||
|
|
||||||
include:
|
include:
|
||||||
|
- template: Code-Quality.gitlab-ci.yml
|
||||||
- local: .gitlab/ci/*.gitlab-ci.yml
|
- local: .gitlab/ci/*.gitlab-ci.yml
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
.build-stage:
|
.build-stage:
|
||||||
stage: build
|
stage: build
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
variables:
|
variables:
|
||||||
YNH_SOURCE: "https://github.com/yunohost"
|
YNH_BUILD_DIR: "$GIT_CLONE_PATH/build"
|
||||||
before_script:
|
before_script:
|
||||||
- mkdir -p $YNH_BUILD_DIR
|
- mkdir -p $YNH_BUILD_DIR
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- $YNH_BUILD_DIR/*.deb
|
- ./*.deb
|
||||||
|
|
||||||
.build_script: &build_script
|
.build_script: &build_script
|
||||||
- cd $YNH_BUILD_DIR/$PACKAGE
|
- cd $YNH_BUILD_DIR/$PACKAGE
|
||||||
- VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null)
|
- VERSION=$(dpkg-parsechangelog -S Version 2>/dev/null)
|
||||||
- VERSION_NIGHTLY="${VERSION}+$(date +%Y%m%d%H%M)"
|
- VERSION_TIMESTAMPED="${VERSION}+$(date +%Y%m%d%H%M)"
|
||||||
- dch --package "${PACKAGE}" --force-bad-version -v "${VERSION_NIGHTLY}" -D "unstable" --force-distribution "Daily build."
|
- dch --package "${PACKAGE}" --force-bad-version -v "${VERSION_TIMESTAMPED}" -D "unstable" --force-distribution "CI build."
|
||||||
- debuild --no-lintian -us -uc
|
- debuild --no-lintian -us -uc
|
||||||
|
- cp $YNH_BUILD_DIR/*.deb ${CI_PROJECT_DIR}/
|
||||||
|
- cd ${CI_PROJECT_DIR}
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# BUILD DEB
|
# BUILD DEB
|
||||||
|
@ -29,18 +31,16 @@ build-yunohost:
|
||||||
- mkdir -p $YNH_BUILD_DIR/$PACKAGE
|
- mkdir -p $YNH_BUILD_DIR/$PACKAGE
|
||||||
- cat archive.tar.gz | tar -xz -C $YNH_BUILD_DIR/$PACKAGE
|
- cat archive.tar.gz | tar -xz -C $YNH_BUILD_DIR/$PACKAGE
|
||||||
- rm archive.tar.gz
|
- rm archive.tar.gz
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $(pwd)/$YNH_BUILD_DIR/$PACKAGE
|
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
||||||
- *build_script
|
- *build_script
|
||||||
|
|
||||||
|
|
||||||
build-ssowat:
|
build-ssowat:
|
||||||
extends: .build-stage
|
extends: .build-stage
|
||||||
variables:
|
variables:
|
||||||
PACKAGE: "ssowat"
|
PACKAGE: "ssowat"
|
||||||
script:
|
script:
|
||||||
- DEBIAN_DEPENDS=$(cat debian/control | tr "," "\n" | grep -Po "ssowat \([>,=,<]+ .*\)" | grep -Po "[0-9\.]+")
|
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $YNH_DEBIAN $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
||||||
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $DEBIAN_DEPENDS $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $(pwd)/$YNH_BUILD_DIR/$PACKAGE
|
|
||||||
- *build_script
|
- *build_script
|
||||||
|
|
||||||
build-moulinette:
|
build-moulinette:
|
||||||
|
@ -48,7 +48,6 @@ build-moulinette:
|
||||||
variables:
|
variables:
|
||||||
PACKAGE: "moulinette"
|
PACKAGE: "moulinette"
|
||||||
script:
|
script:
|
||||||
- DEBIAN_DEPENDS=$(cat debian/control | tr "," "\n" | grep -Po "moulinette \([>,=,<]+ .*\)" | grep -Po "[0-9\.]+")
|
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $YNH_DEBIAN $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
||||||
- git clone $YNH_SOURCE/$PACKAGE -b $CI_COMMIT_REF_NAME $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE -b $DEBIAN_DEPENDS $YNH_BUILD_DIR/$PACKAGE --depth 1 || git clone $YNH_SOURCE/$PACKAGE $YNH_BUILD_DIR/$PACKAGE --depth 1
|
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $YNH_BUILD_DIR/$PACKAGE
|
||||||
- DEBIAN_FRONTEND=noninteractive apt --assume-yes -o Dpkg::Options::="--force-confold" build-dep $(pwd)/$YNH_BUILD_DIR/$PACKAGE
|
|
||||||
- *build_script
|
- *build_script
|
||||||
|
|
|
@ -4,24 +4,28 @@
|
||||||
|
|
||||||
generate-helpers-doc:
|
generate-helpers-doc:
|
||||||
stage: doc
|
stage: doc
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y && apt-get install git hub -y
|
|
||||||
- git config --global user.email "yunohost@yunohost.org"
|
- git config --global user.email "yunohost@yunohost.org"
|
||||||
- git config --global user.name "$GITHUB_USER"
|
- git config --global user.name "$GITHUB_USER"
|
||||||
script:
|
script:
|
||||||
- cd doc
|
- cd doc
|
||||||
- python3 generate_helper_doc.py
|
- python3 generate_helper_doc.py 2
|
||||||
|
- python3 generate_helper_doc.py 2.1
|
||||||
|
- python3 generate_resource_doc.py > resources.md
|
||||||
- hub clone https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/doc.git doc_repo
|
- hub clone https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/doc.git doc_repo
|
||||||
- cp helpers.md doc_repo/pages/04.contribute/04.packaging_apps/11.helpers/packaging_apps_helpers.md
|
- cp helpers.v2.md doc_repo/pages/06.contribute/10.packaging_apps/20.scripts/10.helpers/packaging_app_scripts_helpers.md
|
||||||
|
- cp helpers.v2.1.md doc_repo/pages/06.contribute/10.packaging_apps/20.scripts/12.helpers21/packaging_app_scripts_helpers_v21.md
|
||||||
|
- cp resources.md doc_repo/pages/06.contribute/10.packaging_apps/10.manifest/10.appresources/packaging_app_manifest_resources.md
|
||||||
- cd doc_repo
|
- cd doc_repo
|
||||||
# replace ${CI_COMMIT_REF_NAME} with ${CI_COMMIT_TAG} ?
|
# replace ${CI_COMMIT_REF_NAME} with ${CI_COMMIT_TAG} ?
|
||||||
- hub checkout -b "${CI_COMMIT_REF_NAME}"
|
- hub checkout -b "${CI_COMMIT_REF_NAME}"
|
||||||
- hub commit -am "[CI] Helper for ${CI_COMMIT_REF_NAME}"
|
- hub commit -am "[CI] Update app helpers/resources for ${CI_COMMIT_REF_NAME}"
|
||||||
- hub pull-request -m "[CI] Helper for ${CI_COMMIT_REF_NAME}" -p # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd
|
- hub pull-request -m "[CI] Update app helpers/resources for ${CI_COMMIT_REF_NAME}" -p # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd
|
||||||
artifacts:
|
artifacts:
|
||||||
paths:
|
paths:
|
||||||
- doc/helpers.md
|
- doc/helpers.md
|
||||||
|
- doc/resources.md
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
|
|
|
@ -14,16 +14,14 @@
|
||||||
|
|
||||||
upgrade:
|
upgrade:
|
||||||
extends: .install-stage
|
extends: .install-stage
|
||||||
image: "after-install"
|
image: "core-tests"
|
||||||
script:
|
script:
|
||||||
- apt-get update -o Acquire::Retries=3
|
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
||||||
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ./$YNH_BUILD_DIR/*.deb
|
|
||||||
|
|
||||||
|
|
||||||
install-postinstall:
|
install-postinstall:
|
||||||
extends: .install-stage
|
extends: .install-stage
|
||||||
image: "before-install"
|
image: "before-install"
|
||||||
script:
|
script:
|
||||||
- apt-get update -o Acquire::Retries=3
|
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
||||||
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ./$YNH_BUILD_DIR/*.deb
|
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
|
||||||
- yunohost tools postinstall -d domain.tld -p the_password --ignore-dyndns --force-diskspace
|
|
||||||
|
|
|
@ -3,47 +3,24 @@
|
||||||
########################################
|
########################################
|
||||||
# later we must fix lint and format-check jobs and remove "allow_failure"
|
# later we must fix lint and format-check jobs and remove "allow_failure"
|
||||||
|
|
||||||
---
|
lint39:
|
||||||
lint37:
|
|
||||||
stage: lint
|
stage: lint
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
script:
|
script:
|
||||||
- tox -e py37-lint
|
- tox -e py39-lint
|
||||||
|
|
||||||
invalidcode37:
|
invalidcode39:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- tox -e py37-invalidcode
|
- tox -e py39-invalidcode
|
||||||
|
|
||||||
mypy:
|
mypy:
|
||||||
stage: lint
|
stage: lint
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
script:
|
script:
|
||||||
- tox -e py37-mypy
|
- tox -e py39-mypy
|
||||||
|
|
||||||
black:
|
|
||||||
stage: lint
|
|
||||||
image: "before-install"
|
|
||||||
needs: []
|
|
||||||
before_script:
|
|
||||||
- apt-get update -y && apt-get install git hub -y
|
|
||||||
- git config --global user.email "yunohost@yunohost.org"
|
|
||||||
- git config --global user.name "$GITHUB_USER"
|
|
||||||
- hub clone --branch ${CI_COMMIT_REF_NAME} "https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/yunohost.git" github_repo
|
|
||||||
- cd github_repo
|
|
||||||
script:
|
|
||||||
# create a local branch that will overwrite distant one
|
|
||||||
- git checkout -b "ci-format-${CI_COMMIT_REF_NAME}" --no-track
|
|
||||||
- tox -e py37-black-run
|
|
||||||
- '[ $(git diff | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit
|
|
||||||
- git commit -am "[CI] Format code with Black" || true
|
|
||||||
- git push -f origin "ci-format-${CI_COMMIT_REF_NAME}":"ci-format-${CI_COMMIT_REF_NAME}"
|
|
||||||
- hub pull-request -m "[CI] Format code with Black" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- dev
|
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
.install_debs: &install_debs
|
.install_debs: &install_debs
|
||||||
- apt-get update -o Acquire::Retries=3
|
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ${CI_PROJECT_DIR}/*.deb
|
||||||
- DEBIAN_FRONTEND=noninteractive SUDO_FORCE_REMOVE=yes apt --assume-yes -o Dpkg::Options::="--force-confold" --allow-downgrades install ./$YNH_BUILD_DIR/*.deb
|
|
||||||
|
|
||||||
.test-stage:
|
.test-stage:
|
||||||
stage: tests
|
stage: test
|
||||||
image: "after-install"
|
image: "core-tests"
|
||||||
variables:
|
variables:
|
||||||
PYTEST_ADDOPTS: "--color=yes"
|
PYTEST_ADDOPTS: "--color=yes"
|
||||||
before_script:
|
before_script:
|
||||||
- *install_debs
|
- *install_debs
|
||||||
cache:
|
cache:
|
||||||
paths:
|
paths:
|
||||||
- src/yunohost/tests/apps
|
- src/tests/apps
|
||||||
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
|
key: "$CI_JOB_STAGE-$CI_COMMIT_REF_SLUG"
|
||||||
needs:
|
needs:
|
||||||
- job: build-yunohost
|
- job: build-yunohost
|
||||||
|
@ -22,23 +21,21 @@
|
||||||
artifacts: true
|
artifacts: true
|
||||||
- job: upgrade
|
- job: upgrade
|
||||||
|
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
# TESTS
|
# TESTS
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
full-tests:
|
full-tests:
|
||||||
stage: tests
|
stage: test
|
||||||
image: "before-install"
|
image: "before-install"
|
||||||
variables:
|
variables:
|
||||||
PYTEST_ADDOPTS: "--color=yes"
|
PYTEST_ADDOPTS: "--color=yes"
|
||||||
before_script:
|
before_script:
|
||||||
- *install_debs
|
- *install_debs
|
||||||
- yunohost tools postinstall -d domain.tld -p the_password --ignore-dyndns --force-diskspace
|
- pip install mock pip pyOpenSSL pytest pytest-cov pytest-mock pytest-sugar requests-mock "packaging<22"
|
||||||
|
- yunohost tools postinstall -d domain.tld -u syssa -F 'Syssa Mine' -p the_password --ignore-dyndns --force-diskspace
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest --cov=yunohost tests/ src/yunohost/tests/ data/hooks/diagnosis/ --junitxml=report.xml
|
- python3 -m pytest --cov=yunohost tests/ src/tests/ --junitxml=report.xml
|
||||||
- cd tests
|
|
||||||
- bash test_helpers.sh
|
|
||||||
needs:
|
needs:
|
||||||
- job: build-yunohost
|
- job: build-yunohost
|
||||||
artifacts: true
|
artifacts: true
|
||||||
|
@ -46,163 +43,158 @@ full-tests:
|
||||||
artifacts: true
|
artifacts: true
|
||||||
- job: build-moulinette
|
- job: build-moulinette
|
||||||
artifacts: true
|
artifacts: true
|
||||||
|
coverage: '/TOTAL.*\s+(\d+%)/'
|
||||||
artifacts:
|
artifacts:
|
||||||
reports:
|
reports:
|
||||||
junit: report.xml
|
junit: report.xml
|
||||||
|
|
||||||
test-i18n-keys:
|
|
||||||
extends: .test-stage
|
|
||||||
script:
|
|
||||||
- python3 -m pytest tests/test_i18n_keys.py
|
|
||||||
only:
|
|
||||||
changes:
|
|
||||||
- locales/en.json
|
|
||||||
- src/yunohost/*.py
|
|
||||||
- data/hooks/diagnosis/*.py
|
|
||||||
|
|
||||||
test-translation-format-consistency:
|
|
||||||
extends: .test-stage
|
|
||||||
script:
|
|
||||||
- python3 -m pytest tests/test_translation_format_consistency.py
|
|
||||||
only:
|
|
||||||
changes:
|
|
||||||
- locales/*
|
|
||||||
|
|
||||||
test-actionmap:
|
test-actionmap:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest tests/test_actionmap.py
|
- python3 -m pytest tests/test_actionmap.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- data/actionsmap/*.yml
|
- share/actionsmap.yml
|
||||||
|
|
||||||
test-helpers:
|
test-helpers2:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- cd tests
|
- cd tests
|
||||||
- bash test_helpers.sh
|
- bash test_helpers.sh
|
||||||
only:
|
|
||||||
changes:
|
test-helpers2.1:
|
||||||
- data/helpers.d/*
|
extends: .test-stage
|
||||||
|
script:
|
||||||
|
- cd tests
|
||||||
|
- bash test_helpers.sh 2.1
|
||||||
|
|
||||||
test-domains:
|
test-domains:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_domains.py
|
- python3 -m pytest src/tests/test_domains.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/domain.py
|
- src/domain.py
|
||||||
|
|
||||||
test-dns:
|
test-dns:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_dns.py
|
- python3 -m pytest src/tests/test_dns.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/dns.py
|
- src/dns.py
|
||||||
- src/yunohost/utils/dns.py
|
- src/utils/dns.py
|
||||||
|
|
||||||
test-apps:
|
test-apps:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_apps.py
|
- python3 -m pytest src/tests/test_apps.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/app.py
|
- src/app.py
|
||||||
|
|
||||||
test-appscatalog:
|
test-appscatalog:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_app_catalog.py
|
- python3 -m pytest src/tests/test_app_catalog.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/app_calalog.py
|
- src/app_calalog.py
|
||||||
|
|
||||||
test-appurl:
|
test-appurl:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_appurl.py
|
- python3 -m pytest src/tests/test_appurl.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/app.py
|
- src/app.py
|
||||||
|
|
||||||
test-questions:
|
test-questions:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_questions.py
|
- python3 -m pytest src/tests/test_questions.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/utils/config.py
|
- src/utils/config.py
|
||||||
|
|
||||||
test-app-config:
|
test-app-config:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_app_config.py
|
- python3 -m pytest src/tests/test_app_config.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/app.py
|
- src/app.py
|
||||||
- src/yunohost/utils/config.py
|
- src/utils/config.py
|
||||||
|
|
||||||
|
test-app-resources:
|
||||||
|
extends: .test-stage
|
||||||
|
script:
|
||||||
|
- python3 -m pytest src/tests/test_app_resources.py
|
||||||
|
only:
|
||||||
|
changes:
|
||||||
|
- src/app.py
|
||||||
|
- src/utils/resources.py
|
||||||
|
|
||||||
test-changeurl:
|
test-changeurl:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_changeurl.py
|
- python3 -m pytest src/tests/test_changeurl.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/app.py
|
- src/app.py
|
||||||
|
|
||||||
test-backuprestore:
|
test-backuprestore:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_backuprestore.py
|
- python3 -m pytest src/tests/test_backuprestore.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/backup.py
|
- src/backup.py
|
||||||
|
|
||||||
test-permission:
|
test-permission:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_permission.py
|
- python3 -m pytest src/tests/test_permission.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/permission.py
|
- src/permission.py
|
||||||
|
|
||||||
test-settings:
|
test-settings:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_settings.py
|
- python3 -m pytest src/tests/test_settings.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/settings.py
|
- src/settings.py
|
||||||
|
|
||||||
test-user-group:
|
test-user-group:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_user-group.py
|
- python3 -m pytest src/tests/test_user-group.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/user.py
|
- src/user.py
|
||||||
|
|
||||||
test-regenconf:
|
test-regenconf:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_regenconf.py
|
- python3 -m pytest src/tests/test_regenconf.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/regenconf.py
|
- src/regenconf.py
|
||||||
|
|
||||||
test-service:
|
test-service:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_service.py
|
- python3 -m pytest src/tests/test_service.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/service.py
|
- src/service.py
|
||||||
|
|
||||||
test-ldapauth:
|
test-ldapauth:
|
||||||
extends: .test-stage
|
extends: .test-stage
|
||||||
script:
|
script:
|
||||||
- python3 -m pytest src/yunohost/tests/test_ldapauth.py
|
- python3 -m pytest src/tests/test_ldapauth.py
|
||||||
only:
|
only:
|
||||||
changes:
|
changes:
|
||||||
- src/yunohost/authenticators/*.py
|
- src/authenticators/*.py
|
||||||
|
|
|
@ -1,27 +1,34 @@
|
||||||
########################################
|
########################################
|
||||||
# TRANSLATION
|
# TRANSLATION
|
||||||
########################################
|
########################################
|
||||||
|
test-i18n-keys:
|
||||||
|
stage: translation
|
||||||
|
script:
|
||||||
|
- python3 maintenance/missing_i18n_keys.py --check
|
||||||
|
only:
|
||||||
|
changes:
|
||||||
|
- locales/en.json
|
||||||
|
- src/*.py
|
||||||
|
- src/diagnosers/*.py
|
||||||
|
|
||||||
autofix-translated-strings:
|
autofix-translated-strings:
|
||||||
stage: translation
|
stage: translation
|
||||||
image: "before-install"
|
image: "build-and-lint"
|
||||||
needs: []
|
needs: []
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update -y && apt-get install git hub -y
|
|
||||||
- git config --global user.email "yunohost@yunohost.org"
|
- git config --global user.email "yunohost@yunohost.org"
|
||||||
- git config --global user.name "$GITHUB_USER"
|
- git config --global user.name "$GITHUB_USER"
|
||||||
- git remote set-url origin https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/yunohost.git
|
- hub clone --branch ${CI_COMMIT_REF_NAME} "https://$GITHUB_TOKEN:x-oauth-basic@github.com/YunoHost/yunohost.git" github_repo
|
||||||
|
- cd github_repo
|
||||||
script:
|
script:
|
||||||
- cd tests # Maybe move this script location to another folder?
|
|
||||||
# create a local branch that will overwrite distant one
|
# create a local branch that will overwrite distant one
|
||||||
- git checkout -b "ci-autofix-translated-strings-${CI_COMMIT_REF_NAME}" --no-track
|
- git checkout -b "ci-autofix-translated-strings-${CI_COMMIT_REF_NAME}" --no-track
|
||||||
- python3 remove_stale_translated_strings.py
|
- python3 maintenance/missing_i18n_keys.py --fix
|
||||||
- python3 autofix_locale_format.py
|
- python3 maintenance/autofix_locale_format.py
|
||||||
- python3 reformat_locales.py
|
- '[ $(git diff --ignore-blank-lines --ignore-all-space --ignore-space-at-eol --ignore-cr-at-eol | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit
|
||||||
- '[ $(git diff -w | wc -l) != 0 ] || exit 0' # stop if there is nothing to commit
|
|
||||||
- git commit -am "[CI] Reformat / remove stale translated strings" || true
|
- git commit -am "[CI] Reformat / remove stale translated strings" || true
|
||||||
- git push -f origin "HEAD":"ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}"
|
- git push -f origin "ci-autofix-translated-strings-${CI_COMMIT_REF_NAME}":"ci-remove-stale-translated-strings-${CI_COMMIT_REF_NAME}"
|
||||||
- hub pull-request -m "[CI] Reformat / remove stale translated strings" -b Yunohost:dev -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd
|
- hub pull-request -m "[CI] Reformat / remove stale translated strings" -b Yunohost:$CI_COMMIT_REF_NAME -p || true # GITHUB_USER and GITHUB_TOKEN registered here https://gitlab.com/yunohost/yunohost/-/settings/ci_cd
|
||||||
only:
|
only:
|
||||||
variables:
|
variables:
|
||||||
- $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
|
- $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
|
||||||
|
|
101
CONTRIBUTORS.md
101
CONTRIBUTORS.md
|
@ -1,101 +0,0 @@
|
||||||
YunoHost core contributors
|
|
||||||
==========================
|
|
||||||
|
|
||||||
YunoHost is built and maintained by the YunoHost project community.
|
|
||||||
Everyone is encouraged to submit issues and changes, and to contribute in other ways -- see https://yunohost.org/contribute to find out how.
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
Initial YunoHost core was built by Kload & beudbeud, for YunoHost v2.
|
|
||||||
|
|
||||||
Most of code was written by Kload and jerome, with help of numerous contributors.
|
|
||||||
|
|
||||||
Translation is made by a bunch of lovely people all over the world.
|
|
||||||
|
|
||||||
We would like to thank anyone who ever helped the YunoHost project <3
|
|
||||||
|
|
||||||
|
|
||||||
YunoHost core Contributors
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
- Jérôme Lebleu
|
|
||||||
- Kload
|
|
||||||
- Laurent 'Bram' Peuch
|
|
||||||
- Julien 'ju' Malik
|
|
||||||
- opi
|
|
||||||
- Aleks
|
|
||||||
- Adrien 'beudbeud' Beudin
|
|
||||||
- M5oul
|
|
||||||
- Valentin 'zamentur' / 'ljf' Grimaud
|
|
||||||
- Jocelyn Delalande
|
|
||||||
- infertux
|
|
||||||
- Taziden
|
|
||||||
- ZeHiro
|
|
||||||
- Josue-T
|
|
||||||
- nahoj
|
|
||||||
- a1ex
|
|
||||||
- JimboJoe
|
|
||||||
- vetetix
|
|
||||||
- jellium
|
|
||||||
- Sebastien 'sebian' Badia
|
|
||||||
- lmangani
|
|
||||||
- Julien Vaubourg
|
|
||||||
- thardev
|
|
||||||
- zimo2001
|
|
||||||
|
|
||||||
|
|
||||||
YunoHost core Translators
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
If you want to help translation, please visit https://translate.yunohost.org/projects/yunohost/yunohost/
|
|
||||||
|
|
||||||
|
|
||||||
### Dutch
|
|
||||||
|
|
||||||
- DUBWiSE
|
|
||||||
- Jeroen Keerl
|
|
||||||
- marut
|
|
||||||
|
|
||||||
### English
|
|
||||||
|
|
||||||
- Bugsbane
|
|
||||||
- rokaz
|
|
||||||
|
|
||||||
### French
|
|
||||||
|
|
||||||
- aoz roon
|
|
||||||
- Genma
|
|
||||||
- Jean-Baptiste Holcroft
|
|
||||||
- Jean P.
|
|
||||||
- Jérôme Lebleu
|
|
||||||
- Lapineige
|
|
||||||
- paddy
|
|
||||||
|
|
||||||
|
|
||||||
### German
|
|
||||||
|
|
||||||
- david.bartke
|
|
||||||
- Fabian Gruber
|
|
||||||
- Felix Bartels
|
|
||||||
- Jeroen Keerl
|
|
||||||
- martin kistner
|
|
||||||
- Philip Gatzka
|
|
||||||
|
|
||||||
### Hindi
|
|
||||||
|
|
||||||
- Anmol
|
|
||||||
|
|
||||||
### Italian
|
|
||||||
|
|
||||||
- bricabrac
|
|
||||||
- Thomas Bille
|
|
||||||
|
|
||||||
### Portuguese
|
|
||||||
|
|
||||||
- Deleted User
|
|
||||||
- Trollken
|
|
||||||
|
|
||||||
### Spanish
|
|
||||||
|
|
||||||
- Juanu
|
|
||||||
|
|
44
README.md
44
README.md
|
@ -7,9 +7,10 @@
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||

|

|
||||||
[](https://gitlab.com/yunohost/yunohost/-/pipelines)
|
[](https://gitlab.com/yunohost/yunohost/-/pipelines)
|
||||||

|

|
||||||
[](https://github.com/YunoHost/yunohost/blob/dev/LICENSE)
|
[](https://github.com/YunoHost/yunohost/blob/dev/LICENSE)
|
||||||
|
[](https://github.com/YunoHost/yunohost/security/code-scanning)
|
||||||
[](https://mastodon.social/@yunohost)
|
[](https://mastodon.social/@yunohost)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,28 +19,49 @@ YunoHost is an operating system aiming to simplify as much as possible the admin
|
||||||
|
|
||||||
This repository corresponds to the core code of YunoHost, mainly written in Python and Bash.
|
This repository corresponds to the core code of YunoHost, mainly written in Python and Bash.
|
||||||
|
|
||||||
- [Project features](https://yunohost.org/#/whatsyunohost)
|
- [Project features](https://yunohost.org/whatsyunohost)
|
||||||
- [Project website](https://yunohost.org)
|
- [Project website](https://yunohost.org)
|
||||||
- [Install documentation](https://yunohost.org/install)
|
- [Install documentation](https://yunohost.org/install)
|
||||||
- [Issue tracker](https://github.com/YunoHost/issues)
|
- [Issue tracker](https://github.com/YunoHost/issues)
|
||||||
|
|
||||||
# Screenshots
|
## Screenshots
|
||||||
|
|
||||||
Webadmin ([Yunohost-Admin](https://github.com/YunoHost/yunohost-admin)) | Single sign-on user portal ([SSOwat](https://github.com/YunoHost/ssowat))
|
Webadmin ([Yunohost-Admin](https://github.com/YunoHost/yunohost-admin)) | Single sign-on user portal ([SSOwat](https://github.com/YunoHost/ssowat))
|
||||||
--- | ---
|
--- | ---
|
||||||
 | 
|
 | 
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
- You can learn how to get started with developing on YunoHost by reading [this piece of documentation](https://yunohost.org/dev).
|
- You can learn how to get started with developing on YunoHost by reading [this piece of documentation](https://yunohost.org/dev).
|
||||||
- Come chat with us on the [dev chatroom](https://yunohost.org/#/chat_rooms) !
|
- Come chat with us on the [dev chatroom](https://yunohost.org/chat_rooms)!
|
||||||
- You can help translate YunoHost on our [translation platform](https://translate.yunohost.org/engage/yunohost/?utm_source=widget)
|
- You can help translate YunoHost on our [translation platform](https://translate.yunohost.org/engage/yunohost/?utm_source=widget).
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<img src="https://translate.yunohost.org/widgets/yunohost/-/core/horizontal-auto.svg" alt="Translation status" />
|
<img alt="View of the translation rate for the different languages available in YunoHost" src="https://translate.yunohost.org/widgets/yunohost/-/core/horizontal-auto.svg" alt="Translation status" />
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
As [other components of YunoHost](https://yunohost.org/#/faq_en), this repository is licensed under GNU AGPL v3.
|
As [other components of YunoHost](https://yunohost.org/faq), this repository is licensed under GNU AGPL v3.
|
||||||
|
|
||||||
|
## They support us <3
|
||||||
|
|
||||||
|
We are thankful for our sponsors providing us with infrastructure and grants!
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<p style="margin-left:auto;margin-right:auto;">
|
||||||
|
<a style="padding: 5px;" href="https://nlnet.nl"><img alt="NLnet Foundation" src="https://user-images.githubusercontent.com/36127788/198088570-823c40bd-7ac3-44e3-a8ee-e7a9f14b47ac.png" width="150px"/></a>
|
||||||
|
<a style="padding: 5px;" href="https://www.ngi.eu"><img alt="Next Generation Internet" src="https://user-images.githubusercontent.com/36127788/198088663-daf587b9-fd09-4c00-aaf2-37c803939c94.png" width="130px"/></a>
|
||||||
|
<a style="padding: 5px;" href="https://www.codelutin.com"><img alt="Code Lutin" src="https://user-images.githubusercontent.com/36127788/198088737-d37b6674-379c-4be4-9d74-b93b6ad318d1.png" width="100px"/></a>
|
||||||
|
</p>
|
||||||
|
<p style="margin-left:auto;margin-right:auto;">
|
||||||
|
<a style="padding: 5px;" href="https://www.globenet.org"><img alt="Globenet" src="https://user-images.githubusercontent.com/36127788/198088794-751129ab-737d-4d99-9f35-5e01845dcdfe.png" width="150px"/></a>
|
||||||
|
<a style="padding: 5px;" href="https://www.gitoyen.net"><img alt="Gitoyen" src="https://user-images.githubusercontent.com/36127788/198088931-f16f4af4-57ae-42e9-8d42-fb3e2d8d7ee3.png" width="150px"/></a>
|
||||||
|
<a style="padding: 5px;" href="https://tetaneutral.net"><img alt="tetaneutral.net" src="https://user-images.githubusercontent.com/36127788/198088995-3ad9c34d-9807-4ead-934b-44df97d3c552.png" width="90px"/></a>
|
||||||
|
<a style="padding: 5px;" href="https://ldn-fai.net"><img alt="LDN (Lorraine Data Network)" src="https://user-images.githubusercontent.com/36127788/198089086-a4089d51-9173-4081-bd2e-fa1ac3378e49.png" width="120px"/></a>
|
||||||
|
<a style="padding: 5px;" href="https://www.nbs-system.com"><img alt="NBS System" src="https://user-images.githubusercontent.com/36127788/198089161-4cc0b7b7-bf56-4798-892e-a76112497921.png" width="130px"/></a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
This project was funded through the [NGI0 PET](https://nlnet.nl/PET) Fund, a fund established by NLnet with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825310. If you're interested, [check out how to apply in this video](https://media.ccc.de/v/36c3-10795-ngi_zero_a_treasure_trove_of_it_innovation)!
|
||||||
|
|
61
bin/yunohost
61
bin/yunohost
|
@ -1,67 +1,78 @@
|
||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
sys.path.insert(0, "/usr/lib/moulinette/")
|
|
||||||
import yunohost
|
import yunohost
|
||||||
|
|
||||||
|
|
||||||
def _parse_cli_args():
|
def _parse_cli_args():
|
||||||
"""Parse additional arguments for the cli"""
|
"""Parse additional arguments for the cli"""
|
||||||
parser = argparse.ArgumentParser(add_help=False)
|
parser = argparse.ArgumentParser(add_help=False)
|
||||||
parser.add_argument('--output-as',
|
parser.add_argument(
|
||||||
choices=['json', 'plain', 'none'], default=None,
|
"--output-as",
|
||||||
help="Output result in another format"
|
choices=["json", "plain", "none"],
|
||||||
|
default=None,
|
||||||
|
help="Output result in another format",
|
||||||
)
|
)
|
||||||
parser.add_argument('--debug',
|
parser.add_argument(
|
||||||
action='store_true', default=False,
|
"--debug",
|
||||||
help="Log and print debug messages"
|
action="store_true",
|
||||||
|
default=False,
|
||||||
|
help="Log and print debug messages",
|
||||||
)
|
)
|
||||||
parser.add_argument('--quiet',
|
parser.add_argument(
|
||||||
action='store_true', default=False,
|
"--quiet", action="store_true", default=False, help="Don't produce any output"
|
||||||
help="Don't produce any output"
|
|
||||||
)
|
)
|
||||||
parser.add_argument('--timeout',
|
parser.add_argument(
|
||||||
type=int, default=None,
|
"--version", action="store_true", default=False, help="Display YunoHost packages versions (alias to 'yunohost tools versions')"
|
||||||
help="Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock"
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--timeout",
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
help="Number of seconds before this command will timeout because it can't acquire the lock (meaning that another command is currently running), by default there is no timeout and the command will wait until it can get the lock",
|
||||||
)
|
)
|
||||||
# deprecated arguments
|
# deprecated arguments
|
||||||
parser.add_argument('--plain',
|
parser.add_argument(
|
||||||
action='store_true', default=False, help=argparse.SUPPRESS
|
"--plain", action="store_true", default=False, help=argparse.SUPPRESS
|
||||||
)
|
)
|
||||||
parser.add_argument('--json',
|
parser.add_argument(
|
||||||
action='store_true', default=False, help=argparse.SUPPRESS
|
"--json", action="store_true", default=False, help=argparse.SUPPRESS
|
||||||
)
|
)
|
||||||
|
|
||||||
opts, args = parser.parse_known_args()
|
opts, args = parser.parse_known_args()
|
||||||
|
|
||||||
# output compatibility
|
# output compatibility
|
||||||
if opts.plain:
|
if opts.plain:
|
||||||
opts.output_as = 'plain'
|
opts.output_as = "plain"
|
||||||
elif opts.json:
|
elif opts.json:
|
||||||
opts.output_as = 'json'
|
opts.output_as = "json"
|
||||||
|
|
||||||
return (parser, opts, args)
|
return (parser, opts, args)
|
||||||
|
|
||||||
|
|
||||||
# Stupid PATH management because sometimes (e.g. some cron job) PATH is only /usr/bin:/bin ...
|
# Stupid PATH management because sometimes (e.g. some cron job) PATH is only /usr/bin:/bin ...
|
||||||
|
|
||||||
default_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
default_path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
if os.environ["PATH"] != default_path:
|
if os.environ["PATH"] != default_path:
|
||||||
os.environ["PATH"] = default_path + ":" + os.environ["PATH"]
|
os.environ["PATH"] = default_path + ":" + os.environ["PATH"]
|
||||||
|
|
||||||
# Main action ----------------------------------------------------------
|
# Main action ----------------------------------------------------------
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
if os.geteuid() != 0:
|
if os.geteuid() != 0:
|
||||||
sys.stderr.write("\033[1;31mError:\033[0m yunohost command must be "
|
sys.stderr.write(
|
||||||
"run as root or with sudo.\n")
|
"\033[1;31mError:\033[0m yunohost command must be "
|
||||||
|
"run as root or with sudo.\n"
|
||||||
|
)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
parser, opts, args = _parse_cli_args()
|
parser, opts, args = _parse_cli_args()
|
||||||
|
|
||||||
|
if opts.version:
|
||||||
|
args = ["tools", "versions"]
|
||||||
|
|
||||||
# Execute the action
|
# Execute the action
|
||||||
yunohost.cli(
|
yunohost.cli(
|
||||||
debug=opts.debug,
|
debug=opts.debug,
|
||||||
|
@ -69,5 +80,5 @@ if __name__ == '__main__':
|
||||||
output_as=opts.output_as,
|
output_as=opts.output_as,
|
||||||
timeout=opts.timeout,
|
timeout=opts.timeout,
|
||||||
args=args,
|
args=args,
|
||||||
parser=parser
|
parser=parser,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,44 +1,52 @@
|
||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
sys.path.insert(0, "/usr/lib/moulinette/")
|
|
||||||
import yunohost
|
import yunohost
|
||||||
|
|
||||||
# Default server configuration
|
# Default server configuration
|
||||||
DEFAULT_HOST = 'localhost'
|
DEFAULT_HOST = "localhost"
|
||||||
DEFAULT_PORT = 6787
|
DEFAULT_PORT = 6787
|
||||||
|
|
||||||
|
|
||||||
def _parse_api_args():
|
def _parse_api_args():
|
||||||
"""Parse main arguments for the api"""
|
"""Parse main arguments for the api"""
|
||||||
parser = argparse.ArgumentParser(add_help=False,
|
parser = argparse.ArgumentParser(
|
||||||
|
add_help=False,
|
||||||
description="Run the YunoHost API to manage your server.",
|
description="Run the YunoHost API to manage your server.",
|
||||||
)
|
)
|
||||||
srv_group = parser.add_argument_group('server configuration')
|
srv_group = parser.add_argument_group("server configuration")
|
||||||
srv_group.add_argument('-h', '--host',
|
srv_group.add_argument(
|
||||||
action='store', default=DEFAULT_HOST,
|
"-h",
|
||||||
|
"--host",
|
||||||
|
action="store",
|
||||||
|
default=DEFAULT_HOST,
|
||||||
help="Host to listen on (default: %s)" % DEFAULT_HOST,
|
help="Host to listen on (default: %s)" % DEFAULT_HOST,
|
||||||
)
|
)
|
||||||
srv_group.add_argument('-p', '--port',
|
srv_group.add_argument(
|
||||||
action='store', default=DEFAULT_PORT, type=int,
|
"-p",
|
||||||
|
"--port",
|
||||||
|
action="store",
|
||||||
|
default=DEFAULT_PORT,
|
||||||
|
type=int,
|
||||||
help="Port to listen on (default: %d)" % DEFAULT_PORT,
|
help="Port to listen on (default: %d)" % DEFAULT_PORT,
|
||||||
)
|
)
|
||||||
glob_group = parser.add_argument_group('global arguments')
|
glob_group = parser.add_argument_group("global arguments")
|
||||||
glob_group.add_argument('--debug',
|
glob_group.add_argument(
|
||||||
action='store_true', default=False,
|
"--debug",
|
||||||
|
action="store_true",
|
||||||
|
default=False,
|
||||||
help="Set log level to DEBUG",
|
help="Set log level to DEBUG",
|
||||||
)
|
)
|
||||||
glob_group.add_argument('--help',
|
glob_group.add_argument(
|
||||||
action='help', help="Show this help message and exit",
|
"--help",
|
||||||
|
action="help",
|
||||||
|
help="Show this help message and exit",
|
||||||
)
|
)
|
||||||
|
|
||||||
return parser.parse_args()
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
opts = _parse_api_args()
|
opts = _parse_api_args()
|
||||||
# Run the server
|
# Run the server
|
||||||
yunohost.api(debug=opts.debug, host=opts.host, port=opts.port)
|
yunohost.api(debug=opts.debug, host=opts.host, port=opts.port)
|
||||||
|
|
45
bin/yunomdns
45
bin/yunomdns
|
@ -21,8 +21,20 @@ def get_network_local_interfaces() -> Dict[str, Dict[str, List[str]]]:
|
||||||
|
|
||||||
interfaces = {
|
interfaces = {
|
||||||
adapter.name: {
|
adapter.name: {
|
||||||
"ipv4": [ip.ip for ip in adapter.ips if ip.is_IPv4 and ip_address(ip.ip).is_private],
|
"ipv4": [
|
||||||
"ipv6": [ip.ip[0] for ip in adapter.ips if ip.is_IPv6 and ip_address(ip.ip[0]).is_private and not ip_address(ip.ip[0]).is_link_local],
|
ip.ip
|
||||||
|
for ip in adapter.ips
|
||||||
|
if ip.is_IPv4
|
||||||
|
and ip_address(ip.ip).is_private
|
||||||
|
and not ip_address(ip.ip).is_link_local
|
||||||
|
],
|
||||||
|
"ipv6": [
|
||||||
|
ip.ip[0]
|
||||||
|
for ip in adapter.ips
|
||||||
|
if ip.is_IPv6
|
||||||
|
and ip_address(ip.ip[0]).is_private
|
||||||
|
and not ip_address(ip.ip[0]).is_link_local
|
||||||
|
],
|
||||||
}
|
}
|
||||||
for adapter in ifaddr.get_adapters()
|
for adapter in ifaddr.get_adapters()
|
||||||
if adapter.name != "lo"
|
if adapter.name != "lo"
|
||||||
|
@ -33,7 +45,6 @@ def get_network_local_interfaces() -> Dict[str, Dict[str, List[str]]]:
|
||||||
# Listener class, to detect duplicates on the network
|
# Listener class, to detect duplicates on the network
|
||||||
# Stores the list of servers in its list property
|
# Stores the list of servers in its list property
|
||||||
class Listener:
|
class Listener:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.list = []
|
self.list = []
|
||||||
|
|
||||||
|
@ -66,14 +77,18 @@ def main() -> bool:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if "interfaces" not in config:
|
if "interfaces" not in config:
|
||||||
config["interfaces"] = [interface
|
config["interfaces"] = [
|
||||||
for interface, local_ips in interfaces.items()
|
interface
|
||||||
if local_ips["ipv4"]]
|
for interface, local_ips in interfaces.items()
|
||||||
|
if local_ips["ipv4"]
|
||||||
|
]
|
||||||
|
|
||||||
if "ban_interfaces" in config:
|
if "ban_interfaces" in config:
|
||||||
config["interfaces"] = [interface
|
config["interfaces"] = [
|
||||||
for interface in config["interfaces"]
|
interface
|
||||||
if interface not in config["ban_interfaces"]]
|
for interface in config["interfaces"]
|
||||||
|
if interface not in config["ban_interfaces"]
|
||||||
|
]
|
||||||
|
|
||||||
# Let's discover currently published .local domains accross the network
|
# Let's discover currently published .local domains accross the network
|
||||||
zc = Zeroconf()
|
zc = Zeroconf()
|
||||||
|
@ -103,14 +118,18 @@ def main() -> bool:
|
||||||
|
|
||||||
return domain_i
|
return domain_i
|
||||||
|
|
||||||
config['domains'] = [find_domain_not_already_published(domain) for domain in config['domains']]
|
config["domains"] = [
|
||||||
|
find_domain_not_already_published(domain) for domain in config["domains"]
|
||||||
|
]
|
||||||
|
|
||||||
zcs: Dict[Zeroconf, List[ServiceInfo]] = {}
|
zcs: Dict[Zeroconf, List[ServiceInfo]] = {}
|
||||||
|
|
||||||
for interface in config["interfaces"]:
|
for interface in config["interfaces"]:
|
||||||
|
|
||||||
if interface not in interfaces:
|
if interface not in interfaces:
|
||||||
print(f"Interface {interface} listed in config file is not present on system.")
|
print(
|
||||||
|
f"Interface {interface} listed in config file is not present on system."
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Only broadcast IPv4 because IPv6 is buggy ... because we ain't using python3-ifaddr >= 0.1.7
|
# Only broadcast IPv4 because IPv6 is buggy ... because we ain't using python3-ifaddr >= 0.1.7
|
||||||
|
@ -149,7 +168,9 @@ def main() -> bool:
|
||||||
print("Registering...")
|
print("Registering...")
|
||||||
for zc, infos in zcs.items():
|
for zc, infos in zcs.items():
|
||||||
for info in infos:
|
for info in infos:
|
||||||
zc.register_service(info, allow_name_change=True, cooperating_responders=True)
|
zc.register_service(
|
||||||
|
info, allow_name_change=True, cooperating_responders=True
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print("Registered. Press Ctrl+C or stop service to stop.")
|
print("Registered. Press Ctrl+C or stop service to stop.")
|
||||||
|
|
|
@ -1,77 +1,34 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
set -e
|
import sys
|
||||||
set -u
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
PASTE_URL="https://paste.yunohost.org"
|
SERVER_URL = "https://paste.yunohost.org"
|
||||||
|
TIMEOUT = 3
|
||||||
|
|
||||||
_die() {
|
def create_snippet(data):
|
||||||
printf "Error: %s\n" "$*"
|
try:
|
||||||
exit 1
|
url = SERVER_URL + "/documents"
|
||||||
}
|
response = requests.post(url, data=data.encode('utf-8'), timeout=TIMEOUT)
|
||||||
|
response.raise_for_status()
|
||||||
|
dockey = json.loads(response.text)['key']
|
||||||
|
return SERVER_URL + "/raw/" + dockey
|
||||||
|
except requests.exceptions.RequestException as e:
|
||||||
|
print("\033[31mError: {}\033[0m".format(e))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
check_dependencies() {
|
|
||||||
curl -V > /dev/null 2>&1 || _die "This script requires curl."
|
|
||||||
}
|
|
||||||
|
|
||||||
paste_data() {
|
def main():
|
||||||
json=$(curl -X POST -s -d "$1" "${PASTE_URL}/documents")
|
output = sys.stdin.read()
|
||||||
[[ -z "$json" ]] && _die "Unable to post the data to the server."
|
|
||||||
|
|
||||||
key=$(echo "$json" \
|
if not output:
|
||||||
| python -c 'import json,sys;o=json.load(sys.stdin);print o["key"]' \
|
print("\033[31mError: No input received from stdin.\033[0m")
|
||||||
2>/dev/null)
|
sys.exit(1)
|
||||||
[[ -z "$key" ]] && _die "Unable to parse the server response."
|
|
||||||
|
|
||||||
echo "${PASTE_URL}/${key}"
|
url = create_snippet(output)
|
||||||
}
|
|
||||||
|
|
||||||
usage() {
|
print("\033[32mURL: {}\033[0m".format(url))
|
||||||
printf "Usage: ${0} [OPTION]...
|
|
||||||
|
|
||||||
Read from input stream and paste the data to the YunoHost
|
if __name__ == "__main__":
|
||||||
Haste server.
|
main()
|
||||||
|
|
||||||
For example, to paste the output of the YunoHost diagnosis, you
|
|
||||||
can simply execute the following:
|
|
||||||
yunohost diagnosis show | ${0}
|
|
||||||
|
|
||||||
It will return the URL where you can access the pasted data.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
-h, --help show this help message and exit
|
|
||||||
"
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
# parse options
|
|
||||||
while (( ${#} )); do
|
|
||||||
case "${1}" in
|
|
||||||
--help|-h)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown parameter detected: ${1}" >&2
|
|
||||||
echo >&2
|
|
||||||
usage >&2
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
shift 1
|
|
||||||
done
|
|
||||||
|
|
||||||
# check input stream
|
|
||||||
read -t 0 || {
|
|
||||||
echo -e "Invalid usage: No input is provided.\n" >&2
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
paste_data "$(cat)"
|
|
||||||
}
|
|
||||||
|
|
||||||
check_dependencies
|
|
||||||
|
|
||||||
main "${@}"
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ EOF
|
||||||
|
|
||||||
echo "$LOGO_AND_FINGERPRINTS" > /etc/issue
|
echo "$LOGO_AND_FINGERPRINTS" > /etc/issue
|
||||||
|
|
||||||
if [[ ! -f /etc/yunohost/installed ]]
|
if ! groups | grep -q all_users && [[ ! -f /etc/yunohost/installed ]]
|
||||||
then
|
then
|
||||||
chvt 2
|
chvt 2
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ then
|
||||||
You should now proceed with YunoHost post-installation. This is where you will
|
You should now proceed with YunoHost post-installation. This is where you will
|
||||||
be asked for:
|
be asked for:
|
||||||
- the main domain of your server;
|
- the main domain of your server;
|
||||||
- the administration password.
|
- the username and password for the first admin
|
||||||
|
|
||||||
You can perform this step:
|
You can perform this step:
|
||||||
- from your web browser, by accessing: https://yunohost.local/ or ${local_ip}
|
- from your web browser, by accessing: https://yunohost.local/ or ${local_ip}
|
||||||
|
|
|
@ -10,7 +10,7 @@ mail_uid = 500
|
||||||
|
|
||||||
protocols = imap sieve {% if pop3_enabled == "True" %}pop3{% endif %}
|
protocols = imap sieve {% if pop3_enabled == "True" %}pop3{% endif %}
|
||||||
|
|
||||||
mail_plugins = $mail_plugins quota
|
mail_plugins = $mail_plugins quota notify push_notification
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
@ -21,9 +21,14 @@ ssl = required
|
||||||
|
|
||||||
ssl_cert = </etc/yunohost/certs/{{ main_domain }}/crt.pem
|
ssl_cert = </etc/yunohost/certs/{{ main_domain }}/crt.pem
|
||||||
ssl_key = </etc/yunohost/certs/{{ main_domain }}/key.pem
|
ssl_key = </etc/yunohost/certs/{{ main_domain }}/key.pem
|
||||||
|
{% for domain in domain_list.split() %}{% if domain != main_domain %}
|
||||||
|
local_name {{ domain }} {
|
||||||
|
ssl_cert = </etc/yunohost/certs/{{ domain }}/crt.pem
|
||||||
|
ssl_key = </etc/yunohost/certs/{{ domain }}/key.pem
|
||||||
|
}{% endif %}{% endfor %}
|
||||||
|
|
||||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
|
||||||
ssl_dh = </usr/share/yunohost/other/ffdhe2048.pem
|
ssl_dh = </usr/share/yunohost/ffdhe2048.pem
|
||||||
|
|
||||||
# intermediate configuration
|
# intermediate configuration
|
||||||
ssl_min_protocol = TLSv1.2
|
ssl_min_protocol = TLSv1.2
|
||||||
|
@ -33,14 +38,26 @@ ssl_prefer_server_ciphers = no
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Regular Yunohost accounts
|
||||||
passdb {
|
passdb {
|
||||||
args = /etc/dovecot/dovecot-ldap.conf
|
args = /etc/dovecot/dovecot-ldap.conf
|
||||||
driver = ldap
|
driver = ldap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Internally, allow authentication from apps system user who have "enable_email = true"
|
||||||
|
passdb {
|
||||||
|
driver = passwd-file
|
||||||
|
args = /etc/dovecot/app-senders-passwd
|
||||||
|
}
|
||||||
|
|
||||||
userdb {
|
userdb {
|
||||||
args = /etc/dovecot/dovecot-ldap.conf
|
|
||||||
driver = ldap
|
driver = ldap
|
||||||
|
args = /etc/dovecot/dovecot-ldap.conf
|
||||||
|
}
|
||||||
|
|
||||||
|
userdb {
|
||||||
|
driver = passwd-file
|
||||||
|
args = username_format=%n /etc/dovecot/app-senders-passwd
|
||||||
}
|
}
|
||||||
|
|
||||||
protocol imap {
|
protocol imap {
|
||||||
|
@ -48,13 +65,40 @@ protocol imap {
|
||||||
mail_plugins = $mail_plugins imap_quota antispam
|
mail_plugins = $mail_plugins imap_quota antispam
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protocol lda {
|
protocol lda {
|
||||||
auth_socket_path = /var/run/dovecot/auth-master
|
auth_socket_path = /var/run/dovecot/auth-master
|
||||||
mail_plugins = quota sieve
|
mail_plugins = quota sieve
|
||||||
postmaster_address = postmaster@{{ main_domain }}
|
postmaster_address = postmaster@{{ main_domain }}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace inbox {
|
||||||
|
inbox = yes
|
||||||
|
|
||||||
|
mailbox Drafts {
|
||||||
|
special_use = \Drafts
|
||||||
|
auto = subscribe
|
||||||
|
}
|
||||||
|
mailbox Junk {
|
||||||
|
special_use = \Junk
|
||||||
|
auto = subscribe
|
||||||
|
}
|
||||||
|
mailbox Trash {
|
||||||
|
special_use = \Trash
|
||||||
|
auto = subscribe
|
||||||
|
}
|
||||||
|
mailbox Sent {
|
||||||
|
special_use = \Sent
|
||||||
|
auto = subscribe
|
||||||
|
}
|
||||||
|
mailbox "Sent Messages" {
|
||||||
|
special_use = \Sent
|
||||||
|
}
|
||||||
|
mailbox "Archive" {
|
||||||
|
special_use = \Archive
|
||||||
|
auto = subscribe
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protocol sieve {
|
protocol sieve {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +146,8 @@ plugin {
|
||||||
antispam_debug_target = syslog
|
antispam_debug_target = syslog
|
||||||
antispam_verbose_debug = 0
|
antispam_verbose_debug = 0
|
||||||
antispam_backend = pipe
|
antispam_backend = pipe
|
||||||
antispam_spam = Junk;SPAM
|
antispam_spam_pattern_ignorecase = junk;spam
|
||||||
antispam_trash = Trash
|
antispam_trash_pattern_ignorecase = trash;papierkorb;deleted messages
|
||||||
antispam_pipe_program = /usr/bin/rspamc
|
antispam_pipe_program = /usr/bin/rspamc
|
||||||
antispam_pipe_program_args = -h;localhost:11334;-P;q1
|
antispam_pipe_program_args = -h;localhost:11334;-P;q1
|
||||||
antispam_pipe_program_spam_arg = learn_spam
|
antispam_pipe_program_spam_arg = learn_spam
|
|
@ -1,4 +1,4 @@
|
||||||
require "fileinto";
|
require "fileinto";
|
||||||
if header :contains "X-Spam-Flag" "YES" {
|
if header :contains "X-Spam-Flag" "Yes" {
|
||||||
fileinto "Junk";
|
fileinto "Junk";
|
||||||
}
|
}
|
6
conf/fail2ban/postfix-sasl.conf
Normal file
6
conf/fail2ban/postfix-sasl.conf
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Fail2Ban filter for postfix authentication failures
|
||||||
|
[INCLUDES]
|
||||||
|
before = common.conf
|
||||||
|
[Definition]
|
||||||
|
_daemon = postfix/smtpd
|
||||||
|
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL (?:LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(: [ A-Za-z0-9+/]*={0,2})?\s*$
|
|
@ -8,6 +8,13 @@ enabled = true
|
||||||
[postfix]
|
[postfix]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
||||||
|
[sasl]
|
||||||
|
enabled = true
|
||||||
|
port = smtp
|
||||||
|
filter = postfix-sasl
|
||||||
|
logpath = /var/log/mail.log
|
||||||
|
maxretry = 5
|
||||||
|
|
||||||
[dovecot]
|
[dovecot]
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=YunoHost mDNS service
|
Description=YunoHost mDNS service
|
||||||
After=network.target
|
Wants=network-online.target
|
||||||
|
After=network-online.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
User=mdns
|
User=mdns
|
||||||
|
@ -8,7 +9,7 @@ Group=mdns
|
||||||
Type=simple
|
Type=simple
|
||||||
Environment=PYTHONUNBUFFERED=1
|
Environment=PYTHONUNBUFFERED=1
|
||||||
ExecStart=/usr/bin/yunomdns
|
ExecStart=/usr/bin/yunomdns
|
||||||
StandardOutput=syslog
|
StandardOutput=journal
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
75
conf/metronome/domain.tpl.cfg.lua
Normal file
75
conf/metronome/domain.tpl.cfg.lua
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
VirtualHost "{{ domain }}"
|
||||||
|
enable = true
|
||||||
|
ssl = {
|
||||||
|
key = "/etc/yunohost/certs/{{ domain }}/key.pem";
|
||||||
|
certificate = "/etc/yunohost/certs/{{ domain }}/crt.pem";
|
||||||
|
}
|
||||||
|
authentication = "ldap2"
|
||||||
|
ldap = {
|
||||||
|
hostname = "localhost",
|
||||||
|
user = {
|
||||||
|
basedn = "ou=users,dc=yunohost,dc=org",
|
||||||
|
filter = "(&(objectClass=posixAccount)(mail=*@{{ domain }})(permission=cn=xmpp.main,ou=permission,dc=yunohost,dc=org))",
|
||||||
|
usernamefield = "mail",
|
||||||
|
namefield = "cn",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Discovery items
|
||||||
|
disco_items = {
|
||||||
|
{ "muc.{{ domain }}" },
|
||||||
|
{ "pubsub.{{ domain }}" },
|
||||||
|
{ "jabber.{{ domain }}" },
|
||||||
|
{ "vjud.{{ domain }}" },
|
||||||
|
{ "xmpp-upload.{{ domain }}" },
|
||||||
|
};
|
||||||
|
|
||||||
|
-- contact_info = {
|
||||||
|
-- abuse = { "mailto:abuse@{{ domain }}", "xmpp:admin@{{ domain }}" };
|
||||||
|
-- admin = { "mailto:root@{{ domain }}", "xmpp:admin@{{ domain }}" };
|
||||||
|
-- };
|
||||||
|
|
||||||
|
------ Components ------
|
||||||
|
-- You can specify components to add hosts that provide special services,
|
||||||
|
-- like multi-user conferences, and transports.
|
||||||
|
|
||||||
|
---Set up a MUC (multi-user chat) room server
|
||||||
|
Component "muc.{{ domain }}" "muc"
|
||||||
|
name = "{{ domain }} Chatrooms"
|
||||||
|
|
||||||
|
modules_enabled = {
|
||||||
|
"muc_limits";
|
||||||
|
"muc_log";
|
||||||
|
"muc_log_mam";
|
||||||
|
"muc_log_http";
|
||||||
|
"muc_vcard";
|
||||||
|
}
|
||||||
|
|
||||||
|
muc_event_rate = 0.5
|
||||||
|
muc_burst_factor = 10
|
||||||
|
room_default_config = {
|
||||||
|
logging = true,
|
||||||
|
persistent = true
|
||||||
|
};
|
||||||
|
|
||||||
|
---Set up a PubSub server
|
||||||
|
Component "pubsub.{{ domain }}" "pubsub"
|
||||||
|
name = "{{ domain }} Publish/Subscribe"
|
||||||
|
|
||||||
|
unrestricted_node_creation = true -- Anyone can create a PubSub node (from any server)
|
||||||
|
|
||||||
|
---Set up a HTTP Upload service
|
||||||
|
Component "xmpp-upload.{{ domain }}" "http_upload"
|
||||||
|
name = "{{ domain }} Sharing Service"
|
||||||
|
|
||||||
|
http_file_path = "/var/xmpp-upload/{{ domain }}/upload"
|
||||||
|
http_external_url = "https://xmpp-upload.{{ domain }}:443"
|
||||||
|
http_file_base_path = "/upload"
|
||||||
|
http_file_size_limit = 6*1024*1024
|
||||||
|
http_file_quota = 60*1024*1024
|
||||||
|
http_upload_file_size_limit = 100 * 1024 * 1024 -- bytes
|
||||||
|
http_upload_quota = 10 * 1024 * 1024 * 1024 -- bytes
|
||||||
|
|
||||||
|
---Set up a VJUD service
|
||||||
|
Component "vjud.{{ domain }}" "vjud"
|
||||||
|
vjud_disco_name = "{{ domain }} User Directory"
|
123
conf/metronome/metronome.cfg.lua
Normal file
123
conf/metronome/metronome.cfg.lua
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
-- ** Metronome's config file example **
|
||||||
|
--
|
||||||
|
-- The format is exactly equal to Prosody's:
|
||||||
|
--
|
||||||
|
-- Lists are written { "like", "this", "one" }
|
||||||
|
-- Lists can also be of { 1, 2, 3 } numbers, etc.
|
||||||
|
-- Either commas, or semi-colons; may be used as seperators.
|
||||||
|
--
|
||||||
|
-- A table is a list of values, except each value has a name. An
|
||||||
|
-- example would be:
|
||||||
|
--
|
||||||
|
-- ssl = { key = "keyfile.key", certificate = "certificate.cert" }
|
||||||
|
--
|
||||||
|
-- Tip: You can check that the syntax of this file is correct when you have finished
|
||||||
|
-- by running: luac -p metronome.cfg.lua
|
||||||
|
-- If there are any errors, it will let you know what and where they are, otherwise it
|
||||||
|
-- will keep quiet.
|
||||||
|
|
||||||
|
-- Global settings go in this section
|
||||||
|
|
||||||
|
-- This is the list of modules Metronome will load on startup.
|
||||||
|
-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too.
|
||||||
|
|
||||||
|
modules_enabled = {
|
||||||
|
-- Generally required
|
||||||
|
"roster"; -- Allow users to have a roster. Recommended.
|
||||||
|
"saslauth"; -- Authentication for clients. Recommended if you want to log in.
|
||||||
|
"tls"; -- Add support for secure TLS on c2s/s2s connections
|
||||||
|
"disco"; -- Service discovery
|
||||||
|
|
||||||
|
-- Not essential, but recommended
|
||||||
|
"private"; -- Private XML storage (for room bookmarks, etc.)
|
||||||
|
"vcard"; -- Allow users to set vCards
|
||||||
|
"pep"; -- Allows setting of mood, tune, etc.
|
||||||
|
"pubsub"; -- Publish-subscribe XEP-0060
|
||||||
|
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
|
||||||
|
"bidi"; -- Enables Bidirectional Server-to-Server Streams.
|
||||||
|
|
||||||
|
-- Nice to have
|
||||||
|
"version"; -- Replies to server version requests
|
||||||
|
"uptime"; -- Report how long server has been running
|
||||||
|
"time"; -- Let others know the time here on this server
|
||||||
|
"ping"; -- Replies to XMPP pings with pongs
|
||||||
|
"register"; -- Allow users to register on this server using a client and change passwords
|
||||||
|
"stream_management"; -- Allows clients and servers to use Stream Management
|
||||||
|
"stanza_optimizations"; -- Allows clients to use Client State Indication and SIFT
|
||||||
|
"message_carbons"; -- Allows clients to enable carbon copies of messages
|
||||||
|
"mam"; -- Enable server-side message archives using Message Archive Management
|
||||||
|
"push"; -- Enable Push Notifications via PubSub using XEP-0357
|
||||||
|
"lastactivity"; -- Enables clients to know the last presence status of an user
|
||||||
|
"adhoc_cm"; -- Allow to set client certificates to login through SASL External via adhoc
|
||||||
|
"admin_adhoc"; -- administration adhoc commands
|
||||||
|
"bookmarks"; -- XEP-0048 Bookmarks synchronization between PEP and Private Storage
|
||||||
|
"sec_labels"; -- Allows to use a simplified version XEP-0258 Security Labels and related ACDFs.
|
||||||
|
"privacy"; -- Add privacy lists and simple blocking command support
|
||||||
|
|
||||||
|
-- Other specific functionality
|
||||||
|
--"admin_telnet"; -- administration console, telnet to port 5582
|
||||||
|
--"admin_web"; -- administration web interface
|
||||||
|
"bosh"; -- Enable support for BOSH clients, aka "XMPP over Bidirectional Streams over Synchronous HTTP"
|
||||||
|
--"compression"; -- Allow clients to enable Stream Compression
|
||||||
|
--"spim_block"; -- Require authorization via OOB form for messages from non-contacts and block unsollicited messages
|
||||||
|
--"gate_guard"; -- Enable config-based blacklisting and hit-based auto-banning features
|
||||||
|
--"incidents_handling"; -- Enable Incidents Handling support (can be administered via adhoc commands)
|
||||||
|
--"server_presence"; -- Enables Server Buddies extension support
|
||||||
|
--"service_directory"; -- Enables Service Directories extension support
|
||||||
|
--"public_service"; -- Enables Server vCard support for public services in directories and advertises in features
|
||||||
|
--"register_api"; -- Provides secure API for both Out-Of-Band and In-Band registration for E-Mail verification
|
||||||
|
"websocket"; -- Enable support for WebSocket clients, aka "XMPP over WebSockets"
|
||||||
|
};
|
||||||
|
|
||||||
|
-- Server PID
|
||||||
|
pidfile = "/var/run/metronome/metronome.pid"
|
||||||
|
|
||||||
|
-- HTTP server
|
||||||
|
http_ports = { 5290 }
|
||||||
|
http_interfaces = { "127.0.0.1", "::1" }
|
||||||
|
|
||||||
|
--https_ports = { 5291 }
|
||||||
|
--https_interfaces = { "127.0.0.1", "::1" }
|
||||||
|
|
||||||
|
-- Enable IPv6
|
||||||
|
use_ipv6 = true
|
||||||
|
|
||||||
|
-- BOSH configuration (mod_bosh)
|
||||||
|
consider_bosh_secure = true
|
||||||
|
cross_domain_bosh = true
|
||||||
|
|
||||||
|
-- WebSocket configuration (mod_websocket)
|
||||||
|
consider_websocket_secure = true
|
||||||
|
cross_domain_websocket = true
|
||||||
|
|
||||||
|
-- Disable account creation by default, for security
|
||||||
|
allow_registration = false
|
||||||
|
|
||||||
|
-- Use LDAP storage backend for all stores
|
||||||
|
storage = "ldap"
|
||||||
|
|
||||||
|
-- stanza optimization
|
||||||
|
csi_config_queue_all_muc_messages_but_mentions = false;
|
||||||
|
|
||||||
|
|
||||||
|
-- Logging configuration
|
||||||
|
log = {
|
||||||
|
info = "/var/log/metronome/metronome.log"; -- Change 'info' to 'debug' for verbose logging
|
||||||
|
error = "/var/log/metronome/metronome.err";
|
||||||
|
-- "*syslog"; -- Uncomment this for logging to syslog
|
||||||
|
-- "*console"; -- Log to the console, useful for debugging with daemonize=false
|
||||||
|
}
|
||||||
|
|
||||||
|
------ Components ------
|
||||||
|
-- You can specify components to add hosts that provide special services,
|
||||||
|
-- like multi-user conferences, and transports.
|
||||||
|
|
||||||
|
---Set up a local BOSH service
|
||||||
|
Component "localhost" "http"
|
||||||
|
modules_enabled = { "bosh" }
|
||||||
|
|
||||||
|
----------- Virtual hosts -----------
|
||||||
|
-- You need to add a VirtualHost entry for each domain you wish Metronome to serve.
|
||||||
|
-- Settings under each VirtualHost entry apply *only* to that host.
|
||||||
|
|
||||||
|
Include "conf.d/*.cfg.lua"
|
90
conf/metronome/modules/mod_auth_ldap2.lua
Normal file
90
conf/metronome/modules/mod_auth_ldap2.lua
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
-- vim:sts=4 sw=4
|
||||||
|
|
||||||
|
-- Metronome IM
|
||||||
|
-- Copyright (C) 2008-2010 Matthew Wild
|
||||||
|
-- Copyright (C) 2008-2010 Waqas Hussain
|
||||||
|
-- Copyright (C) 2012 Rob Hoelz
|
||||||
|
-- Copyright (C) 2015 YUNOHOST.ORG
|
||||||
|
--
|
||||||
|
-- This project is MIT/X11 licensed. Please see the
|
||||||
|
-- COPYING file in the source package for more information.
|
||||||
|
--
|
||||||
|
-- https://github.com/YunoHost/yunohost-config-metronome/blob/unstable/lib/modules/mod_auth_ldap2.lua
|
||||||
|
-- adapted to use common LDAP store on Metronome
|
||||||
|
|
||||||
|
local ldap = module:require 'ldap';
|
||||||
|
local new_sasl = require 'util.sasl'.new;
|
||||||
|
local jsplit = require 'util.jid'.split;
|
||||||
|
|
||||||
|
local log = module._log
|
||||||
|
|
||||||
|
if not ldap then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
function new_default_provider(host)
|
||||||
|
local provider = { name = "ldap2" };
|
||||||
|
log("debug", "initializing ldap2 authentication provider for host '%s'", host);
|
||||||
|
|
||||||
|
function provider.test_password(username, password)
|
||||||
|
return ldap.bind(username, password);
|
||||||
|
end
|
||||||
|
|
||||||
|
function provider.user_exists(username)
|
||||||
|
local params = ldap.getparams()
|
||||||
|
|
||||||
|
local filter = ldap.filter.combine_and(params.user.filter, params.user.usernamefield .. '=' .. username);
|
||||||
|
if params.user.usernamefield == 'mail' then
|
||||||
|
filter = ldap.filter.combine_and(params.user.filter, 'mail=' .. username .. '@*');
|
||||||
|
end
|
||||||
|
|
||||||
|
return ldap.singlematch {
|
||||||
|
base = params.user.basedn,
|
||||||
|
filter = filter,
|
||||||
|
};
|
||||||
|
end
|
||||||
|
|
||||||
|
function provider.get_password(username)
|
||||||
|
return nil, "Passwords unavailable for LDAP.";
|
||||||
|
end
|
||||||
|
|
||||||
|
function provider.set_password(username, password)
|
||||||
|
return nil, "Passwords unavailable for LDAP.";
|
||||||
|
end
|
||||||
|
|
||||||
|
function provider.create_user(username, password)
|
||||||
|
return nil, "Account creation/modification not available with LDAP.";
|
||||||
|
end
|
||||||
|
|
||||||
|
function provider.get_sasl_handler(session)
|
||||||
|
local testpass_authentication_profile = {
|
||||||
|
session = session,
|
||||||
|
plain_test = function(sasl, username, password, realm)
|
||||||
|
return provider.test_password(username, password), true;
|
||||||
|
end,
|
||||||
|
order = { "plain_test" },
|
||||||
|
};
|
||||||
|
return new_sasl(module.host, testpass_authentication_profile);
|
||||||
|
end
|
||||||
|
|
||||||
|
function provider.is_admin(jid)
|
||||||
|
local admin_config = ldap.getparams().admin;
|
||||||
|
|
||||||
|
if not admin_config then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
local ld = ldap:getconnection();
|
||||||
|
local username = jsplit(jid);
|
||||||
|
local filter = ldap.filter.combine_and(admin_config.filter, admin_config.namefield .. '=' .. username);
|
||||||
|
|
||||||
|
return ldap.singlematch {
|
||||||
|
base = admin_config.basedn,
|
||||||
|
filter = filter,
|
||||||
|
};
|
||||||
|
end
|
||||||
|
|
||||||
|
return provider;
|
||||||
|
end
|
||||||
|
|
||||||
|
module:add_item("auth-provider", new_default_provider(module.host));
|
86
conf/metronome/modules/mod_legacyauth.lua
Normal file
86
conf/metronome/modules/mod_legacyauth.lua
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
-- Prosody IM
|
||||||
|
-- Copyright (C) 2008-2010 Matthew Wild
|
||||||
|
-- Copyright (C) 2008-2010 Waqas Hussain
|
||||||
|
--
|
||||||
|
-- This project is MIT/X11 licensed. Please see the
|
||||||
|
-- COPYING file in the source package for more information.
|
||||||
|
--
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local st = require "util.stanza";
|
||||||
|
local t_concat = table.concat;
|
||||||
|
|
||||||
|
local secure_auth_only = module:get_option("c2s_require_encryption")
|
||||||
|
or module:get_option("require_encryption")
|
||||||
|
or not(module:get_option("allow_unencrypted_plain_auth"));
|
||||||
|
|
||||||
|
local sessionmanager = require "core.sessionmanager";
|
||||||
|
local usermanager = require "core.usermanager";
|
||||||
|
local nodeprep = require "util.encodings".stringprep.nodeprep;
|
||||||
|
local resourceprep = require "util.encodings".stringprep.resourceprep;
|
||||||
|
|
||||||
|
module:add_feature("jabber:iq:auth");
|
||||||
|
module:hook("stream-features", function(event)
|
||||||
|
local origin, features = event.origin, event.features;
|
||||||
|
if secure_auth_only and not origin.secure then
|
||||||
|
-- Sorry, not offering to insecure streams!
|
||||||
|
return;
|
||||||
|
elseif not origin.username then
|
||||||
|
features:tag("auth", {xmlns='http://jabber.org/features/iq-auth'}):up();
|
||||||
|
end
|
||||||
|
end);
|
||||||
|
|
||||||
|
module:hook("stanza/iq/jabber:iq:auth:query", function(event)
|
||||||
|
local session, stanza = event.origin, event.stanza;
|
||||||
|
|
||||||
|
if session.type ~= "c2s_unauthed" then
|
||||||
|
(session.sends2s or session.send)(st.error_reply(stanza, "cancel", "service-unavailable", "Legacy authentication is only allowed for unauthenticated client connections."));
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
|
if secure_auth_only and not session.secure then
|
||||||
|
session.send(st.error_reply(stanza, "modify", "not-acceptable", "Encryption (SSL or TLS) is required to connect to this server"));
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
|
local username = stanza.tags[1]:child_with_name("username");
|
||||||
|
local password = stanza.tags[1]:child_with_name("password");
|
||||||
|
local resource = stanza.tags[1]:child_with_name("resource");
|
||||||
|
if not (username and password and resource) then
|
||||||
|
local reply = st.reply(stanza);
|
||||||
|
session.send(reply:query("jabber:iq:auth")
|
||||||
|
:tag("username"):up()
|
||||||
|
:tag("password"):up()
|
||||||
|
:tag("resource"):up());
|
||||||
|
else
|
||||||
|
username, password, resource = t_concat(username), t_concat(password), t_concat(resource);
|
||||||
|
username = nodeprep(username);
|
||||||
|
resource = resourceprep(resource)
|
||||||
|
if not (username and resource) then
|
||||||
|
session.send(st.error_reply(stanza, "modify", "bad-request"));
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
if usermanager.test_password(username, session.host, password) then
|
||||||
|
-- Authentication successful!
|
||||||
|
local success, err = sessionmanager.make_authenticated(session, username);
|
||||||
|
if success then
|
||||||
|
local err_type, err_msg;
|
||||||
|
success, err_type, err, err_msg = sessionmanager.bind_resource(session, resource);
|
||||||
|
if not success then
|
||||||
|
session.send(st.error_reply(stanza, err_type, err, err_msg));
|
||||||
|
session.username, session.type = nil, "c2s_unauthed"; -- FIXME should this be placed in sessionmanager?
|
||||||
|
return true;
|
||||||
|
elseif resource ~= session.resource then -- server changed resource, not supported by legacy auth
|
||||||
|
session.send(st.error_reply(stanza, "cancel", "conflict", "The requested resource could not be assigned to this session."));
|
||||||
|
session:close(); -- FIXME undo resource bind and auth instead of closing the session?
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
session.send(st.reply(stanza));
|
||||||
|
else
|
||||||
|
session.send(st.error_reply(stanza, "auth", "not-authorized"));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true;
|
||||||
|
end);
|
243
conf/metronome/modules/mod_storage_ldap.lua
Normal file
243
conf/metronome/modules/mod_storage_ldap.lua
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
-- vim:sts=4 sw=4
|
||||||
|
|
||||||
|
-- Metronome IM
|
||||||
|
-- Copyright (C) 2008-2010 Matthew Wild
|
||||||
|
-- Copyright (C) 2008-2010 Waqas Hussain
|
||||||
|
-- Copyright (C) 2012 Rob Hoelz
|
||||||
|
-- Copyright (C) 2015 YUNOHOST.ORG
|
||||||
|
--
|
||||||
|
-- This project is MIT/X11 licensed. Please see the
|
||||||
|
-- COPYING file in the source package for more information.
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Constants and such --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
local setmetatable = setmetatable;
|
||||||
|
|
||||||
|
local get_config = require "core.configmanager".get;
|
||||||
|
local ldap = module:require 'ldap';
|
||||||
|
local vcardlib = module:require 'vcard';
|
||||||
|
local st = require 'util.stanza';
|
||||||
|
local gettime = require 'socket'.gettime;
|
||||||
|
|
||||||
|
local log = module._log
|
||||||
|
|
||||||
|
if not ldap then
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
local CACHE_EXPIRY = 300;
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Utility Functions --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
local function ldap_record_to_vcard(record, format)
|
||||||
|
return vcardlib.create {
|
||||||
|
record = record,
|
||||||
|
format = format,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_alias_for_user;
|
||||||
|
|
||||||
|
do
|
||||||
|
local user_cache;
|
||||||
|
local last_fetch_time;
|
||||||
|
|
||||||
|
local function populate_user_cache()
|
||||||
|
local user_c = get_config(module.host, 'ldap').user;
|
||||||
|
if not user_c then return; end
|
||||||
|
|
||||||
|
local ld = ldap.getconnection();
|
||||||
|
|
||||||
|
local usernamefield = user_c.usernamefield;
|
||||||
|
local namefield = user_c.namefield;
|
||||||
|
|
||||||
|
user_cache = {};
|
||||||
|
|
||||||
|
for _, attrs in ld:search { base = user_c.basedn, scope = 'onelevel', filter = user_c.filter } do
|
||||||
|
user_cache[attrs[usernamefield]] = attrs[namefield];
|
||||||
|
end
|
||||||
|
last_fetch_time = gettime();
|
||||||
|
end
|
||||||
|
|
||||||
|
function get_alias_for_user(user)
|
||||||
|
if last_fetch_time and last_fetch_time + CACHE_EXPIRY < gettime() then
|
||||||
|
user_cache = nil;
|
||||||
|
end
|
||||||
|
if not user_cache then
|
||||||
|
populate_user_cache();
|
||||||
|
end
|
||||||
|
return user_cache[user];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Base LDAP store class --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
local function ldap_store(config)
|
||||||
|
local self = {};
|
||||||
|
local config = config;
|
||||||
|
|
||||||
|
function self:get(username)
|
||||||
|
return nil, "Data getting is not available for this storage backend";
|
||||||
|
end
|
||||||
|
|
||||||
|
function self:set(username, data)
|
||||||
|
return nil, "Data setting is not available for this storage backend";
|
||||||
|
end
|
||||||
|
|
||||||
|
return self;
|
||||||
|
end
|
||||||
|
|
||||||
|
local adapters = {};
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Roster Storage Implementation --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
adapters.roster = function (config)
|
||||||
|
-- Validate configuration requirements
|
||||||
|
if not config.groups then return nil; end
|
||||||
|
|
||||||
|
local self = ldap_store(config)
|
||||||
|
|
||||||
|
function self:get(username)
|
||||||
|
local ld = ldap.getconnection();
|
||||||
|
local contacts = {};
|
||||||
|
|
||||||
|
local memberfield = config.groups.memberfield;
|
||||||
|
local namefield = config.groups.namefield;
|
||||||
|
local filter = memberfield .. '=' .. tostring(username);
|
||||||
|
|
||||||
|
local groups = {};
|
||||||
|
for _, config in ipairs(config.groups) do
|
||||||
|
groups[ config[namefield] ] = config.name;
|
||||||
|
end
|
||||||
|
|
||||||
|
log("debug", "Found %d group(s) for user %s", select('#', groups), username)
|
||||||
|
|
||||||
|
-- XXX this kind of relies on the way we do groups at INOC
|
||||||
|
for _, attrs in ld:search { base = config.groups.basedn, scope = 'onelevel', filter = filter } do
|
||||||
|
if groups[ attrs[namefield] ] then
|
||||||
|
local members = attrs[memberfield];
|
||||||
|
|
||||||
|
for _, user in ipairs(members) do
|
||||||
|
if user ~= username then
|
||||||
|
local jid = user .. '@' .. module.host;
|
||||||
|
local record = contacts[jid];
|
||||||
|
|
||||||
|
if not record then
|
||||||
|
record = {
|
||||||
|
subscription = 'both',
|
||||||
|
groups = {},
|
||||||
|
name = get_alias_for_user(user),
|
||||||
|
};
|
||||||
|
contacts[jid] = record;
|
||||||
|
end
|
||||||
|
|
||||||
|
record.groups[ groups[ attrs[namefield] ] ] = true;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return contacts;
|
||||||
|
end
|
||||||
|
|
||||||
|
function self:set(username, data)
|
||||||
|
log("warn", "Setting data in Roster LDAP storage is not supported yet")
|
||||||
|
return nil, "not supported";
|
||||||
|
end
|
||||||
|
|
||||||
|
return self;
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- vCard Storage Implementation --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
adapters.vcard = function (config)
|
||||||
|
-- Validate configuration requirements
|
||||||
|
if not config.vcard_format or not config.user then return nil; end
|
||||||
|
|
||||||
|
local self = ldap_store(config)
|
||||||
|
|
||||||
|
function self:get(username)
|
||||||
|
local ld = ldap.getconnection();
|
||||||
|
local filter = config.user.usernamefield .. '=' .. tostring(username);
|
||||||
|
|
||||||
|
log("debug", "Retrieving vCard for user '%s'", username);
|
||||||
|
|
||||||
|
local match = ldap.singlematch {
|
||||||
|
base = config.user.basedn,
|
||||||
|
filter = filter,
|
||||||
|
};
|
||||||
|
if match then
|
||||||
|
match.jid = username .. '@' .. module.host
|
||||||
|
return st.preserialize(ldap_record_to_vcard(match, config.vcard_format));
|
||||||
|
else
|
||||||
|
return nil, "username not found";
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function self:set(username, data)
|
||||||
|
log("warn", "Setting data in vCard LDAP storage is not supported yet")
|
||||||
|
return nil, "not supported";
|
||||||
|
end
|
||||||
|
|
||||||
|
return self;
|
||||||
|
end
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
-- Driver Definition --
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
cache = {};
|
||||||
|
|
||||||
|
local driver = { name = "ldap" };
|
||||||
|
|
||||||
|
function driver:open(store)
|
||||||
|
log("debug", "Opening ldap storage backend for host '%s' and store '%s'", module.host, store);
|
||||||
|
|
||||||
|
if not cache[module.host] then
|
||||||
|
log("debug", "Caching adapters for the host '%s'", module.host);
|
||||||
|
|
||||||
|
local ad_config = get_config(module.host, "ldap");
|
||||||
|
local ad_cache = {};
|
||||||
|
for k, v in pairs(adapters) do
|
||||||
|
ad_cache[k] = v(ad_config);
|
||||||
|
end
|
||||||
|
|
||||||
|
cache[module.host] = ad_cache;
|
||||||
|
end
|
||||||
|
|
||||||
|
local adapter = cache[module.host][store];
|
||||||
|
|
||||||
|
if not adapter then
|
||||||
|
log("info", "Unavailable adapter for store '%s'", store);
|
||||||
|
return nil, "unsupported-store";
|
||||||
|
end
|
||||||
|
return adapter;
|
||||||
|
end
|
||||||
|
|
||||||
|
function driver:stores(username, type, pattern)
|
||||||
|
return nil, "not implemented";
|
||||||
|
end
|
||||||
|
|
||||||
|
function driver:store_exists(username, type)
|
||||||
|
return nil, "not implemented";
|
||||||
|
end
|
||||||
|
|
||||||
|
function driver:purge(username)
|
||||||
|
return nil, "not implemented";
|
||||||
|
end
|
||||||
|
|
||||||
|
function driver:nodes(type)
|
||||||
|
return nil, "not implemented";
|
||||||
|
end
|
||||||
|
|
||||||
|
module:add_item("data-driver", driver);
|
|
@ -135,28 +135,28 @@ function builder_methods:build()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function new_builder(params)
|
local function new_builder(params)
|
||||||
local vcard_tag = st.stanza('vCard', { xmlns = VCARD_NS });
|
local vcard_tag = st.stanza('vCard', { xmlns = VCARD_NS });
|
||||||
|
|
||||||
local object = {
|
local object = {
|
||||||
vcard = vcard_tag,
|
vcard = vcard_tag,
|
||||||
__index = builder_methods,
|
__index = builder_methods,
|
||||||
};
|
};
|
||||||
|
|
||||||
for k, v in pairs(params) do
|
for k, v in pairs(params) do
|
||||||
object[k] = v;
|
object[k] = v;
|
||||||
end
|
end
|
||||||
|
|
||||||
setmetatable(object, object);
|
setmetatable(object, object);
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
end
|
end
|
||||||
|
|
||||||
local _M = {};
|
local _M = {};
|
||||||
|
|
||||||
function _M.create(params)
|
function _M.create(params)
|
||||||
local builder = new_builder(params);
|
local builder = new_builder(params);
|
||||||
|
|
||||||
return builder:build();
|
return builder:build();
|
||||||
end
|
end
|
||||||
|
|
||||||
return _M;
|
return _M;
|
|
@ -1,6 +1,6 @@
|
||||||
location ^~ '/.well-known/acme-challenge/'
|
location ^~ '/.well-known/acme-challenge/'
|
||||||
{
|
{
|
||||||
default_type "text/plain";
|
default_type "text/plain";
|
||||||
alias /tmp/acme-challenge-public/;
|
alias /var/www/.well-known/acme-challenge-public/;
|
||||||
gzip off;
|
gzip off;
|
||||||
}
|
}
|
7
conf/nginx/plain/yunohost_http_errors.conf.inc
Normal file
7
conf/nginx/plain/yunohost_http_errors.conf.inc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
error_page 502 /502.html;
|
||||||
|
|
||||||
|
location = /502.html {
|
||||||
|
|
||||||
|
root /usr/share/yunohost/html/;
|
||||||
|
|
||||||
|
}
|
3
conf/nginx/redirect_to_admin.conf
Normal file
3
conf/nginx/redirect_to_admin.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
location / {
|
||||||
|
return 302 https://$host/yunohost/admin;
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ ssl_prefer_server_ciphers off;
|
||||||
# Pre-defined FFDHE group (RFC 7919)
|
# Pre-defined FFDHE group (RFC 7919)
|
||||||
# From https://ssl-config.mozilla.org/ffdhe2048.txt
|
# From https://ssl-config.mozilla.org/ffdhe2048.txt
|
||||||
# https://security.stackexchange.com/a/149818
|
# https://security.stackexchange.com/a/149818
|
||||||
ssl_dhparam /usr/share/yunohost/other/ffdhe2048.pem;
|
ssl_dhparam /usr/share/yunohost/ffdhe2048.pem;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,10 +26,9 @@ ssl_dhparam /usr/share/yunohost/other/ffdhe2048.pem;
|
||||||
# https://wiki.mozilla.org/Security/Guidelines/Web_Security
|
# https://wiki.mozilla.org/Security/Guidelines/Web_Security
|
||||||
# https://observatory.mozilla.org/
|
# https://observatory.mozilla.org/
|
||||||
{% if experimental == "True" %}
|
{% if experimental == "True" %}
|
||||||
more_set_headers "Content-Security-Policy : upgrade-insecure-requests; default-src https: data: blob: ; object-src https: data: 'unsafe-inline'; style-src https: data: 'unsafe-inline' ; script-src https: data: 'unsafe-inline' 'unsafe-eval'";
|
more_set_headers "Content-Security-Policy : upgrade-insecure-requests; default-src https: data: blob: ; object-src https: data: 'unsafe-inline'; style-src https: data: 'unsafe-inline' ; script-src https: data: 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:;";
|
||||||
{% else %}
|
{% else %}
|
||||||
more_set_headers "Content-Security-Policy : upgrade-insecure-requests";
|
more_set_headers "Content-Security-Policy : upgrade-insecure-requests";
|
||||||
more_set_headers "Content-Security-Policy-Report-Only : default-src https: data: blob: ; object-src https: data: 'unsafe-inline'; style-src https: data: 'unsafe-inline' ; script-src https: data: 'unsafe-inline' 'unsafe-eval'";
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
more_set_headers "X-Content-Type-Options : nosniff";
|
more_set_headers "X-Content-Type-Options : nosniff";
|
||||||
more_set_headers "X-XSS-Protection : 1; mode=block";
|
more_set_headers "X-XSS-Protection : 1; mode=block";
|
|
@ -6,30 +6,34 @@ map $http_upgrade $connection_upgrade {
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name {{ domain }} xmpp-upload.{{ domain }};
|
server_name {{ domain }}{% if xmpp_enabled == "True" %} xmpp-upload.{{ domain }} muc.{{ domain }}{% endif %};
|
||||||
|
|
||||||
access_by_lua_file /usr/share/ssowat/access.lua;
|
access_by_lua_file /usr/share/ssowat/access.lua;
|
||||||
|
|
||||||
include /etc/nginx/conf.d/acme-challenge.conf.inc;
|
include /etc/nginx/conf.d/acme-challenge.conf.inc;
|
||||||
|
|
||||||
location ^~ '/.well-known/ynh-diagnosis/' {
|
location ^~ '/.well-known/ynh-diagnosis/' {
|
||||||
alias /tmp/.well-known/ynh-diagnosis/;
|
alias /var/www/.well-known/ynh-diagnosis/;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{% if mail_enabled == "True" %}
|
||||||
location ^~ '/.well-known/autoconfig/mail/' {
|
location ^~ '/.well-known/autoconfig/mail/' {
|
||||||
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
||||||
}
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{# Note that this != "False" is meant to be failure-safe, in the case the redrect_to_https would happen to contain empty string or whatever value. We absolutely don't want to disable the HTTPS redirect *except* when it's explicitly being asked to be disabled. #}
|
{# Note that this != "False" is meant to be failure-safe, in the case the redrect_to_https would happen to contain empty string or whatever value. We absolutely don't want to disable the HTTPS redirect *except* when it's explicitly being asked to be disabled. #}
|
||||||
{% if redirect_to_https != "False" %}
|
{% if redirect_to_https != "False" %}
|
||||||
location / {
|
location / {
|
||||||
return 301 https://$http_host$request_uri;
|
return 301 https://$host$request_uri;
|
||||||
}
|
}
|
||||||
{# The app config snippets are not included in the HTTP conf unless HTTPS redirect is disabled, because app's location may blocks will conflict or bypass/ignore the HTTPS redirection. #}
|
{# The app config snippets are not included in the HTTP conf unless HTTPS redirect is disabled, because app's location may blocks will conflict or bypass/ignore the HTTPS redirection. #}
|
||||||
{% else %}
|
{% else %}
|
||||||
include /etc/nginx/conf.d/{{ domain }}.d/*.conf;
|
include /etc/nginx/conf.d/{{ domain }}.d/*.conf;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
include /etc/nginx/conf.d/yunohost_http_errors.conf.inc;
|
||||||
|
|
||||||
access_log /var/log/nginx/{{ domain }}-access.log;
|
access_log /var/log/nginx/{{ domain }}-access.log;
|
||||||
error_log /var/log/nginx/{{ domain }}-error.log;
|
error_log /var/log/nginx/{{ domain }}-error.log;
|
||||||
}
|
}
|
||||||
|
@ -44,21 +48,23 @@ server {
|
||||||
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
||||||
|
|
||||||
{% if domain_cert_ca != "Self-signed" %}
|
{% if domain_cert_ca != "selfsigned" %}
|
||||||
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if domain_cert_ca == "Let's Encrypt" %}
|
{% if domain_cert_ca == "letsencrypt" %}
|
||||||
# OCSP settings
|
# OCSP settings
|
||||||
ssl_stapling on;
|
ssl_stapling on;
|
||||||
ssl_stapling_verify on;
|
ssl_stapling_verify on;
|
||||||
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
resolver 127.0.0.1 127.0.1.1 valid=300s;
|
resolver 1.1.1.1 9.9.9.9 valid=300s;
|
||||||
resolver_timeout 5s;
|
resolver_timeout 5s;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if mail_enabled == "True" %}
|
||||||
location ^~ '/.well-known/autoconfig/mail/' {
|
location ^~ '/.well-known/autoconfig/mail/' {
|
||||||
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
alias /var/www/.well-known/{{ domain }}/autoconfig/mail/;
|
||||||
}
|
}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
access_by_lua_file /usr/share/ssowat/access.lua;
|
access_by_lua_file /usr/share/ssowat/access.lua;
|
||||||
|
|
||||||
|
@ -67,11 +73,13 @@ server {
|
||||||
include /etc/nginx/conf.d/yunohost_sso.conf.inc;
|
include /etc/nginx/conf.d/yunohost_sso.conf.inc;
|
||||||
include /etc/nginx/conf.d/yunohost_admin.conf.inc;
|
include /etc/nginx/conf.d/yunohost_admin.conf.inc;
|
||||||
include /etc/nginx/conf.d/yunohost_api.conf.inc;
|
include /etc/nginx/conf.d/yunohost_api.conf.inc;
|
||||||
|
include /etc/nginx/conf.d/yunohost_http_errors.conf.inc;
|
||||||
|
|
||||||
access_log /var/log/nginx/{{ domain }}-access.log;
|
access_log /var/log/nginx/{{ domain }}-access.log;
|
||||||
error_log /var/log/nginx/{{ domain }}-error.log;
|
error_log /var/log/nginx/{{ domain }}-error.log;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{% if xmpp_enabled == "True" %}
|
||||||
# vhost dedicated to XMPP http_upload
|
# vhost dedicated to XMPP http_upload
|
||||||
server {
|
server {
|
||||||
listen 443 ssl http2;
|
listen 443 ssl http2;
|
||||||
|
@ -99,18 +107,19 @@ server {
|
||||||
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
ssl_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
ssl_certificate_key /etc/yunohost/certs/{{ domain }}/key.pem;
|
||||||
|
|
||||||
{% if domain_cert_ca != "Self-signed" %}
|
{% if domain_cert_ca != "selfsigned" %}
|
||||||
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
more_set_headers "Strict-Transport-Security : max-age=63072000; includeSubDomains; preload";
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if domain_cert_ca == "Let's Encrypt" %}
|
{% if domain_cert_ca == "letsencrypt" %}
|
||||||
# OCSP settings
|
# OCSP settings
|
||||||
ssl_stapling on;
|
ssl_stapling on;
|
||||||
ssl_stapling_verify on;
|
ssl_stapling_verify on;
|
||||||
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
ssl_trusted_certificate /etc/yunohost/certs/{{ domain }}/crt.pem;
|
||||||
resolver 127.0.0.1 127.0.1.1 valid=300s;
|
resolver 1.1.1.1 9.9.9.9 valid=300s;
|
||||||
resolver_timeout 5s;
|
resolver_timeout 5s;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
access_log /var/log/nginx/xmpp-upload.{{ domain }}-access.log;
|
access_log /var/log/nginx/xmpp-upload.{{ domain }}-access.log;
|
||||||
error_log /var/log/nginx/xmpp-upload.{{ domain }}-error.log;
|
error_log /var/log/nginx/xmpp-upload.{{ domain }}-error.log;
|
||||||
}
|
}
|
||||||
|
{% endif %}
|
|
@ -7,9 +7,11 @@ location /yunohost/admin/ {
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|
||||||
{% if webadmin_allowlist_enabled == "True" %}
|
{% if webadmin_allowlist_enabled == "True" %}
|
||||||
{% for ip in webadmin_allowlist.split(',') %}
|
{% if webadmin_allowlist.strip() -%}
|
||||||
allow {{ ip }};
|
{% for ip in webadmin_allowlist.strip().split(',') -%}
|
||||||
{% endfor %}
|
allow {{ ip.strip() }};
|
||||||
|
{% endfor -%}
|
||||||
|
{% endif -%}
|
||||||
deny all;
|
deny all;
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -19,6 +21,10 @@ location /yunohost/admin/ {
|
||||||
more_set_headers "Cache-Control: no-store, no-cache, must-revalidate";
|
more_set_headers "Cache-Control: no-store, no-cache, must-revalidate";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location /yunohost/admin/applogos/ {
|
||||||
|
alias /usr/share/yunohost/applogos/;
|
||||||
|
}
|
||||||
|
|
||||||
more_set_headers "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; connect-src 'self' https://paste.yunohost.org wss://$host; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; object-src 'none'; img-src 'self' data:;";
|
more_set_headers "Content-Security-Policy: upgrade-insecure-requests; default-src 'self'; connect-src 'self' https://paste.yunohost.org wss://$host; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-eval'; object-src 'none'; img-src 'self' data:;";
|
||||||
more_set_headers "Content-Security-Policy-Report-Only:";
|
more_set_headers "Content-Security-Policy-Report-Only:";
|
||||||
}
|
}
|
|
@ -4,7 +4,7 @@ location /yunohost/api/ {
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection "upgrade";
|
proxy_set_header Connection "upgrade";
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $host;
|
||||||
|
|
||||||
{% if webadmin_allowlist_enabled == "True" %}
|
{% if webadmin_allowlist_enabled == "True" %}
|
||||||
{% for ip in webadmin_allowlist.split(',') %}
|
{% for ip in webadmin_allowlist.split(',') %}
|
|
@ -23,8 +23,11 @@ smtpd_use_tls = yes
|
||||||
|
|
||||||
smtpd_tls_security_level = may
|
smtpd_tls_security_level = may
|
||||||
smtpd_tls_auth_only = yes
|
smtpd_tls_auth_only = yes
|
||||||
smtpd_tls_cert_file = /etc/yunohost/certs/{{ main_domain }}/crt.pem
|
smtpd_tls_chain_files =
|
||||||
smtpd_tls_key_file = /etc/yunohost/certs/{{ main_domain }}/key.pem
|
/etc/yunohost/certs/{{ main_domain }}/key.pem,
|
||||||
|
/etc/yunohost/certs/{{ main_domain }}/crt.pem
|
||||||
|
|
||||||
|
tls_server_sni_maps = hash:/etc/postfix/sni
|
||||||
|
|
||||||
{% if compatibility == "intermediate" %}
|
{% if compatibility == "intermediate" %}
|
||||||
# generated 2020-08-18, Mozilla Guideline v5.6, Postfix 3.4.14, OpenSSL 1.1.1d, intermediate configuration
|
# generated 2020-08-18, Mozilla Guideline v5.6, Postfix 3.4.14, OpenSSL 1.1.1d, intermediate configuration
|
||||||
|
@ -36,7 +39,7 @@ smtpd_tls_mandatory_ciphers = medium
|
||||||
|
|
||||||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
|
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
|
||||||
# not actually 1024 bits, this applies to all DHE >= 1024 bits
|
# not actually 1024 bits, this applies to all DHE >= 1024 bits
|
||||||
smtpd_tls_dh1024_param_file = /usr/share/yunohost/other/ffdhe2048.pem
|
smtpd_tls_dh1024_param_file = /usr/share/yunohost/ffdhe2048.pem
|
||||||
|
|
||||||
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
tls_medium_cipherlist = ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -78,7 +81,7 @@ alias_maps = hash:/etc/aliases
|
||||||
alias_database = hash:/etc/aliases
|
alias_database = hash:/etc/aliases
|
||||||
mydomain = {{ main_domain }}
|
mydomain = {{ main_domain }}
|
||||||
mydestination = localhost
|
mydestination = localhost
|
||||||
{% if relay_host == "" %}
|
{% if relay_enabled != "True" %}
|
||||||
relayhost =
|
relayhost =
|
||||||
{% else %}
|
{% else %}
|
||||||
relayhost = [{{ relay_host }}]:{{ relay_port }}
|
relayhost = [{{ relay_host }}]:{{ relay_port }}
|
||||||
|
@ -97,14 +100,18 @@ message_size_limit = 35914708
|
||||||
|
|
||||||
# Virtual Domains Control
|
# Virtual Domains Control
|
||||||
virtual_mailbox_domains = ldap:/etc/postfix/ldap-domains.cf
|
virtual_mailbox_domains = ldap:/etc/postfix/ldap-domains.cf
|
||||||
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf
|
virtual_mailbox_maps = ldap:/etc/postfix/ldap-accounts.cf,hash:/etc/postfix/app_senders_login_maps
|
||||||
virtual_mailbox_base =
|
virtual_mailbox_base =
|
||||||
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf
|
virtual_alias_maps = ldap:/etc/postfix/ldap-aliases.cf,ldap:/etc/postfix/ldap-groups.cf
|
||||||
virtual_alias_domains =
|
virtual_alias_domains =
|
||||||
virtual_minimum_uid = 100
|
virtual_minimum_uid = 100
|
||||||
virtual_uid_maps = static:vmail
|
virtual_uid_maps = static:vmail
|
||||||
virtual_gid_maps = static:mail
|
virtual_gid_maps = static:mail
|
||||||
smtpd_sender_login_maps= ldap:/etc/postfix/ldap-accounts.cf
|
smtpd_sender_login_maps = unionmap:{
|
||||||
|
# Regular Yunohost accounts
|
||||||
|
ldap:/etc/postfix/ldap-accounts.cf,
|
||||||
|
# Extra maps for app system users who need to send emails
|
||||||
|
hash:/etc/postfix/app_senders_login_maps }
|
||||||
|
|
||||||
# Dovecot LDA
|
# Dovecot LDA
|
||||||
virtual_transport = dovecot
|
virtual_transport = dovecot
|
||||||
|
@ -195,7 +202,7 @@ smtpd_client_recipient_rate_limit=150
|
||||||
# and after to send spam
|
# and after to send spam
|
||||||
disable_vrfy_command = yes
|
disable_vrfy_command = yes
|
||||||
|
|
||||||
{% if relay_user != "" %}
|
{% if relay_enabled == "True" %}
|
||||||
# Relay email through an other smtp account
|
# Relay email through an other smtp account
|
||||||
# enable SASL authentication
|
# enable SASL authentication
|
||||||
smtp_sasl_auth_enable = yes
|
smtp_sasl_auth_enable = yes
|
||||||
|
@ -204,3 +211,11 @@ smtp_sasl_security_options = noanonymous
|
||||||
# where to find sasl_passwd
|
# where to find sasl_passwd
|
||||||
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
{% if backup_mx_domains != "" %}
|
||||||
|
# Backup MX (secondary MX)
|
||||||
|
relay_domains = $mydestination {{backup_mx_domains}}
|
||||||
|
relay_recipient_maps = hash:/etc/postfix/relay_recipients
|
||||||
|
maximal_queue_lifetime = 20d
|
||||||
|
{% endif %}
|
||||||
|
|
7
conf/postfix/plain/ldap-groups.cf
Normal file
7
conf/postfix/plain/ldap-groups.cf
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
server_host = localhost
|
||||||
|
server_port = 389
|
||||||
|
search_base = dc=yunohost,dc=org
|
||||||
|
query_filter = (&(objectClass=groupOfNamesYnh)(mail=%s))
|
||||||
|
scope = sub
|
||||||
|
result_attribute = memberUid, mail
|
||||||
|
terminal_result_attribute = memberUid
|
4
conf/postfix/sni
Normal file
4
conf/postfix/sni
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# This maps domain to certificates to properly handle multi-domain context
|
||||||
|
# (also we need a comment in this file such that it's never empty to prevent regenconf issues)
|
||||||
|
{% for domain in domain_list.split() %}{{ domain }} /etc/yunohost/certs/{{ domain }}/key.pem /etc/yunohost/certs/{{ domain }}/crt.pem
|
||||||
|
{% endfor %}
|
2
conf/rspamd/redis.conf
Normal file
2
conf/rspamd/redis.conf
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# set redis server
|
||||||
|
servers = "127.0.0.1";
|
|
@ -1,4 +1,4 @@
|
||||||
require ["fileinto"];
|
require ["fileinto"];
|
||||||
if header :is "X-Spam" "yes" {
|
if header :is "X-Spam" "Yes" {
|
||||||
fileinto "Junk";
|
fileinto "Junk";
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
# Config database customization:
|
# Config database customization:
|
||||||
# 1. Edit this file as you want.
|
# 1. Edit this file as you want.
|
||||||
# 2. Apply your modifications. For this just run this following command in a shell:
|
# 2. Apply your modifications. For this just run this following command in a shell:
|
||||||
# $ /usr/share/yunohost/hooks/conf_regen/06-slapd apply_config
|
# $ /usr/share/yunohost/hooks/conf_regen/06-slapd post true
|
||||||
#
|
#
|
||||||
# Note that if you customize this file, YunoHost's regen-conf will NOT
|
# Note that if you customize this file, YunoHost's regen-conf will NOT
|
||||||
# overwrite this file. But that also means that you should be careful about
|
# overwrite this file. But that also means that you should be careful about
|
||||||
|
@ -130,7 +130,6 @@ olcSuffix: dc=yunohost,dc=org
|
||||||
# admin entry below
|
# admin entry below
|
||||||
# These access lines apply to database #1 only
|
# These access lines apply to database #1 only
|
||||||
olcAccess: {0}to attrs=userPassword,shadowLastChange
|
olcAccess: {0}to attrs=userPassword,shadowLastChange
|
||||||
by dn.base="cn=admin,dc=yunohost,dc=org" write
|
|
||||||
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
|
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
|
||||||
by anonymous auth
|
by anonymous auth
|
||||||
by self write
|
by self write
|
||||||
|
@ -140,7 +139,6 @@ olcAccess: {0}to attrs=userPassword,shadowLastChange
|
||||||
# owning it if they are authenticated.
|
# owning it if they are authenticated.
|
||||||
# Others should be able to see it.
|
# Others should be able to see it.
|
||||||
olcAccess: {1}to attrs=cn,gecos,givenName,mail,maildrop,displayName,sn
|
olcAccess: {1}to attrs=cn,gecos,givenName,mail,maildrop,displayName,sn
|
||||||
by dn.base="cn=admin,dc=yunohost,dc=org" write
|
|
||||||
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
|
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
|
||||||
by self write
|
by self write
|
||||||
by * read
|
by * read
|
||||||
|
@ -160,9 +158,8 @@ olcAccess: {2}to dn.base=""
|
||||||
# The admin dn has full write access, everyone else
|
# The admin dn has full write access, everyone else
|
||||||
# can read everything.
|
# can read everything.
|
||||||
olcAccess: {3}to *
|
olcAccess: {3}to *
|
||||||
by dn.base="cn=admin,dc=yunohost,dc=org" write
|
|
||||||
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
|
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
|
||||||
by group/groupOfNames/member.exact="cn=admin,ou=groups,dc=yunohost,dc=org" write
|
by group/groupOfNamesYnh/member.exact="cn=admins,ou=groups,dc=yunohost,dc=org" write
|
||||||
by * read
|
by * read
|
||||||
#
|
#
|
||||||
olcAddContentAcl: FALSE
|
olcAddContentAcl: FALSE
|
|
@ -5,15 +5,6 @@ objectClass: organization
|
||||||
o: yunohost.org
|
o: yunohost.org
|
||||||
dc: yunohost
|
dc: yunohost
|
||||||
|
|
||||||
dn: cn=admin,ou=sudo,dc=yunohost,dc=org
|
|
||||||
cn: admin
|
|
||||||
objectClass: sudoRole
|
|
||||||
objectClass: top
|
|
||||||
sudoCommand: ALL
|
|
||||||
sudoUser: admin
|
|
||||||
sudoOption: !authenticate
|
|
||||||
sudoHost: ALL
|
|
||||||
|
|
||||||
dn: ou=users,dc=yunohost,dc=org
|
dn: ou=users,dc=yunohost,dc=org
|
||||||
objectClass: organizationalUnit
|
objectClass: organizationalUnit
|
||||||
objectClass: top
|
objectClass: top
|
||||||
|
@ -39,27 +30,23 @@ objectClass: organizationalUnit
|
||||||
objectClass: top
|
objectClass: top
|
||||||
ou: groups
|
ou: groups
|
||||||
|
|
||||||
|
dn: cn=admins,ou=sudo,dc=yunohost,dc=org
|
||||||
|
cn: admins
|
||||||
|
objectClass: sudoRole
|
||||||
|
objectClass: top
|
||||||
|
sudoCommand: ALL
|
||||||
|
sudoUser: %admins
|
||||||
|
sudoHost: ALL
|
||||||
|
|
||||||
dn: ou=sudo,dc=yunohost,dc=org
|
dn: ou=sudo,dc=yunohost,dc=org
|
||||||
objectClass: organizationalUnit
|
objectClass: organizationalUnit
|
||||||
objectClass: top
|
objectClass: top
|
||||||
ou: sudo
|
ou: sudo
|
||||||
|
|
||||||
dn: cn=admin,dc=yunohost,dc=org
|
|
||||||
objectClass: organizationalRole
|
|
||||||
objectClass: posixAccount
|
|
||||||
objectClass: simpleSecurityObject
|
|
||||||
cn: admin
|
|
||||||
uid: admin
|
|
||||||
uidNumber: 1007
|
|
||||||
gidNumber: 1007
|
|
||||||
homeDirectory: /home/admin
|
|
||||||
loginShell: /bin/bash
|
|
||||||
userPassword: yunohost
|
|
||||||
|
|
||||||
dn: cn=admins,ou=groups,dc=yunohost,dc=org
|
dn: cn=admins,ou=groups,dc=yunohost,dc=org
|
||||||
objectClass: posixGroup
|
objectClass: posixGroup
|
||||||
objectClass: top
|
objectClass: top
|
||||||
memberUid: admin
|
objectClass: groupOfNamesYnh
|
||||||
gidNumber: 4001
|
gidNumber: 4001
|
||||||
cn: admins
|
cn: admins
|
||||||
|
|
|
@ -89,4 +89,7 @@ olcObjectClasses: ( 1.3.6.1.4.1.40328.1.1.2.3
|
||||||
NAME 'mailGroup' SUP top AUXILIARY
|
NAME 'mailGroup' SUP top AUXILIARY
|
||||||
DESC 'Mail Group'
|
DESC 'Mail Group'
|
||||||
MUST ( mail )
|
MUST ( mail )
|
||||||
|
MAY (
|
||||||
|
mailalias $ maildrop
|
||||||
|
)
|
||||||
)
|
)
|
|
@ -21,7 +21,7 @@ SLAPD_PIDFILE=
|
||||||
# sockets.
|
# sockets.
|
||||||
# Example usage:
|
# Example usage:
|
||||||
# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
|
# SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
|
||||||
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps:/// ldapi:///"
|
SLAPD_SERVICES="ldap://localhost:389/ ldaps:/// ldapi:///"
|
||||||
|
|
||||||
# If SLAPD_NO_START is set, the init script will not start or restart
|
# If SLAPD_NO_START is set, the init script will not start or restart
|
||||||
# slapd (but stop will still work). Uncomment this if you are
|
# slapd (but stop will still work). Uncomment this if you are
|
|
@ -2,6 +2,8 @@
|
||||||
# by YunoHost
|
# by YunoHost
|
||||||
|
|
||||||
Protocol 2
|
Protocol 2
|
||||||
|
# PLEASE: if you wish to change the ssh port properly in YunoHost, use this command:
|
||||||
|
# yunohost settings set security.ssh.ssh_port -v <port>
|
||||||
Port {{ port }}
|
Port {{ port }}
|
||||||
|
|
||||||
{% if ipv6_enabled == "true" %}ListenAddress ::{% endif %}
|
{% if ipv6_enabled == "true" %}ListenAddress ::{% endif %}
|
||||||
|
@ -53,12 +55,16 @@ PermitEmptyPasswords no
|
||||||
ChallengeResponseAuthentication no
|
ChallengeResponseAuthentication no
|
||||||
UsePAM yes
|
UsePAM yes
|
||||||
|
|
||||||
# Change to no to disable tunnelled clear text passwords
|
# PLEASE: if you wish to force everybody to authenticate using ssh keys, run this command:
|
||||||
# (i.e. everybody will need to authenticate using ssh keys)
|
# yunohost settings set security.ssh.ssh_password_authentication -v no
|
||||||
|
{% if password_authentication == "False" %}
|
||||||
|
PasswordAuthentication no
|
||||||
|
{% else %}
|
||||||
#PasswordAuthentication yes
|
#PasswordAuthentication yes
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Post-login stuff
|
# Post-login stuff
|
||||||
Banner /etc/issue.net
|
# Banner none
|
||||||
PrintMotd no
|
PrintMotd no
|
||||||
PrintLastLog yes
|
PrintLastLog yes
|
||||||
ClientAliveInterval 60
|
ClientAliveInterval 60
|
||||||
|
@ -78,7 +84,7 @@ Subsystem sftp internal-sftp
|
||||||
|
|
||||||
# Apply following instructions to user with sftp perm only
|
# Apply following instructions to user with sftp perm only
|
||||||
Match Group sftp.main,!ssh.main
|
Match Group sftp.main,!ssh.main
|
||||||
ForceCommand internal-sftp
|
ForceCommand internal-sftp -u 0002
|
||||||
# We can't restrict to /home/%u because the chroot base must be owned by root
|
# We can't restrict to /home/%u because the chroot base must be owned by root
|
||||||
# So we chroot only on /home
|
# So we chroot only on /home
|
||||||
# See https://serverfault.com/questions/584986/bad-ownership-or-modes-for-chroot-directory-component
|
# See https://serverfault.com/questions/584986/bad-ownership-or-modes-for-chroot-directory-component
|
||||||
|
@ -91,7 +97,7 @@ Match Group sftp.main,!ssh.main
|
||||||
PermitUserRC no
|
PermitUserRC no
|
||||||
|
|
||||||
Match Group sftp.app,!ssh.app
|
Match Group sftp.app,!ssh.app
|
||||||
ForceCommand internal-sftp
|
ForceCommand internal-sftp -u 0002
|
||||||
ChrootDirectory %h
|
ChrootDirectory %h
|
||||||
AllowTcpForwarding no
|
AllowTcpForwarding no
|
||||||
AllowStreamLocalForwarding no
|
AllowStreamLocalForwarding no
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# This definition stops the following lines choking if HOME isn't
|
# This definition stops the following lines choking if HOME isn't
|
||||||
# defined.
|
# defined.
|
||||||
HOME = /usr/share/yunohost/yunohost-config/ssl
|
HOME = /usr/share/yunohost/ssl
|
||||||
RANDFILE = $ENV::HOME/.rnd
|
RANDFILE = $ENV::HOME/.rnd
|
||||||
|
|
||||||
# Extra OBJECT IDENTIFIER info:
|
# Extra OBJECT IDENTIFIER info:
|
||||||
|
@ -34,7 +34,7 @@ default_ca = Yunohost # The default ca section
|
||||||
####################################################################
|
####################################################################
|
||||||
[ Yunohost ]
|
[ Yunohost ]
|
||||||
|
|
||||||
dir = /usr/share/yunohost/yunohost-config/ssl/yunoCA # Where everything is kept
|
dir = /usr/share/yunohost/ssl # Where everything is kept
|
||||||
certs = $dir/certs # Where the issued certs are kept
|
certs = $dir/certs # Where the issued certs are kept
|
||||||
crl_dir = $dir/crl # Where the issued crl are kept
|
crl_dir = $dir/crl # Where the issued crl are kept
|
||||||
database = $dir/index.txt # database index file.
|
database = $dir/index.txt # database index file.
|
|
@ -12,24 +12,31 @@ metronome:
|
||||||
log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err]
|
log: [/var/log/metronome/metronome.log,/var/log/metronome/metronome.err]
|
||||||
needs_exposed_ports: [5222, 5269]
|
needs_exposed_ports: [5222, 5269]
|
||||||
category: xmpp
|
category: xmpp
|
||||||
|
ignore_if_package_is_not_installed: metronome
|
||||||
mysql:
|
mysql:
|
||||||
log: [/var/log/mysql.log,/var/log/mysql.err,/var/log/mysql/error.log]
|
log: [/var/log/mysql.log,/var/log/mysql.err,/var/log/mysql/error.log]
|
||||||
actual_systemd_service: mariadb
|
actual_systemd_service: mariadb
|
||||||
category: database
|
category: database
|
||||||
|
ignore_if_package_is_not_installed: mariadb-server
|
||||||
nginx:
|
nginx:
|
||||||
log: /var/log/nginx
|
log: /var/log/nginx
|
||||||
test_conf: nginx -t
|
test_conf: nginx -t
|
||||||
needs_exposed_ports: [80, 443]
|
needs_exposed_ports: [80, 443]
|
||||||
category: web
|
category: web
|
||||||
php7.3-fpm:
|
# Yunohost will dynamically add installed php-fpm services (7.3, 7.4, 8.0, ...) in services.py
|
||||||
log: /var/log/php7.3-fpm.log
|
#php7.4-fpm:
|
||||||
test_conf: php-fpm7.3 --test
|
# log: /var/log/php7.4-fpm.log
|
||||||
category: web
|
# test_conf: php-fpm7.4 --test
|
||||||
|
# category: web
|
||||||
postfix:
|
postfix:
|
||||||
log: [/var/log/mail.log,/var/log/mail.err]
|
log: [/var/log/mail.log,/var/log/mail.err]
|
||||||
actual_systemd_service: postfix@-
|
actual_systemd_service: postfix@-
|
||||||
needs_exposed_ports: [25, 587]
|
needs_exposed_ports: [25, 587]
|
||||||
category: email
|
category: email
|
||||||
|
postgresql:
|
||||||
|
actual_systemd_service: 'postgresql@13-main'
|
||||||
|
category: database
|
||||||
|
ignore_if_package_is_not_installed: postgresql-13
|
||||||
redis-server:
|
redis-server:
|
||||||
log: /var/log/redis/redis-server.log
|
log: /var/log/redis/redis-server.log
|
||||||
category: database
|
category: database
|
||||||
|
@ -68,5 +75,6 @@ spamassassin: null
|
||||||
rmilter: null
|
rmilter: null
|
||||||
php5-fpm: null
|
php5-fpm: null
|
||||||
php7.0-fpm: null
|
php7.0-fpm: null
|
||||||
|
php7.3-fpm: null
|
||||||
nslcd: null
|
nslcd: null
|
||||||
avahi-daemon: null
|
avahi-daemon: null
|
|
@ -4,9 +4,7 @@ After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
Environment=DAEMON_OPTS=
|
ExecStart=/usr/bin/yunohost-api
|
||||||
EnvironmentFile=-/etc/default/yunohost-api
|
|
||||||
ExecStart=/usr/bin/yunohost-api $DAEMON_OPTS
|
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
TimeoutStopSec=30
|
TimeoutStopSec=30
|
|
@ -1,8 +0,0 @@
|
||||||
# -*- shell-script -*-
|
|
||||||
|
|
||||||
readonly XTRACE_ENABLE=$(set +o | grep xtrace) # This is a trick to later only restore set -x if it was set when calling this script
|
|
||||||
set +x
|
|
||||||
for helper in $(run-parts --list /usr/share/yunohost/helpers.d 2>/dev/null) ; do
|
|
||||||
[ -r $helper ] && . $helper || true
|
|
||||||
done
|
|
||||||
eval "$XTRACE_ENABLE"
|
|
|
@ -1,109 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Use logrotate to manage the logfile
|
|
||||||
#
|
|
||||||
# usage: ynh_use_logrotate [--logfile=/log/file] [--nonappend] [--specific_user=user/group]
|
|
||||||
# | arg: -l, --logfile= - absolute path of logfile
|
|
||||||
# | arg: -n, --nonappend - (optional) Replace the config file instead of appending this new config.
|
|
||||||
# | arg: -u, --specific_user= - run logrotate as the specified user and group. If not specified logrotate is runned as root.
|
|
||||||
#
|
|
||||||
# If no `--logfile` is provided, `/var/log/$app` will be used as default.
|
|
||||||
# `logfile` can point to a directory or a file.
|
|
||||||
#
|
|
||||||
# It's possible to use this helper multiple times, each config will be added to
|
|
||||||
# the same logrotate config file. Unless you use the option `--non-append`
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
# Requires YunoHost version 3.2.0 or higher for the argument `--specific_user`
|
|
||||||
ynh_use_logrotate() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=lnuya
|
|
||||||
local -A args_array=([l]=logfile= [n]=nonappend [u]=specific_user= [y]=non [a]=append)
|
|
||||||
# [y]=non [a]=append are only for legacy purpose, to not fail on the old option '--non-append'
|
|
||||||
local logfile
|
|
||||||
local nonappend
|
|
||||||
local specific_user
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
logfile="${logfile:-}"
|
|
||||||
nonappend="${nonappend:-0}"
|
|
||||||
specific_user="${specific_user:-}"
|
|
||||||
|
|
||||||
# LEGACY CODE - PRE GETOPTS
|
|
||||||
if [ $# -gt 0 ] && [ "$1" == "--non-append" ]; then
|
|
||||||
nonappend=1
|
|
||||||
# Destroy this argument for the next command.
|
|
||||||
shift
|
|
||||||
elif [ $# -gt 1 ] && [ "$2" == "--non-append" ]; then
|
|
||||||
nonappend=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $# -gt 0 ] && [ "$(echo ${1:0:1})" != "-" ]; then
|
|
||||||
# If the given logfile parameter already exists as a file, or if it ends up with ".log",
|
|
||||||
# we just want to manage a single file
|
|
||||||
if [ -f "$1" ] || [ "$(echo ${1##*.})" == "log" ]; then
|
|
||||||
local logfile=$1
|
|
||||||
# Otherwise we assume we want to manage a directory and all its .log file inside
|
|
||||||
else
|
|
||||||
local logfile=$1/*.log
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# LEGACY CODE
|
|
||||||
|
|
||||||
local customtee="tee --append"
|
|
||||||
if [ "$nonappend" -eq 1 ]; then
|
|
||||||
customtee="tee"
|
|
||||||
fi
|
|
||||||
if [ -n "$logfile" ]; then
|
|
||||||
if [ ! -f "$1" ] && [ "$(echo ${logfile##*.})" != "log" ]; then # Keep only the extension to check if it's a logfile
|
|
||||||
local logfile="$logfile/*.log" # Else, uses the directory and all logfile into it.
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
logfile="/var/log/${app}/*.log" # Without argument, use a defaut directory in /var/log
|
|
||||||
fi
|
|
||||||
local su_directive=""
|
|
||||||
if [[ -n $specific_user ]]; then
|
|
||||||
su_directive=" # Run logorotate as specific user - group
|
|
||||||
su ${specific_user%/*} ${specific_user#*/}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat >./${app}-logrotate <<EOF # Build a config file for logrotate
|
|
||||||
$logfile {
|
|
||||||
# Rotate if the logfile exceeds 100Mo
|
|
||||||
size 100M
|
|
||||||
# Keep 12 old log maximum
|
|
||||||
rotate 12
|
|
||||||
# Compress the logs with gzip
|
|
||||||
compress
|
|
||||||
# Compress the log at the next cycle. So keep always 2 non compressed logs
|
|
||||||
delaycompress
|
|
||||||
# Copy and truncate the log to allow to continue write on it. Instead of move the log.
|
|
||||||
copytruncate
|
|
||||||
# Do not do an error if the log is missing
|
|
||||||
missingok
|
|
||||||
# Not rotate if the log is empty
|
|
||||||
notifempty
|
|
||||||
# Keep old logs in the same dir
|
|
||||||
noolddir
|
|
||||||
$su_directive
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
mkdir --parents $(dirname "$logfile") # Create the log directory, if not exist
|
|
||||||
cat ${app}-logrotate | $customtee /etc/logrotate.d/$app >/dev/null # Append this config to the existing config file, or replace the whole config file (depending on $customtee)
|
|
||||||
|
|
||||||
if ynh_user_exists --username="$app"; then
|
|
||||||
chown $app:$app "$logfile"
|
|
||||||
chmod o-rwx "$logfile"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the app's logrotate config.
|
|
||||||
#
|
|
||||||
# usage: ynh_remove_logrotate
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_remove_logrotate() {
|
|
||||||
if [ -e "/etc/logrotate.d/$app" ]; then
|
|
||||||
rm "/etc/logrotate.d/$app"
|
|
||||||
fi
|
|
||||||
}
|
|
|
@ -1,970 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
YNH_APP_BASEDIR=${YNH_APP_BASEDIR:-$(realpath ..)}
|
|
||||||
|
|
||||||
# Handle script crashes / failures
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# usage:
|
|
||||||
# ynh_exit_properly is used only by the helper ynh_abort_if_errors.
|
|
||||||
# You should not use it directly.
|
|
||||||
# Instead, add to your script:
|
|
||||||
# ynh_clean_setup () {
|
|
||||||
# instructions...
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# This function provide a way to clean some residual of installation that not managed by remove script.
|
|
||||||
#
|
|
||||||
# It prints a warning to inform that the script was failed, and execute the ynh_clean_setup function if used in the app script
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_exit_properly() {
|
|
||||||
local exit_code=$?
|
|
||||||
|
|
||||||
rm -rf "/var/cache/yunohost/download/"
|
|
||||||
|
|
||||||
if [ "$exit_code" -eq 0 ]; then
|
|
||||||
exit 0 # Exit without error if the script ended correctly
|
|
||||||
fi
|
|
||||||
|
|
||||||
trap '' EXIT # Ignore new exit signals
|
|
||||||
# Do not exit anymore if a command fail or if a variable is empty
|
|
||||||
set +o errexit # set +e
|
|
||||||
set +o nounset # set +u
|
|
||||||
|
|
||||||
# Small tempo to avoid the next message being mixed up with other DEBUG messages
|
|
||||||
sleep 0.5
|
|
||||||
|
|
||||||
if type -t ynh_clean_setup >/dev/null; then # Check if the function exist in the app script.
|
|
||||||
ynh_clean_setup # Call the function to do specific cleaning for the app.
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Exit with error status
|
|
||||||
# We don't call ynh_die basically to avoid unecessary 10-ish
|
|
||||||
# debug lines about parsing args and stuff just to exit 1..
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Exits if an error occurs during the execution of the script.
|
|
||||||
#
|
|
||||||
# usage: ynh_abort_if_errors
|
|
||||||
#
|
|
||||||
# This configure the rest of the script execution such that, if an error occurs
|
|
||||||
# or if an empty variable is used, the execution of the script stops immediately
|
|
||||||
# and a call to `ynh_clean_setup` is triggered if it has been defined by your script.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_abort_if_errors() {
|
|
||||||
set -o errexit # set -e; Exit if a command fail
|
|
||||||
set -o nounset # set -u; And if a variable is used unset
|
|
||||||
trap ynh_exit_properly EXIT # Capturing exit signals on shell script
|
|
||||||
}
|
|
||||||
|
|
||||||
# Download, check integrity, uncompress and patch the source from app.src
|
|
||||||
#
|
|
||||||
# usage: ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"]
|
|
||||||
# | arg: -d, --dest_dir= - Directory where to setup sources
|
|
||||||
# | arg: -s, --source_id= - Name of the source, defaults to `app`
|
|
||||||
# | arg: -k, --keep= - Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs/'
|
|
||||||
#
|
|
||||||
# This helper will read `conf/${source_id}.src`, download and install the sources.
|
|
||||||
#
|
|
||||||
# The src file need to contains:
|
|
||||||
# ```
|
|
||||||
# SOURCE_URL=Address to download the app archive
|
|
||||||
# SOURCE_SUM=Control sum
|
|
||||||
# # (Optional) Program to check the integrity (sha256sum, md5sum...). Default: sha256
|
|
||||||
# SOURCE_SUM_PRG=sha256
|
|
||||||
# # (Optional) Archive format. Default: tar.gz
|
|
||||||
# SOURCE_FORMAT=tar.gz
|
|
||||||
# # (Optional) Put false if sources are directly in the archive root. Default: true
|
|
||||||
# # Instead of true, SOURCE_IN_SUBDIR could be the number of sub directories to remove.
|
|
||||||
# SOURCE_IN_SUBDIR=false
|
|
||||||
# # (Optionnal) Name of the local archive (offline setup support). Default: ${src_id}.${src_format}
|
|
||||||
# SOURCE_FILENAME=example.tar.gz
|
|
||||||
# # (Optional) If it set as false don't extract the source. Default: true
|
|
||||||
# # (Useful to get a debian package or a python wheel.)
|
|
||||||
# SOURCE_EXTRACT=(true|false)
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# The helper will:
|
|
||||||
# - Check if there is a local source archive in `/opt/yunohost-apps-src/$APP_ID/$SOURCE_FILENAME`
|
|
||||||
# - Download `$SOURCE_URL` if there is no local archive
|
|
||||||
# - Check the integrity with `$SOURCE_SUM_PRG -c --status`
|
|
||||||
# - Uncompress the archive to `$dest_dir`.
|
|
||||||
# - If `$SOURCE_IN_SUBDIR` is true, the first level directory of the archive will be removed.
|
|
||||||
# - If `$SOURCE_IN_SUBDIR` is a numeric value, the N first level directories will be removed.
|
|
||||||
# - Patches named `sources/patches/${src_id}-*.patch` will be applied to `$dest_dir`
|
|
||||||
# - Extra files in `sources/extra_files/$src_id` will be copied to dest_dir
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_setup_source() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=dsk
|
|
||||||
local -A args_array=([d]=dest_dir= [s]=source_id= [k]=keep=)
|
|
||||||
local dest_dir
|
|
||||||
local source_id
|
|
||||||
local keep
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
source_id="${source_id:-app}"
|
|
||||||
keep="${keep:-}"
|
|
||||||
|
|
||||||
local src_file_path="$YNH_APP_BASEDIR/conf/${source_id}.src"
|
|
||||||
|
|
||||||
# Load value from configuration file (see above for a small doc about this file
|
|
||||||
# format)
|
|
||||||
local src_url=$(grep 'SOURCE_URL=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_sum=$(grep 'SOURCE_SUM=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_sumprg=$(grep 'SOURCE_SUM_PRG=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_format=$(grep 'SOURCE_FORMAT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_extract=$(grep 'SOURCE_EXTRACT=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_in_subdir=$(grep 'SOURCE_IN_SUBDIR=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
local src_filename=$(grep 'SOURCE_FILENAME=' "$src_file_path" | cut --delimiter='=' --fields=2-)
|
|
||||||
|
|
||||||
# Default value
|
|
||||||
src_sumprg=${src_sumprg:-sha256sum}
|
|
||||||
src_in_subdir=${src_in_subdir:-true}
|
|
||||||
src_format=${src_format:-tar.gz}
|
|
||||||
src_format=$(echo "$src_format" | tr '[:upper:]' '[:lower:]')
|
|
||||||
src_extract=${src_extract:-true}
|
|
||||||
if [ "$src_filename" = "" ]; then
|
|
||||||
src_filename="${source_id}.${src_format}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# (Unused?) mecanism where one can have the file in a special local cache to not have to download it...
|
|
||||||
local local_src="/opt/yunohost-apps-src/${YNH_APP_ID}/${src_filename}"
|
|
||||||
|
|
||||||
mkdir -p /var/cache/yunohost/download/${YNH_APP_ID}/
|
|
||||||
src_filename="/var/cache/yunohost/download/${YNH_APP_ID}/${src_filename}"
|
|
||||||
|
|
||||||
if test -e "$local_src"; then
|
|
||||||
cp $local_src $src_filename
|
|
||||||
else
|
|
||||||
[ -n "$src_url" ] || ynh_die "Couldn't parse SOURCE_URL from $src_file_path ?"
|
|
||||||
|
|
||||||
# NB. we have to declare the var as local first,
|
|
||||||
# otherwise 'local foo=$(false) || echo 'pwet'" does'nt work
|
|
||||||
# because local always return 0 ...
|
|
||||||
local out
|
|
||||||
# Timeout option is here to enforce the timeout on dns query and tcp connect (c.f. man wget)
|
|
||||||
out=$(wget --tries 3 --no-dns-cache --timeout 900 --no-verbose --output-document=$src_filename $src_url 2>&1) \
|
|
||||||
|| ynh_die --message="$out"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the control sum
|
|
||||||
echo "${src_sum} ${src_filename}" | ${src_sumprg} --check --status \
|
|
||||||
|| ynh_die --message="Corrupt source"
|
|
||||||
|
|
||||||
# Keep files to be backup/restored at the end of the helper
|
|
||||||
# Assuming $dest_dir already exists
|
|
||||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
|
||||||
if [ -n "$keep" ] && [ -e "$dest_dir" ]; then
|
|
||||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
|
||||||
mkdir -p $keep_dir
|
|
||||||
local stuff_to_keep
|
|
||||||
for stuff_to_keep in $keep; do
|
|
||||||
if [ -e "$dest_dir/$stuff_to_keep" ]; then
|
|
||||||
mkdir --parents "$(dirname "$keep_dir/$stuff_to_keep")"
|
|
||||||
cp --archive "$dest_dir/$stuff_to_keep" "$keep_dir/$stuff_to_keep"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract source into the app dir
|
|
||||||
mkdir --parents "$dest_dir"
|
|
||||||
|
|
||||||
if [ -n "${final_path:-}" ] && [ "$dest_dir" == "$final_path" ]; then
|
|
||||||
_ynh_apply_default_permissions $dest_dir
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! "$src_extract"; then
|
|
||||||
mv $src_filename $dest_dir
|
|
||||||
elif [ "$src_format" = "zip" ]; then
|
|
||||||
# Zip format
|
|
||||||
# Using of a temp directory, because unzip doesn't manage --strip-components
|
|
||||||
if $src_in_subdir; then
|
|
||||||
local tmp_dir=$(mktemp --directory)
|
|
||||||
unzip -quo $src_filename -d "$tmp_dir"
|
|
||||||
cp --archive $tmp_dir/*/. "$dest_dir"
|
|
||||||
ynh_secure_remove --file="$tmp_dir"
|
|
||||||
else
|
|
||||||
unzip -quo $src_filename -d "$dest_dir"
|
|
||||||
fi
|
|
||||||
ynh_secure_remove --file="$src_filename"
|
|
||||||
else
|
|
||||||
local strip=""
|
|
||||||
if [ "$src_in_subdir" != "false" ]; then
|
|
||||||
if [ "$src_in_subdir" == "true" ]; then
|
|
||||||
local sub_dirs=1
|
|
||||||
else
|
|
||||||
local sub_dirs="$src_in_subdir"
|
|
||||||
fi
|
|
||||||
strip="--strip-components $sub_dirs"
|
|
||||||
fi
|
|
||||||
if [[ "$src_format" =~ ^tar.gz|tar.bz2|tar.xz$ ]]; then
|
|
||||||
tar --extract --file=$src_filename --directory="$dest_dir" $strip
|
|
||||||
else
|
|
||||||
ynh_die --message="Archive format unrecognized."
|
|
||||||
fi
|
|
||||||
ynh_secure_remove --file="$src_filename"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Apply patches
|
|
||||||
if [ -d "$YNH_APP_BASEDIR/sources/patches/" ]; then
|
|
||||||
local patches_folder=$(realpath $YNH_APP_BASEDIR/sources/patches/)
|
|
||||||
if (($(find $patches_folder -type f -name "${source_id}-*.patch" 2>/dev/null | wc --lines) > "0")); then
|
|
||||||
(
|
|
||||||
cd "$dest_dir"
|
|
||||||
for p in $patches_folder/${source_id}-*.patch; do
|
|
||||||
echo $p
|
|
||||||
patch --strip=1 <$p
|
|
||||||
done
|
|
||||||
) || ynh_die --message="Unable to apply patches"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add supplementary files
|
|
||||||
if test -e "$YNH_APP_BASEDIR/sources/extra_files/${source_id}"; then
|
|
||||||
cp --archive $YNH_APP_BASEDIR/sources/extra_files/$source_id/. "$dest_dir"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Keep files to be backup/restored at the end of the helper
|
|
||||||
# Assuming $dest_dir already exists
|
|
||||||
if [ -n "$keep" ]; then
|
|
||||||
local keep_dir=/var/cache/yunohost/files_to_keep_during_setup_source/${YNH_APP_ID}
|
|
||||||
local stuff_to_keep
|
|
||||||
for stuff_to_keep in $keep; do
|
|
||||||
if [ -e "$keep_dir/$stuff_to_keep" ]; then
|
|
||||||
mkdir --parents "$(dirname "$dest_dir/$stuff_to_keep")"
|
|
||||||
cp --archive "$keep_dir/$stuff_to_keep" "$dest_dir/$stuff_to_keep"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
rm -rf /var/cache/yunohost/files_to_keep_during_setup_source/
|
|
||||||
}
|
|
||||||
|
|
||||||
# Curl abstraction to help with POST requests to local pages (such as installation forms)
|
|
||||||
#
|
|
||||||
# usage: ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...
|
|
||||||
# | arg: page_uri - Path (relative to `$path_url`) of the page where POST data will be sent
|
|
||||||
# | arg: key1=value1 - (Optionnal) POST key and corresponding value
|
|
||||||
# | arg: key2=value2 - (Optionnal) Another POST key and corresponding value
|
|
||||||
# | arg: ... - (Optionnal) More POST keys and values
|
|
||||||
#
|
|
||||||
# example: ynh_local_curl "/install.php?installButton" "foo=$var1" "bar=$var2"
|
|
||||||
#
|
|
||||||
# For multiple calls, cookies are persisted between each call for the same app
|
|
||||||
#
|
|
||||||
# `$domain` and `$path_url` should be defined externally (and correspond to the domain.tld and the /path (of the app?))
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_local_curl() {
|
|
||||||
# Define url of page to curl
|
|
||||||
local local_page=$(ynh_normalize_url_path $1)
|
|
||||||
local full_path=$path_url$local_page
|
|
||||||
|
|
||||||
if [ "${path_url}" == "/" ]; then
|
|
||||||
full_path=$local_page
|
|
||||||
fi
|
|
||||||
|
|
||||||
local full_page_url=https://localhost$full_path
|
|
||||||
|
|
||||||
# Concatenate all other arguments with '&' to prepare POST data
|
|
||||||
local POST_data=""
|
|
||||||
local arg=""
|
|
||||||
for arg in "${@:2}"; do
|
|
||||||
POST_data="${POST_data}${arg}&"
|
|
||||||
done
|
|
||||||
if [ -n "$POST_data" ]; then
|
|
||||||
# Add --data arg and remove the last character, which is an unecessary '&'
|
|
||||||
POST_data="--data ${POST_data::-1}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait untils nginx has fully reloaded (avoid curl fail with http2)
|
|
||||||
sleep 2
|
|
||||||
|
|
||||||
local cookiefile=/tmp/ynh-$app-cookie.txt
|
|
||||||
touch $cookiefile
|
|
||||||
chown root $cookiefile
|
|
||||||
chmod 700 $cookiefile
|
|
||||||
|
|
||||||
# Temporarily enable visitors if needed...
|
|
||||||
local visitors_enabled=$(ynh_permission_has_user "main" "visitors" && echo yes || echo no)
|
|
||||||
if [[ $visitors_enabled == "no" ]]; then
|
|
||||||
ynh_permission_update --permission "main" --add "visitors"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Curl the URL
|
|
||||||
curl --silent --show-error --insecure --location --header "Host: $domain" --resolve $domain:443:127.0.0.1 $POST_data "$full_page_url" --cookie-jar $cookiefile --cookie $cookiefile
|
|
||||||
|
|
||||||
if [[ $visitors_enabled == "no" ]]; then
|
|
||||||
ynh_permission_update --permission "main" --remove "visitors"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a dedicated config file from a template
|
|
||||||
#
|
|
||||||
# usage: ynh_add_config --template="template" --destination="destination"
|
|
||||||
# | arg: -t, --template= - Template config file to use
|
|
||||||
# | arg: -d, --destination= - Destination of the config file
|
|
||||||
#
|
|
||||||
# examples:
|
|
||||||
# ynh_add_config --template=".env" --destination="$final_path/.env"
|
|
||||||
# ynh_add_config --template="../conf/.env" --destination="$final_path/.env"
|
|
||||||
# ynh_add_config --template="/etc/nginx/sites-available/default" --destination="etc/nginx/sites-available/mydomain.conf"
|
|
||||||
#
|
|
||||||
# The template can be by default the name of a file in the conf directory
|
|
||||||
# of a YunoHost Package, a relative path or an absolute path.
|
|
||||||
#
|
|
||||||
# The helper will use the template `template` to generate a config file
|
|
||||||
# `destination` by replacing the following keywords with global variables
|
|
||||||
# that should be defined before calling this helper :
|
|
||||||
# ```
|
|
||||||
# __PATH__ by $path_url
|
|
||||||
# __NAME__ by $app
|
|
||||||
# __NAMETOCHANGE__ by $app
|
|
||||||
# __USER__ by $app
|
|
||||||
# __FINALPATH__ by $final_path
|
|
||||||
# __PHPVERSION__ by $YNH_PHP_VERSION
|
|
||||||
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
|
||||||
# ```
|
|
||||||
# And any dynamic variables that should be defined before calling this helper like:
|
|
||||||
# ```
|
|
||||||
# __DOMAIN__ by $domain
|
|
||||||
# __APP__ by $app
|
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# The helper will verify the checksum and backup the destination file
|
|
||||||
# if it's different before applying the new template.
|
|
||||||
#
|
|
||||||
# And it will calculate and store the destination file checksum
|
|
||||||
# into the app settings when configuration is done.
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_add_config() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=tdv
|
|
||||||
local -A args_array=([t]=template= [d]=destination=)
|
|
||||||
local template
|
|
||||||
local destination
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
local template_path
|
|
||||||
|
|
||||||
if [ -f "$YNH_APP_BASEDIR/conf/$template" ]; then
|
|
||||||
template_path="$YNH_APP_BASEDIR/conf/$template"
|
|
||||||
elif [ -f "$template" ]; then
|
|
||||||
template_path=$template
|
|
||||||
else
|
|
||||||
ynh_die --message="The provided template $template doesn't exist"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ynh_backup_if_checksum_is_different --file="$destination"
|
|
||||||
|
|
||||||
# Make sure to set the permissions before we copy the file
|
|
||||||
# This is to cover a case where an attacker could have
|
|
||||||
# created a file beforehand to have control over it
|
|
||||||
# (cp won't overwrite ownership / modes by default...)
|
|
||||||
touch $destination
|
|
||||||
chown root:root $destination
|
|
||||||
chmod 640 $destination
|
|
||||||
|
|
||||||
cp -f "$template_path" "$destination"
|
|
||||||
|
|
||||||
_ynh_apply_default_permissions $destination
|
|
||||||
|
|
||||||
ynh_replace_vars --file="$destination"
|
|
||||||
|
|
||||||
ynh_store_file_checksum --file="$destination"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Replace variables in a file
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# usage: ynh_replace_vars --file="file"
|
|
||||||
# | arg: -f, --file= - File where to replace variables
|
|
||||||
#
|
|
||||||
# The helper will replace the following keywords with global variables
|
|
||||||
# that should be defined before calling this helper :
|
|
||||||
# __PATH__ by $path_url
|
|
||||||
# __NAME__ by $app
|
|
||||||
# __NAMETOCHANGE__ by $app
|
|
||||||
# __USER__ by $app
|
|
||||||
# __FINALPATH__ by $final_path
|
|
||||||
# __PHPVERSION__ by $YNH_PHP_VERSION
|
|
||||||
# __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH
|
|
||||||
#
|
|
||||||
# And any dynamic variables that should be defined before calling this helper like:
|
|
||||||
# __DOMAIN__ by $domain
|
|
||||||
# __APP__ by $app
|
|
||||||
# __VAR_1__ by $var_1
|
|
||||||
# __VAR_2__ by $var_2
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.1.0 or higher.
|
|
||||||
ynh_replace_vars() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=f
|
|
||||||
local -A args_array=([f]=file=)
|
|
||||||
local file
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
# Replace specific YunoHost variables
|
|
||||||
if test -n "${path_url:-}"; then
|
|
||||||
# path_url_slash_less is path_url, or a blank value if path_url is only '/'
|
|
||||||
local path_url_slash_less=${path_url%/}
|
|
||||||
ynh_replace_string --match_string="__PATH__/" --replace_string="$path_url_slash_less/" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__PATH__" --replace_string="$path_url" --target_file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${app:-}"; then
|
|
||||||
ynh_replace_string --match_string="__NAME__" --replace_string="$app" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__NAMETOCHANGE__" --replace_string="$app" --target_file="$file"
|
|
||||||
ynh_replace_string --match_string="__USER__" --replace_string="$app" --target_file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${final_path:-}"; then
|
|
||||||
ynh_replace_string --match_string="__FINALPATH__" --replace_string="$final_path" --target_file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${YNH_PHP_VERSION:-}"; then
|
|
||||||
ynh_replace_string --match_string="__PHPVERSION__" --replace_string="$YNH_PHP_VERSION" --target_file="$file"
|
|
||||||
fi
|
|
||||||
if test -n "${ynh_node_load_PATH:-}"; then
|
|
||||||
ynh_replace_string --match_string="__YNH_NODE_LOAD_PATH__" --replace_string="$ynh_node_load_PATH" --target_file="$file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Replace others variables
|
|
||||||
|
|
||||||
# List other unique (__ __) variables in $file
|
|
||||||
local uniques_vars=($(grep -oP '__[A-Z0-9]+?[A-Z0-9_]*?[A-Z0-9]*?__' $file | sort --unique | sed "s@__\([^.]*\)__@\L\1@g"))
|
|
||||||
|
|
||||||
# Do the replacement
|
|
||||||
local delimit=@
|
|
||||||
for one_var in "${uniques_vars[@]}"; do
|
|
||||||
# Validate that one_var is indeed defined
|
|
||||||
# -v checks if the variable is defined, for example:
|
|
||||||
# -v FOO tests if $FOO is defined
|
|
||||||
# -v $FOO tests if ${!FOO} is defined
|
|
||||||
# More info: https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash/17538964#comment96392525_17538964
|
|
||||||
[[ -v "${one_var:-}" ]] || ynh_die --message="Variable \$$one_var wasn't initialized when trying to replace __${one_var^^}__ in $file"
|
|
||||||
|
|
||||||
# Escape delimiter in match/replace string
|
|
||||||
match_string="__${one_var^^}__"
|
|
||||||
match_string=${match_string//${delimit}/"\\${delimit}"}
|
|
||||||
replace_string="${!one_var}"
|
|
||||||
replace_string=${replace_string//\\/\\\\}
|
|
||||||
replace_string=${replace_string//${delimit}/"\\${delimit}"}
|
|
||||||
|
|
||||||
# Actually replace (sed is used instead of ynh_replace_string to avoid triggering an epic amount of debug logs)
|
|
||||||
sed --in-place "s${delimit}${match_string}${delimit}${replace_string}${delimit}g" "$file"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get a value from heterogeneous file (yaml, json, php, python...)
|
|
||||||
#
|
|
||||||
# usage: ynh_read_var_in_file --file=PATH --key=KEY
|
|
||||||
# | arg: -f, --file= - the path to the file
|
|
||||||
# | arg: -k, --key= - the key to get
|
|
||||||
#
|
|
||||||
# This helpers match several var affectation use case in several languages
|
|
||||||
# We don't use jq or equivalent to keep comments and blank space in files
|
|
||||||
# This helpers work line by line, it is not able to work correctly
|
|
||||||
# if you have several identical keys in your files
|
|
||||||
#
|
|
||||||
# Example of line this helpers can managed correctly
|
|
||||||
# .yml
|
|
||||||
# title: YunoHost documentation
|
|
||||||
# email: 'yunohost@yunohost.org'
|
|
||||||
# .json
|
|
||||||
# "theme": "colib'ris",
|
|
||||||
# "port": 8102
|
|
||||||
# "some_boolean": false,
|
|
||||||
# "user": null
|
|
||||||
# .ini
|
|
||||||
# some_boolean = On
|
|
||||||
# action = "Clear"
|
|
||||||
# port = 20
|
|
||||||
# .php
|
|
||||||
# $user=
|
|
||||||
# user => 20
|
|
||||||
# .py
|
|
||||||
# USER = 8102
|
|
||||||
# user = 'https://donate.local'
|
|
||||||
# CUSTOM['user'] = 'YunoHost'
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.3 or higher.
|
|
||||||
ynh_read_var_in_file() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=fka
|
|
||||||
local -A args_array=([f]=file= [k]=key= [a]=after=)
|
|
||||||
local file
|
|
||||||
local key
|
|
||||||
local after
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
after="${after:-}"
|
|
||||||
|
|
||||||
[[ -f $file ]] || ynh_die --message="File $file does not exists"
|
|
||||||
|
|
||||||
set +o xtrace # set +x
|
|
||||||
|
|
||||||
# Get the line number after which we search for the variable
|
|
||||||
local line_number=1
|
|
||||||
if [[ -n "$after" ]]; then
|
|
||||||
line_number=$(grep -n $after $file | cut -d: -f1)
|
|
||||||
if [[ -z "$line_number" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local filename="$(basename -- "$file")"
|
|
||||||
local ext="${filename##*.}"
|
|
||||||
local endline=',;'
|
|
||||||
local assign="=>|:|="
|
|
||||||
local comments="#"
|
|
||||||
local string="\"'"
|
|
||||||
if [[ "$ext" =~ ^ini|env|toml|yml|yaml$ ]]; then
|
|
||||||
endline='#'
|
|
||||||
fi
|
|
||||||
if [[ "$ext" =~ ^ini|env$ ]]; then
|
|
||||||
comments="[;#]"
|
|
||||||
fi
|
|
||||||
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
|
|
||||||
comments="//"
|
|
||||||
fi
|
|
||||||
local list='\[\s*['$string']?\w+['$string']?\]'
|
|
||||||
local var_part='^\s*((const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
|
|
||||||
var_part+="[$string]?${key}[$string]?"
|
|
||||||
var_part+='\s*\]?\s*'
|
|
||||||
var_part+="($assign)"
|
|
||||||
var_part+='\s*'
|
|
||||||
|
|
||||||
# Extract the part after assignation sign
|
|
||||||
local expression_with_comment="$(tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL | head -n1)"
|
|
||||||
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
echo YNH_NULL
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove comments if needed
|
|
||||||
local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
|
|
||||||
|
|
||||||
local first_char="${expression:0:1}"
|
|
||||||
if [[ "$first_char" == '"' ]]; then
|
|
||||||
echo "$expression" | grep -m1 -o -P '"\K([^"](\\")?)*[^\\](?=")' | head -n1 | sed 's/\\"/"/g'
|
|
||||||
elif [[ "$first_char" == "'" ]]; then
|
|
||||||
echo "$expression" | grep -m1 -o -P "'\K([^'](\\\\')?)*[^\\\\](?=')" | head -n1 | sed "s/\\\\'/'/g"
|
|
||||||
else
|
|
||||||
echo "$expression"
|
|
||||||
fi
|
|
||||||
set -o xtrace # set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set a value into heterogeneous file (yaml, json, php, python...)
|
|
||||||
#
|
|
||||||
# usage: ynh_write_var_in_file --file=PATH --key=KEY --value=VALUE
|
|
||||||
# | arg: -f, --file= - the path to the file
|
|
||||||
# | arg: -k, --key= - the key to set
|
|
||||||
# | arg: -v, --value= - the value to set
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 4.3 or higher.
|
|
||||||
ynh_write_var_in_file() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=fkva
|
|
||||||
local -A args_array=([f]=file= [k]=key= [v]=value= [a]=after=)
|
|
||||||
local file
|
|
||||||
local key
|
|
||||||
local value
|
|
||||||
local after
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
after="${after:-}"
|
|
||||||
|
|
||||||
[[ -f $file ]] || ynh_die --message="File $file does not exists"
|
|
||||||
|
|
||||||
set +o xtrace # set +x
|
|
||||||
|
|
||||||
# Get the line number after which we search for the variable
|
|
||||||
local line_number=1
|
|
||||||
if [[ -n "$after" ]]; then
|
|
||||||
line_number=$(grep -n $after $file | cut -d: -f1)
|
|
||||||
if [[ -z "$line_number" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
local range="${line_number},\$ "
|
|
||||||
|
|
||||||
local filename="$(basename -- "$file")"
|
|
||||||
local ext="${filename##*.}"
|
|
||||||
local endline=',;'
|
|
||||||
local assign="=>|:|="
|
|
||||||
local comments="#"
|
|
||||||
local string="\"'"
|
|
||||||
if [[ "$ext" =~ ^ini|env|toml|yml|yaml$ ]]; then
|
|
||||||
endline='#'
|
|
||||||
fi
|
|
||||||
if [[ "$ext" =~ ^ini|env$ ]]; then
|
|
||||||
comments="[;#]"
|
|
||||||
fi
|
|
||||||
if [[ "php" == "$ext" ]] || [[ "$ext" == "js" ]]; then
|
|
||||||
comments="//"
|
|
||||||
fi
|
|
||||||
local list='\[\s*['$string']?\w+['$string']?\]'
|
|
||||||
local var_part='^\s*((const|var|let)\s+)?\$?(\w+('$list')*(->|\.|\[))*\s*'
|
|
||||||
var_part+="[$string]?${key}[$string]?"
|
|
||||||
var_part+='\s*\]?\s*'
|
|
||||||
var_part+="($assign)"
|
|
||||||
var_part+='\s*'
|
|
||||||
|
|
||||||
# Extract the part after assignation sign
|
|
||||||
local expression_with_comment="$(tail +$line_number ${file} | grep -i -o -P $var_part'\K.*$' || echo YNH_NULL | head -n1)"
|
|
||||||
if [[ "$expression_with_comment" == "YNH_NULL" ]]; then
|
|
||||||
set -o xtrace # set -x
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove comments if needed
|
|
||||||
local expression="$(echo "$expression_with_comment" | sed "s@${comments}[^$string]*\$@@g" | sed "s@\s*[$endline]*\s*]*\$@@")"
|
|
||||||
endline=${expression_with_comment#"$expression"}
|
|
||||||
endline="$(echo "$endline" | sed 's/\\/\\\\/g')"
|
|
||||||
value="$(echo "$value" | sed 's/\\/\\\\/g')"
|
|
||||||
local first_char="${expression:0:1}"
|
|
||||||
delimiter=$'\001'
|
|
||||||
if [[ "$first_char" == '"' ]]; then
|
|
||||||
# \ and sed is quite complex you need 2 \\ to get one in a sed
|
|
||||||
# So we need \\\\ to go through 2 sed
|
|
||||||
value="$(echo "$value" | sed 's/"/\\\\"/g')"
|
|
||||||
sed -ri "${range}s$delimiter"'(^'"${var_part}"'")([^"]|\\")*("[\s;,]*)(\s*'$comments'.*)?$'$delimiter'\1'"${value}"'"'"${endline}${delimiter}i" ${file}
|
|
||||||
elif [[ "$first_char" == "'" ]]; then
|
|
||||||
# \ and sed is quite complex you need 2 \\ to get one in a sed
|
|
||||||
# However double quotes implies to double \\ to
|
|
||||||
# So we need \\\\\\\\ to go through 2 sed and 1 double quotes str
|
|
||||||
value="$(echo "$value" | sed "s/'/\\\\\\\\'/g")"
|
|
||||||
sed -ri "${range}s$delimiter(^${var_part}')([^']|\\')*('"'[\s,;]*)(\s*'$comments'.*)?$'$delimiter'\1'"${value}'${endline}${delimiter}i" ${file}
|
|
||||||
else
|
|
||||||
if [[ "$value" == *"'"* ]] || [[ "$value" == *'"'* ]] || [[ "$ext" =~ ^php|py|json|js$ ]]; then
|
|
||||||
value='\"'"$(echo "$value" | sed 's/"/\\\\"/g')"'\"'
|
|
||||||
fi
|
|
||||||
if [[ "$ext" =~ ^yaml|yml$ ]]; then
|
|
||||||
value=" $value"
|
|
||||||
fi
|
|
||||||
sed -ri "${range}s$delimiter(^${var_part}).*\$$delimiter\1${value}${endline}${delimiter}i" ${file}
|
|
||||||
fi
|
|
||||||
set -o xtrace # set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Render templates with Jinja2
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# Attention : Variables should be exported before calling this helper to be
|
|
||||||
# accessible inside templates.
|
|
||||||
#
|
|
||||||
# usage: ynh_render_template some_template output_path
|
|
||||||
# | arg: some_template - Template file to be rendered
|
|
||||||
# | arg: output_path - The path where the output will be redirected to
|
|
||||||
ynh_render_template() {
|
|
||||||
local template_path=$1
|
|
||||||
local output_path=$2
|
|
||||||
mkdir -p "$(dirname $output_path)"
|
|
||||||
# Taken from https://stackoverflow.com/a/35009576
|
|
||||||
python3 -c 'import os, sys, jinja2; sys.stdout.write(
|
|
||||||
jinja2.Template(sys.stdin.read()
|
|
||||||
).render(os.environ));' <$template_path >$output_path
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fetch the Debian release codename
|
|
||||||
#
|
|
||||||
# usage: ynh_get_debian_release
|
|
||||||
# | ret: The Debian release codename (i.e. jessie, stretch, ...)
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.7.12 or higher.
|
|
||||||
ynh_get_debian_release() {
|
|
||||||
echo $(lsb_release --codename --short)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create a directory under /tmp
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# Deprecated helper
|
|
||||||
#
|
|
||||||
# usage: ynh_mkdir_tmp
|
|
||||||
# | ret: the created directory path
|
|
||||||
ynh_mkdir_tmp() {
|
|
||||||
ynh_print_warn --message="The helper ynh_mkdir_tmp is deprecated."
|
|
||||||
ynh_print_warn --message="You should use 'mktemp -d' instead and manage permissions \
|
|
||||||
properly with chmod/chown."
|
|
||||||
local TMP_DIR=$(mktemp --directory)
|
|
||||||
|
|
||||||
# Give rights to other users could be a security risk.
|
|
||||||
# But for retrocompatibility we need it. (This helpers is deprecated)
|
|
||||||
chmod 755 $TMP_DIR
|
|
||||||
echo $TMP_DIR
|
|
||||||
}
|
|
||||||
|
|
||||||
_acceptable_path_to_delete() {
|
|
||||||
local file=$1
|
|
||||||
|
|
||||||
local forbidden_paths=$(ls -d / /* /{var,home,usr}/* /etc/{default,sudoers.d,yunohost,cron*})
|
|
||||||
|
|
||||||
# Legacy : A couple apps still have data in /home/$app ...
|
|
||||||
if [[ -n "$app" ]]
|
|
||||||
then
|
|
||||||
forbidden_paths=$(echo "$forbidden_paths" | grep -v "/home/$app")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use realpath to normalize the path ..
|
|
||||||
# i.e convert ///foo//bar//..///baz//// to /foo/baz
|
|
||||||
file=$(realpath --no-symlinks "$file")
|
|
||||||
if [ -z "$file" ] || grep -q -x -F "$file" <<< "$forbidden_paths"; then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Remove a file or a directory securely
|
|
||||||
#
|
|
||||||
# usage: ynh_secure_remove --file=path_to_remove
|
|
||||||
# | arg: -f, --file= - File or directory to remove
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 2.6.4 or higher.
|
|
||||||
ynh_secure_remove() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=f
|
|
||||||
local -A args_array=([f]=file=)
|
|
||||||
local file
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
set +o xtrace # set +x
|
|
||||||
|
|
||||||
if [ $# -ge 2 ]; then
|
|
||||||
ynh_print_warn --message="/!\ Packager ! You provided more than one argument to ynh_secure_remove but it will be ignored... Use this helper with one argument at time."
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "$file" ]]; then
|
|
||||||
ynh_print_warn --message="ynh_secure_remove called with empty argument, ignoring."
|
|
||||||
elif [[ ! -e $file ]]; then
|
|
||||||
ynh_print_info --message="'$file' wasn't deleted because it doesn't exist."
|
|
||||||
elif ! _acceptable_path_to_delete "$file"; then
|
|
||||||
ynh_print_warn --message="Not deleting '$file' because it is not an acceptable path to delete."
|
|
||||||
else
|
|
||||||
rm --recursive "$file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
set -o xtrace # set -x
|
|
||||||
}
|
|
||||||
|
|
||||||
# Extract a key from a plain command output
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# (Deprecated, use --output-as json and jq instead)
|
|
||||||
ynh_get_plain_key() {
|
|
||||||
local prefix="#"
|
|
||||||
local found=0
|
|
||||||
# We call this key_ so that it's not caught as
|
|
||||||
# an info to be redacted by the core
|
|
||||||
local key_=$1
|
|
||||||
shift
|
|
||||||
while read line; do
|
|
||||||
if [[ "$found" == "1" ]]; then
|
|
||||||
[[ "$line" =~ ^${prefix}[^#] ]] && return
|
|
||||||
echo $line
|
|
||||||
elif [[ "$line" =~ ^${prefix}${key_}$ ]]; then
|
|
||||||
if [[ -n "${1:-}" ]]; then
|
|
||||||
prefix+="#"
|
|
||||||
key_=$1
|
|
||||||
shift
|
|
||||||
else
|
|
||||||
found=1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read the value of a key in a ynh manifest file
|
|
||||||
#
|
|
||||||
# usage: ynh_read_manifest --manifest="manifest.json" --key="key"
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
# | arg: -k, --key= - Name of the key to find
|
|
||||||
# | ret: the value associate to that key
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_read_manifest() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=mk
|
|
||||||
local -A args_array=([m]=manifest= [k]=manifest_key=)
|
|
||||||
local manifest
|
|
||||||
local manifest_key
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
if [ ! -e "$manifest" ]; then
|
|
||||||
# If the manifest isn't found, try the common place for backup and restore script.
|
|
||||||
manifest="$YNH_APP_BASEDIR/manifest.json"
|
|
||||||
fi
|
|
||||||
|
|
||||||
jq ".$manifest_key" "$manifest" --raw-output
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read the upstream version from the manifest or `$YNH_APP_MANIFEST_VERSION`
|
|
||||||
#
|
|
||||||
# usage: ynh_app_upstream_version [--manifest="manifest.json"]
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
# | ret: the version number of the upstream app
|
|
||||||
#
|
|
||||||
# If the `manifest` is not specified, the envvar `$YNH_APP_MANIFEST_VERSION` will be used.
|
|
||||||
#
|
|
||||||
# The version number in the manifest is defined by `<upstreamversion>~ynh<packageversion>`.
|
|
||||||
#
|
|
||||||
# For example, if the manifest contains `4.3-2~ynh3` the function will return `4.3-2`
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_app_upstream_version() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=m
|
|
||||||
local -A args_array=([m]=manifest=)
|
|
||||||
local manifest
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
manifest="${manifest:-}"
|
|
||||||
|
|
||||||
if [[ "$manifest" != "" ]] && [[ -e "$manifest" ]]; then
|
|
||||||
version_key_=$(ynh_read_manifest --manifest="$manifest" --manifest_key="version")
|
|
||||||
else
|
|
||||||
version_key_=$YNH_APP_MANIFEST_VERSION
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "${version_key_/~ynh*/}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Read package version from the manifest
|
|
||||||
#
|
|
||||||
# usage: ynh_app_package_version [--manifest="manifest.json"]
|
|
||||||
# | arg: -m, --manifest= - Path of the manifest to read
|
|
||||||
# | ret: the version number of the package
|
|
||||||
#
|
|
||||||
# The version number in the manifest is defined by `<upstreamversion>~ynh<packageversion>`.
|
|
||||||
#
|
|
||||||
# For example, if the manifest contains `4.3-2~ynh3` the function will return `3`
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_app_package_version() {
|
|
||||||
# Declare an array to define the options of this helper.
|
|
||||||
local legacy_args=m
|
|
||||||
local -A args_array=([m]=manifest=)
|
|
||||||
local manifest
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
version_key_=$YNH_APP_MANIFEST_VERSION
|
|
||||||
echo "${version_key_/*~ynh/}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Checks the app version to upgrade with the existing app version and returns:
|
|
||||||
#
|
|
||||||
# usage: ynh_check_app_version_changed
|
|
||||||
# | ret: `UPGRADE_APP` if the upstream version changed, `UPGRADE_PACKAGE` otherwise.
|
|
||||||
#
|
|
||||||
# This helper should be used to avoid an upgrade of an app, or the upstream part
|
|
||||||
# of it, when it's not needed
|
|
||||||
#
|
|
||||||
# You can force an upgrade, even if the package is up to date, with the `--force` (or `-F`) argument :
|
|
||||||
# ```
|
|
||||||
# sudo yunohost app upgrade <appname> --force
|
|
||||||
# ```
|
|
||||||
# Requires YunoHost version 3.5.0 or higher.
|
|
||||||
ynh_check_app_version_changed() {
|
|
||||||
local return_value=${YNH_APP_UPGRADE_TYPE}
|
|
||||||
|
|
||||||
if [ "$return_value" == "UPGRADE_FULL" ] || [ "$return_value" == "UPGRADE_FORCED" ] || [ "$return_value" == "DOWNGRADE_FORCED" ]; then
|
|
||||||
return_value="UPGRADE_APP"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo $return_value
|
|
||||||
}
|
|
||||||
|
|
||||||
# Compare the current package version against another version given as an argument.
|
|
||||||
#
|
|
||||||
# usage: ynh_compare_current_package_version --comparison (lt|le|eq|ne|ge|gt) --version <X~ynhY>
|
|
||||||
# | arg: --comparison - Comparison type. Could be : `lt` (lower than), `le` (lower or equal), `eq` (equal), `ne` (not equal), `ge` (greater or equal), `gt` (greater than)
|
|
||||||
# | arg: --version - The version to compare. Need to be a version in the yunohost package version type (like `2.3.1~ynh4`)
|
|
||||||
# | ret: 0 if the evaluation is true, 1 if false.
|
|
||||||
#
|
|
||||||
# example: ynh_compare_current_package_version --comparison lt --version 2.3.2~ynh1
|
|
||||||
#
|
|
||||||
# This helper is usually used when we need to do some actions only for some old package versions.
|
|
||||||
#
|
|
||||||
# Generally you might probably use it as follow in the upgrade script :
|
|
||||||
# ```
|
|
||||||
# if ynh_compare_current_package_version --comparison lt --version 2.3.2~ynh1
|
|
||||||
# then
|
|
||||||
# # Do something that is needed for the package version older than 2.3.2~ynh1
|
|
||||||
# fi
|
|
||||||
# ```
|
|
||||||
#
|
|
||||||
# Requires YunoHost version 3.8.0 or higher.
|
|
||||||
ynh_compare_current_package_version() {
|
|
||||||
local legacy_args=cv
|
|
||||||
declare -Ar args_array=([c]=comparison= [v]=version=)
|
|
||||||
local version
|
|
||||||
local comparison
|
|
||||||
# Manage arguments with getopts
|
|
||||||
ynh_handle_getopts_args "$@"
|
|
||||||
|
|
||||||
local current_version=$YNH_APP_CURRENT_VERSION
|
|
||||||
|
|
||||||
# Check the syntax of the versions
|
|
||||||
if [[ ! $version =~ '~ynh' ]] || [[ ! $current_version =~ '~ynh' ]]; then
|
|
||||||
ynh_die --message="Invalid argument for version."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check validity of the comparator
|
|
||||||
if [[ ! $comparison =~ (lt|le|eq|ne|ge|gt) ]]; then
|
|
||||||
ynh_die --message="Invalid comparator must be : lt, le, eq, ne, ge, gt"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Return the return value of dpkg --compare-versions
|
|
||||||
dpkg --compare-versions $current_version $comparison $version
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if we should enforce sane default permissions (= disable rwx for 'others')
|
|
||||||
# on file/folders handled with ynh_setup_source and ynh_add_config
|
|
||||||
#
|
|
||||||
# [internal]
|
|
||||||
#
|
|
||||||
# Having a file others-readable or a folder others-executable(=enterable)
|
|
||||||
# is a security risk comparable to "chmod 777"
|
|
||||||
#
|
|
||||||
# Configuration files may contain secrets. Or even just being able to enter a
|
|
||||||
# folder may allow an attacker to do nasty stuff (maybe a file or subfolder has
|
|
||||||
# some write permission enabled for 'other' and the attacker may edit the
|
|
||||||
# content or create files as leverage for priviledge escalation ...)
|
|
||||||
#
|
|
||||||
# The sane default should be to set ownership to $app:$app.
|
|
||||||
# In specific case, you may want to set the ownership to $app:www-data
|
|
||||||
# for example if nginx needs access to static files.
|
|
||||||
#
|
|
||||||
_ynh_apply_default_permissions() {
|
|
||||||
local target=$1
|
|
||||||
|
|
||||||
local ynh_requirement=$(jq -r '.requirements.yunohost' $YNH_APP_BASEDIR/manifest.json | tr -d '>= ')
|
|
||||||
|
|
||||||
if [ -z "$ynh_requirement" ] || [ "$ynh_requirement" == "null" ] || dpkg --compare-versions $ynh_requirement ge 4.2; then
|
|
||||||
chmod o-rwx $target
|
|
||||||
chmod g-w $target
|
|
||||||
chown -R root:root $target
|
|
||||||
if ynh_system_user_exists $app; then
|
|
||||||
chown $app:$app $target
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
. /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
do_pre_regen() {
|
|
||||||
pending_dir=$1
|
|
||||||
|
|
||||||
# If the (legacy) 'from_script' flag is here,
|
|
||||||
# we won't touch anything in the ssh config.
|
|
||||||
[[ ! -f /etc/yunohost/from_script ]] || return 0
|
|
||||||
|
|
||||||
cd /usr/share/yunohost/templates/ssh
|
|
||||||
|
|
||||||
# do not listen to IPv6 if unavailable
|
|
||||||
[[ -f /proc/net/if_inet6 ]] && ipv6_enabled=true || ipv6_enabled=false
|
|
||||||
|
|
||||||
ssh_keys=$(ls /etc/ssh/ssh_host_{ed25519,rsa,ecdsa}_key 2>/dev/null || true)
|
|
||||||
|
|
||||||
# Support legacy setting (this setting might be disabled by a user during a migration)
|
|
||||||
if [[ "$(yunohost settings get 'service.ssh.allow_deprecated_dsa_hostkey')" == "True" ]]; then
|
|
||||||
ssh_keys="$ssh_keys $(ls /etc/ssh/ssh_host_dsa_key 2>/dev/null || true)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Support different strategy for security configurations
|
|
||||||
export compatibility="$(yunohost settings get 'security.ssh.compatibility')"
|
|
||||||
export port="$(yunohost settings get 'security.ssh.port')"
|
|
||||||
export ssh_keys
|
|
||||||
export ipv6_enabled
|
|
||||||
ynh_render_template "sshd_config" "${pending_dir}/etc/ssh/sshd_config"
|
|
||||||
}
|
|
||||||
|
|
||||||
do_post_regen() {
|
|
||||||
regen_conf_files=$1
|
|
||||||
|
|
||||||
# If the (legacy) 'from_script' flag is here,
|
|
||||||
# we won't touch anything in the ssh config.
|
|
||||||
[[ ! -f /etc/yunohost/from_script ]] || return 0
|
|
||||||
|
|
||||||
# If no file changed, there's nothing to do
|
|
||||||
[[ -n "$regen_conf_files" ]] || return 0
|
|
||||||
|
|
||||||
# Enforce permissions for /etc/ssh/sshd_config
|
|
||||||
chown root:root "/etc/ssh/sshd_config"
|
|
||||||
chmod 644 "/etc/ssh/sshd_config"
|
|
||||||
|
|
||||||
systemctl restart ssh
|
|
||||||
}
|
|
||||||
|
|
||||||
do_$1_regen ${@:2}
|
|
|
@ -1,56 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
do_pre_regen() {
|
|
||||||
pending_dir=$1
|
|
||||||
|
|
||||||
mkdir --parents "${pending_dir}/etc/apt/preferences.d"
|
|
||||||
|
|
||||||
packages_to_refuse_from_sury="php php-fpm php-mysql php-xml php-zip php-mbstring php-ldap php-gd php-curl php-bz2 php-json php-sqlite3 php-intl openssl libssl1.1 libssl-dev"
|
|
||||||
for package in $packages_to_refuse_from_sury; do
|
|
||||||
echo "
|
|
||||||
Package: $package
|
|
||||||
Pin: origin \"packages.sury.org\"
|
|
||||||
Pin-Priority: -1" >>"${pending_dir}/etc/apt/preferences.d/extra_php_version"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "
|
|
||||||
|
|
||||||
# PLEASE READ THIS WARNING AND DON'T EDIT THIS FILE
|
|
||||||
|
|
||||||
# You are probably reading this file because you tried to install apache2 or
|
|
||||||
# bind9. These 2 packages conflict with YunoHost.
|
|
||||||
|
|
||||||
# Installing apache2 will break nginx and break the entire YunoHost ecosystem
|
|
||||||
# on your server, therefore don't remove those lines!
|
|
||||||
|
|
||||||
# You have been warned.
|
|
||||||
|
|
||||||
Package: apache2
|
|
||||||
Pin: release *
|
|
||||||
Pin-Priority: -1
|
|
||||||
|
|
||||||
Package: apache2-bin
|
|
||||||
Pin: release *
|
|
||||||
Pin-Priority: -1
|
|
||||||
|
|
||||||
# Also bind9 will conflict with dnsmasq.
|
|
||||||
# Same story as for apache2.
|
|
||||||
# Don't install it, don't remove those lines.
|
|
||||||
|
|
||||||
Package: bind9
|
|
||||||
Pin: release *
|
|
||||||
Pin-Priority: -1
|
|
||||||
" >>"${pending_dir}/etc/apt/preferences.d/ban_packages"
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
do_post_regen() {
|
|
||||||
regen_conf_files=$1
|
|
||||||
|
|
||||||
# Make sure php7.3 is the default version when using php in cli
|
|
||||||
update-alternatives --set php /usr/bin/php7.3
|
|
||||||
}
|
|
||||||
|
|
||||||
do_$1_regen ${@:2}
|
|
|
@ -1,81 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
. /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
do_pre_regen() {
|
|
||||||
pending_dir=$1
|
|
||||||
|
|
||||||
cd /usr/share/yunohost/templates/postfix
|
|
||||||
|
|
||||||
postfix_dir="${pending_dir}/etc/postfix"
|
|
||||||
mkdir -p "$postfix_dir"
|
|
||||||
|
|
||||||
default_dir="${pending_dir}/etc/default/"
|
|
||||||
mkdir -p "$default_dir"
|
|
||||||
|
|
||||||
# install plain conf files
|
|
||||||
cp plain/* "$postfix_dir"
|
|
||||||
|
|
||||||
# prepare main.cf conf file
|
|
||||||
main_domain=$(cat /etc/yunohost/current_host)
|
|
||||||
|
|
||||||
# Support different strategy for security configurations
|
|
||||||
export compatibility="$(yunohost settings get 'security.postfix.compatibility')"
|
|
||||||
|
|
||||||
# Add possibility to specify a relay
|
|
||||||
# Could be useful with some isp with no 25 port open or more complex setup
|
|
||||||
export relay_port=""
|
|
||||||
export relay_user=""
|
|
||||||
export relay_host="$(yunohost settings get 'smtp.relay.host')"
|
|
||||||
if [ -n "${relay_host}" ]; then
|
|
||||||
relay_port="$(yunohost settings get 'smtp.relay.port')"
|
|
||||||
relay_user="$(yunohost settings get 'smtp.relay.user')"
|
|
||||||
relay_password="$(yunohost settings get 'smtp.relay.password')"
|
|
||||||
|
|
||||||
# Avoid to display "Relay account paswword" to other users
|
|
||||||
touch ${postfix_dir}/sasl_passwd
|
|
||||||
chmod 750 ${postfix_dir}/sasl_passwd
|
|
||||||
# Avoid "postmap: warning: removing zero-length database file"
|
|
||||||
chown postfix ${pending_dir}/etc/postfix
|
|
||||||
chown postfix ${pending_dir}/etc/postfix/sasl_passwd
|
|
||||||
|
|
||||||
cat <<<"[${relay_host}]:${relay_port} ${relay_user}:${relay_password}" >${postfix_dir}/sasl_passwd
|
|
||||||
postmap ${postfix_dir}/sasl_passwd
|
|
||||||
fi
|
|
||||||
export main_domain
|
|
||||||
export domain_list="$YNH_DOMAINS"
|
|
||||||
ynh_render_template "main.cf" "${postfix_dir}/main.cf"
|
|
||||||
|
|
||||||
cat postsrsd \
|
|
||||||
| sed "s/{{ main_domain }}/${main_domain}/g" \
|
|
||||||
| sed "s/{{ domain_list }}/${YNH_DOMAINS}/g" \
|
|
||||||
>"${default_dir}/postsrsd"
|
|
||||||
|
|
||||||
# adapt it for IPv4-only hosts
|
|
||||||
ipv6="$(yunohost settings get 'smtp.allow_ipv6')"
|
|
||||||
if [ "$ipv6" == "False" ] || [ ! -f /proc/net/if_inet6 ]; then
|
|
||||||
sed -i \
|
|
||||||
's/ \[::ffff:127.0.0.0\]\/104 \[::1\]\/128//g' \
|
|
||||||
"${postfix_dir}/main.cf"
|
|
||||||
sed -i \
|
|
||||||
's/inet_interfaces = all/&\ninet_protocols = ipv4/' \
|
|
||||||
"${postfix_dir}/main.cf"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
do_post_regen() {
|
|
||||||
regen_conf_files=$1
|
|
||||||
|
|
||||||
if [ -e /etc/postfix/sasl_passwd ]; then
|
|
||||||
chmod 750 /etc/postfix/sasl_passwd*
|
|
||||||
chown postfix:root /etc/postfix/sasl_passwd*
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ -z "$regen_conf_files" ]] \
|
|
||||||
|| { systemctl restart postfix && systemctl restart postsrsd; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
do_$1_regen ${@:2}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Exit hook on subcommand error or unset variable
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
# Source YNH helpers
|
|
||||||
source /usr/share/yunohost/helpers
|
|
||||||
|
|
||||||
ynh_restore_file --origin_path="/home/yunohost.multimedia" --not_mandatory
|
|
|
@ -1,55 +0,0 @@
|
||||||
version = "1.0"
|
|
||||||
i18n = "domain_config"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Other things we may want to implement in the future:
|
|
||||||
#
|
|
||||||
# - maindomain handling
|
|
||||||
# - default app
|
|
||||||
# - autoredirect www in nginx conf
|
|
||||||
# - ?
|
|
||||||
#
|
|
||||||
|
|
||||||
[feature]
|
|
||||||
|
|
||||||
[feature.mail]
|
|
||||||
#services = ['postfix', 'dovecot']
|
|
||||||
|
|
||||||
[feature.mail.features_disclaimer]
|
|
||||||
type = "alert"
|
|
||||||
style = "warning"
|
|
||||||
icon = "warning"
|
|
||||||
|
|
||||||
[feature.mail.mail_out]
|
|
||||||
type = "boolean"
|
|
||||||
default = 1
|
|
||||||
|
|
||||||
[feature.mail.mail_in]
|
|
||||||
type = "boolean"
|
|
||||||
default = 1
|
|
||||||
|
|
||||||
#[feature.mail.backup_mx]
|
|
||||||
#type = "tags"
|
|
||||||
#default = []
|
|
||||||
#pattern.regexp = '^([^\W_A-Z]+([-]*[^\W_A-Z]+)*\.)+((xn--)?[^\W_]{2,})$'
|
|
||||||
#pattern.error = "pattern_error"
|
|
||||||
|
|
||||||
[feature.xmpp]
|
|
||||||
|
|
||||||
[feature.xmpp.xmpp]
|
|
||||||
type = "boolean"
|
|
||||||
default = 0
|
|
||||||
|
|
||||||
[dns]
|
|
||||||
|
|
||||||
[dns.registrar]
|
|
||||||
optional = true
|
|
||||||
|
|
||||||
# This part is automatically generated in DomainConfigPanel
|
|
||||||
|
|
||||||
# [dns.advanced]
|
|
||||||
#
|
|
||||||
# [dns.advanced.ttl]
|
|
||||||
# type = "number"
|
|
||||||
# min = 0
|
|
||||||
# default = 3600
|
|
Binary file not shown.
|
@ -1,75 +0,0 @@
|
||||||
VirtualHost "{{ domain }}"
|
|
||||||
enable = true
|
|
||||||
ssl = {
|
|
||||||
key = "/etc/yunohost/certs/{{ domain }}/key.pem";
|
|
||||||
certificate = "/etc/yunohost/certs/{{ domain }}/crt.pem";
|
|
||||||
}
|
|
||||||
authentication = "ldap2"
|
|
||||||
ldap = {
|
|
||||||
hostname = "localhost",
|
|
||||||
user = {
|
|
||||||
basedn = "ou=users,dc=yunohost,dc=org",
|
|
||||||
filter = "(&(objectClass=posixAccount)(mail=*@{{ domain }})(permission=cn=xmpp.main,ou=permission,dc=yunohost,dc=org))",
|
|
||||||
usernamefield = "mail",
|
|
||||||
namefield = "cn",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Discovery items
|
|
||||||
disco_items = {
|
|
||||||
{ "muc.{{ domain }}" },
|
|
||||||
{ "pubsub.{{ domain }}" },
|
|
||||||
{ "jabber.{{ domain }}" },
|
|
||||||
{ "vjud.{{ domain }}" },
|
|
||||||
{ "xmpp-upload.{{ domain }}" },
|
|
||||||
};
|
|
||||||
|
|
||||||
-- contact_info = {
|
|
||||||
-- abuse = { "mailto:abuse@{{ domain }}", "xmpp:admin@{{ domain }}" };
|
|
||||||
-- admin = { "mailto:root@{{ domain }}", "xmpp:admin@{{ domain }}" };
|
|
||||||
-- };
|
|
||||||
|
|
||||||
------ Components ------
|
|
||||||
-- You can specify components to add hosts that provide special services,
|
|
||||||
-- like multi-user conferences, and transports.
|
|
||||||
|
|
||||||
---Set up a MUC (multi-user chat) room server
|
|
||||||
Component "muc.{{ domain }}" "muc"
|
|
||||||
name = "{{ domain }} Chatrooms"
|
|
||||||
|
|
||||||
modules_enabled = {
|
|
||||||
"muc_limits";
|
|
||||||
"muc_log";
|
|
||||||
"muc_log_mam";
|
|
||||||
"muc_log_http";
|
|
||||||
"muc_vcard";
|
|
||||||
}
|
|
||||||
|
|
||||||
muc_event_rate = 0.5
|
|
||||||
muc_burst_factor = 10
|
|
||||||
room_default_config = {
|
|
||||||
logging = true,
|
|
||||||
persistent = true
|
|
||||||
};
|
|
||||||
|
|
||||||
---Set up a PubSub server
|
|
||||||
Component "pubsub.{{ domain }}" "pubsub"
|
|
||||||
name = "{{ domain }} Publish/Subscribe"
|
|
||||||
|
|
||||||
unrestricted_node_creation = true -- Anyone can create a PubSub node (from any server)
|
|
||||||
|
|
||||||
---Set up a HTTP Upload service
|
|
||||||
Component "xmpp-upload.{{ domain }}" "http_upload"
|
|
||||||
name = "{{ domain }} Sharing Service"
|
|
||||||
|
|
||||||
http_file_path = "/var/xmpp-upload/{{ domain }}/upload"
|
|
||||||
http_external_url = "https://xmpp-upload.{{ domain }}:443"
|
|
||||||
http_file_base_path = "/upload"
|
|
||||||
http_file_size_limit = 6*1024*1024
|
|
||||||
http_file_quota = 60*1024*1024
|
|
||||||
http_upload_file_size_limit = 100 * 1024 * 1024 -- bytes
|
|
||||||
http_upload_quota = 10 * 1024 * 1024 * 1024 -- bytes
|
|
||||||
|
|
||||||
---Set up a VJUD service
|
|
||||||
Component "vjud.{{ domain }}" "vjud"
|
|
||||||
vjud_disco_name = "{{ domain }} User Directory"
|
|
|
@ -1,123 +0,0 @@
|
||||||
-- ** Metronome's config file example **
|
|
||||||
--
|
|
||||||
-- The format is exactly equal to Prosody's:
|
|
||||||
--
|
|
||||||
-- Lists are written { "like", "this", "one" }
|
|
||||||
-- Lists can also be of { 1, 2, 3 } numbers, etc.
|
|
||||||
-- Either commas, or semi-colons; may be used as seperators.
|
|
||||||
--
|
|
||||||
-- A table is a list of values, except each value has a name. An
|
|
||||||
-- example would be:
|
|
||||||
--
|
|
||||||
-- ssl = { key = "keyfile.key", certificate = "certificate.cert" }
|
|
||||||
--
|
|
||||||
-- Tip: You can check that the syntax of this file is correct when you have finished
|
|
||||||
-- by running: luac -p metronome.cfg.lua
|
|
||||||
-- If there are any errors, it will let you know what and where they are, otherwise it
|
|
||||||
-- will keep quiet.
|
|
||||||
|
|
||||||
-- Global settings go in this section
|
|
||||||
|
|
||||||
-- This is the list of modules Metronome will load on startup.
|
|
||||||
-- It looks for mod_modulename.lua in the plugins folder, so make sure that exists too.
|
|
||||||
|
|
||||||
modules_enabled = {
|
|
||||||
-- Generally required
|
|
||||||
"roster"; -- Allow users to have a roster. Recommended.
|
|
||||||
"saslauth"; -- Authentication for clients. Recommended if you want to log in.
|
|
||||||
"tls"; -- Add support for secure TLS on c2s/s2s connections
|
|
||||||
"disco"; -- Service discovery
|
|
||||||
|
|
||||||
-- Not essential, but recommended
|
|
||||||
"private"; -- Private XML storage (for room bookmarks, etc.)
|
|
||||||
"vcard"; -- Allow users to set vCards
|
|
||||||
"pep"; -- Allows setting of mood, tune, etc.
|
|
||||||
"pubsub"; -- Publish-subscribe XEP-0060
|
|
||||||
"posix"; -- POSIX functionality, sends server to background, enables syslog, etc.
|
|
||||||
"bidi"; -- Enables Bidirectional Server-to-Server Streams.
|
|
||||||
|
|
||||||
-- Nice to have
|
|
||||||
"version"; -- Replies to server version requests
|
|
||||||
"uptime"; -- Report how long server has been running
|
|
||||||
"time"; -- Let others know the time here on this server
|
|
||||||
"ping"; -- Replies to XMPP pings with pongs
|
|
||||||
"register"; -- Allow users to register on this server using a client and change passwords
|
|
||||||
"stream_management"; -- Allows clients and servers to use Stream Management
|
|
||||||
"stanza_optimizations"; -- Allows clients to use Client State Indication and SIFT
|
|
||||||
"message_carbons"; -- Allows clients to enable carbon copies of messages
|
|
||||||
"mam"; -- Enable server-side message archives using Message Archive Management
|
|
||||||
"push"; -- Enable Push Notifications via PubSub using XEP-0357
|
|
||||||
"lastactivity"; -- Enables clients to know the last presence status of an user
|
|
||||||
"adhoc_cm"; -- Allow to set client certificates to login through SASL External via adhoc
|
|
||||||
"admin_adhoc"; -- administration adhoc commands
|
|
||||||
"bookmarks"; -- XEP-0048 Bookmarks synchronization between PEP and Private Storage
|
|
||||||
"sec_labels"; -- Allows to use a simplified version XEP-0258 Security Labels and related ACDFs.
|
|
||||||
"privacy"; -- Add privacy lists and simple blocking command support
|
|
||||||
|
|
||||||
-- Other specific functionality
|
|
||||||
--"admin_telnet"; -- administration console, telnet to port 5582
|
|
||||||
--"admin_web"; -- administration web interface
|
|
||||||
"bosh"; -- Enable support for BOSH clients, aka "XMPP over Bidirectional Streams over Synchronous HTTP"
|
|
||||||
--"compression"; -- Allow clients to enable Stream Compression
|
|
||||||
--"spim_block"; -- Require authorization via OOB form for messages from non-contacts and block unsollicited messages
|
|
||||||
--"gate_guard"; -- Enable config-based blacklisting and hit-based auto-banning features
|
|
||||||
--"incidents_handling"; -- Enable Incidents Handling support (can be administered via adhoc commands)
|
|
||||||
--"server_presence"; -- Enables Server Buddies extension support
|
|
||||||
--"service_directory"; -- Enables Service Directories extension support
|
|
||||||
--"public_service"; -- Enables Server vCard support for public services in directories and advertises in features
|
|
||||||
--"register_api"; -- Provides secure API for both Out-Of-Band and In-Band registration for E-Mail verification
|
|
||||||
"websocket"; -- Enable support for WebSocket clients, aka "XMPP over WebSockets"
|
|
||||||
};
|
|
||||||
|
|
||||||
-- Server PID
|
|
||||||
pidfile = "/var/run/metronome/metronome.pid"
|
|
||||||
|
|
||||||
-- HTTP server
|
|
||||||
http_ports = { 5290 }
|
|
||||||
http_interfaces = { "127.0.0.1", "::1" }
|
|
||||||
|
|
||||||
--https_ports = { 5291 }
|
|
||||||
--https_interfaces = { "127.0.0.1", "::1" }
|
|
||||||
|
|
||||||
-- Enable IPv6
|
|
||||||
use_ipv6 = true
|
|
||||||
|
|
||||||
-- BOSH configuration (mod_bosh)
|
|
||||||
consider_bosh_secure = true
|
|
||||||
cross_domain_bosh = true
|
|
||||||
|
|
||||||
-- WebSocket configuration (mod_websocket)
|
|
||||||
consider_websocket_secure = true
|
|
||||||
cross_domain_websocket = true
|
|
||||||
|
|
||||||
-- Disable account creation by default, for security
|
|
||||||
allow_registration = false
|
|
||||||
|
|
||||||
-- Use LDAP storage backend for all stores
|
|
||||||
storage = "ldap"
|
|
||||||
|
|
||||||
-- stanza optimization
|
|
||||||
csi_config_queue_all_muc_messages_but_mentions = false;
|
|
||||||
|
|
||||||
|
|
||||||
-- Logging configuration
|
|
||||||
log = {
|
|
||||||
info = "/var/log/metronome/metronome.log"; -- Change 'info' to 'debug' for verbose logging
|
|
||||||
error = "/var/log/metronome/metronome.err";
|
|
||||||
-- "*syslog"; -- Uncomment this for logging to syslog
|
|
||||||
-- "*console"; -- Log to the console, useful for debugging with daemonize=false
|
|
||||||
}
|
|
||||||
|
|
||||||
------ Components ------
|
|
||||||
-- You can specify components to add hosts that provide special services,
|
|
||||||
-- like multi-user conferences, and transports.
|
|
||||||
|
|
||||||
---Set up a local BOSH service
|
|
||||||
Component "localhost" "http"
|
|
||||||
modules_enabled = { "bosh" }
|
|
||||||
|
|
||||||
----------- Virtual hosts -----------
|
|
||||||
-- You need to add a VirtualHost entry for each domain you wish Metronome to serve.
|
|
||||||
-- Settings under each VirtualHost entry apply *only* to that host.
|
|
||||||
|
|
||||||
Include "conf.d/*.cfg.lua"
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue