at 23.11-pre 3.6 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.virtualisation.anbox; 8 kernelPackages = config.boot.kernelPackages; 9 addrOpts = v: addr: pref: name: { 10 address = mkOption { 11 default = addr; 12 type = types.str; 13 description = lib.mdDoc '' 14 IPv${toString v} ${name} address. 15 ''; 16 }; 17 18 prefixLength = mkOption { 19 default = pref; 20 type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128)); 21 description = lib.mdDoc '' 22 Subnet mask of the ${name} address, specified as the number of 23 bits in the prefix (`${if v == 4 then "24" else "64"}`). 24 ''; 25 }; 26 }; 27 28in 29 30{ 31 32 options.virtualisation.anbox = { 33 34 enable = mkEnableOption (lib.mdDoc "Anbox"); 35 36 image = mkOption { 37 default = pkgs.anbox.image; 38 defaultText = literalExpression "pkgs.anbox.image"; 39 type = types.package; 40 description = lib.mdDoc '' 41 Base android image for Anbox. 42 ''; 43 }; 44 45 extraInit = mkOption { 46 type = types.lines; 47 default = ""; 48 description = lib.mdDoc '' 49 Extra shell commands to be run inside the container image during init. 50 ''; 51 }; 52 53 ipv4 = { 54 container = addrOpts 4 "192.168.250.2" 24 "Container"; 55 gateway = addrOpts 4 "192.168.250.1" 24 "Host"; 56 57 dns = mkOption { 58 default = "1.1.1.1"; 59 type = types.str; 60 description = lib.mdDoc '' 61 Container DNS server. 62 ''; 63 }; 64 }; 65 }; 66 67 config = mkIf cfg.enable { 68 69 assertions = singleton { 70 assertion = versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.18"; 71 message = "Anbox needs user namespace support to work properly"; 72 }; 73 74 environment.systemPackages = with pkgs; [ anbox ]; 75 76 services.udev.extraRules = '' 77 KERNEL=="ashmem", NAME="%k", MODE="0666" 78 KERNEL=="binder*", NAME="%k", MODE="0666" 79 ''; 80 81 virtualisation.lxc.enable = true; 82 networking.bridges.anbox0.interfaces = []; 83 networking.interfaces.anbox0.ipv4.addresses = [ cfg.ipv4.gateway ]; 84 85 networking.nat = { 86 enable = true; 87 internalInterfaces = [ "anbox0" ]; 88 }; 89 90 systemd.services.anbox-container-manager = let 91 anboxloc = "/var/lib/anbox"; 92 in { 93 description = "Anbox Container Management Daemon"; 94 95 environment.XDG_RUNTIME_DIR="${anboxloc}"; 96 97 wantedBy = [ "multi-user.target" ]; 98 preStart = let 99 initsh = pkgs.writeText "nixos-init" ('' 100 #!/system/bin/sh 101 setprop nixos.version ${config.system.nixos.version} 102 103 # we don't have radio 104 setprop ro.radio.noril yes 105 stop ril-daemon 106 107 # speed up boot 108 setprop debug.sf.nobootanimation 1 109 '' + cfg.extraInit); 110 initshloc = "${anboxloc}/rootfs-overlay/system/etc/init.goldfish.sh"; 111 in '' 112 mkdir -p ${anboxloc} 113 mkdir -p $(dirname ${initshloc}) 114 [ -f ${initshloc} ] && rm ${initshloc} 115 cp ${initsh} ${initshloc} 116 chown 100000:100000 ${initshloc} 117 chmod +x ${initshloc} 118 ''; 119 120 serviceConfig = { 121 ExecStart = '' 122 ${pkgs.anbox}/bin/anbox container-manager \ 123 --data-path=${anboxloc} \ 124 --android-image=${cfg.image} \ 125 --container-network-address=${cfg.ipv4.container.address} \ 126 --container-network-gateway=${cfg.ipv4.gateway.address} \ 127 --container-network-dns-servers=${cfg.ipv4.dns} \ 128 --use-rootfs-overlay \ 129 --privileged 130 ''; 131 }; 132 }; 133 }; 134 135}