Initial commit: implemented MSVSphere 9.1 default image building

master 0.0.1
Eugene Zamriy 2 years ago
commit 6f7e4a7f09
Signed by: ezamriy
GPG Key ID: 7EBF95C7DCFA496C

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Eugene Zamriy, Softline.ru.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,55 @@
# Inferit MSVSphere Docker images
This project contains configuration files and tools for building
[official MSVSphere Docker](https://hub.docker.com/r/inferit/msvsphere) images.
## Build requirements
In order to build an MSVSphere Docker image you need an MSVSphere system with
the following packages installed:
```shell
$ sudo dnf install -y anaconda-tui lorax tar
```
You may also need to change SELinux mode to permissive.
## Usage
The [build-image.sh](build-image.sh) tool must be executed from a root user
shell. See it's `--help` for a list of supported arguments.
Here is an MSVSphere 9 default image build example:
```shell
$ sudo ./build-image.sh --release 9 --type default --output ./result
```
The result will be a built rootfs-tarball, a generated Dockerfile and
corresponding build logs:
```shell
$ ls result/9-default/ -1
Dockerfile
logs
msvsphere-9-default.tar.xz
```
## References
* Docker documentation: [Create a base image](https://docs.docker.com/build/building/base-images/)
* RHEL System Design Guide: [Kickstart Reference guide](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/system_design_guide/kickstart-script-file-format-reference_system-design-guide)
* Opencontainers [image-spec annotations/labels](https://github.com/opencontainers/image-spec/blob/master/annotations.md)
## License
Licensed under the MIT license, see the [LICENSE](LICENSE) file for details.
## Authors
* [Eugene Zamriy](https://github.com/ezamriy)

@ -0,0 +1,133 @@
#!/bin/bash
set -eo pipefail
ARCH="$(uname -m)"
IMAGE_TYPE='default'
RELEASE='9'
BASE_DIR='./result'
PROGRAM_DIR="$(dirname -- "$0")"
VERSION='0.0.1'
show_usage() {
echo -e 'Generates an MSVSphere container image RootFS and Dockerfile\n'
echo -e 'Usage: build-image.sh [OPTION]...\n'
echo ' -h, --help show this message and exit'
echo " -r, --release RELEASE target MSVSphere release, default is ${RELEASE}"
echo ' -t, --type TYPE image type, supported values are: default.'
echo " Default value is '${IMAGE_TYPE}'"
echo " -o, --output DIR output directory path, default is ${BASE_DIR}"
echo ' -v, --version show program version and exit'
}
log_error() {
echo "ERROR : ${1}" >&2
}
gen_dockerfile() {
local -r image_name="${1}"
local -r build_date="$(date --rfc-3339=seconds --utc)"
echo 'FROM scratch'
echo "ADD ${image_name} /"
echo ''
# see https://github.com/opencontainers/image-spec/blob/master/annotations.md for details
echo "LABEL org.opencontainers.image.title=\"MSVSphere ${RELEASE} ${ARCH} ${IMAGE_TYPE} image\""
echo 'LABEL org.opencontainers.image.vendor="MSVSphere"'
echo 'LABEL org.opencontainers.image.licenses="MIT"'
echo "LABEL org.opencontainers.image.created=\"${build_date}\""
echo 'LABEL org.opencontainers.image.authors="Eugene Zamriy <ezamriy@msvsphere.ru>"'
echo 'LABEL org.opencontainers.image.source="https://git.inferitos.ru/msvsphere/docker-images"'
echo ''
#
case "${IMAGE_TYPE}" in
default)
echo 'CMD ["/bin/bash"]'
;;
*)
log_error "unsupported image type ${IMAGE_TYPE}"
exit 1
;;
esac
}
collect_logs() {
local -r logs_dir="${1}/logs"
mkdir "${logs_dir}"
if [[ -d anaconda ]]; then
mv anaconda "${logs_dir}/"
fi
mv ./*.log "${logs_dir}/"
}
main() {
local -r image_name="msvsphere-${RELEASE}-${IMAGE_TYPE}.tar.xz"
local -r ks_file="${PROGRAM_DIR}/kickstarts/msvsphere-${RELEASE}-${IMAGE_TYPE}.ks"
local -r project="MSVSphere ${RELEASE} ${IMAGE_TYPE} Docker image"
local -r result_dir="${BASE_DIR%%/}/${RELEASE}-${IMAGE_TYPE}"
local -r docker_file="${result_dir}/Dockerfile"
if [[ -d "${result_dir}" ]]; then
log_error "directory ${result_dir} is already exist, please remove it first"
exit 1
elif [[ ! -f "${ks_file}" ]]; then
log_error "kickstart file ${ks_file} is not found"
exit 1
fi
# generate RootFS tarball
livemedia-creator --no-virt --make-tar \
--project "${project}" \
--releasever "${RELEASE}" \
--image-name "${image_name}" \
--ks "${ks_file}" \
--resultdir "${result_dir}" \
--anaconda-arg "--nosave all"
# generate Dockerfile and save build logs
gen_dockerfile "${image_name}" >"${docker_file}"
collect_logs "${result_dir}"
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
ARGS=()
while [[ $# -gt 0 ]]; do
case ${1} in
-h | --help)
show_usage
exit 0
;;
-t | --type)
case "${2}" in
default)
IMAGE_TYPE="${2}"
;;
*)
log_error "unsupported image type '${2}'"
exit 2
;;
esac
shift
shift
;;
-o | --output)
if [[ -z "${2}" ]]; then
log_error 'output directory path is required'
exit 2
fi
BASE_DIR="${2}"
shift
shift
;;
-v | --version)
echo "${VERSION}"
exit 0
;;
-*)
log_error "unknown option ${1}"
exit 2
;;
*)
ARGS+=("${1}")
shift
;;
esac
done
main
fi

@ -0,0 +1,107 @@
# MSVSphere 9 default Docker image kickstart file
# TODO: change to the kickstart repo URL when we have it
url --url https://rsync.inferitos.ru/msvsphere/9/BaseOS/$basearch/os/
repo --name=BaseOS --baseurl=https://rsync.inferitos.ru/msvsphere/9/BaseOS/$basearch/os/
repo --name=AppStream --baseurl=https://rsync.inferitos.ru/msvsphere/9/AppStream/$basearch/os/
lang C.UTF-8
keyboard us
timezone --nontp --utc UTC
network --activate --bootproto=dhcp --device=link --onboot=on
selinux --disabled
bootloader --disabled
zerombr
clearpart --all --initlabel
autopart --fstype=ext4 --type=plain --nohome --noboot --noswap
rootpw --lock --plaintext msvsphere
shutdown
%packages --excludedocs --nocore --instLangs=en --excludeWeakdeps
sphere-release
bash
binutils
coreutils-single
crypto-policies-scripts
curl-minimal
findutils
hostname
iputils
glibc-minimal-langpack
less
libcurl-minimal
rootfiles
tar
vim-minimal
yum
xz
-dosfstools
-e2fsprogs
-gnupg2-smime
-hyperv*
-kernel
-langpacks-*
-langpacks-en
-libss
-open-vm-tools
-pinentry
-qemu-guest-agent
-subscription-manager
-trousers
-xfsprogs
-xkeyboard-config
%end
# NOTE: add --log=/root/anaconda-post.log for debugging
%post --erroronfail
# generate build time file for compatibility with CentOS
/bin/date +%Y%m%d_%H%M > /etc/BUILDTIME
# Change format of the RPM database from Berkeley DB to a new SQLite format
rpmdb --rebuilddb
# set DNF infra variable to container for compatibility with CentOS
echo 'container' > /etc/dnf/vars/infra
# import MSVSphere PGP key
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-MSVSphere-9
# install only C.UTF-8 locale files, see
# https://fedoraproject.org/wiki/Changes/Glibc_locale_subpackaging for details
LANG="C.utf8"
echo "%_install_langs $LANG" > /etc/rpm/macros.image-language-conf
# https://bugzilla.redhat.com/show_bug.cgi?id=1727489
echo 'LANG="C.UTF-8"' > /etc/locale.conf
# force each container to have a unique machine-id
> /etc/machine-id
# create tmp directories because there is no tmpfs support in Docker
umount /run
systemd-tmpfiles --create --boot
# disable login prompt, mounts and fix: https://bugzilla.redhat.com/show_bug.cgi?id=1472439
systemctl mask systemd-remount-fs.service \
dev-hugepages.mount \
sys-fs-fuse-connections.mount \
systemd-logind.service \
getty.target \
console-getty.service
KEEPLANG=en_US
for dir in locale i18n; do
find /usr/share/${dir} -mindepth 1 -maxdepth 1 -type d -not \( -name "${KEEPLANG}" -o -name POSIX \) -exec rm -rfv {} +
done
# remove unnecessary files
rm -f /var/lib/dnf \
/run/nologin
rm -fr /var/log/* \
/tmp/* /tmp/.* \
/boot || true
%end
Loading…
Cancel
Save