LXC container support without LXD (#552)

* LXC container support without LXD

* Fix: LXC required root privilege

* Update README
This commit is contained in:
Mai MISHIRO
2017-12-18 22:54:32 +09:00
committed by Kota Kanbe
parent 19b581edef
commit 0e8736045e
5 changed files with 173 additions and 17 deletions

View File

@@ -110,6 +110,12 @@ func (l *base) allContainers() (containers []config.Container, err error) {
return containers, err
}
return l.parseLxdPs(stdout)
case "lxc":
stdout, err := l.lxcPs("-1")
if err != nil {
return containers, err
}
return l.parseLxcPs(stdout)
default:
return containers, fmt.Errorf(
"Not supported yet: %s", l.ServerInfo.Containers.Type)
@@ -130,6 +136,12 @@ func (l *base) runningContainers() (containers []config.Container, err error) {
return containers, err
}
return l.parseLxdPs(stdout)
case "lxc":
stdout, err := l.lxcPs("-1 --running")
if err != nil {
return containers, err
}
return l.parseLxcPs(stdout)
default:
return containers, fmt.Errorf(
"Not supported yet: %s", l.ServerInfo.Containers.Type)
@@ -150,6 +162,12 @@ func (l *base) exitedContainers() (containers []config.Container, err error) {
return containers, err
}
return l.parseLxdPs(stdout)
case "lxc":
stdout, err := l.lxcPs("-1 --stopped")
if err != nil {
return containers, err
}
return l.parseLxcPs(stdout)
default:
return containers, fmt.Errorf(
"Not supported yet: %s", l.ServerInfo.Containers.Type)
@@ -174,6 +192,15 @@ func (l *base) lxdPs(option string) (string, error) {
return r.Stdout, nil
}
func (l *base) lxcPs(option string) (string, error) {
cmd := fmt.Sprintf("lxc-ls %s 2>/dev/null", option)
r := l.exec(cmd, sudo)
if !r.isSuccess() {
return "", fmt.Errorf("failed to SSH: %s", r)
}
return r.Stdout, nil
}
func (l *base) parseDockerPs(stdout string) (containers []config.Container, err error) {
lines := strings.Split(stdout, "\n")
for _, line := range lines {
@@ -214,6 +241,21 @@ func (l *base) parseLxdPs(stdout string) (containers []config.Container, err err
return
}
func (l *base) parseLxcPs(stdout string) (containers []config.Container, err error) {
lines := strings.Split(stdout, "\n")
for _, line := range lines {
fields := strings.Fields(line)
if len(fields) == 0 {
break
}
containers = append(containers, config.Container{
ContainerID: fields[0],
Name: fields[0],
})
}
return
}
func (l *base) detectPlatform() {
ok, instanceID, err := l.detectRunningOnAws()
if err != nil {

View File

@@ -365,8 +365,16 @@ func decorateCmd(c conf.ServerInfo, cmd string, sudo bool) string {
cmd = fmt.Sprintf(`docker exec --user 0 %s %s -c '%s'`,
c.Container.ContainerID, dockerShell(c.Distro.Family), cmd)
case "lxd":
// If the user belong to the "lxd" group, root privilege is not required.
cmd = fmt.Sprintf(`lxc exec %s -- %s -c '%s'`,
c.Container.Name, dockerShell(c.Distro.Family), cmd)
case "lxc":
cmd = fmt.Sprintf(`lxc-attach -n %s 2>/dev/null -- %s -c '%s'`,
c.Container.Name, dockerShell(c.Distro.Family), cmd)
// LXC required root privilege
if c.User != "root" {
cmd = fmt.Sprintf("sudo -S %s", cmd)
}
}
}
// cmd = fmt.Sprintf("set -x; %s", cmd)

View File

@@ -46,21 +46,21 @@ func TestDecorateCmd(t *testing.T) {
},
// non-root sudo false
{
conf: config.ServerInfo{User: "non-roor"},
conf: config.ServerInfo{User: "non-root"},
cmd: "ls",
sudo: false,
expected: "ls",
},
// non-root sudo true
{
conf: config.ServerInfo{User: "non-roor"},
conf: config.ServerInfo{User: "non-root"},
cmd: "ls",
sudo: true,
expected: "sudo -S ls",
},
// non-root sudo true
{
conf: config.ServerInfo{User: "non-roor"},
conf: config.ServerInfo{User: "non-root"},
cmd: "ls | grep hoge",
sudo: true,
expected: "sudo -S ls | grep hoge",
@@ -70,7 +70,7 @@ func TestDecorateCmd(t *testing.T) {
{
conf: config.ServerInfo{
User: "root",
Container: config.Container{ContainerID: "abc"},
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "docker"},
},
cmd: "ls",
@@ -81,7 +81,7 @@ func TestDecorateCmd(t *testing.T) {
{
conf: config.ServerInfo{
User: "root",
Container: config.Container{ContainerID: "abc"},
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "docker"},
},
cmd: "ls",
@@ -92,7 +92,7 @@ func TestDecorateCmd(t *testing.T) {
{
conf: config.ServerInfo{
User: "non-root",
Container: config.Container{ContainerID: "abc"},
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "docker"},
},
cmd: "ls",
@@ -103,7 +103,7 @@ func TestDecorateCmd(t *testing.T) {
{
conf: config.ServerInfo{
User: "non-root",
Container: config.Container{ContainerID: "abc"},
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "docker"},
},
cmd: "ls",
@@ -114,7 +114,7 @@ func TestDecorateCmd(t *testing.T) {
{
conf: config.ServerInfo{
User: "non-root",
Container: config.Container{ContainerID: "abc"},
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "docker"},
},
cmd: "ls | grep hoge",
@@ -177,6 +177,62 @@ func TestDecorateCmd(t *testing.T) {
sudo: true,
expected: `lxc exec def -- /bin/sh -c 'ls | grep hoge'`,
},
// -------------lxc-------------
// root sudo false lxc
{
conf: config.ServerInfo{
User: "root",
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "lxc"},
},
cmd: "ls",
sudo: false,
expected: `lxc-attach -n def 2>/dev/null -- /bin/sh -c 'ls'`,
},
// root sudo true lxc
{
conf: config.ServerInfo{
User: "root",
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "lxc"},
},
cmd: "ls",
sudo: true,
expected: `lxc-attach -n def 2>/dev/null -- /bin/sh -c 'ls'`,
},
// non-root sudo false, lxc
{
conf: config.ServerInfo{
User: "non-root",
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "lxc"},
},
cmd: "ls",
sudo: false,
expected: `sudo -S lxc-attach -n def 2>/dev/null -- /bin/sh -c 'ls'`,
},
// non-root sudo true, lxc
{
conf: config.ServerInfo{
User: "non-root",
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "lxc"},
},
cmd: "ls",
sudo: true,
expected: `sudo -S lxc-attach -n def 2>/dev/null -- /bin/sh -c 'ls'`,
},
// non-root sudo true lxc
{
conf: config.ServerInfo{
User: "non-root",
Container: config.Container{ContainerID: "abc", Name: "def"},
Containers: config.Containers{Type: "lxc"},
},
cmd: "ls | grep hoge",
sudo: true,
expected: `sudo -S lxc-attach -n def 2>/dev/null -- /bin/sh -c 'ls | grep hoge'`,
},
}
for _, tt := range tests {