at 22.05-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 = '' 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 = '' 22 Subnet mask of the ${name} address, specified as the number of 23 bits in the prefix (<literal>${if v == 4 then "24" else "64"}</literal>). 24 ''; 25 }; 26 }; 27 28in 29 30{ 31 32 options.virtualisation.anbox = { 33 34 enable = mkEnableOption "Anbox"; 35 36 image = mkOption { 37 default = pkgs.anbox.image; 38 defaultText = literalExpression "pkgs.anbox.image"; 39 type = types.package; 40 description = '' 41 Base android image for Anbox. 42 ''; 43 }; 44 45 extraInit = mkOption { 46 type = types.lines; 47 default = ""; 48 description = '' 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 = '' 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 boot.kernelModules = [ "ashmem_linux" "binder_linux" ]; 77 boot.extraModulePackages = [ kernelPackages.anbox ]; 78 79 services.udev.extraRules = '' 80 KERNEL=="ashmem", NAME="%k", MODE="0666" 81 KERNEL=="binder*", NAME="%k", MODE="0666" 82 ''; 83 84 virtualisation.lxc.enable = true; 85 networking.bridges.anbox0.interfaces = []; 86 networking.interfaces.anbox0.ipv4.addresses = [ cfg.ipv4.gateway ]; 87 88 networking.nat = { 89 enable = true; 90 internalInterfaces = [ "anbox0" ]; 91 }; 92 93 systemd.services.anbox-container-manager = let 94 anboxloc = "/var/lib/anbox"; 95 in { 96 description = "Anbox Container Management Daemon"; 97 98 environment.XDG_RUNTIME_DIR="${anboxloc}"; 99 100 wantedBy = [ "multi-user.target" ]; 101 preStart = let 102 initsh = pkgs.writeText "nixos-init" ('' 103 #!/system/bin/sh 104 setprop nixos.version ${config.system.nixos.version} 105 106 # we don't have radio 107 setprop ro.radio.noril yes 108 stop ril-daemon 109 110 # speed up boot 111 setprop debug.sf.nobootanimation 1 112 '' + cfg.extraInit); 113 initshloc = "${anboxloc}/rootfs-overlay/system/etc/init.goldfish.sh"; 114 in '' 115 mkdir -p ${anboxloc} 116 mkdir -p $(dirname ${initshloc}) 117 [ -f ${initshloc} ] && rm ${initshloc} 118 cp ${initsh} ${initshloc} 119 chown 100000:100000 ${initshloc} 120 chmod +x ${initshloc} 121 ''; 122 123 serviceConfig = { 124 ExecStart = '' 125 ${pkgs.anbox}/bin/anbox container-manager \ 126 --data-path=${anboxloc} \ 127 --android-image=${cfg.image} \ 128 --container-network-address=${cfg.ipv4.container.address} \ 129 --container-network-gateway=${cfg.ipv4.gateway.address} \ 130 --container-network-dns-servers=${cfg.ipv4.dns} \ 131 --use-rootfs-overlay \ 132 --privileged 133 ''; 134 }; 135 }; 136 }; 137 138}