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+ }
0 commit comments