Merge branch 'milestone--v3' into 'master'
Version 3 Closes #24, #10, #38, #39, #6, #42, #9, #25, #44, #43, #41, and #37 See merge request flwgns-docker/seafile-client!9
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
.idea/
|
||||
*.pyc
|
||||
docker-compose.test.yml
|
||||
venv/
|
||||
*.description
|
||||
.env/
|
||||
tarballs/
|
||||
VERSIONS.txt
|
||||
documentations/*.md
|
||||
|
||||
108
.gitlab-ci.yml
108
.gitlab-ci.yml
@@ -3,67 +3,101 @@ image: docker:latest
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
.parallel:
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: [oldstable, stable, unstable]
|
||||
|
||||
stages:
|
||||
- report
|
||||
- build
|
||||
- test
|
||||
- publish
|
||||
- release
|
||||
|
||||
before_script:
|
||||
- apk add bash git
|
||||
- apk add bash git curl jq make
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- /bin/bash .utilities/check.sh
|
||||
- /bin/bash -e .utilities/build.sh
|
||||
- make build
|
||||
- make save
|
||||
extends: .parallel
|
||||
only:
|
||||
- merge_requests
|
||||
- tags
|
||||
artifacts:
|
||||
paths:
|
||||
- "$CI_PROJECT_NAME.tar"
|
||||
|
||||
build:description_template:
|
||||
image: python:3.8-alpine
|
||||
stage: build
|
||||
script: sh -e .utilities/templates/templater.sh
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
paths:
|
||||
- "*.description"
|
||||
- "tarballs/"
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script: /bin/bash -e .utilities/test.sh
|
||||
script:
|
||||
- make load
|
||||
- make build-test
|
||||
- make test
|
||||
extends: .parallel
|
||||
needs:
|
||||
- job: build
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: oldstable
|
||||
- TARGET: stable
|
||||
- TARGET: unstable
|
||||
only:
|
||||
- merge_requests
|
||||
- tags
|
||||
artifacts:
|
||||
paths:
|
||||
- tarballs/
|
||||
|
||||
publish-images:
|
||||
stage: release
|
||||
script:
|
||||
- make load
|
||||
- make publish-images
|
||||
needs:
|
||||
- job: build
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: oldstable
|
||||
- TARGET: stable
|
||||
- TARGET: unstable
|
||||
- job: test
|
||||
extends: .parallel
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
paths:
|
||||
- "$CI_PROJECT_NAME.tar"
|
||||
- tarballs/
|
||||
- versions/*
|
||||
|
||||
publish:
|
||||
stage: publish
|
||||
script: /bin/bash -e .utilities/publish.sh
|
||||
make-documents:
|
||||
stage: release
|
||||
script:
|
||||
- apk add py3-jinja2
|
||||
- make documents
|
||||
needs:
|
||||
- job: publish-images
|
||||
parallel:
|
||||
matrix:
|
||||
- TARGET: oldstable
|
||||
- TARGET: stable
|
||||
- TARGET: unstable
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
paths:
|
||||
- "$CI_PROJECT_NAME.tar"
|
||||
- versions/*
|
||||
- documentations/*.md
|
||||
|
||||
#update_docker_hub_full_description:
|
||||
# stage: publish
|
||||
# script: /bin/bash -e .utilities/update-docker-hub-full-description.sh
|
||||
# only:
|
||||
# - master
|
||||
|
||||
bot:package_update_notification:
|
||||
stage: report
|
||||
script: bash -e .utilities/package_update_notifier.sh
|
||||
publish-documents:
|
||||
stage: release
|
||||
script:
|
||||
- make publish-documents
|
||||
needs:
|
||||
- job: make-documents
|
||||
only:
|
||||
- schedules
|
||||
# see https://docs.gitlab.com/ce/ci/yaml/README.html#onlyexcept-advanced for feature updates
|
||||
# refs:
|
||||
# - schedules
|
||||
# variables:
|
||||
# - $SCHEDULE_ID == $PACKAGE_UPDATE_NOTIFICATION_SCHEDULE_ID
|
||||
- tags
|
||||
artifacts:
|
||||
paths:
|
||||
- documentations/*.md
|
||||
@@ -1,34 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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 the CI pipeline sources.
|
||||
if ! [[ "$CI_PIPELINE_SOURCE" == "push" ]]; then
|
||||
echo "CI pipelines are only allowed from push."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check the tag is properly defined on job other than update_docker_hub_full_description job,
|
||||
# on pushed CI pipelines.
|
||||
if [[ "$CI_PIPELINE_SOURCE" == "push" ]]; then
|
||||
if ! [[ "$CI_JOB_NAME" == "update_docker_hub_full_description" ]]; then
|
||||
if [[ -z "$CI_COMMIT_TAG" && "$CI_COMMIT_TAG" =~ ^[0-9]+[.][0-9]+[.][0-9]+$ ]]; then
|
||||
echo "The \$CI_COMMIT_TAG $CI_COMMIT_TAG does not match the MAJOR.Minor.revision layout."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
@@ -1,71 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
apk add curl jq
|
||||
|
||||
# Load utilities functions.
|
||||
SCRIPT_DIRECTORY=$(dirname ${BASH_SOURCE[0]})
|
||||
source $SCRIPT_DIRECTORY/utilities.sh
|
||||
|
||||
# Restrict the job to the right schedule.
|
||||
if [[ "$SCHEDULE_ID" != "$PACKAGE_UPDATE_NOTIFICATION_SCHEDULE_ID" ]]; then
|
||||
exit_with_message_and_code "Schedule ID did not match." 0
|
||||
fi
|
||||
|
||||
# Fetch the issue state if the ISSUE_ID variable is set,
|
||||
# if that state is closed remove the ISSUE_ID variable and continue the job, otherwise exit the job.
|
||||
if [[ -n "$ISSUE_ID" ]]; then
|
||||
issue_state="$(curl -H \"PRIVATE-TOKEN: $REPORTER_BOT_ACCESS_TOKEN\" \
|
||||
https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/issue/$ISSUE_ID | jq .state)"
|
||||
if [[ "$issue_state" == "closed" ]]; then
|
||||
echo "An issue exist, but is closed. Removing ISSUE_ID schedule variable..."
|
||||
curl -X DELETE \
|
||||
-H "PRIVATE-TOKEN: $REPORTER_BOT_ACCESS_TOKEN" \
|
||||
https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/pipeline_schedules/$SCHEDULE_ID/variables/$ISSUE_ID
|
||||
else
|
||||
exit_with_message_and_code "An issue already exists, it is not closed yet." 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Get the installed and candidate versions of the seafile-cli package from the latest Docker image.
|
||||
docker pull $CI_REGISTRY_IMAGE:latest
|
||||
candidate_version=$(docker run --rm --entrypoint="" $CI_REGISTRY_IMAGE:latest \
|
||||
bash -c "\
|
||||
apt-get -qq update;\
|
||||
apt-cache policy seafile-cli | grep 'Candidate:' | awk '{print \$2}'")
|
||||
installed_version=$(docker run --rm --entrypoint="" $CI_REGISTRY_IMAGE:latest \
|
||||
bash -c "\
|
||||
apt-get -qq update;\
|
||||
apt-cache policy seafile-cli | grep 'Installed:' | awk '{print \$2}'")
|
||||
|
||||
# Create an issue if a new version was released.
|
||||
if [[ "$installed_version" == "$candidate_version" ]]; then
|
||||
exit_with_message_and_code "No new version of the seafile-cli package have been released." 0
|
||||
else
|
||||
echo "A new version of the seafile-cli package have been released. Creating a new issue..."
|
||||
data=$(jq -n \
|
||||
--arg title "seafile-cli v${candidate_version} was released" \
|
||||
--arg description "Check for new feature, breaking changes or anything worth updating to update the Docker image." \
|
||||
--arg labels "enhancement" \
|
||||
'{title: $title, description: $description, labels: [$labels]}')
|
||||
curl -X POST \
|
||||
-H "PRIVATE-TOKEN: $REPORTER_BOT_ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$data"
|
||||
https://gitlab.com/api/v4/projects/$CI_PROJECT_ID/issues
|
||||
fi
|
||||
@@ -1,38 +0,0 @@
|
||||
# !/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
apk add curl
|
||||
|
||||
SCRIPT_DIRECTORY=$(dirname ${BASH_SOURCE[0]})
|
||||
source $SCRIPT_DIRECTORY/utilities.sh
|
||||
load_images_artifacts
|
||||
|
||||
# Generate version tags.
|
||||
tags=("latest")
|
||||
for version_component in $(echo $CI_COMMIT_TAG | tr "." "\n"); do
|
||||
tag+="$version_component"
|
||||
tags+=("$tag")
|
||||
tag+="."
|
||||
done
|
||||
|
||||
# Tag then push the Docker Hub registry.
|
||||
echo $CI_REGISTRY_BOT_PASSWORD | docker login --password-stdin --username $CI_REGISTRY_BOT_USERNAME
|
||||
for tag in "${tags[@]}"; do
|
||||
docker tag $CI_PROJECT_NAME:build $CI_REGISTRY_IMAGE:$tag
|
||||
docker push $CI_REGISTRY_IMAGE:$tag
|
||||
done
|
||||
@@ -1,3 +0,0 @@
|
||||
click==7.1.1
|
||||
Jinja2==2.11.1
|
||||
markupsafe==2.0.1
|
||||
@@ -1,79 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
import re
|
||||
|
||||
from jinja2 import Template
|
||||
import click
|
||||
|
||||
README_FILENAME = "README.md"
|
||||
CHANGELOG_FILENAME = "CHANGELOG.md"
|
||||
SEAFILE_TOPIC_POST_TEMPLATE_FILENAME = ".utilities/templates/seafile_topic_post.template"
|
||||
DOCKER_HUB_DESCRIPTION_FILENAME = "docker_hub.description"
|
||||
SEAFILE_FORUM_TOPIC_POST_DESCRIPTION_FILENAME = "seafile_forum_topic_post.description"
|
||||
|
||||
|
||||
def translate_issues_references_into_urls(string):
|
||||
return re.sub(
|
||||
r' #([0-9]+)',
|
||||
r' [issue#\1](https://gitlab.com/flwgns-docker/seafile-client/-/issues/\1)',
|
||||
string)
|
||||
|
||||
|
||||
def translate_markdown_links_of_repository_files_into_urls(string, ref):
|
||||
return re.sub(
|
||||
r'(\[.+\])\((?!.+:\/\/)(?!mailto:.+)(.+)\)',
|
||||
r'\1(https://gitlab.com/flwgns-docker/seafile-client/-/blob/{}/\2)'
|
||||
.format(ref),
|
||||
string)
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.argument('ref', type=click.STRING)
|
||||
def templater(ref):
|
||||
"""CLI entrypoint the templater."""
|
||||
|
||||
if len(ref) != 40:
|
||||
raise Exception("Commit reference must be 40 characters long (i.e. not the short ref)")
|
||||
|
||||
# Extract text from the README.md, CHANGELOG.md and the Seafile forum topic post template files.
|
||||
with open(README_FILENAME, mode="rt") as fo:
|
||||
readme_text = fo.read()
|
||||
with open(CHANGELOG_FILENAME, mode="rt") as fo:
|
||||
changelog_text = fo.read()
|
||||
with open(SEAFILE_TOPIC_POST_TEMPLATE_FILENAME, mode="rt") as fo:
|
||||
seafile_topic_post_template_text = fo.read()
|
||||
|
||||
# Generate the Docker Hub description by:
|
||||
# - translating Markdown links of repository files to reachable URLs
|
||||
docker_hub_description = translate_markdown_links_of_repository_files_into_urls(readme_text, ref)
|
||||
with open(DOCKER_HUB_DESCRIPTION_FILENAME, mode="wt") as fo:
|
||||
fo.write(docker_hub_description)
|
||||
|
||||
# Generate the Seafile forum topic post description by:
|
||||
# - translating issues reference into reachable URLs
|
||||
# - templating the previous into the existing post
|
||||
seafile_topic_post_template = Template(seafile_topic_post_template_text)
|
||||
changlog_reachable_issue_urls = translate_issues_references_into_urls(changelog_text)
|
||||
seafile_topic_post_description = seafile_topic_post_template.render(changelog=changlog_reachable_issue_urls)
|
||||
with open(SEAFILE_FORUM_TOPIC_POST_DESCRIPTION_FILENAME, mode="wt") as fo:
|
||||
fo.write(seafile_topic_post_description)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
templater()
|
||||
@@ -1,26 +0,0 @@
|
||||
# !/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
SCRIPT_DIRECTORY=$(dirname ${BASH_SOURCE[0]})
|
||||
source $SCRIPT_DIRECTORY/utilities.sh
|
||||
load_images_artifacts
|
||||
|
||||
docker run \
|
||||
--interactive \
|
||||
--attach stderr \
|
||||
$CI_PROJECT_NAME:build /tests/test_binaries.sh
|
||||
@@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
# Based upon https://gist.github.com/jlhawn/8f218e7c0b14c941c41f
|
||||
# and https://github.com/moikot/golang-dep/blob/master/.travis/push.sh
|
||||
|
||||
# This action can only be done with the actual owner of the repository,
|
||||
# unless you can extend the collaborator's permissions but as far as I know, you can't.
|
||||
|
||||
# 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/
|
||||
@@ -1,26 +0,0 @@
|
||||
# !/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
load_images_artifacts() {
|
||||
docker load --input $CI_PROJECT_NAME.tar
|
||||
}
|
||||
|
||||
exit_with_message_and_code() {
|
||||
echo $1
|
||||
exit $2
|
||||
}
|
||||
118
CHANGELOG.md
118
CHANGELOG.md
@@ -1,23 +1,57 @@
|
||||
- Close #16: add a templater for Docker Hub and Seafile's forum topic description
|
||||
# Changelog
|
||||
|
||||
## __[2.2.0](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.2.0)__ | _2022/08/26_
|
||||
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]
|
||||
### Added
|
||||
### Changed
|
||||
### Deprecated
|
||||
### Removed
|
||||
### Fixed
|
||||
### Security
|
||||
[tag]: url_to_tag
|
||||
-->
|
||||
|
||||
## [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/flwgns-docker/seafile-client/-/tags/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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.1.1)__ | _2020/03/10_
|
||||
- Close #14: prevent re-initialization and re-synchronization of the container if it's life cycle change but is not deleted
|
||||
## __[2.1.0](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.1.0)__ | _2020/01/30_
|
||||
- Close #13: replace previous Bash script that parse `seaf-cli status` with a Python script that use __pysearpc__ to run checks
|
||||
- Ongoing #14: implement a workaround to probable issue, waiting for the issue to appear
|
||||
## [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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.2)__ | _2020/01/14_
|
||||
- Close #5: read [the docs](https://docs.docker.com/engine/reference/commandline/build/#set-build-time-variables---build-arg) a bit more.
|
||||
### __[2.0.2](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.2)__ | _2020/01/14_
|
||||
- Ongoing #5: 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).
|
||||
### __[2.0.1](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.1)__ | _2020/01/14_
|
||||
- Fix #11: update chown path to library, comment chown to an obsolete healthcheck.sh.
|
||||
- Ongoing #5: pass $CI_PROJECT_URL to the Dockerfile as a build argument.
|
||||
# __[2.0.0](https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.0)__ | _2020/01/06_
|
||||
## [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
|
||||
@@ -28,42 +62,62 @@
|
||||
- Revise README
|
||||
- Change the volume path from /volume to /library for consistency
|
||||
|
||||
### __[1.2.1](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.2.1)__ | _2019/12/29_
|
||||
- Fix #4:
|
||||
- Switch base image from Debian oldoldstable Jessie to Debian stable Buster to fix unmet dependencies of `seafile-cli` to `python-future` and `python-searpc`
|
||||
- Replace `;` with `&&` as commands separators in the Dockerfile's `RUN` to properly report failed commands at CI
|
||||
## __[1.2.0](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.2.0)__ | _2019/05/02_
|
||||
## [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.
|
||||
- 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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.1.2)__ | _2019/04/18_
|
||||
## [1.1.2] - 2019/04/18
|
||||
- Slim down the Docker image, from 102MB to 67MB, gaining 35MB, reducing size by 34%.
|
||||
### __[1.1.1](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.1.1)__ | _2019/04/18_
|
||||
## [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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.1.0)__ | _2019/04/09_
|
||||
## [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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.6)__ | _2019/03/25_
|
||||
## [1.0.6] - 2019/03/25
|
||||
- More minor fixes from v1.0.4
|
||||
### __[1.0.5](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.5)__ | _2019/03/25_
|
||||
## [1.0.5] - 2019/03/25
|
||||
- Minor fixes from v1.0.4
|
||||
### __[1.0.4](https://gitlab.com/flwgns-docker/seafile-client/-/tags/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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/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](https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.0)__ | _2019/03/15_
|
||||
## [1.0.0] - 2019/03/15
|
||||
- Release to Docker Hub
|
||||
|
||||
### __[0.9.2](https://gitlab.com/flwgns-docker/seafile-client/-/tags/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/flwgns-docker/seafile-client/-/tags/2.2.0
|
||||
[2.1.1]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.1.1
|
||||
[2.1.0]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.1.0
|
||||
[2.0.3]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.2
|
||||
[2.0.2]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.2
|
||||
[2.0.1]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.1
|
||||
[2.0.0]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/2.0.0
|
||||
[1.2.1]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.2.1
|
||||
[1.2.0]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.2.0
|
||||
[1.1.2]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.1.2
|
||||
[1.1.1]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.1.1
|
||||
[1.1.0]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.1.0
|
||||
[1.0.6]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.6
|
||||
[1.0.5]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.5
|
||||
[1.0.4]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.4
|
||||
[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.1]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.1
|
||||
[1.0.0]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/1.0.0
|
||||
[0.9.2]: https://gitlab.com/flwgns-docker/seafile-client/-/tags/0.9.2
|
||||
|
||||
@@ -24,26 +24,92 @@ One great way to help is simply to say thanks. You can do that by [adding a star
|
||||
# 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
|
||||
|
||||
## Development
|
||||
## Management
|
||||
|
||||
A few utilities Bash scripts are available to operate the project:
|
||||
* [build.sh](.utilities/build.sh): build the Docker image and save as a tarball
|
||||
* [check.sh](.utilities/check.sh): validate CI pipelines
|
||||
* [package_update_notifier.sh](.utilities/package_update_notifier.sh): notify, through a GitLab issue, if a new `seaf-cli` version is available
|
||||
* [publish.sh](.utilities/publish.sh): tag and push the image to Docker Hub
|
||||
* [test.sh](.utilities/test.sh): run the test suite
|
||||
* [update-docker-hub-full-description.sh](.utilities/update-docker-hub-full-description.sh): push the README.md to the Docker Hub
|
||||
* [utilities.sh](.utilities/utilities.sh): functions and assets
|
||||
The project managemenet is mostly run through the Makefile.
|
||||
|
||||
Following a trunk-based development strategy, all changes must come from a short lived branch and fast-forward merged into master.
|
||||
All commits must be squashed into a single commit referencing a specific issue.
|
||||
The parameter `TARGET` define on which Debian version the instructions are run.
|
||||
|
||||
## CI/CD
|
||||
Tests are run only on merge requests, but they can be run on demand in a local environment.
|
||||
The [CHANGELOG.md](CHANGELOG.md) and [AUTHORS.md](AUTHORS.md) will be updated on every merge.
|
||||
Only merge resquests associated with a milestone will end up in a new release. The [README.md](README.md) will be updated then. Description pages for Docker Hub and Seafile's forum will be templated then as well and made available as artifacts for a manual update since #10 and #17 are still opened issues.
|
||||
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.
|
||||
|
||||
71
Dockerfile
71
Dockerfile
@@ -1,71 +0,0 @@
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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:bullseye-slim
|
||||
|
||||
ARG BUILD_DATE
|
||||
ARG VCS_REF
|
||||
ARG VERSION
|
||||
ARG PROJECT_URL
|
||||
LABEL maintainer="flow.gunso@gmail.com" \
|
||||
org.label-schema.build-date=$BUILD_DATE \
|
||||
org.label-schema.name="Seafile Docker client" \
|
||||
org.label-schema.description="Sync Seafile librairies within Docker containers." \
|
||||
org.label-schema.url=$PROJECT_URL \
|
||||
org.label-schema.vcs-ref=$VCS_REF \
|
||||
org.label-schema.vcs-url=$PROJECT_URL \
|
||||
org.label-schema.vendor="flow.gunso@gmail.com" \
|
||||
org.label-schema.version=$VERSION \
|
||||
org.label-schema.schema-version="1.0"
|
||||
|
||||
# Copy over the assets.
|
||||
COPY seafile-client/docker-entrypoint.sh /entrypoint.sh
|
||||
COPY seafile-client/docker-healthcheck.sh /healthcheck.sh
|
||||
COPY tests /tests
|
||||
|
||||
# Install seaf-cli and oathtool, prepare the user.
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV UNAME=seafuser UID=1000 GID=1000
|
||||
RUN apt-get update && apt-get install -y gnupg wget && \
|
||||
mkdir -p /etc/apt/sources.list.d/ && \
|
||||
wget https://linux-clients.seafile.com/seafile.asc -O /usr/share/keyrings/seafile-keyring.asc && \
|
||||
bash -c "echo 'deb [arch=amd64 signed-by=/usr/share/keyrings/seafile-keyring.asc] https://linux-clients.seafile.com/seafile-deb/bullseye/ stable main' > /etc/apt/sources.list.d/seafile.list" && \
|
||||
apt-get purge --yes gnupg wget && apt-get autoremove --yes && \
|
||||
apt-get update && apt-get install \
|
||||
--no-install-recommends \
|
||||
--yes \
|
||||
seafile-cli \
|
||||
oathtool && \
|
||||
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/* \
|
||||
mkdir /library/ && \
|
||||
groupadd -g $GID -o $UNAME && \
|
||||
useradd -m -u $UID -g $GID -o -s /bin/bash $UNAME && \
|
||||
mkdir /home/$UNAME/.seafile && \
|
||||
chown $UNAME:$GID /home/$UNAME/.seafile
|
||||
|
||||
COPY seafile-client/seafile-entrypoint.sh /home/seafuser/entrypoint.sh
|
||||
COPY seafile-client/seafile-healthcheck.py /home/seafuser/healthcheck.py
|
||||
RUN chmod +x /home/$UNAME/healthcheck.py && \
|
||||
chown $UNAME:$GID /home/$UNAME/
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "--"]
|
||||
CMD ["/entrypoint.sh"]
|
||||
HEALTHCHECK --start-period=1m CMD /healthcheck.sh
|
||||
49
Makefile
Normal file
49
Makefile
Normal file
@@ -0,0 +1,49 @@
|
||||
TARGET?=unstable
|
||||
|
||||
mock:
|
||||
docker compose -f tests/mock/compose.yaml up -d
|
||||
|
||||
unmock:
|
||||
docker compose -f tests/mock/compose.yaml down
|
||||
|
||||
client:
|
||||
docker compose -f tests/mock/compose.yaml rm -fs client
|
||||
docker compose -f tests/mock/compose.yaml up -d client
|
||||
|
||||
shell:
|
||||
docker compose -f tests/mock/compose.yaml exec client bash
|
||||
|
||||
logs:
|
||||
docker compose -f tests/mock/compose.yaml logs -f client
|
||||
|
||||
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
|
||||
|
||||
documents:
|
||||
python scripts/make-documents.py docker.md.j2
|
||||
python scripts/make-documents.py seafile.md.j2
|
||||
|
||||
publish-images:
|
||||
TARGET=${TARGET} \
|
||||
DOCKER_HUB_BOT_USERNAME=${DOCKER_HUB_BOT_USERNAME} \
|
||||
DOCKER_HUB_BOT_TOKEN=${DOCKER_HUB_BOT_TOKEN} \
|
||||
DOCKER_HUB_OWNER_USERNAME=${DOCKER_HUB_OWNER_USERNAME} \
|
||||
DOCKER_HUB_OWNER_TOKEN=${DOCKER_HUB_OWNER_TOKEN} \
|
||||
DOCKER_HUB_IMAGE=${DOCKER_HUB_IMAGE} \
|
||||
bash scripts/publish-images.sh
|
||||
|
||||
publish-documents:
|
||||
bash scripts/publish-documents.sh
|
||||
|
||||
save:
|
||||
mkdir -p tarballs/
|
||||
docker save --output tarballs/${TARGET}.tar seafile-client:${TARGET}
|
||||
|
||||
load:
|
||||
docker load --input tarballs/${TARGET}.tar
|
||||
181
README.md
181
README.md
@@ -1,91 +1,153 @@
|
||||
[](https://gitlab.com/flwgns-docker/seafile-client/commits/2.2.0)
|
||||
[](https://hub.docker.com/r/flowgunso/seafile-client)
|
||||
[](https://hub.docker.com/r/flowgunso/seafile-client)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
[](https://gitlab.com/flwgns-docker/seafile-client/)
|
||||
[![][badge-pipeline]][url-pipelines]
|
||||
[![][badge-image-size]][url-docker]
|
||||
[![][badge-pulls]][url-docker]
|
||||
[![][badge-release]][url-sources]
|
||||
![][badge-license]
|
||||
|
||||
[url-pipelines]: https://gitlab.com/flwgns-docker/seafile-client/-/pipelines
|
||||
[url-docker]: https://hub.docker.com/r/flowgunso/seafile-client
|
||||
[url-sources]: https://gitlab.com/flwgns-docker/seafile-client/
|
||||
|
||||
[badge-pipeline]: https://img.shields.io/gitlab/pipeline-status/flwgns-docker%2Fseafile-client
|
||||
[badge-image-size]: https://img.shields.io/docker/image-size/flowgunso/seafile-client/latest?logo=docker&label=Image%20size&color=%230778b8
|
||||
[badge-pulls]: https://img.shields.io/docker/pulls/flowgunso/seafile-client?logo=docker&label=Pulls&color=%230778b8
|
||||
[badge-license]: https://img.shields.io/gitlab/license/11322291?label=License&color=fca326
|
||||
[badge-release]: https://img.shields.io/gitlab/v/release/11322291?logo=gitlab&label=Source%20code&color=fca326
|
||||
|
||||
**Share a Seafile library as a volume to other containers.**
|
||||
|
||||
# Supported tags
|
||||
[`2`, `2.2`, `2.2.0`, `latest`](seafile-client/Dockerfile)
|
||||
|
||||
# Informations
|
||||
* Synchronize a single Seafile library, available at the path `/library/'.
|
||||
* Password protected librairies are supported.
|
||||
* Two factor authentication is supported.
|
||||
* Upload and download speeds are configurable.
|
||||
* SSL certificates are skippable.
|
||||
<!-- -->
|
||||
* 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/flwgns-docker/seafile-client/).
|
||||
|
||||
# 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
|
||||
|
||||
# Usage
|
||||
## Required configuration
|
||||
__SEAF_SERVER_URL__, __SEAF_USERNAME__, __SEAF_PASSWORD__, __SEAF_LIBRARY_UUID__
|
||||
Provide your Seafile _server URL_, _username_, _password_ and _library UUID_ to synchronise your library at `/library`, then share it as a volume.
|
||||
|
||||
The `seaf-cli` is ran within the container as the user `seafuser`.
|
||||
## Start a Seafile client
|
||||
|
||||
## Optional configurations
|
||||
__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_LIBRARY_PASSWORD__
|
||||
Password protected librairies can be sync provided with the _password_.
|
||||
|
||||
__SEAF_UPLOAD_LIMIT__, __SEAF_DOWNLOAD_LIMIT__
|
||||
Upload and download speeds are configurable as _absolute 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 volume read/write permissions.
|
||||
|
||||
# Examples
|
||||
## As a Docker command
|
||||
```
|
||||
### Docker command-line
|
||||
The following command start the Seafile client with one library:
|
||||
```bash
|
||||
docker run \
|
||||
-e SEAF_SERVER_URL=https://seafile.example/ \
|
||||
-e SEAF_USERNAME=a_seafile_user \
|
||||
-e SEAF_PASSWORD=SoMePaSSWoRD \
|
||||
-e SEAF_LIBRARY_UUID=an-hexadecimal-library-uuid \
|
||||
-v path/to/shared/volume:/library \
|
||||
-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 \
|
||||
flowgunso/seafile-client:latest
|
||||
```
|
||||
## As a Docker Compose
|
||||
|
||||
### Docker Compose
|
||||
The following Docker Compose start a Seafile client with two libraries, with one password protected:
|
||||
```yaml
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
seafile-client:
|
||||
image: flowgunso/seafile-client:latest
|
||||
volumes:
|
||||
- shared_volume:/library
|
||||
- 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_UUID: "an-hexadecimal-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
|
||||
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
|
||||
|
||||
volumes:
|
||||
shared_volume:
|
||||
audio:
|
||||
documents:
|
||||
client:
|
||||
```
|
||||
## With all optional configurations
|
||||
```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
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
seafile-client:
|
||||
image: flowgunso/seafile-client:latest
|
||||
volumes:
|
||||
- shared_volume:/library
|
||||
- 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_UUID: "an-hexadecimal-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
|
||||
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
|
||||
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
|
||||
SEAF_2FA_SECRET: "JBSWY3DPEHPK3PXPIXDAUMXEDOXIUCDXWC32CS"
|
||||
SEAF_LIBRARY_PASSWORD: "LiBRaRyPaSSWoRD"
|
||||
SEAF_UPLOAD_LIMIT: "1000000"
|
||||
SEAF_DOWNLOAD_LIMIT: "1000000"
|
||||
SEAF_SKIP_SSL_CERT: "true"
|
||||
@@ -93,6 +155,11 @@ services:
|
||||
GID: "1000"
|
||||
|
||||
volumes:
|
||||
shared_volume:
|
||||
audio:
|
||||
documents:
|
||||
client:
|
||||
```
|
||||
Or use the [docker-compose.yml](documentations/docker-compose.yml) template.
|
||||
|
||||
# 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/flwgns-docker/seafile-client/).
|
||||
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 \
|
||||
flowgunso/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: flowgunso/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: flowgunso/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:
|
||||
@@ -1,20 +0,0 @@
|
||||
version: "3.4"
|
||||
|
||||
services:
|
||||
seafile-client:
|
||||
image: flowgunso/seafile-client:latest
|
||||
volumes:
|
||||
- shared_volume:/library
|
||||
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.
|
||||
# SEAF_LIBRARY_PASSWORD: "" # The Seafile library password, if required.
|
||||
# SEAF_SKIP_SSL_CERT: "true" # Any string is true, omit to set to false.
|
||||
# SEAF_2FA_SECRET: "" # The 2FA secret key available at Seafile 2FA setup.
|
||||
# UID: "" # Default is 1000.
|
||||
# GID: "" # Default is 1000.
|
||||
|
||||
volumes:
|
||||
shared_volume:
|
||||
11
documentations/docker.md.j2
Normal file
11
documentations/docker.md.j2
Normal file
@@ -0,0 +1,11 @@
|
||||
{% include "parts/badges.md.j2" %}
|
||||
|
||||
**Share a Seafile library 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" %}
|
||||
15
documentations/parts/badges.md.j2
Normal file
15
documentations/parts/badges.md.j2
Normal file
@@ -0,0 +1,15 @@
|
||||
[![][badge-pipeline]][url-pipelines]
|
||||
[![][badge-image-size]][url-docker]
|
||||
[![][badge-pulls]][url-docker]
|
||||
[![][badge-release]][url-sources]
|
||||
![][badge-license]
|
||||
|
||||
[url-pipelines]: https://gitlab.com/flwgns-docker/seafile-client/-/pipelines
|
||||
[url-docker]: https://hub.docker.com/r/flowgunso/seafile-client
|
||||
[url-sources]: https://gitlab.com/flwgns-docker/seafile-client/
|
||||
|
||||
[badge-pipeline]: https://img.shields.io/gitlab/pipeline-status/flwgns-docker%2Fseafile-client
|
||||
[badge-image-size]: https://img.shields.io/docker/image-size/flowgunso/seafile-client/latest?logo=docker&label=Image%20size&color=%230778b8
|
||||
[badge-pulls]: https://img.shields.io/docker/pulls/flowgunso/seafile-client?logo=docker&label=Pulls&color=%230778b8
|
||||
[badge-license]: https://img.shields.io/gitlab/license/11322291?label=License&color=fca326
|
||||
[badge-release]: https://img.shields.io/gitlab/v/release/11322291?logo=gitlab&label=Source%20code&color=fca326
|
||||
7
documentations/parts/features.md.j2
Normal file
7
documentations/parts/features.md.j2
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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
|
||||
7
documentations/parts/supported_tags.md.j2
Normal file
7
documentations/parts/supported_tags.md.j2
Normal file
@@ -0,0 +1,7 @@
|
||||
# Supported tags
|
||||
|
||||
{% for version in versions %}
|
||||
[{{ version | join(", ")}}][Dockerfile]
|
||||
{% endfor %}
|
||||
|
||||
[Dockerfile]: https://gitlab.com/flwgns-docker/seafile-client/-/blob/master/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/flwgns-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" %}
|
||||
```
|
||||
@@ -11,17 +11,18 @@ Example usage with docker-compose and for the docker cli are provided. Essential
|
||||
Feedback is welcome so I can keep improving it.
|
||||
|
||||
# Quick informations
|
||||
**[flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client)** on Docker Hub, latest stable version: **2.1.1**
|
||||
**[flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client)** on Docker Hub, latest stable version: **{{version}}**
|
||||
Contribute and report issues on [Gitlab](https://gitlab.com/flwgns-docker/seafile-client/).
|
||||
|
||||
## Features
|
||||
* Synchronize a single Seafile library, available at the path `/library/'.
|
||||
* Password protected librairies are supported.
|
||||
* Two factor authentication is supported.
|
||||
* Upload and download speeds are configurable.
|
||||
* SSL certificates are skippable.
|
||||
{% include "parts/supported_tags.md.j2" %}
|
||||
|
||||
# Change log
|
||||
{% include "parts/features.md.j2" %}
|
||||
|
||||
{% include "parts/usage.md.j2" %}
|
||||
|
||||
{% include "parts/troubleshooting.md.j2" %}
|
||||
|
||||
# Changelog
|
||||
[details]
|
||||
{{ changelog }}
|
||||
[/details]
|
||||
{{changelog}}
|
||||
[/details]
|
||||
@@ -16,12 +16,19 @@
|
||||
# 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-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
|
||||
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
|
||||
--build-arg VERSION=$CI_COMMIT_TAG \
|
||||
--build-arg PROJECT_URL=$CI_PROJECT_URL \
|
||||
--tag $CI_PROJECT_NAME:build .
|
||||
|
||||
docker save --output $CI_PROJECT_NAME.tar $CI_PROJECT_NAME:build
|
||||
$build_arguments \
|
||||
--tag seafile-client:$TARGET \
|
||||
seafile-client/
|
||||
54
scripts/make-documents.py
Executable file
54
scripts/make-documents.py
Executable file
@@ -0,0 +1,54 @@
|
||||
# !/usr/bin/env python
|
||||
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
|
||||
REPOSITORY_PATH = Path(__file__).parent.parent
|
||||
|
||||
# Argument parsing.
|
||||
parser = argparse.ArgumentParser(prog="Seafile Docker client documentation renderer")
|
||||
parser.add_argument("template", type=str)
|
||||
args = parser.parse_args()
|
||||
|
||||
# Setup Jinja2 templater
|
||||
documentations_path = REPOSITORY_PATH.joinpath("documentations")
|
||||
loader = FileSystemLoader(documentations_path)
|
||||
environment = Environment(loader=loader)
|
||||
template = environment.get_template(args.template)
|
||||
|
||||
|
||||
buffer=[]
|
||||
for path in Path("versions").iterdir():
|
||||
with open(path, "rt") as fo:
|
||||
buffer.append(fo.read().strip())
|
||||
buffer.sort(reverse=True)
|
||||
|
||||
# Prepare the render context.
|
||||
latest = True
|
||||
versions = []
|
||||
for line in buffer:
|
||||
version = line.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
|
||||
versions.append(blocks)
|
||||
|
||||
# Render
|
||||
content = template.render(versions=versions)
|
||||
#content = template.render() # When version/ is unavailable.
|
||||
filename = Path(args.template).with_suffix("")
|
||||
document = documentations_path.joinpath(filename)
|
||||
|
||||
# Write to file
|
||||
with open(document, mode="w") as fo:
|
||||
fo.write(content)
|
||||
19
scripts/publish-documents.sh
Normal file
19
scripts/publish-documents.sh
Normal file
@@ -0,0 +1,19 @@
|
||||
# Get a token from hub.docker.com with the owner credentials.
|
||||
token=$(curl -s \
|
||||
-X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username": "'"$DOCKER_HUB_OWNER_USERNAME"'", "password": "'"$DOCKER_HUB_OWNER_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":"Synchronize a Seafile library. Support password protected librairies and 2FA authentication."}')
|
||||
|
||||
# Update the Docker Hub repository's full_description.
|
||||
curl -siL \
|
||||
-X PATCH \
|
||||
-d "$json" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: JWT $token" \
|
||||
"https://hub.docker.com/v2/repositories/$DOCKER_HUB_IMAGE/"
|
||||
56
scripts/publish-images.sh
Normal file
56
scripts/publish-images.sh
Normal file
@@ -0,0 +1,56 @@
|
||||
# !/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
|
||||
set -ex
|
||||
|
||||
raise() {
|
||||
echo $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Validate the required parameters.
|
||||
# [[ -z "$DOCKER_HUB_BOT_USERNAME" ]] && raise "Missing DOCKER_HUB_BOT_USERNAME envvar."
|
||||
# [[ -z "$DOCKER_HUB_BOT_TOKEN" ]] && raise "Missing DOCKER_HUB_BOT_TOKEN envvar."
|
||||
# [[ -z "$DOCKER_HUB_OWNER_USERNAME" ]] && raise "Missing DOCKER_HUB_OWNER_USERNAME envvar."
|
||||
# [[ -z "$DOCKER_HUB_OWNER_TOKEN" ]] && raise "Missing DOCKER_HUB_OWNER_TOKEN envvar."
|
||||
# [[ -z "$DOCKER_HUB_IMAGE" ]] && raise "Missing DOCKER_HUB_IMAGE envvar"
|
||||
|
||||
# Grab version with the container
|
||||
version="$(docker run --rm seafile-client:$TARGET 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_HUB_BOT_TOKEN | docker login --password-stdin --username $DOCKER_HUB_BOT_USERNAME
|
||||
for tag in "${tags[@]}"; do
|
||||
docker tag seafile-client:$TARGET $DOCKER_HUB_IMAGE:$tag
|
||||
docker push $DOCKER_HUB_IMAGE:$tag
|
||||
done
|
||||
55
seafile-client/Dockerfile
Normal file
55
seafile-client/Dockerfile
Normal file
@@ -0,0 +1,55 @@
|
||||
ARG TARGET=unstable
|
||||
FROM debian:${TARGET}-slim
|
||||
|
||||
ARG UID
|
||||
ARG GID
|
||||
ENV UID 1000
|
||||
ENV GID 1000
|
||||
ENV PYTHONUNBUFFERED 1
|
||||
|
||||
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/*
|
||||
|
||||
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="flow.gunso@gmail.com"
|
||||
LABEL org.opencontainers.image.url="https://hub.docker.com/r/flowgunso/seafile-client"
|
||||
LABEL org.opencontainers.image.documentation="https://gitlab.com/flwgns-docker/seafile-client"
|
||||
LABEL org.opencontainers.image.source="https://gitlab.com/flwgns-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"]
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
function fail_with_message {
|
||||
echo "$1"
|
||||
echo "Exiting container."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check mandatory Seafile configuration have been properly set.
|
||||
[[ -z "$SEAF_SERVER_URL" ]] && fail_with_message "The \$SEAF_SERVER_URL is not defined."
|
||||
[[ -z "$SEAF_USERNAME" ]] && fail_with_message "The \$SEAF_USERNAME is not defined."
|
||||
[[ -z "$SEAF_PASSWORD" ]] && fail_with_message "The \$SEAF_PASSWORD is not defined."
|
||||
[[ -z "$SEAF_LIBRARY_UUID" ]] && fail_with_message "The \$SEAF_LIBRARY_UUID is not defined."
|
||||
[[ -n "$SEAF_UPLOAD_LIMIT" && $SEAF_UPLOAD_LIMIT =~ ^[0-9]+$ && "$SEAF_UPLOAD_LIMIT" -gt 0 ]] && \
|
||||
fail_with_message "The \$SEAF_UPLOAD_LIMIT is not an integer greater than 0."
|
||||
[[ -n "$SEAF_DOWNLOAD_LIMIT" && $SEAF_DOWNLOAD_LIMIT =~ ^[0-9]+$ && "$SEAF_DOWNLOAD_LIMIT" -gt 0 ]] && \
|
||||
fail_with_message "The \$SEAF_DOWNLOAD_LIMIT is not an integer greater than 0."
|
||||
|
||||
# Update the user ID, if the $UID changed.
|
||||
# TODO: What if the $UID already exists ?
|
||||
[[ "$UID" != "1000" ]] && usermod -u $UID $UNAME
|
||||
|
||||
# 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 /home/seafuser/healthcheck.sh
|
||||
chown $UID.$GID /home/seafuser/entrypoint.sh
|
||||
chown $UID.$GID -R /library
|
||||
|
||||
# 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
|
||||
[[ "$SEAF_SKIP_SSL_CERT" ]] && export SEAF_SKIP_SSL_CERT=$SEAF_SKIP_SSL_CERT
|
||||
[[ "$SEAF_UPLOAD_LIMIT" ]] && export SEAF_UPLOAD_LIMIT=$SEAF_UPLOAD_LIMIT
|
||||
[[ "$SEAF_DOWNLOAD_LIMIT" ]] && export SEAF_DOWNLOAD_LIMIT=$SEAF_DOWNLOAD_LIMIT
|
||||
[[ "$SEAF_2FA_SECRET" ]] && export SEAF_2FA_SECRET=$SEAF_2FA_SECRET
|
||||
[[ "$SEAF_LIBRARY_PASSWORD" ]] && export SEAF_LIBRARY_PASSWORD=$SEAF_LIBRARY_PASSWORD
|
||||
/bin/bash /home/seafuser/entrypoint.sh
|
||||
EO
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
# Grab the status of the active repos then return as healthy/unhealthy
|
||||
# depending the healthy statuses.
|
||||
|
||||
su - $UNAME << EO
|
||||
~/healthcheck.py -c ~/.seafile/seafile-data/ $SEAF_LIBRARY_UUID
|
||||
EO
|
||||
12
.utilities/templates/templater.sh → seafile-client/entrypoint-docker.sh
Normal file → Executable file
12
.utilities/templates/templater.sh → seafile-client/entrypoint-docker.sh
Normal file → Executable file
@@ -16,6 +16,14 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
pip install -r .utilities/templates/requirements.txt
|
||||
#!/bin/bash
|
||||
|
||||
python .utilities/templates/templater.py $CI_COMMIT_SHA
|
||||
set -e
|
||||
|
||||
groupmod -g $GID seafile &> /dev/null
|
||||
usermod -u $UID -g $GID seafile &> /dev/null
|
||||
|
||||
sudo \
|
||||
-HE \
|
||||
-u seafile \
|
||||
-- "$@"
|
||||
310
seafile-client/entrypoint-seafile.py
Executable file
310
seafile-client/entrypoint-seafile.py
Executable file
@@ -0,0 +1,310 @@
|
||||
#!/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]
|
||||
|
||||
# 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)
|
||||
|
||||
def configure(self):
|
||||
command = self.binary + ["config"]
|
||||
if self.skip_ssl_cert:
|
||||
subprocess.run(command +["-k", "disable_verify_certificate", "-v", 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.
|
||||
@@ -1,55 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
# Initialise the Seafile client, if not already initialised.
|
||||
seafile_ini="$HOME/.ccnet/seafile.ini"
|
||||
if [ ! -f "$seafile_ini" ]; then
|
||||
echo "Initializing Seafile client..."
|
||||
seaf-cli init -d ~/.seafile
|
||||
while [ ! -f "$seafile_ini" ]; do sleep 1; done
|
||||
fi
|
||||
|
||||
# Start the Seafile daemon.
|
||||
echo "Starting Seafile client..."
|
||||
seaf-cli start
|
||||
while [ ! -S "$HOME/.seafile/seafile-data/seafile.sock" ]; do sleep 1; done
|
||||
|
||||
# Synchronize the library, if not already synchronized.
|
||||
if [ -z "$(seaf-cli status | grep -v ^\#)" ]; then
|
||||
echo "Synchronizing Seafile library..."
|
||||
# Set the disable_verify_certificate key to true only if the environment variable exists.
|
||||
[[ "$SEAF_SKIP_SSL_CERT" ]] && seaf-cli config -k disable_verify_certificate -v true
|
||||
|
||||
# Set the upload/download limits
|
||||
[[ "$SEAF_UPLOAD_LIMIT" ]] && seaf-cli config -k upload_limit -v $SEAF_UPLOAD_LIMIT
|
||||
[[ "$SEAF_DOWNLOAD_LIMIT" ]] && seaf-cli config -k download_limit -v $SEAF_DOWNLOAD_LIMIT
|
||||
|
||||
# Build the seaf-cli sync command.
|
||||
cmd="seaf-cli sync -u $SEAF_USERNAME -p $SEAF_PASSWORD -s $SEAF_SERVER_URL -l $SEAF_LIBRARY_UUID -d /library"
|
||||
[[ "$SEAF_2FA_SECRET" ]] && cmd+=" -a $(oathtool --base32 --totp $SEAF_2FA_SECRET)"
|
||||
[[ "$SEAF_LIBRARY_PASSWORD" ]] && cmd+=" -e $SEAF_LIBRARY_PASSWORD"
|
||||
|
||||
# Run it.
|
||||
if ! eval $cmd; then echo "Failed to synchronize."; exit 1; fi
|
||||
fi
|
||||
|
||||
# Continously print the log, infinitely.
|
||||
while true; do
|
||||
tail -v -f ~/.ccnet/logs/seafile.log
|
||||
echo $?
|
||||
done
|
||||
@@ -1,65 +0,0 @@
|
||||
#!/usr/bin/env python2
|
||||
|
||||
# Docker Seafile client, help you mount a Seafile library as a volume.
|
||||
# Copyright (C) 2019-2020, 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/>.
|
||||
|
||||
# Given a path to a valid Seafile confdir and a repository, check the
|
||||
# synchronization status and otherwise the transfer status of that
|
||||
# repository.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import seafile
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Parse Seafile's confdir and repository ID to check.
|
||||
parser = argparse.ArgumentParser(description="Check the status of a synced repository.")
|
||||
parser.add_argument('repository_id', type=str, help="Repository ID to check the status of.")
|
||||
parser.add_argument('-c', '--confdir', type=str, required=True, help="Seafile configuration directory to load the Socket from.")
|
||||
args = parser.parse_args()
|
||||
|
||||
# Instanciate Seafile RPC.
|
||||
seafile_socket = os.path.join(args.confdir, "seafile.sock")
|
||||
if not os.path.exists(seafile_socket):
|
||||
raise Exception("Could not find a Seafile socket at {}".format(args.confdir))
|
||||
seafile_rpc = seafile.RpcClient(seafile_socket)
|
||||
|
||||
# Fetch the sync task of the repository.
|
||||
repository_sync_task = seafile_rpc.get_repo_sync_task(args.repository_id)
|
||||
if repository_sync_task is not None:
|
||||
sync_state = repository_sync_task.state
|
||||
msg = "Repository synchronization state: {}".format(sync_state)
|
||||
if sync_state == "error":
|
||||
raise Exception(msg)
|
||||
else:
|
||||
print(msg)
|
||||
sys.exit(0)
|
||||
|
||||
# Fetch the transfer task of the repository.
|
||||
repository_transfer_task = seafile_rpc.find_transfer_task(args.repository_id)
|
||||
if repository_transfer_task is not None:
|
||||
transfer_state = repository_transfer_task.state
|
||||
msg = "Repository transfer state: {}".format(transfer_state)
|
||||
if transfer_state == "error":
|
||||
raise Exception(msg)
|
||||
else:
|
||||
print(msg)
|
||||
sys.exit(0)
|
||||
|
||||
raise Exception("Could not find any information about any repository synchronization or transfer tasks.")
|
||||
6
tests/image/Dockerfile
Normal file
6
tests/image/Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
ARG TARGET=unstable
|
||||
FROM seafile-client:${TARGET}
|
||||
|
||||
COPY --chmod=755 test_binaries.sh /test.sh
|
||||
|
||||
CMD ["/test.sh"]
|
||||
52
tests/mock/compose.yaml
Normal file
52
tests/mock/compose.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
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:unstable
|
||||
volumes:
|
||||
#- library:/library
|
||||
- data:/seafile
|
||||
# user: "1000:1000"
|
||||
environment:
|
||||
SEAF_SERVER_URL: "http://seafile"
|
||||
SEAF_USERNAME: "seafile@localhost"
|
||||
SEAF_PASSWORD: "password"
|
||||
SEAF_LIBRARY_UUID: "1b7d4e92-6753-4c4a-85b0-42566eab42c8"
|
||||
DEBUG: 1
|
||||
depends_on:
|
||||
- seafile
|
||||
|
||||
volumes:
|
||||
database:
|
||||
seafile:
|
||||
library:
|
||||
data:
|
||||
Reference in New Issue
Block a user