Skip to content

Instantly share code, notes, and snippets.

@vbatts
Last active June 3, 2022 16:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vbatts/0de8674ccbc6974b7f1829a5407eed0c to your computer and use it in GitHub Desktop.
Save vbatts/0de8674ccbc6974b7f1829a5407eed0c to your computer and use it in GitHub Desktop.
Makefile for running flatcar qemu images locally

Quickly run Flatcar in QEMU

Pull this gist down. Edit the cloud-config if desired. In one terminal:

make run

And then in another terminal:

make ssh

make help

See make help for more info:

$ make help
run		start the flatcar qemu instance (downloading if needed)
dev		start the flatcar developer container instance (downloading if needed)
		Default variables and values:
			- SSH_KEY=/home/vbatts/.ssh/authorized_keys
			- HOST_NAME=flatcar-local.test.lan
			- MEMORY=4096
			- PORT=2223
			- CHANNEL=stable
			- BOARD=amd64-usr
			- VERSION=current
			- UEFI=false (either: true | false)
ssh		ssh into the running instance
ctr		build a docker image from the flatcar container (~ 900mb)
dev-ctr		build a docker image from the flatcar developer container (~ 2.5gb)
clean		basic cleanup of files
dist-clean	deletes all the image files (they'll have to download and extract again)

Examples

variables you can pass to override

make run CHANNEL=alpha BOARD=arm64-usr

Development container

make dev CHANNEL=beta
#cloud-config
coreos:
units:
- name: docker.service
command: start
drop-ins:
- name: 50-crun-runtime.conf
content: |
[Service]
Environment=DOCKER_OPTS='--add-runtime crun=/opt/bin/crun --default-runtime=crun'
- name: crun-amd64-fetch.service
command: start
content: |
[Unit]
Description=fetch crun amd64 binary
Before=docker.service
ConditionArchitecture=x86-64
[Service]
Type=oneshot
ExecStart=/usr/bin/mkdir -p /opt/bin
ExecStart=/usr/bin/curl -sSL -o /opt/bin/crun https://github.com/containers/crun/releases/download/0.18/crun-0.18-linux-amd64
ExecStart=/usr/bin/chmod +x /opt/bin/crun
- name: crun-arm64-fetch.service
command: start
content: |
[Unit]
Description=fetch crun arm64 binary
Before=docker.service
ConditionArchitecture=arm64
[Service]
Type=oneshot
ExecStart=/usr/bin/mkdir -p /opt/bin
ExecStart=/usr/bin/curl -sSL -o /opt/bin/crun https://github.com/containers/crun/releases/download/0.18/crun-0.18-linux-arm64
ExecStart=/usr/bin/chmod +x /opt/bin/crun
write_files:
ssh_authorized_keys:
- <SSH_KEY>
hostname: <HOSTNAME>
# Vincent Batts <vbatts@kinvolk.io> 2020-09
CWD := $(shell pwd)
SSH_KEY ?= $(shell realpath $$HOME/.ssh/authorized_keys)
HOST_NAME ?= flatcar-local.test.lan
ISO_FILE = $(CWD)/$(HOST_NAME).iso
MEMORY ?= 4096
PORT ?= 2223
CHANNEL ?= stable
BOARD ?= amd64-usr
VERSION ?= current
UEFI ?= false
IGNITION ?= false
IGNITION_FILE = $(CWD)/ignition.json
FLATCAR_SIGNING_KEY ?= 782B3BC9F10CF638A5DCF5105B2910CBFCBEAB91
CREDS =
QEMU_ARGS ?=
ifeq ($(CHANNEL),lts)
CREDS := --user "$(shell cat htpasswd)"
endif
ifeq ($(BOARD),arm64-usr)
UEFI := true
endif
ifeq ($(UEFI),true)
U := _uefi
endif
CLEAN_FILES := *~
DISTCLEAN_FILES := *~
BASE := $(CHANNEL)/$(BOARD)/$(VERSION)
FLATCAR_FILES := \
$(BASE)/version.txt \
$(BASE)/flatcar_production_qemu$(U).sh \
$(BASE)/flatcar_production_qemu$(U).README \
$(BASE)/flatcar_production_qemu$(U)_image.img.bz2 \
$(BASE)/flatcar_production_qemu$(U)_image.img.bz2.DIGESTS \
$(BASE)/flatcar_production_qemu$(U)_image.img.bz2.DIGESTS.asc
ifeq ($(UEFI),true)
FLATCAR_FILES += \
$(BASE)/flatcar_production_qemu$(U)_efi_vars.fd \
$(BASE)/flatcar_production_qemu$(U)_efi_code.fd
endif
default: help
.PHONY: help
help:
@echo -n "run\t\tstart the flatcar qemu instance (downloading if needed)\n"
@echo -n "dev\t\tstart the flatcar developer container instance (downloading if needed)\n"
@echo -n "\t\tDefault variables and values:\n"
@echo -n "\t\t\t- SSH_KEY=$(SSH_KEY)\n"
@echo -n "\t\t\t- HOST_NAME=$(HOST_NAME)\n"
@echo -n "\t\t\t- MEMORY=$(MEMORY)\n"
@echo -n "\t\t\t- PORT=$(PORT)\n"
@echo -n "\t\t\t- CHANNEL=$(CHANNEL)\n"
@echo -n "\t\t\t- BOARD=$(BOARD)\n"
@echo -n "\t\t\t- VERSION=$(VERSION)\n"
@echo -n "\t\t\t- UEFI=$(UEFI) (either: true | false)\n"
@echo -n "ssh\t\tssh into the running instance\n"
@echo -n "ctr\t\tbuild a docker image from the flatcar container (~ 900mb)\n"
@echo -n "dev-ctr\t\tbuild a docker image from the flatcar developer container (~ 2.5gb)\n"
@echo -n "clean\t\tbasic cleanup of files\n"
@echo -n "dist-clean\tdeletes all the image files (they'll have to download and extract again)\n"
DISTCLEAN_FILES += $(BASE)/flatcar_production_qemu$(U)_image.img
run: $(BASE)/.check .run
ifeq ($(IGNITION),true)
.run: $(IGNITION_FILE) $(BASE)/flatcar_production_qemu$(U)_image.img
@sh $(BASE)/flatcar_production_qemu$(U).sh -i $(IGNITION_FILE) -p $(PORT) -- -nographic -m $(MEMORY) -s $(QEMU_ARGS)
else
.run: $(ISO_FILE) $(BASE)/flatcar_production_qemu$(U)_image.img
@sh $(BASE)/flatcar_production_qemu$(U).sh -c $(ISO_FILE) -p $(PORT) -- -nographic -m $(MEMORY) -s $(QEMU_ARGS)
endif
.PHONY: ssh
ssh:
@export TERM=screen ; \
ssh -t -l core -o UserKnownHostsFile=/dev/null -o NoHostAuthenticationForLocalhost=yes -A -p $(PORT) localhost ||:
CLEAN_FILES += $(BASE)/version.txt $(BASE)/flatcar-container.tar.gz
ctr: $(BASE)/version.txt $(BASE)/flatcar-container.tar.gz
zcat $(BASE)/flatcar-container.tar.gz | docker import - flatcar:$(patsubst FLATCAR_VERSION=%,%,$(filter FLATCAR_VERSION=%,$(shell cat $(BASE)/version.txt)))
CLEAN_FILES += $(BASE)/version.txt $(BASE)/flatcar_developer_container.bin $(BASE)/tmp-x $(BASE)/tmp-xx
dev-ctr: $(BASE)/version.txt $(BASE)/flatcar_developer_container.bin
sudo losetup -f --show -P $(BASE)/flatcar_developer_container.bin > $(BASE)/tmp-x && \
mkdir -p $(BASE)/flatcar_developer_container && \
sudo fdisk -l `cat $(BASE)/tmp-x` | grep "Linux root" | awk '{ print $$1 }' > $(BASE)/tmp-xx && \
sudo mount `cat $(BASE)/tmp-xx` $(BASE)/flatcar_developer_container/ && \
sudo tar -C $(BASE)/flatcar_developer_container/ -c . | docker import - flatcar:dev-$(patsubst FLATCAR_VERSION=%,%,$(filter FLATCAR_VERSION=%,$(shell cat $(BASE)/version.txt))) && \
sudo umount $(BASE)/flatcar_developer_container/ && \
sudo losetup -d `cat /tmp/x` && \
rm /tmp/x /tmp/xx
DISTCLEAN_FILES += $(BASE)/flatcar_developer_container.bin
dev: $(BASE)/flatcar_developer_container.bin
sudo systemd-nspawn -bn --setenv TERM=screen --hostname=$(HOST_NAME) --bind=$$HOME:/media/home -i $(BASE)/flatcar_developer_container.bin
.PHONY: clean
clean:
rm -rf $(CLEAN_FILES)
dist-clean: clean
rm -rf $(DISTCLEAN_FILES)
CLEAN_FILES += $(BASE)/.check
DISTCLEAN_FILES += $(FLATCAR_FILES)
.PHONY: .check
.check: $(BASE)/.check
$(BASE)/.check: .recvkey $(FLATCAR_FILES)
test -d $(BASE) || mkdir -p $(BASE) && \
cd $(BASE)/ && \
gpg --verify flatcar_production_qemu$(U)_image.img.bz2.DIGESTS.asc && \
sha512sum -c flatcar_production_qemu$(U)_image.img.bz2.DIGESTS && \
cd - ; \
touch $@
CLEAN_FILES += .recvkey
DISTCLEAN_FILES += Flatcar_Image_Signing_Key.asc
.recvkey:
@if [ -z "$$(command -v gpg)" ] ; then \
echo "ERROR: 'gpg' must be present" ; \
false ; \
fi && \
if ! gpg -k 2>/dev/null | grep -q $(FLATCAR_SIGNING_KEY) ; then \
echo "WARN: gpg key $(FLATCAR_SIGNING_KEY) not in your keyring" ;\
curl -LO https://www.flatcar-linux.org/security/image-signing-key/Flatcar_Image_Signing_Key.asc ;\
echo "INFO: importing key from https://www.flatcar-linux.org/security/image-signing-key/Flatcar_Image_Signing_Key.asc" ;\
gpg --import Flatcar_Image_Signing_Key.asc ;\
fi && \
touch $@
DISTCLEAN_FILES += $(ISO_FILE)
.PHONY: iso
iso: $(ISO_FILE)
$(ISO_FILE): cloud-config.yml.in create-basic-configdrive $(SSH_KEY)
./create-basic-configdrive -H $(HOST_NAME) -S $(SSH_KEY) -c cloud-config.yml.in
$(IGNITION_FILE): $(CWD)/ignition.json.in
m4 < $< > $@
DISTCLEAN_FILES += create-basic-configdrive
create-basic-configdrive:
curl -o $@ -sSL https://raw.githubusercontent.com/flatcar-linux/scripts/main/contrib/create-basic-configdrive && \
chmod +x $@
$(BASE)/flatcar_production_qemu$(U)_image.img:
bzcat $(BASE)/flatcar_production_qemu$(U)_image.img.bz2 > $@
DISTCLEAN_FILES += $(BASE)/flatcar_developer_container.bin.bz2
$(BASE)/flatcar_developer_container.bin: $(BASE)/flatcar_developer_container.bin.bz2
bzcat $< > $@
$(BASE)/%:
test -d $(BASE) || mkdir -p $(BASE) && \
curl -o $@ $(CREDS) -L "https://$(CHANNEL).release.flatcar-linux.net/$(BOARD)/$(VERSION)/$(notdir $@)" ; \
test $$(wc -c < $@) -gt 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment