Skip to content

Commit

Permalink
Merge pull request #13299 from npate012/fix_systemd_generate_name_on_…
Browse files Browse the repository at this point in the history
…empty_prefix

Separator is no longer prepended when prefix is empty on podman generate systemd
  • Loading branch information
openshift-merge-robot authored Mar 17, 2022
2 parents b1d37a7 + 714e5a1 commit 6ce9677
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 13 deletions.
34 changes: 23 additions & 11 deletions pkg/api/handlers/libpod/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,37 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
RestartSec uint `schema:"restartSec"`
StopTimeout uint `schema:"stopTimeout"`
StartTimeout uint `schema:"startTimeout"`
ContainerPrefix string `schema:"containerPrefix"`
PodPrefix string `schema:"podPrefix"`
Separator string `schema:"separator"`
ContainerPrefix *string `schema:"containerPrefix"`
PodPrefix *string `schema:"podPrefix"`
Separator *string `schema:"separator"`
Wants []string `schema:"wants"`
After []string `schema:"after"`
Requires []string `schema:"requires"`
}{
StartTimeout: 0,
StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
ContainerPrefix: "container",
PodPrefix: "pod",
Separator: "-",
StartTimeout: 0,
StopTimeout: util.DefaultContainerConfig().Engine.StopTimeout,
}

if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}

var ContainerPrefix = "container"
if query.ContainerPrefix != nil {
ContainerPrefix = *query.ContainerPrefix
}

var PodPrefix = "pod"
if query.PodPrefix != nil {
PodPrefix = *query.PodPrefix
}

var Separator = "-"
if query.Separator != nil {
Separator = *query.Separator
}

containerEngine := abi.ContainerEngine{Libpod: runtime}
options := entities.GenerateSystemdOptions{
Name: query.Name,
Expand All @@ -53,9 +65,9 @@ func GenerateSystemd(w http.ResponseWriter, r *http.Request) {
RestartPolicy: query.RestartPolicy,
StartTimeout: &query.StartTimeout,
StopTimeout: &query.StopTimeout,
ContainerPrefix: query.ContainerPrefix,
PodPrefix: query.PodPrefix,
Separator: query.Separator,
ContainerPrefix: ContainerPrefix,
PodPrefix: PodPrefix,
Separator: Separator,
RestartSec: &query.RestartSec,
Wants: query.Wants,
After: query.After,
Expand Down
14 changes: 14 additions & 0 deletions pkg/systemd/generate/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,17 @@ func removeArg(arg string, args []string) []string {
}
return newArgs
}

// This function is used to get name of systemd service from prefix, separator, and
// container/pod name. If prefix is empty, the service name does not include the
// separator. This is to avoid a situation where service name starts with the separator
// which is usually hyphen.
func getServiceName(prefix string, separator string, name string) string {
serviceName := name

if len(prefix) > 0 {
serviceName = prefix + separator + name
}

return serviceName
}
4 changes: 3 additions & 1 deletion pkg/systemd/generate/containers.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,9 @@ func containerServiceName(ctr *libpod.Container, options entities.GenerateSystem
if options.Name {
nameOrID = ctr.Name()
}
serviceName := fmt.Sprintf("%s%s%s", options.ContainerPrefix, options.Separator, nameOrID)

serviceName := getServiceName(options.ContainerPrefix, options.Separator, nameOrID)

return nameOrID, serviceName
}

Expand Down
42 changes: 42 additions & 0 deletions pkg/systemd/generate/containers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,30 @@ ExecStopPost=/usr/bin/podman stop -t 10 foobar
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
WantedBy=default.target
`

goodNameEmptyContainerPrefix := `# foobar.service
# autogenerated by Podman CI
[Unit]
Description=Podman foobar.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/var/run/containers/storage
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStart=/usr/bin/podman start foobar
ExecStop=/usr/bin/podman stop -t 10 foobar
ExecStopPost=/usr/bin/podman stop -t 10 foobar
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
WantedBy=default.target
`
Expand Down Expand Up @@ -1206,6 +1230,24 @@ WantedBy=default.target
false,
true,
},
{"good with name and empty container-prefix",
containerInfo{
Executable: "/usr/bin/podman",
ServiceName: "foobar",
ContainerNameOrID: "foobar",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 10,
PodmanVersion: "CI",
EnvVariable: define.EnvVariable,
GraphRoot: "/var/lib/containers/storage",
RunRoot: "/var/run/containers/storage",
},
goodNameEmptyContainerPrefix,
false,
false,
false,
false,
},
}
for _, tt := range tests {
test := tt
Expand Down
3 changes: 2 additions & 1 deletion pkg/systemd/generate/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,8 @@ func generatePodInfo(pod *libpod.Pod, options entities.GenerateSystemdOptions) (
nameOrID = pod.Name()
ctrNameOrID = infraCtr.Name()
}
serviceName := fmt.Sprintf("%s%s%s", options.PodPrefix, options.Separator, nameOrID)

serviceName := getServiceName(options.PodPrefix, options.Separator, nameOrID)

info := podInfo{
ServiceName: serviceName,
Expand Down
44 changes: 44 additions & 0 deletions pkg/systemd/generate/pods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,32 @@ WantedBy=default.target
podGood := serviceInfo + headerInfo + podContent
podGoodNoHeaderInfo := serviceInfo + podContent

podGoodWithEmptyPrefix := `# 123abc.service
# autogenerated by Podman CI
[Unit]
Description=Podman 123abc.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/var/run/containers/storage
Requires=container-1.service container-2.service
Before=container-1.service container-2.service
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=102
ExecStart=/usr/bin/podman start jadda-jadda-infra
ExecStop=/usr/bin/podman stop -t 42 jadda-jadda-infra
ExecStopPost=/usr/bin/podman stop -t 42 jadda-jadda-infra
PIDFile=/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
Type=forking
[Install]
WantedBy=default.target
`

podGoodCustomWants := `# pod-123abc.service
# autogenerated by Podman CI
Expand Down Expand Up @@ -580,6 +606,24 @@ WantedBy=default.target
false,
false,
},
{"pod with empty pod-prefix",
podInfo{
Executable: "/usr/bin/podman",
ServiceName: "123abc",
InfraNameOrID: "jadda-jadda-infra",
PIDFile: "/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
StopTimeout: 42,
PodmanVersion: "CI",
GraphRoot: "/var/lib/containers/storage",
RunRoot: "/var/run/containers/storage",
RequiredServices: []string{"container-1", "container-2"},
CreateCommand: []string{"podman", "pod", "create", "--name", "foo", "bar=arg with space"},
},
podGoodWithEmptyPrefix,
false,
false,
false,
},
}

for _, tt := range tests {
Expand Down
52 changes: 52 additions & 0 deletions test/e2e/generate_systemd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,20 @@ var _ = Describe("Podman generate systemd", func() {

})

It("podman generate systemd --container-prefix ''", func() {
n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"})
n.WaitWithDefaultTimeout()
Expect(n).Should(Exit(0))

session := podmanTest.Podman([]string{"generate", "systemd", "--name", "--container-prefix", "", "foo"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))

// Grepping the output (in addition to unit tests)
Expect(session.OutputToString()).To(ContainSubstring("# foo.service"))

})

It("podman generate systemd --separator _", func() {
n := podmanTest.Podman([]string{"create", "--name", "foo", "alpine", "top"})
n.WaitWithDefaultTimeout()
Expand Down Expand Up @@ -485,6 +499,44 @@ var _ = Describe("Podman generate systemd", func() {
Expect(session.OutputToString()).To(ContainSubstring("BindsTo=p_foo.service"))
})

It("podman generate systemd pod --pod-prefix '' --container-prefix '' --separator _ change all prefixes/separator", func() {
n := podmanTest.Podman([]string{"pod", "create", "--name", "foo"})
n.WaitWithDefaultTimeout()
Expect(n).Should(Exit(0))

n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-1", "alpine", "top"})
n.WaitWithDefaultTimeout()
Expect(n).Should(Exit(0))

n = podmanTest.Podman([]string{"create", "--pod", "foo", "--name", "foo-2", "alpine", "top"})
n.WaitWithDefaultTimeout()
Expect(n).Should(Exit(0))

// test systemd generate with empty pod prefix
session1 := podmanTest.Podman([]string{"generate", "systemd", "--pod-prefix", "", "--name", "foo"})
session1.WaitWithDefaultTimeout()
Expect(session1).Should(Exit(0))

// Grepping the output (in addition to unit tests)
Expect(session1.OutputToString()).To(ContainSubstring("# foo.service"))
Expect(session1.OutputToString()).To(ContainSubstring("Requires=container-foo-1.service container-foo-2.service"))
Expect(session1.OutputToString()).To(ContainSubstring("# container-foo-1.service"))
Expect(session1.OutputToString()).To(ContainSubstring("BindsTo=foo.service"))

// test systemd generate with empty container and pod prefix
session2 := podmanTest.Podman([]string{"generate", "systemd", "--container-prefix", "", "--pod-prefix", "", "--separator", "_", "--name", "foo"})
session2.WaitWithDefaultTimeout()
Expect(session2).Should(Exit(0))

// Grepping the output (in addition to unit tests)
Expect(session2.OutputToString()).To(ContainSubstring("# foo.service"))
Expect(session2.OutputToString()).To(ContainSubstring("Requires=foo-1.service foo-2.service"))
Expect(session2.OutputToString()).To(ContainSubstring("# foo-1.service"))
Expect(session2.OutputToString()).To(ContainSubstring("# foo-2.service"))
Expect(session2.OutputToString()).To(ContainSubstring("BindsTo=foo.service"))

})

It("podman generate systemd pod with containers --new", func() {
tmpDir, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())
Expand Down

0 comments on commit 6ce9677

Please sign in to comment.