-
-
Notifications
You must be signed in to change notification settings - Fork 492
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allows the user to enable the Colima container runtime for macOS. Normally Colima is run inside the current user's their context, but I wanted to use Colima closer to how Docker works on Linux. Where the Docker daemon on Linux is run as the root user, and users have to either run the docker command with sudo, or add themselves to the docker group. Effectively enabling multi-user interaction on macOS. Just enabling the following config doesn't do a whole lot, as the user would have to log in as the colima user to interact with the colima VM. services.colima.enable = true; Instead, this module is meant to be used as follows, so that the user can use Colima as a Docker Desktop for macOS alternative. services.colima = { enable = true; enableDockerCompatability = true; }; This will set up everything for the Docker CLI to work with the Colima VM under the hood. Co-authored-by: Sam <[email protected]> Refs: https://github.com/abiosoft/colima
- Loading branch information
1 parent
bd92122
commit ec825fd
Showing
5 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { | ||
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 { | ||
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" | ||
]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
''; | ||
} |