diff --git a/.dockerignore b/.dockerignore index 82650f5..72e8ffc 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1 @@ -.tox/ -.git/ -.gitignore -LICENSE -README.md +* diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml new file mode 100644 index 0000000..c8084c2 --- /dev/null +++ b/.github/workflows/container.yml @@ -0,0 +1,47 @@ +name: Build Container Image + +on: + push: + branches: + - main + - master + tags: + - "v*" + pull_request: {} + +env: + REGISTRY: ghcr.io + IMAGE_NAME: vshn/modulesync + +jobs: + # Push image to GitHub Packages. + container: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v4 + + - name: Log in to the Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Determine Tags & Labels based on Git ref + id: meta + uses: docker/metadata-action@v5 + with: + images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}" + + - name: Build & Push container image + uses: docker/build-push-action@v6 + with: + context: . + file: ./Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/0.10.0/Dockerfile b/0.10.0/Dockerfile deleted file mode 100644 index 023e652..0000000 --- a/0.10.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 0.10.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/0.9.0/Dockerfile b/0.9.0/Dockerfile deleted file mode 100644 index e73fb03..0000000 --- a/0.9.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 0.9.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/1.0.0/Dockerfile b/1.0.0/Dockerfile deleted file mode 100644 index 3b2c049..0000000 --- a/1.0.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 1.0.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/1.1.0/Dockerfile b/1.1.0/Dockerfile deleted file mode 100644 index de6c1c3..0000000 --- a/1.1.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 1.1.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/1.2.0/Dockerfile b/1.2.0/Dockerfile deleted file mode 100644 index cfead47..0000000 --- a/1.2.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 1.2.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/1.3.0/Dockerfile b/1.3.0/Dockerfile deleted file mode 100644 index dcbea10..0000000 --- a/1.3.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 1.3.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/2.0.0/Dockerfile b/2.0.0/Dockerfile deleted file mode 100644 index dfa1bdd..0000000 --- a/2.0.0/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM ruby:2.5-slim - -LABEL maintainer="VSHN AG " - -WORKDIR /app - -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ - git \ - && gem install modulesync --version 2.0.0 \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -USER msync - -CMD ["msync"] diff --git a/Dockerfile b/Dockerfile index 7d650a8..ae752ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,17 @@ -FROM ruby:2.7-slim - -LABEL maintainer="VSHN AG " - +FROM docker.io/library/ruby:3.3-slim WORKDIR /app -RUN adduser --disabled-password --gecos '' msync \ - && apt-get update \ - && apt-get install -y --no-install-recommends \ - build-essential \ +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ git \ - ssh \ - && git clone --depth=1 https://github.com/voxpupuli/modulesync.git \ - && cd modulesync \ - && gem build modulesync.gemspec \ - && gem install --no-document modulesync-*.gem \ - && apt-get purge -y build-essential \ - && apt-get autoremove --purge -y \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* \ - && cd .. \ - && rm -rf modulesync + openssh-client && \ + apt-get clean all && \ + rm -rf /var/lib/apt/lists/* && \ + adduser --disabled-password --gecos '' msync -USER msync +# renovate: datasource=rubygems depName=modulesync versioning=ruby +ENV MODULESYNC_VERSION="3.2.0" +RUN gem install modulesync --version="$MODULESYNC_VERSION" -CMD ["msync"] +USER msync +CMD ["msync", "help"] diff --git a/README.md b/README.md index 38e5f37..529ee02 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,6 @@ -ModuleSync -========== +# ModuleSync -[![dockeri.co](http://dockeri.co/image/vshn/modulesync)](https://hub.docker.com/r/vshn/modulesync/) - -[![Build Status](https://img.shields.io/travis/vshn/docker-modulesync/master.svg)](https://travis-ci.org/vshn/docker-modulesync -) [![GitHub issues](https://img.shields.io/github/issues-raw/vshn/docker-modulesync.svg)](https://github.com/vshn/docker-modulesync/issues -) [![GitHub PRs](https://img.shields.io/github/issues-pr-raw/vshn/docker-modulesync.svg)](https://github.com/vshn/docker-modulesync/pulls -) [![License](https://img.shields.io/github/license/vshn/docker-modulesync.svg)](https://github.com/vshn/docker-modulesync/blob/master/LICENSE) - -Repository File Sync --------------------- +## Repository File Sync Originally, a utility script to keep configuration files in sync for Puppet modules, [ModuleSync](https://github.com/voxpupuli/modulesync/) allows you to keep files in @@ -23,101 +14,28 @@ This Docker image runs ModuleSync with an unprivileged `msync` user in `/app`. See [Concierge](https://github.com/vshn/docker-concierge/) if you want to sync multiple configurations from a single configuration repository. -Supported Tags --------------- - -- [![latest]( - https://img.shields.io/badge/latest-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:latest.svg)]( - https://microbadger.com/images/vshn/modulesync:latest) [![based on]( - https://img.shields.io/badge/Git-master-grey.svg?colorA=5a5b5c&colorB=9a9b9c&logo=github)]( - https://github.com/voxpupuli/modulesync) -- [![2.0.0]( - https://img.shields.io/badge/2.0.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/2.0.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:2.0.0.svg)]( - https://microbadger.com/images/vshn/modulesync:2.0.0) [![based on]( - https://img.shields.io/badge/Gem-2.0.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/2.0.0) -- [![1.3.0]( - https://img.shields.io/badge/1.3.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/1.3.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:1.3.0.svg)]( - https://microbadger.com/images/vshn/modulesync:1.3.0) [![based on]( - https://img.shields.io/badge/Gem-1.3.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/1.3.0) -- [![1.2.0]( - https://img.shields.io/badge/1.2.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/1.2.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:1.2.0.svg)]( - https://microbadger.com/images/vshn/modulesync:1.2.0) [![based on]( - https://img.shields.io/badge/Gem-1.2.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/1.2.0) -- [![1.1.0]( - https://img.shields.io/badge/1.1.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/1.1.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:1.1.0.svg)]( - https://microbadger.com/images/vshn/modulesync:1.1.0) [![based on]( - https://img.shields.io/badge/Gem-1.1.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/1.1.0) -- [![1.0.0]( - https://img.shields.io/badge/1.0.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/1.0.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:1.0.0.svg)]( - https://microbadger.com/images/vshn/modulesync:1.0.0) [![based on]( - https://img.shields.io/badge/Gem-1.0.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/1.0.0) -- [![0.10.0]( - https://img.shields.io/badge/0.10.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/0.10.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:0.10.0.svg)]( - https://microbadger.com/images/vshn/modulesync:0.10.0) [![based on]( - https://img.shields.io/badge/Gem-0.10.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/0.10.0) -- [![0.9.0]( - https://img.shields.io/badge/0.9.0-blue.svg?colorA=22313f&colorB=4a637b&logo=docker)]( - https://github.com/vshn/docker-modulesync/blob/master/0.9.0/Dockerfile) [![size/layers]( - https://images.microbadger.com/badges/image/vshn/modulesync:0.9.0.svg)]( - https://microbadger.com/images/vshn/modulesync:0.9.0) [![based on]( - https://img.shields.io/badge/Gem-0.9.0-red.svg?colorA=ff919f&colorB=9a9b9c&logo=ruby)]( - https://rubygems.org/gems/modulesync/versions/0.9.0) - -Usage ------ +## Usage In a GitLab CI configuration file: -``` - image: vshn/modulesync - script: - - msync update -``` - -In a Docker Compose file as a pseudo-service: - -``` - modulesync: - image: vshn/modulesync - volumes: - - .:/app +```yaml +image: ghcr.io/vshn/modulesync +script: + - msync update ``` With Docker on the command line: -```bash -$ docker run --rm -v "$PWD":/app vshn/modulesync msync update +```sh +$ docker run --rm -v "$PWD":/app ghcr.io/vshn/modulesync msync update ``` -Development ------------ +## Development - [Issue tracker](https://github.com/vshn/docker-modulesync/) (GitHub) To add a new ModuleSync version tag: -1. Add the version number to the [update script]( - https://github.com/vshn/docker-modulesync/blob/master/update.py#L7-L10), and -1. Run `./update.py` and update the Docker build settings as indicated. - -Please, run [tox](https://tox.readthedocs.io/) before contributing changes. +1. Renovate should automatically create a [Pull Request](https://github.com/vshn/docker-modulesync/pulls). +1. After merging it, make sure you pulled the latest commits, and run `./tag.sh` to create an appropriate Git Tag. +1. `git push --follow-tags` to push the tag. A new docker image is built automatically. diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..1758330 --- /dev/null +++ b/renovate.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended"], + "customManagers": [ + { + "customType": "regex", + "fileMatch": ["^Dockerfile$"], + "matchStrings": [ + "#\\s*renovate:\\s*datasource=(?.*?) depName=(?.*?)( versioning=(?.*?))?\\sENV .*?_VERSION=\"(?.*)\"\\s" + ], + "versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}" + } + ] +} diff --git a/tag.sh b/tag.sh new file mode 100755 index 0000000..103d48c --- /dev/null +++ b/tag.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +tag="v$(awk -F'=' '/ENV MODULESYNC_VERSION/{ print $2 }' Dockerfile)" +git tag -s "${tag}" -m "Release ${tag}" + +echo "---> Tagged as ${tag}" +echo " Don't forget to push the tag: git push --follow-tags" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index 0e37622..0000000 --- a/tox.ini +++ /dev/null @@ -1,20 +0,0 @@ -[tox] -envlist = - flake8 - pylint -skipsdist = true - -[testenv:flake8] -deps = flake8 -commands = flake8 {posargs} - -[testenv:pylint] -deps = pylint -commands = pylint --rcfile tox.ini {posargs:update} - -[flake8] -exclude = .cache,.git,.tox -max-line-length = 85 - -[pylint] -reports = no diff --git a/update.py b/update.py deleted file mode 100755 index 9f44e4e..0000000 --- a/update.py +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env python3 -""" -Creates and updates version-based Dockerfile folders. -""" -from os import makedirs, path - -VERSIONS = [ - '0.9.0', - '0.10.0', - '1.0.0', - '1.1.0', - '1.2.0', - '1.3.0', - '2.0.0', - # add new versions here -] -DOCKER_IMAGE = 'vshn/modulesync' -DOCKERHUB_USER = 'vshn' -GIT_REPO = 'vshn/docker-modulesync' - -EMPTY_LINE = '\n\n' - -README_TAG_ANCHOR = ' https://github.com/voxpupuli/modulesync)' - -TESTS_CONTEXT_NEEDLE = ' - CONTEXT=' -TESTS_CONTEXT_ANCHOR = ' - CONTEXT=.' - - -def create_dockerfile(ver): - """ - Create a Dockerfile in a version subdirectory, taking the main, - off-repository install based, Dockerfile as a template. - """ - print(f"Updating Dockerfile: version {ver} ...") - - build_commands_needle = ' && apt-get update ' - install_commands = [ - " && apt-get update \\", - " && apt-get install -y --no-install-recommends \\", - " build-essential \\", - " git \\", - f" && gem install modulesync --version {ver} \\", - " && apt-get purge -y build-essential \\", - " && apt-get autoremove --purge -y \\", - " && apt-get clean \\", - " && rm -rf /var/lib/apt/lists/*", - ] - - makedirs(ver, exist_ok=True) - target_filename = path.join(ver, 'Dockerfile') - - # replace gem build command sequence by gem install command - with open('Dockerfile', 'r') as dockerfile, \ - open(target_filename, 'w') as target_file: - original = dockerfile.read() - start = original.index(build_commands_needle) - stop = original.index(EMPTY_LINE, start) - target_conf = ( - original[:start] + - '\n'.join(install_commands) + - original[stop:] - ) - target_file.write(target_conf) - - -def remove_old_badges_from_readme(): - """ - Remove all version tag badges from the README. - """ - print('Clearing old tags from README ...') - - with open('README.md', 'r+') as readme: - lines = readme.read().splitlines() - - anchor = lines.index(README_TAG_ANCHOR) + 1 - next_blank_line = lines.index('', anchor) - lines = lines[:anchor] + lines[next_blank_line:] - - readme.seek(0) - readme.truncate() - readme.write('\n'.join(lines) + '\n') - - -def remove_old_versions_from_tests(): - """ - Remove all version ENV values from the test setup. - """ - print('Clearing old test setup from CI config ...') - - with open('.travis.yml', 'r+') as file: - lines = file.read().splitlines() - - anchor = lines.index(TESTS_CONTEXT_ANCHOR) + 1 - next_blank_line = lines.index('', anchor) - lines = lines[:anchor] + lines[next_blank_line:] - - file.seek(0) - file.truncate() - file.write('\n'.join(lines) + '\n') - - -def add_tag_badge_to_readme(ver): - """ - Add links of supported tags to the README. - """ - print(f"Updating README: tag {ver} ...") - - dockerfile_badge = f"https://img.shields.io/badge/{ver}-blue.svg" \ - "?colorA=22313f&colorB=4a637b&logo=docker" - dockerfile_url = f"https://github.com/{GIT_REPO}/blob/master/{ver}/Dockerfile" - sizelayers_badge = "https://images.microbadger.com/badges/image/" \ - f"{DOCKER_IMAGE}:{ver}.svg" - sizelayers_url = f"https://microbadger.com/images/{DOCKER_IMAGE}:{ver}" - rubygem_badge = f"https://img.shields.io/badge/Gem-{ver}-red.svg" \ - "?colorA=ff919f&colorB=9a9b9c&logo=ruby" - rubygem_url = f"https://rubygems.org/gems/modulesync/versions/{ver}" - tag_lines = [ - f"- [![{ver}](", - f" {dockerfile_badge})](", - f" {dockerfile_url}) [![size/layers](", - f" {sizelayers_badge})](", - f" {sizelayers_url}) [![based on](", - f" {rubygem_badge})](", - f" {rubygem_url})", - ] - - with open('README.md', 'r+') as file: - lines = file.read().splitlines() - - anchor = lines.index(README_TAG_ANCHOR) + 1 - lines = lines[:anchor] + tag_lines + lines[anchor:] - - file.seek(0) - file.truncate() - file.write('\n'.join(lines) + '\n') - - -def add_version_to_tests(ver): - """ - Ensure all versions of the image are built on Travis CI. - """ - print(f"Updating CI config: test build for {ver} ...") - - context_line = f"{TESTS_CONTEXT_NEEDLE}{ver}" - - with open('.travis.yml', 'r+') as file: - lines = file.read().splitlines() - - anchor = lines.index(TESTS_CONTEXT_ANCHOR) + 1 - lines = lines[:anchor] + [context_line] + lines[anchor:] - - file.seek(0) - file.truncate() - file.write('\n'.join(lines) + '\n') - - -def main(): - """ - Take the main Dockerfile as a template and create Dockerfiles in - subdirectories (with ModuleSync version numbers), replacing the 'bundle - install' by Ruby Gem installs. Also update the README file. - """ - remove_old_badges_from_readme() - remove_old_versions_from_tests() - - for version in VERSIONS: - create_dockerfile(version) - add_tag_badge_to_readme(version) - add_version_to_tests(version) - - print("Done. Put the changes under version control now, " - "and update your Docker image configuration at " - f"https://cloud.docker.com/u/{DOCKERHUB_USER}/repository/docker/" - f"{DOCKER_IMAGE}/hubbuilds. Thank you!") - - -if __name__ == '__main__': - main()