summaryrefslogtreecommitdiffstats
path: root/bootstrap
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:20:00 +0000
commit8daa83a594a2e98f39d764422bfbdbc62c9efd44 (patch)
tree4099e8021376c7d8c05bdf8503093d80e9c7bad0 /bootstrap
parentInitial commit. (diff)
downloadsamba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.tar.xz
samba-8daa83a594a2e98f39d764422bfbdbc62c9efd44.zip
Adding upstream version 2:4.20.0+dfsg.upstream/2%4.20.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/.gitlab-ci.yml123
-rw-r--r--bootstrap/README.md108
-rw-r--r--bootstrap/config.py688
-rw-r--r--bootstrap/generated-dists/Vagrantfile98
-rw-r--r--bootstrap/generated-dists/centos7/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/centos7/bootstrap.sh120
-rwxr-xr-xbootstrap/generated-dists/centos7/locale.sh55
-rw-r--r--bootstrap/generated-dists/centos7/packages.yml100
-rw-r--r--bootstrap/generated-dists/centos8s/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/centos8s/bootstrap.sh125
-rwxr-xr-xbootstrap/generated-dists/centos8s/locale.sh55
-rw-r--r--bootstrap/generated-dists/centos8s/packages.yml105
-rw-r--r--bootstrap/generated-dists/debian11-32bit/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/debian11-32bit/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/debian11-32bit/locale.sh55
-rw-r--r--bootstrap/generated-dists/debian11-32bit/packages.yml102
-rw-r--r--bootstrap/generated-dists/debian11/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/debian11/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/debian11/locale.sh55
-rw-r--r--bootstrap/generated-dists/debian11/packages.yml102
-rw-r--r--bootstrap/generated-dists/debian12-32bit/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/debian12-32bit/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/debian12-32bit/locale.sh55
-rw-r--r--bootstrap/generated-dists/debian12-32bit/packages.yml102
-rw-r--r--bootstrap/generated-dists/debian12/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/debian12/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/debian12/locale.sh55
-rw-r--r--bootstrap/generated-dists/debian12/packages.yml102
-rw-r--r--bootstrap/generated-dists/fedora39/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/fedora39/bootstrap.sh126
-rwxr-xr-xbootstrap/generated-dists/fedora39/locale.sh55
-rw-r--r--bootstrap/generated-dists/fedora39/packages.yml111
-rw-r--r--bootstrap/generated-dists/opensuse155/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/opensuse155/bootstrap.sh119
-rwxr-xr-xbootstrap/generated-dists/opensuse155/locale.sh55
-rw-r--r--bootstrap/generated-dists/opensuse155/packages.yml101
-rw-r--r--bootstrap/generated-dists/ubuntu1804-32bit/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/ubuntu1804-32bit/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/ubuntu1804-32bit/locale.sh55
-rw-r--r--bootstrap/generated-dists/ubuntu1804-32bit/packages.yml102
-rw-r--r--bootstrap/generated-dists/ubuntu1804/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/ubuntu1804/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/ubuntu1804/locale.sh55
-rw-r--r--bootstrap/generated-dists/ubuntu1804/packages.yml102
-rw-r--r--bootstrap/generated-dists/ubuntu2004/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/ubuntu2004/bootstrap.sh117
-rwxr-xr-xbootstrap/generated-dists/ubuntu2004/locale.sh55
-rw-r--r--bootstrap/generated-dists/ubuntu2004/packages.yml102
-rw-r--r--bootstrap/generated-dists/ubuntu2204/Dockerfile29
-rwxr-xr-xbootstrap/generated-dists/ubuntu2204/bootstrap.sh118
-rwxr-xr-xbootstrap/generated-dists/ubuntu2204/locale.sh55
-rw-r--r--bootstrap/generated-dists/ubuntu2204/packages.yml103
-rw-r--r--bootstrap/sha1sum.txt1
-rwxr-xr-xbootstrap/template.py142
54 files changed, 4829 insertions, 0 deletions
diff --git a/bootstrap/.gitlab-ci.yml b/bootstrap/.gitlab-ci.yml
new file mode 100644
index 0000000..ba82cdc
--- /dev/null
+++ b/bootstrap/.gitlab-ci.yml
@@ -0,0 +1,123 @@
+---
+.build_image_template:
+ image: quay.io/podman/stable:latest
+ stage: images
+ tags:
+ # We need to make sure we only use gitlab.com
+ # runners and not our own runners, as our current runners
+ # don't allow 'docker build ...' to run.
+ - docker
+ - gce
+ - shared
+ variables:
+ SAMBA_CI_IS_BROKEN_IMAGE: "no"
+ SAMBA_CI_TEST_JOB: "samba-o3"
+ before_script:
+ # install prerequisites
+ - dnf install -qy diffutils
+ # Ensure we are generating correct the container
+ - uname -a
+ - cat /etc/os-release
+ - echo "SAMBA_CI_CONTAINER_REGISTRY[${SAMBA_CI_CONTAINER_REGISTRY}]"
+ - echo "SAMBA_CI_CONTAINER_TAG[${SAMBA_CI_CONTAINER_TAG}]"
+ - echo "SAMBA_CI_IS_BROKEN_IMAGE[${SAMBA_CI_IS_BROKEN_IMAGE}]"
+ - echo "SAMBA_CI_REBUILD_IMAGES[${SAMBA_CI_REBUILD_IMAGES}]"
+ - echo "SAMBA_CI_REBUILD_BROKEN_IMAGES[${SAMBA_CI_REBUILD_BROKEN_IMAGES}]"
+ - echo "GITLAB_USER_LOGIN[${GITLAB_USER_LOGIN}]"
+ - echo "${SAMBA_CI_CONTAINER_TAG}" > /tmp/sha1sum-tag.txt
+ - diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt
+ script: |
+ set -xueo pipefail
+ ci_image_name=samba-ci-${CI_JOB_NAME}
+ podman build -t ${ci_image_name} --build-arg SHA1SUM=${SAMBA_CI_CONTAINER_TAG} bootstrap/generated-dists/${CI_JOB_NAME}
+ ci_image_path="${SAMBA_CI_CONTAINER_REGISTRY}/${ci_image_name}"
+ timestamp=$(date +%Y%m%d%H%M%S)
+ container_hash=$(podman image inspect --format='{{ .Id }}' ${ci_image_name} | cut -c 1-9)
+ timestamp_tag=${SAMBA_CI_CONTAINER_TAG}-${timestamp}-${GITLAB_USER_LOGIN}-${container_hash}
+ samba_repo_root=/home/samba/samba
+ # Ensure we are generating the correct container that we expect to be in
+ echo "${SAMBA_CI_CONTAINER_TAG}" > /tmp/sha1sum-tag.txt
+ diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt
+ podman run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \
+ /bin/bash -c "echo \"${SAMBA_CI_CONTAINER_TAG}\" > /tmp/sha1sum-tag.txt; diff -u bootstrap/sha1sum.txt /tmp/sha1sum-tag.txt"
+ podman run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \
+ diff -u bootstrap/sha1sum.txt /sha1sum.txt
+ podman run --volume $(pwd):${samba_repo_root} --workdir ${samba_repo_root} ${ci_image_name} \
+ bootstrap/template.py --sha1sum > /tmp/sha1sum-template.txt
+ diff -u bootstrap/sha1sum.txt /tmp/sha1sum-template.txt
+ # run smoke test with samba-o3 or samba-fuzz
+ podman run --volume $(pwd):/src:ro ${ci_image_name} \
+ /bin/bash -c "git clone /src samba && cd samba && export PKG_CONFIG_PATH=/usr/lib64/compat-gnutls34/pkgconfig:/usr/lib64/compat-nettle32/pkgconfig && script/autobuild.py ${SAMBA_CI_TEST_JOB} --verbose --nocleanup --keeplogs --tail --testbase /tmp/samba-testbase"
+ podman tag ${ci_image_name} ${ci_image_path}:${SAMBA_CI_CONTAINER_TAG}
+ podman tag ${ci_image_name} ${ci_image_path}:${timestamp_tag}
+ # We build all images, but only upload is it's not marked as broken
+ test x"${SAMBA_CI_IS_BROKEN_IMAGE}" = x"yes" || { \
+ podman login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY; \
+ podman push ${ci_image_path}:${SAMBA_CI_CONTAINER_TAG}; \
+ podman push ${ci_image_path}:${timestamp_tag}; \
+ }
+ echo "Success for ${ci_image_path}:${timestamp_tag}"
+ test x"${SAMBA_CI_IS_BROKEN_IMAGE}" = x"no" || { \
+ echo "The image ${CI_JOB_NAME} is marked as broken and should have failed!"; \
+ echo "Replace .build_image_template_force_broken with .build_image_template!"; \
+ echo "Add a .samba-o3-template section at the end of the main .gitlab-ci.yml!"; \
+ /bin/false; \
+ }
+ only:
+ variables:
+ #
+ # You need a custom pipeline which passes
+ # SAMBA_CI_REBUILD_IMAGES="yes".
+ #
+ # https://gitlab.com/samba-team/devel/samba/pipelines/new
+ #
+ - $SAMBA_CI_REBUILD_IMAGES == "yes"
+
+.build_image_template_force_broken:
+ extends: .build_image_template
+ variables:
+ SAMBA_CI_IS_BROKEN_IMAGE: "yes"
+ only:
+ variables:
+ #
+ # You need a custom pipeline which passes
+ # SAMBA_CI_REBUILD_BROKEN_IMAGES="yes"
+ # in order to build broken images for debugging
+ #
+ # https://gitlab.com/samba-team/devel/samba/pipelines/new
+ #
+ - $SAMBA_CI_REBUILD_BROKEN_IMAGES == "yes"
+
+ubuntu2004:
+ extends: .build_image_template
+
+ubuntu2204:
+ extends: .build_image_template
+
+debian11:
+ extends: .build_image_template
+
+debian12:
+ extends: .build_image_template
+
+fedora39:
+ extends: .build_image_template
+
+debian11-32bit:
+ extends: .build_image_template
+ variables:
+ SAMBA_CI_TEST_JOB: "samba-32bit"
+
+centos8s:
+ extends: .build_image_template
+
+centos7:
+ extends: .build_image_template
+ variables:
+ # Shallow copies are not supported by git on CentOS7
+ GIT_DEPTH: ""
+ # We install a compat-gnutls34 package for GnuTLS >= 3.4.7
+ PKG_CONFIG_PATH: /usr/lib64/compat-gnutls34/pkgconfig:/usr/lib64/compat-nettle32/pkgconfig
+
+opensuse155:
+ extends: .build_image_template
diff --git a/bootstrap/README.md b/bootstrap/README.md
new file mode 100644
index 0000000..6b3de98
--- /dev/null
+++ b/bootstrap/README.md
@@ -0,0 +1,108 @@
+# Samba Bootstrap
+
+A pure python3 module with CLI to bootstrap Samba envs for multiple distributions.
+
+## Features
+
+- manage Samba dependencies list for multiple distributions
+- render dependencies package list to bootstrap shell scripts(apt, yum and dnf)
+- render Vagrantfile to provision virtual machines with bootstrap scripts
+- render Dockerfile to build docker images with bootstrap scripts
+- build/tag/push docker images
+
+## Supported Distributions
+
+deb: Debian 10, Ubuntu 1604|1804|2004
+rpm: CentOS 7|8, Fedora 33|34, openSUSE Leap 15.1|15.2
+
+Easy to add more.
+
+## Usage
+
+Render files:
+
+ bootstrap/template.py --render
+
+Files are rendered into `bootstrap/generated-dists` directory in current dir.
+It also generates bootstrap/sha1sum.txt and prints out the sha1sum of the
+current code/configuration.
+
+Just calculate the sha1sum for consistency checks:
+
+ bootstrap/template.py --sha1sum
+
+The checksum needs to be added as `SAMBA_CI_CONTAINER_TAG` in
+the toplevel .gitlab-ci-main.yml file.
+
+NOTE: Remember to remove any files not tracked by git from the bootstrap
+directory before running bootstrap/template.py.
+
+ git clean -dfx bootstrap
+
+Otherwise the files will affect the checksum but because they are not
+checked in and won't be pushed to CI system the checksum calculated there
+won't match.
+
+## User Stories
+
+As a gitlab-ci user, I can use this tool to build new CI docker images:
+
+ After committing the result of calling `bootstrap/template.py --render`
+ and updating `SAMBA_CI_CONTAINER_TAG` in .gitlab-ci.yml, you can push.
+
+ But you need to pass `SAMBA_CI_REBUILD_IMAGES=yes` as environment
+ variable. It means the pipeline runs the 'images' stage and builds
+ the new container images for all supported distributions and
+ uploads the images into the registry.gitlab.com/samba-team/devel/samba
+ container registry.
+
+ You can push by specifying the variable (note multiple -o options are allowed,
+ see https://docs.gitlab.com/ee/user/project/push_options.html):
+
+ `git push -o ci.variable='SAMBA_CI_REBUILD_IMAGES=yes' git@gitlab.com:samba-team/devel/samba.git ...`
+
+ If you want to try to build images for the (currently) broken
+ distributions, you would pass `SAMBA_CI_REBUILD_BROKEN_IMAGES=yes`
+ in addition to the custom pipeline. Note the images for
+ the broken distributions are just build, but not uploaded
+ to the container registry. And any failures in the image
+ creation is ignored. Once you managed to get success, you should
+ move from `.build_image_template_force_broken` to `.build_image_template`.
+ And also add a `.samba-o3-template` job for the new image
+ in the main .gitlab-ci.yml file.
+
+ Over time we'll get a lot of images pushed to the container registry.
+ The approach we're using allows gitlab project maintainers to
+ remove old images! But it is possible to regenerate the images
+ if you have the need to run a gitlab ci pipeline based on an
+ older branch.
+
+As a Samba developer/tester, I can setup a Samba env very quickly.
+
+With Docker:
+
+ cd ~/samba
+ git clean -xdf
+ docker login
+ docker pull registry.gitlab.com/samba-team/devel/samba/samba-ci-ubuntu1804:${sha1sum}
+ docker run -it -v $(pwd):/home/samba/samba samba-ci-ubuntu1804:${sha1sum} bash
+
+With podman:
+
+ podman run -ti --cap-add=SYS_PTRACE --security-opt seccomp=unconfined registry.gitlab.com/samba-team/devel/samba/samba-ci-ubuntu1804:${sha1sum} bash
+
+With Vagrant:
+
+ cd bootstrap/generated-dists/
+ vagrant up # start all
+ vagrant up debian10 # start one
+ vagrant ssh debian10
+ vagrant destroy debian10 # destroy one
+ vagrant destroy # destroy all
+
+Or a remote/cloud machine:
+
+ scp bootstrap/generated-dists/fedora33/bootstrap.sh USER@IP:
+ ssh USER@IP
+ sudo bash ./bootstrap.sh
+
diff --git a/bootstrap/config.py b/bootstrap/config.py
new file mode 100644
index 0000000..11d8314
--- /dev/null
+++ b/bootstrap/config.py
@@ -0,0 +1,688 @@
+#!/usr/bin/env python3
+
+# Copyright (C) Catalyst.Net Ltd 2019
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Manage dependencies and bootstrap environments for Samba.
+
+Config file for packages and templates.
+
+Update the lists in this file to require new packages in the
+container images used in GitLab CI
+
+Author: Joe Guo <joeg@catalyst.net.nz>
+"""
+import os
+from os.path import abspath, dirname, join
+HERE = abspath(dirname(__file__))
+# output dir for rendered files
+OUT = join(HERE, 'generated-dists')
+
+
+# pkgs with same name in all packaging systems
+COMMON = [
+ 'acl',
+ 'attr',
+ 'autoconf',
+ 'binutils',
+ 'bison',
+ 'ccache',
+ 'curl',
+ 'chrpath',
+ 'codespell',
+ 'flex',
+ 'gcc',
+ 'gdb',
+ 'git',
+ 'gzip',
+ 'hostname',
+ 'htop',
+ 'jq',
+ 'lcov',
+ 'make',
+ 'patch',
+ 'perl',
+ 'psmisc', # for pstree in test
+ 'rng-tools',
+ 'rsync',
+ 'sed',
+ 'shfmt',
+ 'sudo', # docker images has no sudo by default
+ 'tar',
+ 'tree',
+ 'wget',
+]
+
+
+# define pkgs for all packaging systems in parallel
+# make it easier to find missing ones
+# use latest ubuntu and fedora as defaults
+# deb, rpm, ...
+PKGS = [
+ # NAME1-dev, NAME2-devel
+ ('lmdb-utils', 'lmdb'),
+ ('mingw-w64', 'mingw64-gcc'),
+ ('zlib1g-dev', 'zlib-devel'),
+ ('libbsd-dev', 'libbsd-devel'),
+ ('liburing-dev', 'liburing-devel'),
+ ('libarchive-dev', 'libarchive-devel'),
+ ('libblkid-dev', 'libblkid-devel'),
+ ('libcap-dev', 'libcap-devel'),
+ ('libacl1-dev', 'libacl-devel'),
+ ('libattr1-dev', 'libattr-devel'),
+
+ # libNAME1-dev, NAME2-devel
+ ('libpopt-dev', 'popt-devel'),
+ ('libreadline-dev', 'readline-devel'),
+ ('libjansson-dev', 'jansson-devel'),
+ ('liblmdb-dev', 'lmdb-devel'),
+ ('libncurses5-dev', 'ncurses-devel'),
+ # NOTE: Debian 7+ or Ubuntu 16.04+
+ ('libsystemd-dev', 'systemd-devel'),
+ ('libkrb5-dev', 'krb5-devel'),
+ ('libldap2-dev', 'openldap-devel'),
+ ('libcups2-dev', 'cups-devel'),
+ ('libpam0g-dev', 'pam-devel'),
+ ('libgpgme11-dev', 'gpgme-devel'),
+ # NOTE: Debian 8+ and Ubuntu 14.04+
+ ('libgnutls28-dev', 'gnutls-devel'),
+ ('gnutls-bin', 'gnutls-utils'),
+ ('libtasn1-bin', 'libtasn1-tools'),
+ ('libtasn1-dev', 'libtasn1-devel'),
+ ('', 'quota-devel'),
+ ('uuid-dev', 'libuuid-devel'),
+ ('libjs-jquery', ''),
+ ('libavahi-common-dev', 'avahi-devel'),
+ ('libdbus-1-dev', 'dbus-devel'),
+ ('libpcap-dev', 'libpcap-devel'),
+ ('libunwind-dev', 'libunwind-devel'), # for back trace
+ ('libglib2.0-dev', 'glib2-devel'),
+ ('libicu-dev', 'libicu-devel'),
+ ('heimdal-multidev', ''),
+
+ # NAME1, NAME2
+ # for debian, locales provide locale support with language packs
+ # ubuntu split language packs to language-pack-xx
+ # for centos, glibc-common provide locale support with language packs
+ # fedora split language packs to glibc-langpack-xx
+ ('locales', 'glibc-common'), # required for locale
+ ('language-pack-en', 'glibc-langpack-en'), # we need en_US.UTF-8
+ ('bind9utils', 'bind-utils'),
+ ('dnsutils', ''),
+ ('xsltproc', 'libxslt'),
+ ('krb5-user', 'krb5-workstation'),
+ ('krb5-config', ''),
+ ('krb5-kdc', 'krb5-server'),
+ ('apt-utils', 'yum-utils'),
+ ('pkg-config', 'pkgconfig'),
+ ('procps', 'procps-ng'), # required for the free cmd in tests
+ ('lsb-release', 'lsb-release'), # we need lsb_release to show info
+ ('', 'rpcgen'), # required for test
+ # refer: https://fedoraproject.org/wiki/Changes/SunRPCRemoval
+ ('', 'libtirpc-devel'), # for <rpc/rpc.h> header on fedora
+ ('', 'rpcsvc-proto-devel'), # for <rpcsvc/rquota.h> header
+ ('mawk', 'gawk'),
+ ('', 'mold'),
+ ('shellcheck', 'ShellCheck'),
+ ('', 'crypto-policies-scripts'),
+
+ ('python3', 'python3'),
+ ('python3-cryptography', 'python3-cryptography'), # for krb5 tests
+ ('python3-dev', 'python3-devel'),
+ ('python3-dbg', ''),
+ ('python3-iso8601', 'python3-iso8601'),
+ ('python3-gpg', 'python3-gpg'), # defaults to ubuntu/fedora latest
+ ('python3-markdown', 'python3-markdown'),
+ ('python3-dnspython', 'python3-dns'),
+ ('python3-pexpect', ''), # for wintest only
+ ('python3-pyasn1', 'python3-pyasn1'), # for krb5 tests
+ ('python3-setproctitle', 'python3-setproctitle'),
+ ('python3-requests', 'python3-requests'), # for cert auto enroll
+
+ ('', 'python3-libsemanage'),
+ ('', 'python3-policycoreutils'),
+
+ # perl
+ ('libparse-yapp-perl', 'perl-Parse-Yapp'),
+ ('perl-modules', ''),
+ ('', 'perl-FindBin'),
+ ('', 'perl-Archive-Tar'),
+ ('', 'perl-ExtUtils-MakeMaker'),
+ ('', 'perl-Test-Base'),
+ ('', 'perl-generators'),
+ ('', 'perl-interpreter'),
+
+ # fs
+ ('xfslibs-dev', 'xfsprogs-devel'), # for xfs quota support
+ ('', 'glusterfs-api-devel'),
+ ('glusterfs-common', 'glusterfs-devel'),
+ ('libcephfs-dev', 'libcephfs-devel'),
+
+ # spotlight
+ ('libtracker-sparql-2.0-dev', 'tracker-devel'),
+
+ # misc
+ # @ means group for rpm, use fedora as rpm default
+ ('build-essential', '@development-tools'),
+ ('debhelper', ''),
+ # rpm has no pkg for docbook-xml
+ ('docbook-xml', 'docbook-dtds'),
+ ('docbook-xsl', 'docbook-style-xsl'),
+ ('libkeyutils-dev', 'keyutils-libs-devel'),
+ ('', 'which'),
+ ('xz-utils', 'xz')
+]
+
+
+DEB_PKGS = COMMON + [pkg for pkg, _ in PKGS if pkg]
+RPM_PKGS = COMMON + [pkg for _, pkg in PKGS if pkg]
+
+GENERATED_MARKER = r"""
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+"""
+
+
+APT_BOOTSTRAP = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ {pkgs}
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean
+"""
+
+
+YUM_BOOTSTRAP = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+yum update -y
+yum install -y epel-release
+yum install -y yum-plugin-copr
+yum copr enable -y sergiomb/SambaAD
+yum update -y
+
+yum install -y \
+ {pkgs}
+
+yum clean all
+
+if [ ! -f /usr/bin/python3 ]; then
+ ln -sf /usr/bin/python3.6 /usr/bin/python3
+fi
+"""
+
+CENTOS8S_YUM_BOOTSTRAP = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+yum update -y
+yum install -y dnf-plugins-core
+yum install -y epel-release
+
+yum -v repolist all
+yum config-manager --set-enabled powertools -y
+
+yum update -y
+
+yum install -y \
+ --setopt=install_weak_deps=False \
+ {pkgs}
+
+yum clean all
+"""
+
+DNF_BOOTSTRAP = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+dnf update -y
+
+dnf install -y \
+ --setopt=install_weak_deps=False \
+ {pkgs}
+
+dnf clean all
+
+update-crypto-policies --set DEFAULT:AD-SUPPORT
+"""
+
+DNF_BOOTSTRAP_MIT = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+dnf update -y
+dnf install -y dnf-plugins-core
+dnf copr -y enable abbra/krb5-test
+dnf update -y
+
+dnf install -y \
+ --setopt=install_weak_deps=False \
+ {pkgs}
+
+dnf clean all
+"""
+
+ZYPPER_BOOTSTRAP = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+zypper --non-interactive refresh
+zypper --non-interactive update
+zypper --non-interactive install \
+ --no-recommends \
+ system-user-nobody \
+ {pkgs}
+
+zypper --non-interactive clean
+
+if [ -f /usr/lib/mit/bin/krb5-config ]; then
+ ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config
+fi
+"""
+
+# A generic shell script to setup locale
+LOCALE_SETUP = r"""
+#!/bin/bash
+{GENERATED_MARKER}
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi
+"""
+
+
+DOCKERFILE = r"""
+{GENERATED_MARKER}
+FROM {docker_image}
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || {{ LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }}
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || {{ LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }}
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US
+"""
+
+# Vagrantfile snippet for each dist
+VAGRANTFILE_SNIPPET = r"""
+ config.vm.define "{name}" do |v|
+ v.vm.box = "{vagrant_box}"
+ v.vm.hostname = "{name}"
+ v.vm.provision :shell, path: "{name}/bootstrap.sh"
+ v.vm.provision :shell, path: "{name}/locale.sh"
+ end
+"""
+
+# global Vagrantfile with snippets for all dists
+VAGRANTFILE_GLOBAL = r"""
+{GENERATED_MARKER}
+
+Vagrant.configure("2") do |config|
+ config.ssh.insert_key = false
+
+{vagrantfile_snippets}
+
+end
+"""
+
+DEB_DISTS = {
+ 'debian11': {
+ 'docker_image': 'debian:11',
+ 'vagrant_box': 'debian/bullseye64',
+ 'replace': {
+ 'language-pack-en': '', # included in locales
+ 'shfmt': '',
+ }
+ },
+ 'debian11-32bit': {
+ 'docker_image': 'registry-1.docker.io/i386/debian:11',
+ 'vagrant_box': 'debian/bullseye32',
+ 'replace': {
+ 'language-pack-en': '', # included in locales
+ 'shfmt': '',
+ }
+ },
+ 'debian12': {
+ 'docker_image': 'debian:12',
+ 'vagrant_box': 'debian/bookworm64',
+ 'replace': {
+ 'language-pack-en': '', # included in locales
+ 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
+ }
+ },
+ 'debian12-32bit': {
+ 'docker_image': 'registry-1.docker.io/i386/debian:12',
+ 'vagrant_box': 'debian/bookworm32',
+ 'replace': {
+ 'language-pack-en': '', # included in locales
+ 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
+ }
+ },
+ 'ubuntu1804': {
+ 'docker_image': 'ubuntu:18.04',
+ 'vagrant_box': 'ubuntu/bionic64',
+ 'replace': {
+ 'liburing-dev': '', # not available
+ 'shfmt': '',
+ }
+ },
+ 'ubuntu1804-32bit': {
+ 'docker_image': 'registry-1.docker.io/i386/ubuntu:18.04',
+ 'vagrant_box': 'ubuntu/bionic32',
+ 'replace': {
+ 'liburing-dev': '', # not available
+ 'shfmt': '',
+ }
+ },
+ 'ubuntu2004': {
+ 'docker_image': 'ubuntu:20.04',
+ 'vagrant_box': 'ubuntu/focal64',
+ 'replace': {
+ 'liburing-dev': '', # not available
+ 'shfmt': '',
+ }
+ },
+ 'ubuntu2204': {
+ 'docker_image': 'ubuntu:22.04',
+ 'vagrant_box': 'ubuntu/jammy64',
+ 'replace': {
+ 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
+ },
+ }
+}
+
+
+RPM_DISTS = {
+ 'centos7': {
+ 'docker_image': 'centos:7',
+ 'vagrant_box': 'centos/7',
+ 'bootstrap': YUM_BOOTSTRAP,
+ 'replace': {
+ 'lsb-release': 'redhat-lsb',
+ 'python3': 'python36',
+ 'python3-cryptography': 'python36-cryptography',
+ 'python3-devel': 'python36-devel',
+ 'python3-dns': 'python36-dns',
+ 'python3-pyasn1': 'python36-pyasn1',
+ 'python3-gpg': 'python36-gpg',
+ 'python3-iso8601' : 'python36-iso8601',
+ 'python3-markdown': 'python36-markdown',
+ 'python3-requests': 'python36-requests',
+ # although python36-devel is available
+ # after epel-release installed
+ # however, all other python3 pkgs are still python36-ish
+ 'python2-gpg': 'pygpgme',
+ '@development-tools': '"@Development Tools"', # add quotes
+ 'glibc-langpack-en': '', # included in glibc-common
+ 'glibc-locale-source': '', # included in glibc-common
+ # update perl core modules on centos
+ # fix: Can't locate Archive/Tar.pm in @INC
+ 'perl': 'perl-core',
+ 'perl-FindBin': '',
+ 'rpcsvc-proto-devel': '',
+ 'glusterfs-api-devel': '',
+ 'glusterfs-devel': '',
+ 'libcephfs-devel': '',
+ 'gnutls-devel': 'compat-gnutls37-devel',
+ 'gnutls-utils': 'compat-gnutls37-utils',
+ 'liburing-devel': '', # not available
+ 'python3-setproctitle': 'python36-setproctitle',
+ 'tracker-devel': '', # do not install
+ 'mold': '',
+ 'ShellCheck': '',
+ 'shfmt': '',
+ 'codespell': '',
+ }
+ },
+ 'centos8s': {
+ 'docker_image': 'quay.io/centos/centos:stream8',
+ 'vagrant_box': 'centos/stream8',
+ 'bootstrap': CENTOS8S_YUM_BOOTSTRAP,
+ 'replace': {
+ 'lsb-release': 'redhat-lsb',
+ '@development-tools': '"@Development Tools"', # add quotes
+ 'lcov': '', # does not exist
+ 'perl-JSON-Parse': '', # does not exist?
+ 'perl-Test-Base': 'perl-Test-Simple',
+ 'perl-FindBin': '',
+ 'liburing-devel': '', # not available yet, Add me back, once available!
+ 'mold': '',
+ 'ShellCheck': '',
+ 'shfmt': '',
+ 'codespell': '',
+ }
+ },
+ 'fedora39': {
+ 'docker_image': 'quay.io/fedora/fedora:39',
+ 'vagrant_box': 'fedora/39-cloud-base',
+ 'bootstrap': DNF_BOOTSTRAP,
+ 'replace': {
+ 'lsb-release': 'redhat-lsb',
+ 'perl-FindBin': '',
+ 'python3-iso8601': 'python3-dateutil',
+ 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
+ }
+ },
+ 'opensuse155': {
+ 'docker_image': 'opensuse/leap:15.5',
+ 'vagrant_box': 'opensuse/openSUSE-15.5-x86_64',
+ 'bootstrap': ZYPPER_BOOTSTRAP,
+ 'replace': {
+ '@development-tools': '',
+ 'dbus-devel': 'dbus-1-devel',
+ 'docbook-style-xsl': 'docbook-xsl-stylesheets',
+ 'glibc-common': 'glibc-locale',
+ 'glibc-locale-source': 'glibc-i18ndata',
+ 'glibc-langpack-en': '',
+ 'jansson-devel': 'libjansson-devel',
+ 'keyutils-libs-devel': 'keyutils-devel',
+ 'krb5-workstation': 'krb5-client',
+ 'python3-libsemanage': 'python3-semanage',
+ 'openldap-devel': 'openldap2-devel',
+ 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper',
+ 'perl-JSON-Parse': 'perl-JSON-XS',
+ 'perl-generators': '',
+ 'perl-interpreter': '',
+ 'perl-FindBin': '',
+ 'procps-ng': 'procps',
+ 'python3-iso8601': 'python3-python-dateutil',
+ 'python3-dns': 'python3-dnspython',
+ 'python3-markdown': 'python3-Markdown',
+ 'quota-devel': '',
+ 'glusterfs-api-devel': '',
+ 'gnutls-utils': 'gnutls',
+ 'libtasn1-tools': '', # asn1Parser is part of libtasn1
+ 'mold': '',
+ 'shfmt': '',
+ 'yum-utils': '',
+ }
+ }
+}
+
+
+DEB_FAMILY = {
+ 'name': 'deb',
+ 'pkgs': DEB_PKGS,
+ 'bootstrap': APT_BOOTSTRAP, # family default
+ 'dists': DEB_DISTS,
+}
+
+
+RPM_FAMILY = {
+ 'name': 'rpm',
+ 'pkgs': RPM_PKGS,
+ 'bootstrap': YUM_BOOTSTRAP, # family default
+ 'dists': RPM_DISTS,
+}
+
+
+YML_HEADER = r"""
+---
+packages:
+"""
+
+
+def expand_family_dists(family):
+ dists = {}
+ for name, config in family['dists'].items():
+ config = config.copy()
+ config['name'] = name
+ config['home'] = join(OUT, name)
+ config['family'] = family['name']
+ config['GENERATED_MARKER'] = GENERATED_MARKER
+
+ # replace dist specific pkgs
+ replace = config.get('replace', {})
+ pkgs = []
+ for pkg in family['pkgs']:
+ pkg = replace.get(pkg, pkg) # replace if exists or get self
+ if pkg:
+ pkgs.append(pkg)
+ pkgs.sort()
+
+ lines = [' - {}'.format(pkg) for pkg in pkgs]
+ config['packages.yml'] = YML_HEADER.lstrip() + os.linesep.join(lines)
+
+ sep = ' \\' + os.linesep + ' '
+ config['pkgs'] = sep.join(pkgs)
+
+ # get dist bootstrap template or fall back to family default
+ bootstrap_template = config.get('bootstrap', family['bootstrap'])
+ config['bootstrap.sh'] = bootstrap_template.format(**config).strip()
+ config['locale.sh'] = LOCALE_SETUP.format(**config).strip()
+
+ config['Dockerfile'] = DOCKERFILE.format(**config).strip()
+ # keep the indent, no strip
+ config['vagrantfile_snippet'] = VAGRANTFILE_SNIPPET.format(**config)
+
+ dists[name] = config
+ return dists
+
+
+# expanded config for dists
+DEB_DISTS_EXP = expand_family_dists(DEB_FAMILY)
+RPM_DISTS_EXP = expand_family_dists(RPM_FAMILY)
+
+# assemble all together
+DISTS = {}
+DISTS.update(DEB_DISTS_EXP)
+DISTS.update(RPM_DISTS_EXP)
+
+
+def render_vagrantfile(dists):
+ """
+ Render all snippets for each dist into global Vagrantfile.
+
+ Vagrant supports multiple vms in one Vagrantfile.
+ This make it easier to manage the fleet, e.g:
+
+ start all: vagrant up
+ start one: vagrant up ubuntu1804
+
+ All other commands apply to above syntax, e.g.: status, destroy, provision
+ """
+ # sort dists by name and put all vagrantfile snippets together
+ snippets = [
+ dists[dist]['vagrantfile_snippet']
+ for dist in sorted(dists.keys())]
+
+ return VAGRANTFILE_GLOBAL.format(
+ vagrantfile_snippets=''.join(snippets),
+ GENERATED_MARKER=GENERATED_MARKER
+ )
+
+
+VAGRANTFILE = render_vagrantfile(DISTS)
+
+
+# data we need to expose
+__all__ = ['DISTS', 'VAGRANTFILE', 'OUT']
diff --git a/bootstrap/generated-dists/Vagrantfile b/bootstrap/generated-dists/Vagrantfile
new file mode 100644
index 0000000..2c6468d
--- /dev/null
+++ b/bootstrap/generated-dists/Vagrantfile
@@ -0,0 +1,98 @@
+
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+
+Vagrant.configure("2") do |config|
+ config.ssh.insert_key = false
+
+
+ config.vm.define "centos7" do |v|
+ v.vm.box = "centos/7"
+ v.vm.hostname = "centos7"
+ v.vm.provision :shell, path: "centos7/bootstrap.sh"
+ v.vm.provision :shell, path: "centos7/locale.sh"
+ end
+
+ config.vm.define "centos8s" do |v|
+ v.vm.box = "centos/stream8"
+ v.vm.hostname = "centos8s"
+ v.vm.provision :shell, path: "centos8s/bootstrap.sh"
+ v.vm.provision :shell, path: "centos8s/locale.sh"
+ end
+
+ config.vm.define "debian11" do |v|
+ v.vm.box = "debian/bullseye64"
+ v.vm.hostname = "debian11"
+ v.vm.provision :shell, path: "debian11/bootstrap.sh"
+ v.vm.provision :shell, path: "debian11/locale.sh"
+ end
+
+ config.vm.define "debian11-32bit" do |v|
+ v.vm.box = "debian/bullseye32"
+ v.vm.hostname = "debian11-32bit"
+ v.vm.provision :shell, path: "debian11-32bit/bootstrap.sh"
+ v.vm.provision :shell, path: "debian11-32bit/locale.sh"
+ end
+
+ config.vm.define "debian12" do |v|
+ v.vm.box = "debian/bookworm64"
+ v.vm.hostname = "debian12"
+ v.vm.provision :shell, path: "debian12/bootstrap.sh"
+ v.vm.provision :shell, path: "debian12/locale.sh"
+ end
+
+ config.vm.define "debian12-32bit" do |v|
+ v.vm.box = "debian/bookworm32"
+ v.vm.hostname = "debian12-32bit"
+ v.vm.provision :shell, path: "debian12-32bit/bootstrap.sh"
+ v.vm.provision :shell, path: "debian12-32bit/locale.sh"
+ end
+
+ config.vm.define "fedora39" do |v|
+ v.vm.box = "fedora/39-cloud-base"
+ v.vm.hostname = "fedora39"
+ v.vm.provision :shell, path: "fedora39/bootstrap.sh"
+ v.vm.provision :shell, path: "fedora39/locale.sh"
+ end
+
+ config.vm.define "opensuse155" do |v|
+ v.vm.box = "opensuse/openSUSE-15.5-x86_64"
+ v.vm.hostname = "opensuse155"
+ v.vm.provision :shell, path: "opensuse155/bootstrap.sh"
+ v.vm.provision :shell, path: "opensuse155/locale.sh"
+ end
+
+ config.vm.define "ubuntu1804" do |v|
+ v.vm.box = "ubuntu/bionic64"
+ v.vm.hostname = "ubuntu1804"
+ v.vm.provision :shell, path: "ubuntu1804/bootstrap.sh"
+ v.vm.provision :shell, path: "ubuntu1804/locale.sh"
+ end
+
+ config.vm.define "ubuntu1804-32bit" do |v|
+ v.vm.box = "ubuntu/bionic32"
+ v.vm.hostname = "ubuntu1804-32bit"
+ v.vm.provision :shell, path: "ubuntu1804-32bit/bootstrap.sh"
+ v.vm.provision :shell, path: "ubuntu1804-32bit/locale.sh"
+ end
+
+ config.vm.define "ubuntu2004" do |v|
+ v.vm.box = "ubuntu/focal64"
+ v.vm.hostname = "ubuntu2004"
+ v.vm.provision :shell, path: "ubuntu2004/bootstrap.sh"
+ v.vm.provision :shell, path: "ubuntu2004/locale.sh"
+ end
+
+ config.vm.define "ubuntu2204" do |v|
+ v.vm.box = "ubuntu/jammy64"
+ v.vm.hostname = "ubuntu2204"
+ v.vm.provision :shell, path: "ubuntu2204/bootstrap.sh"
+ v.vm.provision :shell, path: "ubuntu2204/locale.sh"
+ end
+
+
+end
diff --git a/bootstrap/generated-dists/centos7/Dockerfile b/bootstrap/generated-dists/centos7/Dockerfile
new file mode 100644
index 0000000..a11c4db
--- /dev/null
+++ b/bootstrap/generated-dists/centos7/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM centos:7
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos7/bootstrap.sh b/bootstrap/generated-dists/centos7/bootstrap.sh
new file mode 100755
index 0000000..fd86761
--- /dev/null
+++ b/bootstrap/generated-dists/centos7/bootstrap.sh
@@ -0,0 +1,120 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+yum update -y
+yum install -y epel-release
+yum install -y yum-plugin-copr
+yum copr enable -y sergiomb/SambaAD
+yum update -y
+
+yum install -y \
+ "@Development Tools" \
+ acl \
+ attr \
+ autoconf \
+ avahi-devel \
+ bind-utils \
+ binutils \
+ bison \
+ ccache \
+ chrpath \
+ compat-gnutls37-devel \
+ compat-gnutls37-utils \
+ crypto-policies-scripts \
+ cups-devel \
+ curl \
+ dbus-devel \
+ docbook-dtds \
+ docbook-style-xsl \
+ flex \
+ gawk \
+ gcc \
+ gdb \
+ git \
+ glib2-devel \
+ glibc-common \
+ gpgme-devel \
+ gzip \
+ hostname \
+ htop \
+ jansson-devel \
+ jq \
+ keyutils-libs-devel \
+ krb5-devel \
+ krb5-server \
+ krb5-workstation \
+ lcov \
+ libacl-devel \
+ libarchive-devel \
+ libattr-devel \
+ libblkid-devel \
+ libbsd-devel \
+ libcap-devel \
+ libicu-devel \
+ libpcap-devel \
+ libtasn1-devel \
+ libtasn1-tools \
+ libtirpc-devel \
+ libunwind-devel \
+ libuuid-devel \
+ libxslt \
+ lmdb \
+ lmdb-devel \
+ make \
+ mingw64-gcc \
+ ncurses-devel \
+ openldap-devel \
+ pam-devel \
+ patch \
+ perl-Archive-Tar \
+ perl-ExtUtils-MakeMaker \
+ perl-Parse-Yapp \
+ perl-Test-Base \
+ perl-core \
+ perl-generators \
+ perl-interpreter \
+ pkgconfig \
+ popt-devel \
+ procps-ng \
+ psmisc \
+ python3-libsemanage \
+ python3-policycoreutils \
+ python36 \
+ python36-cryptography \
+ python36-devel \
+ python36-dns \
+ python36-gpg \
+ python36-iso8601 \
+ python36-markdown \
+ python36-pyasn1 \
+ python36-requests \
+ python36-setproctitle \
+ quota-devel \
+ readline-devel \
+ redhat-lsb \
+ rng-tools \
+ rpcgen \
+ rsync \
+ sed \
+ sudo \
+ systemd-devel \
+ tar \
+ tree \
+ wget \
+ which \
+ xfsprogs-devel \
+ xz \
+ yum-utils \
+ zlib-devel
+
+yum clean all
+
+if [ ! -f /usr/bin/python3 ]; then
+ ln -sf /usr/bin/python3.6 /usr/bin/python3
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos7/locale.sh b/bootstrap/generated-dists/centos7/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/centos7/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos7/packages.yml b/bootstrap/generated-dists/centos7/packages.yml
new file mode 100644
index 0000000..2234baf
--- /dev/null
+++ b/bootstrap/generated-dists/centos7/packages.yml
@@ -0,0 +1,100 @@
+---
+packages:
+ - "@Development Tools"
+ - acl
+ - attr
+ - autoconf
+ - avahi-devel
+ - bind-utils
+ - binutils
+ - bison
+ - ccache
+ - chrpath
+ - compat-gnutls37-devel
+ - compat-gnutls37-utils
+ - crypto-policies-scripts
+ - cups-devel
+ - curl
+ - dbus-devel
+ - docbook-dtds
+ - docbook-style-xsl
+ - flex
+ - gawk
+ - gcc
+ - gdb
+ - git
+ - glib2-devel
+ - glibc-common
+ - gpgme-devel
+ - gzip
+ - hostname
+ - htop
+ - jansson-devel
+ - jq
+ - keyutils-libs-devel
+ - krb5-devel
+ - krb5-server
+ - krb5-workstation
+ - lcov
+ - libacl-devel
+ - libarchive-devel
+ - libattr-devel
+ - libblkid-devel
+ - libbsd-devel
+ - libcap-devel
+ - libicu-devel
+ - libpcap-devel
+ - libtasn1-devel
+ - libtasn1-tools
+ - libtirpc-devel
+ - libunwind-devel
+ - libuuid-devel
+ - libxslt
+ - lmdb
+ - lmdb-devel
+ - make
+ - mingw64-gcc
+ - ncurses-devel
+ - openldap-devel
+ - pam-devel
+ - patch
+ - perl-Archive-Tar
+ - perl-ExtUtils-MakeMaker
+ - perl-Parse-Yapp
+ - perl-Test-Base
+ - perl-core
+ - perl-generators
+ - perl-interpreter
+ - pkgconfig
+ - popt-devel
+ - procps-ng
+ - psmisc
+ - python3-libsemanage
+ - python3-policycoreutils
+ - python36
+ - python36-cryptography
+ - python36-devel
+ - python36-dns
+ - python36-gpg
+ - python36-iso8601
+ - python36-markdown
+ - python36-pyasn1
+ - python36-requests
+ - python36-setproctitle
+ - quota-devel
+ - readline-devel
+ - redhat-lsb
+ - rng-tools
+ - rpcgen
+ - rsync
+ - sed
+ - sudo
+ - systemd-devel
+ - tar
+ - tree
+ - wget
+ - which
+ - xfsprogs-devel
+ - xz
+ - yum-utils
+ - zlib-devel \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos8s/Dockerfile b/bootstrap/generated-dists/centos8s/Dockerfile
new file mode 100644
index 0000000..3b5a681
--- /dev/null
+++ b/bootstrap/generated-dists/centos8s/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM quay.io/centos/centos:stream8
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos8s/bootstrap.sh b/bootstrap/generated-dists/centos8s/bootstrap.sh
new file mode 100755
index 0000000..4b2c62c
--- /dev/null
+++ b/bootstrap/generated-dists/centos8s/bootstrap.sh
@@ -0,0 +1,125 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+yum update -y
+yum install -y dnf-plugins-core
+yum install -y epel-release
+
+yum -v repolist all
+yum config-manager --set-enabled powertools -y
+
+yum update -y
+
+yum install -y \
+ --setopt=install_weak_deps=False \
+ "@Development Tools" \
+ acl \
+ attr \
+ autoconf \
+ avahi-devel \
+ bind-utils \
+ binutils \
+ bison \
+ ccache \
+ chrpath \
+ crypto-policies-scripts \
+ cups-devel \
+ curl \
+ dbus-devel \
+ docbook-dtds \
+ docbook-style-xsl \
+ flex \
+ gawk \
+ gcc \
+ gdb \
+ git \
+ glib2-devel \
+ glibc-common \
+ glibc-langpack-en \
+ glusterfs-api-devel \
+ glusterfs-devel \
+ gnutls-devel \
+ gnutls-utils \
+ gpgme-devel \
+ gzip \
+ hostname \
+ htop \
+ jansson-devel \
+ jq \
+ keyutils-libs-devel \
+ krb5-devel \
+ krb5-server \
+ krb5-workstation \
+ libacl-devel \
+ libarchive-devel \
+ libattr-devel \
+ libblkid-devel \
+ libbsd-devel \
+ libcap-devel \
+ libcephfs-devel \
+ libicu-devel \
+ libpcap-devel \
+ libtasn1-devel \
+ libtasn1-tools \
+ libtirpc-devel \
+ libunwind-devel \
+ libuuid-devel \
+ libxslt \
+ lmdb \
+ lmdb-devel \
+ make \
+ mingw64-gcc \
+ ncurses-devel \
+ openldap-devel \
+ pam-devel \
+ patch \
+ perl \
+ perl-Archive-Tar \
+ perl-ExtUtils-MakeMaker \
+ perl-Parse-Yapp \
+ perl-Test-Simple \
+ perl-generators \
+ perl-interpreter \
+ pkgconfig \
+ popt-devel \
+ procps-ng \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-devel \
+ python3-dns \
+ python3-gpg \
+ python3-iso8601 \
+ python3-libsemanage \
+ python3-markdown \
+ python3-policycoreutils \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ quota-devel \
+ readline-devel \
+ redhat-lsb \
+ rng-tools \
+ rpcgen \
+ rpcsvc-proto-devel \
+ rsync \
+ sed \
+ sudo \
+ systemd-devel \
+ tar \
+ tracker-devel \
+ tree \
+ wget \
+ which \
+ xfsprogs-devel \
+ xz \
+ yum-utils \
+ zlib-devel
+
+yum clean all \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos8s/locale.sh b/bootstrap/generated-dists/centos8s/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/centos8s/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/centos8s/packages.yml b/bootstrap/generated-dists/centos8s/packages.yml
new file mode 100644
index 0000000..f416dea
--- /dev/null
+++ b/bootstrap/generated-dists/centos8s/packages.yml
@@ -0,0 +1,105 @@
+---
+packages:
+ - "@Development Tools"
+ - acl
+ - attr
+ - autoconf
+ - avahi-devel
+ - bind-utils
+ - binutils
+ - bison
+ - ccache
+ - chrpath
+ - crypto-policies-scripts
+ - cups-devel
+ - curl
+ - dbus-devel
+ - docbook-dtds
+ - docbook-style-xsl
+ - flex
+ - gawk
+ - gcc
+ - gdb
+ - git
+ - glib2-devel
+ - glibc-common
+ - glibc-langpack-en
+ - glusterfs-api-devel
+ - glusterfs-devel
+ - gnutls-devel
+ - gnutls-utils
+ - gpgme-devel
+ - gzip
+ - hostname
+ - htop
+ - jansson-devel
+ - jq
+ - keyutils-libs-devel
+ - krb5-devel
+ - krb5-server
+ - krb5-workstation
+ - libacl-devel
+ - libarchive-devel
+ - libattr-devel
+ - libblkid-devel
+ - libbsd-devel
+ - libcap-devel
+ - libcephfs-devel
+ - libicu-devel
+ - libpcap-devel
+ - libtasn1-devel
+ - libtasn1-tools
+ - libtirpc-devel
+ - libunwind-devel
+ - libuuid-devel
+ - libxslt
+ - lmdb
+ - lmdb-devel
+ - make
+ - mingw64-gcc
+ - ncurses-devel
+ - openldap-devel
+ - pam-devel
+ - patch
+ - perl
+ - perl-Archive-Tar
+ - perl-ExtUtils-MakeMaker
+ - perl-Parse-Yapp
+ - perl-Test-Simple
+ - perl-generators
+ - perl-interpreter
+ - pkgconfig
+ - popt-devel
+ - procps-ng
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-devel
+ - python3-dns
+ - python3-gpg
+ - python3-iso8601
+ - python3-libsemanage
+ - python3-markdown
+ - python3-policycoreutils
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - quota-devel
+ - readline-devel
+ - redhat-lsb
+ - rng-tools
+ - rpcgen
+ - rpcsvc-proto-devel
+ - rsync
+ - sed
+ - sudo
+ - systemd-devel
+ - tar
+ - tracker-devel
+ - tree
+ - wget
+ - which
+ - xfsprogs-devel
+ - xz
+ - yum-utils
+ - zlib-devel \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11-32bit/Dockerfile b/bootstrap/generated-dists/debian11-32bit/Dockerfile
new file mode 100644
index 0000000..d0133bd
--- /dev/null
+++ b/bootstrap/generated-dists/debian11-32bit/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM registry-1.docker.io/i386/debian:11
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11-32bit/bootstrap.sh b/bootstrap/generated-dists/debian11-32bit/bootstrap.sh
new file mode 100755
index 0000000..82d2705
--- /dev/null
+++ b/bootstrap/generated-dists/debian11-32bit/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libtracker-sparql-2.0-dev \
+ libunwind-dev \
+ liburing-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11-32bit/locale.sh b/bootstrap/generated-dists/debian11-32bit/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/debian11-32bit/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11-32bit/packages.yml b/bootstrap/generated-dists/debian11-32bit/packages.yml
new file mode 100644
index 0000000..dab6a93
--- /dev/null
+++ b/bootstrap/generated-dists/debian11-32bit/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libtracker-sparql-2.0-dev
+ - libunwind-dev
+ - liburing-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11/Dockerfile b/bootstrap/generated-dists/debian11/Dockerfile
new file mode 100644
index 0000000..90a961f
--- /dev/null
+++ b/bootstrap/generated-dists/debian11/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM debian:11
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11/bootstrap.sh b/bootstrap/generated-dists/debian11/bootstrap.sh
new file mode 100755
index 0000000..82d2705
--- /dev/null
+++ b/bootstrap/generated-dists/debian11/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libtracker-sparql-2.0-dev \
+ libunwind-dev \
+ liburing-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11/locale.sh b/bootstrap/generated-dists/debian11/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/debian11/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian11/packages.yml b/bootstrap/generated-dists/debian11/packages.yml
new file mode 100644
index 0000000..dab6a93
--- /dev/null
+++ b/bootstrap/generated-dists/debian11/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libtracker-sparql-2.0-dev
+ - libunwind-dev
+ - liburing-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12-32bit/Dockerfile b/bootstrap/generated-dists/debian12-32bit/Dockerfile
new file mode 100644
index 0000000..fc72e14
--- /dev/null
+++ b/bootstrap/generated-dists/debian12-32bit/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM registry-1.docker.io/i386/debian:12
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12-32bit/bootstrap.sh b/bootstrap/generated-dists/debian12-32bit/bootstrap.sh
new file mode 100755
index 0000000..033061a
--- /dev/null
+++ b/bootstrap/generated-dists/debian12-32bit/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libunwind-dev \
+ liburing-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ shfmt \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12-32bit/locale.sh b/bootstrap/generated-dists/debian12-32bit/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/debian12-32bit/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12-32bit/packages.yml b/bootstrap/generated-dists/debian12-32bit/packages.yml
new file mode 100644
index 0000000..bd9a558
--- /dev/null
+++ b/bootstrap/generated-dists/debian12-32bit/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libunwind-dev
+ - liburing-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - shfmt
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12/Dockerfile b/bootstrap/generated-dists/debian12/Dockerfile
new file mode 100644
index 0000000..2b0e140
--- /dev/null
+++ b/bootstrap/generated-dists/debian12/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM debian:12
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12/bootstrap.sh b/bootstrap/generated-dists/debian12/bootstrap.sh
new file mode 100755
index 0000000..033061a
--- /dev/null
+++ b/bootstrap/generated-dists/debian12/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libunwind-dev \
+ liburing-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ shfmt \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12/locale.sh b/bootstrap/generated-dists/debian12/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/debian12/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/debian12/packages.yml b/bootstrap/generated-dists/debian12/packages.yml
new file mode 100644
index 0000000..bd9a558
--- /dev/null
+++ b/bootstrap/generated-dists/debian12/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libunwind-dev
+ - liburing-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - shfmt
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/fedora39/Dockerfile b/bootstrap/generated-dists/fedora39/Dockerfile
new file mode 100644
index 0000000..144dc8e
--- /dev/null
+++ b/bootstrap/generated-dists/fedora39/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM quay.io/fedora/fedora:39
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/fedora39/bootstrap.sh b/bootstrap/generated-dists/fedora39/bootstrap.sh
new file mode 100755
index 0000000..e3b3646
--- /dev/null
+++ b/bootstrap/generated-dists/fedora39/bootstrap.sh
@@ -0,0 +1,126 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+dnf update -y
+
+dnf install -y \
+ --setopt=install_weak_deps=False \
+ @development-tools \
+ ShellCheck \
+ acl \
+ attr \
+ autoconf \
+ avahi-devel \
+ bind-utils \
+ binutils \
+ bison \
+ ccache \
+ chrpath \
+ codespell \
+ crypto-policies-scripts \
+ cups-devel \
+ curl \
+ dbus-devel \
+ docbook-dtds \
+ docbook-style-xsl \
+ flex \
+ gawk \
+ gcc \
+ gdb \
+ git \
+ glib2-devel \
+ glibc-common \
+ glibc-langpack-en \
+ glusterfs-api-devel \
+ glusterfs-devel \
+ gnutls-devel \
+ gnutls-utils \
+ gpgme-devel \
+ gzip \
+ hostname \
+ htop \
+ jansson-devel \
+ jq \
+ keyutils-libs-devel \
+ krb5-devel \
+ krb5-server \
+ krb5-workstation \
+ lcov \
+ libacl-devel \
+ libarchive-devel \
+ libattr-devel \
+ libblkid-devel \
+ libbsd-devel \
+ libcap-devel \
+ libcephfs-devel \
+ libicu-devel \
+ libpcap-devel \
+ libtasn1-devel \
+ libtasn1-tools \
+ libtirpc-devel \
+ libunwind-devel \
+ liburing-devel \
+ libuuid-devel \
+ libxslt \
+ lmdb \
+ lmdb-devel \
+ make \
+ mingw64-gcc \
+ mold \
+ ncurses-devel \
+ openldap-devel \
+ pam-devel \
+ patch \
+ perl \
+ perl-Archive-Tar \
+ perl-ExtUtils-MakeMaker \
+ perl-Parse-Yapp \
+ perl-Test-Base \
+ perl-generators \
+ perl-interpreter \
+ pkgconfig \
+ popt-devel \
+ procps-ng \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dateutil \
+ python3-devel \
+ python3-dns \
+ python3-gpg \
+ python3-libsemanage \
+ python3-markdown \
+ python3-policycoreutils \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ quota-devel \
+ readline-devel \
+ redhat-lsb \
+ rng-tools \
+ rpcgen \
+ rpcsvc-proto-devel \
+ rsync \
+ sed \
+ shfmt \
+ sudo \
+ systemd-devel \
+ tar \
+ tracker-devel \
+ tree \
+ wget \
+ which \
+ xfsprogs-devel \
+ xz \
+ yum-utils \
+ zlib-devel
+
+dnf clean all
+
+update-crypto-policies --set DEFAULT:AD-SUPPORT \ No newline at end of file
diff --git a/bootstrap/generated-dists/fedora39/locale.sh b/bootstrap/generated-dists/fedora39/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/fedora39/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/fedora39/packages.yml b/bootstrap/generated-dists/fedora39/packages.yml
new file mode 100644
index 0000000..1fbe398
--- /dev/null
+++ b/bootstrap/generated-dists/fedora39/packages.yml
@@ -0,0 +1,111 @@
+---
+packages:
+ - @development-tools
+ - ShellCheck
+ - acl
+ - attr
+ - autoconf
+ - avahi-devel
+ - bind-utils
+ - binutils
+ - bison
+ - ccache
+ - chrpath
+ - codespell
+ - crypto-policies-scripts
+ - cups-devel
+ - curl
+ - dbus-devel
+ - docbook-dtds
+ - docbook-style-xsl
+ - flex
+ - gawk
+ - gcc
+ - gdb
+ - git
+ - glib2-devel
+ - glibc-common
+ - glibc-langpack-en
+ - glusterfs-api-devel
+ - glusterfs-devel
+ - gnutls-devel
+ - gnutls-utils
+ - gpgme-devel
+ - gzip
+ - hostname
+ - htop
+ - jansson-devel
+ - jq
+ - keyutils-libs-devel
+ - krb5-devel
+ - krb5-server
+ - krb5-workstation
+ - lcov
+ - libacl-devel
+ - libarchive-devel
+ - libattr-devel
+ - libblkid-devel
+ - libbsd-devel
+ - libcap-devel
+ - libcephfs-devel
+ - libicu-devel
+ - libpcap-devel
+ - libtasn1-devel
+ - libtasn1-tools
+ - libtirpc-devel
+ - libunwind-devel
+ - liburing-devel
+ - libuuid-devel
+ - libxslt
+ - lmdb
+ - lmdb-devel
+ - make
+ - mingw64-gcc
+ - mold
+ - ncurses-devel
+ - openldap-devel
+ - pam-devel
+ - patch
+ - perl
+ - perl-Archive-Tar
+ - perl-ExtUtils-MakeMaker
+ - perl-Parse-Yapp
+ - perl-Test-Base
+ - perl-generators
+ - perl-interpreter
+ - pkgconfig
+ - popt-devel
+ - procps-ng
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dateutil
+ - python3-devel
+ - python3-dns
+ - python3-gpg
+ - python3-libsemanage
+ - python3-markdown
+ - python3-policycoreutils
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - quota-devel
+ - readline-devel
+ - redhat-lsb
+ - rng-tools
+ - rpcgen
+ - rpcsvc-proto-devel
+ - rsync
+ - sed
+ - shfmt
+ - sudo
+ - systemd-devel
+ - tar
+ - tracker-devel
+ - tree
+ - wget
+ - which
+ - xfsprogs-devel
+ - xz
+ - yum-utils
+ - zlib-devel \ No newline at end of file
diff --git a/bootstrap/generated-dists/opensuse155/Dockerfile b/bootstrap/generated-dists/opensuse155/Dockerfile
new file mode 100644
index 0000000..d2429f1
--- /dev/null
+++ b/bootstrap/generated-dists/opensuse155/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM opensuse/leap:15.5
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/opensuse155/bootstrap.sh b/bootstrap/generated-dists/opensuse155/bootstrap.sh
new file mode 100755
index 0000000..45d11ef
--- /dev/null
+++ b/bootstrap/generated-dists/opensuse155/bootstrap.sh
@@ -0,0 +1,119 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+zypper --non-interactive refresh
+zypper --non-interactive update
+zypper --non-interactive install \
+ --no-recommends \
+ system-user-nobody \
+ ShellCheck \
+ acl \
+ attr \
+ autoconf \
+ avahi-devel \
+ bind-utils \
+ binutils \
+ bison \
+ ccache \
+ chrpath \
+ codespell \
+ crypto-policies-scripts \
+ cups-devel \
+ curl \
+ dbus-1-devel \
+ docbook-dtds \
+ docbook-xsl-stylesheets \
+ flex \
+ gawk \
+ gcc \
+ gdb \
+ git \
+ glib2-devel \
+ glibc-locale \
+ glusterfs-devel \
+ gnutls \
+ gnutls-devel \
+ gpgme-devel \
+ gzip \
+ hostname \
+ htop \
+ jq \
+ keyutils-devel \
+ krb5-client \
+ krb5-devel \
+ krb5-server \
+ lcov \
+ libacl-devel \
+ libarchive-devel \
+ libattr-devel \
+ libblkid-devel \
+ libbsd-devel \
+ libcap-devel \
+ libcephfs-devel \
+ libicu-devel \
+ libjansson-devel \
+ libpcap-devel \
+ libtasn1-devel \
+ libtirpc-devel \
+ libunwind-devel \
+ liburing-devel \
+ libuuid-devel \
+ libxslt \
+ lmdb \
+ lmdb-devel \
+ lsb-release \
+ make \
+ mingw64-gcc \
+ ncurses-devel \
+ openldap2-devel \
+ pam-devel \
+ patch \
+ perl \
+ perl-Archive-Tar-Wrapper \
+ perl-ExtUtils-MakeMaker \
+ perl-Parse-Yapp \
+ perl-Test-Base \
+ pkgconfig \
+ popt-devel \
+ procps \
+ psmisc \
+ python3 \
+ python3-Markdown \
+ python3-cryptography \
+ python3-devel \
+ python3-dnspython \
+ python3-gpg \
+ python3-policycoreutils \
+ python3-pyasn1 \
+ python3-python-dateutil \
+ python3-requests \
+ python3-semanage \
+ python3-setproctitle \
+ readline-devel \
+ rng-tools \
+ rpcgen \
+ rpcsvc-proto-devel \
+ rsync \
+ sed \
+ sudo \
+ systemd-devel \
+ tar \
+ tracker-devel \
+ tree \
+ wget \
+ which \
+ xfsprogs-devel \
+ xz \
+ zlib-devel
+
+zypper --non-interactive clean
+
+if [ -f /usr/lib/mit/bin/krb5-config ]; then
+ ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/opensuse155/locale.sh b/bootstrap/generated-dists/opensuse155/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/opensuse155/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/opensuse155/packages.yml b/bootstrap/generated-dists/opensuse155/packages.yml
new file mode 100644
index 0000000..519b62c
--- /dev/null
+++ b/bootstrap/generated-dists/opensuse155/packages.yml
@@ -0,0 +1,101 @@
+---
+packages:
+ - ShellCheck
+ - acl
+ - attr
+ - autoconf
+ - avahi-devel
+ - bind-utils
+ - binutils
+ - bison
+ - ccache
+ - chrpath
+ - codespell
+ - crypto-policies-scripts
+ - cups-devel
+ - curl
+ - dbus-1-devel
+ - docbook-dtds
+ - docbook-xsl-stylesheets
+ - flex
+ - gawk
+ - gcc
+ - gdb
+ - git
+ - glib2-devel
+ - glibc-locale
+ - glusterfs-devel
+ - gnutls
+ - gnutls-devel
+ - gpgme-devel
+ - gzip
+ - hostname
+ - htop
+ - jq
+ - keyutils-devel
+ - krb5-client
+ - krb5-devel
+ - krb5-server
+ - lcov
+ - libacl-devel
+ - libarchive-devel
+ - libattr-devel
+ - libblkid-devel
+ - libbsd-devel
+ - libcap-devel
+ - libcephfs-devel
+ - libicu-devel
+ - libjansson-devel
+ - libpcap-devel
+ - libtasn1-devel
+ - libtirpc-devel
+ - libunwind-devel
+ - liburing-devel
+ - libuuid-devel
+ - libxslt
+ - lmdb
+ - lmdb-devel
+ - lsb-release
+ - make
+ - mingw64-gcc
+ - ncurses-devel
+ - openldap2-devel
+ - pam-devel
+ - patch
+ - perl
+ - perl-Archive-Tar-Wrapper
+ - perl-ExtUtils-MakeMaker
+ - perl-Parse-Yapp
+ - perl-Test-Base
+ - pkgconfig
+ - popt-devel
+ - procps
+ - psmisc
+ - python3
+ - python3-Markdown
+ - python3-cryptography
+ - python3-devel
+ - python3-dnspython
+ - python3-gpg
+ - python3-policycoreutils
+ - python3-pyasn1
+ - python3-python-dateutil
+ - python3-requests
+ - python3-semanage
+ - python3-setproctitle
+ - readline-devel
+ - rng-tools
+ - rpcgen
+ - rpcsvc-proto-devel
+ - rsync
+ - sed
+ - sudo
+ - systemd-devel
+ - tar
+ - tracker-devel
+ - tree
+ - wget
+ - which
+ - xfsprogs-devel
+ - xz
+ - zlib-devel \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804-32bit/Dockerfile b/bootstrap/generated-dists/ubuntu1804-32bit/Dockerfile
new file mode 100644
index 0000000..4feffbd
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804-32bit/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM registry-1.docker.io/i386/ubuntu:18.04
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804-32bit/bootstrap.sh b/bootstrap/generated-dists/ubuntu1804-32bit/bootstrap.sh
new file mode 100755
index 0000000..da249a8
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804-32bit/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ language-pack-en \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libtracker-sparql-2.0-dev \
+ libunwind-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804-32bit/locale.sh b/bootstrap/generated-dists/ubuntu1804-32bit/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804-32bit/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804-32bit/packages.yml b/bootstrap/generated-dists/ubuntu1804-32bit/packages.yml
new file mode 100644
index 0000000..94957fc
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804-32bit/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - language-pack-en
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libtracker-sparql-2.0-dev
+ - libunwind-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804/Dockerfile b/bootstrap/generated-dists/ubuntu1804/Dockerfile
new file mode 100644
index 0000000..f389e0b
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM ubuntu:18.04
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804/bootstrap.sh b/bootstrap/generated-dists/ubuntu1804/bootstrap.sh
new file mode 100755
index 0000000..da249a8
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ language-pack-en \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libtracker-sparql-2.0-dev \
+ libunwind-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804/locale.sh b/bootstrap/generated-dists/ubuntu1804/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu1804/packages.yml b/bootstrap/generated-dists/ubuntu1804/packages.yml
new file mode 100644
index 0000000..94957fc
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu1804/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - language-pack-en
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libtracker-sparql-2.0-dev
+ - libunwind-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2004/Dockerfile b/bootstrap/generated-dists/ubuntu2004/Dockerfile
new file mode 100644
index 0000000..b77adb7
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2004/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM ubuntu:20.04
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2004/bootstrap.sh b/bootstrap/generated-dists/ubuntu2004/bootstrap.sh
new file mode 100755
index 0000000..da249a8
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2004/bootstrap.sh
@@ -0,0 +1,117 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ language-pack-en \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libtracker-sparql-2.0-dev \
+ libunwind-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2004/locale.sh b/bootstrap/generated-dists/ubuntu2004/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2004/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2004/packages.yml b/bootstrap/generated-dists/ubuntu2004/packages.yml
new file mode 100644
index 0000000..94957fc
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2004/packages.yml
@@ -0,0 +1,102 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - language-pack-en
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libtracker-sparql-2.0-dev
+ - libunwind-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2204/Dockerfile b/bootstrap/generated-dists/ubuntu2204/Dockerfile
new file mode 100644
index 0000000..0b73aac
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2204/Dockerfile
@@ -0,0 +1,29 @@
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+FROM ubuntu:22.04
+
+# pass in with --build-arg while build
+ARG SHA1SUM
+RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
+
+ADD *.sh /tmp/
+# need root permission, do it before USER samba
+RUN /tmp/bootstrap.sh && /tmp/locale.sh
+
+# if ld.gold exists, force link it to ld
+RUN set -x; ! LD_GOLD=$(which ld.gold) || { LD=$(which ld) && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"; }
+# if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
+RUN set -x; ! LD_MOLD=$(which ld.mold) || { LD=$(which ld) && ln -sf $LD_MOLD $LD && test -x $LD && echo "$LD is now $LD_MOLD"; }
+
+# make test can not work with root, so we have to create a new user
+RUN useradd -m -U -s /bin/bash samba && \
+ mkdir -p /etc/sudoers.d && \
+ echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
+
+USER samba
+WORKDIR /home/samba
+# samba tests rely on this
+ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2204/bootstrap.sh b/bootstrap/generated-dists/ubuntu2204/bootstrap.sh
new file mode 100755
index 0000000..1a3c3b1
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2204/bootstrap.sh
@@ -0,0 +1,118 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+export DEBIAN_FRONTEND=noninteractive
+apt-get -y update
+
+apt-get -y install \
+ acl \
+ apt-utils \
+ attr \
+ autoconf \
+ bind9utils \
+ binutils \
+ bison \
+ build-essential \
+ ccache \
+ chrpath \
+ codespell \
+ curl \
+ debhelper \
+ dnsutils \
+ docbook-xml \
+ docbook-xsl \
+ flex \
+ gcc \
+ gdb \
+ git \
+ glusterfs-common \
+ gnutls-bin \
+ gzip \
+ heimdal-multidev \
+ hostname \
+ htop \
+ jq \
+ krb5-config \
+ krb5-kdc \
+ krb5-user \
+ language-pack-en \
+ lcov \
+ libacl1-dev \
+ libarchive-dev \
+ libattr1-dev \
+ libavahi-common-dev \
+ libblkid-dev \
+ libbsd-dev \
+ libcap-dev \
+ libcephfs-dev \
+ libcups2-dev \
+ libdbus-1-dev \
+ libglib2.0-dev \
+ libgnutls28-dev \
+ libgpgme11-dev \
+ libicu-dev \
+ libjansson-dev \
+ libjs-jquery \
+ libkeyutils-dev \
+ libkrb5-dev \
+ libldap2-dev \
+ liblmdb-dev \
+ libncurses5-dev \
+ libpam0g-dev \
+ libparse-yapp-perl \
+ libpcap-dev \
+ libpopt-dev \
+ libreadline-dev \
+ libsystemd-dev \
+ libtasn1-bin \
+ libtasn1-dev \
+ libunwind-dev \
+ liburing-dev \
+ lmdb-utils \
+ locales \
+ lsb-release \
+ make \
+ mawk \
+ mingw-w64 \
+ patch \
+ perl \
+ perl-modules \
+ pkg-config \
+ procps \
+ psmisc \
+ python3 \
+ python3-cryptography \
+ python3-dbg \
+ python3-dev \
+ python3-dnspython \
+ python3-gpg \
+ python3-iso8601 \
+ python3-markdown \
+ python3-pexpect \
+ python3-pyasn1 \
+ python3-requests \
+ python3-setproctitle \
+ rng-tools \
+ rsync \
+ sed \
+ shellcheck \
+ shfmt \
+ sudo \
+ tar \
+ tree \
+ uuid-dev \
+ wget \
+ xfslibs-dev \
+ xsltproc \
+ xz-utils \
+ zlib1g-dev
+
+apt-get -y autoremove
+apt-get -y autoclean
+apt-get -y clean \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2204/locale.sh b/bootstrap/generated-dists/ubuntu2204/locale.sh
new file mode 100755
index 0000000..cc64e18
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2204/locale.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+#
+# This file is generated by 'bootstrap/template.py --render'
+# See also bootstrap/config.py
+#
+
+set -xueo pipefail
+
+# refer to /usr/share/i18n/locales
+INPUTFILE=en_US
+# refer to /usr/share/i18n/charmaps
+CHARMAP=UTF-8
+# locale to generate in /usr/lib/locale
+# glibc/localedef will normalize UTF-8 to utf8, follow the naming style
+LOCALE=$INPUTFILE.utf8
+
+# if locale is already correct, exit
+( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
+
+# if locale not available, generate locale into /usr/lib/locale
+if ! ( locale --all-locales | grep -i $LOCALE )
+then
+ # no-archive means create its own dir
+ localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
+fi
+
+# update locale conf and global env file
+# set both LC_ALL and LANG for safe
+
+# update conf for Debian family
+FILE=/etc/default/locale
+if [ -f $FILE ]
+then
+ echo LC_ALL="$LOCALE" > $FILE
+ echo LANG="$LOCALE" >> $FILE
+fi
+
+# update conf for RedHat family
+FILE=/etc/locale.conf
+if [ -f $FILE ]
+then
+ # LC_ALL is not valid in this file, set LANG only
+ echo LANG="$LOCALE" > $FILE
+fi
+
+# update global env file
+FILE=/etc/environment
+if [ -f $FILE ]
+then
+ # append LC_ALL if not exist
+ grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
+ # append LANG if not exist
+ grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
+fi \ No newline at end of file
diff --git a/bootstrap/generated-dists/ubuntu2204/packages.yml b/bootstrap/generated-dists/ubuntu2204/packages.yml
new file mode 100644
index 0000000..c3b741f
--- /dev/null
+++ b/bootstrap/generated-dists/ubuntu2204/packages.yml
@@ -0,0 +1,103 @@
+---
+packages:
+ - acl
+ - apt-utils
+ - attr
+ - autoconf
+ - bind9utils
+ - binutils
+ - bison
+ - build-essential
+ - ccache
+ - chrpath
+ - codespell
+ - curl
+ - debhelper
+ - dnsutils
+ - docbook-xml
+ - docbook-xsl
+ - flex
+ - gcc
+ - gdb
+ - git
+ - glusterfs-common
+ - gnutls-bin
+ - gzip
+ - heimdal-multidev
+ - hostname
+ - htop
+ - jq
+ - krb5-config
+ - krb5-kdc
+ - krb5-user
+ - language-pack-en
+ - lcov
+ - libacl1-dev
+ - libarchive-dev
+ - libattr1-dev
+ - libavahi-common-dev
+ - libblkid-dev
+ - libbsd-dev
+ - libcap-dev
+ - libcephfs-dev
+ - libcups2-dev
+ - libdbus-1-dev
+ - libglib2.0-dev
+ - libgnutls28-dev
+ - libgpgme11-dev
+ - libicu-dev
+ - libjansson-dev
+ - libjs-jquery
+ - libkeyutils-dev
+ - libkrb5-dev
+ - libldap2-dev
+ - liblmdb-dev
+ - libncurses5-dev
+ - libpam0g-dev
+ - libparse-yapp-perl
+ - libpcap-dev
+ - libpopt-dev
+ - libreadline-dev
+ - libsystemd-dev
+ - libtasn1-bin
+ - libtasn1-dev
+ - libunwind-dev
+ - liburing-dev
+ - lmdb-utils
+ - locales
+ - lsb-release
+ - make
+ - mawk
+ - mingw-w64
+ - patch
+ - perl
+ - perl-modules
+ - pkg-config
+ - procps
+ - psmisc
+ - python3
+ - python3-cryptography
+ - python3-dbg
+ - python3-dev
+ - python3-dnspython
+ - python3-gpg
+ - python3-iso8601
+ - python3-markdown
+ - python3-pexpect
+ - python3-pyasn1
+ - python3-requests
+ - python3-setproctitle
+ - rng-tools
+ - rsync
+ - sed
+ - shellcheck
+ - shfmt
+ - sudo
+ - tar
+ - tree
+ - uuid-dev
+ - wget
+ - xfslibs-dev
+ - xsltproc
+ - xz-utils
+ - zlib1g-dev \ No newline at end of file
diff --git a/bootstrap/sha1sum.txt b/bootstrap/sha1sum.txt
new file mode 100644
index 0000000..61ecaf0
--- /dev/null
+++ b/bootstrap/sha1sum.txt
@@ -0,0 +1 @@
+9a406973474a7903fe7fd6215226660911ed73c0
diff --git a/bootstrap/template.py b/bootstrap/template.py
new file mode 100755
index 0000000..0acfaa2
--- /dev/null
+++ b/bootstrap/template.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+
+# Copyright (C) Catalyst.Net Ltd 2019
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""
+Manage dependencies and bootstrap environments for Samba.
+
+CLI script to render bootstrap.sh/Dockerfile/Vagrantfile.
+
+Author: Joe Guo <joeg@catalyst.net.nz>
+"""
+
+import io
+import os
+import hashlib
+import logging
+import argparse
+from config import DISTS, VAGRANTFILE, OUT
+
+HERE = os.path.abspath(os.path.dirname(__file__))
+SHA1SUM_FILE_PATH = os.path.join(HERE, 'sha1sum.txt')
+README_FILE_PATH = os.path.join(HERE, 'README.md')
+
+logging.basicConfig(level='INFO')
+log = logging.getLogger(__file__)
+
+
+def get_files(path):
+ """Get all files recursively in path as a list"""
+ filepaths = []
+ for root, dirnames, filenames in os.walk(path):
+ for filename in filenames:
+ filepath = os.path.join(root, filename)
+ filepaths.append(filepath)
+ return filepaths
+
+
+def get_sha1sum(debug=False):
+ """Get sha1sum for dists + .gitlab-ci.yml"""
+ filepaths = get_files(HERE)
+ m = hashlib.sha1()
+ i = 0
+ for filepath in sorted(list(filepaths)):
+ _filepath = os.path.relpath(filepath)
+ i += 1
+ if filepath == SHA1SUM_FILE_PATH:
+ d = "skip "
+ if debug:
+ print("%s: %s: %s" % (i, d, _filepath))
+ continue
+ if filepath == README_FILE_PATH:
+ d = "skip "
+ if debug:
+ print("%s: %s: %s" % (i, d, _filepath))
+ continue
+ if filepath.endswith('.pyc'):
+ d = "skip "
+ if debug:
+ print("%s: %s: %s" % (i, d, _filepath))
+ continue
+ with io.open(filepath, mode='rb') as _file:
+ _bytes = _file.read()
+
+ m1 = hashlib.sha1()
+ m1.update(_bytes)
+ d = m1.hexdigest()
+ if debug:
+ print("%s: %s: %s" % (i, d, _filepath))
+
+ m.update(_bytes)
+ return m.hexdigest()
+
+
+def render(dists):
+ """Render files for all dists"""
+ for dist, config in dists.items():
+ home = config['home']
+ os.makedirs(home, exist_ok=True)
+ for key in ['bootstrap.sh', 'locale.sh', 'packages.yml', 'Dockerfile']:
+ path = os.path.join(home, key)
+ log.info('%s: render "%s" to %s', dist, key, path)
+ with io.open(path, mode='wt', encoding='utf8') as fp:
+ fp.write(config[key])
+ if path.endswith('.sh'):
+ os.chmod(path, 0o755)
+
+ key = 'Vagrantfile'
+ path = os.path.join(OUT, key)
+ log.info('%s: render "%s" to %s', dist, key, path)
+ with io.open(path, mode='wt', encoding='utf8') as fp:
+ fp.write(VAGRANTFILE)
+
+ # always calc sha1sum after render
+ sha1sum = get_sha1sum()
+ log.info('write sha1sum to %s: %s', SHA1SUM_FILE_PATH, sha1sum)
+ with io.open(SHA1SUM_FILE_PATH, mode='wt', encoding='utf8') as fp:
+ fp.write(sha1sum + "\n")
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ description=('Render templates with samba dependencies '
+ 'to bootstrap multiple distributions.'))
+
+ parser.add_argument(
+ '-r', '--render', action='store_true', help='Render templates')
+
+ parser.add_argument(
+ '-s', '--sha1sum', action='store_true', help='Print sha1sum')
+ parser.add_argument(
+ '-d', '--debug', action='store_true', help='Debug sha1sum')
+
+ args = parser.parse_args()
+ need_help = True
+
+ if args.render:
+ render(DISTS)
+ need_help = False
+ if args.sha1sum:
+ # we will use the output to check sha1sum in ci
+ print(get_sha1sum(args.debug))
+ need_help = False
+ if need_help:
+ parser.print_help()
+
+
+if __name__ == '__main__':
+ main()