aboutsummaryrefslogtreecommitdiffhomepage
path: root/bundle.nix
blob: 2d5212d0e538ed4b00d381fc8ade3fe7cebb1998 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
{
  nixpkgsFor,
  system,
  nixpkgs,
  home-manager,
}:

{
  lib,
  writeScript,
  runtimeShell,
  writeText,
  vmTools,
  runCommand,

  nix,

  name ? throw "name is required",
  version ? throw "version is required",
  pname ? "${name}-${version}",
  modules ? [ ],
  script ? ''
    exec "$SHELL" "$@"
  '',

  id ? name,
  app_id ? throw "app_id is required",
  groups ? [ ],
  userns ? false,
  net ? true,
  dev ? false,
  no_new_session ? false,
  map_real_uid ? false,
  direct_wayland ? false,
  system_bus ? null,
  session_bus ? null,

  allow_wayland ? true,
  allow_x11 ? false,
  allow_dbus ? true,
  allow_pulse ? true,
  gpu ? allow_wayland || allow_x11,
}:

let
  inherit (lib) optionals;

  homeManagerConfiguration = home-manager.lib.homeManagerConfiguration {
    pkgs = nixpkgsFor.${system};
    modules = modules ++ [
      {
        home = {
          username = "fortify";
          homeDirectory = "/data/data/${id}";
          stateVersion = "22.11";
        };
      }
    ];
  };

  launcher = writeScript "fortify-${pname}" ''
    #!${runtimeShell} -el
    ${script}
  '';

  extraNixOSConfig =
    { pkgs, ... }:
    {
      environment = {
        etc.nixpkgs.source = nixpkgs.outPath;
        systemPackages = [ pkgs.nix ];
      };
    };
  nixos = nixpkgs.lib.nixosSystem {
    inherit system;
    modules = [
      extraNixOSConfig
      { nix.settings.experimental-features = [ "flakes" ]; }
      { nix.settings.experimental-features = [ "nix-command" ]; }
      { boot.isContainer = true; }
      { system.stateVersion = "22.11"; }
    ];
  };

  etc = vmTools.runInLinuxVM (
    runCommand "etc" { } ''
      mkdir -p /etc
      ${nixos.config.system.build.etcActivationCommands}

      # remove unused files
      rm -rf /etc/sudoers

      mkdir -p $out
      tar -C /etc -cf "$out/etc.tar" .
    ''
  );

  extendSessionDefault = id: ext: {
    filter = true;

    talk = [ "org.freedesktop.Notifications" ] ++ ext.talk;
    own =
      (optionals (id != null) [
        "${id}.*"
        "org.mpris.MediaPlayer2.${id}.*"
      ])
      ++ ext.own;

    inherit (ext) call broadcast;
  };

  info = builtins.toJSON {
    inherit
      name
      version
      id
      app_id
      launcher
      groups
      userns
      net
      dev
      no_new_session
      map_real_uid
      direct_wayland
      system_bus
      gpu
      ;

    session_bus =
      if session_bus != null then
        (session_bus (extendSessionDefault id))
      else
        (extendSessionDefault id {
          talk = [ ];
          own = [ ];
          call = { };
          broadcast = { };
        });

    enablements =
      (if allow_wayland then 1 else 0)
      + (if allow_x11 then 2 else 0)
      + (if allow_dbus then 4 else 0)
      + (if allow_pulse then 8 else 0);

    current_system = nixos.config.system.build.toplevel;
    activation_package = homeManagerConfiguration.activationPackage;
  };
in

writeScript "fortify-${pname}-bundle-prelude" ''
  #!${runtimeShell} -el
  OUT="$(mktemp -d)"
  TAR="$(mktemp -u)"
  set -x

  nix copy --no-check-sigs --to "$OUT" "${nix}" "${nixos.config.system.build.toplevel}"
  nix store --store "$OUT" optimise
  chmod -R +r "$OUT/nix/var"
  nix copy --no-check-sigs --to "file://$OUT/res?compression=zstd&compression-level=19&parallel-compression=true" "${homeManagerConfiguration.activationPackage}" "${launcher}"
  mkdir -p "$OUT/etc"
  tar -C "$OUT/etc" -xf "${etc}/etc.tar"
  cp "${writeText "bundle.json" info}" "$OUT/bundle.json"

  # creating an intermediate file improves zstd performance
  tar -C "$OUT" -cf "$TAR" .
  chmod +w -R "$OUT" && rm -rf "$OUT"

  zstd -T0 -19 -fo "${pname}.pkg" "$TAR"
  rm "$TAR"
''