diff --git a/README.md b/README.md index 25207e4..140f9c6 100644 --- a/README.md +++ b/README.md @@ -372,6 +372,7 @@ If a feature is missing, please feel free to [create an issue](https://github.co | [`runtime`](https://docs.docker.com/compose/compose-file/05-services/#runtime) | ✅ | | | [`security_opt`](https://docs.docker.com/compose/compose-file/05-services/#security_opt) | ✅ | | | [`command`](https://docs.docker.com/compose/compose-file/05-services/#command) | ✅ | | +| [`entrypoint`](https://docs.docker.com/compose/compose-file/05-services/#entrypoint) | ✅ | | | [`healthcheck`](https://docs.docker.com/compose/compose-file/05-services/#healthcheck) | ✅ | | | [`hostname`](https://docs.docker.com/compose/compose-file/05-services/#hostname) | ✅ | | | [`mac_address`](https://docs.docker.com/compose/compose-file/05-services/#mac_address) | ✅ | | @@ -384,6 +385,7 @@ If a feature is missing, please feel free to [create an issue](https://github.co | [`name`](https://docs.docker.com/compose/compose-file/06-networks/#name) | ✅ | | [`driver`](https://docs.docker.com/compose/compose-file/06-networks/#driver) | ✅ | | [`driver_opts`](https://docs.docker.com/compose/compose-file/06-networks/#driver_opts) | ✅ | +| [`enable_ipv6`](https://docs.docker.com/compose/compose-file/06-networks/#enable_ipv6) | ✅ | | [`ipam`](https://docs.docker.com/compose/compose-file/06-networks/#ipam) | ✅ | | [`external`](https://docs.docker.com/compose/compose-file/06-networks/#external) | ✅ | | [`internal`](https://docs.docker.com/compose/compose-file/06-networks/#internal) | ✅ | diff --git a/compose.go b/compose.go index 3d0600d..3888ae0 100644 --- a/compose.go +++ b/compose.go @@ -3,7 +3,6 @@ package main import ( "cmp" "context" - "encoding/json" "fmt" "log" "path" @@ -241,11 +240,7 @@ func healthCheckCommandToString(cmd []string) (string, error) { case "CMD-SHELL": return cmd[1], nil case "CMD": - j, err := json.Marshal(cmd[1:]) - if err != nil { - return "", fmt.Errorf("failed to convert %v to JSON: %w", cmd[1:], err) - } - return string(j), nil + return sliceToStringArray(cmd[1:]), nil } panic("unreachable") } @@ -330,6 +325,9 @@ func (g *Generator) buildNixContainer(service types.ServiceConfig, networkMap ma if !service.Command.IsZero() { c.Command = service.Command } + if entrypoint := service.Entrypoint; !entrypoint.IsZero() { + c.ExtraOptions = append(c.ExtraOptions, fmt.Sprintf("--entrypoint=%s", sliceToStringArray(entrypoint))) + } // Figure out explicit dependencies for this container. // @@ -745,6 +743,9 @@ func (g *Generator) buildNixNetworks(composeProject *types.Project) ([]*NixNetwo if network.Internal { n.ExtraOptions = append(n.ExtraOptions, "--internal") } + if enableIPv6 := network.EnableIPv6; enableIPv6 != nil && *enableIPv6 { + n.ExtraOptions = append(n.ExtraOptions, "--ipv6") + } // IPAM configuration. // https://docs.docker.com/compose/compose-file/06-networks/#ipam diff --git a/helpers.go b/helpers.go index 54a9309..b4b7a6d 100644 --- a/helpers.go +++ b/helpers.go @@ -31,6 +31,17 @@ func mapToRepeatedKeyValFlag(flagName string, m map[string]string) []string { return arr } +func sliceToStringArray(s []string) string { + b := strings.Builder{} + b.WriteString("[") + for i := range s { + // We purposefully do not use %q to avoid Go's built-in string escaping. + // Otherwise, we'd escape " characters a 2nd time for Nix. + s[i] = fmt.Sprintf(`"%s"`, s[i]) + } + return fmt.Sprintf("[%s]", strings.Join(s, ", ")) +} + // ReadEnvFiles reads the given set of env files into a list of KEY=VAL entries. // // If mergeWithEnv is set, the running env is merged with the provided env files. Any diff --git a/nix_test.go b/nix_test.go index 7b3e959..0a2b8e7 100644 --- a/nix_test.go +++ b/nix_test.go @@ -144,6 +144,16 @@ func TestUpheldBy(t *testing.T) { runSubtestsWithGenerator(t, g) } +func TestCommandAndEntrypoint(t *testing.T) { + composePath, envFilePath := getPaths(t, false) + g := &Generator{ + Project: NewProject("test"), + Inputs: []string{composePath}, + EnvFiles: []string{envFilePath}, + } + runSubtestsWithGenerator(t, g) +} + func TestRemoveVolumes(t *testing.T) { composePath, envFilePath := getPaths(t, true) g := &Generator{ @@ -254,6 +264,16 @@ func TestNetworkAndVolumeNames(t *testing.T) { runSubtestsWithGenerator(t, g) } +func TestNetworkSettings(t *testing.T) { + composePath, _ := getPaths(t, false) + g := &Generator{ + Project: NewProject("test"), + Inputs: []string{composePath}, + GenerateUnusedResources: true, + } + runSubtestsWithGenerator(t, g) +} + func TestRelativeServiceVolumes(t *testing.T) { composePath, _ := getPaths(t, false) g := &Generator{ diff --git a/nixos-test/docker-compose.nix b/nixos-test/docker-compose.nix index 7314b0a..1302ccf 100644 --- a/nixos-test/docker-compose.nix +++ b/nixos-test/docker-compose.nix @@ -10,6 +10,32 @@ virtualisation.oci-containers.backend = "docker"; # Containers + virtualisation.oci-containers.containers."myproject-entrypoint" = { + image = "docker.io/library/nginx:stable-alpine-slim"; + log-driver = "journald"; + extraOptions = [ + "--entrypoint=[\"echo\", \"abc\"]" + "--network-alias=entrypoint" + "--network=myproject_default" + ]; + }; + systemd.services."docker-myproject-entrypoint" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-myproject_default.service" + ]; + requires = [ + "docker-network-myproject_default.service" + ]; + partOf = [ + "docker-compose-myproject-root.target" + ]; + wantedBy = [ + "docker-compose-myproject-root.target" + ]; + }; virtualisation.oci-containers.containers."myproject-no-restart" = { image = "docker.io/library/nginx:stable-alpine-slim"; log-driver = "journald"; @@ -150,6 +176,19 @@ }; # Networks + systemd.services."docker-network-myproject_another" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "docker network rm -f myproject_another"; + }; + script = '' + docker network inspect myproject_another || docker network create myproject_another --driver=bridge --ipv6 + ''; + partOf = [ "docker-compose-myproject-root.target" ]; + wantedBy = [ "docker-compose-myproject-root.target" ]; + }; systemd.services."docker-network-myproject_default" = { path = [ pkgs.docker ]; serviceConfig = { diff --git a/nixos-test/docker-compose.yml b/nixos-test/docker-compose.yml index a92344e..85140a6 100644 --- a/nixos-test/docker-compose.yml +++ b/nixos-test/docker-compose.yml @@ -43,6 +43,11 @@ services: restart: on-failure:3 no-restart: image: docker.io/library/nginx:stable-alpine-slim + entrypoint: + image: docker.io/library/nginx:stable-alpine-slim + entrypoint: + - echo + - abc networks: something: @@ -53,6 +58,9 @@ networks: labels: - "test-label=okay" - "escape-me=''hello''" + another: + driver: bridge + enable_ipv6: true volumes: storage: diff --git a/nixos-test/podman-compose.nix b/nixos-test/podman-compose.nix index fbcc4e5..7a9b93c 100644 --- a/nixos-test/podman-compose.nix +++ b/nixos-test/podman-compose.nix @@ -15,6 +15,32 @@ virtualisation.oci-containers.backend = "podman"; # Containers + virtualisation.oci-containers.containers."myproject-entrypoint" = { + image = "docker.io/library/nginx:stable-alpine-slim"; + log-driver = "journald"; + extraOptions = [ + "--entrypoint=[\"echo\", \"abc\"]" + "--network-alias=entrypoint" + "--network=myproject_default" + ]; + }; + systemd.services."podman-myproject-entrypoint" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "podman-network-myproject_default.service" + ]; + requires = [ + "podman-network-myproject_default.service" + ]; + partOf = [ + "podman-compose-myproject-root.target" + ]; + wantedBy = [ + "podman-compose-myproject-root.target" + ]; + }; virtualisation.oci-containers.containers."myproject-no-restart" = { image = "docker.io/library/nginx:stable-alpine-slim"; log-driver = "journald"; @@ -152,6 +178,19 @@ }; # Networks + systemd.services."podman-network-myproject_another" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f myproject_another"; + }; + script = '' + podman network inspect myproject_another || podman network create myproject_another --driver=bridge --ipv6 + ''; + partOf = [ "podman-compose-myproject-root.target" ]; + wantedBy = [ "podman-compose-myproject-root.target" ]; + }; systemd.services."podman-network-myproject_default" = { path = [ pkgs.podman ]; serviceConfig = { diff --git a/nixos-test/update.sh b/nixos-test/update.sh index e00c229..5fc4720 100755 --- a/nixos-test/update.sh +++ b/nixos-test/update.sh @@ -10,11 +10,14 @@ bin/compose2nix \ -output=nixos-test/docker-compose.nix \ -check_systemd_mounts \ -include_env_files=true \ + -generate_unused_resources=true \ -use_upheld_by bin/compose2nix \ -runtime=podman \ -inputs=nixos-test/docker-compose.yml \ -output=nixos-test/podman-compose.nix \ -check_systemd_mounts \ - -use_upheld_by \ - -include_env_files=true + -include_env_files=true \ + -generate_unused_resources=true \ + -use_upheld_by + diff --git a/template.go b/template.go index bc6440d..17fac1f 100644 --- a/template.go +++ b/template.go @@ -37,7 +37,8 @@ func toNixValue(v any) any { func toNixList(s []string) string { b := strings.Builder{} for i, e := range s { - b.WriteString(fmt.Sprintf("%q", escapeNixString(e))) + // We purposefully do not use %q to avoid Go's built-in string escaping. + b.WriteString(fmt.Sprintf(`"%s"`, escapeNixString(e))) if i < len(s)-1 { b.WriteString(" ") } diff --git a/templates/container.nix.tmpl b/templates/container.nix.tmpl index 4aaac0c..a693523 100644 --- a/templates/container.nix.tmpl +++ b/templates/container.nix.tmpl @@ -33,7 +33,7 @@ virtualisation.oci-containers.containers."{{.Name}}" = { ]; {{- end}} - {{- if .Command}} + {{- if ne .Command nil}} cmd = {{toNixList .Command}}; {{- end}} diff --git a/testdata/TestBasic.docker.nix b/testdata/TestBasic.docker.nix index 860d4c7..851e88f 100644 --- a/testdata/TestBasic.docker.nix +++ b/testdata/TestBasic.docker.nix @@ -145,7 +145,7 @@ user = "1000:1000"; log-driver = "journald"; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestBasic.podman.nix b/testdata/TestBasic.podman.nix index b5ff201..df6b746 100644 --- a/testdata/TestBasic.podman.nix +++ b/testdata/TestBasic.podman.nix @@ -145,7 +145,7 @@ user = "1000:1000"; log-driver = "journald"; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestBasicAutoFormat.docker.nix b/testdata/TestBasicAutoFormat.docker.nix index 16a4165..c89812d 100644 --- a/testdata/TestBasicAutoFormat.docker.nix +++ b/testdata/TestBasicAutoFormat.docker.nix @@ -135,7 +135,7 @@ user = "1000:1000"; log-driver = "journald"; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestBasicAutoFormat.podman.nix b/testdata/TestBasicAutoFormat.podman.nix index 2941397..75aaeba 100644 --- a/testdata/TestBasicAutoFormat.podman.nix +++ b/testdata/TestBasicAutoFormat.podman.nix @@ -135,7 +135,7 @@ user = "1000:1000"; log-driver = "journald"; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestCommandAndEntrypoint.compose.yml b/testdata/TestCommandAndEntrypoint.compose.yml new file mode 100644 index 0000000..ad3b7ed --- /dev/null +++ b/testdata/TestCommandAndEntrypoint.compose.yml @@ -0,0 +1,17 @@ +services: + both: + image: nginx:latest + command: ["ls", "-la", "\"escape me please\""] + entrypoint: + ["nginx", "-g", "daemon off;", "-c", "/etc/config/nginx/conf/nginx.conf"] + string: + image: nginx:latest + entrypoint: "ENV_VAR=$${ABC} bash /abc.sh" + empty-command-and-entrypoint: + image: nginx:latest + command: [] + entrypoint: [] + "null-command-and-entrypoint": + image: nginx:latest + command: null + entrypoint: null diff --git a/testdata/TestCommandAndEntrypoint.docker.nix b/testdata/TestCommandAndEntrypoint.docker.nix new file mode 100644 index 0000000..9edea1f --- /dev/null +++ b/testdata/TestCommandAndEntrypoint.docker.nix @@ -0,0 +1,121 @@ +{ pkgs, lib, ... }: + +{ + # Runtime + virtualisation.docker = { + enable = true; + autoPrune.enable = true; + }; + virtualisation.oci-containers.backend = "docker"; + + # Containers + virtualisation.oci-containers.containers."test-both" = { + image = "nginx:latest"; + cmd = [ "ls" "-la" "\"escape me please\"" ]; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--entrypoint=[\"nginx\", \"-g\", \"daemon off;\", \"-c\", \"/etc/config/nginx/conf/nginx.conf\"]" + "--network-alias=both" + "--network=test_default" + ]; + }; + systemd.services."docker-test-both" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-test_default.service" + ]; + requires = [ + "docker-network-test_default.service" + ]; + }; + virtualisation.oci-containers.containers."test-empty-command-and-entrypoint" = { + image = "nginx:latest"; + cmd = [ ]; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--entrypoint=[]" + "--network-alias=empty-command-and-entrypoint" + "--network=test_default" + ]; + }; + systemd.services."docker-test-empty-command-and-entrypoint" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-test_default.service" + ]; + requires = [ + "docker-network-test_default.service" + ]; + }; + virtualisation.oci-containers.containers."test-null-command-and-entrypoint" = { + image = "nginx:latest"; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--network-alias=null-command-and-entrypoint" + "--network=test_default" + ]; + }; + systemd.services."docker-test-null-command-and-entrypoint" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-test_default.service" + ]; + requires = [ + "docker-network-test_default.service" + ]; + }; + virtualisation.oci-containers.containers."test-string" = { + image = "nginx:latest"; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--entrypoint=[\"ENV_VAR=\${ABC}\", \"bash\", \"/abc.sh\"]" + "--network-alias=string" + "--network=test_default" + ]; + }; + systemd.services."docker-test-string" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-test_default.service" + ]; + requires = [ + "docker-network-test_default.service" + ]; + }; + + # Networks + systemd.services."docker-network-test_default" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "docker network rm -f test_default"; + }; + script = '' + docker network inspect test_default || docker network create test_default + ''; + partOf = [ "docker-compose-test-root.target" ]; + wantedBy = [ "docker-compose-test-root.target" ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."docker-compose-test-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + }; +} diff --git a/testdata/TestCommandAndEntrypoint.podman.nix b/testdata/TestCommandAndEntrypoint.podman.nix new file mode 100644 index 0000000..e829a9d --- /dev/null +++ b/testdata/TestCommandAndEntrypoint.podman.nix @@ -0,0 +1,126 @@ +{ pkgs, lib, ... }: + +{ + # Runtime + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + defaultNetwork.settings = { + # Required for container networking to be able to use names. + dns_enabled = true; + }; + }; + virtualisation.oci-containers.backend = "podman"; + + # Containers + virtualisation.oci-containers.containers."test-both" = { + image = "nginx:latest"; + cmd = [ "ls" "-la" "\"escape me please\"" ]; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--entrypoint=[\"nginx\", \"-g\", \"daemon off;\", \"-c\", \"/etc/config/nginx/conf/nginx.conf\"]" + "--network-alias=both" + "--network=test_default" + ]; + }; + systemd.services."podman-test-both" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "podman-network-test_default.service" + ]; + requires = [ + "podman-network-test_default.service" + ]; + }; + virtualisation.oci-containers.containers."test-empty-command-and-entrypoint" = { + image = "nginx:latest"; + cmd = [ ]; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--entrypoint=[]" + "--network-alias=empty-command-and-entrypoint" + "--network=test_default" + ]; + }; + systemd.services."podman-test-empty-command-and-entrypoint" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "podman-network-test_default.service" + ]; + requires = [ + "podman-network-test_default.service" + ]; + }; + virtualisation.oci-containers.containers."test-null-command-and-entrypoint" = { + image = "nginx:latest"; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--network-alias=null-command-and-entrypoint" + "--network=test_default" + ]; + }; + systemd.services."podman-test-null-command-and-entrypoint" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "podman-network-test_default.service" + ]; + requires = [ + "podman-network-test_default.service" + ]; + }; + virtualisation.oci-containers.containers."test-string" = { + image = "nginx:latest"; + log-driver = "journald"; + autoStart = false; + extraOptions = [ + "--entrypoint=[\"ENV_VAR=\${ABC}\", \"bash\", \"/abc.sh\"]" + "--network-alias=string" + "--network=test_default" + ]; + }; + systemd.services."podman-test-string" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "podman-network-test_default.service" + ]; + requires = [ + "podman-network-test_default.service" + ]; + }; + + # Networks + systemd.services."podman-network-test_default" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f test_default"; + }; + script = '' + podman network inspect test_default || podman network create test_default + ''; + partOf = [ "podman-compose-test-root.target" ]; + wantedBy = [ "podman-compose-test-root.target" ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."podman-compose-test-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + }; +} diff --git a/testdata/TestNetworkSettings.compose.yml b/testdata/TestNetworkSettings.compose.yml new file mode 100644 index 0000000..7ff635b --- /dev/null +++ b/testdata/TestNetworkSettings.compose.yml @@ -0,0 +1,10 @@ +networks: + nginx_net: + driver: bridge + enable_ipv6: true + ipam: + config: + - subnet: "2001:1111:3000::/64" + other: + ipam: + driver: dhcp diff --git a/testdata/TestNetworkSettings.docker.nix b/testdata/TestNetworkSettings.docker.nix new file mode 100644 index 0000000..13079ce --- /dev/null +++ b/testdata/TestNetworkSettings.docker.nix @@ -0,0 +1,47 @@ +{ pkgs, lib, ... }: + +{ + # Runtime + virtualisation.docker = { + enable = true; + autoPrune.enable = true; + }; + virtualisation.oci-containers.backend = "docker"; + + # Networks + systemd.services."docker-network-test_nginx_net" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "docker network rm -f test_nginx_net"; + }; + script = '' + docker network inspect test_nginx_net || docker network create test_nginx_net --driver=bridge --subnet=2001:1111:3000::/64 --ipv6 + ''; + partOf = [ "docker-compose-test-root.target" ]; + wantedBy = [ "docker-compose-test-root.target" ]; + }; + systemd.services."docker-network-test_other" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "docker network rm -f test_other"; + }; + script = '' + docker network inspect test_other || docker network create test_other --ipam-driver=dhcp + ''; + partOf = [ "docker-compose-test-root.target" ]; + wantedBy = [ "docker-compose-test-root.target" ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."docker-compose-test-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + }; +} diff --git a/testdata/TestNetworkSettings.podman.nix b/testdata/TestNetworkSettings.podman.nix new file mode 100644 index 0000000..d542391 --- /dev/null +++ b/testdata/TestNetworkSettings.podman.nix @@ -0,0 +1,52 @@ +{ pkgs, lib, ... }: + +{ + # Runtime + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + defaultNetwork.settings = { + # Required for container networking to be able to use names. + dns_enabled = true; + }; + }; + virtualisation.oci-containers.backend = "podman"; + + # Networks + systemd.services."podman-network-test_nginx_net" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f test_nginx_net"; + }; + script = '' + podman network inspect test_nginx_net || podman network create test_nginx_net --driver=bridge --subnet=2001:1111:3000::/64 --ipv6 + ''; + partOf = [ "podman-compose-test-root.target" ]; + wantedBy = [ "podman-compose-test-root.target" ]; + }; + systemd.services."podman-network-test_other" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f test_other"; + }; + script = '' + podman network inspect test_other || podman network create test_other --ipam-driver=dhcp + ''; + partOf = [ "podman-compose-test-root.target" ]; + wantedBy = [ "podman-compose-test-root.target" ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."podman-compose-test-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + }; +} diff --git a/testdata/TestNoWriteNixSetup.docker.nix b/testdata/TestNoWriteNixSetup.docker.nix index a3d1eda..e6a28f3 100644 --- a/testdata/TestNoWriteNixSetup.docker.nix +++ b/testdata/TestNoWriteNixSetup.docker.nix @@ -130,7 +130,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestNoWriteNixSetup.podman.nix b/testdata/TestNoWriteNixSetup.podman.nix index d59bb46..6abb6cb 100644 --- a/testdata/TestNoWriteNixSetup.podman.nix +++ b/testdata/TestNoWriteNixSetup.podman.nix @@ -125,7 +125,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestOverrideSystemdStopTimeout.docker.nix b/testdata/TestOverrideSystemdStopTimeout.docker.nix index dda0c2b..44625a6 100644 --- a/testdata/TestOverrideSystemdStopTimeout.docker.nix +++ b/testdata/TestOverrideSystemdStopTimeout.docker.nix @@ -138,7 +138,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestOverrideSystemdStopTimeout.podman.nix b/testdata/TestOverrideSystemdStopTimeout.podman.nix index 8d4363b..41b7b1c 100644 --- a/testdata/TestOverrideSystemdStopTimeout.podman.nix +++ b/testdata/TestOverrideSystemdStopTimeout.podman.nix @@ -138,7 +138,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestProject.docker.nix b/testdata/TestProject.docker.nix index ff406c1..9bab495 100644 --- a/testdata/TestProject.docker.nix +++ b/testdata/TestProject.docker.nix @@ -136,7 +136,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestProject.podman.nix b/testdata/TestProject.podman.nix index 5f81348..4db124d 100644 --- a/testdata/TestProject.podman.nix +++ b/testdata/TestProject.podman.nix @@ -136,7 +136,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestRemoveVolumes.docker.nix b/testdata/TestRemoveVolumes.docker.nix index bbecaa1..b55ba57 100644 --- a/testdata/TestRemoveVolumes.docker.nix +++ b/testdata/TestRemoveVolumes.docker.nix @@ -136,7 +136,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestRemoveVolumes.podman.nix b/testdata/TestRemoveVolumes.podman.nix index 307a894..4695f64 100644 --- a/testdata/TestRemoveVolumes.podman.nix +++ b/testdata/TestRemoveVolumes.podman.nix @@ -136,7 +136,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestSystemdMount.docker.nix b/testdata/TestSystemdMount.docker.nix index 5002282..157f3c0 100644 --- a/testdata/TestSystemdMount.docker.nix +++ b/testdata/TestSystemdMount.docker.nix @@ -142,7 +142,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestSystemdMount.podman.nix b/testdata/TestSystemdMount.podman.nix index daa1ee0..bcecf50 100644 --- a/testdata/TestSystemdMount.podman.nix +++ b/testdata/TestSystemdMount.podman.nix @@ -142,7 +142,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s" diff --git a/testdata/TestUpheldBy.docker.nix b/testdata/TestUpheldBy.docker.nix index ca0a9b8..a1909c9 100644 --- a/testdata/TestUpheldBy.docker.nix +++ b/testdata/TestUpheldBy.docker.nix @@ -139,7 +139,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-period=40s" diff --git a/testdata/TestUpheldBy.podman.nix b/testdata/TestUpheldBy.podman.nix index d0d5da3..f447339 100644 --- a/testdata/TestUpheldBy.podman.nix +++ b/testdata/TestUpheldBy.podman.nix @@ -139,7 +139,7 @@ log-driver = "journald"; autoStart = false; extraOptions = [ - "--health-cmd=[\"curl\",\"-f\",\"http://localhost\"]" + "--health-cmd=[\"curl\", \"-f\", \"http://localhost\"]" "--health-interval=1m30s" "--health-retries=3" "--health-start-interval=5s"