colima.nix 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. {
  2. config,
  3. lib,
  4. pkgs,
  5. ...
  6. }:
  7. with lib;
  8. let
  9. cfg = config.services.colima;
  10. user = config.users.users."colima";
  11. group = config.users.groups."_colima";
  12. in
  13. {
  14. options.services.colima = {
  15. enable = mkEnableOption "Container runtimes on macOS";
  16. createDockerSocket = mkEnableOption ''
  17. Create a symlink from Colima's socket to /var/run/docker.sock, and set
  18. it's permissions so that users part of the _colima group can use it.
  19. '';
  20. package = mkOption {
  21. type = types.package;
  22. default = pkgs.colima;
  23. defaultText = literalExpression "pkgs.colima";
  24. };
  25. logFile = mkOption {
  26. type = types.path;
  27. default = "/var/log/colima.log";
  28. description = "Stdout and sterr of the colima process.";
  29. };
  30. groupMembers = mkOption {
  31. type = types.listOf types.str;
  32. default = [ ];
  33. description = "List of users that should be added to the colima group.";
  34. };
  35. runtime = mkOption {
  36. type = types.enum [
  37. "docker"
  38. "containerd"
  39. "incus"
  40. ];
  41. default = "docker";
  42. description = "The runtime to use with Colima.";
  43. };
  44. architectue = mkOption {
  45. type = types.enum [
  46. "x86_64"
  47. "aarch64"
  48. "host"
  49. ];
  50. default = "host";
  51. description = "The architecture to use for the Colima virtual machine.";
  52. };
  53. extraFlags = mkOption {
  54. type = types.listOf types.str;
  55. default = [ ];
  56. example = [ "--vz-rosetta" ];
  57. description = "Extra commandline options to pass to the colima start command.";
  58. };
  59. vmType = mkOption {
  60. type = types.enum [
  61. "qemu"
  62. "vz"
  63. ];
  64. default = "vz";
  65. description = "Virtual machine type to use with Colima.";
  66. };
  67. };
  68. config = mkIf cfg.enable {
  69. launchd.daemons.colima-create-docker-socket-and-set-permissions = {
  70. script = ''
  71. until [ -S ${user.home}/.colima/default/docker.sock ]
  72. do
  73. sleep 5
  74. done
  75. chmod g+rw ${user.home}/.colima/default/docker.sock
  76. ln -sf ${user.home}/.colima/default/docker.sock /var/run/docker.sock
  77. '';
  78. serviceConfig.RunAtLoad = cfg.createDockerSocket;
  79. serviceConfig.EnvironmentVariables.PATH = "/usr/bin:/bin:/usr/sbin:/sbin";
  80. };
  81. launchd.daemons.colima = {
  82. script = concatStringsSep " " (
  83. [
  84. "exec"
  85. (getExe cfg.package)
  86. "start"
  87. "--foreground"
  88. "--runtime ${cfg.runtime}"
  89. "--arch ${cfg.architectue}"
  90. "--vm-type ${cfg.vmType}"
  91. ]
  92. ++ cfg.extraFlags
  93. );
  94. serviceConfig.KeepAlive = true;
  95. serviceConfig.RunAtLoad = true;
  96. serviceConfig.StandardErrorPath = cfg.logFile;
  97. serviceConfig.StandardOutPath = cfg.logFile;
  98. serviceConfig.GroupName = group.name;
  99. serviceConfig.UserName = user.name;
  100. serviceConfig.WorkingDirectory = user.home;
  101. serviceConfig.EnvironmentVariables = {
  102. PATH = "${pkgs.colima}/bin:${pkgs.docker}/bin:/usr/bin:/bin:/usr/sbin:/sbin";
  103. COLIMA_HOME = "${user.home}/.colima";
  104. };
  105. };
  106. system.activationScripts.preActivation.text = ''
  107. touch '${cfg.logFile}'
  108. chown ${toString user.uid}:${toString user.gid} '${cfg.logFile}'
  109. '';
  110. users.knownGroups = [
  111. "colima"
  112. "_colima"
  113. ];
  114. users.knownUsers = [
  115. "colima"
  116. "_colima"
  117. ];
  118. users.users."colima" = {
  119. uid = mkDefault 400;
  120. gid = mkDefault group.gid;
  121. home = mkDefault "/var/lib/colima";
  122. # The username isn't allowed to have an underscore in its name, the VM
  123. # will fail to start with the following error otherwise
  124. # > "[hostagent] identifier \"_colima\" must match ^[A-Za-z0-9]+(?:[._-](?:[A-Za-z0-9]+))*$: invalid argument" fields.level=fatal
  125. name = "colima";
  126. createHome = true;
  127. shell = "/bin/bash";
  128. description = "System user for Colima";
  129. };
  130. users.groups."_colima" = {
  131. gid = mkDefault 32002;
  132. name = "_colima";
  133. description = "System group for Colima";
  134. };
  135. users.groups."_colima".members = cfg.groupMembers;
  136. };
  137. meta.maintainers = [
  138. lib.maintainers.bryanhonof or "bryanhonof"
  139. ];
  140. }