forked from shuveb/containers-the-hard-way
-
Notifications
You must be signed in to change notification settings - Fork 0
/
exec.go
68 lines (62 loc) · 1.98 KB
/
exec.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main
import (
"golang.org/x/sys/unix"
"log"
"os"
"os/exec"
"strconv"
"strings"
)
func getPidForRunningContainer(containerID string) int {
containers, err := getRunningContainers()
if err != nil {
log.Fatalf("Unable to get running containers: %v\n", err)
}
for _, container := range containers {
if container.containerId == containerID {
return container.pid
}
}
return 0
}
func execInContainer(containerId string) {
pid := getPidForRunningContainer(containerId)
if pid == 0 {
log.Fatalf("No such container!")
}
baseNsPath := "/proc/" + strconv.Itoa(pid) + "/ns"
ipcFd, ipcErr := os.Open(baseNsPath + "/ipc")
mntFd, mntErr := os.Open(baseNsPath + "/mnt")
netFd, netErr := os.Open(baseNsPath + "/net")
pidFd, pidErr := os.Open(baseNsPath + "/pid")
utsFd, utsErr := os.Open(baseNsPath + "/uts")
if ipcErr != nil || mntErr != nil || netErr != nil ||
pidErr != nil || utsErr != nil {
log.Fatalf("Unable to open namespace files!")
}
unix.Setns(int(ipcFd.Fd()), unix.CLONE_NEWIPC)
unix.Setns(int(mntFd.Fd()), unix.CLONE_NEWNS)
unix.Setns(int(netFd.Fd()), unix.CLONE_NEWNET)
unix.Setns(int(pidFd.Fd()), unix.CLONE_NEWPID)
unix.Setns(int(utsFd.Fd()), unix.CLONE_NEWUTS)
containerConfig, err := getRunningContainerInfoForId(containerId)
if err != nil {
log.Fatalf("Unable to get container configuration")
}
imageNameAndTag := strings.Split(containerConfig.image, ":")
exists, imageShaHex := imageExistByTag(imageNameAndTag[0], imageNameAndTag[1])
if !exists {
log.Fatalf("Unable to get image details")
}
imgConfig := parseContainerConfig(imageShaHex)
containerMntPath := getGockerContainersPath() + "/" + containerId + "/fs/mnt"
createCGroups(containerId, false)
doOrDieWithMsg(unix.Chroot(containerMntPath), "Unable to chroot")
os.Chdir("/")
cmd := exec.Command(os.Args[3], os.Args[4:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = imgConfig.Config.Env
doOrDieWithMsg(cmd.Run(), "Unable to exec command in container")
}