dxvk_1: fix build compatibility with GCC 14 (#360918)
[NixPkgs.git] / nixos / modules / virtualisation / anbox.nix
blob6752788ac36cf981c637ed072ecdca2945f90b59
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 with lib;
10 let
12   cfg = config.virtualisation.anbox;
14   addrOpts = v: addr: pref: name: {
15     address = mkOption {
16       default = addr;
17       type = types.str;
18       description = ''
19         IPv${toString v} ${name} address.
20       '';
21     };
23     prefixLength = mkOption {
24       default = pref;
25       type = types.addCheck types.int (n: n >= 0 && n <= (if v == 4 then 32 else 128));
26       description = ''
27         Subnet mask of the ${name} address, specified as the number of
28         bits in the prefix (`${if v == 4 then "24" else "64"}`).
29       '';
30     };
31   };
33   finalImage =
34     if cfg.imageModifications == "" then
35       cfg.image
36     else
37       (pkgs.callPackage (
38         { runCommandNoCC, squashfsTools }:
40         runCommandNoCC "${cfg.image.name}-modified.img"
41           {
42             nativeBuildInputs = [
43               squashfsTools
44             ];
45           }
46           ''
47             echo "-> Extracting Anbox root image..."
48             unsquashfs -dest rootfs ${cfg.image}
50             echo "-> Modifying Anbox root image..."
51             (
52             cd rootfs
53             ${cfg.imageModifications}
54             )
56             echo "-> Packing modified Anbox root image..."
57             mksquashfs rootfs $out -comp xz -no-xattrs -all-root
58           ''
59       ) { });
65   options.virtualisation.anbox = {
67     enable = mkEnableOption "Anbox";
69     image = mkOption {
70       default = pkgs.anbox.image;
71       defaultText = literalExpression "pkgs.anbox.image";
72       type = types.package;
73       description = ''
74         Base android image for Anbox.
75       '';
76     };
78     imageModifications = mkOption {
79       default = "";
80       type = types.lines;
81       description = ''
82         Commands to edit the image filesystem.
84         This can be used to e.g. bundle a privileged F-Droid.
86         Commands are ran with PWD being at the root of the filesystem.
87       '';
88     };
90     extraInit = mkOption {
91       type = types.lines;
92       default = "";
93       description = ''
94         Extra shell commands to be run inside the container image during init.
95       '';
96     };
98     ipv4 = {
99       container = addrOpts 4 "192.168.250.2" 24 "Container";
100       gateway = addrOpts 4 "192.168.250.1" 24 "Host";
102       dns = mkOption {
103         default = "1.1.1.1";
104         type = types.str;
105         description = ''
106           Container DNS server.
107         '';
108       };
109     };
110   };
112   config = mkIf cfg.enable {
114     assertions = singleton {
115       assertion = with config.boot.kernelPackages; kernelAtLeast "5.5" && kernelOlder "5.18";
116       message = "Anbox needs a kernel with binder and ashmem support";
117     };
119     environment.systemPackages = with pkgs; [ anbox ];
121     systemd.mounts = singleton {
122       requiredBy = [ "anbox-container-manager.service" ];
123       description = "Anbox Binder File System";
124       what = "binder";
125       where = "/dev/binderfs";
126       type = "binder";
127     };
129     virtualisation.lxc.enable = true;
130     networking.bridges.anbox0.interfaces = [ ];
131     networking.interfaces.anbox0.ipv4.addresses = [ cfg.ipv4.gateway ];
133     networking.nat = {
134       enable = true;
135       internalInterfaces = [ "anbox0" ];
136     };
138     # Ensures NetworkManager doesn't touch anbox0
139     networking.networkmanager.unmanaged = [ "anbox0" ];
141     systemd.services.anbox-container-manager =
142       let
143         anboxloc = "/var/lib/anbox";
144       in
145       {
146         description = "Anbox Container Management Daemon";
148         environment.XDG_RUNTIME_DIR = "${anboxloc}";
150         wantedBy = [ "multi-user.target" ];
151         preStart =
152           let
153             initsh = pkgs.writeText "nixos-init" (
154               ''
155                 #!/system/bin/sh
156                 setprop nixos.version ${config.system.nixos.version}
158                 # we don't have radio
159                 setprop ro.radio.noril yes
160                 stop ril-daemon
162                 # speed up boot
163                 setprop debug.sf.nobootanimation 1
164               ''
165               + cfg.extraInit
166             );
167             initshloc = "${anboxloc}/rootfs-overlay/system/etc/init.goldfish.sh";
168           in
169           ''
170             mkdir -p ${anboxloc}
171             mkdir -p $(dirname ${initshloc})
172             [ -f ${initshloc} ] && rm ${initshloc}
173             cp ${initsh} ${initshloc}
174             chown 100000:100000 ${initshloc}
175             chmod +x ${initshloc}
176           '';
178         serviceConfig = {
179           ExecStart = ''
180             ${pkgs.anbox}/bin/anbox container-manager \
181               --data-path=${anboxloc} \
182               --android-image=${finalImage} \
183               --container-network-address=${cfg.ipv4.container.address} \
184               --container-network-gateway=${cfg.ipv4.gateway.address} \
185               --container-network-dns-servers=${cfg.ipv4.dns} \
186               --use-rootfs-overlay \
187               --privileged \
188               --daemon
189           '';
190         };
191       };
192   };