Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

colima: init #1275

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions modules/misc/ids.nix
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ in
ids.uids = {
nixbld = lib.mkDefault 350;
_prometheus-node-exporter = 534;
colima = 400;
};

ids.gids = {
nixbld = lib.mkDefault (if config.system.stateVersion < 5 then 30000 else 350);
_prometheus-node-exporter = 534;
_colima = 400;
};

};
Expand Down
1 change: 1 addition & 0 deletions modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
./services/buildkite-agents.nix
./services/chunkwm.nix
./services/cachix-agent.nix
./services/colima
./services/dnsmasq.nix
./services/emacs.nix
./services/eternal-terminal.nix
Expand Down
192 changes: 192 additions & 0 deletions modules/services/colima/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
{
config,
lib,
pkgs,
...
}:

with lib;
let
cfg = config.services.colima;
user = config.users.users."colima";
group = config.users.groups."_colima";
in
{
options.services.colima = {
enable = mkEnableOption "Colima, a macOS container runtime";

enableDockerCompatability = mkOption {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
enableDockerCompatability = mkOption {
enableDockerCompatibility = mkOption {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And of course all other occurences of "compatability" -> "compatibility"

type = types.bool;
default = false;
description = ''
Create a symlink from Colima's socket to /var/run/docker.sock, and set
its permissions so that users part of the _colima group can use it.
'';
};

package = mkPackageOption pkgs "colima" { };

stateDir = lib.mkOption {
type = types.path;
default = "/var/lib/colima";
description = "State directory of the Colima process.";
};

logFile = mkOption {
type = types.path;
default = "/var/log/colima.log";
description = "Combined stdout and stderr of the colima process. Set to /dev/null to disable.";
};

groupMembers = mkOption {
type = types.listOf types.str;
default = [ ];
description = ''
List of users that should be added to the _colima group.
Only has effect with enableDockerCompatability enabled.
'';
};

runtime = mkOption {
type = types.enum [
"docker"
"containerd"
"incus"
];
default = "docker";
description = "The runtime to use with Colima.";
};

architectue = mkOption {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
architectue = mkOption {
architecture = mkOption {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And all other occurences of "architectue" -> "architecture"

type = types.enum [
"x86_64"
"aarch64"
"host"
];
default = "host";
description = "The architecture to use for the Colima virtual machine.";
};

extraFlags = mkOption {
type = types.listOf types.str;
default = [ ];
example = [ "--vz-rosetta" ];
description = "Extra commandline options to pass to the colima start command.";
};

vmType = mkOption {
type = types.enum [
"qemu"
"vz"
];
default = "vz";
description = "Virtual machine type to use with Colima.";
};
};

config = mkMerge [
(mkIf cfg.enableDockerCompatability {
assertions = [
{
assertion = !cfg.enable;
message = "services.colima.enableDockerCompatability doesn't make sense without enabling services.colima.enable";
}
];

launchd.daemons.colima-docker-compat = {
script = ''
# Wait for the docker socket to be created. This is important when
# we enabled Colima and Docker compatability at the same time, for
# the first time. Colima takes a while creating the VM.
until [ -S ${cfg.stateDir}/.colima/default/docker.sock ]
do
sleep 5
done

chmod g+rw ${cfg.stateDir}/.colima/default/docker.sock
ln -sf ${cfg.stateDir}/.colima/default/docker.sock /var/run/docker.sock
'';

serviceConfig = {
RunAtLoad = true;
EnvironmentVariables.PATH = "/usr/bin:/bin:/usr/sbin:/sbin";
};
};

users.groups."_colima".members = cfg.groupMembers;

environment.systemPackages = [
pkgs.docker
];
})

(mkIf cfg.enable {
launchd.daemons.colima = {
script =
concatStringsSep " " [
"exec"
(getExe cfg.package)
"start"
"--foreground"
"--runtime ${cfg.runtime}"
"--arch ${cfg.architectue}"
"--vm-type ${cfg.vmType}"
]
+ escapeShellArgs cfg.extraFlags;

serviceConfig = {
KeepAlive = true;
RunAtLoad = true;
StandardErrorPath = cfg.logFile;
StandardOutPath = cfg.logFile;
GroupName = group.name;
UserName = user.name;
WorkingDirectory = cfg.stateDir;
EnvironmentVariables = {
PATH = "${pkgs.colima}/bin:${pkgs.docker}/bin:/usr/bin:/bin:/usr/sbin:/sbin";
COLIMA_HOME = "${cfg.stateDir}/.colima";
};
};
};

system.activationScripts.preActivation.text = ''
touch '${cfg.logFile}'
chown ${toString user.uid}:${toString user.gid} '${cfg.logFile}'
'';

users = {
knownGroups = [
"colima"
"_colima"
];
knownUsers = [
"colima"
"_colima"
];
};

users.users."colima" = {
uid = config.ids.uids.colima;
gid = config.ids.gids._colima;
home = cfg.stateDir;
# The username isn't allowed to have an underscore in the beginning of
# its name, otherwise the VM will fail to start with the following error
# > "[hostagent] identifier \"_colima\" must match ^[A-Za-z0-9]+(?:[._-](?:[A-Za-z0-9]+))*$: invalid argument" fields.level=fatal
name = "colima";
createHome = true;
shell = "/bin/bash";
description = "System user for Colima";
};

users.groups."_colima" = {
gid = config.ids.gids._colima;
name = "_colima";
description = "System group for Colima";
};
})
];

meta.maintainers = [
lib.maintainers.bryanhonof or "bryanhonof"
];
}
1 change: 1 addition & 0 deletions release.nix
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ in {
tests.services-activate-system = makeTest ./tests/services-activate-system.nix;
tests.services-activate-system-changed-label-prefix = makeTest ./tests/services-activate-system-changed-label-prefix.nix;
tests.services-buildkite-agent = makeTest ./tests/services-buildkite-agent.nix;
tests.services-colima = makeTest ./tests/services-colima.nix;
tests.services-github-runners = makeTest ./tests/services-github-runners.nix;
tests.services-lorri = makeTest ./tests/services-lorri.nix;
tests.services-nix-daemon = makeTest ./tests/services-nix-daemon.nix;
Expand Down
45 changes: 45 additions & 0 deletions tests/services-colima.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{ config, pkgs, ... }:

let
colima = pkgs.runCommand "colima-0.0.0" { } "mkdir $out";
in

{
services.colima = {
enable = true;
enableDockerCompatability = true;
package = colima;
groupMembers = [ "john" "jane" ];
};

test = ''
echo "checking colima service in /Library/LaunchDaemons" >&2
grep "org.nixos.colima" ${config.out}/Library/LaunchDaemons/org.nixos.colima.plist
grep "${colima}/bin/dnsmasq" ${config.out}/Library/LaunchDaemons/org.nixos.colima.plist

echo "checking colima docker compat service in /Library/LaunchDaemons" >&2
grep "org.nixos.colima-docker-compat" ${config.out}/Library/LaunchDaemons/org.nixos.colima-docker-compat.plist

echo "checking colima config" >&2
grep -F "--foreground" ${config.out}/Library/LaunchDaemons/org.nixos.colima.plist
grep -F "--runtime docker" ${config.out}/Library/LaunchDaemons/org.nixos.colima.plist
grep -F "--architectue host" ${config.out}/Library/LaunchDaemons/org.nixos.colima.plist

echo "checking user creation in /activate" >&2
grep "sysadminctl -addUser ${lib.escapeShellArgs [ "foo" "-UID" config.ids.uids.colima "-GID" config.ids.uids._colima "-fullName" "colima" "-home" "/var/lib/colima" "-shell" "/bin/bash" ]}" ${config.out}/activate
grep "createhomedir -cu ${lib.escapeShellArg "colima"}" ${config.out}/activate
grep "sysadminctl -addUser ${lib.escapeShellArgs [ "colima" "-UID" config.ids.uids.colima ]} .* ${lib.escapeShellArgs [ "-shell" "/bin/bash" ] }" ${config.out}/activate
grep "sysadminctl -addUser ${lib.escapeShellArg "colima"} .* ${lib.escapeShellArgs [ "-home" "/var/lib/colima" ]}" ${config.out}/activate
(! grep "dscl . -delete ${lib.escapeShellArg "/Users/colima"}" ${config.out}/activate)
(! grep "dscl . -delete ${lib.escapeShellArg "/Groups/_colima"}" ${config.out}/activate)

echo "checking group creation in /activate" >&2
grep "dscl . -create ${lib.escapeShellArg "/Groups/_colima"} PrimaryGroupID ${builtins.toString config.ids.gids._colima}" ${config.out}/activate
grep "dscl . -create ${lib.escapeShellArg "/Groups/_colima"} RealName ${lib.escapeShellArg "_colima"}" ${config.out}/activate
grep "dscl . -create ${lib.escapeShellArg "/Groups/_colima"} PrimaryGroupID ${builtins.toString config.ids.gids._colima}" ${config.out}/activate
(! grep "dscl . -delete ${lib.escapeShellArg "/Groups/_colima"}" ${config.out}/activate)

echo "checking group membership in /activate" >&2
grep "dscl . -create ${lib.escapeShellArg "/Groups/_colima"} GroupMembership ${lib.escapeShellArgs [ "john" "jane" ]}" ${config.out}/activate
'';
}
Loading