modules/services/colima: init
This commit is contained in:
parent
d787ec69c3
commit
58bf3ecb2d
11 changed files with 488 additions and 0 deletions
9
modules/misc/news/2025/10/2025-10-15_10-44-58.nix
Normal file
9
modules/misc/news/2025/10/2025-10-15_10-44-58.nix
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
time = "2025-10-14T23:44:58+00:00";
|
||||
condition = true;
|
||||
message = ''
|
||||
A new module is available: `services.colima`
|
||||
|
||||
Colima is a tool for orchestrating container runtimes under a linux VM.
|
||||
'';
|
||||
}
|
||||
266
modules/services/colima.nix
Normal file
266
modules/services/colima.nix
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.services.colima;
|
||||
yamlFormat = pkgs.formats.yaml { };
|
||||
in
|
||||
{
|
||||
meta.maintainers = [
|
||||
lib.hm.maintainers.will-lol
|
||||
];
|
||||
|
||||
options.services.colima = {
|
||||
enable = lib.mkEnableOption "Colima, a container runtime";
|
||||
|
||||
package = lib.mkPackageOption pkgs "colima" { };
|
||||
dockerPackage = lib.mkPackageOption pkgs "docker" {
|
||||
extraDescription = "Used by colima to activate profiles. Not needed if no profile is set to isActive.";
|
||||
};
|
||||
perlPackage = lib.mkPackageOption pkgs "perl" {
|
||||
extraDescription = "Used by colima during image download for the shasum command.";
|
||||
};
|
||||
sshPackage = lib.mkPackageOption pkgs "openssh" {
|
||||
extraDescription = "Used by colima to manage the vm.";
|
||||
};
|
||||
coreutilsPackage = lib.mkPackageOption pkgs "coreutils" {
|
||||
extraDescription = "Used in various ways by colima.";
|
||||
};
|
||||
curlPackage = lib.mkPackageOption pkgs "curl" {
|
||||
extraDescription = "Used by colima to donwload images.";
|
||||
};
|
||||
bashPackage = lib.mkPackageOption pkgs "bashNonInteractive" {
|
||||
extraDescription = "Used by colima's internal scripts.";
|
||||
};
|
||||
|
||||
profiles = lib.mkOption {
|
||||
default = {
|
||||
default = {
|
||||
isActive = true;
|
||||
isService = true;
|
||||
};
|
||||
};
|
||||
description = ''
|
||||
Profiles allow multiple colima configurations. The default profile is active by default.
|
||||
If you have used colima before, you may need to delete existing configuration using `colima delete` or use a different profile.
|
||||
|
||||
Note that removing a configured profile will not delete the corresponding Colima instance.
|
||||
You will need to manually run `colima delete <profile-name>` to remove the instance and release resources.
|
||||
'';
|
||||
example = ''
|
||||
{
|
||||
default = {
|
||||
isActive = true;
|
||||
isService = true;
|
||||
};
|
||||
rosetta = {
|
||||
isService = true;
|
||||
settings.rosetta = true;
|
||||
};
|
||||
powerful = {
|
||||
settings.cpu = 8;
|
||||
};
|
||||
};
|
||||
'';
|
||||
type = lib.types.attrsOf (
|
||||
lib.types.submodule (
|
||||
{ name, ... }:
|
||||
{
|
||||
options = {
|
||||
name = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = name;
|
||||
readOnly = true;
|
||||
description = "The profile's name.";
|
||||
};
|
||||
|
||||
isService = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether this profile will run as a service.
|
||||
'';
|
||||
};
|
||||
|
||||
isActive = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
example = true;
|
||||
description = ''
|
||||
Whether to set this profile as:
|
||||
- active docker context
|
||||
- active kubernetes context
|
||||
- active incus remote
|
||||
Exactly one or zero profiles should have this option set.
|
||||
'';
|
||||
};
|
||||
|
||||
logFile = lib.mkOption {
|
||||
type = lib.types.path;
|
||||
default = "${config.home.homeDirectory}/.local/state/colima-${name}.log";
|
||||
defaultText = lib.literalExpression "\${config.home.homeDirectory}/.local/state/colima-\${name}.log";
|
||||
description = "Combined stdout and stderr log file for the Colima service.";
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
inherit (yamlFormat) type;
|
||||
default = { };
|
||||
description = "Colima configuration settings, see <https://github.com/abiosoft/colima/blob/main/embedded/defaults/colima.yaml> or run `colima template`.";
|
||||
example = ''
|
||||
{
|
||||
cpu = 2;
|
||||
disk = 100;
|
||||
memory = 2;
|
||||
arch = "host";
|
||||
runtime = "docker";
|
||||
hostname = null;
|
||||
kubernetes = {
|
||||
enabled = false;
|
||||
version = "v1.33.3+k3s1";
|
||||
k3sArgs = [ "--disable=traefik" ];
|
||||
port = 0;
|
||||
};
|
||||
autoActivate = true;
|
||||
network = {
|
||||
address = false;
|
||||
mode = "shared";
|
||||
interface = "en0";
|
||||
preferredRoute = false;
|
||||
dns = [ ];
|
||||
dnsHosts = {
|
||||
"host.docker.internal" = "host.lima.internal";
|
||||
};
|
||||
hostAddresses = false;
|
||||
};
|
||||
forwardAgent = false;
|
||||
docker = { };
|
||||
vmType = "qemu";
|
||||
portForwarder = "ssh";
|
||||
rosetta = false;
|
||||
binfmt = true;
|
||||
nestedVirtualization = false;
|
||||
mountType = "sshfs";
|
||||
mountInotify = false;
|
||||
cpuType = "host";
|
||||
provision = [ ];
|
||||
sshConfig = true;
|
||||
sshPort = 0;
|
||||
mounts = [ ];
|
||||
diskImage = "";
|
||||
rootDisk = 20;
|
||||
env = { };
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable ({
|
||||
assertions = [
|
||||
{
|
||||
assertion = (lib.count (p: p.isActive) (lib.attrValues cfg.profiles)) <= 1;
|
||||
message = "Only one Colima profile can be active at a time.";
|
||||
}
|
||||
];
|
||||
|
||||
home.packages = lib.mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
home.file = lib.mkMerge (
|
||||
lib.mapAttrsToList (profileName: profile: {
|
||||
".colima/${profileName}/colima.yaml" = {
|
||||
source = yamlFormat.generate "colima.yaml" profile.settings;
|
||||
};
|
||||
}) (lib.filterAttrs (name: profile: profile.settings != { }) cfg.profiles)
|
||||
);
|
||||
|
||||
programs.docker-cli.settings.currentContext =
|
||||
let
|
||||
activeProfile = lib.findFirst (p: p.isActive) null (lib.attrValues cfg.profiles);
|
||||
in
|
||||
lib.mkIf (activeProfile != null) (
|
||||
if activeProfile.name != "default" then "colima-${activeProfile.name}" else "colima"
|
||||
);
|
||||
|
||||
launchd.agents = lib.mkIf pkgs.stdenv.isDarwin (
|
||||
lib.mapAttrs' (
|
||||
name: profile:
|
||||
lib.nameValuePair "colima-${name}" {
|
||||
enable = true;
|
||||
config = {
|
||||
ProgramArguments = [
|
||||
"${lib.getExe cfg.package}"
|
||||
"start"
|
||||
name
|
||||
"-f"
|
||||
"--activate=${if profile.isActive then "true" else "false"}"
|
||||
"--save-config=false"
|
||||
];
|
||||
KeepAlive = true;
|
||||
RunAtLoad = true;
|
||||
EnvironmentVariables.PATH = lib.makeBinPath [
|
||||
cfg.package
|
||||
cfg.perlPackage
|
||||
cfg.dockerPackage
|
||||
cfg.sshPackage
|
||||
cfg.coreutilsPackage
|
||||
cfg.curlPackage
|
||||
cfg.bashPackage
|
||||
pkgs.darwin.DarwinTools
|
||||
];
|
||||
StandardOutPath = profile.logFile;
|
||||
StandardErrorPath = profile.logFile;
|
||||
};
|
||||
}
|
||||
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
|
||||
);
|
||||
|
||||
systemd.user.services = lib.mkIf pkgs.stdenv.isLinux (
|
||||
lib.mapAttrs' (
|
||||
name: profile:
|
||||
lib.nameValuePair "colima-${name}" {
|
||||
Unit = {
|
||||
Description = "Colima container runtime (${name} profile)";
|
||||
After = [ "network-online.target" ];
|
||||
Wants = [ "network-online.target" ];
|
||||
};
|
||||
Service = {
|
||||
ExecStart = ''
|
||||
${lib.getExe cfg.package} start ${name} \
|
||||
-f \
|
||||
--activate=${if profile.isActive then "true" else "false"} \
|
||||
--save-config=false
|
||||
'';
|
||||
Restart = "always";
|
||||
RestartSec = 2;
|
||||
Environment = [
|
||||
"PATH=${
|
||||
lib.makeBinPath [
|
||||
cfg.package
|
||||
cfg.perlPackage
|
||||
cfg.dockerPackage
|
||||
cfg.sshPackage
|
||||
cfg.coreutilsPackage
|
||||
cfg.curlPackage
|
||||
cfg.bashPackage
|
||||
]
|
||||
}"
|
||||
];
|
||||
StandardOutput = "append:${profile.logFile}";
|
||||
StandardError = "append:${profile.logFile}";
|
||||
};
|
||||
Install = {
|
||||
WantedBy = [ "default.target" ];
|
||||
};
|
||||
}
|
||||
) (lib.filterAttrs (_: p: p.isService) cfg.profiles)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
services.colima = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "colima";
|
||||
outPath = "@colima@";
|
||||
};
|
||||
dockerPackage = config.lib.test.mkStubPackage {
|
||||
name = "docker";
|
||||
outPath = "@docker@";
|
||||
};
|
||||
perlPackage = config.lib.test.mkStubPackage {
|
||||
name = "perl";
|
||||
outPath = "@perl@";
|
||||
};
|
||||
sshPackage = config.lib.test.mkStubPackage {
|
||||
name = "openssh";
|
||||
outPath = "@openssh@";
|
||||
};
|
||||
|
||||
profiles.default.settings = {
|
||||
cpu = 4;
|
||||
memory = 8;
|
||||
kubernetes.enabled = true;
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.colima/default/colima.yaml
|
||||
assertFileContent home-files/.colima/default/colima.yaml ${./custom-settings-expected.yaml}
|
||||
'';
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
nixpkgs.overlays = [
|
||||
(self: super: {
|
||||
darwin = super.darwin // {
|
||||
DarwinTools = config.lib.test.mkStubPackage {
|
||||
name = "DarwinTools";
|
||||
outPath = "@DarwinTools@";
|
||||
};
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
services.colima = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "colima";
|
||||
outPath = "@colima@";
|
||||
};
|
||||
dockerPackage = config.lib.test.mkStubPackage {
|
||||
name = "docker";
|
||||
outPath = "@docker@";
|
||||
};
|
||||
perlPackage = config.lib.test.mkStubPackage {
|
||||
name = "perl";
|
||||
outPath = "@perl@";
|
||||
};
|
||||
sshPackage = config.lib.test.mkStubPackage {
|
||||
name = "openssh";
|
||||
outPath = "@openssh@";
|
||||
};
|
||||
coreutilsPackage = config.lib.test.mkStubPackage {
|
||||
name = "coreutils";
|
||||
outPath = "@coreutils@";
|
||||
};
|
||||
curlPackage = config.lib.test.mkStubPackage {
|
||||
name = "curl";
|
||||
outPath = "@curl@";
|
||||
};
|
||||
bashPackage = config.lib.test.mkStubPackage {
|
||||
name = "bashNonInteractive";
|
||||
outPath = "@bashNonInteractive@";
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertPathNotExists home-files/.colima/default/colima.yaml
|
||||
|
||||
serviceFile=LaunchAgents/org.nix-community.home.colima-default.plist
|
||||
|
||||
assertFileExists "$serviceFile"
|
||||
|
||||
assertFileContent "$serviceFile" ${./expected-agent.plist}
|
||||
'';
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
cpu: 4
|
||||
kubernetes:
|
||||
enabled: true
|
||||
memory: 8
|
||||
4
tests/modules/services/colima/darwin/default.nix
Normal file
4
tests/modules/services/colima/darwin/default.nix
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"colima-default-config" = ./colima-default-config.nix;
|
||||
"colima-custom-settings" = ./colima-custom-settings.nix;
|
||||
}
|
||||
30
tests/modules/services/colima/darwin/expected-agent.plist
Normal file
30
tests/modules/services/colima/darwin/expected-agent.plist
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>EnvironmentVariables</key>
|
||||
<dict>
|
||||
<key>PATH</key>
|
||||
<string>@colima@/bin:@perl@/bin:@docker@/bin:@openssh@/bin:@coreutils@/bin:@curl@/bin:@bashNonInteractive@/bin:@DarwinTools@/bin</string>
|
||||
</dict>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>org.nix-community.home.colima-default</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>@colima@/bin/colima</string>
|
||||
<string>start</string>
|
||||
<string>default</string>
|
||||
<string>-f</string>
|
||||
<string>--activate=true</string>
|
||||
<string>--save-config=false</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/home/hm-user/.local/state/colima-default.log</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/home/hm-user/.local/state/colima-default.log</string>
|
||||
</dict>
|
||||
</plist>
|
||||
3
tests/modules/services/colima/default.nix
Normal file
3
tests/modules/services/colima/default.nix
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{ lib, pkgs, ... }:
|
||||
(lib.optionalAttrs pkgs.stdenv.hostPlatform.isDarwin (import ./darwin/default.nix))
|
||||
// (lib.optionalAttrs pkgs.stdenv.hostPlatform.isLinux (import ./linux/default.nix))
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
services.colima = {
|
||||
enable = true;
|
||||
package = config.lib.test.mkStubPackage {
|
||||
name = "colima";
|
||||
outPath = "@colima@";
|
||||
};
|
||||
dockerPackage = config.lib.test.mkStubPackage {
|
||||
name = "docker";
|
||||
outPath = "@docker@";
|
||||
};
|
||||
perlPackage = config.lib.test.mkStubPackage {
|
||||
name = "perl";
|
||||
outPath = "@perl@";
|
||||
};
|
||||
sshPackage = config.lib.test.mkStubPackage {
|
||||
name = "openssh";
|
||||
outPath = "@openssh@";
|
||||
};
|
||||
coreutilsPackage = config.lib.test.mkStubPackage {
|
||||
name = "coreutils";
|
||||
outPath = "@coreutils@";
|
||||
};
|
||||
curlPackage = config.lib.test.mkStubPackage {
|
||||
name = "curl";
|
||||
outPath = "@curl@";
|
||||
};
|
||||
bashPackage = config.lib.test.mkStubPackage {
|
||||
name = "bashNonInteractive";
|
||||
outPath = "@bashNonInteractive@";
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertPathNotExists home-files/.colima/default/colima.yaml
|
||||
|
||||
assertFileExists home-files/.config/systemd/user/colima-default.service
|
||||
|
||||
assertFileContent \
|
||||
home-files/.config/systemd/user/colima-default.service \
|
||||
${./expected-service.service}
|
||||
'';
|
||||
}
|
||||
3
tests/modules/services/colima/linux/default.nix
Normal file
3
tests/modules/services/colima/linux/default.nix
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"colima-default-config" = ./colima-default-config.nix;
|
||||
}
|
||||
19
tests/modules/services/colima/linux/expected-service.service
Normal file
19
tests/modules/services/colima/linux/expected-service.service
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
[Service]
|
||||
Environment=PATH=@colima@/bin:@perl@/bin:@docker@/bin:@openssh@/bin:@coreutils@/bin:@curl@/bin:@bashNonInteractive@/bin
|
||||
ExecStart=@colima@/bin/colima start default \
|
||||
-f \
|
||||
--activate=true \
|
||||
--save-config=false
|
||||
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
StandardError=append:/home/hm-user/.local/state/colima-default.log
|
||||
StandardOutput=append:/home/hm-user/.local/state/colima-default.log
|
||||
|
||||
[Unit]
|
||||
After=network-online.target
|
||||
Description=Colima container runtime (default profile)
|
||||
Wants=network-online.target
|
||||
Loading…
Add table
Add a link
Reference in a new issue