зеркало из https://github.com/microsoft/docker.git
LXC CAP ADD CAP DROP IN TEMPLATE
Added cap-drop and cap-add in lxc template Docker-DCO-1.1-Signed-off-by: Abin Shahab <ashahab@altiscale.com> (github: ashahab-altiscale)
This commit is contained in:
Родитель
595cd5279e
Коммит
fdf7457683
|
@ -123,14 +123,6 @@ func (d *driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, startCallba
|
|||
params = append(params, "-w", c.WorkingDir)
|
||||
}
|
||||
|
||||
if len(c.CapAdd) > 0 {
|
||||
params = append(params, fmt.Sprintf("-cap-add=%s", strings.Join(c.CapAdd, ":")))
|
||||
}
|
||||
|
||||
if len(c.CapDrop) > 0 {
|
||||
params = append(params, fmt.Sprintf("-cap-drop=%s", strings.Join(c.CapDrop, ":")))
|
||||
}
|
||||
|
||||
params = append(params, "--", c.ProcessConfig.Entrypoint)
|
||||
params = append(params, c.ProcessConfig.Arguments...)
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
@ -14,7 +13,6 @@ import (
|
|||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/reexec"
|
||||
"github.com/docker/libcontainer/netlink"
|
||||
)
|
||||
|
||||
// Args provided to the init function for a driver
|
||||
|
@ -59,12 +57,7 @@ func setupNamespace(args *InitArgs) error {
|
|||
if err := setupEnv(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setupHostname(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setupNetworking(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := finalizeNamespace(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -138,59 +131,6 @@ func setupEnv(args *InitArgs) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func setupHostname(args *InitArgs) error {
|
||||
hostname := getEnv(args, "HOSTNAME")
|
||||
if hostname == "" {
|
||||
return nil
|
||||
}
|
||||
return setHostname(hostname)
|
||||
}
|
||||
|
||||
// Setup networking
|
||||
func setupNetworking(args *InitArgs) error {
|
||||
if args.Ip != "" {
|
||||
// eth0
|
||||
iface, err := net.InterfaceByName("eth0")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
ip, ipNet, err := net.ParseCIDR(args.Ip)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
if err := netlink.NetworkLinkAddIp(iface, ip, ipNet); err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
if err := netlink.NetworkSetMTU(iface, args.Mtu); err != nil {
|
||||
return fmt.Errorf("Unable to set MTU: %v", err)
|
||||
}
|
||||
if err := netlink.NetworkLinkUp(iface); err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
|
||||
// loopback
|
||||
iface, err = net.InterfaceByName("lo")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
if err := netlink.NetworkLinkUp(iface); err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
}
|
||||
if args.Gateway != "" {
|
||||
gw := net.ParseIP(args.Gateway)
|
||||
if gw == nil {
|
||||
return fmt.Errorf("Unable to set up networking, %s is not a valid gateway IP", args.Gateway)
|
||||
}
|
||||
|
||||
if err := netlink.AddDefaultGw(gw.String(), "eth0"); err != nil {
|
||||
return fmt.Errorf("Unable to set up networking: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setup working directory
|
||||
func setupWorkingDirectory(args *InitArgs) error {
|
||||
if args.WorkDir == "" {
|
||||
|
|
|
@ -2,74 +2,19 @@ package lxc
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
"github.com/docker/docker/daemon/execdriver/native/template"
|
||||
"github.com/docker/libcontainer/namespaces"
|
||||
"github.com/docker/libcontainer/security/capabilities"
|
||||
"github.com/docker/libcontainer/system"
|
||||
"github.com/docker/libcontainer/utils"
|
||||
)
|
||||
|
||||
func setHostname(hostname string) error {
|
||||
return syscall.Sethostname([]byte(hostname))
|
||||
}
|
||||
|
||||
func finalizeNamespace(args *InitArgs) error {
|
||||
if err := utils.CloseExecFrom(3); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We use the native drivers default template so that things like caps are consistent
|
||||
// across both drivers
|
||||
container := template.New()
|
||||
|
||||
if !args.Privileged {
|
||||
// drop capabilities in bounding set before changing user
|
||||
if err := capabilities.DropBoundingSet(container.Capabilities); err != nil {
|
||||
return fmt.Errorf("drop bounding set %s", err)
|
||||
}
|
||||
|
||||
// preserve existing capabilities while we change users
|
||||
if err := system.SetKeepCaps(); err != nil {
|
||||
return fmt.Errorf("set keep caps %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := namespaces.SetupUser(args.User); err != nil {
|
||||
return fmt.Errorf("setup user %s", err)
|
||||
}
|
||||
|
||||
if !args.Privileged {
|
||||
if err := system.ClearKeepCaps(); err != nil {
|
||||
return fmt.Errorf("clear keep caps %s", err)
|
||||
}
|
||||
|
||||
var (
|
||||
adds []string
|
||||
drops []string
|
||||
)
|
||||
|
||||
if args.CapAdd != "" {
|
||||
adds = strings.Split(args.CapAdd, ":")
|
||||
}
|
||||
if args.CapDrop != "" {
|
||||
drops = strings.Split(args.CapDrop, ":")
|
||||
}
|
||||
|
||||
caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// drop all other capabilities
|
||||
if err := capabilities.DropCapabilities(caps); err != nil {
|
||||
return fmt.Errorf("drop capabilities %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := setupWorkingDirectory(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
package lxc
|
||||
|
||||
func setHostname(hostname string) error {
|
||||
panic("Not supported on darwin")
|
||||
}
|
||||
|
||||
func finalizeNamespace(args *InitArgs) error {
|
||||
panic("Not supported on darwin")
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package lxc
|
|||
|
||||
import (
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
|
||||
"github.com/docker/libcontainer/label"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -15,6 +16,13 @@ lxc.network.type = veth
|
|||
lxc.network.link = {{.Network.Interface.Bridge}}
|
||||
lxc.network.name = eth0
|
||||
lxc.network.mtu = {{.Network.Mtu}}
|
||||
{{if .Network.Interface.IPAddress}}
|
||||
lxc.network.ipv4 = {{.Network.Interface.IPAddress}}/{{.Network.Interface.IPPrefixLen}}
|
||||
{{end}}
|
||||
{{if .Network.Interface.Gateway}}
|
||||
lxc.network.ipv4.gateway = {{.Network.Interface.Gateway}}
|
||||
{{end}}
|
||||
lxc.network.flags = up
|
||||
{{else if .Network.HostNetworking}}
|
||||
lxc.network.type = none
|
||||
{{else}}
|
||||
|
@ -78,6 +86,18 @@ lxc.mount.entry = {{$value.Source}} {{escapeFstabSpaces $ROOTFS}}/{{escapeFstabS
|
|||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if .ProcessConfig.Env}}
|
||||
lxc.utsname = {{getHostname .ProcessConfig.Env}}
|
||||
{{end}}
|
||||
|
||||
{{if .ProcessConfig.Privileged}}
|
||||
# No cap values are needed, as lxc is starting in privileged mode
|
||||
{{else}}
|
||||
{{range $value := keepCapabilities .CapAdd .CapDrop}}
|
||||
lxc.cap.keep = {{$value}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if .ProcessConfig.Privileged}}
|
||||
{{if .AppArmor}}
|
||||
lxc.aa_profile = unconfined
|
||||
|
@ -118,6 +138,19 @@ func escapeFstabSpaces(field string) string {
|
|||
return strings.Replace(field, " ", "\\040", -1)
|
||||
}
|
||||
|
||||
func keepCapabilities(adds []string, drops []string) []string {
|
||||
container := nativeTemplate.New()
|
||||
caps, err := execdriver.TweakCapabilities(container.Capabilities, adds, drops)
|
||||
var newCaps []string
|
||||
for _, cap := range caps {
|
||||
newCaps = append(newCaps, strings.ToLower(cap))
|
||||
}
|
||||
if err != nil {
|
||||
return []string{}
|
||||
}
|
||||
return newCaps
|
||||
}
|
||||
|
||||
func isDirectory(source string) string {
|
||||
f, err := os.Stat(source)
|
||||
if err != nil {
|
||||
|
@ -152,6 +185,16 @@ func getLabel(c map[string][]string, name string) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func getHostname(env []string) string {
|
||||
for _, kv := range env {
|
||||
parts := strings.SplitN(kv, "=", 2)
|
||||
if parts[0] == "HOSTNAME" && len(parts) == 2 {
|
||||
return parts[1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
funcMap := template.FuncMap{
|
||||
|
@ -159,6 +202,8 @@ func init() {
|
|||
"escapeFstabSpaces": escapeFstabSpaces,
|
||||
"formatMountLabel": label.FormatMountLabel,
|
||||
"isDirectory": isDirectory,
|
||||
"keepCapabilities": keepCapabilities,
|
||||
"getHostname": getHostname,
|
||||
}
|
||||
LxcTemplateCompiled, err = template.New("lxc").Funcs(funcMap).Parse(LxcTemplate)
|
||||
if err != nil {
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/docker/docker/daemon/execdriver"
|
||||
nativeTemplate "github.com/docker/docker/daemon/execdriver/native/template"
|
||||
"github.com/docker/libcontainer/devices"
|
||||
)
|
||||
|
||||
|
@ -104,6 +105,10 @@ func TestCustomLxcConfig(t *testing.T) {
|
|||
}
|
||||
|
||||
func grepFile(t *testing.T, path string, pattern string) {
|
||||
grepFileWithReverse(t, path, pattern, false)
|
||||
}
|
||||
|
||||
func grepFileWithReverse(t *testing.T, path string, pattern string, inverseGrep bool) {
|
||||
f, err := os.Open(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -117,9 +122,15 @@ func grepFile(t *testing.T, path string, pattern string) {
|
|||
for err == nil {
|
||||
line, err = r.ReadString('\n')
|
||||
if strings.Contains(line, pattern) == true {
|
||||
if inverseGrep {
|
||||
t.Fatalf("grepFile: pattern \"%s\" found in \"%s\"", pattern, path)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
if inverseGrep {
|
||||
return
|
||||
}
|
||||
t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
|
||||
}
|
||||
|
||||
|
@ -228,3 +239,64 @@ func TestCustomLxcConfigMounts(t *testing.T) {
|
|||
grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,ro,create=%s 0 0", tempDir, "/"+tempDir, "dir"))
|
||||
grepFile(t, p, fmt.Sprintf("lxc.mount.entry = %s %s none rbind,rw,create=%s 0 0", tempFile.Name(), "/"+tempFile.Name(), "file"))
|
||||
}
|
||||
|
||||
func TestCustomLxcConfigMisc(t *testing.T) {
|
||||
root, err := ioutil.TempDir("", "TestCustomLxcConfig")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll(root)
|
||||
os.MkdirAll(path.Join(root, "containers", "1"), 0777)
|
||||
driver, err := NewDriver(root, "", false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
processConfig := execdriver.ProcessConfig{
|
||||
Privileged: false,
|
||||
}
|
||||
|
||||
processConfig.Env = []string{"HOSTNAME=testhost"}
|
||||
command := &execdriver.Command{
|
||||
ID: "1",
|
||||
LxcConfig: []string{
|
||||
"lxc.cgroup.cpuset.cpus = 0,1",
|
||||
},
|
||||
Network: &execdriver.Network{
|
||||
Mtu: 1500,
|
||||
Interface: &execdriver.NetworkInterface{
|
||||
Gateway: "10.10.10.1",
|
||||
IPAddress: "10.10.10.10",
|
||||
IPPrefixLen: 24,
|
||||
Bridge: "docker0",
|
||||
},
|
||||
},
|
||||
ProcessConfig: processConfig,
|
||||
CapAdd: []string{"net_admin", "syslog"},
|
||||
CapDrop: []string{"kill", "mknod"},
|
||||
}
|
||||
|
||||
p, err := driver.generateLXCConfig(command)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// network
|
||||
grepFile(t, p, "lxc.network.type = veth")
|
||||
grepFile(t, p, "lxc.network.link = docker0")
|
||||
grepFile(t, p, "lxc.network.name = eth0")
|
||||
grepFile(t, p, "lxc.network.ipv4 = 10.10.10.10/24")
|
||||
grepFile(t, p, "lxc.network.ipv4.gateway = 10.10.10.1")
|
||||
grepFile(t, p, "lxc.network.flags = up")
|
||||
|
||||
// hostname
|
||||
grepFile(t, p, "lxc.utsname = testhost")
|
||||
grepFile(t, p, "lxc.cgroup.cpuset.cpus = 0,1")
|
||||
container := nativeTemplate.New()
|
||||
for _, cap := range container.Capabilities {
|
||||
cap = strings.ToLower(cap)
|
||||
if cap != "mknod" && cap != "kill" {
|
||||
grepFile(t, p, fmt.Sprintf("lxc.cap.keep = %s", cap))
|
||||
}
|
||||
}
|
||||
grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = kill"), true)
|
||||
grepFileWithReverse(t, p, fmt.Sprintf("lxc.cap.keep = mknod"), true)
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче