43 Commits

Author SHA1 Message Date
Florian Anceau
3670ad2fb8 Merge branch '75-libraries-name-fetched-from-the-environment-variables-are-not-formatted-to-lower-case' into 'master'
Format librairies name fetched from envvars to lower case.

Closes #75

See merge request flrnnc-oss/docker-seafile-client!22
2024-09-24 11:32:25 +00:00
Florian Anceau
062f57f002 Format librairies name fetched from envvars to lower case. 2024-09-24 11:32:24 +00:00
Florian Anceau
0b49050521 Fix build badge script ordering 2024-09-19 22:40:30 +00:00
Florian Anceau
62c80d3cac Merge branch 'fix--skip-ssl-cert' into 'master'
Fix skip SSL certificate parameter

Close #72

See merge request flrnnc-oss/docker-seafile-client!21
2024-09-19 21:51:17 +00:00
Florian Anceau
a86c629d64 Fix skip SSL certificate parameter 2024-09-19 21:51:17 +00:00
Florian Anceau
085e2db3d9 Fix usage of full_description. 2024-09-18 14:25:48 +00:00
Florian Anceau
327ee22307 Fix the docker-old filename, move the short description to CI/CD variables. 2024-09-17 21:42:02 +00:00
flowgunso
10e004a92d Update all links, close #70 2024-08-24 22:46:19 +02:00
flowgunso
0c186bea29 Apply proper documentation 2024-08-24 20:50:56 +02:00
flowgunso
fc3991a9cd Use appropriate document 2024-08-24 20:47:33 +02:00
flowgunso
377831b972 Fix path 2024-08-24 20:31:53 +02:00
flowgunso
afedea4c72 Fix the filename again 2024-08-24 20:18:29 +02:00
flowgunso
944c8c4ea9 Fix filename 2024-08-24 20:03:21 +02:00
flowgunso
e4e95c3bbc Push licencing years 2024-08-24 19:40:16 +02:00
flowgunso
7cd3eabdd6 Debug 2024-08-24 19:40:03 +02:00
flowgunso
95daece6a3 Add missing suffix for Docker tags 2024-08-24 19:08:40 +02:00
flowgunso
3323912c61 Fix CI/CD variables 2024-08-24 18:47:55 +02:00
Florian Anceau
0570e3965e Log changes 2024-08-24 14:42:12 +00:00
Florian Anceau
f423949bff Merge branch '68-migrate-to-flrnnc-docker-hub-organization' into 'master'
Migrate to flrnnc Docker Hub organization.

Closes #60 and #69

See merge request florian.anceau-oss/docker-seafile-client!20
2024-08-24 14:19:24 +00:00
Florian Anceau
659e102935 Migrate to flrnnc Docker Hub organization. 2024-08-24 14:19:24 +00:00
Florian Anceau
3375aca7dd Merge branch '61-create-a-last-build-date-badge' into 'master'
Update the build badge date on builds

Closes #61

See merge request florian.anceau-oss/docker-seafile-client!19
2024-06-27 06:37:33 +00:00
Florian Anceau
b2e855ec52 Update the build badge date on builds 2024-06-27 06:37:32 +00:00
Florian Anceau
214bb03a2b typo 2024-06-09 21:28:58 +00:00
Florian Anceau
a49cfccc7b Improve #53 2024-06-09 21:27:55 +00:00
Florian Anceau
b1a1c11676 Improved the readme #53 2024-06-09 21:14:15 +00:00
Florian Anceau
3bcd083837 Remove badges from the README 2024-06-09 21:03:54 +00:00
Florian Anceau
4cec73c7b8 Merge branch '54-latest-tag-was-not-published-on-docker-hub' into 'master'
Allow latest tag to be published, restrict SAST jobs to approved MR

Closes #54 and #58

See merge request florian.anceau-oss/docker-seafile-client!18
2024-06-09 12:57:15 +00:00
Florian Anceau
fe793698e7 Allow latest tag to be published, restrict SAST jobs to approved MR 2024-06-09 12:57:15 +00:00
Florian Anceau
bd098de313 Merge branch '62-use-the-badge-from-the-project-itself-rely-on-the-api-to-build-the-document' into 'master'
Use the badge from the project itself. Rely on the API to build the document

Closes #62

See merge request florian.anceau-oss/docker-seafile-client!17
2024-06-09 10:38:03 +00:00
Florian Anceau
0743bd7c21 Use the badge from the project itself. Rely on the API to build the document 2024-06-09 10:38:03 +00:00
Florian Anceau
eaa8a1edeb Merge branch '64-using-gid-100-early-exit-with-code-4' into 'master'
Change the users group GID from 100 to 90

Closes #64

See merge request florian.anceau-oss/docker-seafile-client!16
2024-06-06 20:56:51 +00:00
Florian Anceau
95aacc7847 Change the users group GID from 100 to 90 2024-06-06 20:56:51 +00:00
Florian Anceau
b192910a2f Merge branch '63-rpc-client-does-not-get-instanciated' into 'master'
Instanciate the RPC at initialization

Closes #63

See merge request florian.anceau/docker-seafile-client!14
2024-06-02 13:41:01 +00:00
Florian Anceau
1928ec8190 Instanciate the RPC at initialization 2024-06-02 13:41:01 +00:00
Florian Anceau
e6bbd483cc Merge branch '51-build-badge-does-not-work' into 'master'
Use working pipeline badge

Closes #51

See merge request florian.anceau/docker-seafile-client!12
2024-05-27 21:43:38 +00:00
Florian Anceau
b2a60e2041 Use working pipeline badge 2024-05-27 21:43:37 +00:00
Florian Anceau
415024b1e2 Merge branch '56--moving-to-gitlab-open-source-program' into 'master'
Apply to open source programs. (#56)

See merge request florian.anceau/seafile-client!11
2024-05-26 21:44:25 +00:00
Florian Anceau
20e321d930 Apply to open source programs. 2024-05-26 21:44:25 +00:00
Florian Anceau
3cf6b608b2 Merge branch 'fix--documents-rendering' into 'master'
Fix documents renderings, except for the missing changelog in the Seafile forum render

See merge request florian.anceau/seafile-client!10
2024-05-26 20:00:49 +00:00
flow.gunso
772b8ca89d Fix documents renderings, except for the missing changelog in the Seafile forum render 2024-05-26 20:00:49 +00:00
flow.gunso
5230067d82 Add LiberaPay sponsoring (#50) 2024-04-07 09:01:51 +00:00
flow.gunso
8dbe494b87 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
2024-03-16 21:58:04 +00:00
flow.gunso
f25b0182d2 Version 3
Support for multiple libraries synchronization (#44, #43, #41)
Support for Docker Secrets (#25)
Support for Seafile client's version through Docker tags (#9)
Mock Seafile server for testings (#6)
Revised project layout and workflow (#38, #39)
Working Docker Hub description publishing (#10)
2024-03-16 21:58:04 +00:00
50 changed files with 1670 additions and 837 deletions

8
.gitignore vendored
View File

@@ -1,5 +1,5 @@
.idea/
*.pyc
docker-compose.test.yml
venv/
*.description
.env/
tarballs/
VERSIONS.txt
documentations/*.md

View File

@@ -3,67 +3,159 @@ image: docker:latest
services:
- docker:dind
.parallel:
parallel:
matrix:
- TARGET: [oldstable, stable, unstable]
stages:
- report
- schedule
- build
- test
- publish
- release
before_script:
- apk add bash git
include:
- template: Jobs/Code-Quality.gitlab-ci.yml
- template: Jobs/SAST.latest.gitlab-ci.yml
build:
stage: build
before_script:
- apk add bash git curl jq make
script:
- /bin/bash .utilities/check.sh
- /bin/bash -e .utilities/build.sh
only:
- tags
- make build
- make save
extends: .parallel
rules:
- if: $CI_COMMIT_TAG
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
artifacts:
paths:
- "$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
only:
- tags
before_script:
- apk add bash git curl jq make
script:
- make load
- make build-test
- make test
extends: .parallel
needs:
- job: build
parallel:
matrix:
- TARGET: oldstable
- TARGET: stable
- TARGET: unstable
rules:
- if: $CI_COMMIT_TAG
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
artifacts:
paths:
- "$CI_PROJECT_NAME.tar"
- tarballs/
publish:
stage: publish
script: /bin/bash -e .utilities/publish.sh
only:
- tags
publish-images:
stage: release
before_script:
- apk add bash git curl jq make
script:
- export
- make load
- make publish-images
needs:
- job: build
parallel:
matrix:
- TARGET: oldstable
- TARGET: stable
- TARGET: unstable
- job: test
extends: .parallel
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
- when: never
artifacts:
paths:
- "$CI_PROJECT_NAME.tar"
- tarballs/
- versions/*
variables:
CI_DEBUG_TRACE: "true"
#update_docker_hub_full_description:
# stage: publish
# script: /bin/bash -e .utilities/update-docker-hub-full-description.sh
# only:
# - master
make-documents:
stage: release
before_script:
- apk add bash git curl jq make py3-jinja2 py3-gitlab
script:
- make documents
needs:
- job: publish-images
parallel:
matrix:
- TARGET: oldstable
- TARGET: stable
- TARGET: unstable
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
- when: never
artifacts:
paths:
- versions/*
- documentations/*.md
bot:package_update_notification:
stage: report
script: bash -e .utilities/package_update_notifier.sh
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
publish-documents:
stage: release
before_script:
- apk add bash git curl jq make py3-gitlab
script:
- make publish-documents
needs:
- job: make-documents
rules:
- if: $CI_COMMIT_TAG
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
- when: never
artifacts:
paths:
- documentations/*.md
weekly-build-disable:
stage: release
needs:
- job: publish-documents
before_script:
- apk add bash git curl jq make py3-requests py3-gitlab
script:
- make unschedule-weekly-build
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build"
- when: never
weekly-build-scheduler:
stage: schedule
before_script:
- apk add bash git curl jq make py3-requests py3-gitlab
script:
- make schedule-weekly-build
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULED_PIPELINE == "weekly-build-scheduler"
- when: never
artifacts:
reports:
metrics: metrics.txt
code_quality:
rules:
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
- when: never
semgrep-sast:
rules:
- if: $CI_MERGE_REQUEST_ID && $CI_MERGE_REQUEST_TITLE !~ /^Draft/
- when: never

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,3 +0,0 @@
click==7.1.1
Jinja2==2.11.1
markupsafe==2.0.1

View File

@@ -1,27 +0,0 @@
Hello everyone,
I wanted to use files from my Seafile server within Docker containers.
I started looking for existing image featuring a Seafile client on Docker Hub. There are some, but with issues such as non-existant/vague documentation or improper tagging.
I don't know if it's something that people are looking for, but I made one. It's available at flowgunso/seafile-client in Docker Hub.
Example usage with docker-compose and for the docker cli are provided. Essentially, it runs `seaf-cli sync`, but you have to pass to the container your Seafile server URL, your credentials and the library ID you want to sync with. Then you can share the path `/library` as a volume to your containers for your own usages.
Feedback is welcome so I can keep improving it.
# Quick informations
**[flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client)** on Docker Hub, latest stable version: **2.1.1**
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.
# Change log
[details]
{{ changelog }}
[/details]

View File

@@ -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()

View File

@@ -1,21 +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/>.
pip install -r .utilities/templates/requirements.txt
python .utilities/templates/templater.py $CI_COMMIT_SHA

View File

@@ -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

View File

@@ -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/

View File

@@ -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
}

View File

@@ -1,23 +1,157 @@
- 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 --/>
## [Unreleased] - year-month-date
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
[Unreleased]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/Unreleased
<!-- /Unreleased /-->
<!-- 3.4.0 -->
## [3.4.0] - 2024-09-24
### Added
- Explicit project name to mock Docker Compose.
### Fixed
- Librairies name are formatted to lower case (#75).
- Use for $TARGET in mock Docker Compose.
- Fix pipeline jobs rules, specifically on Draft MR.
[3.4.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.4.0
<!-- /3.4.0 -->
<!-- 3.3.0 -->
## [3..0]
### Modified
* Add TARGET environment variable to Makefile commands.
### Fixed
* Fix the TypeError for the skip SSL certificates parameters.
[3.3.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.3.0
<!-- /3.3.0 -->
<!-- 3.2.5 -->
## [3.2.5]
### Modified
* Use CI/CD environment variables for the Docker Hub short description
### Fixed
* The file name used for the Docker Hub full description
[3.2.5]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.5
<!-- /3.2.5 -->
<!-- 3.2.4 -->
## [3.2.4]
### Added
* Publish to the new flrnnc/seafile-client repository.
* Write notices regarding the Docker repository move.
### Changed
* Use new CI/CD variables.
* Do not run pipelines on Draft MR. (#69)
### Removed
* Remove the changelog from the Seafile documentation.
[3.2.4]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.4
<!-- /3.2.4 -->
## [3.2.3] - 2024/06/27
### Changed
- Update the build badge date on builds. (#61)
[3.2.3]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.3
<!-- /3.2.3 -->
## [3.2.2] - 2024/06/09
### Fixed
- Allow the latest tag to be applied to the v9 versions. (#54)
- Restricted SAST jobs to approved pipelines. (#58)
[3.2.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.2
<!-- /3.2.2 -->
## [3.2.1] - 2024/06/09
### Added
- Merge requests pipeline only runs when merge request has been approved.
### Changed
- Badges are rendered from the Gitlab project itself, not from code. (#62)
[3.2.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.1
<!-- /3.2.1 -->
## [3.2.0] - 2024/06/06
### Changed
- Changed the group _users_ GID from 100 to 90. This allow to use the GID 100. (#64)
[3.2.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.2.0
<!-- /3.2.0 -->
## [3.1.0] - 2024/06/02
### Changed
- Disable pipelines on approved merge requests
### Fixed
- Instanciate the RPC client at the initialization (#63)
[3.1.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.1.0
<!-- /3.1.0 -->
## [3.0.1] - 2024/05/27
### Added
* New script to schedule the best possible time to run the build. It relies on WattTime Load Shift feature (#56)
* Weekly build through pipeline schedules. (#56)
### Changed
* Every links pointing to the previous repository flwgns-docker/seafile-client are pointing now to flrnnc-oss/docker-seafile-client. (#56)
[3.0.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.0.1
<!-- /3.0.1 -->
## [3.0.0] - 2024/03/16
### Added
- Support for multiple libraries synchronization (#44, #43, #41)
- Support for Docker Secrets (#25)
- Support for Seafile client's version through Docker tags (#9)
- Build documentation with Jinja2 templates (#42)
- Manage the project with a Makefile (#38)
- Mock Seafile server for testings (#6)
### Changed
- Revised project layout and workflow (#38, #39)
### Fixed
- Fixed the Docker Hub description publish through their API (#10)
- Add ca-certificates and gnupg to support more HTTP certificates (#24)
[3.0.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/3.0.0
<!-- /3.0.0 -->
## [2.2.0] - 2022/08/26
- Update from Debian Buster to Debian Bullseye (!7)
- Improved Seafile apt source installation (!7)
### __[2.1.1](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 +162,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/flrnnc-oss/docker-seafile-client/-/releases/2.2.0
[2.1.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.1.1
[2.1.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.1.0
[2.0.3]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.2
[2.0.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.2
[2.0.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.1
[2.0.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/2.0.0
[1.2.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.2.1
[1.2.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.2.0
[1.1.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.1.2
[1.1.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.1.1
[1.1.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.1.0
[1.0.6]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.6
[1.0.5]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.5
[1.0.4]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.4
[1.0.3]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.3
[1.0.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.2
[1.0.1]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.1
[1.0.0]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/1.0.0
[0.9.2]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/releases/0.9.2

View File

@@ -13,37 +13,103 @@
They are several ways to help and improve this project.
## Report issues, propose features
You think you found a bug ? You think something is missing out ? Check that it has not been [already reported](https://gitlab.com/flwgns-docker/seafile-client/-/issues). If it has not, [report it](https://gitlab.com/flwgns-docker/seafile-client/-/issues/new?issue).
You think you found a bug ? You think something is missing out ? Check that it has not been [already reported](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/issues). If it has not, [report it](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/issues/new?issue).
## Solve problems
You can't wait for a problem to be solved ? Pick one from the [already reported problems](https://gitlab.com/flwgns-docker/seafile-client/-/issues) and solve it. It will be greatly appreciated!
You can't wait for a problem to be solved ? Pick one from the [already reported problems](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/issues) and solve it. It will be greatly appreciated!
## Say thanks
One great way to help is simply to say thanks. You can do that by [adding a star to the Docker Hub repository](https://hub.docker.com/r/flowgunso/seafile-client) or [just saying thanks in the project topic on Seafile's forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
One great way to help is simply to say thanks. You can do that by [adding a star to the Docker Hub repository](https://hub.docker.com/r/flrnnc/seafile-client) or [just saying thanks in the project topic on Seafile's forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
# Project workflow
The ins and outs of the project, from setting up a local environment for developments to notifying users of changes.
To provide the different Seafile's client versions, the project rely on the [`seafile` package available throughout the different Debian versions][packages]. Check out [Debian Developer's Package Overview][ddpo] and [Debian Package Tracker][tracker] for in depth details regarding that package.
[packages]: https://packages.debian.org/search?keywords=seafile-cli
[ddpo]: https://qa.debian.org/developer.php?login=team%2Bseafile%40tracker.debian.org
[tracker]: https://tracker.debian.org/pkg/seafile
The following state diagram describe essentially the project workflow for a release.
```mermaid
stateDiagram-v2
feature: Checkout new branch from main
changes: Apply changes
mr: Create a Merge Request
pipelines: CI/CD pipelines must be successful
log: Changes must be documented
merge: Branch is squash merged into main
release: Release is created
[*] --> feature
feature --> changes
changes --> mr
mr --> pipelines
pipelines --> log
log --> merge
merge --> release
release --> [*]
```
## Environment
The following is required to develop:
* Docker engine
* Bash
* Make
## 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.

View File

@@ -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

View File

@@ -1,7 +1,7 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2019-2020 flow.gunso@gmail.com
Copyright (C) 2019-2024 florian.anceau@gmail.com
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

64
Makefile Normal file
View File

@@ -0,0 +1,64 @@
TARGET?=stable
# Mocking
mock:
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml up -d
unmock:
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml down
client:
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml rm -fs client
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml up -d client
shell:
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml exec client bash
logs:
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml logs -f client
ps:
TARGET=${TARGET} docker compose -f tests/mock/compose.yaml ps
# Build
build:
TARGET=${TARGET} CI_COMMIT_TAG=${CI_COMMIT_TAG} bash scripts/build-images.sh
build-test:
docker build --build-arg TARGET=${TARGET} -t seafile-client:test tests/image
test:
docker run seafile-client:test
# CI/CD
documents:
python scripts/update-build-badge.py
python scripts/make-documents.py docker.md.j2
python scripts/make-documents.py docker-old.md.j2
python scripts/make-documents.py seafile.md.j2
publish-images:
TARGET=${TARGET} \
DOCKER_REGISTRY_USERNAME=${DOCKER_REGISTRY_USERNAME} \
DOCKER_REGISTRY_TOKEN=${DOCKER_REGISTRY_TOKEN} \
DOCKER_REGISTRY_IMAGE_FLOWGUNSO=${DOCKER_REGISTRY_IMAGE_FLOWGUNSO} \
DOCKER_REGISTRY_IMAGE_FLRNNC=${DOCKER_REGISTRY_IMAGE_FLRNNC} \
bash scripts/publish-images.sh
publish-documents:
bash scripts/publish-documents.sh
save:
mkdir -p tarballs/
docker save --output tarballs/${TARGET}-flowgunso.tar seafile-client:${TARGET}-flowgunso
docker save --output tarballs/${TARGET}-flrnnc.tar seafile-client:${TARGET}-flrnnc
load:
docker load --input tarballs/${TARGET}-flowgunso.tar
docker load --input tarballs/${TARGET}-flrnnc.tar
schedule-weekly-build:
python scripts/schedule-build.py
unschedule-weekly-build:
python scripts/schedule-build.py --disable

177
README.md
View File

@@ -1,91 +1,151 @@
[![](https://img.shields.io/gitlab/pipeline/flwgns-docker/seafile-client/2.2.0?label=Build)](https://gitlab.com/flwgns-docker/seafile-client/commits/2.2.0)
[![](https://img.shields.io/docker/image-size/flowgunso/seafile-client/latest?label=Docker%20image%20size&color=%230778b8)](https://hub.docker.com/r/flowgunso/seafile-client)
[![](https://img.shields.io/docker/pulls/flowgunso/seafile-client?label=Docker%20pulls&color=%230778b8)](https://hub.docker.com/r/flowgunso/seafile-client)
[![](https://img.shields.io/badge/License-GPLv3-red.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![](https://img.shields.io/badge/Source%20code-GitLab-red.svg)](https://gitlab.com/flwgns-docker/seafile-client/)
> ⚠️ Please consider sponsoring this project to help me maintaining and improving it. As of right now, you can support me through Liberay, available in the project badges
**Share a Seafile library as a volume to other containers.**
> This project is switching namespaces. The sources previously in [flwgnso-docker/docker-seafile-client](https://gitlab.com/flwgns-docker/seafile-client) are now in [flrnnc-oss/docker-seafile-client](https://gitlab.com/flrnnc-oss/docker-seafile-client). The Docker image can still be found at [flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client) but it will be deprecated, the image [flrnnc/seafile-client](https://hub.docker.com/r/flrnnc/seafile-client) should be used instead.
# Supported tags
[`2`, `2.2`, `2.2.0`, `latest`](seafile-client/Dockerfile)
# Quick informations
# 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.
<!-- -->
_Docker Seafile client_ is a Docker image that provides a Seafile client to sync one or more library as volumes to other containers.
## 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
## Quick links
* Check out the [roadmap](https://gitlab.com/flrnnc-oss/docker-seafile-client/-/wikis/home#roadmap) to see what is anticipated.
* Check out how to [contribute](CONTRIBUTING.md).
* Report issues on [Gitlab](https://gitlab.com/flrnnc-oss/docker-seafile-client/).
* Ask questions on [Seafile forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
* Contribute and report issues on [Gitlab](https://gitlab.com/flwgns-docker/seafile-client/).
# 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 \
flowgunso/seafile-client:latest
-e SEAF_SERVER_URL="https://seafile.example/" \
-e SEAF_USERNAME="a_seafile_user" \
-e SEAF_PASSWORD="SoMePaSSWoRD" \
-e SEAF_LIBRARY="an-hexadecimal-library-uuid" \
-v path/to/library:/library \
-v path/to/client/data:/seafile \
flrnnc/seafile-client:latest
```
## 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
image: flrnnc/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
image: flrnnc/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 +153,7 @@ services:
GID: "1000"
volumes:
shared_volume:
audio:
documents:
client:
```
Or use the [docker-compose.yml](documentations/docker-compose.yml) template.

View File

@@ -0,0 +1,8 @@
docker run \
-e SEAF_SERVER_URL="https://seafile.example/" \
-e SEAF_USERNAME="a_seafile_user" \
-e SEAF_PASSWORD="SoMePaSSWoRD" \
-e SEAF_LIBRARY="an-hexadecimal-library-uuid" \
-v path/to/library:/library \
-v path/to/client/data:/seafile \
flrnnc/seafile-client:latest

View File

@@ -0,0 +1,28 @@
version: "3"
services:
seafile-client:
image: flrnnc/seafile-client:latest
volumes:
- audio:/library/audio
- documents:/library/documents
- client:/seafile
environment:
SEAF_SERVER_URL: "https://seafile.example/"
SEAF_USERNAME: "a_seafile_user"
SEAF_PASSWORD: "SoMePaSSWoRD"
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
SEAF_2FA_SECRET: "JBSWY3DPEHPK3PXPIXDAUMXEDOXIUCDXWC32CS"
SEAF_UPLOAD_LIMIT: "1000000"
SEAF_DOWNLOAD_LIMIT: "1000000"
SEAF_SKIP_SSL_CERT: "true"
UID: "1000"
GID: "1000"
volumes:
audio:
documents:
client:

View File

@@ -0,0 +1,22 @@
version: "3"
services:
seafile-client:
image: flrnnc/seafile-client:latest
volumes:
- audio:/library/audio
- documents:/library/documents
- client:/seafile
environment:
SEAF_SERVER_URL: "https://seafile.example/"
SEAF_USERNAME: "a_seafile_user"
SEAF_PASSWORD: "SoMePaSSWoRD"
SEAF_LIBRARY_AUDIO: "audio-library-uuid"
SEAF_LIBRARY_AUDIO_PASSWORD: "auDioLiBRaRyPaSSWoRD"
SEAF_LIBRARY_DOCUMENTS: "documents-library-uuid"
volumes:
audio:
documents:
client:

View File

@@ -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:

View File

@@ -0,0 +1,15 @@
{% include "parts/notices.md.j2" %}
{% include "parts/badges.md.j2" %}
**Share one or more Seafile libraries as a volume to other containers.**
{% include "parts/supported_tags.md.j2" %}
{% include "parts/features.md.j2" %}
{% include "parts/usage.md.j2" %}
{% include "parts/troubleshooting.md.j2" %}
{% include "parts/moving-to-another-namespace.md.j2" %}

View File

@@ -0,0 +1,11 @@
{% include "parts/badges.md.j2" %}
**Share one or more Seafile libraries as a volume to other containers.**
{% include "parts/supported_tags.md.j2" %}
{% include "parts/features.md.j2" %}
{% include "parts/usage.md.j2" %}
{% include "parts/troubleshooting.md.j2" %}

View 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" %}

View File

@@ -0,0 +1,3 @@
{% for name, links in badges.items() -%}
[![{{name}}]({{links.image}})]({{links.link}})
{% endfor %}

View File

@@ -0,0 +1,9 @@
# Features
* Synchronize one or more Seafile libraries.
* Support password protected librairies.
* Support two factor authentication.
* Configure upload and download limits.
* Skip SSL certificates.
* Set file ownership with user/group ID
The Docker image is built weekly to keep up with security updates.

View File

@@ -0,0 +1,5 @@
# Moving to another namespace
This repository is being moved to a new namespace [flrnnc](https://hub.docker.com/u/flrnnc).
I am applying to open source software programs on the service providers I rely on such as Gitlab and Docker. It means that my project must be reorganized. The `flrnnc` namespace is dedidacted to open source software I publish on Docker.

View File

@@ -0,0 +1,2 @@
> This repository will be moved to another namespace [flrnnc/seafile-client](https://hub.docker.com/repository/docker/flrnnc/seafile-client/).
> See [moving to another namespace](#moving-to-another-namespace]) for explanations.

View File

@@ -0,0 +1,9 @@
# Supported tags
The versions match Seafile versions.
{% for version in versions %}
[{{ version | join(", ")}}][Dockerfile]
{% endfor %}
[Dockerfile]: https://gitlab.com/flrnnc-oss/docker-seafile-client/-/blob/master/seafile-client/Dockerfile

View File

@@ -0,0 +1,3 @@
# Troubleshooting
* Ask questions on [Seafile forum](https://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573).
* Contribute and report issues on [Gitlab](https://gitlab.com/flrnnc-oss/docker-seafile-client/).

View 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" %}
```

View File

@@ -0,0 +1,29 @@
Hello everyone,
I wanted to use files from my Seafile server within Docker containers.
I started looking for existing image featuring a Seafile client on Docker Hub. There are some, but with issues such as non-existant/vague documentation or improper tagging.
I don't know if it's something that people are looking for, but I made one. It's available at flowgunso/seafile-client in Docker Hub.
Example usage with docker-compose and for the docker cli are provided. Essentially, it runs `seaf-cli sync`, but you have to pass to the container your Seafile server URL, your credentials and the library ID you want to sync with. Then you can share the path `/library` as a volume to your containers for your own usages.
Feedback is welcome so I can keep improving it.
# Quick informations
{% include "parts/badges.md.j2" %}
**Please use [u][flrnnc/seafile-client](https://hub.docker.com/r/flrnnc/seafile-client)[/u] instead of [u][flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client)[/u] from now on.**
This project is switching namespaces. The sources previously in [flwgnso-docker/docker-seafile-client](https://gitlab.com/flwgns-docker/seafile-client) are now in [flrnnc-oss/docker-seafile-client](https://gitlab.com/flrnnc-oss/docker-seafile-client). The Docker image can still be found at [flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client) but it will be deprecated, the image [flrnnc/seafile-client](https://hub.docker.com/r/flrnnc/seafile-client) should be used instead.
[flowgunso/seafile-client](https://hub.docker.com/r/flowgunso/seafile-client) will still be updated until usage is low enough to be archived.
{% include "parts/supported_tags.md.j2" %}
{% include "parts/features.md.j2" %}
{% include "parts/usage.md.j2" %}
{% include "parts/troubleshooting.md.j2" %}

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# Docker Seafile client, help you mount a Seafile library as a volume.
# Copyright (C) 2019-2020, flow.gunso@gmail.com
# Copyright (C) 2019-2024, florian.anceau@gmail.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,12 +16,26 @@
# 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 .
$build_arguments \
--build-arg IMAGE=flowgunso \
--tag seafile-client:$TARGET-flowgunso \
seafile-client/
docker save --output $CI_PROJECT_NAME.tar $CI_PROJECT_NAME:build
docker build \
$build_arguments \
--build-arg IMAGE=flrnnc \
--tag seafile-client:$TARGET-flrnnc \
seafile-client/

93
scripts/make-documents.py Executable file
View File

@@ -0,0 +1,93 @@
# !/usr/bin/env python
from pathlib import Path
import argparse
import os
from jinja2 import Environment, FileSystemLoader
from gitlab import Gitlab
REPOSITORY_PATH = Path(__file__).parent.parent
class DocumentMaker:
def __init__(self, filename: str) -> None:
# Intanciate the Jinja2 renderer.
self.directory = REPOSITORY_PATH.joinpath("documentations")
loader = FileSystemLoader(self.directory)
environment = Environment(loader=loader)
self.filename = filename
self.template = environment.get_template(filename)
# Instanciate the Gitlab session.
gitlab_project_id=os.environ["CI_PROJECT_ID"]
gitlab_private_token=os.environ["WEEKLY_BUILD_PRIVATE_TOKEN"]
self.gitlab = Gitlab(private_token=gitlab_private_token)
self.project = self.gitlab.projects.get(gitlab_project_id)
self.versions = []
self.badges = {}
def get_versions(self):
versions = []
for path in Path("versions").iterdir():
with open(path, "rt") as fo:
versions.append(fo.read().strip())
versions.sort(reverse=True)
# Prepare the render context.
latest = True
self.versions = []
for version in versions:
version = version.strip()
parts = version.split(".")
increments = []
blocks = []
for part in parts:
increments.append(part)
section = ".".join(increments)
blocks.append(f"`{section}`")
if latest:
blocks.append("`latest`")
latest = False
self.versions.append(blocks)
def get_badges(self):
badges = self.project.badges.list()
for badge in badges:
name = badge.name
link = badge.rendered_link_url
image = badge.rendered_image_url
links = {"link": link, "image": image}
self.badges[name] = links
def render(self):
# Render
# TODO: read and adapt the CHANGELOG and insert into the render.
content = self.template.render(versions=self.versions, badges=self.badges)
#content = template.render() # When version/ is unavailable.
filename = Path(self.filename).with_suffix("")
path = self.directory.joinpath(filename)
# Write to file
with open(path, mode="w") as fo:
fo.write(content)
if __name__ == "__main__":
# Argument parsing.
parser = argparse.ArgumentParser(prog="Seafile Docker client documentation renderer")
parser.add_argument("template", type=str)
args = parser.parse_args()
maker = DocumentMaker(args.template)
maker.get_versions()
maker.get_badges()
maker.render()

View File

@@ -0,0 +1,30 @@
# Get a token from hub.docker.com with the owner credentials.
token=$(curl -s \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "'"$DOCKER_REGISTRY_USERNAME"'", "password": "'"$DOCKER_REGISTRY_TOKEN"'"}' \
https://hub.docker.com/v2/users/login/ | jq -r .token)
# Generate a JSON with the README.md as the full_description.
json=$(jq -n \
--arg readme "$(<documentations/docker.md)" \
'{"full_description": $readme,"description": "'"$DOCKER_REGISTRY_DESCRIPTION_FLRNNC"'"}')
jsonOld=$(jq -n \
--arg readme "$(<documentations/docker-old.md)" \
'{"full_description": $readme,"description": "'"$DOCKER_REGISTRY_DESCRIPTION_FLOWGUNSO"'"}')
# Update the Docker Hub repository's full_description.
curl -siL \
-X PATCH \
-d "$jsonOld" \
-H "Content-Type: application/json" \
-H "Authorization: JWT $token" \
"https://hub.docker.com/v2/repositories/$DOCKER_REGISTRY_IMAGE_FLOWGUNSO/"
curl -siL \
-X PATCH \
-d "$json" \
-H "Content-Type: application/json" \
-H "Authorization: JWT $token" \
"https://hub.docker.com/v2/repositories/$DOCKER_REGISTRY_IMAGE_FLRNNC/"

54
scripts/publish-images.sh Normal file
View File

@@ -0,0 +1,54 @@
# !/bin/bash
# Docker Seafile client, help you mount a Seafile library as a volume.
# Copyright (C) 2019-2024, florian.anceau@gmail.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -ex
raise() {
echo $1
exit 1
}
# Grab version with the container
version="$(docker run --rm seafile-client:$TARGET-flrnnc cat -s /SEAFILE_VERSION)"
version="$(echo ${version%-*})"
# Output the version to an artifact for documentation rendering.
mkdir -p versions/
echo $version >> "versions/$TARGET"
# Generate version tags.
tags=()
[[ "$TARGET" =~ "unstable" ]] && tags+=("latest")
for version_component in $(echo $version | tr '.' '\n'); do
tag+="$version_component"
tags+=("$tag")
tag+="."
done
# Tag then push to the Docker Hub registry.
echo $DOCKER_REGISTRY_TOKEN | docker login --password-stdin --username $DOCKER_REGISTRY_USERNAME
for tag in "${tags[@]}"; do
docker tag seafile-client:$TARGET-flowgunso $DOCKER_REGISTRY_IMAGE_FLOWGUNSO:$tag
docker push $DOCKER_REGISTRY_IMAGE_FLOWGUNSO:$tag
done
for tag in "${tags[@]}"; do
docker tag seafile-client:$TARGET-flrnnc $DOCKER_REGISTRY_IMAGE_FLRNNC:$tag
docker push $DOCKER_REGISTRY_IMAGE_FLRNNC:$tag
done

132
scripts/schedule-build.py Normal file
View File

@@ -0,0 +1,132 @@
# !/usr/bin/env python
import os
import argparse
import sys
from datetime import datetime
import requests
from requests.auth import HTTPBasicAuth
from gitlab import Gitlab
class Scheduler:
WATTTIME_SIGNAL_TYPE="co2_moer"
def __init__(self, watttime_username, watttime_password, gitlab_private_token,
gitlab_project_id, gitlab_scheduled_pipeline_id):
# Instanciate the WattTime session.
url = "https://api.watttime.org/login"
response = requests.get(url, auth=HTTPBasicAuth(watttime_username, watttime_password))
payload = response.json()
token = payload["token"]
headers = {"Authorization": f"Bearer {token}"}
self.watttime = requests.session()
self.watttime.headers = headers
# Instanciate the Gitlab session and grab the Weekly build scheduled pipeline.
self.gitlab = Gitlab(private_token=gitlab_private_token)
project = self.gitlab.projects.get(gitlab_project_id)
self.pipeline = project.pipelineschedules.get(gitlab_scheduled_pipeline_id)
def geolocate(self):
url = "https://ipinfo.io"
response = requests.get(url)
payload = response.json()
geolocation = payload["loc"]
self.latitude, self.longitude = geolocation.split(",")
def load_shift(self):
# Get region from geolocation.
# TODO: uncomment once premium plan
# url = "https://api.watttime.org/v3/region-from-loc"
# params = {
# "latitude": self.latitude,
# "longitude": self.longitude,
# "signal_type": self.WATTTIME_SIGNAL_TYPE}
# response = self.watttime.get(url, params=params)
# payload = response.json()
# region = payload["region"]
# Get the forecast for said region.
# TODO: don't override the region, get a premium plan
url = "https://api.watttime.org/v3/forecast"
region = "CAISO_NORTH" # Override the region until I get a premium plan
params = {"region": region, "signal_type": self.WATTTIME_SIGNAL_TYPE}
response = self.watttime.get(url, params=params)
payload = response.json()
data = payload["data"]
# Look for the lowest value and it's datetime. Store the current value to know improvements.
lowest_value: float = None
for obj in data:
value = obj["value"]
point_time = datetime.fromisoformat(obj["point_time"])
if not lowest_value:
self.now_value = self.lowest_value = value
self.now = self.then = point_time
continue
if value < lowest_value:
lowest_value = value
self.then = point_time
def metrics(self):
# Write WattTime metrics.
metrics = {}
metrics["watttime_now"] = self.now_value
metrics["watttime_lowest"] = self.lowest_value
metrics["now"] = self.now
metrics["self.then"] = self.then
with open("metrics.txt", "wt") as fileobject:
for metric, value in metrics.items():
fileobject.write(f"{metric} {value}\n")
# TODO: track the metrics of energy cost/gain
def schedule(self):
# Test ownership prior to overtaking ownership.
self.gitlab.auth()
if self.pipeline.owner["id"] != self.gitlab.user.id:
self.pipeline.take_ownership()
# Set pipeline cron schedule to WattTime's Load Shift best moment.
cron = f"{self.then.minute} {self.then.hour} {self.then.day} {self.then.month} *"
self.pipeline.cron = cron
self.pipeline.active = True
self.pipeline.save()
def unschedule(self):
self.pipeline.active = False
self.pipeline.save()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="",
description="",
epilog=""
)
parser.add_argument("--disable", action="store_true")
args = parser.parse_args()
disable = args.disable
scheduler = Scheduler(
watttime_username=os.environ["WATTTIME_USERNAME"],
watttime_password=os.environ["WATTTIME_PASSWORD"],
gitlab_project_id=os.environ["CI_PROJECT_ID"],
gitlab_private_token=os.environ["WEEKLY_BUILD_PRIVATE_TOKEN"],
gitlab_scheduled_pipeline_id=os.environ["WEEKLY_BUILD_PIPELINE_ID"]
)
if disable:
scheduler.unschedule()
sys.exit()
scheduler.geolocate()
scheduler.load_shift()
scheduler.metrics()
scheduler.schedule()

View File

@@ -0,0 +1,34 @@
# !/usr/bin/env python
import os
from datetime import datetime
from gitlab import Gitlab
class BuildBadgeUpdater:
def __init__(self, gitlab_private_token, gitlab_project_id, gitlab_build_badge_id):
# Instanciate the Gitlab session and grab the Weekly build scheduled pipeline.
self.gitlab = Gitlab(private_token=gitlab_private_token)
project = self.gitlab.projects.get(gitlab_project_id)
self.badge = project.badges.get(gitlab_build_badge_id)
def update(self):
now = datetime.now()
date = now.strftime(r"%Y--%m--%d")
image_url = f"https://img.shields.io/badge/_-{date}-_?label=last%20build&color=light-green"
self.badge.image_url = image_url
self.badge.save()
if __name__ == "__main__":
build_badge_updater = BuildBadgeUpdater(
gitlab_project_id=os.environ["CI_PROJECT_ID"],
gitlab_private_token=os.environ["WEEKLY_BUILD_PRIVATE_TOKEN"],
gitlab_build_badge_id=os.environ["BUILD_BADGE_ID"]
)
build_badge_updater.update()

58
seafile-client/Dockerfile Normal file
View File

@@ -0,0 +1,58 @@
ARG TARGET=unstable
FROM debian:${TARGET}-slim
ARG UID
ARG GID
ARG IMAGE
ENV UID 1000
ENV GID 1000
ENV PYTHONUNBUFFERED 1
ENV IMAGE ${IMAGE}
RUN apt-get update && \
apt-get install \
--no-install-recommends \
--yes \
seafile-cli \
oathtool \
ca-certificates \
gnupg \
sudo && \
apt-get clean && apt-get autoclean && \
rm -rf \
/var/log/fsck/*.log \
/var/log/apt/*.log \
/var/cache/debconf/*.dat-old \
/var/lib/apt/lists/* && \
groupmod -g 90 users
COPY --chmod=755 entrypoint-docker.sh /entrypoint.sh
COPY issue /etc/issue
RUN echo '[ ! -z $TERM ] && cat /etc/issue' >> /root/.bashrc && \
groupadd --gid $GID seafile && \
useradd --uid $UID --gid $GID --shell /bin/bash --create-home seafile && \
mkdir /library /seafile && \
chown seafile:seafile /seafile /library && \
apt-cache show seafile-cli | grep 'Version: ' | awk '{print $2}' > /SEAFILE_VERSION
COPY --chmod=755 --chown=seafile:seafile entrypoint-seafile.py /home/seafile/entrypoint.py
ARG CREATED
ARG REVISION
ARG VERSION
LABEL org.opencontainers.image.created=${CREATED}
LABEL org.opencontainers.image.authors="florian.anceau@gmail.com"
LABEL org.opencontainers.image.url="https://hub.docker.com/r/flrnnc/seafile-client"
LABEL org.opencontainers.image.documentation="https://gitlab.com/flrnnc-oss/docker-seafile-client"
LABEL org.opencontainers.image.source="https://gitlab.com/flrnnc-oss/docker-seafile-client"
LABEL org.opencontainers.image.version=${VERSION}
LABEL org.opencontainers.image.revision=${REVISION}
LABEL org.opencontainers.image.licenses="GPL-3.0"
LABEL org.opencontainers.image.title="Seafile Docker client"
LABEL org.opencontainers.image.description="Sync Seafile librairies within Docker containers."
ENTRYPOINT ["/entrypoint.sh"]
CMD ["/home/seafile/entrypoint.py"]
HEALTHCHECK \
CMD ["/entrypoint.sh", "/home/seafile/entrypoint.py", "--healthcheck"]

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,42 @@
#!/bin/bash
# Docker Seafile client, help you mount a Seafile library as a volume.
# Copyright (C) 2019-2024, florian.anceau@gmail.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#!/bin/bash
set -e
groupmod -g $GID seafile &> /dev/null
usermod -u $UID -g $GID seafile &> /dev/null
if [ "$IMAGE" == "flowgunso" ]; then
echo
echo -e "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓"
echo -e "┃ \e[1mPlease use \e[4mflrnnc/seafile-client\e[24m instead of \e[4mflowgunso/seafile-client\e[24m which will be deprecated...\e[0m ┃"
echo -e "┃ See the information notices at: ┃"
echo -e "┃ \thttps://forum.seafile.com/t/docker-client-to-sync-files-with-containers/8573 ┃"
echo -e "┃ \thttps://gitlab.com/flrnnc-oss/docker-seafile-client ┃"
echo -e "┃ \thttps://hub.docker.com/r/flowgunso/seafile-client ┃"
echo -e "┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛"
echo
fi
sudo \
-HE \
-u seafile \
-- "$@"

View File

@@ -0,0 +1,312 @@
#!/usr/bin/env python3
from pathlib import Path
from typing import Any
import argparse
import logging
import os
import subprocess
import sys
import time
import seafile
class BadConfiguration(Exception):
pass
def get_configuration(variable: str, *args) -> Any:
"""Helper function to get a configuration.
see https://gitlab.com/-/snippets/1941025
"""
# Assign the default value from the first item of *args.
if args:
default = args[0]
# Try to get the variable from a Docker Secret.
try:
file = os.environ[f"{variable}_FILE"]
except KeyError:
pass
else:
with open(file, "rt") as fo:
return fo.read()
# Try to get the variable from an environment variable.
try:
return os.environ[variable]
except KeyError:
pass
# Try to return the default value,
# if no default exist, then it is a required variable.
try:
return default
except UnboundLocalError:
raise BadConfiguration(
f"Environment variable {variable} was not found but is required."
)
class Client:
def __init__(self) -> None:
# Client configuration
self.username: str = get_configuration("SEAF_USERNAME")
self.password: str = get_configuration("SEAF_PASSWORD")
self.url: str = get_configuration("SEAF_SERVER_URL")
self.skip_ssl_cert: bool = bool(get_configuration("SEAF_SKIP_SSL_CERT", None))
self.upload_limit: int = get_configuration("SEAF_UPLOAD_LIMIT", None)
self.download_limit: int = get_configuration("SEAF_DOWNLOAD_LIMIT", None)
self.mfa_secret: str = get_configuration("SEAF_2FA_SECRET", None)
# Paths
self.ini = Path.home().joinpath(".ccnet", "seafile.ini")
self.log = Path.home().joinpath(".ccnet", "logs", "seafile.log")
self.seafile = Path("/seafile")
self.socket = self.seafile.joinpath("seafile-data", "seafile.sock")
self.target = Path("/library")
# Binaries, instances.
if self.socket.exists():
self.rpc = seafile.RpcClient(str(self.socket))
self.binary = ["seaf-cli"]
self._get_librairies()
def _get_librairies(self):
self.libraries = {}
# Single library use case. Mutually exclusive to mulitple labraries use case.
single_library_variables = ["SEAF_LIBRARY", "SEAF_LIBRARY_UUID", "SEAF_LIBRARY_PASSWORD"]
if any(environ in single_library_variables for environ in os.environ):
logger.info("Single library detected. Multiple libraries will be ignored.")
library = {}
# Grab the UUID, usin both the
uuid = None
if legacy := os.getenv("SEAF_LIBRARY_UUID", None):
logger.warning("SEAF_LIBRARY_UUID is obsolete, please use SEAF_LIBRARY instead.")
uuid = legacy
if current := os.getenv("SEAF_LIBRARY", None):
uuid = current
# Exit if no UUID was provided, continue otherwise.
if uuid is None:
raise Exception("Please provide an UUID with SEAF_LIBRARY for single library usage.")
library["uuid"] = uuid
if password := os.getenv("SEAF_LIBRARY_PASSWORD", None):
library["password"] = password
# Assign and return a default library.
self.libraries["_"] = library
return
# Multiple libraries use case.
# Loop over all sorted variables prefixed with SEAF_LIBRARY.
for variable in sorted(os.environ):
if variable.startswith("SEAF_LIBRARY"):
# Get the variable name.
name = variable.split("_")[2].lower()
# Read the password as a secret.
if "_PASSWORD" in variable:
password = get_configuration(variable, None)
try:
if password:
self.libraries[name]["password"] = password
except KeyError:
logger.warning(f"Cannot set a password to unknown library {name}")
# Or got the name, build the dictionary with the name and uuid.
else:
self.libraries[name] = {}
uuid = os.environ[variable]
self.libraries[name]["uuid"] = uuid
def initialize(self):
# Initialize the Seafile client.
logger.info("Initializing `seaf-cli`.")
if not self.ini.exists():
logger.info("Seafile .ini file not found, running `seaf-cli init`")
#self.ini.parent.parent.mkdir(parents=True, exist_ok=True)
subprocess.run(self.binary + ["init", "-d", str(self.seafile)])
while not self.ini.exists():
logging.debug("Waiting for the .ini file to be created...")
time.sleep(1)
# Start the Seafile client.
logger.info("Starting `seaf-cli`.")
subprocess.run(self.binary + ["start"])
while not self.socket.exists():
logger.debug("Waiting for the Seafile client socket to be created.")
time.sleep(1)
self.rpc = seafile.RpcClient(str(self.socket))
def configure(self):
command = self.binary + ["config"]
if self.skip_ssl_cert:
subprocess.run(command +["-k", "disable_verify_certificate", "-v", str(self.skip_ssl_cert)])
if self.download_limit:
subprocess.run(command +["-k", "download_limit", "-v", self.download_limit])
if self.upload_limit:
subprocess.run(command +["-k", "upload_limit", "-v", self.upload_limit])
def synchronize(self):
core = self.binary + ["sync", "-u", self.username, "-p", self.password, "-s", self.url]
for name, configuration in self.libraries.items():
uuid = configuration["uuid"]
# Check if repository is already synced.
repository = self.rpc.get_repo(uuid)
if repository is not None:
logger.info(f"Library {name} is already synced.")
continue
command = core + ["-l", uuid]
if "password" in configuration:
password = configuration["password"]
command += ["-e", password]
target = self.target if name == "_" else self.target.joinpath(name)
target.mkdir(parents=True, exist_ok=True)
command += ["-d", str(target)]
if self.mfa_secret:
totp = subprocess.run(
f"oathtool --base32 --totp {self.mfa_secret}",
text=True,
capture_stdout=True).stdout
command += ["-a", totp]
logging.debug(f"Running {' '.join(command)}")
subprocess.run(command)
def follow(self):
logging.debug(f"Running `tail -v -f {self.log}`")
subprocess.run(["tail", "-v", "-f", self.log])
def healthcheck(self):
tasks = self.rpc.get_clone_tasks()
healthy = True
for task in tasks:
name = task.repo_name
state = task.state
if task.state == 'done':
continue
elif state == "fetch":
tx_task = self.rpc.find_transfer_task(task.repo_id)
percentage = 0 if tx_task.block_done == 0 else tx_task.block_done / tx_task.block_total * 100
rate = 0 if tx_task.rate == 0 else tx_task.rate / 1024.0
print(f"{name:<50s}\t{state:<20s}\t{percentage:<.1f}%, {rate:<.1f}KB/s")
elif task.state == "error":
healthy = False
error = self.rpc.sync_error_id_to_str(task.error)
print(f"{name:<50s}\t{state:<20s}\t{error}")
else:
print(f"{name:<50s}\t{state:<20s}")
repos = self.rpc.get_repo_list(-1, -1)
for repo in repos:
name = repo.name
auto_sync_enabled = self.rpc.is_auto_sync_enabled()
if not auto_sync_enabled or not repo.auto_sync:
state = "auto sync disabled"
print(f"{name:<50s}\t{state:<20s}")
continue
task = self.rpc.get_repo_sync_task(repo.id)
if task is None:
state = "waiting for sync"
print(f"{name:<50s}\t{state:<20s}")
continue
state = task.state
if state in ['uploading', 'downloading']:
tx_task = self.rpc.find_transfer_task(repo.id)
if tx_task.rt_state == "data":
state += " files"
percentage = 0 if tx_task.block_done == 0 else tx_task.block_done / tx_task.block_total * 100
rate = 0 if tx_task.rate == 0 else tx_task.rate / 1024.0
print(f"{name:<50s}\t{state:<20s}\t{percentage:<.1f}%, {rate:<.1f}KB/s")
elif tx_task.rt_state == "fs":
state += " files list"
percentage = 0 if tx_task.fs_objects_done == 0 else tx_task.fs_objects_done / tx_task.fs_objects_total * 100
print(f"{name:<50s}\t{state:<20s}\t{percentage:<.1f}%")
elif state == 'error':
healthy = False
error = self.rpc.sync_error_id_to_str(task.error)
print(f"{name:<50s}\t{state:<20s}\t{error}")
else:
print(f"{name:<50s}\t{state:<20s}")
def entrypoint():
try:
logging.debug("Instanciating the client")
client = Client()
except BadConfiguration as e:
logger.error(f"Bad configuration: {e}")
sys.exit(1)
logging.debug("Initializing the client")
client.initialize()
logging.debug("Configuring the client")
client.configure()
logging.debug("Synchronizing the client")
client.synchronize()
logging.debug("Following the client")
client.follow()
debug = get_configuration("DEBUG", False)
level = logging.INFO
format = "%(asctime)s - %(levelname)s - %(message)s"
if debug:
level = logging.DEBUG
format = "%(asctime)s - %(filename)s:%(lineno)d - %(levelname)s - %(message)s"
logging.basicConfig(format=format, level=level)
logger = logging.getLogger()
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="",
description="",
epilog=""
)
parser.add_argument("--healthcheck", action="store_true")
args = parser.parse_args()
healthcheck = args.healthcheck
if healthcheck:
logger.disabled = True
try:
logging.debug("Instanciating the client")
client = Client()
except BadConfiguration as e:
logger.error(f"Bad configuration: {e}")
sys.exit(1)
if healthcheck:
logging.debug("Running healthchecks")
sys.exit(client.healthcheck())
logging.debug("Initializing the client")
client.initialize()
logging.debug("Configuring the client")
client.configure()
logging.debug("Synchronizing the client")
client.synchronize()
logging.debug("Following the client")
client.follow()

4
seafile-client/issue Normal file
View File

@@ -0,0 +1,4 @@
┌───────────────────────┐
│ Seafile Docker client │
└───────────────────────┘
Run `./entrypoint.sh bash` to login as the seafile user.

View File

@@ -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

View File

@@ -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
View File

@@ -0,0 +1,6 @@
ARG TARGET=unstable
FROM seafile-client:${TARGET}-flrnnc
COPY --chmod=755 test_binaries.sh /test.sh
CMD ["/test.sh"]

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# Docker Seafile client, help you mount a Seafile library as a volume.
# Copyright (C) 2019-2020, flow.gunso@gmail.com
# Copyright (C) 2019-2024, florian.anceau@gmail.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

56
tests/mock/compose.yaml Normal file
View File

@@ -0,0 +1,56 @@
name: mock-docker-seafile-client
services:
mariadb:
image: mariadb:10.11
environment:
- MYSQL_ROOT_PASSWORD=password # Requested, set the root's password of MySQL service.
- MYSQL_LOG_CONSOLE=true
- MARIADB_AUTO_UPGRADE=1
volumes:
- database:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store.
memcached:
image: memcached:1.6.18
container_name: seafile-memcached
entrypoint: memcached -m 256
seafile:
image: seafileltd/seafile-mc:latest
ports:
- "80:80"
volumes:
- seafile:/shared # Requested, specifies the path to Seafile data persistent store.
environment:
- DB_HOST=mariadb
- DB_ROOT_PASSWD=password # Requested, the value should be root's password of MySQL service.
- TIME_ZONE=Etc/UTC # Optional, default is UTC. Should be uncomment and set to your local time zone.
- SEAFILE_ADMIN_EMAIL=seafile@localhost # Specifies Seafile admin user, default is 'me@example.com'.
- SEAFILE_ADMIN_PASSWORD=password # Specifies Seafile admin password, default is 'asecret'.
- SEAFILE_SERVER_LETSENCRYPT=false # Whether to use https or not.
depends_on:
- mariadb
- memcached
client:
image: seafile-client:${TARGET}-flowgunso
volumes:
#- library:/library
- data:/seafile
# user: "1000:1000"
environment:
SEAF_SERVER_URL: "http://seafile"
SEAF_USERNAME: "seafile@localhost"
SEAF_PASSWORD: "password"
SEAF_LIBRARY: "1b7d4e92-6753-4c4a-85b0-42566eab42c8"
DEBUG: 1
UID: 1000
GID: 100
depends_on:
- seafile
volumes:
database:
seafile:
library:
data: