Skip to content

Commit

Permalink
Separator is no longer prepended when prefix is empty on podman gener…
Browse files Browse the repository at this point in the history
…ate systemd

When podman generate systemd is invoked, it previously did not check if
container-prefix or pod-prefix are empty. When these are empty, the file name
starts with the separator, which is hyphen by default. This results in files
like '-containername.service'.

The code now checks if these prefixes are empty. If they are, the filename no
longer adds a separator. Instead, it uses name or ID of the container or pod.

Closes containers#13272

Signed-off-by: Nirmal Patel <npate012@gmail.com>
  • Loading branch information
nirmal-j-patel committed Feb 23, 2022
1 parent bc0e084 commit e84e667
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 2 deletions.
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 e84e667

Please sign in to comment.