Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 47 additions & 11 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,93 @@ concurrency:
cancel-in-progress: true

jobs:
build:
builder:
strategy:
max-parallel: 2
fail-fast: true
matrix:
arch: [x86_64, aarch64]
runtime: [none, docker, containerd, incus]
include:
- arch: x86_64
os: ubuntu-latest
- arch: aarch64
os: ubuntu-24.04-arm
runs-on: ${{ matrix.os }}
name: build-${{ matrix.arch }}-${{ matrix.runtime }}
name: builder-${{ matrix.arch }}
timeout-minutes: 180
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false

- name: Build
run: make save-builder

- name: Upload artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: builder-${{ matrix.arch }}
path: builder-${{ matrix.arch }}.tar
overwrite: true

image:
strategy:
max-parallel: 4
fail-fast: true
matrix:
arch: [x86_64, aarch64]
dist: [ubuntu, debian]
include:
- arch: x86_64
os: ubuntu-latest
- arch: aarch64
os: ubuntu-24.04-arm
runs-on: ${{ matrix.os }}
needs: [builder]
name: images-${{ matrix.arch }}-${{ matrix.dist }}
timeout-minutes: 180
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false

- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: builder-${{ matrix.arch }}

- name: Build
run: |
make image OS_ARCH=${{ matrix.arch }} RUNTIME=${{ matrix.runtime }}
docker load -i builder-${{ matrix.arch }}.tar
make DIST=${{ matrix.dist }} none docker containerd incus
ls -lah dist/img

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: img-${{ matrix.arch }}-${{ matrix.runtime }}
path: dist/img/*-${{ matrix.runtime }}.*
name: img-${{ matrix.arch }}-${{ matrix.dist}}
path: dist/img/${{ matrix.dist}}-*-*.raw.*
overwrite: true
retention-days: 1
compression-level: 0

release:
runs-on: ubuntu-latest
needs: [build]
needs: [image]
if: github.event_name != 'pull_request'
permissions:
contents: write
actions: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
fetch-depth: 1
persist-credentials: false

- uses: actions/download-artifact@v4
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
path: dist/img

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist/
scripts/.build-image-stamp*
192 changes: 181 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
# image and tool versions
include dependencies.env

UNAME_S := $(shell uname -s)

to_upper = $(shell echo '$1' | tr '[:lower:]' '[:upper:]')

ifeq ($(MAKE_TERMOUT),)
# Make < 4 doesn't set MAKE_TERMOUT
INTERACTIVE ?= $(shell [ -t 0 ] && echo 1)
else
INTERACTIVE ?= 1
endif

ifeq ($(INTERACTIVE),1)
DOCKER_RUN_ARGS := -i --tty
endif

ifeq ($(UNAME_S),Darwin)
# macOS uses BSD stat
PRINT_STATS_CMD = stat -f "%N%n |- %z bytes%n '- %Sm"
else
# Linux (and most others) use GNU stat
PRINT_STATS_CMD = stat -c "%N\n |- %s bytes\n '- %y"
endif

# quiet target commands by default
ifeq ($(filter $(DEBUG),1 true),)
MAKEFLAGS += -s
else
TARV = v
endif

# which dist image to build (debian or ubuntu)
DIST ?= ubuntu

# runtime
RUNTIMES = docker containerd incus none
RUNTIME ?= docker

# architecture defaults to the current system's.
Expand All @@ -14,32 +48,168 @@ endif
# is required for Docker and asset downloads.
ARCH_x86_64 = amd64
ARCH_aarch64 = arm64
ARCH = $(shell echo "$(ARCH_$(OS_ARCH))")
ARCH = $(ARCH_$(OS_ARCH))

# binfmt needs the opposite of OS_ARCH
BINFMT_ARCH = aarch64
ifeq ($(strip $(OS_ARCH)),aarch64)
BINFMT_ARCH = x86_64
endif

export ARCH
export BINFMT_ARCH

# containerd
CONTAINERD_ARCHIVE ?= dist/containerd/containerd-utils-$(ARCH).tar.gz
NERDCTL_FILE ?= dist/containerd/nerdctl-full-$(NERDCTL_VERSION)-linux-$(ARCH).tar.gz
NERDCTL_URL ?= https://github.com/containerd/nerdctl/releases/download/v$(NERDCTL_VERSION)/$(notdir $(NERDCTL_FILE))
FLANNEL_FILE ?= dist/containerd/cni-plugin-flannel-linux-$(ARCH)-v$(FLANNEL_MINI_VERSION).tgz
FLANNEL_URL ?= https://github.com/flannel-io/cni-plugin/releases/download/v$(FLANNEL_VERSION)/$(notdir $(FLANNEL_FILE))

# binfmt
BINFMT_ARCHIVE = dist/binfmt/binfmt-$(ARCH).tar.gz
BINFMT_DOWNLOAD_URL ?= https://github.com/tonistiigi/binfmt/releases/download/$(BINFMT_VERSION)
BINFMT_FILE ?= dist/binfmt/$(BINFMT_VERSION)/binfmt_linux-$(ARCH).tar.gz
BINFMT_URL ?= $(BINFMT_DOWNLOAD_URL)/$(notdir $(BINFMT_FILE))
BINFMT_QEMU_FILE ?= dist/binfmt/$(BINFMT_QEMU_VERSION)/qemu_v$(BINFMT_QEMU_VERSION)_linux-$(ARCH).tar.gz
BINFMT_QEMU_URL ?= $(BINFMT_DOWNLOAD_URL)/$(notdir $(BINFMT_QEMU_FILE))

# ubuntu
UBUNTU_IMAGE_BASE_URL ?= https://cloud-images.ubuntu.com/minimal/releases/$(UBUNTU_CODENAME)/release-$(UBUNTU_BUILD)
UBUNTU_IMAGE_FILE ?= dist/img/ubuntu-$(UBUNTU_VERSION)-minimal-cloudimg-$(ARCH).img
UBUNTU_IMAGE_SHA_FILE ?= $(UBUNTU_IMAGE_FILE).sha256sum

# debian
DEBIAN_IMAGE_BASE_URL ?= https://cloud.debian.org/images/cloud/$(DEBIAN_CODENAME)/$(DEBIAN_BUILD)
DEBIAN_IMAGE_FILE ?= dist/img/debian-$(DEBIAN_VERSION)-genericcloud-$(ARCH)-$(DEBIAN_BUILD).qcow2
DEBIAN_IMAGE_SHA_FILE ?= $(DEBIAN_IMAGE_FILE).sha512sum

# DIST resolved variables
IMAGE_BASE_URL ?= $($(call to_upper,$(DIST))_IMAGE_BASE_URL)
IMAGE_FILE ?= $($(call to_upper,$(DIST))_IMAGE_FILE)
IMAGE_SHA_FILE ?= $($(call to_upper,$(DIST))_IMAGE_SHA_FILE)
IMAGE_SHA_SIZE ?= $(patsubst .sha%sum,%,$(suffix $(IMAGE_SHA_FILE)))

#
# defines
#

define download_and_verify
$(1):
@echo "downloading $(2)"
mkdir -p $$(@D) && \
curl --retry 3 --connect-timeout 10 -o$$@.download -L $(2) && \
$$(PRINT_STATS_CMD) $$@.download && \
tar -xzOf $$@.download >/dev/null || { \
echo >&2 "error downloading"; \
exit 1; \
}
mv -f $$@.download $$@
endef

# image builder container image
DOCKER_BUILD_IMAGE = scripts/.build-image-stamp-$(ARCH)
DOCKER_BUILD_IMAGE_SOURCES = scripts/Dockerfile scripts/image.sh
DOCKER_BUILD_IMAGE_TAG = colima-core-builder:$(ARCH)

IMAGE_DEPENDENCIES = $(DOCKER_BUILD_IMAGE) $(CONTAINERD_ARCHIVE).sha512sum $(BINFMT_ARCHIVE).sha512sum
#
# targets
#

all: image
.PHONY: clean distclean save-builder image $(RUNTIMES)

# deprecated (default) target
image: $(RUNTIME)

all: $(RUNTIMES)

.PHONY: clean
# rm build targets
clean:
rm -rf $(IMAGE_DEPENDENCIES) dist/img/*.raw.gz*

# rm + cache
distclean: clean
rm -rf dist

cloud-image:
ARCH=$(ARCH) UBUNTU_VERSION=$(UBUNTU_VERSION) UBUNTU_CODENAME=$(UBUNTU_CODENAME) scripts/cloud-image.sh
# base image
$(IMAGE_FILE):
@echo "target: $@"
mkdir -p $(@D) && curl --retry 5 --connect-timeout 10 -o"$@" -L $(IMAGE_BASE_URL)/$(notdir $@)

$(IMAGE_SHA_FILE): $(IMAGE_FILE)
@echo "target: $@"
shasum -a $(IMAGE_SHA_SIZE) $< > $@.tmp
cd dist/img && ( \
curl --retry 5 --connect-timeout 10 -L $(IMAGE_BASE_URL)/SHA$(IMAGE_SHA_SIZE)SUMS | \
grep $(notdir $<) | \
shasum -a $(IMAGE_SHA_SIZE) --check --status \
) || { \
echo >&2 "checksum did not match!"; \
rm -f $@.tmp; \
mv -f $< $<.invalid; \
exit 1; \
}
mv $@.tmp $@

# checksum
%.sha512sum: %
@echo "target: $@"
shasum -a 512 $< > $@

# binfmt
$(BINFMT_ARCHIVE): $(BINFMT_FILE) $(BINFMT_QEMU_FILE)
@echo "target: $@"
rm -f '$@'
TMP_DIR=$$(mktemp -d); \
trap 'rm -rf "$$TMP_DIR"' EXIT; \
for f in $^; do tar $(TARV)zxf "$$f" -C "$$TMP_DIR"; done; \
cd "$$TMP_DIR" && tar $(TARV)czf '$(CURDIR)/$@' binfmt qemu-i386 qemu-$(BINFMT_ARCH) || { \
echo >&2 "failed to create $@" ; \
rm -f '$(CURDIR)/$@'; exit 1; \
}

$(eval $(call download_and_verify,$(BINFMT_FILE),$(BINFMT_URL)))
$(eval $(call download_and_verify,$(BINFMT_QEMU_FILE),$(BINFMT_QEMU_URL)))

# containerd
$(CONTAINERD_ARCHIVE): $(NERDCTL_FILE) $(FLANNEL_FILE)
@echo "target: $@"
rm -f '$@'
TMP_DIR=$$(mktemp -d); \
trap 'rm -rf "$$TMP_DIR"' EXIT; \
for f in $^; do tar $(TARV)xzf "$$f" -C "$$TMP_DIR"; done; \
cd "$$TMP_DIR" && tar $(TARV)czf '$(CURDIR)/$@' bin lib libexec share || { \
echo >&2 "failed to create $@" ; \
rm -f '$(CURDIR)/$@'; exit 1; \
}

$(eval $(call download_and_verify,$(NERDCTL_FILE),$(NERDCTL_URL)))
$(eval $(call download_and_verify,$(FLANNEL_FILE),$(FLANNEL_URL)))

# builder
save-builder: $(DOCKER_BUILD_IMAGE)
docker save $(DOCKER_BUILD_IMAGE_TAG) -o builder-$(OS_ARCH).tar

binfmt:
ARCH=$(ARCH) BINFMT_ARCH=$(BINFMT_ARCH) BINFMT_VERSION=$(BINFMT_VERSION) BINFMT_QEMU_VERSION=$(BINFMT_QEMU_VERSION) scripts/binfmt.sh
$(DOCKER_BUILD_IMAGE): $(DOCKER_BUILD_IMAGE_SOURCES) Makefile
docker build --platform linux/$(ARCH) --build-arg UBUNTU_VERSION=$(UBUNTU_VERSION) -t $(DOCKER_BUILD_IMAGE_TAG) --iidfile $@ $(dir $@)

containerd:
ARCH=$(ARCH) NERDCTL_VERSION=$(NERDCTL_VERSION) FLANNEL_VERSION=$(FLANNEL_VERSION) FLANNEL_MINI_VERSION=$(FLANNEL_MINI_VERSION) RUNTIME=$(RUNTIME) scripts/containerd.sh
# images
$(basename $(IMAGE_FILE))-%.raw.gz: $(IMAGE_SHA_FILE) $(IMAGE_DEPENDENCIES) $(DOCKER_BUILD_IMAGE) Makefile
if [ $(OS_ARCH) != $(ARCH) ] ; then docker run $(DOCKER_RUN_ARGS) --privileged --rm tonistiigi/binfmt --install $(BINFMT_ARCH); fi
docker run $(DOCKER_RUN_ARGS) --rm --privileged \
--platform linux/$(ARCH) \
--volume $(CURDIR):/build \
--env DIST=$(DIST) \
--env BINFMT_ARCHIVE=$(BINFMT_ARCHIVE) \
--env CONTAINERD_ARCHIVE=$(CONTAINERD_ARCHIVE) \
--env IMAGE_FILE=$(IMAGE_FILE) \
--env DOCKER_VERSION=$(DOCKER_VERSION) \
--env RUNTIME=$* \
$(DOCKER_BUILD_IMAGE_TAG) || { \
echo >&2 "failed to create $@"; \
rm -f '$@'* ; exit 1; \
}

image: cloud-image binfmt containerd
ARCH=$(ARCH) BINFMT_ARCH=$(BINFMT_ARCH) UBUNTU_VERSION=$(UBUNTU_VERSION) DOCKER_VERSION=$(DOCKER_VERSION) RUNTIME=$(RUNTIME) scripts/image.docker.sh
$(RUNTIMES): %: $(basename $(IMAGE_FILE))-%.raw.gz
$(PRINT_STATS_CMD) $<
25 changes: 20 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,35 @@ Dependencies for Colima

## Generating image

Generate a raw disk image compressed with gzip (`.raw.gz`) for the OS architecture and default runtime (docker).
Generate a raw disk image compressed with gzip (`.raw.gz`) for the OS architecture, default runtime (docker), and default OS (Ubuntu).

```sh
make image
make
```

Generate a `.raw.gz` image for another architecture. `OS_ARCH` must be one of `aarch64`, `x86_64`

```sh
OS_ARCH=x86_64 make image
OS_ARCH=x86_64 make
```

Generate a `.raw.gz` image for another runtime. `RUNTIME` must be one of `docker`, `containerd`, `incus`, `none`
Generate a `.raw.gz` image for another runtime.

```sh
RUNTIME=containerd make image
make docker # default make target
make containerd
make incus
make none
```

Generate `.raw.gz` images for all runtimes.

```sh
make all
```

Generate images based on Debian.

```sh
DIST=debian make
```
20 changes: 12 additions & 8 deletions dependencies.env
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
UBUNTU_VERSION="24.04"
UBUNTU_CODENAME="noble"
BINFMT_VERSION="deploy/v7.0.0-28"
BINFMT_QEMU_VERSION="7.0.0"
DOCKER_VERSION="29.5.2"
NERDCTL_VERSION="2.3.1"
FLANNEL_VERSION="1.9.1-flannel1"
FLANNEL_MINI_VERSION="1.9.1"
UBUNTU_VERSION=24.04
UBUNTU_CODENAME=noble
UBUNTU_BUILD=20260617
DEBIAN_VERSION=13
DEBIAN_CODENAME=trixie
DEBIAN_BUILD=20260525-2489
BINFMT_VERSION=deploy/v7.0.0-28
BINFMT_QEMU_VERSION=7.0.0
DOCKER_VERSION=29.5.2
NERDCTL_VERSION=2.3.1
FLANNEL_VERSION=1.9.1-flannel1
FLANNEL_MINI_VERSION=1.9.1
Loading