# Simple Makefile to build base VM images using packer and ansible # TODO # * support ssh per user instead of root # * support building with non-qemu builders and convert to qemu afterwards # * testing target # * auto-detect flavors PACKER=packer ANSIBLE_DIR=ansible-roles # the "provisioning" flavor, expects a 'setup-.yml' playbook # in the 'ansible-roles' submodule! This will likely change... FLAVORS := $(patsubst $(ANSIBLE_DIR)/setup-%.yml,%, $(wildcard $(ANSIBLE_DIR)/setup-*.yml)) SUPPORTED_BUILDERS = qemu virtualbox-iso vmware-iso # check which hypervisors are available ifeq ($(shell which qemu-system-$(shell uname -m | sed 's/i686/i386/') 2>&1 > /dev/null && echo $$?), 0) AVAILABLE_BUILDERS += qemu BUILDER := qemu endif ifndef BUILDER ifeq ($(shell which virtualbox 2>&1 > /dev/null && echo $$?), 0) AVAILABLE_BUILDERS += virtualbox-iso BUILDER := virtualbox-iso endif endif ifndef BUILDER ifeq ($(shell which vmplayer 2>&1 > /dev/null && echo $$?), 0) AVAILABLE_BUILDERS += vmware-iso BUILDER := vmware-iso endif endif ifndef BUILDER $(error No usable builder found! Please install a hypervisor...) endif MISSING_BUILDERS = $(filter-out $(AVAILABLE_BUILDERS),$(SUPPORTED_BUILDERS)) ifneq ($(words $(MISSING_BUILDERS)), 0) $(info Builders missing on this system: $(MISSING_BUILDERS)) $(info If you wish to use these, install the corresponding hypervisor and retry.) $(info ) endif TEMPLATES := $(basename $(filter-out base.json,$(wildcard *.json))) BASETARGETS := $(foreach template, $(TEMPLATES), $(template)/base) PROVTARGETS := $(foreach template, $(TEMPLATES), $(foreach flavor, $(FLAVORS), $(template)/$(flavor))) BOOTTARGETS := $(foreach template, $(TEMPLATES), $(template)/base/boot) BOOTTARGETS += $(foreach prov, $(PROVTARGETS), $(prov)/boot) PACKER_OPTS := -var-file=base.json ifdef DEBUG PACKER_OPTS += -debug PACKER_OPTS += -var='headless=false' endif .PHONY: all help clean all: help ## # Creating base images ## $(BASETARGETS): ifndef ROOTPW $(error ROOTPW is not set) endif $(info ** Building template '$(@D)' using '$(BUILDER)' **) $(PACKER) build -only=$(BUILDER) \ $(PACKER_OPTS) \ -var='vm_name=$(@D)' \ $(@D).json @test -f output-$(@D)-$(BUILDER)/$(@D) || false @-test -d $(@D)/base && rm -rf $(@D)/base @-mkdir $(@D) @mv output-$(@D)-$(BUILDER) $(@D)/base @mv $(@D)/base/$(@D) $(@D)/base/image @echo "** Success **" ## # Provisioning images ## # This should still only use base images $(PROVTARGETS): $(foreach flav, $(FLAVORS), %/$(flav)): %/base $(info ** Provisioning '$(@D)' with '$(@F)' **) $(PACKER) build -only=$(BUILDER) \ $(PACKER_OPTS) \ -var='vm_name=$(@F)' \ -var='image_dir=$(@D)' \ -var='image_name=base/image' \ -var='playbook=setup-$(@F).yml' \ $(ANSIBLE_DIR)/run-playbook-only.json @test -f output-$(@D)/$(@F) || false @-test -d $(@D)/$(@F) && rm -rf $(@D)/$(@F) @-mkdir $(@D)/$(@F) @mv output-$(@D)/$(@F) $(@D)/$(@F)/image @rmdir output-$(@D) @echo "** Success **" ## # Generating boot files ## # This should use provisioned image $(BOOTTARGETS): %/boot: % $(info ** Generating boot files for '$(patsubst %/,%,$(dir $(@D))):$(notdir $(@D))' **) $(PACKER) build -only=$(BUILDER) \ $(PACKER_OPTS) \ -var='vm_name=$(notdir $(@D)).tmp' \ -var='image_dir=$(patsubst %/,%,$(dir $(@D)))/$(notdir $(@D))' \ -var='image_name=image' \ -var='playbook=build-dracut-initramfs.yml' \ $(ANSIBLE_DIR)/run-playbook-only.json @test -f $(ANSIBLE_DIR)/boot_files/initramfs || false @-test -d $(patsubst %/,%,$(dir $(@D)))/$(notdir $(@D))/boot && \ rm -rf $(patsubst %/,%,$(dir $(@D)))/$(notdir $(@D))/boot @mv $(ANSIBLE_DIR)/boot_files $(patsubst %/,%,$(dir $(@D)))/$(notdir $(@D))/boot ifndef DEBUG @rm -rf output-$(patsubst %/,%,$(dir $(@D)))/ endif @echo "** Success **" help: @echo "General syntax: