func createUser(id containers.Identifier) error { cmd := exec.Command("/usr/sbin/useradd", id.LoginFor(), "-m", "-d", id.HomePath(), "-c", "Container user") if out, err := cmd.CombinedOutput(); err != nil { log.Println(out) return err } selinux.RestoreCon(id.HomePath(), true) return nil }
func InitPreStart(dockerSocket string, id containers.Identifier, imageName string) error { var ( err error imgInfo *dc.Image d *docker.DockerClient ) _, socketActivationType, err := containers.GetSocketActivation(id) if err != nil { fmt.Printf("init_pre_start: Error while parsing unit file: %v\n", err) return err } if _, err = user.Lookup(id.LoginFor()); err != nil { if _, ok := err.(user.UnknownUserError); !ok { return err } if err = createUser(id); err != nil { return err } } if d, err = docker.GetConnection(dockerSocket); err != nil { return err } if imgInfo, err = d.GetImage(imageName); err != nil { return err } if err := os.MkdirAll(id.HomePath(), 0700); err != nil { return err } u, _ := user.Lookup(id.LoginFor()) volumes := make([]string, 0, 10) for volPath := range imgInfo.Config.Volumes { volumes = append(volumes, volPath) } user := imgInfo.Config.User if user == "" { user = "******" } ports, err := containers.GetExistingPorts(id) if err != nil { fmt.Printf("container init pre-start: Unable to retrieve port mapping\n") return err } containerData := containers.ContainerInitScript{ imgInfo.Config.User == "", user, u.Uid, u.Gid, strings.Join(imgInfo.Config.Cmd, " "), len(volumes) > 0, strings.Join(volumes, " "), ports, socketActivationType == "proxied", } file, _, err := utils.OpenFileExclusive(path.Join(id.RunPathFor(), "container-init.sh"), 0700) if err != nil { fmt.Printf("container init pre-start: Unable to open script file: %v\n", err) return err } defer file.Close() if erre := containers.ContainerInitTemplate.Execute(file, containerData); erre != nil { fmt.Printf("container init pre-start: Unable to output template: ", erre) return erre } if err := file.Close(); err != nil { return err } file, _, err = utils.OpenFileExclusive(path.Join(id.RunPathFor(), "container-cmd.sh"), 0705) if err != nil { fmt.Printf("container init pre-start: Unable to open cmd script file: %v\n", err) return err } defer file.Close() if erre := containers.ContainerCmdTemplate.Execute(file, containerData); erre != nil { fmt.Printf("container init pre-start: Unable to output cmd template: ", erre) return erre } if err := file.Close(); err != nil { return err } return nil }
// FIXME: Refactor into separate responsibilities for file creation, templating, and disk access func generateAuthorizedKeys(id containers.Identifier, u *user.User, forceCreate, printToStdOut bool) error { var ( err error sshKeys []string destFile *os.File srcFile *os.File w *bufio.Writer ) var authorizedKeysPortSpec string ports, err := containers.GetExistingPorts(id) if err != nil { fmt.Errorf("container init pre-start: Unable to retrieve port mapping") return err } for _, port := range ports { authorizedKeysPortSpec += fmt.Sprintf("permitopen=\"127.0.0.1:%v\",", port.External) } sshKeys, err = filepath.Glob(path.Join(SshAccessBasePath(id), "*")) if !printToStdOut { os.MkdirAll(id.HomePath(), 0700) os.Mkdir(path.Join(id.HomePath(), ".ssh"), 0700) authKeysPath := id.AuthKeysPathFor() if _, err = os.Stat(authKeysPath); err != nil { if !os.IsNotExist(err) { return err } } else { if forceCreate { os.Remove(authKeysPath) } else { return nil } } if destFile, err = os.Create(authKeysPath); err != nil { return err } defer destFile.Close() w = bufio.NewWriter(destFile) } else { w = bufio.NewWriter(os.Stdout) } for _, keyFile := range sshKeys { s, err := os.Stat(keyFile) if err != nil { continue } if s.IsDir() { continue } srcFile, err = os.Open(keyFile) defer srcFile.Close() w.WriteString(fmt.Sprintf("command=\"/usr/bin/switchns\",%vno-agent-forwarding,no-X11-forwarding ", authorizedKeysPortSpec)) io.Copy(w, srcFile) w.WriteString("\n") } w.Flush() if !printToStdOut { uid, _ := strconv.Atoi(u.Uid) gid, _ := strconv.Atoi(u.Gid) for _, path := range []string{ id.HomePath(), filepath.Join(id.HomePath(), ".ssh"), filepath.Join(id.HomePath(), ".ssh", "authorized_keys"), } { if err := os.Chown(path, uid, gid); err != nil { return err } } if err := selinux.RestoreCon(id.BaseHomePath(), true); err != nil { return err } } return nil }