|
|
|
@ -3,6 +3,7 @@ package main
|
|
|
|
|
import (
|
|
|
|
|
"bufio"
|
|
|
|
|
_ "embed"
|
|
|
|
|
"errors"
|
|
|
|
|
"flag"
|
|
|
|
|
"fmt"
|
|
|
|
|
"os"
|
|
|
|
@ -29,6 +30,51 @@ var customLisp string
|
|
|
|
|
//go:embed bash/bash_aliases
|
|
|
|
|
var bashAliases string
|
|
|
|
|
|
|
|
|
|
var ErrAddUserFailExit = errors.New("useradd command returned no-zero exit code")
|
|
|
|
|
var ErrAddGroupFailExit = errors.New("groupadd command returned no-zero exit code")
|
|
|
|
|
|
|
|
|
|
func AddUser(username string, uid string) error {
|
|
|
|
|
cmd := exec.Command(
|
|
|
|
|
"useradd",
|
|
|
|
|
"--no-create-home",
|
|
|
|
|
"--uid", uid,
|
|
|
|
|
"--user-group",
|
|
|
|
|
username,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf(
|
|
|
|
|
"Error adding user: %w. Process error: %w. Process output: %s",
|
|
|
|
|
ErrAddUserFailExit,
|
|
|
|
|
err,
|
|
|
|
|
output,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func AddGroup(name string, gid string) error {
|
|
|
|
|
cmd := exec.Command(
|
|
|
|
|
"groupadd",
|
|
|
|
|
"--gid", gid,
|
|
|
|
|
name,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf(
|
|
|
|
|
"Error adding group: %w. Process error: %w. Process output: %s",
|
|
|
|
|
ErrAddGroupFailExit,
|
|
|
|
|
err,
|
|
|
|
|
output,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func EntryPoint(command []string) error {
|
|
|
|
|
if len(command) == 0 {
|
|
|
|
|
command = []string{"/bin/bash", "-i"}
|
|
|
|
@ -44,7 +90,8 @@ func EntryPoint(command []string) error {
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dockerGid, err := strconv.Atoi(os.Getenv("WORKSPACE_DOCKER_GID"))
|
|
|
|
|
dockerGidString := os.Getenv("WORKSPACE_DOCKER_GID")
|
|
|
|
|
dockerGid, err := strconv.Atoi(dockerGidString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf(
|
|
|
|
|
"Failed to parse GID from WORKSPACE_DOCKER_GID env var with contents \"%s\". Error: %w",
|
|
|
|
@ -53,17 +100,27 @@ func EntryPoint(command []string) error {
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = AddUser(os.Getenv("WORKSPACE_USERNAME"), uidString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = AddGroup("docker", dockerGidString)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = syscall.Setgroups([]int{dockerGid})
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = syscall.Setgid(uid)
|
|
|
|
|
err = syscall.Setgid(int(uid))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = syscall.Setuid(uid)
|
|
|
|
|
err = syscall.Setuid(int(uid))
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
@ -78,7 +135,7 @@ func EntryPoint(command []string) error {
|
|
|
|
|
return syscall.Exec(path, command, os.Environ())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Run(detach bool, command []string) error {
|
|
|
|
|
func Run(detach bool, mounts []string, command []string) error {
|
|
|
|
|
workDir, err := os.Getwd()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
@ -100,18 +157,13 @@ func Run(detach bool, command []string) error {
|
|
|
|
|
"--workdir=" + workDir,
|
|
|
|
|
"-e", "DISPLAY=" + os.Getenv("DISPLAY"),
|
|
|
|
|
"-e", "WORKSPACE_USER=" + curUser.Uid,
|
|
|
|
|
"-e", "WORKSPACE_USERNAME=" + curUser.Name,
|
|
|
|
|
"-e", "WORKSPACE_USERNAME=" + curUser.Username,
|
|
|
|
|
"-e", "WORKSPACE_DOCKER_GID=" + dockerGroup.Gid,
|
|
|
|
|
"-e", "HOME=" + home,
|
|
|
|
|
"-h", os.Getenv("HOSTNAME"),
|
|
|
|
|
"-v", "/var/run/docker.sock:/var/run/docker.sock",
|
|
|
|
|
"-v", "/etc/subuid:/etc/subuid:ro",
|
|
|
|
|
"-v", "/etc/subgid:/etc/subgid:ro",
|
|
|
|
|
"-v", "/etc/hosts:/etc/hosts:ro",
|
|
|
|
|
"-v", "/etc/passwd:/etc/passwd:ro",
|
|
|
|
|
"-v", "/etc/resolv.conf:/etc/resolv.conf:ro",
|
|
|
|
|
"-v", "/etc/sudoers:/etc/sudoers:ro",
|
|
|
|
|
"-v", "/etc/group:/etc/group:ro",
|
|
|
|
|
"-v", home + ":" + home,
|
|
|
|
|
"-e", "SSH_AGENT_LAUNCHER=" + os.Getenv("SSH_AGENT_LAUNCHER"),
|
|
|
|
|
"-e", "SSH_AUTH_SOCK=" + os.Getenv("SSH_AUTH_SOCK"),
|
|
|
|
@ -131,6 +183,10 @@ func Run(detach bool, command []string) error {
|
|
|
|
|
dockerCommand = append(dockerCommand, "-ti")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, mount := range mounts {
|
|
|
|
|
dockerCommand = append(dockerCommand, "-v", mount+":"+mount)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileInfo, err := os.Lstat(home)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return fmt.Errorf(
|
|
|
|
@ -216,6 +272,9 @@ func main() {
|
|
|
|
|
"Whether or not to detach from the container after running the command",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var mounts arrayFlag
|
|
|
|
|
run.Var(&mounts, "mount", "Directory to mount inside the workspace container")
|
|
|
|
|
|
|
|
|
|
switch cmd {
|
|
|
|
|
case "entrypoint":
|
|
|
|
|
err := EntryPoint(os.Args[2:])
|
|
|
|
@ -231,7 +290,7 @@ func main() {
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = Run(detach, run.Args())
|
|
|
|
|
err = Run(detach, mounts, run.Args())
|
|
|
|
|
if err != nil {
|
|
|
|
|
fmt.Println("error running command in container", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|