1
0
Fork 0

nixbld: refactor hydra-www-outputs to generate etags for nginx

Should again resolve Gitea issue #12
This commit is contained in:
Astro 2019-05-21 21:41:12 +02:00
parent e7eedf0f48
commit 8e3f1cc5a0
3 changed files with 133 additions and 22 deletions

View File

@ -4,14 +4,12 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
let
hydraWwwOutputs = "/var/www/hydra-outputs";
in
{ {
imports = imports =
[ # Include the results of the hardware scan. [ # Include the results of the hardware scan.
./hardware-configuration.nix ./hardware-configuration.nix
./homu/nixos-module.nix ./homu/nixos-module.nix
./hydra-www-outputs.nix
]; ];
# Use the systemd-boot EFI boot loader. # Use the systemd-boot EFI boot loader.
@ -139,25 +137,20 @@ ACTION=="add", SUBSYSTEM=="tty", \
'' ''
binary_cache_secret_key_file = /etc/nixos/secret/nixbld.m-labs.hk-1 binary_cache_secret_key_file = /etc/nixos/secret/nixbld.m-labs.hk-1
max_output_size = 5500000000 max_output_size = 5500000000
<runcommand>
job = artiq:main:artiq-manual-html
command = ln -sf $(jq -r '.outputs[0].path' < $HYDRA_JSON) ${hydraWwwOutputs}/artiq-manual-html-beta
</runcommand>
<runcommand>
job = artiq:main:artiq-manual-latexpdf
command = ln -sf $(jq -r '.outputs[0].path' < $HYDRA_JSON) ${hydraWwwOutputs}/artiq-manual-latexpdf-beta
</runcommand>
''; '';
}; };
systemd.services.hydra-www-outputs-init = { services.hydraWwwOutputs = {
description = "Set up a hydra-owned directory for build outputs"; "m-labs.hk" = {
wantedBy = [ "multi-user.target" ]; "artiq-manual-beta-html" = {
requiredBy = [ "hydra-queue-runner.service" ]; job = "artiq:main:artiq-manual-html";
before = [ "hydra-queue-runner.service" ]; httpPath = "/artiq/manual-beta";
serviceConfig = { outputPath = "share/doc/artiq-manual/html";
Type = "oneshot"; };
ExecStart = [ "${pkgs.coreutils}/bin/mkdir -p ${hydraWwwOutputs}" "${pkgs.coreutils}/bin/chown hydra-queue-runner:hydra ${hydraWwwOutputs}" ]; "artiq-manual-beta-latexpdf" = {
job = "artiq:main:artiq-manual-latexpdf";
httpPath = "/artiq/manual-beta.pdf";
outputPath = "share/doc/artiq-manual/ARTIQ.pdf";
};
}; };
}; };
@ -230,8 +223,6 @@ ACTION=="add", SUBSYSTEM=="tty", \
locations."/gateware.html".extraConfig = '' locations."/gateware.html".extraConfig = ''
return 301 /migen/; return 301 /migen/;
''; '';
locations."/artiq/manual-beta".alias = "${hydraWwwOutputs}/artiq-manual-html-beta/share/doc/artiq-manual/html";
locations."/artiq/manual-beta.pdf".alias = "${hydraWwwOutputs}/artiq-manual-latexpdf-beta/share/doc/artiq-manual/ARTIQ.pdf";
}; };
"www.m-labs.hk" = { "www.m-labs.hk" = {
addSSL = true; addSSL = true;

View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -e
# Argument 1:
CONF=$1
# Argument 2: HTTP location
LOCATION=$2
# Argument 3: HTTP alias target within the derivation output
HTTP_PATH=$3
# Get path of first output
OUTPUT=$(jq -r '.outputs[0].path' < $HYDRA_JSON)
HASH=${OUTPUT:11:32}
ROOT="$OUTPUT/$HTTP_PATH"
cat > $CONF <<EOF
location $LOCATION {
alias $ROOT;
# Do not generate Etags from /nix/store's 1970 timestamps.
etag off;
add_header etag "\"$HASH\"";
}
EOF
/run/wrappers/bin/sudo systemctl reload nginx

View File

@ -0,0 +1,94 @@
{ config, pkgs, lib, ... }:
with lib;
let
hookPkg =
{ stdenv, makeWrapper, bash, coreutils, jq }:
stdenv.mkDerivation rec {
name = "hydra-www-hook";
src = ./.;
buildInputs = [ makeWrapper ];
propagatedBuildInputs = [ bash coreutils jq ];
phases = [ "unpackPhase" "installPhase" "fixupPhase" ];
installPhase = ''
mkdir -p $out/bin/
cp hydra-www-hook.sh $out/bin/
wrapProgram $out/bin/hydra-www-hook.sh \
--prefix PATH : ${makeBinPath propagatedBuildInputs}
'';
};
hook = pkgs.callPackage hookPkg {};
hydraWwwOutputs = "/var/www/hydra-outputs";
cfg = config.services.hydraWwwOutputs;
in
{
options.services.hydraWwwOutputs = mkOption {
type = with types; attrsOf (attrsOf (submodule {
options = {
job = mkOption {
type = string;
};
httpPath = mkOption {
type = string;
};
outputPath = mkOption {
type = string;
};
};
}));
};
config.services.hydra = {
extraConfig = builtins.concatStringsSep "\n"
(builtins.concatMap (vhost:
builtins.attrValues (
builtins.mapAttrs (name: cfg: ''
<runcommand>
job = ${cfg.job}
command = ${hook}/bin/hydra-www-hook.sh ${hydraWwwOutputs}/${name}.conf ${cfg.httpPath} ${cfg.outputPath}
</runcommand>
'') cfg.${vhost}
)) (builtins.attrNames cfg)
);
};
config.systemd.services.hydra-www-outputs-init = {
description = "Set up a hydra-owned directory for build outputs";
wantedBy = [ "multi-user.target" ];
requiredBy = [ "hydra-queue-runner.service" ];
before = [ "hydra-queue-runner.service" ];
serviceConfig = {
Type = "oneshot";
ExecStart = [
"${pkgs.coreutils}/bin/mkdir -p ${hydraWwwOutputs}"
] ++
(builtins.concatMap (vhost:
map (name:
"${pkgs.coreutils}/bin/touch ${hydraWwwOutputs}/${name}.conf"
) (builtins.attrNames cfg.${vhost})
) (builtins.attrNames cfg)) ++ [
"${pkgs.coreutils}/bin/chown -R hydra-queue-runner:hydra ${hydraWwwOutputs}"
];
};
};
# Allow the hook to reload nginx
config.security.sudo.extraRules = [ {
users = [ "hydra-queue-runner" ];
commands = [ {
command = "${config.systemd.package}/bin/systemctl reload nginx";
options = [ "NOPASSWD" ];
} ];
} ];
config.services.nginx = {
virtualHosts = builtins.mapAttrs (vhost: cfg': {
extraConfig = builtins.concatStringsSep "\n" (
map (name:
"include ${hydraWwwOutputs}/${name}.conf;"
) (builtins.attrNames cfg')
);
}) cfg;
};
}