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/>.
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>
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
58 'psmisc', # for pstree in test
63 'sudo', # docker images has no sudo by default
71 # define pkgs for all packaging systems in parallel
72 # make it easier to find missing ones
73 # use latest ubuntu and fedora as defaults
76 # NAME1-dev, NAME2-devel
77 ('lmdb-utils', 'lmdb'),
78 ('mingw-w64', 'mingw64-gcc'),
79 ('zlib1g-dev', 'zlib-devel'),
80 ('libbsd-dev', 'libbsd-devel'),
81 ('liburing-dev', 'liburing-devel'),
82 ('libarchive-dev', 'libarchive-devel'),
83 ('libblkid-dev', 'libblkid-devel'),
84 ('libcap-dev', 'libcap-devel'),
85 ('libacl1-dev', 'libacl-devel'),
86 ('libattr1-dev', 'libattr-devel'),
87 ('libutf8proc-dev', 'utf8proc-devel'),
88 ('libssl-dev', 'openssl-devel'),
89 ('libclang-dev', 'clang-devel'),
91 # libNAME1-dev, NAME2-devel
92 ('libpopt-dev', 'popt-devel'),
93 ('libreadline-dev', 'readline-devel'),
94 ('libjansson-dev', 'jansson-devel'),
95 ('liblmdb-dev', 'lmdb-devel'),
96 ('libncurses5-dev', 'ncurses-devel'),
97 # NOTE: Debian 7+ or Ubuntu 16.04+
98 ('libsystemd-dev', 'systemd-devel'),
99 ('libkrb5-dev', 'krb5-devel'),
100 ('libldap2-dev', 'openldap-devel'),
101 ('libcups2-dev', 'cups-devel'),
102 ('libpam0g-dev', 'pam-devel'),
103 ('libgpgme11-dev', 'gpgme-devel'),
104 # NOTE: Debian 8+ and Ubuntu 14.04+
105 ('libgnutls28-dev', 'gnutls-devel'),
106 ('gnutls-bin', 'gnutls-utils'),
107 ('libtasn1-bin', 'libtasn1-tools'),
108 ('libtasn1-dev', 'libtasn1-devel'),
110 ('uuid-dev', 'libuuid-devel'),
111 ('libjs-jquery', ''),
112 ('libavahi-common-dev', 'avahi-devel'),
113 ('libdbus-1-dev', 'dbus-devel'),
114 ('libpcap-dev', 'libpcap-devel'),
115 ('libunwind-dev', 'libunwind-devel'), # for back trace
116 ('libglib2.0-dev', 'glib2-devel'),
117 ('libicu-dev', 'libicu-devel'),
118 ('heimdal-multidev', ''),
121 # for debian, locales provide locale support with language packs
122 # ubuntu split language packs to language-pack-xx
123 # for centos, glibc-common provide locale support with language packs
124 # fedora split language packs to glibc-langpack-xx
125 ('locales', 'glibc-common'), # required for locale
126 ('language-pack-en', 'glibc-langpack-en'), # we need en_US.UTF-8
127 ('bind9utils', 'bind-utils'),
129 ('xsltproc', 'libxslt'),
130 ('krb5-user', 'krb5-workstation'),
132 ('krb5-kdc', 'krb5-server'),
133 ('apt-utils', 'yum-utils'),
134 ('pkg-config', 'pkgconfig'),
135 ('procps', 'procps-ng'), # required for the free cmd in tests
136 ('lsb-release', 'lsb-release'), # we need lsb_release to show info
137 ('', 'rpcgen'), # required for test
138 # refer: https://fedoraproject.org/wiki/Changes/SunRPCRemoval
139 ('', 'libtirpc-devel'), # for <rpc/rpc.h> header on fedora
140 ('', 'rpcsvc-proto-devel'), # for <rpcsvc/rquota.h> header
143 ('shellcheck', 'ShellCheck'),
144 ('', 'crypto-policies-scripts'),
146 ('python3', 'python3'),
147 ('python3-cryptography', 'python3-cryptography'), # for krb5 tests
148 ('python3-dev', 'python3-devel'),
150 ('python3-iso8601', 'python3-iso8601'),
151 ('python3-gpg', 'python3-gpg'), # defaults to ubuntu/fedora latest
152 ('python3-markdown', 'python3-markdown'),
153 ('python3-dnspython', 'python3-dns'),
154 ('python3-pexpect', ''), # for wintest only
155 ('python3-pyasn1', 'python3-pyasn1'), # for krb5 tests
156 ('python3-setproctitle', 'python3-setproctitle'),
157 ('python3-requests', 'python3-requests'), # for cert auto enroll
159 ('', 'python3-libsemanage'),
160 ('', 'python3-policycoreutils'),
162 # A copy of the `crypt` module that was removed in Python 3.13
163 # See also https://bugzilla.samba.org/show_bug.cgi?id=15756
164 ('', 'python3-crypt-r'),
167 ('libparse-yapp-perl', 'perl-Parse-Yapp'),
168 ('perl-modules', ''),
169 ('', 'perl-FindBin'),
170 ('', 'perl-Archive-Tar'),
171 ('', 'perl-ExtUtils-MakeMaker'),
172 ('', 'perl-Test-Base'),
173 ('', 'perl-generators'),
174 ('', 'perl-interpreter'),
177 ('xfslibs-dev', 'xfsprogs-devel'), # for xfs quota support
178 ('', 'glusterfs-api-devel'),
179 ('glusterfs-common', 'glusterfs-devel'),
180 ('libcephfs-dev', 'libcephfs-devel'),
183 ('libtracker-sparql-2.0-dev', 'tracker-devel'),
186 # @ means group for rpm, use fedora as rpm default
187 ('build-essential', '@development-tools'),
189 # rpm has no pkg for docbook-xml
190 ('docbook-xml', 'docbook-dtds'),
191 ('docbook-xsl', 'docbook-style-xsl'),
192 ('libkeyutils-dev', 'keyutils-libs-devel'),
198 DEB_PKGS
= COMMON
+ [pkg
for pkg
, _
in PKGS
if pkg
]
199 RPM_PKGS
= COMMON
+ [pkg
for _
, pkg
in PKGS
if pkg
]
201 GENERATED_MARKER
= r
"""
203 # This file is generated by 'bootstrap/template.py --render'
204 # See also bootstrap/config.py
214 export DEBIAN_FRONTEND=noninteractive
220 apt-get -y autoremove
232 yum install -y epel-release
233 yum install -y yum-plugin-copr
234 yum copr enable -y sergiomb/SambaAD
242 if [ ! -f /usr/bin/python3 ]; then
243 ln -sf /usr/bin/python3.6 /usr/bin/python3
247 ROCKY8_DNF_BOOTSTRAP
= r
"""
253 yum install -y dnf-plugins-core
254 yum install -y epel-release
255 yum install -y centos-release-ceph-pacific
257 sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Ceph-*
258 sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Ceph-*
259 sed -i 's/$contentdir/centos/g' /etc/yum.repos.d/CentOS-Ceph-*
262 yum config-manager --set-enabled powertools -y
267 --setopt=install_weak_deps=False \
268 --setopt=centos-ceph-pacific.module_hotfixes=true \
274 CENTOS9S_DNF_BOOTSTRAP
= r
"""
280 dnf install -y dnf-plugins-core
281 dnf install -y epel-release
282 dnf install -y centos-release-gluster9
285 dnf config-manager --set-enabled crb -y
290 --setopt=install_weak_deps=False \
304 --setopt=install_weak_deps=False \
309 update-crypto-policies --set DEFAULT:AD-SUPPORT
312 DNF_BOOTSTRAP_MIT
= r
"""
318 dnf install -y dnf-plugins-core
319 dnf copr -y enable abbra/krb5-test
323 --setopt=install_weak_deps=False \
329 ZYPPER_BOOTSTRAP
= r
"""
334 zypper --non-interactive refresh
335 zypper --non-interactive update
336 zypper --non-interactive install \
341 zypper --non-interactive clean
343 if [ -f /usr/lib/mit/bin/krb5-config ]; then
344 ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config
348 # A generic shell script to setup locale
354 # refer to /usr/share/i18n/locales
356 # refer to /usr/share/i18n/charmaps
358 # locale to generate in /usr/lib/locale
359 # glibc/localedef will normalize UTF-8 to utf8, follow the naming style
360 LOCALE=$INPUTFILE.utf8
362 # if locale is already correct, exit
363 ( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
365 # if locale not available, generate locale into /usr/lib/locale
366 if ! ( locale --all-locales | grep -i $LOCALE )
368 # no-archive means create its own dir
369 localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
372 # update locale conf and global env file
373 # set both LC_ALL and LANG for safe
375 # update conf for Debian family
376 FILE=/etc/default/locale
379 echo LC_ALL="$LOCALE" > $FILE
380 echo LANG="$LOCALE" >> $FILE
383 # update conf for RedHat family
384 FILE=/etc/locale.conf
387 # LC_ALL is not valid in this file, set LANG only
388 echo LANG="$LOCALE" > $FILE
391 # update global env file
392 FILE=/etc/environment
395 # append LC_ALL if not exist
396 grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
397 # append LANG if not exist
398 grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
407 # pass in with --build-arg while build
409 RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
412 # need root permission, do it before USER samba
413 RUN /tmp/bootstrap.sh && /tmp/locale.sh
415 # if ld.gold exists, force link it to ld
416 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"; }}
417 # if ld.mold exists, force link it to ld (prefer mold over gold! ;-)
418 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"; }}
420 # make test can not work with root, so we have to create a new user
421 RUN useradd -m -U -s /bin/bash samba && \
422 mkdir -p /etc/sudoers.d && \
423 echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
427 # samba tests rely on this
428 ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8 LANGUAGE=en_US
431 # Vagrantfile snippet for each dist
432 VAGRANTFILE_SNIPPET
= r
"""
433 config.vm.define "{name}" do |v|
434 v.vm.box = "{vagrant_box}"
435 v.vm.hostname = "{name}"
436 v.vm.provision :shell, path: "{name}/bootstrap.sh"
437 v.vm.provision :shell, path: "{name}/locale.sh"
441 # global Vagrantfile with snippets for all dists
442 VAGRANTFILE_GLOBAL
= r
"""
445 Vagrant.configure("2") do |config|
446 config.ssh.insert_key = false
448 {vagrantfile_snippets}
455 'docker_image': 'debian:11',
456 'vagrant_box': 'debian/bullseye64',
458 'language-pack-en': '', # included in locales
460 'cargo': '', # included cargo is broken
464 'docker_image': 'debian:11', # specify the platform in .gitlab-ci.yaml
465 'vagrant_box': 'debian/bullseye32',
467 'language-pack-en': '', # included in locales
469 'cargo': '', # included cargo is broken
473 'docker_image': 'debian:12',
474 'vagrant_box': 'debian/bookworm64',
476 'language-pack-en': '', # included in locales
477 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
478 'cargo': '', # included cargo is broken
482 'docker_image': 'registry-1.docker.io/i386/debian:12',
483 'vagrant_box': 'debian/bookworm32',
485 'language-pack-en': '', # included in locales
486 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
487 'cargo': '', # included cargo is broken
491 'docker_image': 'ubuntu:18.04',
492 'vagrant_box': 'ubuntu/bionic64',
494 'liburing-dev': '', # not available
498 'ubuntu1804-32bit': {
499 'docker_image': 'registry-1.docker.io/i386/ubuntu:18.04',
500 'vagrant_box': 'ubuntu/bionic32',
502 'liburing-dev': '', # not available
507 'docker_image': 'ubuntu:20.04',
508 'vagrant_box': 'ubuntu/focal64',
510 'liburing-dev': '', # not available
515 'docker_image': 'ubuntu:22.04',
516 'vagrant_box': 'ubuntu/jammy64',
518 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
526 'docker_image': 'docker.io/library/rockylinux:8',
527 'vagrant_box': 'rocky/8',
528 'bootstrap': ROCKY8_DNF_BOOTSTRAP
,
530 'lsb-release': 'redhat-lsb',
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',
536 'liburing-devel': '', # not available yet, Add me back, once available!
541 'python3-crypt-r': '',
545 'docker_image': 'quay.io/centos/centos:stream9',
546 'vagrant_box': 'centos/stream9',
547 'bootstrap': CENTOS9S_DNF_BOOTSTRAP
,
549 'lsb-release': 'lsb_release',
550 '@development-tools': '"@Development Tools"', # add quotes
551 'lcov': '', # does not exist
552 'perl-JSON-Parse': '', # does not exist?
553 'perl-Test-Base': 'perl-Test-Simple',
559 'libcephfs-devel': '', # not available anymore
560 'curl': '', # Use installed curl-minimal
561 'python3-crypt-r': '',
565 'docker_image': 'quay.io/fedora/fedora:41',
566 'vagrant_box': 'fedora/41-cloud-base',
567 'bootstrap': DNF_BOOTSTRAP
,
569 'lsb-release': 'redhat-lsb',
571 'python3-iso8601': 'python3-dateutil',
572 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
576 'docker_image': 'opensuse/leap:15.5',
577 'vagrant_box': 'opensuse/openSUSE-15.5-x86_64',
578 'bootstrap': ZYPPER_BOOTSTRAP
,
580 '@development-tools': '',
581 'dbus-devel': 'dbus-1-devel',
582 'docbook-style-xsl': 'docbook-xsl-stylesheets',
583 'glibc-common': 'glibc-locale',
584 'glibc-locale-source': 'glibc-i18ndata',
585 'glibc-langpack-en': '',
586 'jansson-devel': 'libjansson-devel',
587 'keyutils-libs-devel': 'keyutils-devel',
588 'krb5-workstation': 'krb5-client',
589 'python3-libsemanage': 'python3-semanage',
590 'python3-crypt-r': '',
591 'openldap-devel': 'openldap2-devel',
592 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper',
593 'perl-JSON-Parse': 'perl-JSON-XS',
594 'perl-generators': '',
595 'perl-interpreter': '',
597 'procps-ng': 'procps',
598 'python3-iso8601': 'python3-python-dateutil',
599 'python3-dns': 'python3-dnspython',
600 'python3-markdown': 'python3-Markdown',
602 'glusterfs-api-devel': '',
603 'gnutls-utils': 'gnutls',
604 'libtasn1-tools': '', # asn1Parser is part of libtasn1
616 'bootstrap': APT_BOOTSTRAP
, # family default
624 'bootstrap': YUM_BOOTSTRAP
, # family default
635 def expand_family_dists(family
):
637 for name
, config
in family
['dists'].items():
638 config
= config
.copy()
639 config
['name'] = name
640 config
['home'] = join(OUT
, name
)
641 config
['family'] = family
['name']
642 config
['GENERATED_MARKER'] = GENERATED_MARKER
644 # replace dist specific pkgs
645 replace
= config
.get('replace', {})
647 for pkg
in family
['pkgs']:
648 pkg
= replace
.get(pkg
, pkg
) # replace if exists or get self
653 lines
= [' - {}'.format(pkg
) for pkg
in pkgs
]
654 config
['packages.yml'] = YML_HEADER
.lstrip() + os
.linesep
.join(lines
)
656 sep
= ' \\' + os
.linesep
+ ' '
657 config
['pkgs'] = sep
.join(pkgs
)
659 # get dist bootstrap template or fall back to family default
660 bootstrap_template
= config
.get('bootstrap', family
['bootstrap'])
661 config
['bootstrap.sh'] = bootstrap_template
.format(**config
).strip()
662 config
['locale.sh'] = LOCALE_SETUP
.format(**config
).strip()
664 config
['Dockerfile'] = DOCKERFILE
.format(**config
).strip()
665 # keep the indent, no strip
666 config
['vagrantfile_snippet'] = VAGRANTFILE_SNIPPET
.format(**config
)
672 # expanded config for dists
673 DEB_DISTS_EXP
= expand_family_dists(DEB_FAMILY
)
674 RPM_DISTS_EXP
= expand_family_dists(RPM_FAMILY
)
676 # assemble all together
678 DISTS
.update(DEB_DISTS_EXP
)
679 DISTS
.update(RPM_DISTS_EXP
)
682 def render_vagrantfile(dists
):
684 Render all snippets for each dist into global Vagrantfile.
686 Vagrant supports multiple vms in one Vagrantfile.
687 This make it easier to manage the fleet, e.g:
689 start all: vagrant up
690 start one: vagrant up ubuntu1804
692 All other commands apply to above syntax, e.g.: status, destroy, provision
694 # sort dists by name and put all vagrantfile snippets together
696 dists
[dist
]['vagrantfile_snippet']
697 for dist
in sorted(dists
.keys())]
699 return VAGRANTFILE_GLOBAL
.format(
700 vagrantfile_snippets
=''.join(snippets
),
701 GENERATED_MARKER
=GENERATED_MARKER
705 VAGRANTFILE
= render_vagrantfile(DISTS
)
708 # data we need to expose
709 __all__
= ['DISTS', 'VAGRANTFILE', 'OUT']