Skip to main content

Tool for building and deploying software on HPC clusters

Project description

Karsk - Keeping Auditable Release Selection Known

Karsk (pronounced kashk) is a Norwegian cocktail from Trøndelag county mixing coffee with moonshine. It is also a tool for deploying software on our NFS-backed Linux cluster.

Karsk solves the following problems for us:

  1. Continuous upgrades: Users reliably access the latest versions of software without needing to update anything themselves.

  2. User-controlled versioning: Each deploy persists on disk. Users can select any existing version anytime.

  3. Simple rollbacks: Because releases are symbolic links, rollbacks are quick and painless.

How it works

Karsk has three stages: build, install, and sync. Each stage writes to a different location, and the destination is strictly append-only — nothing is ever overwritten.

┌─────────────────────────────────────────────────────────────────────────┐
│                          karsk build                                    │
│                                                                         │
│  Builds packages in containers, then assembles an environment           │
│  (symlink tree + manifest) in the staging directory.                    │
│                                                                         │
│  staging/                                                               │
│  ├── store/                                                             │
│  │   └── a1b2c3-myapp-1.0.0/       ← built package artifacts            │
│  ├── versions/                                                          │
│  │   ├── 1.0.0+1/                   ← environment (symlinks into store) │
│  │   │   ├── bin/myapp -> ../../store/a1b2c3-myapp-1.0.0/bin/myapp      │
│  │   │   └── manifest                                                   │
│  │   ├── latest -> 1.0.0+1                                              │
│  │   └── stable -> latest                                               │
│  └── bin/run                        ← wrapper script                    │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                          karsk install                                  │
│                                                                         │
│  Copies store packages from staging to destination and builds the       │
│  environment there. Destination is append-only: the build ID is         │
│  allocated against what already exists in destination.                  │
│                                                                         │
│  destination/  (/opt/karsk/myapp)                                       │
│  ├── store/                                                             │
│  │   ├── a1b2c3-myapp-1.0.0/       ← first build                        │
│  │   └── d4e5f6-myapp-1.0.0/       ← second build (new hash)            │
│  ├── versions/                                                          │
│  │   ├── 1.0.0+1/                   ← first build env                   │
│  │   ├── 1.0.0+2/                   ← second build env                  │
│  │   ├── latest -> 1.0.0+2                                              │
│  │   └── stable -> latest                                               │
│  └── bin/run                                                            │
└─────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                          karsk sync                                     │
│                                                                         │
│  Replicates the destination to remote hosts via rsync + SSH.            │
│  Build IDs are identical across all sync locations.                     │
└─────────────────────────────────────────────────────────────────────────┘

Build IDs

Each environment directory is named <version>+<build_id>, e.g. 1.0.0+1. The + prefix follows semver build metadata conventions. The build ID is a monotonically increasing counter scoped to its target directory. Because staging is typically cleared between builds while destination is not, the same build may get different IDs in staging vs destination:

staging:      1.0.0+1  (staging was cleared, starts from 1)
destination:  1.0.0+3  (two previous builds already exist)

This is by design. The key invariant is:

  • Destination is append-only — existing builds are never overwritten or removed.
  • Sync locations are identicalkarsk sync replicates the destination layout exactly, so build IDs match across all remote hosts.
  • Same manifest = same build — if a build with an identical manifest already exists at the target, it is skipped.

Installing

Karsk is written in Python and requires uv and some container engine. Currently, only Podman is supported, but Docker may work as well.

To get started, clone this repository and run uv sync to get the karsk executable.

Using

See examples directory for examples. Use karsk --help to view documentation.

Developing

Karsk entrypoint

Karsk entrypoint is a Rust application that is deployed and serves as the user-facing entrypoint.

Testing

This project uses pytest for tests, mypy for type-checking and ruff for linting and formatting.

# Run tests
uv run pytest tests

# Typecheck (note: we don't typecheck test code)
uv run mypy --strict src

# Lint and format
uv run ruff format
uv run ruff check --fix

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

karsk-0.4.2.tar.gz (124.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

karsk-0.4.2-py3-none-any.whl (46.9 kB view details)

Uploaded Python 3

File details

Details for the file karsk-0.4.2.tar.gz.

File metadata

  • Download URL: karsk-0.4.2.tar.gz
  • Upload date:
  • Size: 124.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for karsk-0.4.2.tar.gz
Algorithm Hash digest
SHA256 99f2374ad8d0c7fde5e5d91df91bb4bb0e9d4ab62eb674fe43d185b94022a6aa
MD5 72df3e898d8628d4d38342183401fe74
BLAKE2b-256 7cf3fb61942f204044666a449a80e7c8144d611964e1d04d38e47610bd959832

See more details on using hashes here.

File details

Details for the file karsk-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: karsk-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 46.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.13 {"installer":{"name":"uv","version":"0.11.13","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for karsk-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 941e3d4e1c106a5b06ffe04d93590495515bd4eb4c47e32b3ca68272d80317a9
MD5 6df838813f38ff604907b961c996ba48
BLAKE2b-256 4145ebfad5e9ad17d2bbe901ff2290f1e837855094d05a6b79147414490559ad

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page