Skip to content

GitHub mirror of Software Heritage virtual environment packaging manifests

License

Notifications You must be signed in to change notification settings

SoftwareHeritage/swh-apps

Repository files navigation

Software Heritage virtual environment packaging manifests

This repository contains the manifests and scripts to automate the packaging of SWH applications into (fairly) reproducible Python virtual environments, and then onto container images.

Problem statement

To move away from our legacy Debian-based packaging and deployment workflow, we are using Python virtual environments to generate (fairly) reproducible deployment environments, that would be consistent between:

  • docker-based local environments
  • "bare VM/Metal" deployments (on Debian systems still managed by puppet)
  • elastic deployments based on k8s
  • CI environments used for testing packages

We want the input for generating these environments to be declarative (for instance, "I want an environment with swh.provenance"), and the resulting environments to be:

  • frozen (using a consistent, known set of package versions)
  • kept up to date automatically (for our swh packages, as well as the external dependencies)
  • tested before publication (at least to a minimal extent, e.g. ensuring that the tests of the declared input modules are successful before tagging an application as ready to deploy)

Packaging Workflow

Each standalone application is generated from an input requirements.txt file. Out of this, a virtualenv is generated and frozen into a requirements-frozen.txt file, which is then used to build container images (when associated with a Dockerfile and an entry point script).

The frozen requirements file can also be used to deploy virtual environments directly, e.g. on an existing VM or bare metal server.

Local development

App-manager

It's the cli tools which allows to execute various actions: - list dependency between swh modules - manipulate the generation of frozen requirements for our python applications - helm chart dependency version update - etc...

# Build the app-manager image
docker build -t app-manager scripts

List dependent applications

This is the listing command to list whatever other applications is depending on a specification application version.

docker run --rm -v $workspace/swh-apps:/src \
  app-manager list-dependent-apps \
    --application swh.graph --version v6.3.0

Example:

docker run --rm -v $workspace/swh-apps:/src \
  app-manager list-dependent-apps \
    --application swh.graph --version v6.3.0
swh-alter
swh-graph
swh-provenance
swh-vault-cookers
swh-web

Freeze application dependencies

This is in charge of using the existing requirements.txt declared besides the application's Dockerfile and generate an updated frozen-requirements.txt. This file is then used within the docker image to build an identical python environments within the image.

Note that it does update any dependencies within the environments so any new upstream libraries will get updated if new releases happened.

docker run --rm -v $workspace/swh-apps:/src \
  app-manager generate-frozen-requirements swh-provenance
$ docker run --rm -v $workspace/swh-apps:/src \
    app-manager generate-frozen-requirements swh-provenance
Collecting uv
  Downloading uv-0.5.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (16.2 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 16.2/16.2 MB 36.4 MB/s eta 0:00:00
Installing collected packages: uv
Successfully installed uv-0.5.26

[notice] A new release of pip is available: 23.0.1 -> 25.0
[notice] To update, run: python3 -m pip install --upgrade pip
Using Python 3.10.15 environment at: /tmp/swh-provenancep16_3kh7
Resolved 3 packages in 46ms
Prepared 3 packages in 86ms
Uninstalled 2 packages in 51ms
Installed 3 packages in 32ms
 - pip==23.0.1
 + pip==25.0
 - setuptools==65.5.0
 + setuptools==75.8.0
 + wheel==0.45.1
# This file was autogenerated by uv via the following command:
#    uv pip compile /src/apps/swh-provenance/requirements.txt -o /src/apps/swh-provenance/tmpk6i4m4rz
Resolved 76 packages in 850ms
aiohappyeyeballs==2.4.4
    # via aiohttp
    # via -r /src/apps/swh-provenance/requirements.txt
python-magic==0.4.27
    # via swh-core
python-mimeparse==2.0.0
    # via aiohttp-utils
pyyaml==6.0.2
    # via swh-core
redis==5.2.1
    # via
    # via -r /src/apps/swh-provenance/requirements.txt
...
swh-storage==2.9.0
    # via
    #   swh-dataset
    #   swh-provenance
tenacity==9.0.0
    # via
    #   swh-core
    #   swh-journal
    #   swh-storage
tqdm==4.67.1
    # via swh-dataset
types-protobuf==5.29.1.20241207
    # via mypy-protobuf
types-requests==2.32.0.20241016
    # via swh-dataset
typing-extensions==4.12.2
    # via
    #   multidict
    #   swh-core
    #   swh-model
    #   swh-objstorage
    #   swh-storage
urllib3==2.3.0
    # via
    #   botocore
    #   requests
    #   sentry-sdk
    #   types-requests
werkzeug==3.1.3
    # via flask
wrapt==1.17.2
    # via deprecated
yarl==1.18.3
    # via aiohttp

Update swh-charts' version

Providing access to both the swh-apps and the swh-charts repositories, this allows to update the values of values-swh-application-versions.yaml with the most recent docker image versions. This also bumps the Charts.yaml's version incrementally.

docker run --rm \
  --volume $workspace/swh-apps:/src \
  --volume $workspace/swh-charts:/tmp/swh-charts \
  app-manager update-versions \
    --applications-filepath /tmp/s-charts/values-swh-application-versions.yaml \
    --chart-filepath /tmp/swh-charts/swh/Chart.yaml

Build application image

Each application is stored in swh-apps:/apps/$application_dir/ folder. It usually holds the same set of files: - Dockerfile: The set of instructions to build the application's docker image - entrypoint.sh: The last Dockerfile instruction refers to this executable to run in the

image.
  • requirements.txt: The set of python dependencies the application requires to run.
  • requirements-frozen.txt: The derivative frozen set of dependencies to reproduce the
    environment in the docker image. It's built by the app-manager out of the requirements.txt file.

Cli call to build the application locally:

$ DOCKER_BUILDKIT=1 docker build -t swh-toolbox:latest apps/swh-toolbox \
  --build-arg REGISTRY=

Note: The REGISTRY is empty so we only rely to local docker image. You can avoid changing it, in which case, it will use the swh's gitlab registry.

Cli call to run the application and be dropped in a shell:

$ docker run -it swh-toolbox:latest shell

Note: This is specific command depending on the entrypoint.sh. In that case, the entrypoint.sh allows a shell option to be dropped in an interactive bash session.