FreeBSD on FreeIPA/IDM with Poudriere Repo

I already wrote twice about this topic:

FreeIPA-logo

In both earlier attempts I compiled and configured everything by hand – at it was a very interactive time consuming process. This time – after having some poudriere(8) experience – Simple FreeBSD Poudriere Harvester Guide – as shared here – I will now automate customized FreeIPA/IDM packages creation in a FreeBSD Poudriere tool.

One final note for the rest of the guide – please use /bin/sh shell for the commands … or zsh(1) for example πŸ™‚

This is the Table of Contents for this article.

  • FreeBSD on FreeIPA/IDM with Poudriere Repo
  • Poudriere Setup
    • FreeBSD Config
    • Development Poudriere Version
    • Nginx Setup
    • Latest Ccache Version
    • FreeIPA/IDM Repo
    • FreeIPA/IDM Configure Options
    • Repo Update
  • FreeBSD Client

Poudriere Setup

For a start lets switch to latest branch for more fresh pkg(8) packages.

# mkdir -p /usr/local/etc/pkg/repos

# sed s-quarterly-latest-g /etc/pkg/FreeBSD.conf > /usr/local/etc/pkg/repos/FreeBSD.conf

We will now install the needed packages.

# pkg install -y \
    poudriere-devel \
    nginx           \
    git-lite        \
    ccache4         \
    tree

FreeBSD Config

Main FreeBSD config.

# cat /etc/rc.conf
# NETWORK
  hostname="poudriere.lab.org"
  ifconfig_vtnet0="inet 10.0.0.122/24"
  defaultrouter="10.0.0.1"

# DAEMONS
  syslogd_flags="-ss"
  sshd_enable="YES"
  zfs_enable="YES"
  ntpdate_enable="YES"
  nginx_enable="YES"

# OTHER
  clear_tmp_enable="YES"
  dumpdev="AUTO"

… and /etc/hosts file.

# cat /etc/hosts
::1              localhost  localhost.my.domain
127.0.0.1        localhost  localhost.my.domain
10.0.0.122       poudriere-devel.lab.org  poudriere-devel

Development Poudriere Version

Contrary to my earlier guide I used the development ports-mgmt/poudriere-devel package because it offers more features.

The most interesting one is -b latest for the poudriere-bulk(8) command. For packages that you do not modify and only need as dependencies – Poudriere will just fetch them from the latest repository using pkg(8) and then (re)build the customized packages you want.

… currently this feature is broken and requires small fix/patch to work properly πŸ™‚

The sort(1) command needs to have -u flag added in two places as described here:

We will now apply this patch.

# pkg info -l poudriere-devel | grep common.sh
        /usr/local/share/poudriere/common.sh
        /usr/local/share/poudriere/include/common.sh.dragonfly
        /usr/local/share/poudriere/include/common.sh.freebsd

# cd /usr/local/share/poudriere/

# cp common.sh common.sh.NEW

# cp common.sh common.sh.OLD

# vi common.sh.NEW

# diff -u common.sh common.sh.NEW | tee PATCH
--- common.sh   2023-08-09 15:08:29.831701000 +0200
+++ common.sh.NEW       2023-08-09 14:49:22.097238000 +0200
@@ -3672,7 +3672,7 @@
            $1 == pkgbase && $3 == "off" {print "-"$2;printed=1}
            $1 != pkgbase && printed == 1 {exit}
            ' \
-           "${remote_all_options}" | sort -k1.2 | paste -s -d ' ' -)
+           "${remote_all_options}" | sort -k1.2 -u | paste -s -d ' ' -)
 
        shash_get pkgname-options "${pkgname}" selected_options || \
            selected_options=
@@ -3698,7 +3698,7 @@
            $1 == pkgbase {print $2;printed=1}
            $1 != pkgbase && printed == 1 {exit}
            ' \
-           "${remote_all_deps}" | sort | paste -s -d ' ' -)
+           "${remote_all_deps}" | sort -u | paste -s -d ' ' -)
        case "${local_deps}" in
        ${remote_deps}) ;;
        *)

# grep sort common.sh | grep -- -u | wc -l
       9

# grep sort common.sh.NEW | grep -- -u | wc -l
      11

# grep sort common.sh.OLD | grep -- -u | wc -l
       9

# patch < PATCH
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- common.sh  2023-08-09 15:08:29.831701000 +0200
|+++ common.sh.NEW      2023-08-09 14:49:22.097238000 +0200
--------------------------
Patching file common.sh using Plan A...
Hunk #1 succeeded at 3672.
Hunk #2 succeeded at 3698.
done

# grep sort common.sh | grep -- -u | wc -l
      11

# grep sort common.sh.NEW | grep -- -u | wc -l
      11

# grep sort common.sh.OLD | grep -- -u | wc -l
       9

Now the SSL keys.

# SSL=/usr/local/etc/ssl

# mkdir -p            /usr/ports/distfiles \
                      ${SSL}/keys \
                      ${SSL}/certs

# chmod 0600          ${SSL}/keys

# openssl genrsa -out ${SSL}/keys/poudriere.key 4096

# openssl rsa     -in ${SSL}/keys/poudriere.key -pubout \
                 -out ${SSL}/certs/poudriere.cert

… and ZFS datasets.

# zfs create -o mountpoint=/usr/local/poudriere zroot/poudriere

# zfs create -o mountpoint=/var/ccache          zroot/var/ccache

Now the Poudriere config.

[ CAUTION: BEGIN ]

Because of the ZROOTFS /usr/local bug I have switched the ZROOTFS variable to /dev/null and Poudriere still works well.

[ CAUTION: END ]

# IP=10.0.0.122

# cat << EOF > /usr/local/etc/poudriere.conf
ZPOOL=zroot
BASEFS=/usr/local/poudriere
ZROOTFS=/dev/null
FREEBSD_HOST=ftp://ftp.freebsd.org
POUDRIERE_DATA=/usr/local/poudriere/data
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key
URL_BASE=http://${IP}/
USE_TMPFS=no
TMPFS_LIMIT=12
MAX_MEMORY=12
PARALLEL_JOBS=4
PREPARE_PARALLEL_JOBS=4
MAX_FILES=4096
DISTFILES_CACHE=/usr/ports/distfiles
KEEP_OLD_PACKAGES=yes
KEEP_OLD_PACKAGES_COUNT=3
CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
CCACHE_DIR=/var/ccache
RESTRICT_NETWORKING=no
EOF

… and symlink for certificate that we will use later.

# mkdir -p /usr/local/poudriere/data/logs/bulk

# ln -s /usr/local/etc/ssl/certs/poudriere.cert \
        /usr/local/poudriere/data/logs/bulk/poudriere.cert

Nginx Setup

Simple Nginx config to host the packages.

# IP=10.0.0.122

# service nginx enable

# sed -i '' -E 's|text/plain[\t\ ]*txt|text/plain txt log|g' /usr/local/etc/nginx/mime.types

# cat << EOF > /usr/local/etc/nginx/nginx.conf

events {
  worker_connections 1024;
}

http {
  include      mime.types;
  default_type application/octet-stream;

  server {
    listen 80 default;
    server_name ${IP};
    root /usr/local/share/poudriere/html;

    location /data {
      alias /usr/local/poudriere/data/logs/bulk;
      autoindex on;
    }

    location /packages {
      root /usr/local/poudriere/data;
      autoindex on;
    }
  }
}
EOF

# service nginx restart

# sockstat -l4
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS      
www      nginx      83135 7  tcp4   *:80                  *:*
root     nginx      82843 7  tcp4   *:80                  *:*
root     sendmail   67293 5  tcp4   127.0.0.1:25          *:*
root     sshd       66135 5  tcp4   *:22                  *:*

Latest Ccache Version

Previous guide used older Ccache version 3.x along with some small Memcached addition/modification. I wrote that article just 4 months ago but even after such short period of time the ccache-memcached is not longer available.

I could use ‘generic’ Ccache 3.x or I could move to latest 4.x branch. I have chosen the latter.

It seems a wise decision as the last Ccache release from the 3.x tree (3.7.12) was released almost 3 years ago – on 2020/10/01.

Below we will configure Ccache to our needs.


# mkdir -p /var/ccache

# cat << EOF > /var/ccache/ccache.conf
max_size = 0
cache_dir = /var/ccache
base_dir = /var/ccache
hash_dir = false
EOF

We can check Ccache settings with -p option.

# ccache -p
(default) absolute_paths_in_stderr = false
(/var/ccache/ccache.conf) base_dir = /var/ccache
(/var/ccache/ccache.conf) cache_dir = /var/ccache
(default) compiler = 
(default) compiler_check = mtime
(default) compiler_type = auto
(default) compression = true
(default) compression_level = 0
(default) cpp_extension = 
(default) debug = false
(default) debug_dir = 
(default) depend_mode = false
(default) direct_mode = true
(default) disable = false
(default) extra_files_to_hash = 
(default) file_clone = false
(default) hard_link = false
(/var/ccache/ccache.conf) hash_dir = false
(default) ignore_headers_in_manifest = 
(default) ignore_options = 
(default) inode_cache = true
(default) keep_comments_cpp = false
(default) log_file = 
(default) max_files = 0
(/var/ccache/ccache.conf) max_size = 0 bytes
(default) msvc_dep_prefix = Note: including file:
(default) namespace = 
(default) path = 
(default) pch_external_checksum = false
(default) prefix_command = 
(default) prefix_command_cpp = 
(default) read_only = false
(default) read_only_direct = false
(default) recache = false
(default) remote_only = false
(default) remote_storage = 
(default) reshare = false
(default) run_second_cpp = true
(default) sloppiness = 
(default) stats = true
(default) stats_log = 
(default) temporary_dir = /var/ccache/tmp
(default) umask = 

… and its Ccache cache stats – currently empty as its a fresh install.


# ccache -s
Local storage:
  Cache size (GiB): 0.0

FreeIPA/IDM Repo

Now options to setup for our customized pkg(8) repo.

# cat << EOF > /usr/local/etc/poudriere.d/make.conf
ALLOW_UNSUPPORTED_SYSTEM=yes
DISABLE_LICENSES=yes
EOF

We will now create new jail(8) where our packages will be built.

# poudriere jail -c -j 13-2-R-amd64 -v 13.2-RELEASE
(...)

# poudriere jail -l
13-2-R-amd64 13.2-RELEASE-p1 amd64 http   2023-08-08 20:36:49 /usr/local/poudriere/jails/13-2-R-amd64

Up to date FreeBSD Ports tree will also be needed – we will create a separate idm profile for it.

# poudriere ports -c -p idm
(...)

# poudriere ports -l
idm       git+https 2023-08-09 20:31:07 /usr/local/poudriere/ports/idm

FreeIPA/IDM Configure Options

Below are the options we will have to choose to make our FreeBSD systems be able to join FreeIPA/IDM domain.

# poudriere options -c -n -p idm security/cyrus-sasl2-gssapi
//   SELECT: (*) GSSAPI_MIT

# poudriere options -c -n -p idm net/openldap26-client
//   SELECT: [x] GSSAPI

# poudriere options -c -n -p idm security/sudo
// DESELECT: [ ] PAM
//   SELECT: (*) GSSAPI_MIT
//   SELECT: (*) SSSD

# poudriere options -c -n -p idm security/sssd
//   SELECT: [x] SMB

These options were stored below.

I needed to replace the ANSI line graphics with universal ‘-‘ and ‘+‘ characters as WordPress had issues with them.


# tree /usr/local/etc/poudriere.d/idm-options
/usr/local/etc/poudriere.d/idm-options
+-- net_openldap26-client
|   +-- options
+-- security_cyrus-sasl2-gssapi
|   +-- options
+-- security_sssd
|   +-- options
+-- security_sudo
    +-- options

5 directories, 4 files

We will now specify packages that we want to be sure will be built of fetched from the latest branch.

# cat << EOF > /usr/local/etc/poudriere.d/idm
security/krb5
security/sudo
security/sssd
security/cyrus-sasl2
security/cyrus-sasl2-gssapi
security/pam_mkhomedir
net/openldap26-client
net/samba413
EOF


We can now start the build process.

# poudriere bulk -j 13-2-R-amd64 -b latest -p idm -f /usr/local/etc/poudriere.d/idm

The simplified output with (...) edits in between is shown below.

poudriere-devel-build-log-cut
The full log of such build process is available here.

If not much (or nothing) changed then the following update build process is very short and fast.

poudriere-devel-build-log-rebuild

This is how the built FreeIPA/IDM repo looks like in the Nginx interface.

poudriere-devel-built

After several such builds you will see historic versions as shown below.

poudriere-devel-several-times

Now – below is a summary about our created packages.

[13-2-R-amd64-idm] [2023-08-08_11h15m23s] [committing:] Queued: 197 Built: 11  Failed: 0   Skipped: 0   Ignored: 0   Fetched: 186 Tobuild: 0    Time: 00:17:17

To summarize:

  • From needed 197 packages only 11 were sent to compilation which means about 5.6% of them needed compilation.
  • During compilation of these 11 packages Ccache hit ratio was at 54.4% rate.

To make you visualize how much time was save here – let me just remind you that lang/gcc12 would need 12-16 hours of compilation and another 6-10 hours would be needed for lang/rust. These were only two packages … and the whole process tool about quarter of hour with these optimizations. Not to mention that compilation can sometimes fail – which leaves you without repo and needed packages and with even more work to figure out why it failed. Not worth the hassle IMHO.

The Ccache stats below.

# ccache -s
Cacheable calls:      44834 / 68237 (65.70%)
  Hits:               24389 / 44834 (54.40%)
    Direct:           21118 / 24389 (86.59%)
    Preprocessed:      3271 / 24389 (13.41%)
  Misses:             20445 / 44834 (45.60%)
Uncacheable calls:    23319 / 68237 (34.17%)
Errors:                  84 / 68237 ( 0.12%)
Local storage:
  Cache size (GiB): 65536.0

Some more Ccache stats and disk usage below.

# du -smA /var/ccache
1593    /var/ccache

# du -sm /var/ccache
827     /var/ccache

# zfs get compressratio zroot/var/ccache
NAME              PROPERTY       VALUE  SOURCE
zroot/var/ccache  compressratio  2.35x  -

# zfs list zroot/var/ccache
NAME               USED  AVAIL     REFER  MOUNTPOINT
zroot/var/ccache   841M  28.2G      841M  /var/ccache

Repo Update

Every time you will need to update the packages in that FreeIPA/IDM repo You will need to run these commands.

# poudriere ports -p idm -u

# poudriere jail -j 13-2-R-amd64 -u

# poudriere bulk -j 13-2-R-amd64 -b latest -p idm -f /usr/local/etc/poudriere.d/idm

Which means:

  • Update the idm FreeBSD Ports tree.
  • Update the 13.2-RELEASE 13-2-R-amd64 FreeBSD Jail container.
  • Rebuild/refetch packages against updated idm Ports and 13-2-R-amd64 Jail.

FreeBSD Client

This section would show how to use our newly create pkg(8) repo to install custom packages.

Lets bootstrap pkg(8) for a start with some random package.

# pkg install -y beadm

Copy repo certificate from Poudriere server.

# IP=10.0.0.122

# mkdir -p /usr/local/etc/ssl/certs

# fetch -o /usr/local/etc/ssl/certs/poudriere.cert http://${IP}/data/poudriere.cert

Disable default pkg(8) repo.

# mkdir -p /usr/local/etc/pkg/repos

# echo "FreeBSD: { enabled: no }" > /usr/local/etc/pkg/repos/FreeBSD.conf

Add our custom pkg(8) repository.


# IP=10.0.10.122

# mkdir -p /usr/local/etc/pkg/repos

# cat << EOF > /usr/local/etc/pkg/repos/13-2-R-amd64.conf
13-2-R-amd64-idm: {
    url: "http://${IP}/packages/13-2-R-amd64-idm/",
    mirror_type: "http",
    signature_type: "pubkey",
    pubkey: "/usr/local/etc/ssl/certs/poudriere.cert",
    enabled: yes,
    priority: 100
}
EOF

Update the pkg(8) metadata.

# pkg update

# pkg -vv | grep -A 99 Repositories:
Repositories:
  13-2-R-amd64-idm: { 
    url             : "http://10.0.0.122/packages/13-2-R-amd64-idm/",
    enabled         : yes,
    priority        : 100,
    mirror_type     : "HTTP",
    signature_type  : "PUBKEY",
    pubkey          : "/usr/local/etc/ssl/certs/poudriere.cert"
  }

Install the FreeIPA/IDM required client packages.

# pkg install -y      \
    krb5              \
    sudo              \
    sssd              \
    cyrus-sasl        \
    cyrus-sasl-gssapi \
    openldap26-client \
    pam_mkhomedir

… and now please continue with the FreeBSD Setup section of the older Connect FreeBSD 13.2 to FreeIPA/IDM guide because the client addon process did not changed.

Let me know in comments if something is not clear … or when You have better ideas then me πŸ™‚

EOF

11 thoughts on “FreeBSD on FreeIPA/IDM with Poudriere Repo

  1. Pingback: FreeBSD em Freeipa/IDM com Poudriere Repo – linux-BR.org

  2. Johan Hendriks's avatarJohan Hendriks

    Why not use the poudriere port options option instead of creating the port settings on the host machine and then copy the adjusted settings to the poudriere port settings.

    Tmux as an example in this case.

    $ poudriere options -p idm sysutils/tmux
    

    … or for a specific jail.

    $ poudriere options -j 13-2-R-amd64 -p idm sysutils/tmux
    

    … or select all options for all the ports in your build.

    $ poudriere options -j 13-2-R-amd64 -p idm
    

    Like

    Reply
    1. vermaden's avatarvermaden Post author

      Thank You.

      I once done that (with poudriere options command) but then moved to make(1) and for some reason I do not remember I stayed with it.

      I will check that again and update the article to use poudriere options command in next window of free time.

      Thanks,
      vermaden

      Like

      Reply
  3. Pingback: Links 11/08/2023: OpenSSH 9.4 Released, PostgreSQL 15.4 and PostgreSQL 16 Beta 3 | Techrights

  4. Pingback: Valuable News – 2023/08/14 | πšŸπšŽπš›πš–πšŠπšπšŽπš—

  5. Pingback: Simple FreeBSD Poudriere Harvester Guide | πšŸπšŽπš›πš–πšŠπšπšŽπš—

  6. Pingback: Connect FreeBSD 13.2 to FreeIPA/IDM | πšŸπšŽπš›πš–πšŠπšπšŽπš—

  7. Pingback: Personal FreeBSD PKGBASE Update Server | πšŸπšŽπš›πš–πšŠπšπšŽπš—

  8. Pingback: Connect FreeBSD 14.0-STABLE to FreeIPA/IDM | πšŸπšŽπš›πš–πšŠπšπšŽπš—

  9. Pingback: Keycloak Identity and Access Management on FreeBSD | πšŸπšŽπš›πš–πšŠπšπšŽπš—

  10. Pingback: FreeBSD Samba Share with FreeIPA/IDM Auth | πšŸπšŽπš›πš–πšŠπšπšŽπš—

Leave a comment