Mitigating the singularity of codebuff

· nat's blog


This article was written for "ubuntu:latest". It is probably wiser to use something else, so some of the problems encountered here do not surface. See Installing codebuff below.

Anyway, put codebuff into a distrobox. Export the command.

Setup a new user on the host and in the distrobox #

Need a new user on the host (groupid is important, you figure out which one to use. I changed my default group from "nat" to "develop").

1sudo useradd -m -u 1500 -g develop nat-bot

As the user has no password set, he can't login. Perfect security...

You do the same in the distrobox with:

1sudo groupmod -n develop nat
2sudo useradd -m -u 1500 -g develop nat-bot 

Run codebuff with this user #

So this assumes we are using docker underneath distrobox.

Edit which codebuff to use the new user:

 1#!/bin/sh
 2# distrobox_binary
 3# name: codebuff
 4if [ -z "${CONTAINER_ID}" ]; then
 5	exec "/usr/local/bin/distrobox-enter" \
 6	       -n codebuff  \
 7  	       --additional-flags "--user nat-bot:develop" \
 8	       -- '/usr/local/bin/codebuff'  "$@"
 9elif [ -n "${CONTAINER_ID}" ] && [ "${CONTAINER_ID}" != "codebuff" ]; then
10	exec distrobox-host-exec '/home/nat/bin/codebuff'  "$@"
11else
12	exec '/usr/local/bin/codebuff' "$@"
13fi

The command codebuff will be executed now as the user nat-bot. Unfortunately, you will notice that the files codebuff writes will be created with umask 022, so they are not writable for other users in the group "develop", namely myself.

Fix umask #

Running a docker with the nat-bot user does not change the user "inside" the docker. The user is still nat. This just affects the files on the host.

The easy way #

Change the umask in the script before calling the codebuff command. In the line -- '/usr/local/bin/codebuff' "$@" you can force to use a login shell with bash -l and execute multiple arguments with bash -c. We need to pass the command and the arguments as escaped strings to the bash now. You could also do the escaping with /bin/sh, but its more painful, so we switch to bash for the script:

 1#! /usr/bin/env bash
 2...
 3	cmdline="umask 002 ; /usr/local/bin/codebuff"
 4	for arg in "$@"
 5	do
 6		printf -v cmdline "%s %q" "${cmdline}" "$arg"
 7	done
 8
 9	exec "/usr/local/bin/distrobox-enter" \
10            -n codebuff  \
11            --additional-flags "--user nat-bot:develop" \
12            -- /usr/bin/bash -l -c "${cmdline}"

Here we actually don't need to create a login shell with -l. This still might be preferable though.

The hard way #

We want to set the umask system wide in the distronox for all users. One is "supposed to" use PAM for this. But that does not work properly with debian and/or distrobox

debian #

The documented way to a system wide umask for a linux system is to edit /etc/login.defs and set the UMASK variable. As simple as that sounds, it doesn't work. Why I don't know really, but there is a Stackoverflow answer.

The main take away is, I quote the answer:

... a small shell script in /etc/profile.d/ [that is] calling umask 002

I beautified this a bit with:

1umask $(grep "^UMASK" /etc/login.defs | awk '{print $2}')

Unfortunately files created with codebuff are still umask 0022 after this, even after stopping the distrobox and restarting it.

distrobox #

Now I surmise the following: when you run a distrobox exported command, you are not running a login shell and the command bypasses PAM.

So we need to make sure we are running a login shell. This is done by:

 1#! /usr/bin/env bash
 2...
 3	cmdline="/usr/local/bin/codebuff"
 4	for arg in "$@"
 5	do
 6		printf -v cmdline "%s %q" "${cmdline}" "$arg"
 7	done
 8
 9	exec "/usr/local/bin/distrobox-enter" \
10            -n codebuff  \
11            --additional-flags "--user nat-bot:develop" \
12            -- /usr/bin/bash -l -c "${cmdline}"

Installing codebuff #

In tumbleweed (OpenSUSE) #

Use distrobox --image "registry.opensuse.org/opensuse/tumbleweed"

1sudo zypper install -y curl pattern:devel_basis

Use distrobox --image "ubuntu:latest"

1sudo apt-get install curl build-essential

Currently fails because a newer C++ compiler is needed, then the one provided by ubunutu:latest. (Jan-2025)

Install nvm and node #

1sudo mkdir -p /opt/nvm
2sudo chown `id -u` /opt/nvm
3export NVM_DIR="/opt/nvm"
4curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
5[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" 
6nvm install node

Install codebuff #

1npm install -g codebuff

Export codebuff #

1sudo ln -s -f `which codebuff` /usr/local/bin/codebuff
2distrobox-export --bin /usr/local/bin/codebuff --export-path /home/nat/bin

As we need the environment variables in the distrobox, we need to use bash -l in our exported script.