[AIR-152] Initial debian based iso builder

Tool for building ephemeral kubernetes cluster deployment iso image

Change-Id: Id9774eaef1c4d61ffe1a29a293c197c4a954e129
This commit is contained in:
Nikolay Fedorov 2019-09-13 17:32:13 +04:00
parent 0f752a0f61
commit 0f9fbdce8b
11 changed files with 449 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*build/

44
debian-isogen/Dockerfile Normal file
View File

@ -0,0 +1,44 @@
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
ARG FROM=debian:stable
FROM ${FROM}
LABEL org.opencontainers.image.authors='airship-discuss@lists.airshipit.org, irc://#airshipit@freenode' \
org.opencontainers.image.url='https://airshipit.org' \
org.opencontainers.image.documentation='https://airship-images.readthedocs.org' \
org.opencontainers.image.source='https://opendev.org/airship/images' \
org.opencontainers.image.vendor='The Airship Authors' \
org.opencontainers.image.licenses='Apache-2.0'
RUN apt-get update && apt-get install -y \
debootstrap \
grub-efi-amd64-bin \
grub-pc-bin \
mtools \
squashfs-tools \
xorriso \
curl\
&& rm -rf /var/lib/apt/lists/*
COPY ./files/build.sh /builder/
COPY ./files/functions.sh /builder/
COPY ./files/grub.conf /builder/
COPY ./files/packages_install.sh /builder/
RUN curl -L https://github.com/mikefarah/yq/releases/download/2.4.0/yq_linux_amd64 -o /bin/yq \
&& chmod +x /bin/yq
CMD /bin/bash /builder/build.sh

136
debian-isogen/Makefile Normal file
View File

@ -0,0 +1,136 @@
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
SHELL := /bin/bash
BUILD_DIR ?= build
PUSH_IMAGE ?= false
IMAGE_ID ?= none
COMMIT ?= $(shell git rev-parse HEAD)
LABEL ?= org.airshipit.build=community
IMAGE_NAME ?= isogen
DOCKER_REGISTRY ?= quay.io
IMAGE_PREFIX ?= airshipit
IMAGE_TAG ?= latest
DISTRO ?= debian_stable
IMAGE := ${DOCKER_REGISTRY}/${IMAGE_PREFIX}/${IMAGE_NAME}:${IMAGE_TAG}-${DISTRO}
SH_TO_CHECK := $(wildcard files/*.sh )
PROXY ?= http://proxy.foo.com:8000
NO_PROXY ?= localhost,127.0.0.1,.svc.cluster.local
USE_PROXY ?= false
all: lint images
check-docker:
@if [ -z $$(which docker) ]; then \
echo "Missing \`docker\` client which is required for development"; \
exit 2; \
fi
images: check-docker build_isogen
docs: clean build_docs
build_docs:
echo TODO
run_images: run_isogen
run_isogen: $(BUILD_DIR)/output-metadata.yaml
echo OK
#TODO consistance test
$(BUILD_DIR)/output-metadata.yaml: $(BUILD_DIR)/image_id
cp examples/user-data $(BUILD_DIR)
cp examples/isogen.yaml $(BUILD_DIR)
cp examples/network-config $(BUILD_DIR)
ifeq ($(USE_PROXY), true)
docker run \
--rm \
-e BUILDER_CONFIG=/config/isogen.yaml \
-e http_proxy=$(PROXY) \
-e https_proxy=$(PROXY) \
-e HTTP_PROXY=$(PROXY) \
-e HTTPS_PROXY=$(PROXY) \
-e no_proxy=$(NO_PROXY) \
-e NO_PROXY=$(NO_PROXY) \
-v $(shell realpath $(BUILD_DIR)):/config/ \
$(shell cat $(BUILD_DIR)/image_id)
else
docker run \
--rm \
-e BUILDER_CONFIG=/config/isogen.yaml \
-v $(shell realpath $(BUILD_DIR)):/config/ \
$(shell cat $(BUILD_DIR)/image_id)
endif
$(BUILD_DIR)/image_id: build_isogen
build_isogen:
mkdir -p $(BUILD_DIR)
ifeq ($(IMAGE_ID), none)
ifeq ($(USE_PROXY), true)
docker build . --quiet \
--label $(LABEL) \
--label "org.opencontainers.image.revision=$(COMMIT)" \
--label "org.opencontainers.image.created=\
$(shell date --rfc-3339=seconds --utc)" \
--label "org.opencontainers.image.title=$(IMAGE_NAME)" \
--build-arg http_proxy=$(PROXY) \
--build-arg https_proxy=$(PROXY) \
--build-arg HTTP_PROXY=$(PROXY) \
--build-arg HTTPS_PROXY=$(PROXY) \
--build-arg no_proxy=$(NO_PROXY) \
--build-arg NO_PROXY=$(NO_PROXY) \
--build-arg GIT_COMMIT=$(COMMIT) > $(BUILD_DIR)/image_id
else
docker build . --quiet \
--label $(LABEL) \
--label "org.opencontainers.image.revision=$(COMMIT)" \
--label "org.opencontainers.image.created=\
$(shell date --rfc-3339=seconds --utc)" \
--label "org.opencontainers.image.title=$(IMAGE_NAME)" \
--build-arg GIT_COMMIT=$(COMMIT) > $(BUILD_DIR)/image_id
endif
else
echo $(IMAGE_ID) > $(BUILD_DIR)/image_id
endif
ifeq ($(PUSH_IMAGE), true)
docker push $(IMAGE)
endif
clean:
ifeq ($(IMAGE_ID), none)
if [[ -s $(BUILD_DIR)/image_id ]]; \
then \
docker rmi $$(cat $(BUILD_DIR)/image_id); \
fi
endif
rm -rf $(BUILD_DIR)
# style checks
lint: test-shellcheck
tests: lint unit_tests
test-shellcheck: $(SH_TO_CHECK)
unit_tests:
echo TODO
$(SH_TO_CHECK):
docker run --rm -v $(shell pwd):/mnt \
nlknguyen/alpine-shellcheck -x /mnt/$(@)
.PHONY: test clean $(SH_TO_CHECK) test-shellcheck tests lint build_isogen \
run_isogen run_images all build_docs docs check-docker images

27
debian-isogen/README.md Normal file
View File

@ -0,0 +1,27 @@
# airship-isogen
Iso creation tool
Prepare
$(BUILD_DIR)=/some_path...
mkdir $(BUILD_DIR)
If you don't have isogen image
make build_isogen
Usage
cp examples/user-data $(BUILD_DIR)
cp examples/isogen.yaml $(BUILD_DIR)
cp examples/network-config $(BUILD_DIR)
#Modify files if necessary
docker run \
--rm \
-e BUILDER_CONFIG=/config/isogen.yaml \
-v $(shell realpath $(BUILD_DIR)):/config/ \
$(shell cat $(BUILD_DIR)/image_id)
Get debian-custom.iso from dir $(BUILD_DIR)

View File

@ -0,0 +1,9 @@
container:
volume: ./examples:/config
image: dukov/image_gen:latest
containerRuntime: docker
privileged: false
builder:
userDataFileName: user-data
networkConfigFileName : network-config
outputMetadataFileName: output-metadata.yaml

View File

@ -0,0 +1,12 @@
network:
version: 1
config:
- type: physical
name: id0
mac_address: "52:54:00:bf:b2:d8"
subnets:
- type: static
address: 192.168.100.100
netmask: 255.255.255.0
gateway: 192.168.100.1

View File

@ -0,0 +1,5 @@
#cloud-config
runcmd:
- kubeadm init --pod-network-cidr=192.168.0.0/24 --ignore-preflight-errors 'SystemVerification'
- kubectl --kubeconfig /etc/kubernetes/admin.conf taint nodes --all node-role.kubernetes.io/master-

View File

@ -0,0 +1,39 @@
#!/bin/bash
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
BASEDIR="$(dirname "$(realpath "$0")")"
# shellcheck source=files/functions.sh
source "${BASEDIR}/functions.sh"
set -xe
_check_input_data_set_vars
_debootstrap
chroot "${CHROOT}" < "${BASEDIR}/packages_install.sh"
cat "${NET_CONFIG}" >> "${CHROOT}/etc/cloud/cloud.cfg.d/network-config.cfg"
cat "${USER_DATA}" >> "${CHROOT}/etc/cloud/cloud.cfg.d/user-data.cfg"
echo "datasource_list: [ NoCloud, None ]" > \
"${CHROOT}/etc/cloud/cloud.cfg.d/95_no_cloud_ds.cfg"
_make_kernel
_grub_install
_make_iso
OUTPUT="$(yq r "${BUILDER_CONFIG}" builder.outputMetadataFileName)"
HOST_PATH="${ADDR[0]}"
_make_metadata "${VOLUME}/${OUTPUT}" "${HOST_PATH}"

View File

@ -0,0 +1,134 @@
#!/bin/bash
#functions
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
function _debootstrap (){
debootstrap \
--arch=amd64 \
--variant=minbase \
buster \
"${HOME}"/LIVE_BOOT/chroot \
http://ftp.debian.org/debian/
}
function _make_kernel(){
mkdir -p "${HOME}"/LIVE_BOOT/{scratch,image/live}
mksquashfs \
"${HOME}"/LIVE_BOOT/chroot \
"${HOME}"/LIVE_BOOT/image/live/filesystem.squashfs \
-e boot
cp "${HOME}"/LIVE_BOOT/chroot/boot/vmlinuz-* \
"${HOME}"/LIVE_BOOT/image/vmlinuz &&
cp "${HOME}"/LIVE_BOOT/chroot/boot/initrd.img-* \
"${HOME}"/LIVE_BOOT/image/initrd
}
function _grub_install (){
cp /builder/grub.conf "${HOME}"/LIVE_BOOT/scratch/grub.cfg
touch "${HOME}/LIVE_BOOT/image/DEBIAN_CUSTOM"
grub-mkstandalone \
--format=i386-pc \
--output="${HOME}/LIVE_BOOT/scratch/core.img" \
--install-modules="linux normal iso9660 biosdisk memdisk search tar ls all_video" \
--modules="linux normal iso9660 biosdisk search" \
--locales="" \
--fonts="" \
boot/grub/grub.cfg="${HOME}/LIVE_BOOT/scratch/grub.cfg"
cat \
/usr/lib/grub/i386-pc/cdboot.img "${HOME}/LIVE_BOOT/scratch/core.img" \
> "${HOME}/LIVE_BOOT/scratch/bios.img"
}
function _make_iso(){
xorriso \
-as mkisofs \
-iso-level 3 \
-full-iso9660-filenames \
-volid "DEBIAN_CUSTOM" \
--grub2-boot-info \
--grub2-mbr /usr/lib/grub/i386-pc/boot_hybrid.img \
-eltorito-boot \
boot/grub/bios.img \
-no-emul-boot \
-boot-load-size 4 \
-boot-info-table \
--eltorito-catalog boot/grub/boot.cat \
-output "/config/debian-custom.iso" \
-graft-points \
"${HOME}/LIVE_BOOT/image" \
/boot/grub/bios.img="${HOME}/LIVE_BOOT/scratch/bios.img"
}
function _make_metadata(){
echo "bootImagePath: ${2:?}/debian-custom.iso" > "${1:?}"
}
function _check_input_data_set_vars(){
CHROOT="${HOME}/LIVE_BOOT/chroot"
export CHROOT
echo "${BUILDER_CONFIG:?}"
if [ ! -f "${BUILDER_CONFIG}" ]
then
echo "file ${BUILDER_CONFIG} not found"
exit 1
fi
IFS=':' read -ra ADDR <<<"$(yq r "${BUILDER_CONFIG}" container.volume)"
VOLUME="${ADDR[1]}"
echo "${VOLUME:?}"
if [[ "${VOLUME}" == 'none' ]]
then
echo "variable container.volume \
is not present in $BUILDER_CONFIG"
exit 1
else
if [[ ! -d "${VOLUME}" ]]
then
echo "${VOLUME} not exist"
exit 1
fi
fi
USER_DATA="${VOLUME}/$(yq r "${BUILDER_CONFIG}" builder.userDataFileName)"
echo "${USER_DATA:?}"
if [[ "${USER_DATA}" == 'none' ]]
then
echo "variable userDataFileName \
is not present in ${BUILDER_CONFIG}"
exit 1
else
if [[ ! -f ${USER_DATA} ]]
then
echo "${USER_DATA} not exist"
exit 1
fi
fi
NET_CONFIG="${VOLUME}/$(yq r "${BUILDER_CONFIG}" \
builder.networkConfigFileName)"
echo "${NET_CONFIG:?}"
if [[ "${NET_CONFIG}" == 'none' ]]
then
echo "variable networkConfigFileName \
is not present in ${BUILDER_CONFIG}"
exit 1
if [[ ! -f ${NET_CONFIG} ]]
then
echo "${NET_CONFIG} not exist"
exit 1
fi
fi
}

View File

@ -0,0 +1,11 @@
search --set=root --file /DEBIAN_CUSTOM
insmod all_video
set default="0"
set timeout=1
menuentry "Debian Live" {
linux /vmlinuz boot=live quiet nomodeset ip=frommedia overlay-size=70%
initrd /initrd
}

View File

@ -0,0 +1,31 @@
#!/bin/bash
# Copyright 2018 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -xe
echo "debian-live" > /etc/hostname
echo "127.0.0.1 localhost" > /etc/hosts
apt-get update && apt-get install -y --no-install-recommends \
linux-image-amd64 \
live-boot \
systemd-sysv\
apt-transport-https \
openssh-server \
curl \
gnupg \
iptables
echo "deb http://ftp.debian.org/debian unstable main" >> /etc/apt/sources.list
apt-get update && apt-get install -y --no-install-recommends \
cloud-init
rm -rf /var/lib/apt/lists/*