diff --git a/src/arion b/src/arion index 32ec65d..41a1dea 100755 --- a/src/arion +++ b/src/arion @@ -46,6 +46,11 @@ while test $# != 0; do shift break ;; + exec) + command="$1" + shift + break + ;; docker-compose) command="docker-compose" shift @@ -231,6 +236,45 @@ do_repl_cleanup() { rm -f $REPL_TMP } +run_exec() { + case "${#docker_compose_args[@]}" in + 0) + echo "As an argument to exec, please specify a service" + exit 1 + ;; + 1) + case "${docker_compose_args[0]}" in + -*|--*) + echo "As an argument to exec, please specify a service" + echo "Note that executing the default command currently does not support" + echo "docker-compose options." + # This requires parsing the options, in order to figure out + # which service to invoke. + exit 1 + ;; + *) + serviceName="${docker_compose_args[0]}" + do_eval + default_args=() + while read arg; do + default_args+=("$arg") + done < <( + jq < "$docker_compose_yaml" \ + --arg serviceName "$serviceName" \ + -r \ + '.["x-arion"].serviceInfo.webserver.defaultExec | tostream | .[1] | select(.)' + ) + docker-compose -f $docker_compose_yaml exec "$serviceName" "${default_args[@]}" + ;; + esac + ;; + *) + do_eval + docker-compose -f $docker_compose_yaml exec "${docker_compose_args[@]}" + ;; + esac +} + case "$command" in cat) do_eval @@ -239,6 +283,9 @@ case "$command" in repl) do_repl ;; + exec) + run_exec "$@" + ;; docker-compose) if [[ ${#docker_compose_args[@]} != 0 && ${docker_compose_args[0]} != "help" diff --git a/src/nix/eval-service.nix b/src/nix/eval-service.nix index 09fe579..26a498c 100644 --- a/src/nix/eval-service.nix +++ b/src/nix/eval-service.nix @@ -9,6 +9,7 @@ let builtinModules = [ argsModule + ./modules/service/default-exec.nix ./modules/service/docker-compose-service.nix ./modules/service/extended-info.nix ./modules/service/host-store.nix diff --git a/src/nix/modules/nixos/default-shell.nix b/src/nix/modules/nixos/default-shell.nix new file mode 100644 index 0000000..2eb4173 --- /dev/null +++ b/src/nix/modules/nixos/default-shell.nix @@ -0,0 +1,4 @@ +{ config, utils, ... }: +{ + config.system.build.x-arion-defaultShell = utils.toShellPath config.users.defaultUserShell; +} diff --git a/src/nix/modules/service/default-exec.nix b/src/nix/modules/service/default-exec.nix new file mode 100644 index 0000000..299e083 --- /dev/null +++ b/src/nix/modules/service/default-exec.nix @@ -0,0 +1,19 @@ +{ config, lib, ... }: +let + inherit (lib) types mkOption; +in +{ + options = { + service.defaultExec = mkOption { + type = types.listOf types.str; + default = ["/bin/sh"]; + description = '' + Container program and arguments to invoke when calling + arion exec <service.name> without further arguments. + ''; + }; + }; + config = { + build.extendedInfo.defaultExec = config.service.defaultExec; + }; +} \ No newline at end of file diff --git a/src/nix/modules/service/nixos-init.nix b/src/nix/modules/service/nixos-init.nix index 0dab936..9fe52c3 100644 --- a/src/nix/modules/service/nixos-init.nix +++ b/src/nix/modules/service/nixos-init.nix @@ -21,6 +21,7 @@ in config = lib.mkIf (config.nixos.useSystemd) { nixos.configuration.imports = [ ../nixos/container-systemd.nix + ../nixos/default-shell.nix (pkgs.path + "/nixos/modules/profiles/minimal.nix") ]; image.command = [ "${config.nixos.build.toplevel}/init" ]; @@ -35,5 +36,6 @@ in ]; service.stop_signal = "SIGRTMIN+3"; service.tty = true; + service.defaultExec = [config.nixos.build.x-arion-defaultShell "-l"]; }; } diff --git a/tests/arion-test/default.nix b/tests/arion-test/default.nix index 4ad5aca..1020a1b 100644 --- a/tests/arion-test/default.nix +++ b/tests/arion-test/default.nix @@ -51,6 +51,8 @@ in subtest "full-nixos", sub { $machine->succeed("cp -r ${../../examples/full-nixos} work && cd work && NIX_PATH=nixpkgs='${pkgs.path}' arion up -d"); $machine->waitUntilSucceeds("curl localhost:8000"); + # Also test exec with defaultExec + $machine->succeed("cd work && export NIX_PATH=nixpkgs='${pkgs.path}' && (echo 'nix run -f ~/h/arion arion -c arion exec webserver'; echo 'target=world; echo Hello \$target'; echo exit) | script /dev/null | grep 'Hello world'"); $machine->succeed("cd work && NIX_PATH=nixpkgs='${pkgs.path}' arion down && rm -rf work"); $machine->waitUntilFails("curl localhost:8000"); };