commit
6f7e4a7f09
@ -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…
Reference in new issue