Compare commits
240 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3670ad2fb8 | ||
|
|
062f57f002 | ||
|
|
0b49050521 | ||
|
|
62c80d3cac | ||
|
|
a86c629d64 | ||
|
|
085e2db3d9 | ||
|
|
327ee22307 | ||
|
|
10e004a92d | ||
|
|
0c186bea29 | ||
|
|
fc3991a9cd | ||
|
|
377831b972 | ||
|
|
afedea4c72 | ||
|
|
944c8c4ea9 | ||
|
|
e4e95c3bbc | ||
|
|
7cd3eabdd6 | ||
|
|
95daece6a3 | ||
|
|
3323912c61 | ||
|
|
0570e3965e | ||
|
|
f423949bff | ||
|
|
659e102935 | ||
|
|
3375aca7dd | ||
|
|
b2e855ec52 | ||
|
|
214bb03a2b | ||
|
|
a49cfccc7b | ||
|
|
b1a1c11676 | ||
|
|
3bcd083837 | ||
|
|
4cec73c7b8 | ||
|
|
fe793698e7 | ||
|
|
bd098de313 | ||
|
|
0743bd7c21 | ||
|
|
eaa8a1edeb | ||
|
|
95aacc7847 | ||
|
|
b192910a2f | ||
|
|
1928ec8190 | ||
|
|
e6bbd483cc | ||
|
|
b2a60e2041 | ||
|
|
415024b1e2 | ||
|
|
20e321d930 | ||
|
|
3cf6b608b2 | ||
|
|
772b8ca89d | ||
|
|
5230067d82 | ||
|
|
8dbe494b87 | ||
|
|
f25b0182d2 | ||
|
|
4c347b9156 | ||
|
|
b09641641c | ||
|
|
4fe0e733a2 | ||
|
|
f43a0ecd41 | ||
|
|
35dda1c9e0 | ||
|
|
710b3818f1 | ||
|
|
2c9b66e5f3 | ||
|
|
fe73a237ae | ||
|
|
f597db2f1b | ||
|
|
f3af39896c | ||
|
|
a30097bdde | ||
|
|
ed41ec6415 | ||
|
|
4e3e17fbd7 | ||
|
|
2470dcb124 | ||
|
|
7b02f7c360 | ||
|
|
13d2ca6f78 | ||
|
|
ba77217235 | ||
|
|
cdd6d82a45 | ||
|
|
9483b81767 | ||
|
|
9f7ab04cda | ||
|
|
be076f9a89 | ||
|
|
c5dca12cb2 | ||
|
|
556e9f5228 | ||
|
|
46eaa93de9 | ||
|
|
dd9ea8df75 | ||
|
|
fcd691ad97 | ||
|
|
03499c491c | ||
|
|
c270ab3713 | ||
|
|
50b1da8a00 | ||
|
|
a24300b7a5 | ||
|
|
9ccbd7b7a3 | ||
|
|
ee35c0d9b8 | ||
|
|
6b52b102c8 | ||
|
|
878887361a | ||
|
|
fa3bc5e596 | ||
|
|
8d46c1de76 | ||
|
|
4b0af17cec | ||
|
|
7c39ab53ed | ||
|
|
9438004c9d | ||
|
|
1f5fcf8c29 | ||
|
|
0197cf898e | ||
|
|
00e14bd3c8 | ||
|
|
0cff1f8247 | ||
|
|
ca82cd5aec | ||
|
|
959749d6ed | ||
|
|
7efb910719 | ||
|
|
a4100b50ae | ||
|
|
c695fe2a87 | ||
|
|
91a31bfa00 | ||
|
|
d82f7e47ad | ||
|
|
46bd227b90 | ||
|
|
254722f3ad | ||
|
|
1c9f036a1b | ||
|
|
fe1ca24a49 | ||
|
|
c6451a9429 | ||
|
|
6fe8a5d533 | ||
|
|
cd332a8691 | ||
|
|
fcd5c71820 | ||
|
|
c387f0fcea | ||
|
|
dc984b0ea1 | ||
|
|
aa98abafc2 | ||
|
|
f1de7f880e | ||
|
|
f46ea7746f | ||
|
|
57fbd7d483 | ||
|
|
eec8d0aa38 | ||
|
|
ac7426e879 | ||
|
|
186ffd1f45 | ||
|
|
648df8b9cb | ||
|
|
8dc4c9d234 | ||
|
|
46b3729639 | ||
|
|
95b5de700e | ||
|
|
832618477e | ||
|
|
92ebbee242 | ||
|
|
6e0d51d735 | ||
|
|
578676d121 | ||
|
|
3455c65959 | ||
|
|
c63fa89e23 | ||
|
|
a11a6ad68d | ||
|
|
dfd6229f3f | ||
|
|
e2bf73a78b | ||
|
|
2ba6477d90 | ||
|
|
fe1df17b65 | ||
|
|
0e7c402b82 | ||
|
|
474a2f26ad | ||
|
|
7712fb8066 | ||
|
|
2344c6027e | ||
|
|
a2ad2990ea | ||
|
|
ff117e8b95 | ||
|
|
34df27de8f | ||
|
|
84e299e4dd | ||
|
|
f2783a04b3 | ||
|
|
0e15bc856d | ||
|
|
29c0dac564 | ||
|
|
c24858ce59 | ||
|
|
4cbeea381d | ||
|
|
6d020b4c2a | ||
|
|
b0afee7b64 | ||
|
|
7a7187deef | ||
|
|
ce0e30b50c | ||
|
|
642e98cc12 | ||
|
|
dcceb61730 | ||
|
|
00e72634da | ||
|
|
59cf0d11ac | ||
|
|
fc271c8722 | ||
|
|
87c40f3f95 | ||
|
|
9bae0fafc9 | ||
|
|
179c70a4fa | ||
|
|
7543a06f51 | ||
|
|
eb5c9a1650 | ||
|
|
8b00ea6bcb | ||
|
|
c882874383 | ||
|
|
4b18dc7d6a | ||
|
|
db9546f71b | ||
|
|
39007bf56e | ||
|
|
a3d1580c6a | ||
|
|
d16a21758f | ||
|
|
1741ddb98d | ||
|
|
bf2d04f036 | ||
|
|
cc9273a982 | ||
|
|
67ecaa91b5 | ||
|
|
9f526467fe | ||
|
|
8e33c7431e | ||
|
|
8267535a97 | ||
|
|
06f184d1ad | ||
|
|
9af5f1bde9 | ||
|
|
2412ada16a | ||
|
|
f53f798e82 | ||
|
|
0899bc6609 | ||
|
|
8663b11112 | ||
|
|
755d019a65 | ||
|
|
c22971b4e8 | ||
|
|
50a119a98b | ||
|
|
96aaa59114 | ||
|
|
9c3942000e | ||
|
|
3172996a77 | ||
|
|
16dd5a071a | ||
|
|
1e5fe32d2a | ||
|
|
d03bed11e2 | ||
|
|
926b8836ab | ||
|
|
7b09e0fe66 | ||
|
|
8662725918 | ||
|
|
cbb2b84e77 | ||
|
|
2c2f766290 | ||
|
|
cf2b56d658 | ||
|
|
cf39d73cc5 | ||
|
|
67f09f71b2 | ||
|
|
ee0975a1aa | ||
|
|
2f465ca270 | ||
|
|
ab2c6dc1a7 | ||
|
|
76c26f7356 | ||
|
|
b8eef1e161 | ||
|
|
ef1f52560c | ||
|
|
953b784e92 | ||
|
|
00cae794a0 | ||
|
|
280b42dc37 | ||
|
|
31acb88cde | ||
|
|
030111b90c | ||
|
|
3e1e7f7b71 | ||
|
|
215db335a6 | ||
|
|
33a93d7bc2 | ||
|
|
1a44140556 | ||
|
|
82f52e36df | ||
|
|
19281a3883 | ||
|
|
a98cc3fe4f | ||
|
|
8a79d04d8c | ||
|
|
2fc76dbf8b | ||
|
|
511d18c4ae | ||
|
|
16f5887522 | ||
|
|
9cfbe0d129 | ||
|
|
d56cb13d7f | ||
|
|
2b9c85c65d | ||
|
|
5501553cb5 | ||
|
|
5382c5c6e1 | ||
|
|
6b57dd606b | ||
|
|
9e76014bc3 | ||
|
|
f4247ef875 | ||
|
|
fe5f07f20a | ||
|
|
7ca5f50727 | ||
|
|
c8c575dfa1 | ||
|
|
e7daeeaec1 | ||
|
|
2b228c3484 | ||
|
|
79a58b200d | ||
|
|
a7ad61a79b | ||
|
|
fa5a36187b | ||
|
|
f08a8e8686 | ||
|
|
ce93086822 | ||
|
|
16776c07b0 | ||
|
|
4394d81929 | ||
|
|
fd4d1314b3 | ||
|
|
a5319569ef | ||
|
|
7bd456dde5 | ||
|
|
760d5b511f | ||
|
|
8320756645 | ||
|
|
4ab49d3e01 | ||
|
|
9507884e06 | ||
|
|
31de89ece4 | ||
|
|
3c3babc0ce |
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1 +1,5 @@
|
||||
.idea/
|
||||
*.pyc
|
||||
.env/
|
||||
tarballs/
|
||||
VERSIONS.txt
|
||||
documentations/*.md
|
||||
|
||||
170
.gitlab-ci.yml
170
.gitlab-ci.yml
@@ -1,33 +1,161 @@
|
||||
image: docker:latest
|
||||
|
||||
services:
|
||||
- docker:dind
|
||||
- docker:dind
|
||||
|
||||
.parallel:
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: [oldstable, stable, unstable]
|
||||
|
||||
stages:
|
||||
- build_publish
|
||||
- schedule
|
||||
- build
|
||||
- test
|
||||
- release
|
||||
|
||||
before_script:
|
||||
- apk add bash
|
||||
include:
|
||||
- template: Jobs/Code-Quality.gitlab-ci.yml
|
||||
- template: Jobs/SAST.latest.gitlab-ci.yml
|
||||
|
||||
staging:
|
||||
stage: build_publish
|
||||
build:
|
||||
stage: build
|
||||
before_script:
|
||||
- apk add bash git curl jq make
|
||||
script:
|
||||
- /bin/bash utils/publish/staging.sh
|
||||
only:
|
||||
- staging
|
||||
- make build
|
||||
- make save
|
||||
extends: .parallel
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
|
||||
artifacts:
|
||||
paths:
|
||||
- "tarballs/"
|
||||
|
||||
production:
|
||||
stage: build_publish
|
||||
test:
|
||||
stage: test
|
||||
before_script:
|
||||
- apk add bash git curl jq make
|
||||
script:
|
||||
- /bin/bash utils/publish/production.sh
|
||||
only:
|
||||
- tags
|
||||
except:
|
||||
- branches
|
||||
- make load
|
||||
- make build-test
|
||||
- make test
|
||||
extends: .parallel
|
||||
needs:
|
||||
- job: build
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: oldstable
|
||||
- TARGET: stable
|
||||
- TARGET: unstable
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
|
||||
artifacts:
|
||||
paths:
|
||||
- tarballs/
|
||||
|
||||
update_docker_hub_full_description:
|
||||
stage: build_publish
|
||||
publish-images:
|
||||
stage: release
|
||||
before_script:
|
||||
- apk add bash git curl jq make
|
||||
script:
|
||||
- /bin/bash utils/publish/update-docker-hub-full-description.sh
|
||||
only:
|
||||
- master
|
||||
- export
|
||||
- make load
|
||||
- make publish-images
|
||||
needs:
|
||||
- job: build
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: oldstable
|
||||
- TARGET: stable
|
||||
- TARGET: unstable
|
||||
- job: test
|
||||
extends: .parallel
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
|
||||
- when: never
|
||||
artifacts:
|
||||
paths:
|
||||
- tarballs/
|
||||
- versions/*
|
||||
variables:
|
||||
CI_DEBUG_TRACE: "true"
|
||||
|
||||
make-documents:
|
||||
stage: release
|
||||
before_script:
|
||||
- apk add bash git curl jq make py3-jinja2 py3-gitlab
|
||||
script:
|
||||
- make documents
|
||||
needs:
|
||||
- job: publish-images
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: oldstable
|
||||
- TARGET: stable
|
||||
- TARGET: unstable
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
|
||||
- when: never
|
||||
artifacts:
|
||||
paths:
|
||||
- versions/*
|
||||
- documentations/*.md
|
||||
|
||||
publish-documents:
|
||||
stage: release
|
||||
before_script:
|
||||
- apk add bash git curl jq make py3-gitlab
|
||||
script:
|
||||
- make publish-documents
|
||||
needs:
|
||||
- job: make-documents
|
||||
rules:
|
||||
- if: $CI_COMMIT_TAG
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
|
||||
- when: never
|
||||
artifacts:
|
||||
paths:
|
||||
- documentations/*.md
|
||||
|
||||
weekly-build-disable:
|
||||
stage: release
|
||||
needs:
|
||||
- job: publish-documents
|
||||
before_script:
|
||||
- apk add bash git curl jq make py3-requests py3-gitlab
|
||||
script:
|
||||
- make unschedule-weekly-build
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
|
||||
- when: never
|
||||
|
||||
|
||||
weekly-build-scheduler:
|
||||
stage: schedule
|
||||
before_script:
|
||||
- apk add bash git curl jq make py3-requests py3-gitlab
|
||||
script:
|
||||
- make schedule-weekly-build
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build-scheduler"
|
||||
- when: never
|
||||
artifacts:
|
||||
reports:
|
||||
metrics: metrics.txt
|
||||
|
||||
code_quality:
|
||||
rules:
|
||||
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
|
||||
- when: never
|
||||
|
||||
semgrep-sast:
|
||||
rules:
|
||||
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
|
||||
- when: never
|
||||
|
||||
212
CHANGELOG.md
212
CHANGELOG.md
@@ -1,27 +1,223 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
|
||||
<!-- To log a new version, copy, uncomment, add your changes, then add the tag shortcut at the end of the file -->
|
||||
<!-- Unreleased --/>
|
||||
## [Unreleased] - year-month-date
|
||||
### Added
|
||||
### Changed
|
||||
### Deprecated
|
||||
### Removed
|
||||
### Fixed
|
||||
### Security
|
||||
|
||||
[Unreleased]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/Unreleased
|
||||
<!-- /Unreleased /-->
|
||||
|
||||
<!-- 3.4.0 -->
|
||||
## [3.4.0] - 2024-09-24
|
||||
### Added
|
||||
- Explicit project name to mock Docker Compose.
|
||||
### Fixed
|
||||
- Librairies name are formatted to lower case (#75).
|
||||
- Use for $TARGET in mock Docker Compose.
|
||||
- Fix pipeline jobs rules, specifically on Draft MR.
|
||||
|
||||
[3.4.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.4.0
|
||||
<!-- /3.4.0 -->
|
||||
|
||||
|
||||
<!-- 3.3.0 -->
|
||||
## [3..0]
|
||||
### Modified
|
||||
* Add TARGET environment variable to Makefile commands.
|
||||
### Fixed
|
||||
* Fix the TypeError for the skip SSL certificates parameters.
|
||||
|
||||
[3.3.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.3.0
|
||||
<!-- /3.3.0 -->
|
||||
|
||||
<!-- 3.2.5 -->
|
||||
## [3.2.5]
|
||||
### Modified
|
||||
* Use CI/CD environment variables for the Docker Hub short description
|
||||
### Fixed
|
||||
* The file name used for the Docker Hub full description
|
||||
|
||||
[3.2.5]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.5
|
||||
<!-- /3.2.5 -->
|
||||
|
||||
<!-- 3.2.4 -->
|
||||
## [3.2.4]
|
||||
### Added
|
||||
* Publish to the new flrnnc/seafile-client repository.
|
||||
* Write notices regarding the Docker repository move.
|
||||
### Changed
|
||||
* Use new CI/CD variables.
|
||||
* Do not run pipelines on Draft MR. (#69)
|
||||
### Removed
|
||||
* Remove the changelog from the Seafile documentation.
|
||||
|
||||
[3.2.4]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.4
|
||||
<!-- /3.2.4 -->
|
||||
|
||||
|
||||
## [3.2.3] - 2024/06/27
|
||||
### Changed
|
||||
- Update the build badge date on builds. (#61)
|
||||
|
||||
[3.2.3]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.3
|
||||
<!-- /3.2.3 -->
|
||||
|
||||
## [3.2.2] - 2024/06/09
|
||||
### Fixed
|
||||
- Allow the latest tag to be applied to the v9 versions. (#54)
|
||||
- Restricted SAST jobs to approved pipelines. (#58)
|
||||
|
||||
[3.2.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.2
|
||||
<!-- /3.2.2 -->
|
||||
|
||||
## [3.2.1] - 2024/06/09
|
||||
### Added
|
||||
- Merge requests pipeline only runs when merge request has been approved.
|
||||
### Changed
|
||||
- Badges are rendered from the Gitlab project itself, not from code. (#62)
|
||||
|
||||
[3.2.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.1
|
||||
<!-- /3.2.1 -->
|
||||
|
||||
## [3.2.0] - 2024/06/06
|
||||
### Changed
|
||||
- Changed the group _users_ GID from 100 to 90. This allow to use the GID 100. (#64)
|
||||
|
||||
[3.2.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.0
|
||||
<!-- /3.2.0 -->
|
||||
|
||||
## [3.1.0] - 2024/06/02
|
||||
### Changed
|
||||
- Disable pipelines on approved merge requests
|
||||
### Fixed
|
||||
- Instanciate the RPC client at the initialization (#63)
|
||||
|
||||
[3.1.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.1.0
|
||||
<!-- /3.1.0 -->
|
||||
|
||||
## [3.0.1] - 2024/05/27
|
||||
### Added
|
||||
* New script to schedule the best possible time to run the build. It relies on WattTime Load Shift feature (#56)
|
||||
* Weekly build through pipeline schedules. (#56)
|
||||
### Changed
|
||||
* Every links pointing to the previous repository flwgns-docker/seafile-client are pointing now to flrnnc-oss/docker-seafile-client. (#56)
|
||||
|
||||
[3.0.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.0.1
|
||||
<!-- /3.0.1 -->
|
||||
|
||||
## [3.0.0] - 2024/03/16
|
||||
### Added
|
||||
- Support for multiple libraries synchronization (#44, #43, #41)
|
||||
- Support for Docker Secrets (#25)
|
||||
- Support for Seafile client's version through Docker tags (#9)
|
||||
- Build documentation with Jinja2 templates (#42)
|
||||
- Manage the project with a Makefile (#38)
|
||||
- Mock Seafile server for testings (#6)
|
||||
### Changed
|
||||
- Revised project layout and workflow (#38, #39)
|
||||
### Fixed
|
||||
- Fixed the Docker Hub description publish through their API (#10)
|
||||
- Add ca-certificates and gnupg to support more HTTP certificates (#24)
|
||||
|
||||
[3.0.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.0.0
|
||||
<!-- /3.0.0 -->
|
||||
|
||||
## [2.2.0] - 2022/08/26
|
||||
- Update from Debian Buster to Debian Bullseye (!7)
|
||||
- Improved Seafile apt source installation (!7)
|
||||
|
||||
## [2.1.1] - 2020/03/10
|
||||
- Prevent re-initialization and re-synchronization of the container if it's life cycle change but is not deleted (#14)
|
||||
## [2.1.0] - 2020/01/30
|
||||
- Replace previous Bash script that parse `seaf-cli status` with a Python script that use pysearpc to run checks (#13)
|
||||
- Implement a workaround to probable issue, waiting for the issue to appear (#14)
|
||||
|
||||
## [2.0.3] - 2020/01/14
|
||||
- Read [the docs](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg) a bit more (#5)
|
||||
## [2.0.2] - 2020/01/14
|
||||
- Propagate the CI_COMMIT_TAG and CI_PROJECT_URL environment variables into the Dockerfile as [the docs states](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg) (#5)
|
||||
## [2.0.1] - 2020/01/14
|
||||
- Update chown path to library, comment chown to an obsolete healthcheck.sh (#11)
|
||||
- Pass $CI_PROJECT_URL to the Dockerfile as a build argument (#5)
|
||||
## [2.0.0] - 2020/01/06
|
||||
- Support 2FA authentication through `oathtool` using the secret key
|
||||
- Support for upload/download limits
|
||||
- Support for Seafile library password
|
||||
- Allow skipping SSL certificates verifications
|
||||
- Drop Bash/supervisord/cron implementations in favor of showing seafile's log
|
||||
- Implement basic integration tests that check expected binairies
|
||||
- Improve continuous integration though splitted jobs
|
||||
- Revise README
|
||||
- Change the volume path from /volume to /library for consistency
|
||||
|
||||
## [1.2.1] - 2019/12/29
|
||||
- Switch base image from Debian oldoldstable Jessie to Debian stable Buster to fix unmet dependencies of `seafile-cli` to `python-future` and `python-searpc` (#4)
|
||||
- Replace `;` with `&&` as commands separators in the Dockerfile's `RUN` to properly report failed commands at CI (#4)
|
||||
## [1.2.0] - 2019/05/02
|
||||
- Replace _supervisord_ with _cron_ for running the front job that keeps the container up. It uses less resources.
|
||||
- Improve the infinite-seaf-cli-start.sh into seafile-healthcheck.sh. The Seafile daemon will not be restarted if it's state are either _downloading_ or _committing_, which otherwise is problematic.
|
||||
|
||||
## [1.1.2] - 2019/04/18
|
||||
- Slim down the Docker image, from 102MB to 67MB, gaining 35MB, reducing size by 34%.
|
||||
## [1.1.1] - 2019/04/18
|
||||
- Because of the infinite-seaf-cli-start loop, within the container was running many seaf-daemons. Now, the infinite loop stop the current seaf-daemon before starting it again. (see #3)
|
||||
## [1.1.0] - 2019/04/09
|
||||
- The container now actually use the UID/GID provided to it:
|
||||
The container entrypoint is run with root, then another entrypoint is run by the container's user, seafuser, to run the Seafile client.
|
||||
|
||||
### [1.0.6] - 2019/03/25
|
||||
## [1.0.6] - 2019/03/25
|
||||
- More minor fixes from v1.0.4
|
||||
### [1.0.5] - 2019/03/25
|
||||
## [1.0.5] - 2019/03/25
|
||||
- Minor fixes from v1.0.4
|
||||
### [1.0.4] - 2019/03/25
|
||||
## [1.0.4] - 2019/03/25
|
||||
- Fix the build target detection (@a52559ddb38a64d7fceaa8bf9b8afd7356ccc439)
|
||||
- Login to the Docker Hub from within the script, not the gitlab-ci.yml, using (@72bab017c1167b8ab35cef3cc709ff83686eaca4, @f69483354a4cf8afdbea89ef2bb1d9a9b7b2ac10)
|
||||
- Require Bash on all Gitlab CI stages (@72bab017c1167b8ab35cef3cc709ff83686eaca4)
|
||||
- Add a script to push the README.md into the Docker Hub repository's full_description (@8cb49cbc8253368701d718c2e38017790c78ceca, @ca6128fb96602da71f3b7a560e834d1b7587abac)
|
||||
### [1.0.3] - 2019/03/19
|
||||
## [1.0.3] - 2019/03/19
|
||||
- Restrict staging pipelines to pushed pipelines
|
||||
- Restrict production pipelines to pushed and triggered pipelines
|
||||
- Require a build target on triggered production pipelines
|
||||
### [1.0.2] - 2019/03/18
|
||||
## [1.0.2] - 2019/03/18
|
||||
- Fix a minor issue when testing for requested production build.
|
||||
### [1.0.1] - 2019/03/18
|
||||
## [1.0.1] - 2019/03/18
|
||||
- Add failsafe when importing Seafile's APT-key
|
||||
- Restrict production build to latest, majors, minors and revisions version, on-demand.
|
||||
# [1.0.0] - 2019/03/15
|
||||
## [1.0.0] - 2019/03/15
|
||||
- Release to Docker Hub
|
||||
|
||||
# [0.9.2] - 2019/03/15
|
||||
## [0.9.2] - 2019/03/15
|
||||
- Test release on GitLab, before Docker Hub
|
||||
|
||||
[2.2.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.2.0
|
||||
[2.1.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.1.1
|
||||
[2.1.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.1.0
|
||||
[2.0.3]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.2
|
||||
[2.0.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.2
|
||||
[2.0.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.1
|
||||
[2.0.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.0
|
||||
[1.2.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.2.1
|
||||
[1.2.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.2.0
|
||||
[1.1.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.1.2
|
||||
[1.1.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.1.1
|
||||
[1.1.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.1.0
|
||||
[1.0.6]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.6
|
||||
[1.0.5]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.5
|
||||
[1.0.4]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.4
|
||||
[1.0.3]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.3
|
||||
[1.0.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.2
|
||||
[1.0.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.1
|
||||
[1.0.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.0
|
||||
[0.9.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/0.9.2
|
||||
|
||||
115
CONTRIBUTING.md
Normal file
115
CONTRIBUTING.md
Normal file
@@ -0,0 +1,115 @@
|
||||
**Do you want to contribute ? Please do!**
|
||||
|
||||
* [How to help?](#how-to-help?)
|
||||
* [Report issues, propose features](#report-issues-propose-features)
|
||||
* [Solve problems](#solve-problems)
|
||||
* [Say thanks](#say-thanks)
|
||||
* [Project workflow](#project-workflow)
|
||||
* [Environment](#environment)
|
||||
* [Development](#development)
|
||||
* [CI/CD](#ci/cd)
|
||||
|
||||
# How to help?
|
||||
They are several ways to help and improve this project.
|
||||
|
||||
## Report issues, propose features
|
||||
You think you found a bug ? You think something is missing out ? Check that it has not been [already reported](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/issues). If it has not, [report it](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/issues/new?issue).
|
||||
|
||||
## Solve problems
|
||||
You can't wait for a problem to be solved ? Pick one from the [already reported problems](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/issues) and solve it. It will be greatly appreciated!
|
||||
|
||||
## Say thanks
|
||||
One great way to help is simply to say thanks. You can do that by [adding a star to the Docker Hub repository](https://hub.docker.com/r/flrnnc/seafile-client) or [just saying thanks in the project topic on Seafile's forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
|
||||
|
||||
# Project workflow
|
||||
The ins and outs of the project, from setting up a local environment for developments to notifying users of changes.
|
||||
|
||||
To provide the different Seafile's client versions, the project rely on the [`seafile` package available throughout the different Debian versions][packages]. Check out [Debian Developer's Package Overview][ddpo] and [Debian Package Tracker][tracker] for in depth details regarding that package.
|
||||
|
||||
[packages]: https://packages.debian.org/search?keywords=seafile-cli
|
||||
[ddpo]: https://qa.debian.org/developer.php?login=team%2Bseafile%40tracker.debian.org
|
||||
[tracker]: https://tracker.debian.org/pkg/seafile
|
||||
|
||||
|
||||
The following state diagram describe essentially the project workflow for a release.
|
||||
```mermaid
|
||||
|
||||
stateDiagram-v2
|
||||
feature: Checkout new branch from main
|
||||
changes: Apply changes
|
||||
mr: Create a Merge Request
|
||||
pipelines: CI/CD pipelines must be successful
|
||||
log: Changes must be documented
|
||||
merge: Branch is squash merged into main
|
||||
release: Release is created
|
||||
|
||||
[*] --> feature
|
||||
feature --> changes
|
||||
changes --> mr
|
||||
mr --> pipelines
|
||||
pipelines --> log
|
||||
log --> merge
|
||||
merge --> release
|
||||
release --> [*]
|
||||
```
|
||||
|
||||
## Environment
|
||||
The following is required to develop:
|
||||
* Docker engine
|
||||
* Bash
|
||||
* Make
|
||||
|
||||
## Management
|
||||
|
||||
The project managemenet is mostly run through the Makefile.
|
||||
|
||||
The parameter `TARGET` define on which Debian version the instructions are run.
|
||||
|
||||
The following instructions are available:
|
||||
|
||||
### mock
|
||||
Start the Docker Compose mock for a Seafile server.
|
||||
|
||||
### unmock
|
||||
Start the Docker Compose mock for a Seafile server.
|
||||
|
||||
### client
|
||||
Purge and start the client service on the Docker Compose mock for a Seafile server.
|
||||
|
||||
### logs
|
||||
Continuously display the logs from the client service on the Docker Compose mock for a Seafile server.
|
||||
|
||||
### build
|
||||
Build the Seafile Docker client image depending on the `TARGET`.
|
||||
|
||||
### build-test
|
||||
Build the Seafile Docker client test image depending on the `TARGET`.
|
||||
|
||||
### test
|
||||
Run the Seafile Docker client test container.
|
||||
|
||||
### documents
|
||||
Build the documentation for both Docker Hub and Seafile's forum.
|
||||
|
||||
### publish-images
|
||||
Publish the Docker Seafile client image, properly tagged with the appropriate Seafile cliens versions.
|
||||
|
||||
### publish-documents
|
||||
Publish the generated documentation on Docker Hub only
|
||||
|
||||
### save
|
||||
Export the Seafile Docker client image as a tarball.
|
||||
|
||||
### load
|
||||
Load the Seafile Docker client image from a tarball
|
||||
|
||||
## Pipelines
|
||||
|
||||
Pipelines are run either on merge requests or on commit tags.
|
||||
|
||||
The pipelines are divided into three stages:
|
||||
* Build
|
||||
* Test
|
||||
* Release
|
||||
|
||||
Release jobs are obviously not run on merge requests.
|
||||
48
Dockerfile
48
Dockerfile
@@ -1,48 +0,0 @@
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
FROM debian:jessie
|
||||
|
||||
# Prevent the packages installation to halt.
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
|
||||
# Copy over the seafile repository.
|
||||
COPY assets/seafile.list /etc/apt/sources.list.d/
|
||||
|
||||
# Safely import Seafile APT key, then install both seafile-cli and supervisord.
|
||||
COPY utils/build/import-seafile-apt-key.sh /
|
||||
RUN /bin/bash /import-seafile-apt-key.sh ;\
|
||||
apt-get update ;\
|
||||
apt-get install -o Dpkg::Options::="--force-confold" -y seafile-cli supervisor
|
||||
RUN rm -f /import-seafile-apt-key.sh
|
||||
|
||||
# Create the seafile client user.
|
||||
ENV UNAME=seafuser
|
||||
ENV UID=1000
|
||||
ENV GID=1000
|
||||
RUN groupadd -g $GID -o $UNAME ;\
|
||||
useradd -m -u $UID -g $GID -o -s /bin/bash $UNAME
|
||||
|
||||
# Copy over the Docker entrypoint.
|
||||
COPY assets/docker-entrypoint.sh /entrypoint.sh
|
||||
|
||||
# Copy over the required files for Seafile/SupervisorD.
|
||||
COPY assets/supervisord.conf /home/seafuser/
|
||||
COPY assets/infinite-seaf-cli-start.sh /home/seafuser/
|
||||
COPY assets/seafile-entrypoint.sh /home/seafuser/entrypoint.sh
|
||||
RUN mkdir /volume
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
|
||||
@@ -1,7 +1,7 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2019 flow.gunso@gmail.com
|
||||
Copyright (C) 2019-2024 florian.anceau@gmail.com
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
64
Makefile
Normal file
64
Makefile
Normal file
@@ -0,0 +1,64 @@
|
||||
TARGET?=stable
|
||||
|
||||
# Mocking
|
||||
mock:
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml up -d
|
||||
|
||||
unmock:
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml down
|
||||
|
||||
client:
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml rm -fs client
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml up -d client
|
||||
|
||||
shell:
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml exec client bash
|
||||
|
||||
logs:
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml logs -f client
|
||||
|
||||
ps:
|
||||
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml ps
|
||||
|
||||
# Build
|
||||
build:
|
||||
TARGET=${TARGET} CI_COMMIT_TAG=${CI_COMMIT_TAG} bash scripts/build-images.sh
|
||||
|
||||
build-test:
|
||||
docker build --build-arg TARGET=${TARGET} -t seafile-client:test tests/image
|
||||
|
||||
test:
|
||||
docker run seafile-client:test
|
||||
|
||||
# CI/CD
|
||||
documents:
|
||||
python scripts/update-build-badge.py
|
||||
python scripts/make-documents.py docker.md.j2
|
||||
python scripts/make-documents.py docker-old.md.j2
|
||||
python scripts/make-documents.py seafile.md.j2
|
||||
|
||||
publish-images:
|
||||
TARGET=${TARGET} \
|
||||
DOCKER_REGISTRY_USERNAME=${DOCKER_REGISTRY_USERNAME} \
|
||||
DOCKER_REGISTRY_TOKEN=${DOCKER_REGISTRY_TOKEN} \
|
||||
DOCKER_REGISTRY_IMAGE_FLOWGUNSO=${DOCKER_REGISTRY_IMAGE_FLOWGUNSO} \
|
||||
DOCKER_REGISTRY_IMAGE_FLRNNC=${DOCKER_REGISTRY_IMAGE_FLRNNC} \
|
||||
bash scripts/publish-images.sh
|
||||
|
||||
publish-documents:
|
||||
bash scripts/publish-documents.sh
|
||||
|
||||
save:
|
||||
mkdir -p tarballs/
|
||||
docker save --output tarballs/${TARGET}-flowgunso.tar seafile-client:${TARGET}-flowgunso
|
||||
docker save --output tarballs/${TARGET}-flrnnc.tar seafile-client:${TARGET}-flrnnc
|
||||
|
||||
load:
|
||||
docker load --input tarballs/${TARGET}-flowgunso.tar
|
||||
docker load --input tarballs/${TARGET}-flrnnc.tar
|
||||
|
||||
schedule-weekly-build:
|
||||
python scripts/schedule-build.py
|
||||
|
||||
unschedule-weekly-build:
|
||||
python scripts/schedule-build.py --disable
|
||||
217
README.md
217
README.md
@@ -1,110 +1,159 @@
|
||||
[](https://gitlab.com/flwgns-docker/seafile-client/commits/1.1.0)
|
||||
[](https://hub.docker.com/r/flowgunso/seafile-client)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://gitlab.com/flwgns-docker/seafile-client/)
|
||||
> ⚠️ Please consider sponsoring this project to help me maintaining and improving it. As of right now, you can support me through Liberay, available in the project badges
|
||||
|
||||
# Available tags
|
||||
> This project is switching namespaces. The sources previously in [flwgnso-docker/docker-seafile-client](https://gitlab.com/flwgns-docker/seafile-client) are now in [flrnnc-oss/docker-seafile-client](https://gitlab.com/flrnnc-oss/docker-seafile-client). The Docker image can still be found at [flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client) but it will be deprecated, the image [flrnnc/seafile-client](https://hub.docker.com/r/flrnnc/seafile-client) should be used instead.
|
||||
|
||||
Weekly stable release are built every Monday at 6AM UTC+2.
|
||||
Permanent stable releases will not be built again.
|
||||
# Quick informations
|
||||
|
||||
You can rely on the weekly stable releases. They are stable.
|
||||
_Docker Seafile client_ is a Docker image that provides a Seafile client to sync one or more library as volumes to other containers.
|
||||
|
||||
## Weekly stable releases.
|
||||
[`1`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.1.0),
|
||||
[`1.1`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.1.0),
|
||||
[`1.1.0`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.1.0),
|
||||
[`latest`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.1.0)
|
||||
(see tag/release [1.1.0](https://gitlab.com/flwgns-docker/seafile-client/tags/1.1.0))
|
||||
## Features
|
||||
* Synchronize one or more Seafile libraries.
|
||||
* Support password protected librairies.
|
||||
* Support two factor authentication.
|
||||
* Configure upload and download limits.
|
||||
* Skip SSL certificates.
|
||||
* Set file ownership with user/group ID
|
||||
|
||||
## Permanent stable releases.
|
||||
None at the moment.
|
||||
## Quick links
|
||||
|
||||
## Developmental releases.
|
||||
[`staging`](https://gitlab.com/flwgns-docker/seafile-client/tree/staging)
|
||||
(see branch [staging](https://gitlab.com/flwgns-docker/seafile-client/tree/staging))
|
||||
|
||||
## Obsolete releases.
|
||||
[`1.0`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.0.6) and it's revision
|
||||
[`1.0.6`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.0.6),
|
||||
[`1.0.3`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.0.3),
|
||||
[`1.0.2`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.0.2),
|
||||
[`1.0.0`](https://gitlab.com/flwgns-docker/seafile-client/tags/1.0.0) are now obsolete.
|
||||
|
||||
# Purpose
|
||||
Docker Seafile Client allow you to sync a Seafile library within a container.
|
||||
|
||||
**Essentially, you can share a Seafile library as a volume to other containers**.
|
||||
|
||||
## Seafile?
|
||||
[Seafile is a cloud storage software](https://www.seafile.com/).
|
||||
* Check out the [roadmap](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/wikis/home#roadmap) to see what is anticipated.
|
||||
* Check out how to [contribute](CONTRIBUTING.md).
|
||||
* Report issues on [Gitlab](https://gitlab.com/flrnnc-oss/docker-seafile-client/).
|
||||
* Ask questions on [Seafile forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
|
||||
|
||||
|
||||
# Usage
|
||||
The *Seafile* daemon is running from `/.seafile/` and `~/.ccnet`.
|
||||
The library is synced at `/volume/`.
|
||||
|
||||
The *Seafile* daemon is managed with *supervisord* since it can't run as a foreground process.
|
||||
The *supervisord* is running from `/.supervisord/`, the `supervisord.conf`, `supervisord.log` and `supervisord.pid` can be found there.
|
||||
*supervisord* also manage a shell script, `/infinite-seaf-cli-start.sh` which run `seaf-cli start` every hour: the synchronisation might not work properly if `seaf-cli start` is not run from times to times, for an unresolved reason.
|
||||
## Examples
|
||||
You would have to share the path `/volume/` to other containers, with the following approaches:
|
||||
### Docker CLI
|
||||
```
|
||||
## Start a Seafile client
|
||||
|
||||
### Docker command-line
|
||||
The following command start the Seafile client with one library:
|
||||
```bash
|
||||
docker run \
|
||||
-e SEAF_SERVER_URL= \ # The URL to your Seafile server.
|
||||
-e SEAF_USERNAME= \ # Your Seafile username.
|
||||
-e SEAF_PASSWORD= \ # Your Seafile password
|
||||
-e SEAF_LIBRARY_UUID= \ # The Seafile library UUID you want to sync with.
|
||||
-e UID= \ # Default is 1000.
|
||||
-e GID= \ # Default is 1000.
|
||||
-v your/shared/volume:/volume \
|
||||
flowgunso/seafile-client:latest
|
||||
-e SEAF_SERVER_URL="https://seafile.example/" \
|
||||
-e SEAF_USERNAME="a_seafile_user" \
|
||||
-e SEAF_PASSWORD="SoMePaSSWoRD" \
|
||||
-e SEAF_LIBRARY="an-hexadecimal-library-uuid" \
|
||||
-v path/to/library:/library \
|
||||
-v path/to/client/data:/seafile \
|
||||
flrnnc/seafile-client:latest
|
||||
```
|
||||
### docker-compose
|
||||
|
||||
### Docker Compose
|
||||
The following Docker Compose start a Seafile client with two libraries, with one password protected:
|
||||
```yaml
|
||||
version: "3.4"
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
seafile-client:
|
||||
image: flowgunso/seafile-client:latest
|
||||
restart: on-failure
|
||||
image: flrnnc/seafile-client:latest
|
||||
volumes:
|
||||
- your_shared_volume:/volume
|
||||
- audio:/library/audio
|
||||
- documents:/library/documents
|
||||
- client:/seafile
|
||||
environment:
|
||||
- SEAF_SERVER_URL= # The URL to your Seafile server.
|
||||
- SEAF_USERNAME= # Your Seafile username.
|
||||
- SEAF_PASSWORD= # Your Seafile password.
|
||||
- SEAF_LIBRARY_UUID= # The Seafile library UUID you want to sync with.
|
||||
- UID= # Default is 1000.
|
||||
- GID= # Default is 1000.
|
||||
SEAF_SERVER_URL: "https://seafile.example/"
|
||||
SEAF_USERNAME: "a_seafile_user"
|
||||
SEAF_PASSWORD: "SoMePaSSWoRD"
|
||||
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
|
||||
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
|
||||
|
||||
volumes:
|
||||
your_shared_volume:
|
||||
audio:
|
||||
documents:
|
||||
client:
|
||||
```
|
||||
|
||||
## Librairies
|
||||
Environment variables allows librairies configuration, as shown in the examples above.
|
||||
|
||||
# Environment variables
|
||||
The following environment variable are available.
|
||||
You can configure either a single librairy or multiple librairies.
|
||||
|
||||
## Seafile
|
||||
This Docker **must be configured with the following**, **otherwise** it **will not run**:
|
||||
### SEAF_SERVER_URL
|
||||
The URL to your Seafile server.
|
||||
### SEAF_USERNAME
|
||||
Your Seafile account's username.
|
||||
### SEAF_PASSWORD
|
||||
Your Seafile account's password.
|
||||
### SEAF_LIBRARY_UUID
|
||||
The Seafile library UUID you want to use.
|
||||
### Single library
|
||||
To synchronize a single library, use the environment variables `SEAF_LIBRARY` and `SEAF_LIBRARY_PASSWORD`. The library will be synchronized in _/library_.
|
||||
|
||||
## User permissions
|
||||
This Docker is **not running as `root` but as `seafuser`**. You can override the user/group ID used with:
|
||||
### UID
|
||||
The user ID defaults to `1000`. You may want to override this variable to prevent permission issues.
|
||||
### GID
|
||||
The group ID defaults to `1000`. Similarly, you may want to override this variable to prevent permission issues.
|
||||
### Multiple librairies
|
||||
To synchronise multiple librairies, use the same environment variable as above but suffixed with a single identifier word. That word will be used for the library password and it's synchronization path as well.
|
||||
|
||||
# Source code
|
||||
This Docker image is licensed under GPLv3.
|
||||
The source code is available in [gitlab.com/flwgns-docker/seafile-client](https://gitlab.com/flwgns-docker/seafile-client/).
|
||||
Hence, to synchronise a library identified as **audio**, the environment variables would be `SEAF_LIBRARY_AUDIO` for the library UUID and `SEAF_LIBRARY_AUDIO_PASSWORD` for the library password. The library will be then synchronized in _/library/audio_.
|
||||
|
||||
Identifiers allows to add as many libraries as possible. Identifier are single word only.
|
||||
|
||||
## Environment variables
|
||||
Environment variable allows you to configure the Seafile client.
|
||||
|
||||
### `SEAF_SERVER_URL`
|
||||
> This variable is mandatory.
|
||||
|
||||
The Seafile server URL.
|
||||
|
||||
### `SEAF_USERNAME`
|
||||
> This variable is mandatory.
|
||||
|
||||
The username for the Seafile account.
|
||||
|
||||
### `SEAF_PASSWORD`
|
||||
> This variable is mandatory.
|
||||
|
||||
The password for the Seafile account.
|
||||
|
||||
### `SEAF_LIBRARY`, `SEAF_LIBRARY_[IDENTIFIER]`
|
||||
> This variable is mandatory.
|
||||
|
||||
The UUID of the library, libraries to synchronize.
|
||||
Replace `[IDENTIFIER]` with the a unique single word identifier for each library you want to synchronize.
|
||||
|
||||
### `SEAF_LIBRARY_PASSWORD`, `SEAF_LIBRARY_[IDENTIFIER]_PASSWORD`
|
||||
The password of the library, libraries to synchronize.
|
||||
Replace `[IDENTIFIER]` with the a unique single word identifier for each library you want to synchronize corresponding to the `SEAF_LIBRARY_[IDENTIFIER]`.
|
||||
|
||||
### `SEAF_2FA_SECRET`
|
||||
_Two factor authentication is supported but your secret key must be provided._ That key can be found on your Seafile web interface, only at the 2FA setup, when the QR code is shown. The secret key is embedded in the QR or available as a cookie.
|
||||
|
||||
### `SEAF_UPLOAD_LIMIT`, `SEAF_DOWNLOAD_LIMIT`
|
||||
Set upload and download speeds limits. Limits are in bytes.
|
||||
|
||||
### `SEAF_SKIP_SSL_CERT`
|
||||
Skip SSL certificates verifications.
|
||||
|
||||
> Any string is considered true, omit the variable to set to false. Enable this if you have synchronization failures regarding SSL certificates.
|
||||
|
||||
### `UID`, `GID`
|
||||
Override the _UID_ and _GID_ for user running the Seafile client, hence the volume ownership.
|
||||
|
||||
## Docker Secrets
|
||||
All environments variable supports Docker Secrets, as environment variable variant suffixed with `_FILE` as files.
|
||||
|
||||
## Full example
|
||||
```bash
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
seafile-client:
|
||||
image: flrnnc/seafile-client:latest
|
||||
volumes:
|
||||
- audio:/library/audio
|
||||
- documents:/library/documents
|
||||
- client:/seafile
|
||||
environment:
|
||||
SEAF_SERVER_URL: "https://seafile.example/"
|
||||
SEAF_USERNAME: "a_seafile_user"
|
||||
SEAF_PASSWORD: "SoMePaSSWoRD"
|
||||
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
|
||||
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
|
||||
SEAF_2FA_SECRET: "JBSWY3DPEHPK3PXPIXDAUMXEDOXIUCDXWC32CS"
|
||||
SEAF_UPLOAD_LIMIT: "1000000"
|
||||
SEAF_DOWNLOAD_LIMIT: "1000000"
|
||||
SEAF_SKIP_SSL_CERT: "true"
|
||||
UID: "1000"
|
||||
GID: "1000"
|
||||
|
||||
volumes:
|
||||
audio:
|
||||
documents:
|
||||
client:
|
||||
```
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Check mandatory Seafile configuration have been properly set.
|
||||
if [ -z $SEAF_SERVER_URL ]; then echo "The \$SEAF_SERVER_URL was not defined. Stopping container..."; exit 1; fi
|
||||
if [ -z $SEAF_USERNAME ]; then echo "The \$SEAF_USERNAME was not defined. Stopping container..."; exit 1; fi
|
||||
if [ -z $SEAF_PASSWORD ]; then echo "The \$SEAF_PASSWORD was not defined. Stopping container..."; exit 1; fi
|
||||
if [ -z $SEAF_LIBRARY_UUID ]; then echo "The \$SEAF_LIBRARY_UUID was not defined. Stopping container..."; exit 1; fi
|
||||
|
||||
# Update the user ID, if the $UID changed.
|
||||
if [ "$UID" != "1000" ]; then
|
||||
usermod -u $UID $UNAME
|
||||
# What if the $UID already exists ?
|
||||
fi
|
||||
|
||||
# Change the group, if the $GID changed.
|
||||
if [ "$GID" != "1000" ]; then
|
||||
getent group | grep ":$GID:" >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
usermod -g $GID -G 1000 $UNAME
|
||||
else
|
||||
groupmod -g $GID $UNAME
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set the files ownership.
|
||||
chown $UID.$GID -R /home/seafuser/supervisord.conf
|
||||
chown $UID.$GID -R /home/seafuser/infinite-seaf-cli-start.sh
|
||||
chown $UID.$GID -R /home/seafuser/entrypoint.sh
|
||||
chown $UID.$GID -R /volume
|
||||
|
||||
# Run the Seafile client as the container user.
|
||||
su - $UNAME << EO
|
||||
export SEAF_SERVER_URL=$SEAF_SERVER_URL
|
||||
export SEAF_USERNAME=$SEAF_USERNAME
|
||||
export SEAF_PASSWORD=$SEAF_PASSWORD
|
||||
export SEAF_LIBRARY_UUID=$SEAF_LIBRARY_UUID
|
||||
export UNAME=$UNAME
|
||||
/bin/bash /home/seafuser/entrypoint.sh
|
||||
EO
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Define variable shortcuts for readability purposes.
|
||||
seafile_ini=~/.ccnet/seafile.ini
|
||||
seafile_sock=~/.seafile/seafile-data/seafile.sock
|
||||
supervisord_conf=~/supervisord.conf
|
||||
supervisord_pid=~/.supervisord/supervisord.pid
|
||||
supervisord_log=~/.supervisord/supervisord.log
|
||||
|
||||
# Prepare the directories.
|
||||
mkdir ~/.seafile
|
||||
mkdir ~/.supervisord
|
||||
|
||||
# Safely initialise the Seafile client.
|
||||
/usr/bin/seaf-cli init -d ~/.seafile
|
||||
while [ ! -f $seafile_ini ]; do sleep 1; done
|
||||
|
||||
# Safely start the Seafile daemon.
|
||||
/usr/bin/seaf-cli start
|
||||
while [ ! -S $seafile_sock ]; do sleep 1; done
|
||||
|
||||
# Start the synchronisation.
|
||||
/usr/bin/seaf-cli sync -u $SEAF_USERNAME -p $SEAF_PASSWORD -s $SEAF_SERVER_URL -l $SEAF_LIBRARY_UUID -d /volume
|
||||
|
||||
# Start the supervisord.
|
||||
/usr/bin/supervisord -u $UNAME -c $supervisord_conf -j $supervisord_pid -l $supervisord_log
|
||||
@@ -1 +0,0 @@
|
||||
deb http://deb.seadrive.org jessie main
|
||||
@@ -1,30 +0,0 @@
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Run in the foreground to keep the container running.
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
# Manage the Seafile daemon.
|
||||
[unix_http_socket]
|
||||
file=~/.seafile/seafile-data/seafile.sock
|
||||
|
||||
# Manage the infinite `seaf-cli start`.
|
||||
[program:seaf-cli-start-loop]
|
||||
command=/bin/bash /home/seafuser/infinite-seaf-cli-start.sh
|
||||
process_name=%(program_name)s
|
||||
numprocs=1
|
||||
autostart=true
|
||||
@@ -1,18 +0,0 @@
|
||||
version: "3.4"
|
||||
|
||||
services:
|
||||
seafile-client:
|
||||
image: flowgunso/seafile-client:latest
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- your_shared_volume:/volume
|
||||
environment:
|
||||
- SEAF_SERVER_URL= # The URL to your Seafile server.
|
||||
- SEAF_USERNAME= # Your Seafile username.
|
||||
- SEAF_PASSWORD= # Your Seafile password.
|
||||
- SEAF_LIBRARY_UUID= # The Seafile library UUID you want to sync with.
|
||||
- UID= # Default is 1000.
|
||||
- GID= # Default is 1000.
|
||||
|
||||
volumes:
|
||||
your_shared_volume:
|
||||
8
documentations/assets/cli.bash
Normal file
8
documentations/assets/cli.bash
Normal file
@@ -0,0 +1,8 @@
|
||||
docker run \
|
||||
-e SEAF_SERVER_URL="https://seafile.example/" \
|
||||
-e SEAF_USERNAME="a_seafile_user" \
|
||||
-e SEAF_PASSWORD="SoMePaSSWoRD" \
|
||||
-e SEAF_LIBRARY="an-hexadecimal-library-uuid" \
|
||||
-v path/to/library:/library \
|
||||
-v path/to/client/data:/seafile \
|
||||
flrnnc/seafile-client:latest
|
||||
28
documentations/assets/compose-full.yaml
Normal file
28
documentations/assets/compose-full.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
seafile-client:
|
||||
image: flrnnc/seafile-client:latest
|
||||
volumes:
|
||||
- audio:/library/audio
|
||||
- documents:/library/documents
|
||||
- client:/seafile
|
||||
environment:
|
||||
SEAF_SERVER_URL: "https://seafile.example/"
|
||||
SEAF_USERNAME: "a_seafile_user"
|
||||
SEAF_PASSWORD: "SoMePaSSWoRD"
|
||||
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
|
||||
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
|
||||
SEAF_2FA_SECRET: "JBSWY3DPEHPK3PXPIXDAUMXEDOXIUCDXWC32CS"
|
||||
SEAF_UPLOAD_LIMIT: "1000000"
|
||||
SEAF_DOWNLOAD_LIMIT: "1000000"
|
||||
SEAF_SKIP_SSL_CERT: "true"
|
||||
UID: "1000"
|
||||
GID: "1000"
|
||||
|
||||
volumes:
|
||||
audio:
|
||||
documents:
|
||||
client:
|
||||
22
documentations/assets/compose.yaml
Normal file
22
documentations/assets/compose.yaml
Normal file
@@ -0,0 +1,22 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
seafile-client:
|
||||
image: flrnnc/seafile-client:latest
|
||||
volumes:
|
||||
- audio:/library/audio
|
||||
- documents:/library/documents
|
||||
- client:/seafile
|
||||
environment:
|
||||
SEAF_SERVER_URL: "https://seafile.example/"
|
||||
SEAF_USERNAME: "a_seafile_user"
|
||||
SEAF_PASSWORD: "SoMePaSSWoRD"
|
||||
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
|
||||
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
|
||||
|
||||
volumes:
|
||||
audio:
|
||||
documents:
|
||||
client:
|
||||
15
documentations/docker-old.md.j2
Normal file
15
documentations/docker-old.md.j2
Normal file
@@ -0,0 +1,15 @@
|
||||
{% include "parts/notices.md.j2" %}
|
||||
|
||||
{% include "parts/badges.md.j2" %}
|
||||
|
||||
**Share one or more Seafile libraries as a volume to other containers.**
|
||||
|
||||
{% include "parts/supported_tags.md.j2" %}
|
||||
|
||||
{% include "parts/features.md.j2" %}
|
||||
|
||||
{% include "parts/usage.md.j2" %}
|
||||
|
||||
{% include "parts/troubleshooting.md.j2" %}
|
||||
|
||||
{% include "parts/moving-to-another-namespace.md.j2" %}
|
||||
11
documentations/docker.md.j2
Normal file
11
documentations/docker.md.j2
Normal file
@@ -0,0 +1,11 @@
|
||||
{% include "parts/badges.md.j2" %}
|
||||
|
||||
**Share one or more Seafile libraries as a volume to other containers.**
|
||||
|
||||
{% include "parts/supported_tags.md.j2" %}
|
||||
|
||||
{% include "parts/features.md.j2" %}
|
||||
|
||||
{% include "parts/usage.md.j2" %}
|
||||
|
||||
{% include "parts/troubleshooting.md.j2" %}
|
||||
9
documentations/gitlab.md.j2
Normal file
9
documentations/gitlab.md.j2
Normal file
@@ -0,0 +1,9 @@
|
||||
{% include "parts/badges.md.j2" %}
|
||||
|
||||
**Share a Seafile library as a volume to other containers.**
|
||||
|
||||
{% include "parts/features.md.j2" %}
|
||||
|
||||
{% include "parts/usage.md.j2" %}
|
||||
|
||||
{% include "parts/troubleshooting.md.j2" %}
|
||||
3
documentations/parts/badges.md.j2
Normal file
3
documentations/parts/badges.md.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
{% for name, links in badges.items() -%}
|
||||
[]({{links.link}})
|
||||
{% endfor %}
|
||||
9
documentations/parts/features.md.j2
Normal file
9
documentations/parts/features.md.j2
Normal file
@@ -0,0 +1,9 @@
|
||||
# Features
|
||||
* Synchronize one or more Seafile libraries.
|
||||
* Support password protected librairies.
|
||||
* Support two factor authentication.
|
||||
* Configure upload and download limits.
|
||||
* Skip SSL certificates.
|
||||
* Set file ownership with user/group ID
|
||||
|
||||
The Docker image is built weekly to keep up with security updates.
|
||||
5
documentations/parts/moving-to-another-namespace.md.j2
Normal file
5
documentations/parts/moving-to-another-namespace.md.j2
Normal file
@@ -0,0 +1,5 @@
|
||||
# Moving to another namespace
|
||||
|
||||
This repository is being moved to a new namespace [flrnnc](https://hub.docker.com/u/flrnnc).
|
||||
|
||||
I am applying to open source software programs on the service providers I rely on such as Gitlab and Docker. It means that my project must be reorganized. The `flrnnc` namespace is dedidacted to open source software I publish on Docker.
|
||||
2
documentations/parts/notices.md.j2
Normal file
2
documentations/parts/notices.md.j2
Normal file
@@ -0,0 +1,2 @@
|
||||
> This repository will be moved to another namespace [flrnnc/seafile-client](https://hub.docker.com/repository/docker/flrnnc/seafile-client/).
|
||||
> See [moving to another namespace](#moving-to-another-namespace]) for explanations.
|
||||
9
documentations/parts/supported_tags.md.j2
Normal file
9
documentations/parts/supported_tags.md.j2
Normal file
@@ -0,0 +1,9 @@
|
||||
# Supported tags
|
||||
|
||||
The versions match Seafile versions.
|
||||
|
||||
{% for version in versions %}
|
||||
[{{ version | join(", ")}}][Dockerfile]
|
||||
{% endfor %}
|
||||
|
||||
[Dockerfile]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/blob/master/seafile-client/Dockerfile
|
||||
3
documentations/parts/troubleshooting.md.j2
Normal file
3
documentations/parts/troubleshooting.md.j2
Normal file
@@ -0,0 +1,3 @@
|
||||
# Troubleshooting
|
||||
* Ask questions on [Seafile forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
|
||||
* Contribute and report issues on [Gitlab](https://gitlab.com/flrnnc-oss/docker-seafile-client/).
|
||||
80
documentations/parts/usage.md.j2
Normal file
80
documentations/parts/usage.md.j2
Normal file
@@ -0,0 +1,80 @@
|
||||
# Usage
|
||||
|
||||
## Start a Seafile client
|
||||
|
||||
### Docker command-line
|
||||
The following command start the Seafile client with one library:
|
||||
```bash
|
||||
{% include "assets/cli.bash" %}
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
The following Docker Compose start a Seafile client with two libraries, with one password protected:
|
||||
```yaml
|
||||
{% include "assets/compose.yaml" %}
|
||||
```
|
||||
|
||||
## Librairies
|
||||
Environment variables allows librairies configuration, as shown in the examples above.
|
||||
|
||||
You can configure either a single librairy or multiple librairies.
|
||||
|
||||
### Single library
|
||||
To synchronize a single library, use the environment variables `SEAF_LIBRARY` and `SEAF_LIBRARY_PASSWORD`. The library will be synchronized in _/library_.
|
||||
|
||||
### Multiple librairies
|
||||
To synchronise multiple librairies, use the same environment variable as above but suffixed with a single identifier word. That word will be used for the library password and it's synchronization path as well.
|
||||
|
||||
Hence, to synchronise a library identified as **audio**, the environment variables would be `SEAF_LIBRARY_AUDIO` for the library UUID and `SEAF_LIBRARY_AUDIO_PASSWORD` for the library password. The library will be then synchronized in _/library/audio_.
|
||||
|
||||
Identifiers allows to add as many libraries as possible. Identifier are single word only.
|
||||
|
||||
## Environment variables
|
||||
Environment variable allows you to configure the Seafile client.
|
||||
|
||||
### `SEAF_SERVER_URL`
|
||||
> This variable is mandatory.
|
||||
|
||||
The Seafile server URL.
|
||||
|
||||
### `SEAF_USERNAME`
|
||||
> This variable is mandatory.
|
||||
|
||||
The username for the Seafile account.
|
||||
|
||||
### `SEAF_PASSWORD`
|
||||
> This variable is mandatory.
|
||||
|
||||
The password for the Seafile account.
|
||||
|
||||
### `SEAF_LIBRARY`, `SEAF_LIBRARY_[IDENTIFIER]`
|
||||
> This variable is mandatory.
|
||||
|
||||
The UUID of the library, libraries to synchronize.
|
||||
Replace `[IDENTIFIER]` with the a unique single word identifier for each library you want to synchronize.
|
||||
|
||||
### `SEAF_LIBRARY_PASSWORD`, `SEAF_LIBRARY_[IDENTIFIER]_PASSWORD`
|
||||
The password of the library, libraries to synchronize.
|
||||
Replace `[IDENTIFIER]` with the a unique single word identifier for each library you want to synchronize corresponding to the `SEAF_LIBRARY_[IDENTIFIER]`.
|
||||
|
||||
### `SEAF_2FA_SECRET`
|
||||
_Two factor authentication is supported but your secret key must be provided._ That key can be found on your Seafile web interface, only at the 2FA setup, when the QR code is shown. The secret key is embedded in the QR or available as a cookie.
|
||||
|
||||
### `SEAF_UPLOAD_LIMIT`, `SEAF_DOWNLOAD_LIMIT`
|
||||
Set upload and download speeds limits. Limits are in bytes.
|
||||
|
||||
### `SEAF_SKIP_SSL_CERT`
|
||||
Skip SSL certificates verifications.
|
||||
|
||||
> Any string is considered true, omit the variable to set to false. Enable this if you have synchronization failures regarding SSL certificates.
|
||||
|
||||
### `UID`, `GID`
|
||||
Override the _UID_ and _GID_ for user running the Seafile client, hence the volume ownership.
|
||||
|
||||
## Docker Secrets
|
||||
All environments variable supports Docker Secrets, as environment variable variant suffixed with `_FILE` as files.
|
||||
|
||||
## Full example
|
||||
```bash
|
||||
{% include "assets/compose-full.yaml" %}
|
||||
```
|
||||
29
documentations/seafile.md.j2
Normal file
29
documentations/seafile.md.j2
Normal file
@@ -0,0 +1,29 @@
|
||||
Hello everyone,
|
||||
|
||||
I wanted to use files from my Seafile server within Docker containers.
|
||||
|
||||
I started looking for existing image featuring a Seafile client on Docker Hub. There are some, but with issues such as non-existant/vague documentation or improper tagging.
|
||||
|
||||
I don't know if it's something that people are looking for, but I made one. It's available at flowgunso/seafile-client in Docker Hub.
|
||||
|
||||
Example usage with docker-compose and for the docker cli are provided. Essentially, it runs `seaf-cli sync`, but you have to pass to the container your Seafile server URL, your credentials and the library ID you want to sync with. Then you can share the path `/library` as a volume to your containers for your own usages.
|
||||
|
||||
Feedback is welcome so I can keep improving it.
|
||||
|
||||
# Quick informations
|
||||
{% include "parts/badges.md.j2" %}
|
||||
|
||||
**Please use [u][flrnnc/seafile-client](https://hub.docker.com/r/flrnnc/seafile-client)[/u] instead of [u][flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client)[/u] from now on.**
|
||||
|
||||
This project is switching namespaces. The sources previously in [flwgnso-docker/docker-seafile-client](https://gitlab.com/flwgns-docker/seafile-client) are now in [flrnnc-oss/docker-seafile-client](https://gitlab.com/flrnnc-oss/docker-seafile-client). The Docker image can still be found at [flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client) but it will be deprecated, the image [flrnnc/seafile-client](https://hub.docker.com/r/flrnnc/seafile-client) should be used instead.
|
||||
|
||||
[flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client) will still be updated until usage is low enough to be archived.
|
||||
|
||||
|
||||
{% include "parts/supported_tags.md.j2" %}
|
||||
|
||||
{% include "parts/features.md.j2" %}
|
||||
|
||||
{% include "parts/usage.md.j2" %}
|
||||
|
||||
{% include "parts/troubleshooting.md.j2" %}
|
||||
41
scripts/build-images.sh
Normal file
41
scripts/build-images.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2024, florian.anceau@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Prepare the build arguments
|
||||
build_args=(CREATED=$(date -u +"%Y-%m-%dT%H:%M:%SZ"))
|
||||
[[ "$CI_COMMIT_SHA" ]] && build_args+=(REVISION=$CI_COMMIT_SHA)
|
||||
[[ "$CI_COMMIT_TAG" ]] && build_args+=(VERSION=$CI_COMMIT_TAG)
|
||||
[[ "$TARGET" ]] && build_args+=(TARGET=$TARGET)
|
||||
|
||||
# Build the build argumets string.
|
||||
build_arguments=""
|
||||
for build_arg in "${build_args[@]}"; do
|
||||
build_arguments+="--build-arg $build_arg "
|
||||
done
|
||||
|
||||
docker build \
|
||||
$build_arguments \
|
||||
--build-arg IMAGE=flowgunso \
|
||||
--tag seafile-client:$TARGET-flowgunso \
|
||||
seafile-client/
|
||||
|
||||
docker build \
|
||||
$build_arguments \
|
||||
--build-arg IMAGE=flrnnc \
|
||||
--tag seafile-client:$TARGET-flrnnc \
|
||||
seafile-client/
|
||||
93
scripts/make-documents.py
Executable file
93
scripts/make-documents.py
Executable file
@@ -0,0 +1,93 @@
|
||||
# !/usr/bin/env python
|
||||
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import os
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from gitlab import Gitlab
|
||||
|
||||
|
||||
REPOSITORY_PATH = Path(__file__).parent.parent
|
||||
|
||||
class DocumentMaker:
|
||||
|
||||
def __init__(self, filename: str) -> None:
|
||||
# Intanciate the Jinja2 renderer.
|
||||
self.directory = REPOSITORY_PATH.joinpath("documentations")
|
||||
loader = FileSystemLoader(self.directory)
|
||||
environment = Environment(loader=loader)
|
||||
self.filename = filename
|
||||
self.template = environment.get_template(filename)
|
||||
|
||||
# Instanciate the Gitlab session.
|
||||
gitlab_project_id=os.environ["CI_PROJECT_ID"]
|
||||
gitlab_private_token=os.environ["WEEKLY_BUILD_PRIVATE_TOKEN"]
|
||||
self.gitlab = Gitlab(private_token=gitlab_private_token)
|
||||
self.project = self.gitlab.projects.get(gitlab_project_id)
|
||||
|
||||
self.versions = []
|
||||
self.badges = {}
|
||||
|
||||
def get_versions(self):
|
||||
versions = []
|
||||
for path in Path("versions").iterdir():
|
||||
with open(path, "rt") as fo:
|
||||
versions.append(fo.read().strip())
|
||||
versions.sort(reverse=True)
|
||||
|
||||
# Prepare the render context.
|
||||
latest = True
|
||||
self.versions = []
|
||||
for version in versions:
|
||||
version = version.strip()
|
||||
parts = version.split(".")
|
||||
|
||||
increments = []
|
||||
blocks = []
|
||||
for part in parts:
|
||||
increments.append(part)
|
||||
section = ".".join(increments)
|
||||
blocks.append(f"`{section}`")
|
||||
|
||||
if latest:
|
||||
blocks.append("`latest`")
|
||||
latest = False
|
||||
|
||||
self.versions.append(blocks)
|
||||
|
||||
|
||||
def get_badges(self):
|
||||
badges = self.project.badges.list()
|
||||
|
||||
for badge in badges:
|
||||
name = badge.name
|
||||
link = badge.rendered_link_url
|
||||
image = badge.rendered_image_url
|
||||
links = {"link": link, "image": image}
|
||||
self.badges[name] = links
|
||||
|
||||
|
||||
def render(self):
|
||||
# Render
|
||||
# TODO: read and adapt the CHANGELOG and insert into the render.
|
||||
content = self.template.render(versions=self.versions, badges=self.badges)
|
||||
#content = template.render() # When version/ is unavailable.
|
||||
filename = Path(self.filename).with_suffix("")
|
||||
path = self.directory.joinpath(filename)
|
||||
|
||||
# Write to file
|
||||
with open(path, mode="w") as fo:
|
||||
fo.write(content)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# Argument parsing.
|
||||
parser = argparse.ArgumentParser(prog="Seafile Docker client documentation renderer")
|
||||
parser.add_argument("template", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
maker = DocumentMaker(args.template)
|
||||
maker.get_versions()
|
||||
maker.get_badges()
|
||||
maker.render()
|
||||
30
scripts/publish-documents.sh
Normal file
30
scripts/publish-documents.sh
Normal file
@@ -0,0 +1,30 @@
|
||||
# Get a token from hub.docker.com with the owner credentials.
|
||||
token=$(curl -s \
|
||||
-X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username": "'"$DOCKER_REGISTRY_USERNAME"'", "password": "'"$DOCKER_REGISTRY_TOKEN"'"}' \
|
||||
https://hub.docker.com/v2/users/login/ | jq -r .token)
|
||||
|
||||
# Generate a JSON with the README.md as the full_description.
|
||||
json=$(jq -n \
|
||||
--arg readme "$(<documentations/docker.md)" \
|
||||
'{"full_description": $readme,"description": "'"$DOCKER_REGISTRY_DESCRIPTION_FLRNNC"'"}')
|
||||
|
||||
jsonOld=$(jq -n \
|
||||
--arg readme "$(<documentations/docker-old.md)" \
|
||||
'{"full_description": $readme,"description": "'"$DOCKER_REGISTRY_DESCRIPTION_FLOWGUNSO"'"}')
|
||||
|
||||
# Update the Docker Hub repository's full_description.
|
||||
curl -siL \
|
||||
-X PATCH \
|
||||
-d "$jsonOld" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: JWT $token" \
|
||||
"https://hub.docker.com/v2/repositories/$DOCKER_REGISTRY_IMAGE_FLOWGUNSO/"
|
||||
|
||||
curl -siL \
|
||||
-X PATCH \
|
||||
-d "$json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: JWT $token" \
|
||||
"https://hub.docker.com/v2/repositories/$DOCKER_REGISTRY_IMAGE_FLRNNC/"
|
||||
54
scripts/publish-images.sh
Normal file
54
scripts/publish-images.sh
Normal file
@@ -0,0 +1,54 @@
|
||||
# !/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2024, florian.anceau@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
set -ex
|
||||
|
||||
raise() {
|
||||
echo $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Grab version with the container
|
||||
version="$(docker run --rm seafile-client:$TARGET-flrnnc cat -s /SEAFILE_VERSION)"
|
||||
version="$(echo ${version%-*})"
|
||||
|
||||
# Output the version to an artifact for documentation rendering.
|
||||
mkdir -p versions/
|
||||
echo $version >> "versions/$TARGET"
|
||||
|
||||
# Generate version tags.
|
||||
tags=()
|
||||
[[ "$TARGET" =~ "unstable" ]] && tags+=("latest")
|
||||
for version_component in $(echo $version | tr '.' '\n'); do
|
||||
tag+="$version_component"
|
||||
tags+=("$tag")
|
||||
tag+="."
|
||||
done
|
||||
|
||||
# Tag then push to the Docker Hub registry.
|
||||
echo $DOCKER_REGISTRY_TOKEN | docker login --password-stdin --username $DOCKER_REGISTRY_USERNAME
|
||||
for tag in "${tags[@]}"; do
|
||||
docker tag seafile-client:$TARGET-flowgunso $DOCKER_REGISTRY_IMAGE_FLOWGUNSO:$tag
|
||||
docker push $DOCKER_REGISTRY_IMAGE_FLOWGUNSO:$tag
|
||||
done
|
||||
|
||||
for tag in "${tags[@]}"; do
|
||||
docker tag seafile-client:$TARGET-flrnnc $DOCKER_REGISTRY_IMAGE_FLRNNC:$tag
|
||||
docker push $DOCKER_REGISTRY_IMAGE_FLRNNC:$tag
|
||||
done
|
||||
132
scripts/schedule-build.py
Normal file
132
scripts/schedule-build.py
Normal file
@@ -0,0 +1,132 @@
|
||||
# !/usr/bin/env python
|
||||
|
||||
import os
|
||||
import argparse
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
from requests.auth import HTTPBasicAuth
|
||||
|
||||
from gitlab import Gitlab
|
||||
|
||||
|
||||
class Scheduler:
|
||||
|
||||
WATTTIME_SIGNAL_TYPE="co2_moer"
|
||||
|
||||
def __init__(self, watttime_username, watttime_password, gitlab_private_token,
|
||||
gitlab_project_id, gitlab_scheduled_pipeline_id):
|
||||
# Instanciate the WattTime session.
|
||||
url = "https://api.watttime.org/login"
|
||||
response = requests.get(url, auth=HTTPBasicAuth(watttime_username, watttime_password))
|
||||
payload = response.json()
|
||||
token = payload["token"]
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
self.watttime = requests.session()
|
||||
self.watttime.headers = headers
|
||||
|
||||
# Instanciate the Gitlab session and grab the Weekly build scheduled pipeline.
|
||||
self.gitlab = Gitlab(private_token=gitlab_private_token)
|
||||
project = self.gitlab.projects.get(gitlab_project_id)
|
||||
self.pipeline = project.pipelineschedules.get(gitlab_scheduled_pipeline_id)
|
||||
|
||||
def geolocate(self):
|
||||
url = "https://ipinfo.io"
|
||||
response = requests.get(url)
|
||||
payload = response.json()
|
||||
geolocation = payload["loc"]
|
||||
self.latitude, self.longitude = geolocation.split(",")
|
||||
|
||||
def load_shift(self):
|
||||
|
||||
# Get region from geolocation.
|
||||
# TODO: uncomment once premium plan
|
||||
# url = "https://api.watttime.org/v3/region-from-loc"
|
||||
# params = {
|
||||
# "latitude": self.latitude,
|
||||
# "longitude": self.longitude,
|
||||
# "signal_type": self.WATTTIME_SIGNAL_TYPE}
|
||||
# response = self.watttime.get(url, params=params)
|
||||
# payload = response.json()
|
||||
# region = payload["region"]
|
||||
|
||||
# Get the forecast for said region.
|
||||
# TODO: don't override the region, get a premium plan
|
||||
url = "https://api.watttime.org/v3/forecast"
|
||||
region = "CAISO_NORTH" # Override the region until I get a premium plan
|
||||
params = {"region": region, "signal_type": self.WATTTIME_SIGNAL_TYPE}
|
||||
response = self.watttime.get(url, params=params)
|
||||
payload = response.json()
|
||||
data = payload["data"]
|
||||
|
||||
# Look for the lowest value and it's datetime. Store the current value to know improvements.
|
||||
lowest_value: float = None
|
||||
for obj in data:
|
||||
value = obj["value"]
|
||||
point_time = datetime.fromisoformat(obj["point_time"])
|
||||
|
||||
if not lowest_value:
|
||||
self.now_value = self.lowest_value = value
|
||||
self.now = self.then = point_time
|
||||
continue
|
||||
|
||||
if value < lowest_value:
|
||||
lowest_value = value
|
||||
self.then = point_time
|
||||
|
||||
def metrics(self):
|
||||
# Write WattTime metrics.
|
||||
metrics = {}
|
||||
metrics["watttime_now"] = self.now_value
|
||||
metrics["watttime_lowest"] = self.lowest_value
|
||||
metrics["now"] = self.now
|
||||
metrics["self.then"] = self.then
|
||||
with open("metrics.txt", "wt") as fileobject:
|
||||
for metric, value in metrics.items():
|
||||
fileobject.write(f"{metric} {value}\n")
|
||||
# TODO: track the metrics of energy cost/gain
|
||||
|
||||
def schedule(self):
|
||||
# Test ownership prior to overtaking ownership.
|
||||
self.gitlab.auth()
|
||||
if self.pipeline.owner["id"] != self.gitlab.user.id:
|
||||
self.pipeline.take_ownership()
|
||||
|
||||
# Set pipeline cron schedule to WattTime's Load Shift best moment.
|
||||
cron = f"{self.then.minute} {self.then.hour} {self.then.day} {self.then.month} *"
|
||||
self.pipeline.cron = cron
|
||||
self.pipeline.active = True
|
||||
self.pipeline.save()
|
||||
|
||||
def unschedule(self):
|
||||
self.pipeline.active = False
|
||||
self.pipeline.save()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="",
|
||||
description="",
|
||||
epilog=""
|
||||
)
|
||||
parser.add_argument("--disable", action="store_true")
|
||||
args = parser.parse_args()
|
||||
disable = args.disable
|
||||
|
||||
scheduler = Scheduler(
|
||||
watttime_username=os.environ["WATTTIME_USERNAME"],
|
||||
watttime_password=os.environ["WATTTIME_PASSWORD"],
|
||||
gitlab_project_id=os.environ["CI_PROJECT_ID"],
|
||||
gitlab_private_token=os.environ["WEEKLY_BUILD_PRIVATE_TOKEN"],
|
||||
gitlab_scheduled_pipeline_id=os.environ["WEEKLY_BUILD_PIPELINE_ID"]
|
||||
)
|
||||
|
||||
if disable:
|
||||
scheduler.unschedule()
|
||||
sys.exit()
|
||||
|
||||
scheduler.geolocate()
|
||||
scheduler.load_shift()
|
||||
scheduler.metrics()
|
||||
scheduler.schedule()
|
||||
34
scripts/update-build-badge.py
Normal file
34
scripts/update-build-badge.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# !/usr/bin/env python
|
||||
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
from gitlab import Gitlab
|
||||
|
||||
|
||||
class BuildBadgeUpdater:
|
||||
|
||||
def __init__(self, gitlab_private_token, gitlab_project_id, gitlab_build_badge_id):
|
||||
|
||||
# Instanciate the Gitlab session and grab the Weekly build scheduled pipeline.
|
||||
self.gitlab = Gitlab(private_token=gitlab_private_token)
|
||||
project = self.gitlab.projects.get(gitlab_project_id)
|
||||
self.badge = project.badges.get(gitlab_build_badge_id)
|
||||
|
||||
def update(self):
|
||||
now = datetime.now()
|
||||
date = now.strftime(r"%Y--%m--%d")
|
||||
image_url = f"https://img.shields.io/badge/_-{date}-_?label=last%20build&color=light-green"
|
||||
self.badge.image_url = image_url
|
||||
self.badge.save()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
build_badge_updater = BuildBadgeUpdater(
|
||||
gitlab_project_id=os.environ["CI_PROJECT_ID"],
|
||||
gitlab_private_token=os.environ["WEEKLY_BUILD_PRIVATE_TOKEN"],
|
||||
gitlab_build_badge_id=os.environ["BUILD_BADGE_ID"]
|
||||
)
|
||||
|
||||
build_badge_updater.update()
|
||||
58
seafile-client/Dockerfile
Normal file
58
seafile-client/Dockerfile
Normal file
@@ -0,0 +1,58 @@
|
||||
ARG TARGET=unstable
|
||||
FROM debian:${TARGET}-slim
|
||||
|
||||
ARG UID
|
||||
ARG GID
|
||||
ARG IMAGE
|
||||
ENV UID 1000
|
||||
ENV GID 1000
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
ENV IMAGE ${IMAGE}
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install \
|
||||
--no-install-recommends \
|
||||
--yes \
|
||||
seafile-cli \
|
||||
oathtool \
|
||||
ca-certificates \
|
||||
gnupg \
|
||||
sudo && \
|
||||
apt-get clean && apt-get autoclean && \
|
||||
rm -rf \
|
||||
/var/log/fsck/*.log \
|
||||
/var/log/apt/*.log \
|
||||
/var/cache/debconf/*.dat-old \
|
||||
/var/lib/apt/lists/* && \
|
||||
groupmod -g 90 users
|
||||
|
||||
COPY --chmod=755 entrypoint-docker.sh /entrypoint.sh
|
||||
COPY issue /etc/issue
|
||||
|
||||
RUN echo '[ ! -z $TERM ] && cat /etc/issue' >> /root/.bashrc && \
|
||||
groupadd --gid $GID seafile && \
|
||||
useradd --uid $UID --gid $GID --shell /bin/bash --create-home seafile && \
|
||||
mkdir /library /seafile && \
|
||||
chown seafile:seafile /seafile /library && \
|
||||
apt-cache show seafile-cli | grep 'Version: ' | awk '{print $2}' > /SEAFILE_VERSION
|
||||
|
||||
COPY --chmod=755 --chown=seafile:seafile entrypoint-seafile.py /home/seafile/entrypoint.py
|
||||
|
||||
ARG CREATED
|
||||
ARG REVISION
|
||||
ARG VERSION
|
||||
LABEL org.opencontainers.image.created=${CREATED}
|
||||
LABEL org.opencontainers.image.authors="florian.anceau@gmail.com"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/r/flrnnc/seafile-client"
|
||||
LABEL org.opencontainers.image.documentation="https://gitlab.com/flrnnc-oss/docker-seafile-client"
|
||||
LABEL org.opencontainers.image.source="https://gitlab.com/flrnnc-oss/docker-seafile-client"
|
||||
LABEL org.opencontainers.image.version=${VERSION}
|
||||
LABEL org.opencontainers.image.revision=${REVISION}
|
||||
LABEL org.opencontainers.image.licenses="GPL-3.0"
|
||||
LABEL org.opencontainers.image.title="Seafile Docker client"
|
||||
LABEL org.opencontainers.image.description="Sync Seafile librairies within Docker containers."
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
CMD ["/home/seafile/entrypoint.py"]
|
||||
HEALTHCHECK \
|
||||
CMD ["/entrypoint.sh", "/home/seafile/entrypoint.py", "--healthcheck"]
|
||||
42
seafile-client/entrypoint-docker.sh
Executable file
42
seafile-client/entrypoint-docker.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2024, florian.anceau@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
groupmod -g $GID seafile &> /dev/null
|
||||
usermod -u $UID -g $GID seafile &> /dev/null
|
||||
|
||||
|
||||
if [ "$IMAGE" == "flowgunso" ]; then
|
||||
echo
|
||||
echo -e "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
|
||||
echo -e "┃ \e[1mPlease use \e[4mflrnnc/seafile-client\e[24m instead of \e[4mflowgunso/seafile-client\e[24m which will be deprecated...\e[0m ┃"
|
||||
echo -e "┃ See the information notices at: ┃"
|
||||
echo -e "┃ \thttps://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573 ┃"
|
||||
echo -e "┃ \thttps://gitlab.com/flrnnc-oss/docker-seafile-client ┃"
|
||||
echo -e "┃ \thttps://hub.docker.com/r/flowgunso/seafile-client ┃"
|
||||
echo -e "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
|
||||
echo
|
||||
fi
|
||||
|
||||
sudo \
|
||||
-HE \
|
||||
-u seafile \
|
||||
-- "$@"
|
||||
312
seafile-client/entrypoint-seafile.py
Executable file
312
seafile-client/entrypoint-seafile.py
Executable file
@@ -0,0 +1,312 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import seafile
|
||||
|
||||
|
||||
class BadConfiguration(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_configuration(variable: str, *args) -> Any:
|
||||
"""Helper function to get a configuration.
|
||||
see https://gitlab.com/-/snippets/1941025
|
||||
"""
|
||||
|
||||
# Assign the default value from the first item of *args.
|
||||
if args:
|
||||
default = args[0]
|
||||
|
||||
# Try to get the variable from a Docker Secret.
|
||||
try:
|
||||
file = os.environ[f"{variable}_FILE"]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
with open(file, "rt") as fo:
|
||||
return fo.read()
|
||||
|
||||
# Try to get the variable from an environment variable.
|
||||
try:
|
||||
return os.environ[variable]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Try to return the default value,
|
||||
# if no default exist, then it is a required variable.
|
||||
try:
|
||||
return default
|
||||
except UnboundLocalError:
|
||||
raise BadConfiguration(
|
||||
f"Environment variable {variable} was not found but is required."
|
||||
)
|
||||
|
||||
class Client:
|
||||
|
||||
def __init__(self) -> None:
|
||||
# Client configuration
|
||||
self.username: str = get_configuration("SEAF_USERNAME")
|
||||
self.password: str = get_configuration("SEAF_PASSWORD")
|
||||
self.url: str = get_configuration("SEAF_SERVER_URL")
|
||||
self.skip_ssl_cert: bool = bool(get_configuration("SEAF_SKIP_SSL_CERT", None))
|
||||
self.upload_limit: int = get_configuration("SEAF_UPLOAD_LIMIT", None)
|
||||
self.download_limit: int = get_configuration("SEAF_DOWNLOAD_LIMIT", None)
|
||||
self.mfa_secret: str = get_configuration("SEAF_2FA_SECRET", None)
|
||||
|
||||
# Paths
|
||||
self.ini = Path.home().joinpath(".ccnet", "seafile.ini")
|
||||
self.log = Path.home().joinpath(".ccnet", "logs", "seafile.log")
|
||||
self.seafile = Path("/seafile")
|
||||
self.socket = self.seafile.joinpath("seafile-data", "seafile.sock")
|
||||
self.target = Path("/library")
|
||||
|
||||
# Binaries, instances.
|
||||
if self.socket.exists():
|
||||
self.rpc = seafile.RpcClient(str(self.socket))
|
||||
|
||||
self.binary = ["seaf-cli"]
|
||||
self._get_librairies()
|
||||
|
||||
def _get_librairies(self):
|
||||
self.libraries = {}
|
||||
|
||||
# Single library use case. Mutually exclusive to mulitple labraries use case.
|
||||
single_library_variables = ["SEAF_LIBRARY", "SEAF_LIBRARY_UUID", "SEAF_LIBRARY_PASSWORD"]
|
||||
if any(environ in single_library_variables for environ in os.environ):
|
||||
logger.info("Single library detected. Multiple libraries will be ignored.")
|
||||
library = {}
|
||||
|
||||
# Grab the UUID, usin both the
|
||||
uuid = None
|
||||
if legacy := os.getenv("SEAF_LIBRARY_UUID", None):
|
||||
logger.warning("SEAF_LIBRARY_UUID is obsolete, please use SEAF_LIBRARY instead.")
|
||||
uuid = legacy
|
||||
if current := os.getenv("SEAF_LIBRARY", None):
|
||||
uuid = current
|
||||
|
||||
# Exit if no UUID was provided, continue otherwise.
|
||||
if uuid is None:
|
||||
raise Exception("Please provide an UUID with SEAF_LIBRARY for single library usage.")
|
||||
library["uuid"] = uuid
|
||||
|
||||
if password := os.getenv("SEAF_LIBRARY_PASSWORD", None):
|
||||
library["password"] = password
|
||||
|
||||
# Assign and return a default library.
|
||||
self.libraries["_"] = library
|
||||
return
|
||||
|
||||
# Multiple libraries use case.
|
||||
# Loop over all sorted variables prefixed with SEAF_LIBRARY.
|
||||
for variable in sorted(os.environ):
|
||||
if variable.startswith("SEAF_LIBRARY"):
|
||||
|
||||
# Get the variable name.
|
||||
name = variable.split("_")[2].lower()
|
||||
|
||||
# Read the password as a secret.
|
||||
if "_PASSWORD" in variable:
|
||||
password = get_configuration(variable, None)
|
||||
try:
|
||||
if password:
|
||||
self.libraries[name]["password"] = password
|
||||
except KeyError:
|
||||
logger.warning(f"Cannot set a password to unknown library {name}")
|
||||
|
||||
# Or got the name, build the dictionary with the name and uuid.
|
||||
else:
|
||||
self.libraries[name] = {}
|
||||
uuid = os.environ[variable]
|
||||
self.libraries[name]["uuid"] = uuid
|
||||
|
||||
def initialize(self):
|
||||
# Initialize the Seafile client.
|
||||
logger.info("Initializing `seaf-cli`.")
|
||||
if not self.ini.exists():
|
||||
logger.info("Seafile .ini file not found, running `seaf-cli init`")
|
||||
#self.ini.parent.parent.mkdir(parents=True, exist_ok=True)
|
||||
subprocess.run(self.binary + ["init", "-d", str(self.seafile)])
|
||||
while not self.ini.exists():
|
||||
logging.debug("Waiting for the .ini file to be created...")
|
||||
time.sleep(1)
|
||||
|
||||
# Start the Seafile client.
|
||||
logger.info("Starting `seaf-cli`.")
|
||||
subprocess.run(self.binary + ["start"])
|
||||
while not self.socket.exists():
|
||||
logger.debug("Waiting for the Seafile client socket to be created.")
|
||||
time.sleep(1)
|
||||
|
||||
self.rpc = seafile.RpcClient(str(self.socket))
|
||||
|
||||
def configure(self):
|
||||
command = self.binary + ["config"]
|
||||
if self.skip_ssl_cert:
|
||||
subprocess.run(command +["-k", "disable_verify_certificate", "-v", str(self.skip_ssl_cert)])
|
||||
if self.download_limit:
|
||||
subprocess.run(command +["-k", "download_limit", "-v", self.download_limit])
|
||||
if self.upload_limit:
|
||||
subprocess.run(command +["-k", "upload_limit", "-v", self.upload_limit])
|
||||
|
||||
def synchronize(self):
|
||||
core = self.binary + ["sync", "-u", self.username, "-p", self.password, "-s", self.url]
|
||||
for name, configuration in self.libraries.items():
|
||||
uuid = configuration["uuid"]
|
||||
|
||||
# Check if repository is already synced.
|
||||
repository = self.rpc.get_repo(uuid)
|
||||
if repository is not None:
|
||||
logger.info(f"Library {name} is already synced.")
|
||||
continue
|
||||
|
||||
command = core + ["-l", uuid]
|
||||
|
||||
if "password" in configuration:
|
||||
password = configuration["password"]
|
||||
command += ["-e", password]
|
||||
|
||||
target = self.target if name == "_" else self.target.joinpath(name)
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
command += ["-d", str(target)]
|
||||
|
||||
if self.mfa_secret:
|
||||
totp = subprocess.run(
|
||||
f"oathtool --base32 --totp {self.mfa_secret}",
|
||||
text=True,
|
||||
capture_stdout=True).stdout
|
||||
command += ["-a", totp]
|
||||
|
||||
logging.debug(f"Running {' '.join(command)}")
|
||||
subprocess.run(command)
|
||||
|
||||
def follow(self):
|
||||
logging.debug(f"Running `tail -v -f {self.log}`")
|
||||
subprocess.run(["tail", "-v", "-f", self.log])
|
||||
|
||||
def healthcheck(self):
|
||||
|
||||
tasks = self.rpc.get_clone_tasks()
|
||||
healthy = True
|
||||
for task in tasks:
|
||||
name = task.repo_name
|
||||
state = task.state
|
||||
|
||||
if task.state == 'done':
|
||||
continue
|
||||
elif state == "fetch":
|
||||
tx_task = self.rpc.find_transfer_task(task.repo_id)
|
||||
percentage = 0 if tx_task.block_done == 0 else tx_task.block_done / tx_task.block_total * 100
|
||||
rate = 0 if tx_task.rate == 0 else tx_task.rate / 1024.0
|
||||
print(f"{name:<50s}\t{state:<20s}\t{percentage:<.1f}%, {rate:<.1f}KB/s")
|
||||
elif task.state == "error":
|
||||
healthy = False
|
||||
error = self.rpc.sync_error_id_to_str(task.error)
|
||||
print(f"{name:<50s}\t{state:<20s}\t{error}")
|
||||
else:
|
||||
print(f"{name:<50s}\t{state:<20s}")
|
||||
|
||||
repos = self.rpc.get_repo_list(-1, -1)
|
||||
for repo in repos:
|
||||
name = repo.name
|
||||
|
||||
auto_sync_enabled = self.rpc.is_auto_sync_enabled()
|
||||
if not auto_sync_enabled or not repo.auto_sync:
|
||||
state = "auto sync disabled"
|
||||
print(f"{name:<50s}\t{state:<20s}")
|
||||
continue
|
||||
|
||||
task = self.rpc.get_repo_sync_task(repo.id)
|
||||
if task is None:
|
||||
state = "waiting for sync"
|
||||
print(f"{name:<50s}\t{state:<20s}")
|
||||
continue
|
||||
|
||||
state = task.state
|
||||
if state in ['uploading', 'downloading']:
|
||||
tx_task = self.rpc.find_transfer_task(repo.id)
|
||||
if tx_task.rt_state == "data":
|
||||
state += " files"
|
||||
percentage = 0 if tx_task.block_done == 0 else tx_task.block_done / tx_task.block_total * 100
|
||||
rate = 0 if tx_task.rate == 0 else tx_task.rate / 1024.0
|
||||
print(f"{name:<50s}\t{state:<20s}\t{percentage:<.1f}%, {rate:<.1f}KB/s")
|
||||
elif tx_task.rt_state == "fs":
|
||||
state += " files list"
|
||||
percentage = 0 if tx_task.fs_objects_done == 0 else tx_task.fs_objects_done / tx_task.fs_objects_total * 100
|
||||
print(f"{name:<50s}\t{state:<20s}\t{percentage:<.1f}%")
|
||||
elif state == 'error':
|
||||
healthy = False
|
||||
error = self.rpc.sync_error_id_to_str(task.error)
|
||||
print(f"{name:<50s}\t{state:<20s}\t{error}")
|
||||
else:
|
||||
print(f"{name:<50s}\t{state:<20s}")
|
||||
|
||||
|
||||
def entrypoint():
|
||||
try:
|
||||
logging.debug("Instanciating the client")
|
||||
client = Client()
|
||||
except BadConfiguration as e:
|
||||
logger.error(f"Bad configuration: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
logging.debug("Initializing the client")
|
||||
client.initialize()
|
||||
logging.debug("Configuring the client")
|
||||
client.configure()
|
||||
logging.debug("Synchronizing the client")
|
||||
client.synchronize()
|
||||
logging.debug("Following the client")
|
||||
client.follow()
|
||||
|
||||
|
||||
debug = get_configuration("DEBUG", False)
|
||||
level = logging.INFO
|
||||
format = "%(asctime)s - %(levelname)s - %(message)s"
|
||||
if debug:
|
||||
level = logging.DEBUG
|
||||
format = "%(asctime)s - %(filename)s:%(lineno)d - %(levelname)s - %(message)s"
|
||||
logging.basicConfig(format=format, level=level)
|
||||
logger = logging.getLogger()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="",
|
||||
description="",
|
||||
epilog=""
|
||||
)
|
||||
parser.add_argument("--healthcheck", action="store_true")
|
||||
args = parser.parse_args()
|
||||
healthcheck = args.healthcheck
|
||||
|
||||
if healthcheck:
|
||||
logger.disabled = True
|
||||
|
||||
try:
|
||||
logging.debug("Instanciating the client")
|
||||
client = Client()
|
||||
except BadConfiguration as e:
|
||||
logger.error(f"Bad configuration: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if healthcheck:
|
||||
logging.debug("Running healthchecks")
|
||||
sys.exit(client.healthcheck())
|
||||
|
||||
logging.debug("Initializing the client")
|
||||
client.initialize()
|
||||
logging.debug("Configuring the client")
|
||||
client.configure()
|
||||
logging.debug("Synchronizing the client")
|
||||
client.synchronize()
|
||||
logging.debug("Following the client")
|
||||
client.follow()
|
||||
|
||||
4
seafile-client/issue
Normal file
4
seafile-client/issue
Normal file
@@ -0,0 +1,4 @@
|
||||
┌───────────────────────┐
|
||||
│ Seafile Docker client │
|
||||
└───────────────────────┘
|
||||
Run `./entrypoint.sh bash` to login as the seafile user.
|
||||
6
tests/image/Dockerfile
Normal file
6
tests/image/Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
ARG TARGET=unstable
|
||||
FROM seafile-client:${TARGET}-flrnnc
|
||||
|
||||
COPY --chmod=755 test_binaries.sh /test.sh
|
||||
|
||||
CMD ["/test.sh"]
|
||||
22
assets/infinite-seaf-cli-start.sh → tests/image/test_binaries.sh
Executable file → Normal file
22
assets/infinite-seaf-cli-start.sh → tests/image/test_binaries.sh
Executable file → Normal file
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
# Copyright (C) 2019-2024, florian.anceau@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -16,10 +16,18 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
set -x
|
||||
failures=()
|
||||
binaries=(seaf-cli oathtool grep)
|
||||
|
||||
sleep 10
|
||||
while true; do
|
||||
/usr/bin/seaf-cli start
|
||||
sleep 3600
|
||||
done
|
||||
for binary in "${binaries[@]}"; do
|
||||
if ! [ -x "$(command -v $binary)" ]; then
|
||||
echo "$binary was not found"
|
||||
failures+=($binary)
|
||||
else
|
||||
echo "$binary was found"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#failures[@]} -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
56
tests/mock/compose.yaml
Normal file
56
tests/mock/compose.yaml
Normal file
@@ -0,0 +1,56 @@
|
||||
name: mock-docker-seafile-client
|
||||
|
||||
services:
|
||||
mariadb:
|
||||
image: mariadb:10.11
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=password # Requested, set the root's password of MySQL service.
|
||||
- MYSQL_LOG_CONSOLE=true
|
||||
- MARIADB_AUTO_UPGRADE=1
|
||||
volumes:
|
||||
- database:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store.
|
||||
|
||||
memcached:
|
||||
image: memcached:1.6.18
|
||||
container_name: seafile-memcached
|
||||
entrypoint: memcached -m 256
|
||||
|
||||
seafile:
|
||||
image: seafileltd/seafile-mc:latest
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- seafile:/shared # Requested, specifies the path to Seafile data persistent store.
|
||||
environment:
|
||||
- DB_HOST=mariadb
|
||||
- DB_ROOT_PASSWD=password # Requested, the value should be root's password of MySQL service.
|
||||
- TIME_ZONE=Etc/UTC # Optional, default is UTC. Should be uncomment and set to your local time zone.
|
||||
- SEAFILE_ADMIN_EMAIL=seafile@localhost # Specifies Seafile admin user, default is 'me@example.com'.
|
||||
- SEAFILE_ADMIN_PASSWORD=password # Specifies Seafile admin password, default is 'asecret'.
|
||||
- SEAFILE_SERVER_LETSENCRYPT=false # Whether to use https or not.
|
||||
depends_on:
|
||||
- mariadb
|
||||
- memcached
|
||||
|
||||
client:
|
||||
image: seafile-client:${TARGET}-flowgunso
|
||||
volumes:
|
||||
#- library:/library
|
||||
- data:/seafile
|
||||
# user: "1000:1000"
|
||||
environment:
|
||||
SEAF_SERVER_URL: "http://seafile"
|
||||
SEAF_USERNAME: "seafile@localhost"
|
||||
SEAF_PASSWORD: "password"
|
||||
SEAF_LIBRARY: "1b7d4e92-6753-4c4a-85b0-42566eab42c8"
|
||||
DEBUG: 1
|
||||
UID: 1000
|
||||
GID: 100
|
||||
depends_on:
|
||||
- seafile
|
||||
|
||||
volumes:
|
||||
database:
|
||||
seafile:
|
||||
library:
|
||||
data:
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
not_imported=true
|
||||
while $not_imported; do
|
||||
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 8756C4F765C9AC3CB6B85D62379CE192D401AB61
|
||||
if [ $? -eq 0 ]; then
|
||||
not_imported=false
|
||||
else
|
||||
sleep 5
|
||||
fi
|
||||
done
|
||||
@@ -1,70 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Restrict production build to tag matching MAJOR.MINOR.REVISION.
|
||||
if ! [[ "$CI_COMMIT_TAG" =~ ^[0-9]+[.][0-9]+[.][0-9]+$ ]]; then
|
||||
echo "Version number must match major.minor.revision!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# When this stage is ran from 'push', the build target is BUILD_LATEST.
|
||||
# When this stage is ran from 'trigger', the build target must be provided.
|
||||
# Otherwise, stop the stage.
|
||||
if [ $CI_PIPELINE_SOURCE == "push" ]; then
|
||||
BUILD_LATEST=true
|
||||
elif [ $CI_PIPELINE_SOURCE == "trigger" ]; then
|
||||
if [ -z $BUILD_LATEST ] && \
|
||||
[ -z $BUILD_MAJOR ] && \
|
||||
[ -z $BUILD_MINOR ] && \
|
||||
[ -z $BUILD_REVISION ]; then
|
||||
echo "You must provide build targets to this stage when ran from Pipeline Triggers."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "This stage is restricted to 'push' or 'trigger' Pipeline sources."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cascade the builds by inheritance.
|
||||
if [ $BUILD_LATEST ]; then BUILD_MAJOR=true; BUILD_MINOR=true; BUILD_REVISION=true; fi
|
||||
if [ $BUILD_MAJOR ]; then BUILD_MINOR=true; BUILD_REVISION=true; fi
|
||||
if [ $BUILD_MINOR ]; then BUILD_REVISION=true; fi
|
||||
|
||||
# Define MAJOR, MINOR and REVISION version numbers.
|
||||
MAJOR_NUMBER=$(echo "$CI_COMMIT_TAG" | awk -F \. {'print $1'})
|
||||
MINOR_NUMBER=$(echo "$CI_COMMIT_TAG" | awk -F \. {'print $2'})
|
||||
REVISION_NUMBER=$(echo "$CI_COMMIT_TAG" | awk -F \. {'print $3'})
|
||||
MAJOR=$MAJOR_NUMBER
|
||||
MINOR=$MAJOR.$MINOR_NUMBER
|
||||
REVISION=$MINOR.$REVISION_NUMBER
|
||||
|
||||
# Always build with all tags, there's a single build anyway.
|
||||
docker build \
|
||||
-t index.docker.io/$CI_REGISTRY_IMAGE:latest \
|
||||
-t index.docker.io/$CI_REGISTRY_IMAGE:$MAJOR \
|
||||
-t index.docker.io/$CI_REGISTRY_IMAGE:$MINOR \
|
||||
-t index.docker.io/$CI_REGISTRY_IMAGE:$REVISION .
|
||||
|
||||
# Login with Docker Registry.
|
||||
echo $CI_REGISTRY_BOT_PASSWORD | docker login -u $CI_REGISTRY_BOT_USERNAME docker.io --password-stdin
|
||||
|
||||
# Only push requested builds.
|
||||
if [ $BUILD_LATEST ]; then docker push index.docker.io/$CI_REGISTRY_IMAGE:latest; fi
|
||||
if [ $BUILD_MAJOR ]; then docker push index.docker.io/$CI_REGISTRY_IMAGE:$MAJOR; fi
|
||||
if [ $BUILD_MINOR ]; then docker push index.docker.io/$CI_REGISTRY_IMAGE:$MINOR; fi
|
||||
if [ $BUILD_REVISION ]; then docker push index.docker.io/$CI_REGISTRY_IMAGE:$REVISION; fi
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019, flow.gunso@gmail.com
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Restrict to pipeline triggered by pushes.
|
||||
if [ $CI_PIPELINE_SOURCE != "push" ]; then
|
||||
echo "This must be only ran from pushes."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Login with Docker Registry.
|
||||
echo $CI_REGISTRY_BOT_PASSWORD | docker login -u $CI_REGISTRY_BOT_USERNAME docker.io --password-stdin
|
||||
|
||||
# Build and push as staging.
|
||||
docker build -t index.docker.io/$CI_REGISTRY_IMAGE:staging .
|
||||
docker push index.docker.io/$CI_REGISTRY_IMAGE:staging
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Based upon https://gist.github.com/jlhawn/8f218e7c0b14c941c41f
|
||||
# and https://github.com/moikot/golang-dep/blob/master/.travis/push.sh
|
||||
|
||||
# Install required system packages.
|
||||
apk add curl jq
|
||||
|
||||
# Get a token from hub.docker.com with the owner credentials.
|
||||
token=$(curl -s \
|
||||
-X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username": "'"$CI_REGISTRY_OWNER_USERNAME"'", "password": "'"$CI_REGISTRY_OWNER_PASSWORD"'"}' \
|
||||
https://hub.docker.com/v2/users/login/ | jq -r .token)
|
||||
|
||||
# Generate a JSON with the README.md as the full_description.
|
||||
json=$(jq -n \
|
||||
--arg readme "$(<README.md)" \
|
||||
'{"full_description": $readme}')
|
||||
|
||||
# Update the Docker Hub repository's full_description.
|
||||
curl -s -L \
|
||||
-X PATCH \
|
||||
-d "$json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: JWT $token" \
|
||||
https://cloud.docker.com/v2/repositories/$CI_REGISTRY_IMAGE/
|
||||
Reference in New Issue
Block a user