Skip to content

Commit d87652b

Browse files
authored
Add support for ipc field (#103)
- Translates ipc to --ipc flag for both Docker and Podman - Supports all IPC modes: host, private, shareable, container:name, service:name - Automatically converts service:X to container:X (similar to network_mode) - Adds proper systemd dependencies when using service: mode
1 parent 983c7a7 commit d87652b

6 files changed

Lines changed: 341 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ If a feature is missing, please feel free to [create an issue](https://github.co
430430
| [`mac_address`](https://docs.docker.com/compose/compose-file/05-services/#mac_address) | ✅ | |
431431
| [`user`](https://docs.docker.com/compose/compose-file/05-services/#user) | ✅ | |
432432
| [`group_add`](https://docs.docker.com/compose/compose-file/05-services/#group_add) | ✅ | |
433+
| [`ipc`](https://docs.docker.com/compose/compose-file/05-services/#ipc) | ✅ | |
433434

434435
#### [`networks`](https://docs.docker.com/compose/compose-file/06-networks/)
435436

compose.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,20 @@ func (g *Generator) buildNixContainer(service types.ServiceConfig, networkMap ma
679679
c.ExtraOptions = append(c.ExtraOptions, "--group-add="+group)
680680
}
681681

682+
// https://docs.docker.com/compose/compose-file/05-services/#ipc
683+
// https://docs.docker.com/engine/reference/run/#ipc-settings---ipc
684+
// https://docs.podman.io/en/latest/markdown/podman-run.1.html#ipc-ipc
685+
if ipc := strings.TrimSpace(service.Ipc); ipc != "" {
686+
if strings.HasPrefix(ipc, "service:") {
687+
// Convert the Compose "service" IPC mode to a "container" IPC mode.
688+
// Note: compose-go automatically validates the service exists and adds it as a dependency.
689+
targetService := strings.Split(ipc, ":")[1]
690+
c.ExtraOptions = append(c.ExtraOptions, "--ipc=container:"+g.serviceToContainerName[targetService])
691+
} else {
692+
c.ExtraOptions = append(c.ExtraOptions, "--ipc="+ipc)
693+
}
694+
}
695+
682696
// https://docs.docker.com/compose/compose-file/05-services/#sysctls
683697
// https://docs.docker.com/engine/reference/commandline/run/#sysctl
684698
// https://docs.podman.io/en/latest/markdown/podman-run.1.html#sysctl-name-value

nix_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,3 +499,12 @@ func TestGroupAdd(t *testing.T) {
499499
}
500500
runSubtestsWithGenerator(t, g)
501501
}
502+
503+
func TestIpc(t *testing.T) {
504+
composePath, _ := getPaths(t, false)
505+
g := &Generator{
506+
Inputs: []string{composePath},
507+
Project: NewProject("test"),
508+
}
509+
runSubtestsWithGenerator(t, g)
510+
}

testdata/TestIpc.compose.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
services:
2+
test-ipc-host:
3+
image: alpine:latest
4+
ipc: host
5+
test-ipc-private:
6+
image: alpine:latest
7+
ipc: private
8+
test-ipc-shareable:
9+
image: alpine:latest
10+
ipc: shareable
11+
test-ipc-service:
12+
image: alpine:latest
13+
ipc: "service:test-ipc-shareable"
14+
test-ipc-container:
15+
image: alpine:latest
16+
ipc: "container:external-container"

testdata/TestIpc.docker.nix

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Auto-generated by compose2nix.
2+
3+
{ pkgs, lib, ... }:
4+
5+
{
6+
# Runtime
7+
virtualisation.docker = {
8+
enable = true;
9+
autoPrune.enable = true;
10+
};
11+
virtualisation.oci-containers.backend = "docker";
12+
13+
# Containers
14+
virtualisation.oci-containers.containers."test-test-ipc-container" = {
15+
image = "alpine:latest";
16+
log-driver = "journald";
17+
autoStart = false;
18+
extraOptions = [
19+
"--ipc=container:external-container"
20+
"--network-alias=test-ipc-container"
21+
"--network=test_default"
22+
];
23+
};
24+
systemd.services."docker-test-test-ipc-container" = {
25+
serviceConfig = {
26+
Restart = lib.mkOverride 90 "no";
27+
};
28+
after = [
29+
"docker-network-test_default.service"
30+
];
31+
requires = [
32+
"docker-network-test_default.service"
33+
];
34+
};
35+
virtualisation.oci-containers.containers."test-test-ipc-host" = {
36+
image = "alpine:latest";
37+
log-driver = "journald";
38+
autoStart = false;
39+
extraOptions = [
40+
"--ipc=host"
41+
"--network-alias=test-ipc-host"
42+
"--network=test_default"
43+
];
44+
};
45+
systemd.services."docker-test-test-ipc-host" = {
46+
serviceConfig = {
47+
Restart = lib.mkOverride 90 "no";
48+
};
49+
after = [
50+
"docker-network-test_default.service"
51+
];
52+
requires = [
53+
"docker-network-test_default.service"
54+
];
55+
};
56+
virtualisation.oci-containers.containers."test-test-ipc-private" = {
57+
image = "alpine:latest";
58+
log-driver = "journald";
59+
autoStart = false;
60+
extraOptions = [
61+
"--ipc=private"
62+
"--network-alias=test-ipc-private"
63+
"--network=test_default"
64+
];
65+
};
66+
systemd.services."docker-test-test-ipc-private" = {
67+
serviceConfig = {
68+
Restart = lib.mkOverride 90 "no";
69+
};
70+
after = [
71+
"docker-network-test_default.service"
72+
];
73+
requires = [
74+
"docker-network-test_default.service"
75+
];
76+
};
77+
virtualisation.oci-containers.containers."test-test-ipc-service" = {
78+
image = "alpine:latest";
79+
dependsOn = [
80+
"test-test-ipc-shareable"
81+
];
82+
log-driver = "journald";
83+
autoStart = false;
84+
extraOptions = [
85+
"--ipc=container:test-test-ipc-shareable"
86+
"--network-alias=test-ipc-service"
87+
"--network=test_default"
88+
];
89+
};
90+
systemd.services."docker-test-test-ipc-service" = {
91+
serviceConfig = {
92+
Restart = lib.mkOverride 90 "no";
93+
};
94+
after = [
95+
"docker-network-test_default.service"
96+
];
97+
requires = [
98+
"docker-network-test_default.service"
99+
];
100+
};
101+
virtualisation.oci-containers.containers."test-test-ipc-shareable" = {
102+
image = "alpine:latest";
103+
log-driver = "journald";
104+
autoStart = false;
105+
extraOptions = [
106+
"--ipc=shareable"
107+
"--network-alias=test-ipc-shareable"
108+
"--network=test_default"
109+
];
110+
};
111+
systemd.services."docker-test-test-ipc-shareable" = {
112+
serviceConfig = {
113+
Restart = lib.mkOverride 90 "no";
114+
};
115+
after = [
116+
"docker-network-test_default.service"
117+
];
118+
requires = [
119+
"docker-network-test_default.service"
120+
];
121+
};
122+
123+
# Networks
124+
systemd.services."docker-network-test_default" = {
125+
path = [ pkgs.docker ];
126+
serviceConfig = {
127+
Type = "oneshot";
128+
RemainAfterExit = true;
129+
ExecStop = "docker network rm -f test_default";
130+
};
131+
script = ''
132+
docker network inspect test_default || docker network create test_default
133+
'';
134+
partOf = [ "docker-compose-test-root.target" ];
135+
wantedBy = [ "docker-compose-test-root.target" ];
136+
};
137+
138+
# Root service
139+
# When started, this will automatically create all resources and start
140+
# the containers. When stopped, this will teardown all resources.
141+
systemd.targets."docker-compose-test-root" = {
142+
unitConfig = {
143+
Description = "Root target generated by compose2nix.";
144+
};
145+
};
146+
}

testdata/TestIpc.podman.nix

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# Auto-generated by compose2nix.
2+
3+
{ pkgs, lib, config, ... }:
4+
5+
{
6+
# Runtime
7+
virtualisation.podman = {
8+
enable = true;
9+
autoPrune.enable = true;
10+
dockerCompat = true;
11+
};
12+
13+
# Enable container name DNS for all Podman networks.
14+
networking.firewall.interfaces = let
15+
matchAll = if !config.networking.nftables.enable then "podman+" else "podman*";
16+
in {
17+
"${matchAll}".allowedUDPPorts = [ 53 ];
18+
};
19+
20+
virtualisation.oci-containers.backend = "podman";
21+
22+
# Containers
23+
virtualisation.oci-containers.containers."test-test-ipc-container" = {
24+
image = "alpine:latest";
25+
log-driver = "journald";
26+
autoStart = false;
27+
extraOptions = [
28+
"--ipc=container:external-container"
29+
"--network-alias=test-ipc-container"
30+
"--network=test_default"
31+
];
32+
};
33+
systemd.services."podman-test-test-ipc-container" = {
34+
serviceConfig = {
35+
Restart = lib.mkOverride 90 "no";
36+
};
37+
after = [
38+
"podman-network-test_default.service"
39+
];
40+
requires = [
41+
"podman-network-test_default.service"
42+
];
43+
};
44+
virtualisation.oci-containers.containers."test-test-ipc-host" = {
45+
image = "alpine:latest";
46+
log-driver = "journald";
47+
autoStart = false;
48+
extraOptions = [
49+
"--ipc=host"
50+
"--network-alias=test-ipc-host"
51+
"--network=test_default"
52+
];
53+
};
54+
systemd.services."podman-test-test-ipc-host" = {
55+
serviceConfig = {
56+
Restart = lib.mkOverride 90 "no";
57+
};
58+
after = [
59+
"podman-network-test_default.service"
60+
];
61+
requires = [
62+
"podman-network-test_default.service"
63+
];
64+
};
65+
virtualisation.oci-containers.containers."test-test-ipc-private" = {
66+
image = "alpine:latest";
67+
log-driver = "journald";
68+
autoStart = false;
69+
extraOptions = [
70+
"--ipc=private"
71+
"--network-alias=test-ipc-private"
72+
"--network=test_default"
73+
];
74+
};
75+
systemd.services."podman-test-test-ipc-private" = {
76+
serviceConfig = {
77+
Restart = lib.mkOverride 90 "no";
78+
};
79+
after = [
80+
"podman-network-test_default.service"
81+
];
82+
requires = [
83+
"podman-network-test_default.service"
84+
];
85+
};
86+
virtualisation.oci-containers.containers."test-test-ipc-service" = {
87+
image = "alpine:latest";
88+
dependsOn = [
89+
"test-test-ipc-shareable"
90+
];
91+
log-driver = "journald";
92+
autoStart = false;
93+
extraOptions = [
94+
"--ipc=container:test-test-ipc-shareable"
95+
"--network-alias=test-ipc-service"
96+
"--network=test_default"
97+
];
98+
};
99+
systemd.services."podman-test-test-ipc-service" = {
100+
serviceConfig = {
101+
Restart = lib.mkOverride 90 "no";
102+
};
103+
after = [
104+
"podman-network-test_default.service"
105+
];
106+
requires = [
107+
"podman-network-test_default.service"
108+
];
109+
};
110+
virtualisation.oci-containers.containers."test-test-ipc-shareable" = {
111+
image = "alpine:latest";
112+
log-driver = "journald";
113+
autoStart = false;
114+
extraOptions = [
115+
"--ipc=shareable"
116+
"--network-alias=test-ipc-shareable"
117+
"--network=test_default"
118+
];
119+
};
120+
systemd.services."podman-test-test-ipc-shareable" = {
121+
serviceConfig = {
122+
Restart = lib.mkOverride 90 "no";
123+
};
124+
after = [
125+
"podman-network-test_default.service"
126+
];
127+
requires = [
128+
"podman-network-test_default.service"
129+
];
130+
};
131+
132+
# Networks
133+
systemd.services."podman-network-test_default" = {
134+
path = [ pkgs.podman ];
135+
serviceConfig = {
136+
Type = "oneshot";
137+
RemainAfterExit = true;
138+
ExecStop = "podman network rm -f test_default";
139+
};
140+
script = ''
141+
podman network inspect test_default || podman network create test_default
142+
'';
143+
partOf = [ "podman-compose-test-root.target" ];
144+
wantedBy = [ "podman-compose-test-root.target" ];
145+
};
146+
147+
# Root service
148+
# When started, this will automatically create all resources and start
149+
# the containers. When stopped, this will teardown all resources.
150+
systemd.targets."podman-compose-test-root" = {
151+
unitConfig = {
152+
Description = "Root target generated by compose2nix.";
153+
};
154+
};
155+
}

0 commit comments

Comments
 (0)