Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
a8dd207837 |
6 changed files with 10 additions and 144 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
outputs = { nixpkgs, ... }: let
|
outputs = { nixpkgs, ... }@self: let
|
||||||
supportedArchitectures = [
|
supportedArchitectures = [
|
||||||
"aarch64-darwin"
|
"aarch64-darwin"
|
||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
|
@ -11,17 +11,12 @@
|
||||||
packages = nixpkgs.lib.genAttrs supportedArchitectures (system: {
|
packages = nixpkgs.lib.genAttrs supportedArchitectures (system: {
|
||||||
nix_templater = nixpkgs.legacyPackages.${system}.callPackage ./pkgs/nix_templater {};
|
nix_templater = nixpkgs.legacyPackages.${system}.callPackage ./pkgs/nix_templater {};
|
||||||
});
|
});
|
||||||
legacyPackages = nixpkgs.lib.genAttrs supportedArchitectures (system: let
|
legacyPackages = nixpkgs.lib.genAttrs supportedArchitectures (system: import ./lib.nix {
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
in import ./lib.nix {
|
|
||||||
inherit pkgs;
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
nix_templater = packages.${system}.nix_templater;
|
nix_templater = packages.${system}.nix_templater;
|
||||||
});
|
});
|
||||||
checks = nixpkgs.lib.genAttrs supportedArchitectures (system: {
|
checks = nixpkgs.lib.genAttrs supportedArchitectures (system: {
|
||||||
template = import ./tests/template.nix { inherit legacyPackages system nixpkgs; };
|
template = import ./tests/template.nix { inherit legacyPackages system nixpkgs; };
|
||||||
json = import ./tests/json.nix { inherit legacyPackages system nixpkgs; };
|
|
||||||
toml = import ./tests/toml.nix { inherit legacyPackages system nixpkgs; };
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
55
lib.nix
55
lib.nix
|
@ -1,28 +1,21 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
pkgs,
|
||||||
nix_templater,
|
nix_templater ? pkgs.callPackage ./pkgs/nix_templater { },
|
||||||
lib ? pkgs.lib,
|
|
||||||
}:
|
}:
|
||||||
let
|
{
|
||||||
escapeJson = {
|
|
||||||
"\"" = ''\"'';
|
|
||||||
"\\" = ''\\'';
|
|
||||||
};
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
# placeholder to be substituted with the content of a secret file
|
# placeholder to be substituted with the content of a secret file
|
||||||
fileContents = file: {
|
fileContents = file: {
|
||||||
outPath = "<${builtins.placeholder "nix_template"}${toString file}${builtins.placeholder "nix_template"}>";
|
outPath = "<${builtins.placeholder "nix_template"}${toString file}${builtins.placeholder "nix_template"}>";
|
||||||
file = file;
|
file = file;
|
||||||
};
|
};
|
||||||
|
|
||||||
# make a template with placeholders from a text
|
# make a template with placeholders
|
||||||
templateText = { name, text, outPath, translations ? {} }:
|
template_text = { name, text, outPath }:
|
||||||
pkgs.runCommand name {
|
pkgs.runCommand name {
|
||||||
textBeforeTemplate = text;
|
textBeforeTemplate = text;
|
||||||
script = ''
|
script = ''
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
${nix_templater}/bin/nix_templater ${builtins.placeholder "out"}/template ${builtins.placeholder "nix_template"} "${outPath}" '${lib.strings.toJSON translations}'
|
${nix_templater}/bin/nix_templater ${builtins.placeholder "out"}/template ${builtins.placeholder "nix_template"} "${outPath}"
|
||||||
'';
|
'';
|
||||||
passAsFile = [ "script" "textBeforeTemplate" ];
|
passAsFile = [ "script" "textBeforeTemplate" ];
|
||||||
} ''
|
} ''
|
||||||
|
@ -31,42 +24,4 @@ rec {
|
||||||
cp $scriptPath $out/bin/${name}
|
cp $scriptPath $out/bin/${name}
|
||||||
chmod +x $out/bin/${name}
|
chmod +x $out/bin/${name}
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# make a template with placeholders from a file
|
|
||||||
templateFromFile = { name, templateFile, outPath, translations ? {} }:
|
|
||||||
pkgs.runCommand name {
|
|
||||||
inherit templateFile;
|
|
||||||
script = ''
|
|
||||||
#!/bin/sh
|
|
||||||
${nix_templater}/bin/nix_templater ${builtins.placeholder "out"}/template ${builtins.placeholder "nix_template"} "${outPath}" '${lib.strings.toJSON translations}'
|
|
||||||
'';
|
|
||||||
passAsFile = [ "script" ];
|
|
||||||
} ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
cp $templateFile $out/template
|
|
||||||
cp $scriptPath $out/bin/${name}
|
|
||||||
chmod +x $out/bin/${name}
|
|
||||||
'';
|
|
||||||
|
|
||||||
translateFile = translations: generator: { name, value, outPath }: templateFromFile {
|
|
||||||
inherit name outPath translations;
|
|
||||||
templateFile = generator value;
|
|
||||||
};
|
|
||||||
|
|
||||||
translateText = translations: generator: { name, value, outPath }: templateText {
|
|
||||||
inherit name outPath translations;
|
|
||||||
text = generator value;
|
|
||||||
};
|
|
||||||
|
|
||||||
# escaping: https://www.json.org/json-en.html
|
|
||||||
templateJson = translateFile escapeJson (pkgs.writers.writeJSON "template.json");
|
|
||||||
# just json
|
|
||||||
templateYaml = translateFile escapeJson (pkgs.writers.writeYAML "template.yaml");
|
|
||||||
# escaping: technically also control characters (U+0000 to U+001F): https://toml.io/en/v0.3.0#string
|
|
||||||
templateToml = translateFile escapeJson (pkgs.writers.writeTOML "template.toml");
|
|
||||||
|
|
||||||
# escaping: https://git.kernel.org/pub/scm/git/git.git/tree/Documentation/config.txt?id=a54a84b333adbecf7bc4483c0e36ed5878cac17b#n47
|
|
||||||
templateIniWith = options: translateText escapeJson (lib.generators.toINI options);
|
|
||||||
|
|
||||||
templateIni = templateIniWith { };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
# replace occurrences of a magic string in a template file
|
# replace occurrences of a magic string in a template file
|
||||||
from json import loads
|
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
template_file = sys.argv[1]
|
template_file = sys.argv[1]
|
||||||
magic_string = sys.argv[2]
|
magic_string = sys.argv[2]
|
||||||
outfile = sys.argv[3]
|
outfile = sys.argv[3]
|
||||||
translations = loads(sys.argv[4]) if len(sys.argv) >= 5 else {}
|
|
||||||
|
|
||||||
if Path(outfile).exists():
|
if Path(outfile).exists():
|
||||||
print(f"{outfile} already exists, aborting")
|
print(f"{outfile} already exists, aborting")
|
||||||
|
@ -28,7 +26,7 @@ while True:
|
||||||
]
|
]
|
||||||
output += template_bytes[loc : loc + magic_start]
|
output += template_bytes[loc : loc + magic_start]
|
||||||
# TODO handle errors better here
|
# TODO handle errors better here
|
||||||
output += Path(magic_file.decode()).read_bytes().decode().translate(str.maketrans(translations)).encode()
|
output += Path(magic_file.decode()).read_bytes()
|
||||||
loc = loc + magic_start + magic_end + len(magic_string) + 1
|
loc = loc + magic_start + magic_end + len(magic_string) + 1
|
||||||
|
|
||||||
Path(outfile).write_bytes(output)
|
Path(outfile).write_bytes(output)
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
# test injecting a secret into a json template
|
|
||||||
{ legacyPackages, system, nixpkgs }:
|
|
||||||
let
|
|
||||||
hostPkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
secret_file = hostPkgs.writeText "secret" "secret\\needing\"escaping";
|
|
||||||
in (nixpkgs.lib.nixos.runTest {
|
|
||||||
inherit hostPkgs;
|
|
||||||
name = "nix_templates";
|
|
||||||
|
|
||||||
nodes.machine = {pkgs, ...}: {
|
|
||||||
config = {
|
|
||||||
systemd.services.testservice = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStartPre = "${legacyPackages.${system}.templateJson {
|
|
||||||
name = "test";
|
|
||||||
value = {
|
|
||||||
foo = "text";
|
|
||||||
bar = legacyPackages.${system}.fileContents secret_file;
|
|
||||||
};
|
|
||||||
outPath = "./test";
|
|
||||||
}}/bin/test";
|
|
||||||
ExecStart = pkgs.writeScript "test_file_got_templates" ''
|
|
||||||
#!/bin/sh
|
|
||||||
cat ./test | grep -q 'secret'
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
start_all()
|
|
||||||
print(machine.execute("uname -a"))
|
|
||||||
machine.wait_for_unit("multi-user.target")
|
|
||||||
print(machine.succeed("cat /test"))
|
|
||||||
print(machine.succeed("cat /test | grep -q secret"))
|
|
||||||
print(machine.succeed("cat /test | ${hostPkgs.jq}/bin/jq"))
|
|
||||||
'';
|
|
||||||
})
|
|
|
@ -1,4 +1,4 @@
|
||||||
# test injecting a secret into a text template
|
# test injecting a secret into a template
|
||||||
{ legacyPackages, system, nixpkgs }:
|
{ legacyPackages, system, nixpkgs }:
|
||||||
let
|
let
|
||||||
# this file would usually be outside of the store
|
# this file would usually be outside of the store
|
||||||
|
@ -14,7 +14,7 @@ in (nixpkgs.lib.nixos.runTest {
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
ExecStartPre = "${legacyPackages.${system}.templateText {
|
ExecStartPre = "${legacyPackages.${system}.template_text {
|
||||||
name = "test";
|
name = "test";
|
||||||
text = ''
|
text = ''
|
||||||
public text
|
public text
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
# test injecting a secret into a toml template
|
|
||||||
{ legacyPackages, system, nixpkgs }:
|
|
||||||
let
|
|
||||||
hostPkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
secret_file = hostPkgs.writeText "secret" "secret\\needing\"escaping";
|
|
||||||
in (nixpkgs.lib.nixos.runTest {
|
|
||||||
inherit hostPkgs;
|
|
||||||
name = "nix_templates";
|
|
||||||
|
|
||||||
nodes.machine = {pkgs, ...}: {
|
|
||||||
config = {
|
|
||||||
systemd.services.testservice = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStartPre = "${legacyPackages.${system}.templateToml {
|
|
||||||
name = "test";
|
|
||||||
value = {
|
|
||||||
foo = "text";
|
|
||||||
bar = legacyPackages.${system}.fileContents secret_file;
|
|
||||||
};
|
|
||||||
outPath = "./test";
|
|
||||||
}}/bin/test";
|
|
||||||
ExecStart = pkgs.writeScript "test_file_got_templates" ''
|
|
||||||
#!/bin/sh
|
|
||||||
cat ./test | grep -q 'secret'
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
start_all()
|
|
||||||
print(machine.execute("uname -a"))
|
|
||||||
machine.wait_for_unit("multi-user.target")
|
|
||||||
print(machine.succeed("cat /test"))
|
|
||||||
print(machine.succeed("cat /test | grep -q secret"))
|
|
||||||
# print(machine.succeed("cat /test | ${hostPkgs.jq}/bin/jq"))
|
|
||||||
'';
|
|
||||||
})
|
|
Loading…
Add table
Reference in a new issue