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
56 'psmisc', # for pstree in test
60 'sudo', # docker images has no sudo by default
67 # define pkgs for all packaging systems in parallel
68 # make it easier to find missing ones
69 # use latest ubuntu and fedora as defaults
72 # NAME1-dev, NAME2-devel
73 ('lmdb-utils', 'lmdb'),
74 ('mingw-w64', 'mingw64-gcc'),
75 ('zlib1g-dev', 'zlib-devel'),
76 ('libbsd-dev', 'libbsd-devel'),
77 ('liburing-dev', 'liburing-devel'),
78 ('libarchive-dev', 'libarchive-devel'),
79 ('libblkid-dev', 'libblkid-devel'),
80 ('libcap-dev', 'libcap-devel'),
81 ('libacl1-dev', 'libacl-devel'),
82 ('libattr1-dev', 'libattr-devel'),
84 # libNAME1-dev, NAME2-devel
85 ('libpopt-dev', 'popt-devel'),
86 ('libreadline-dev', 'readline-devel'),
87 ('libjansson-dev', 'jansson-devel'),
88 ('liblmdb-dev', 'lmdb-devel'),
89 ('libncurses5-dev', 'ncurses-devel'),
90 # NOTE: Debian 7+ or Ubuntu 16.04+
91 ('libsystemd-dev', 'systemd-devel'),
92 ('libkrb5-dev', 'krb5-devel'),
93 ('libldap2-dev', 'openldap-devel'),
94 ('libcups2-dev', 'cups-devel'),
95 ('libpam0g-dev', 'pam-devel'),
96 ('libgpgme11-dev', 'gpgme-devel'),
97 # NOTE: Debian 8+ and Ubuntu 14.04+
98 ('libgnutls28-dev', 'gnutls-devel'),
99 ('libtasn1-bin', 'libtasn1-tools'),
100 ('libtasn1-dev', 'libtasn1-devel'),
102 ('uuid-dev', 'libuuid-devel'),
103 ('libjs-jquery', ''),
104 ('libavahi-common-dev', 'avahi-devel'),
105 ('libdbus-1-dev', 'dbus-devel'),
106 ('libpcap-dev', 'libpcap-devel'),
107 ('libunwind-dev', 'libunwind-devel'), # for back trace
108 ('libglib2.0-dev', 'glib2-devel'),
109 ('libicu-dev', 'libicu-devel'),
110 ('heimdal-multidev', ''),
113 # for debian, locales provide locale support with language packs
114 # ubuntu split language packs to language-pack-xx
115 # for centos, glibc-common provide locale support with language packs
116 # fedora split language packs to glibc-langpack-xx
117 ('locales', 'glibc-common'), # required for locale
118 ('language-pack-en', 'glibc-langpack-en'), # we need en_US.UTF-8
119 ('bind9utils', 'bind-utils'),
121 ('xsltproc', 'libxslt'),
122 ('krb5-user', 'krb5-workstation'),
124 ('krb5-kdc', 'krb5-server'),
125 ('apt-utils', 'yum-utils'),
126 ('pkg-config', 'pkgconfig'),
127 ('procps', 'procps-ng'), # required for the free cmd in tests
128 ('lsb-release', 'lsb-release'), # we need lsb_relase to show info
129 ('', 'rpcgen'), # required for test
130 # refer: https://fedoraproject.org/wiki/Changes/SunRPCRemoval
131 ('', 'libtirpc-devel'), # for <rpc/rpc.h> header on fedora
132 ('', 'rpcsvc-proto-devel'), # for <rpcsvc/rquota.h> header
135 ('python3', 'python3'),
136 ('python3-cryptography', 'python3-cryptography'), # for krb5 tests
137 ('python3-dev', 'python3-devel'),
139 ('python3-iso8601', 'python3-iso8601'),
140 ('python3-gpg', 'python3-gpg'), # defaults to ubuntu/fedora latest
141 ('python3-markdown', 'python3-markdown'),
142 ('python3-matplotlib', ''),
143 ('python3-dnspython', 'python3-dns'),
144 ('python3-pexpect', ''), # for wintest only
145 ('python3-pyasn1', 'python3-pyasn1'), # for krb5 tests
146 ('python3-setproctitle', 'python3-setproctitle'),
148 ('', 'libsemanage-python'),
149 ('', 'policycoreutils-python'),
152 ('libparse-yapp-perl', 'perl-Parse-Yapp'),
153 ('libjson-perl', 'perl-JSON'),
154 ('', 'perl-JSON-Parse'),
155 ('perl-modules', ''),
156 ('', 'perl-FindBin'),
157 ('', 'perl-Archive-Tar'),
158 ('', 'perl-ExtUtils-MakeMaker'),
159 ('', 'perl-Test-Base'),
160 ('', 'perl-generators'),
161 ('', 'perl-interpreter'),
164 ('xfslibs-dev', 'xfsprogs-devel'), # for xfs quota support
165 ('', 'glusterfs-api-devel'),
166 ('glusterfs-common', 'glusterfs-devel'),
167 ('libcephfs-dev', 'libcephfs-devel'),
170 ('libtracker-sparql-2.0-dev', 'tracker-devel'),
173 # @ means group for rpm, use fedora as rpm default
174 ('build-essential', '@development-tools'),
176 # rpm has no pkg for docbook-xml
177 ('docbook-xml', 'docbook-dtds'),
178 ('docbook-xsl', 'docbook-style-xsl'),
179 ('', 'keyutils-libs-devel'),
184 DEB_PKGS = COMMON + [pkg for pkg, _ in PKGS if pkg]
185 RPM_PKGS = COMMON + [pkg for _, pkg in PKGS if pkg]
187 GENERATED_MARKER = r"""
189 # This file is generated by 'bootstrap/template.py --render'
190 # See also bootstrap/config.py
200 export DEBIAN_FRONTEND=noninteractive
206 apt-get -y autoremove
218 yum install -y epel-release
219 yum install -y yum-plugin-copr
220 yum copr enable -y sergiomb/SambaAD
228 if [ ! -f /usr/bin/python3 ]; then
229 ln -sf /usr/bin/python3.6 /usr/bin/python3
233 CENTOS8S_YUM_BOOTSTRAP = r"""
239 yum install -y dnf-plugins-core
240 yum install -y epel-release
243 yum config-manager --set-enabled powertools -y || \
244 yum config-manager --set-enabled powertools -y
249 --setopt=install_weak_deps=False \
263 --setopt=install_weak_deps=False \
269 ZYPPER_BOOTSTRAP = r"""
274 zypper --non-interactive refresh
275 zypper --non-interactive update
276 zypper --non-interactive install \
281 zypper --non-interactive clean
283 if [ -f /usr/lib/mit/bin/krb5-config ]; then
284 ln -sf /usr/lib/mit/bin/krb5-config /usr/bin/krb5-config
288 # A generic shell script to setup locale
294 # refer to /usr/share/i18n/locales
296 # refer to /usr/share/i18n/charmaps
298 # locale to generate in /usr/lib/locale
299 # glibc/localedef will normalize UTF-8 to utf8, follow the naming style
300 LOCALE=$INPUTFILE.utf8
302 # if locale is already correct, exit
303 ( locale | grep LC_ALL | grep -i $LOCALE ) && exit 0
305 # if locale not available, generate locale into /usr/lib/locale
306 if ! ( locale --all-locales | grep -i $LOCALE )
308 # no-archive means create its own dir
309 localedef --inputfile $INPUTFILE --charmap $CHARMAP --no-archive $LOCALE
312 # update locale conf and global env file
313 # set both LC_ALL and LANG for safe
315 # update conf for Debian family
316 FILE=/etc/default/locale
319 echo LC_ALL="$LOCALE" > $FILE
320 echo LANG="$LOCALE" >> $FILE
323 # update conf for RedHat family
324 FILE=/etc/locale.conf
327 # LC_ALL is not valid in this file, set LANG only
328 echo LANG="$LOCALE" > $FILE
331 # update global env file
332 FILE=/etc/environment
335 # append LC_ALL if not exist
336 grep LC_ALL $FILE || echo LC_ALL="$LOCALE" >> $FILE
337 # append LANG if not exist
338 grep LANG $FILE || echo LANG="$LOCALE" >> $FILE
347 # pass in with --build-arg while build
349 RUN [ -n $SHA1SUM ] && echo $SHA1SUM > /sha1sum.txt
352 # need root permission, do it before USER samba
353 RUN /tmp/bootstrap.sh && /tmp/locale.sh
355 # if ld.gold exists, force link it to ld
356 RUN set -x; LD=$(which ld); LD_GOLD=$(which ld.gold); test -x $LD_GOLD && ln -sf $LD_GOLD $LD && test -x $LD && echo "$LD is now $LD_GOLD"
358 # make test can not work with root, so we have to create a new user
359 RUN useradd -m -U -s /bin/bash samba && \
360 mkdir -p /etc/sudoers.d && \
361 echo "samba ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/samba
365 # samba tests rely on this
366 ENV USER=samba LC_ALL=en_US.utf8 LANG=en_US.utf8
369 # Vagrantfile snippet for each dist
370 VAGRANTFILE_SNIPPET = r"""
371 config.vm.define "{name}" do |v|
372 v.vm.box = "{vagrant_box}"
373 v.vm.hostname = "{name}"
374 v.vm.provision :shell, path: "{name}/bootstrap.sh"
375 v.vm.provision :shell, path: "{name}/locale.sh"
379 # global Vagrantfile with snippets for all dists
380 VAGRANTFILE_GLOBAL = r"""
383 Vagrant.configure("2") do |config|
384 config.ssh.insert_key = false
386 {vagrantfile_snippets}
394 'docker_image': 'debian:10',
395 'vagrant_box': 'debian/buster64',
397 'language-pack-en': '', # included in locales
398 'liburing-dev': '', # not available
402 'docker_image': 'debian:11',
403 'vagrant_box': 'debian/bullseye64',
405 'language-pack-en': '', # included in locales
409 'docker_image': 'ubuntu:16.04',
410 'vagrant_box': 'ubuntu/xenial64',
412 'python3-gpg': 'python3-gpgme',
413 'glusterfs-common': '',
415 'liburing-dev': '', # not available
416 'libtracker-sparql-2.0-dev': '', # not available
420 'docker_image': 'ubuntu:18.04',
421 'vagrant_box': 'ubuntu/bionic64',
423 'liburing-dev': '', # not available
427 'docker_image': 'ubuntu:20.04',
428 'vagrant_box': 'ubuntu/focal64',
430 'liburing-dev': '', # not available
438 'docker_image': 'centos:7',
439 'vagrant_box': 'centos/7',
440 'bootstrap': YUM_BOOTSTRAP,
442 'lsb-release': 'redhat-lsb',
443 'python3': 'python36',
444 'python3-cryptography': 'python36-cryptography',
445 'python3-devel': 'python36-devel',
446 'python3-dns': 'python36-dns',
447 'python3-pyasn1': 'python36-pyasn1',
448 'python3-gpg': 'python36-gpg',
449 'python3-iso8601' : 'python36-iso8601',
450 'python3-markdown': 'python36-markdown',
451 # although python36-devel is available
452 # after epel-release installed
453 # however, all other python3 pkgs are still python36-ish
454 'python2-gpg': 'pygpgme',
455 'python3-gpg': '', # no python3-gpg yet
456 '@development-tools': '"@Development Tools"', # add quotes
457 'glibc-langpack-en': '', # included in glibc-common
458 'glibc-locale-source': '', # included in glibc-common
459 # update perl core modules on centos
460 # fix: Can't locate Archive/Tar.pm in @INC
463 'rpcsvc-proto-devel': '',
464 'glusterfs-api-devel': '',
465 'glusterfs-devel': '',
466 'libcephfs-devel': '',
467 'gnutls-devel': 'compat-gnutls34-devel',
468 'liburing-devel': '', # not available
469 'python3-setproctitle': 'python36-setproctitle',
470 'tracker-devel': '', # do not install
474 'docker_image': 'quay.io/centos/centos:stream8',
475 'vagrant_box': 'centos/stream8',
476 'bootstrap': CENTOS8S_YUM_BOOTSTRAP,
478 'lsb-release': 'redhat-lsb',
479 '@development-tools': '"@Development Tools"', # add quotes
480 'libsemanage-python': 'python3-libsemanage',
481 'lcov': '', # does not exist
482 'perl-JSON-Parse': '', # does not exist?
483 'perl-Test-Base': 'perl-Test-Simple',
485 'policycoreutils-python': 'python3-policycoreutils',
486 'liburing-devel': '', # not available yet, Add me back, once available!
490 'docker_image': 'fedora:33',
491 'vagrant_box': 'fedora/33-cloud-base',
492 'bootstrap': DNF_BOOTSTRAP,
494 'lsb-release': 'redhat-lsb',
495 'libsemanage-python': 'python3-libsemanage',
496 'policycoreutils-python': 'python3-policycoreutils',
497 'python3-iso8601': 'python3-dateutil',
501 'docker_image': 'fedora:34',
502 'vagrant_box': 'fedora/34-cloud-base',
503 'bootstrap': DNF_BOOTSTRAP,
505 'lsb-release': 'redhat-lsb',
506 'libsemanage-python': 'python3-libsemanage',
507 'policycoreutils-python': 'python3-policycoreutils',
509 'python3-iso8601': 'python3-dateutil',
510 'libtracker-sparql-2.0-dev': '', # only tracker 3.x is available
514 'docker_image': 'opensuse/leap:15.1',
515 'vagrant_box': 'opensuse/openSUSE-15.1-x86_64',
516 'bootstrap': ZYPPER_BOOTSTRAP,
518 '@development-tools': '',
519 'dbus-devel': 'dbus-1-devel',
520 'docbook-style-xsl': 'docbook-xsl-stylesheets',
521 'glibc-common': 'glibc-locale',
522 'glibc-locale-source': 'glibc-i18ndata',
523 'glibc-langpack-en': '',
524 'jansson-devel': 'libjansson-devel',
525 'keyutils-libs-devel': 'keyutils-devel',
526 'krb5-workstation': 'krb5-client',
527 'libsemanage-python': 'python2-semanage',
528 'openldap-devel': 'openldap2-devel',
529 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper',
530 'perl-JSON-Parse': 'perl-JSON-XS',
531 'perl-generators': '',
532 'perl-interpreter': '',
534 'procps-ng': 'procps',
535 'python3-dns': 'python3-dnspython',
536 'python3-markdown': 'python3-Markdown',
538 'glusterfs-api-devel': '',
539 'libtasn1-tools': '', # asn1Parser is part of libtasn1
540 'mingw64-gcc': '', # doesn't exist
541 'liburing-devel': '', # not available
545 'docker_image': 'opensuse/leap:15.2',
546 'vagrant_box': 'opensuse/openSUSE-15.2-x86_64',
547 'bootstrap': ZYPPER_BOOTSTRAP,
549 '@development-tools': '',
550 'dbus-devel': 'dbus-1-devel',
551 'docbook-style-xsl': 'docbook-xsl-stylesheets',
552 'glibc-common': 'glibc-locale',
553 'glibc-locale-source': 'glibc-i18ndata',
554 'glibc-langpack-en': '',
555 'jansson-devel': 'libjansson-devel',
556 'keyutils-libs-devel': 'keyutils-devel',
557 'krb5-workstation': 'krb5-client',
558 'libsemanage-python': 'python2-semanage',
559 'openldap-devel': 'openldap2-devel',
560 'perl-Archive-Tar': 'perl-Archive-Tar-Wrapper',
561 'perl-JSON-Parse': 'perl-JSON-XS',
562 'perl-generators': '',
563 'perl-interpreter': '',
565 'procps-ng': 'procps',
566 'python3-iso8601': 'python3-python-dateutil',
567 'python3-dns': 'python3-dnspython',
568 'python3-markdown': 'python3-Markdown',
570 'glusterfs-api-devel': '',
571 'libtasn1-tools': '', # asn1Parser is part of libtasn1
580 'bootstrap': APT_BOOTSTRAP, # family default
588 'bootstrap': YUM_BOOTSTRAP, # family default
599 def expand_family_dists(family):
601 for name, config in family['dists'].items():
602 config = config.copy()
603 config['name'] = name
604 config['home'] = join(OUT, name)
605 config['family'] = family['name']
606 config['GENERATED_MARKER'] = GENERATED_MARKER
608 # replace dist specific pkgs
609 replace = config.get('replace', {})
611 for pkg in family['pkgs']:
612 pkg = replace.get(pkg, pkg) # replace if exists or get self
617 lines = [' - {}'.format(pkg) for pkg in pkgs]
618 config['packages.yml'] = YML_HEADER.lstrip() + os.linesep.join(lines)
620 sep = ' \\' + os.linesep + ' '
621 config['pkgs'] = sep.join(pkgs)
623 # get dist bootstrap template or fall back to family default
624 bootstrap_template = config.get('bootstrap', family['bootstrap'])
625 config['bootstrap.sh'] = bootstrap_template.format(**config).strip()
626 config['locale.sh'] = LOCALE_SETUP.format(**config).strip()
628 config['Dockerfile'] = DOCKERFILE.format(**config).strip()
629 # keep the indent, no strip
630 config['vagrantfile_snippet'] = VAGRANTFILE_SNIPPET.format(**config)
636 # expanded config for dists
637 DEB_DISTS_EXP = expand_family_dists(DEB_FAMILY)
638 RPM_DISTS_EXP = expand_family_dists(RPM_FAMILY)
640 # assemble all together
642 DISTS.update(DEB_DISTS_EXP)
643 DISTS.update(RPM_DISTS_EXP)
646 def render_vagrantfile(dists):
648 Render all snippets for each dist into global Vagrantfile.
650 Vagrant supports multiple vms in one Vagrantfile.
651 This make it easier to manage the fleet, e.g:
653 start all: vagrant up
654 start one: vagrant up ubuntu1804
656 All other commands apply to above syntax, e.g.: status, destroy, provision
658 # sort dists by name and put all vagrantfile snippets together
660 dists[dist]['vagrantfile_snippet']
661 for dist in sorted(dists.keys())]
663 return VAGRANTFILE_GLOBAL.format(
664 vagrantfile_snippets=''.join(snippets),
665 GENERATED_MARKER=GENERATED_MARKER
669 VAGRANTFILE = render_vagrantfile(DISTS)
672 # data we need to expose
673 __all__ = ['DISTS', 'VAGRANTFILE', 'OUT']