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.3.1.tar.gz (124.3 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.3.1-py3-none-any.whl (46.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: karsk-0.3.1.tar.gz
  • Upload date:
  • Size: 124.3 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.3.1.tar.gz
Algorithm Hash digest
SHA256 e882b7f841a72834d0ab87a05ab999f116b39c64e5759bb06bf37021c4ce5fd3
MD5 5396b46c93d33edfff34ff1f580e76fe
BLAKE2b-256 8fefd8a1d7702ca70d42f2e75af0ee295285c6c0c9a02d868dffb7b330ddafd3

See more details on using hashes here.

File details

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

File metadata

  • Download URL: karsk-0.3.1-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.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f949bb9e4874a7e77adb9b904dd08ec0ea4562fde252f2f423361bf87166b474
MD5 c0a70696ed24c9df0da88feedecc753b
BLAKE2b-256 4eb8e3df9327628086ab1e833d24db18ec903bac4a6e86cfd74fa94a08d2959d

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