diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2f3501 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*build/ diff --git a/debian-isogen/Dockerfile b/debian-isogen/Dockerfile new file mode 100644 index 0000000..4f58f83 --- /dev/null +++ b/debian-isogen/Dockerfile @@ -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 diff --git a/debian-isogen/Makefile b/debian-isogen/Makefile new file mode 100644 index 0000000..f4f3b18 --- /dev/null +++ b/debian-isogen/Makefile @@ -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 diff --git a/debian-isogen/README.md b/debian-isogen/README.md new file mode 100644 index 0000000..b8ec821 --- /dev/null +++ b/debian-isogen/README.md @@ -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) diff --git a/debian-isogen/examples/isogen.yaml b/debian-isogen/examples/isogen.yaml new file mode 100644 index 0000000..7096643 --- /dev/null +++ b/debian-isogen/examples/isogen.yaml @@ -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 diff --git a/debian-isogen/examples/network-config b/debian-isogen/examples/network-config new file mode 100644 index 0000000..c6e03f9 --- /dev/null +++ b/debian-isogen/examples/network-config @@ -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 + diff --git a/debian-isogen/examples/user-data b/debian-isogen/examples/user-data new file mode 100644 index 0000000..594b5a0 --- /dev/null +++ b/debian-isogen/examples/user-data @@ -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- diff --git a/debian-isogen/files/build.sh b/debian-isogen/files/build.sh new file mode 100644 index 0000000..51dae9c --- /dev/null +++ b/debian-isogen/files/build.sh @@ -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}" diff --git a/debian-isogen/files/functions.sh b/debian-isogen/files/functions.sh new file mode 100644 index 0000000..bfdf4ff --- /dev/null +++ b/debian-isogen/files/functions.sh @@ -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 +} diff --git a/debian-isogen/files/grub.conf b/debian-isogen/files/grub.conf new file mode 100644 index 0000000..9718d82 --- /dev/null +++ b/debian-isogen/files/grub.conf @@ -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 +} diff --git a/debian-isogen/files/packages_install.sh b/debian-isogen/files/packages_install.sh new file mode 100644 index 0000000..468f551 --- /dev/null +++ b/debian-isogen/files/packages_install.sh @@ -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/*