ctdb-daemon: Store public address string in VNN
[samba4-gss.git] / bootstrap / config.py
blob7e6c0f47d676b3dd5c2bba951da295862e889723
1 #!/usr/bin/env python3
3 # Copyright (C) Catalyst.Net Ltd 2019
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 """
19 Manage dependencies and bootstrap environments for Samba.
21 Config file for packages and templates.
23 Update the lists in this file to require new packages in the
24 container images used in GitLab CI
26 Author: Joe Guo <joeg@catalyst.net.nz>
27 """
28 import os
29 from os.path import abspath, dirname, join
30 HERE = abspath(dirname(__file__))
31 # output dir for rendered files
32 OUT = join(HERE, 'generated-dists')
35 # pkgs with same name in all packaging systems
36 COMMON = [
37 'acl',
38 'attr',
39 'autoconf',
40 'binutils',
41 'bison',
42 'ccache',
43 'curl',
44 'chrpath',
45 'codespell',
46 'flex',
47 'gcc',
48 'gdb',
49 'git',
50 'gzip',
51 'hostname',
52 'htop',
53 'jq',
54 'lcov',
55 'make',
56 'patch',
57 'perl',
58 'psmisc', # for pstree in test
59 'rng-tools',
60 'rsync',
61 'sed',
62 'shfmt',
63 'sudo', # docker images has no sudo by default
64 'tar',
65 'tree',
66 'wget',
70 # define pkgs for all packaging systems in parallel
71 # make it easier to find missing ones
72 # use latest ubuntu and fedora as defaults
73 # deb, rpm, ...
74 PKGS = [
75 # NAME1-dev, NAME2-devel
76 ('lmdb-utils', 'lmdb'),
77 ('mingw-w64', 'mingw64-gcc'),
78 ('zlib1g-dev', 'zlib-devel'),
79 ('libbsd-dev', 'libbsd-devel'),
80 ('liburing-dev', 'liburing-devel'),
81 ('libarchive-dev', 'libarchive-devel'),
82 ('libblkid-dev', 'libblkid-devel'),
83 ('libcap-dev', 'libcap-devel'),
84 ('libacl1-dev', 'libacl-devel'),
85 ('libattr1-dev', 'libattr-devel'),
87 # libNAME1-dev, NAME2-devel
88 ('libpopt-dev', 'popt-devel'),
89 ('libreadline-dev', 'readline-devel'),
90 ('libjansson-dev', 'jansson-devel'),
91 ('liblmdb-dev', 'lmdb-devel'),
92 ('libncurses5-dev', 'ncurses-devel'),
93 # NOTE: Debian 7+ or Ubuntu 16.04+
94 ('libsystemd-dev', 'systemd-devel'),
95 ('libkrb5-dev', 'krb5-devel'),
96 ('libldap2-dev', 'openldap-devel'),
97 ('libcups2-dev', 'cups-devel'),
98 ('libpam0g-dev', 'pam-devel'),
99 ('libgpgme11-dev', 'gpgme-devel'),
100 # NOTE: Debian 8+ and Ubuntu 14.04+
101 ('libgnutls28-dev', 'gnutls-devel'),
102 ('gnutls-bin', 'gnutls-utils'),
103 ('libtasn1-bin', 'libtasn1-tools'),
104 ('libtasn1-dev', 'libtasn1-devel'),
105 ('', 'quota-devel'),
106 ('uuid-dev', 'libuuid-devel'),
107 ('libjs-jquery', ''),
108 ('libavahi-common-dev', 'avahi-devel'),
109 ('libdbus-1-dev', 'dbus-devel'),
110 ('libpcap-dev', 'libpcap-devel'),
111 ('libunwind-dev', 'libunwind-devel'), # for back trace
112 ('libglib2.0-dev', 'glib2-devel'),
113 ('libicu-dev', 'libicu-devel'),
114 ('heimdal-multidev', ''),
116 # NAME1, NAME2
117 # for debian, locales provide locale support with language packs
118 # ubuntu split language packs to language-pack-xx
119 # for centos, glibc-common provide locale support with language packs
120 # fedora split language packs to glibc-langpack-xx
121 ('locales', 'glibc-common'), # required for locale
122 ('language-pack-en', 'glibc-langpack-en'), # we need en_US.UTF-8
123 ('bind9utils', 'bind-utils'),
124 ('dnsutils', ''),
125 ('xsltproc', 'libxslt'),
126 ('krb5-user', 'krb5-workstation'),
127 ('krb5-config', ''),
128 ('krb5-kdc', 'krb5-server'),
129 ('apt-utils', 'yum-utils'),
130 ('pkg-config', 'pkgconfig'),
131 ('procps', 'procps-ng'), # required for the free cmd in tests
132 ('lsb-release', 'lsb-release'), # we need lsb_release to show info
133 ('', 'rpcgen'), # required for test
134 # refer: https://fedoraproject.org/wiki/Changes/SunRPCRemoval
135 ('', 'libtirpc-devel'), # for <rpc/rpc.h> header on fedora
136 ('', 'rpcsvc-proto-devel'), # for <rpcsvc/rquota.h> header
137 ('mawk', 'gawk'),
138 ('', 'mold'),
139 ('shellcheck', 'ShellCheck'),
140 ('', 'crypto-policies-scripts'),
142 ('python3', 'python3'),
143 ('python3-cryptography', 'python3-cryptography'), # for krb5 tests
144 ('python3-dev', 'python3-devel'),
145 ('python3-dbg', ''),
146 ('python3-iso8601', 'python3-iso8601'),
147 ('python3-gpg', 'python3-gpg'), # defaults to ubuntu/fedora latest
148 ('python3-markdown', 'python3-markdown'),
149 ('python3-dnspython', 'python3-dns'),
150 ('python3-pexpect', ''), # for wintest only
151 ('python3-pyasn1', 'python3-pyasn1'), # for krb5 tests
152 ('python3-setproctitle', 'python3-setproctitle'),
153 ('python3-requests', 'python3-requests'), # for cert auto enroll
155 ('', 'python3-libsemanage'),
156 ('', 'python3-policycoreutils'),
158 # perl
159 ('libparse-yapp-perl', 'perl-Parse-Yapp'),
160 ('perl-modules', ''),
161 ('', 'perl-FindBin'),
162 ('', 'perl-Archive-Tar'),
163 ('', 'perl-ExtUtils-MakeMaker'),
164 ('', 'perl-Test-Base'),
165 ('', 'perl-generators'),
166 ('', 'perl-interpreter'),
168 # fs
169 ('xfslibs-dev', 'xfsprogs-devel'), # for xfs quota support
170 ('', 'glusterfs-api-devel'),
171 ('glusterfs-common', 'glusterfs-devel'),
172 ('libcephfs-dev', 'libcephfs-devel'),
174 # spotlight
175 ('libtracker-sparql-2.0-dev', 'tracker-devel'),
177 # misc
178 # @ means group for rpm, use fedora as rpm default
179 ('build-essential', '@development-tools'),
180 ('debhelper', ''),
181 # rpm has no pkg for docbook-xml
182 ('docbook-xml', 'docbook-dtds'),
183 ('docbook-xsl', 'docbook-style-xsl'),
184 ('libkeyutils-dev', 'keyutils-libs-devel'),
185 ('', 'which'),
186 ('xz-utils', 'xz')
190 DEB_PKGS = COMMON + [pkg for pkg, _ in PKGS if pkg]
191 RPM_PKGS = COMMON + [pkg for _, pkg in PKGS if pkg]
193 GENERATED_MARKER = r"""
195 # This file is generated by 'bootstrap/template.py --render'
196 # See also bootstrap/config.py
201 APT_BOOTSTRAP = r"""
202 #!/bin/bash
203 {GENERATED_MARKER}
204 set -xueo pipefail
206 export DEBIAN_FRONTEND=noninteractive
207 apt-get -y update
209 apt-get -y install \
210 {pkgs}
212 apt-get -y autoremove
213 apt-get -y autoclean
214 apt-get -y clean
218 YUM_BOOTSTRAP = r"""
219 #!/bin/bash
220 {GENERATED_MARKER}
221 set -xueo pipefail
223 yum update -y
224 yum install -y epel-release
225 yum install -y yum-plugin-copr
226 yum copr enable -y sergiomb/SambaAD
227 yum update -y
229 yum install -y \
230 {pkgs}
232 yum clean all
234 if [ ! -f /usr/bin/python3 ]; then
235 ln -sf /usr/bin/python3.6 /usr/bin/python3
239 ROCKY8_DNF_BOOTSTRAP = r"""
240 #!/bin/bash
241 {GENERATED_MARKER}
242 set -xueo pipefail
244 yum update -y
245 yum install -y dnf-plugins-core
246 yum install -y epel-release
248 yum -v repolist all
249 yum config-manager --set-enabled powertools -y
251 yum update -y
253 yum install -y \
254 --setopt=install_weak_deps=False \
255 {pkgs}
257 yum clean all
260 CENTOS9S_DNF_BOOTSTRAP = r"""
261 #!/bin/bash
262 {GENERATED_MARKER}
263 set -xueo pipefail
265 dnf update -y
266 dnf install -y dnf-plugins-core
267 dnf install -y epel-release
268 dnf install -y centos-release-gluster9
270 dnf -v repolist all
271 dnf config-manager --set-enabled crb -y
273 dnf update -y
275 dnf install -y \
276 --setopt=install_weak_deps=False \
277 {pkgs}
279 dnf clean all
282 DNF_BOOTSTRAP = r"""
283 #!/bin/bash
284 {GENERATED_MARKER}
285 set -xueo pipefail
287 dnf update -y
289 dnf install -y \
290 --setopt=install_weak_deps=False \
291 {pkgs}
293 dnf clean all
295 update-crypto-policies --set DEFAULT:AD-SUPPORT
298 DNF_BOOTSTRAP_MIT = r"""
299 #!/bin/bash
300 {GENERATED_MARKER}
301 set -xueo pipefail
303 dnf update -y
304 dnf install -y dnf-plugins-core
305 dnf copr -y enable abbra/krb5-test
306 dnf update -y
308 dnf install -y \
309 --setopt=install_weak_deps=False \
310 {pkgs}
312 dnf clean all
315 ZYPPER_BOOTSTRAP = r"""
316 #!/bin/bash
317 {GENERATED_MARKER}
318 set -xueo pipefail
320 zypper --non-interactive refresh
321 zypper --non-interactive update
322 zypper --non-interactive install \
323 --no-recommends \
324 system-user-nobody \
325 {pkgs}
327 zypper --non-interactive clean
329 if [ -f /usr/lib/mit/bin/krb5-config ]; then
330 ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config
334 # A generic shell script to setup locale
335 LOCALE_SETUP = r"""
336 #!/bin/bash
337 {GENERATED_MARKER}
338 set -xueo pipefail
340 # refer to /usr/share/i18n/locales
341 INPUTFILE=en_US
342 # refer to /usr/share/i18n/charmaps
343 CHARMAP=UTF-8
344 # locale to generate in /usr/lib/locale
345 # glibc/localedef will normalize UTF-8 to utf8, follow the naming style
346 LOCALE=$INPUTFILE.utf8
348 # if locale is already correct, exit
349 ( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
351 # if locale not available, generate locale into /usr/lib/locale
352 if ! ( locale --all-locales | grep -i $LOCALE )
353 then
354 # no-archive means create its own dir
355 localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
358 # update locale conf and global env file
359 # set both LC_ALL and LANG for safe
361 # update conf for Debian family
362 FILE=/etc/default/locale
363 if [ -f $FILE ]
364 then
365 echo LC_ALL="$LOCALE" > $FILE
366 echo LANG="$LOCALE" >> $FILE
369 # update conf for RedHat family
370 FILE=/etc/locale.conf
371 if [ -f $FILE ]
372 then
373 # LC_ALL is not valid in this file, set LANG only
374 echo LANG="$LOCALE" > $FILE
377 # update global env file
378 FILE=/etc/environment
379 if [ -f $FILE ]
380 then
381 # append LC_ALL if not exist
382 grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
383 # append LANG if not exist
384 grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
389 DOCKERFILE = r"""
390 {GENERATED_MARKER}
391 FROM {docker_image}
393 # pass in with --build-arg while build
394 ARG SHA1SUM
395 RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
397 ADD *.sh /tmp/
398 # need root permission, do it before USER samba
399 RUN /tmp/bootstrap.sh && /tmp/locale.sh
401 # if ld.gold exists, force link it to ld
402 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"; }}
403 # if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
404 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"; }}
406 # make test can not work with root, so we have to create a new user
407 RUN useradd -m -U -s /bin/bash samba && \
408 mkdir -p /etc/sudoers.d && \
409 echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
411 USER samba
412 WORKDIR /home/samba
413 # samba tests rely on this
414 ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US
417 # Vagrantfile snippet for each dist
418 VAGRANTFILE_SNIPPET = r"""
419 config.vm.define "{name}" do |v|
420 v.vm.box = "{vagrant_box}"
421 v.vm.hostname = "{name}"
422 v.vm.provision :shell, path: "{name}/bootstrap.sh"
423 v.vm.provision :shell, path: "{name}/locale.sh"
427 # global Vagrantfile with snippets for all dists
428 VAGRANTFILE_GLOBAL = r"""
429 {GENERATED_MARKER}
431 Vagrant.configure("2") do |config|
432 config.ssh.insert_key = false
434 {vagrantfile_snippets}
439 DEB_DISTS = {
440 'debian11': {
441 'docker_image': 'debian:11',
442 'vagrant_box': 'debian/bullseye64',
443 'replace': {
444 'language-pack-en': '', # included in locales
445 'shfmt': '',
448 'debian11-32bit': {
449 'docker_image': 'registry-1.docker.io/i386/debian:11',
450 'vagrant_box': 'debian/bullseye32',
451 'replace': {
452 'language-pack-en': '', # included in locales
453 'shfmt': '',
456 'debian12': {
457 'docker_image': 'debian:12',
458 'vagrant_box': 'debian/bookworm64',
459 'replace': {
460 'language-pack-en': '', # included in locales
461 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
464 'debian12-32bit': {
465 'docker_image': 'registry-1.docker.io/i386/debian:12',
466 'vagrant_box': 'debian/bookworm32',
467 'replace': {
468 'language-pack-en': '', # included in locales
469 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
472 'ubuntu1804': {
473 'docker_image': 'ubuntu:18.04',
474 'vagrant_box': 'ubuntu/bionic64',
475 'replace': {
476 'liburing-dev': '', # not available
477 'shfmt': '',
480 'ubuntu1804-32bit': {
481 'docker_image': 'registry-1.docker.io/i386/ubuntu:18.04',
482 'vagrant_box': 'ubuntu/bionic32',
483 'replace': {
484 'liburing-dev': '', # not available
485 'shfmt': '',
488 'ubuntu2004': {
489 'docker_image': 'ubuntu:20.04',
490 'vagrant_box': 'ubuntu/focal64',
491 'replace': {
492 'liburing-dev': '', # not available
493 'shfmt': '',
496 'ubuntu2204': {
497 'docker_image': 'ubuntu:22.04',
498 'vagrant_box': 'ubuntu/jammy64',
499 'replace': {
500 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
506 RPM_DISTS = {
507 'rocky8': {
508 'docker_image': 'docker.io/library/rockylinux:8',
509 'vagrant_box': 'rocky/8',
510 'bootstrap': ROCKY8_DNF_BOOTSTRAP,
511 'replace': {
512 'lsb-release': 'redhat-lsb',
513 '@development-tools': '"@Development Tools"', # add quotes
514 'lcov': '', # does not exist
515 'perl-JSON-Parse': '', # does not exist?
516 'perl-Test-Base': 'perl-Test-Simple',
517 'perl-FindBin': '',
518 'liburing-devel': '', # not available yet, Add me back, once available!
519 'mold': '',
520 'ShellCheck': '',
521 'shfmt': '',
522 'codespell': '',
525 'centos9s': {
526 'docker_image': 'quay.io/centos/centos:stream9',
527 'vagrant_box': 'centos/stream9',
528 'bootstrap': CENTOS9S_DNF_BOOTSTRAP,
529 'replace': {
530 'lsb-release': 'lsb_release',
531 '@development-tools': '"@Development Tools"', # add quotes
532 'lcov': '', # does not exist
533 'perl-JSON-Parse': '', # does not exist?
534 'perl-Test-Base': 'perl-Test-Simple',
535 'perl-FindBin': '',
536 'mold': '',
537 'ShellCheck': '',
538 'shfmt': '',
539 'codespell': '',
540 'libcephfs-devel': '', # not available anymore
541 'curl': '', # Use installed curl-minimal
544 'fedora40': {
545 'docker_image': 'quay.io/fedora/fedora:40',
546 'vagrant_box': 'fedora/40-cloud-base',
547 'bootstrap': DNF_BOOTSTRAP,
548 'replace': {
549 'lsb-release': 'redhat-lsb',
550 'perl-FindBin': '',
551 'python3-iso8601': 'python3-dateutil',
552 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
555 'opensuse155': {
556 'docker_image': 'opensuse/leap:15.5',
557 'vagrant_box': 'opensuse/openSUSE-15.5-x86_64',
558 'bootstrap': ZYPPER_BOOTSTRAP,
559 'replace': {
560 '@development-tools': '',
561 'dbus-devel': 'dbus-1-devel',
562 'docbook-style-xsl': 'docbook-xsl-stylesheets',
563 'glibc-common': 'glibc-locale',
564 'glibc-locale-source': 'glibc-i18ndata',
565 'glibc-langpack-en': '',
566 'jansson-devel': 'libjansson-devel',
567 'keyutils-libs-devel': 'keyutils-devel',
568 'krb5-workstation': 'krb5-client',
569 'python3-libsemanage': 'python3-semanage',
570 'openldap-devel': 'openldap2-devel',
571 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper',
572 'perl-JSON-Parse': 'perl-JSON-XS',
573 'perl-generators': '',
574 'perl-interpreter': '',
575 'perl-FindBin': '',
576 'procps-ng': 'procps',
577 'python3-iso8601': 'python3-python-dateutil',
578 'python3-dns': 'python3-dnspython',
579 'python3-markdown': 'python3-Markdown',
580 'quota-devel': '',
581 'glusterfs-api-devel': '',
582 'gnutls-utils': 'gnutls',
583 'libtasn1-tools': '', # asn1Parser is part of libtasn1
584 'mold': '',
585 'shfmt': '',
586 'yum-utils': '',
592 DEB_FAMILY = {
593 'name': 'deb',
594 'pkgs': DEB_PKGS,
595 'bootstrap': APT_BOOTSTRAP, # family default
596 'dists': DEB_DISTS,
600 RPM_FAMILY = {
601 'name': 'rpm',
602 'pkgs': RPM_PKGS,
603 'bootstrap': YUM_BOOTSTRAP, # family default
604 'dists': RPM_DISTS,
608 YML_HEADER = r"""
610 packages:
614 def expand_family_dists(family):
615 dists = {}
616 for name, config in family['dists'].items():
617 config = config.copy()
618 config['name'] = name
619 config['home'] = join(OUT, name)
620 config['family'] = family['name']
621 config['GENERATED_MARKER'] = GENERATED_MARKER
623 # replace dist specific pkgs
624 replace = config.get('replace', {})
625 pkgs = []
626 for pkg in family['pkgs']:
627 pkg = replace.get(pkg, pkg) # replace if exists or get self
628 if pkg:
629 pkgs.append(pkg)
630 pkgs.sort()
632 lines = [' - {}'.format(pkg) for pkg in pkgs]
633 config['packages.yml'] = YML_HEADER.lstrip() + os.linesep.join(lines)
635 sep = ' \\' + os.linesep + ' '
636 config['pkgs'] = sep.join(pkgs)
638 # get dist bootstrap template or fall back to family default
639 bootstrap_template = config.get('bootstrap', family['bootstrap'])
640 config['bootstrap.sh'] = bootstrap_template.format(**config).strip()
641 config['locale.sh'] = LOCALE_SETUP.format(**config).strip()
643 config['Dockerfile'] = DOCKERFILE.format(**config).strip()
644 # keep the indent, no strip
645 config['vagrantfile_snippet'] = VAGRANTFILE_SNIPPET.format(**config)
647 dists[name] = config
648 return dists
651 # expanded config for dists
652 DEB_DISTS_EXP = expand_family_dists(DEB_FAMILY)
653 RPM_DISTS_EXP = expand_family_dists(RPM_FAMILY)
655 # assemble all together
656 DISTS = {}
657 DISTS.update(DEB_DISTS_EXP)
658 DISTS.update(RPM_DISTS_EXP)
661 def render_vagrantfile(dists):
663 Render all snippets for each dist into global Vagrantfile.
665 Vagrant supports multiple vms in one Vagrantfile.
666 This make it easier to manage the fleet, e.g:
668 start all: vagrant up
669 start one: vagrant up ubuntu1804
671 All other commands apply to above syntax, e.g.: status, destroy, provision
673 # sort dists by name and put all vagrantfile snippets together
674 snippets = [
675 dists[dist]['vagrantfile_snippet']
676 for dist in sorted(dists.keys())]
678 return VAGRANTFILE_GLOBAL.format(
679 vagrantfile_snippets=''.join(snippets),
680 GENERATED_MARKER=GENERATED_MARKER
684 VAGRANTFILE = render_vagrantfile(DISTS)
687 # data we need to expose
688 __all__ = ['DISTS', 'VAGRANTFILE', 'OUT']