Skip to content

Commit b4f97f7

Browse files
committed
cmd/oci-runtime-tool: add FreeBSD support
Signed-off-by: Doug Rabson <[email protected]>
1 parent 8c1f6ed commit b4f97f7

File tree

2 files changed

+306
-0
lines changed

2 files changed

+306
-0
lines changed

cmd/oci-runtime-tool/generate.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"bytes"
66
"encoding/json"
77
"fmt"
8+
"net"
89
"os"
910
"runtime"
1011
"strconv"
@@ -23,6 +24,30 @@ var generateFlags = []cli.Flag{
2324
cli.StringFlag{Name: "domainname", Usage: "domainname value for the container"},
2425
cli.StringSliceFlag{Name: "env", Usage: "add environment variable e.g. key=value"},
2526
cli.StringSliceFlag{Name: "env-file", Usage: "read in a file of environment variables"},
27+
cli.StringSliceFlag{Name: "freebsd-device-add", Usage: "add a device which must be made available in the container"},
28+
cli.StringSliceFlag{Name: "freebsd-device-remove", Usage: "remove a device which must be made available in the container"},
29+
cli.BoolFlag{Name: "freebsd-jail-allow-chflags", Usage: "allow chflags(2) inside the jail"},
30+
cli.BoolFlag{Name: "freebsd-jail-allow-mlock", Usage: "allow using mlock(2) inside the jail"},
31+
cli.StringSliceFlag{Name: "freebsd-jail-allow-mount", Usage: "allow mounting filesystems inside the jail"},
32+
cli.BoolFlag{Name: "freebsd-jail-allow-quotas", Usage: "allow administering quotas inside the jail"},
33+
cli.BoolFlag{Name: "freebsd-jail-allow-raw-sockets", Usage: "allow using raw sockets inside the jail"},
34+
cli.BoolFlag{Name: "freebsd-jail-allow-reserved-ports", Usage: "allow using reserved IP ports inside the jail"},
35+
cli.BoolFlag{Name: "freebsd-jail-allow-set-hostname", Usage: "allow setting hostname inside the jail"},
36+
cli.BoolFlag{Name: "freebsd-jail-allow-socket-af", Usage: "allow using non-IP protocols inside the jail"},
37+
cli.BoolFlag{Name: "freebsd-jail-allow-suser", Usage: "allow super-user inside the jail"},
38+
cli.IntFlag{Name: "freebsd-jail-enforce-statfs", Usage: "specifies the visibility of mounts in the jail"},
39+
cli.StringFlag{Name: "freebsd-jail-host", Usage: "specifies the jail's host namespace"},
40+
cli.StringFlag{Name: "freebsd-jail-interface", Usage: "specifies the network interface to use for ip4 and ip6 addresses"},
41+
cli.StringFlag{Name: "freebsd-jail-ip4", Usage: "specifies the jail's ip4 namespace"},
42+
cli.StringSliceFlag{Name: "freebsd-jail-ip4-addr", Usage: "specifies the jail's ip4 addresses"},
43+
cli.StringFlag{Name: "freebsd-jail-ip6", Usage: "specifies the jail's ip6 namespace"},
44+
cli.StringSliceFlag{Name: "freebsd-jail-ip6-addr", Usage: "specifies the jail's ip6 addresses"},
45+
cli.StringFlag{Name: "freebsd-jail-parent", Usage: "set the name of a parent jail which can share namespaces with this container"},
46+
cli.StringFlag{Name: "freebsd-jail-sysvmsg", Usage: "specifies the jail's SYSV IPC message namespace"},
47+
cli.StringFlag{Name: "freebsd-jail-sysvsem", Usage: "specifies the jail's SYSV IPC semaphore namespace"},
48+
cli.StringFlag{Name: "freebsd-jail-sysvshm", Usage: "specifies the jail's SYSV IPC shared memory namespace"},
49+
cli.StringFlag{Name: "freebsd-jail-vnet", Usage: "specifies the jail's vnet namespace"},
50+
cli.StringSliceFlag{Name: "freebsd-jail-vnet-interface", Usage: "specifies interfaces to move into the jail's vnet"},
2651
cli.StringSliceFlag{Name: "hooks-poststart-add", Usage: "set command to run in poststart hooks"},
2752
cli.BoolFlag{Name: "hooks-poststart-remove-all", Usage: "remove all poststart hooks"},
2853
cli.StringSliceFlag{Name: "hooks-poststop-add", Usage: "set command to run in poststop hooks"},
@@ -1017,6 +1042,134 @@ func setupSpec(g *generate.Generator, context *cli.Context) error {
10171042
g.SetWindowsServicing(context.Bool("windows-servicing"))
10181043
}
10191044

1045+
if context.IsSet("freebsd-device-add") {
1046+
devices := context.StringSlice("freebsd-device-add")
1047+
for _, deviceArg := range devices {
1048+
dev, err := parseFreeBSDDevice(deviceArg)
1049+
if err != nil {
1050+
return err
1051+
}
1052+
g.AddFreeBSDDevice(dev)
1053+
}
1054+
}
1055+
1056+
if context.IsSet("freebsd-device-remove") {
1057+
devices := context.StringSlice("freebsd-device-remove")
1058+
for _, device := range devices {
1059+
g.RemoveFreeBSDDevice(device)
1060+
}
1061+
}
1062+
if context.IsSet("freebsd-jail-parent") {
1063+
g.SetFreeBSDJailParent(context.String("freebsd-jail-parent"))
1064+
}
1065+
if context.IsSet("freebsd-jail-host") {
1066+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-host"), false)
1067+
if err != nil {
1068+
return err
1069+
}
1070+
g.SetFreeBSDJailHost(sharing)
1071+
}
1072+
if context.IsSet("freebsd-jail-ip4") {
1073+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-ip4"), true)
1074+
if err != nil {
1075+
return err
1076+
}
1077+
g.SetFreeBSDJailIp4(sharing)
1078+
}
1079+
if context.IsSet("freebsd-jail-ip4-addr") {
1080+
addrs := context.StringSlice("freebsd-jail-ip4-addr")
1081+
for _, addr := range addrs {
1082+
if !validFreeBSDIp4Addr(addr) {
1083+
return fmt.Errorf("invalid IPv4 address: %s", addr)
1084+
}
1085+
}
1086+
g.SetFreeBSDJailIp4Addr(addrs)
1087+
}
1088+
if context.IsSet("freebsd-jail-ip6") {
1089+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-ip6"), true)
1090+
if err != nil {
1091+
return err
1092+
}
1093+
g.SetFreeBSDJailIp6(sharing)
1094+
}
1095+
if context.IsSet("freebsd-jail-ip6-addr") {
1096+
addrs := context.StringSlice("freebsd-jail-ip6-addr")
1097+
for _, addr := range addrs {
1098+
if !validFreeBSDIp6Addr(addr) {
1099+
return fmt.Errorf("invalid IPv6 address: %s", addr)
1100+
}
1101+
}
1102+
g.SetFreeBSDJailIp6Addr(addrs)
1103+
}
1104+
if context.IsSet("freebsd-jail-vnet") {
1105+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-vnet"), false)
1106+
if err != nil {
1107+
return err
1108+
}
1109+
g.SetFreeBSDJailVnet(sharing)
1110+
}
1111+
if context.IsSet("freebsd-jail-interface") {
1112+
g.SetFreeBSDJailInterface(context.String("freebsd-jail-interface"))
1113+
}
1114+
if context.IsSet("freebsd-jail-vnet-interface") {
1115+
g.SetFreeBSDJailVnetInterfaces(context.StringSlice("freebsd-jail-vnet-interface"))
1116+
}
1117+
if context.IsSet("freebsd-jail-sysvmsg") {
1118+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-sysvmsg"), true)
1119+
if err != nil {
1120+
return err
1121+
}
1122+
g.SetFreeBSDJailSysVMsg(sharing)
1123+
}
1124+
if context.IsSet("freebsd-jail-sysvsem") {
1125+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-sysvsem"), true)
1126+
if err != nil {
1127+
return err
1128+
}
1129+
g.SetFreeBSDJailSysVSem(sharing)
1130+
}
1131+
if context.IsSet("freebsd-jail-sysvshm") {
1132+
sharing, err := parseFreeBSDSharing(context.String("freebsd-jail-sysvshm"), true)
1133+
if err != nil {
1134+
return err
1135+
}
1136+
g.SetFreeBSDJailSysVShm(sharing)
1137+
}
1138+
if context.IsSet("freebsd-jail-enforce-statfs") {
1139+
val := context.Int("freebsd-jail-enforce-statfs")
1140+
if val < 0 || val > 2 {
1141+
return fmt.Errorf("invalid enforce-statfs value: %d", val)
1142+
}
1143+
g.SetFreeBSDJailEnforceStatfs(val)
1144+
}
1145+
if context.IsSet("freebsd-jail-allow-set-hostname") {
1146+
g.SetFreeBSDJailAllowSetHostname(context.Bool("freebsd-jail-allow-set-hostname"))
1147+
}
1148+
if context.IsSet("freebsd-jail-allow-raw-sockets") {
1149+
g.SetFreeBSDJailAllowRawSockets(context.Bool("freebsd-jail-allow-raw-sockets"))
1150+
}
1151+
if context.IsSet("freebsd-jail-allow-reserved-ports") {
1152+
g.SetFreeBSDJailAllowReservedPorts(context.Bool("freebsd-jail-allow-reserved-ports"))
1153+
}
1154+
if context.IsSet("freebsd-jail-allow-chflags") {
1155+
g.SetFreeBSDJailAllowChflags(context.Bool("freebsd-jail-allow-chflags"))
1156+
}
1157+
if context.IsSet("freebsd-jail-allow-quotas") {
1158+
g.SetFreeBSDJailAllowQuotas(context.Bool("freebsd-jail-allow-quotas"))
1159+
}
1160+
if context.IsSet("freebsd-jail-allow-socket-af") {
1161+
g.SetFreeBSDJailAllowSocketAf(context.Bool("freebsd-jail-allow-socket-af"))
1162+
}
1163+
if context.IsSet("freebsd-jail-allow-mlock") {
1164+
g.SetFreeBSDJailAllowMlock(context.Bool("freebsd-jail-allow-mlock"))
1165+
}
1166+
if context.IsSet("freebsd-jail-allow-suser") {
1167+
g.SetFreeBSDJailAllowSuser(context.Bool("freebsd-jail-allow-suser"))
1168+
}
1169+
if context.IsSet("freebsd-jail-allow-mount") {
1170+
g.SetFreeBSDJailAllowMount(context.StringSlice("freebsd-jail-allow-mount"))
1171+
}
1172+
10201173
err := addSeccomp(context, g)
10211174
return err
10221175
}
@@ -1565,3 +1718,54 @@ func parseThrottleDevice(throttleDevice string) (int64, int64, int64, error) {
15651718

15661719
return int64(major), int64(minor), int64(rate), nil
15671720
}
1721+
1722+
// parseFreeBSDDevice takes the raw string passed with the --freebsd-device-add flag
1723+
func parseFreeBSDDevice(device string) (rspec.FreeBSDDevice, error) {
1724+
dev := rspec.FreeBSDDevice{}
1725+
argsParts := strings.Split(device, ":")
1726+
if len(argsParts) < 2 {
1727+
return dev, fmt.Errorf("Incomplete device arguments: %s", device)
1728+
}
1729+
if len(argsParts) > 2 {
1730+
return dev, fmt.Errorf("Too many device arguments: %s", device)
1731+
}
1732+
dev.Path = argsParts[0]
1733+
i, err := strconv.ParseInt(argsParts[1], 10, 32)
1734+
if err != nil {
1735+
return dev, err
1736+
}
1737+
mode := os.FileMode(i)
1738+
dev.Mode = &mode
1739+
1740+
return dev, nil
1741+
}
1742+
1743+
// parseFreeBSDSharing takes a string representing a namespace sharing mode
1744+
func parseFreeBSDSharing(sharing string, allowDisable bool) (rspec.FreeBSDSharing, error) {
1745+
if sharing == "inherit" {
1746+
return rspec.FreeBSDShareInherit, nil
1747+
}
1748+
if sharing == "new" {
1749+
return rspec.FreeBSDShareNew, nil
1750+
}
1751+
if allowDisable && sharing == "disable" {
1752+
return rspec.FreeBSDShareDisable, nil
1753+
}
1754+
return "", fmt.Errorf("Invalid sharing mode: %s", sharing)
1755+
}
1756+
1757+
func validFreeBSDIp4Addr(addr string) bool {
1758+
ip := net.ParseIP(addr)
1759+
if ip == nil || ip.To4() == nil {
1760+
return false
1761+
}
1762+
return true
1763+
}
1764+
1765+
func validFreeBSDIp6Addr(addr string) bool {
1766+
ip := net.ParseIP(addr)
1767+
if ip == nil || ip.To4() != nil {
1768+
return false
1769+
}
1770+
return true
1771+
}

man/oci-runtime-tool-generate.1.md

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,108 @@ read the configuration from `config.json`.
3939
When specified multiple times, files are loaded in order with duplicate
4040
keys overwriting previous ones.
4141

42+
**--freebsd-device-add**=*PATH:MODE*
43+
Add a device file in container. e.g. --freebsd-device-add=/dev/cuau0c/fuse:438
44+
*PATH* is the device path.
45+
*MODE* is the file mode of the device file.
46+
This option can be specified multiple times.
47+
48+
**--freebsd-device-remove**=*PATH*
49+
Remove a device file in container.
50+
This option can be specified multiple times.
51+
52+
**--freebsd-jail-allow-chflags**
53+
Allow using the *chroot* syscall inside the container.
54+
55+
**--freebsd-jail-allow-mlock**
56+
Allow using the *mlock* and *munlock* syscalls inside the container.
57+
58+
**--freebsd-jail-allow-mount**=*FSTYPE*
59+
Allow mounting filesystems of type *FSTYPE* inside the container.
60+
This option can be specified multiple times.
61+
62+
**--freebsd-jail-allow-quotas**
63+
Allow administering quotas inside the container.
64+
65+
**--freebsd-jail-allow-raw-sockets**
66+
Allow using raw sockets inside the container.
67+
68+
**--freebsd-jail-allow-reserved-ports**
69+
Allow using reserved IP ports inside the container.
70+
71+
**--freebsd-jail-allow-set-hostname**
72+
Allow setting hostname inside the container.
73+
74+
**--freebsd-jail-allow-socket-af**
75+
Allow using non-IP network protocols inside the container.
76+
77+
**--freebsd-jail-allow-suser**
78+
Allow super-user inside the container.
79+
80+
**--freebsd-jail-enforce-statfs**=*VALUE*
81+
Specifies the visibility of mounts in the container. The value should be one of:
82+
*0* all mount points on the host are visible.
83+
*1* only mount points below the container's root are visible.
84+
*2* syscalls are limited to operate only on a mount-point where the container's root directory is located.
85+
86+
**--freebsd-jail-host**=*SHARING*
87+
Specify the jail's host namespace. The value of *SHARING* should be one of:
88+
*new* to create a new namespace for the container.
89+
*inherit* to share the namespace from the host (or parent jail if specified).
90+
91+
**--freebsd-jail-interface**=*INTERFACE*
92+
Specifies a network interface to use for IPv4 and IPv6 addresses when not using *VNET*.
93+
94+
**--freebsd-jail-ip4**=*SHARING*
95+
Specify the jail's IPv4 namespace. The value of *SHARING* should be one of:
96+
*new* to create a new namespace for the container.
97+
*inherit* to share the host namespace from the host (or parent jail if specified).
98+
*disable* to stop the container from using IPv4.
99+
100+
**--freebsd-jail-ip4-addr**=*ADDRESS*
101+
Specifies an IPv4 address that is available for the container.
102+
This option can be specified multiple times.
103+
104+
**--freebsd-jail-ip6**=*SHARING*
105+
Specify the jail's IPv6 namespace. The value of *SHARING* should be one of:
106+
*new* to create a new namespace for the container.
107+
*inherit* to share the host namespace from the host (or parent jail if specified).
108+
*disable* to stop the container from using IPv6.
109+
110+
**--freebsd-jail-ip6-addr**=*ADDRESS*
111+
Specifies an IPv6 address that is available for the container.
112+
This option can be specified multiple times.
113+
114+
**--freebsd-jail-parent**=*NAME*
115+
Specify the name of a parent jail for this container, if required.
116+
117+
**--freebsd-jail-sysvmsg**=*SHARING*
118+
Specify the jail's SYSV IPC message namespace. The value of *SHARING* should be one of:
119+
*new* to create a new namespace for the container.
120+
*inherit* to share the host namespace from the host (or parent jail if specified).
121+
*disable* to stop the container from using SYSV messages.
122+
123+
**--freebsd-jail-sysvsem**=*SHARING*
124+
Specify the jail's SYSV IPC semaphore namespace. The value of *SHARING* should be one of:
125+
*new* to create a new namespace for the container.
126+
*inherit* to share the host namespace from the host (or parent jail if specified).
127+
*disable* to stop the container from using SYSV semaphores.
128+
129+
**--freebsd-jail-sysvshm**=*SHARING*
130+
Specify the jail's SYSV IPC shared memory namespace. The value of *SHARING* should be one of:
131+
*new* to create a new namespace for the container.
132+
*inherit* to share the host namespace from the host (or parent jail if specified).
133+
*disable* to stop the container from using SYSV shared memory.
134+
135+
**--freebsd-jail-vnet**=*SHARING*
136+
Specify the jail's VNET namespace. The value of *SHARING* should be one of:
137+
*new* to create a new namespace for the container.
138+
*inherit* to share the host namespace from the host (or parent jail if specified).
139+
140+
**--freebsd-jail-vnet-interface**=*INTERFACE*
141+
Specifies an interface to move into the container's vnet during its lifetime.
142+
This option can be specified multiple times.
143+
42144
**--help**
43145
Print usage statement
44146

0 commit comments

Comments
 (0)