Initial Commit
commit
399298133c
@ -0,0 +1 @@
|
||||
/workspace
|
@ -0,0 +1,103 @@
|
||||
FROM ubuntu:21.10
|
||||
|
||||
RUN apt-get -y update && apt-get -y install locales
|
||||
|
||||
RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
|
||||
locale-gen
|
||||
|
||||
ENV LANG=C.UTF-8
|
||||
ENV LANGUAGE=en_AU:en
|
||||
ENV LC_CTYPE="C.UTF-8"
|
||||
ENV LC_NUMERIC=en_US.UTF-8
|
||||
ENV LC_TIME=en_US.UTF-8
|
||||
ENV LC_COLLATE="C.UTF-8"
|
||||
ENV LC_MONETARY=en_US.UTF-8
|
||||
ENV LC_MESSAGES="C.UTF-8"
|
||||
ENV LC_PAPER=en_US.UTF-8
|
||||
ENV LC_NAME=en_US.UTF-8
|
||||
ENV LC_ADDRESS=en_US.UTF-8
|
||||
ENV LC_TELEPHONE=en_US.UTF-8
|
||||
ENV LC_MEASUREMENT=en_US.UTF-8
|
||||
ENV LC_IDENTIFICATION=en_US.UTF-8
|
||||
ENV TZ=Europe/Amsterdam
|
||||
|
||||
|
||||
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
||||
man-db jq curl git pwgen build-essential libjansson-dev \
|
||||
libtiff-dev libgif-dev ffmpeg libffi-dev xutils-dev \
|
||||
libxpm-dev libpng-dev zlib1g-dev libgmp-dev autoconf pkg-config \
|
||||
p11-kit libp11-kit-dev nettle-dev libgnutls28-dev libtool \
|
||||
libncurses-dev bash cmake htop net-tools dnsutils libgtk-3-dev wget \
|
||||
libmagickwand-dev imagemagick libacl1-dev libxml2-dev
|
||||
|
||||
|
||||
RUN wget https://ftp.gnu.org/gnu/emacs/emacs-27.2.tar.gz \
|
||||
-O /tmp/emacs.tar.gz
|
||||
|
||||
WORKDIR /tmp/emacs
|
||||
|
||||
RUN tar --strip-components=1 -xf /tmp/emacs.tar.gz
|
||||
|
||||
|
||||
RUN ./configure
|
||||
|
||||
RUN sed -i 's!static unsigned char sigsegv_stack\[SIGSTKSZ\]!static max_align_t sigsegv_stack\[(64 * 1024 + sizeof (max_align_t) - 1) / sizeof (max_align_t)\]!g' ./src/sysdep.c
|
||||
|
||||
RUN make install
|
||||
|
||||
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
||||
libreadline8 bash-completion sudo
|
||||
|
||||
RUN apt-get update && apt-get -y install \
|
||||
php8.0-memcached \
|
||||
php-redis \
|
||||
php8.0-bcmath \
|
||||
php8.0-bz2 \
|
||||
php8.0-cli \
|
||||
php8.0-common \
|
||||
php8.0-curl \
|
||||
php8.0-gmp \
|
||||
php8.0-intl \
|
||||
php-json \
|
||||
php8.0-mbstring \
|
||||
php8.0-mysql \
|
||||
php8.0-odbc \
|
||||
php8.0-opcache \
|
||||
php8.0-pgsql \
|
||||
php8.0-readline \
|
||||
php8.0-tidy \
|
||||
php8.0-xml \
|
||||
php8.0-xsl \
|
||||
php8.0-zip \
|
||||
php8.0-gd \
|
||||
php-bcmath \
|
||||
php-apcu \
|
||||
php-cli \
|
||||
php-imagick \
|
||||
composer
|
||||
|
||||
RUN curl --location "https://golang.org/dl/go1.18.linux-amd64.tar.gz" | tar -xzf - -C /usr/local/
|
||||
RUN ln -s /usr/local/go/bin/* /usr/local/bin/
|
||||
|
||||
run mkdir -p /opt/nodejs
|
||||
RUN curl --location "https://nodejs.org/dist/v17.8.0/node-v17.8.0-linux-x64.tar.xz" | tar -Jxf - --strip-components=1 -C /opt/nodejs/
|
||||
RUN ln -s /opt/nodejs/bin/* /usr/local/bin/
|
||||
|
||||
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install \
|
||||
ca-certificates curl gnupg lsb-release
|
||||
|
||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||
&& echo \
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||||
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install docker-ce-cli
|
||||
|
||||
ADD . /opt/workspace-repo
|
||||
WORKDIR /opt/workspace-repo
|
||||
RUN go build .
|
||||
RUN cp ./workspace /bin/workspace
|
||||
|
||||
ENTRYPOINT [ "/bin/workspace", "entrypoint" ]
|
||||
|
||||
#"source ~/dotfiles/environment; dots pkg exec \"$@\"", "--"]
|
@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare -a run_options=()
|
||||
|
||||
if tty >/dev/null; then
|
||||
run_options=("-ti")
|
||||
fi
|
||||
|
||||
if [[ "$DOTFILE_WORKSPACE_DETACH" == 'true' ]]; then
|
||||
run_options=("${run_options[@]}" '--detach')
|
||||
unset DOTFILE_WORKSPACE_DETACH
|
||||
fi
|
||||
|
||||
exec docker run "${run_options[@]}" \
|
||||
--network=host \
|
||||
--workdir="$(pwd)" \
|
||||
-e DISPLAY=$DISPLAY \
|
||||
-e WORKSPACE_USER=$(id -u) \
|
||||
-h $HOSTNAME \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-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="$SSH_AGENT_LAUNCHER" \
|
||||
-e SSH_AUTH_SOCK="$SSH_AUTH_SOCK" \
|
||||
-e PULSE_SERVER=unix:/run/user/1000/pulse/native \
|
||||
-e DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
|
||||
-v /tmp/.X11-unix:/tmp/.X11-unix \
|
||||
-v /run/user/"$(id -u)":/run/user/"$(id -u)" \
|
||||
-v /dev/snd \
|
||||
--user=$(id -u) hugotty/workspace:latest "$@"
|
@ -0,0 +1,185 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
const usage = `workspace - Use a containerized workspace
|
||||
|
||||
COMMANDS
|
||||
`
|
||||
|
||||
func EntryPoint(command []string) error {
|
||||
if len(command) == 0 {
|
||||
command = []string{"/bin/bash", "-i"}
|
||||
}
|
||||
|
||||
uid, err := strconv.ParseInt(os.Getenv("WORKSPACE_USER"), 10, 64)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Failed to parse UID from WORKSPACE_USER env var with contents \"%s\". Error: %w",
|
||||
os.Getenv("WORKSPACE_USER"),
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
err = syscall.Setuid(int(uid))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path, err := exec.LookPath(command[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
SetEnvVars()
|
||||
|
||||
return syscall.Exec(path, command, os.Environ())
|
||||
}
|
||||
|
||||
func Run(detach bool, command []string) error {
|
||||
workDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uid := strconv.Itoa(syscall.Getuid())
|
||||
home := os.Getenv("HOME")
|
||||
|
||||
dockerCommand := []string{
|
||||
"/bin/docker", "run", "--network=host",
|
||||
"--workdir=" + workDir,
|
||||
"--user=0:" + strconv.Itoa(syscall.Getgid()),
|
||||
"-e", "DISPLAY=" + os.Getenv("DISPLAY"),
|
||||
"-e", "WORKSPACE_USER=" + uid,
|
||||
"-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"),
|
||||
"-e", "PULSE_SERVER=unix:/run/user/" + uid + "/pulse/native",
|
||||
"-e", "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/" + uid + "/bus",
|
||||
"-e", "TERM=" + os.Getenv("TERM"),
|
||||
"-v", "/tmp/.X11-unix:/tmp/.X11-unix",
|
||||
"-v", "/run/user/" + uid + ":/run/user/" + uid,
|
||||
"-v", "/dev/snd",
|
||||
}
|
||||
|
||||
if detach {
|
||||
dockerCommand = append(dockerCommand, "--detach")
|
||||
}
|
||||
|
||||
if fileInfo, _ := os.Stdout.Stat(); (fileInfo.Mode() & os.ModeCharDevice) != 0 {
|
||||
dockerCommand = append(dockerCommand, "-ti")
|
||||
}
|
||||
|
||||
fileInfo, err := os.Lstat(home)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Failed to determine whether home directory is a symbolic link: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
if fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
destination, err := os.Readlink(home)
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Failed to determine whether home directory is a symbolic link: %w",
|
||||
err,
|
||||
)
|
||||
}
|
||||
|
||||
dockerCommand = append(dockerCommand, "-v", destination+":"+destination)
|
||||
}
|
||||
|
||||
dockerCommand = append(dockerCommand, "hugotty/workspace:latest")
|
||||
dockerCommand = append(dockerCommand, command...)
|
||||
|
||||
return syscall.Exec(dockerCommand[0], dockerCommand, os.Environ())
|
||||
}
|
||||
|
||||
func SetEnvVars() {
|
||||
home := os.Getenv("HOME")
|
||||
os.Setenv("PATH", home+"/bin:"+os.Getenv("PATH"))
|
||||
os.Setenv("PATH", home+"/dotfiles/bin:"+os.Getenv("PATH"))
|
||||
|
||||
// PHP
|
||||
os.Setenv("PATH", home+"/.config/composer/vendor/bin:"+os.Getenv("PATH"))
|
||||
|
||||
// Node
|
||||
os.Setenv("PATH", home+"/.npm_packages/bin:"+os.Getenv("PATH"))
|
||||
|
||||
// Perl
|
||||
os.Setenv("PATH", home+"/perl5/perlbrew/bin:"+os.Getenv("PATH"))
|
||||
|
||||
// Rust
|
||||
os.Setenv("PATH", home+"/.cargo/bin:"+os.Getenv("PATH"))
|
||||
|
||||
// Locally installed python packages
|
||||
os.Setenv("PATH", home+"/.local/bin:"+os.Getenv("PATH"))
|
||||
|
||||
// Home for virtualenvs
|
||||
os.Setenv("WORKON_HOME", home+"/.local/share/virtualenvs")
|
||||
|
||||
// GO Stuff
|
||||
os.Setenv("GOPATH", home+"/go")
|
||||
os.Setenv("PATH", home+"/go/bin:"+os.Getenv("PATH"))
|
||||
os.Setenv("GOPRIVATE", "git.snorba.art")
|
||||
}
|
||||
|
||||
func main() {
|
||||
var cmd string
|
||||
if len(os.Args) > 1 {
|
||||
cmd = os.Args[1]
|
||||
}
|
||||
|
||||
var detach bool
|
||||
run := flag.NewFlagSet("run", flag.ExitOnError)
|
||||
run.BoolVar(
|
||||
&detach,
|
||||
"detach",
|
||||
false,
|
||||
"Whether or not to detach from the container afnter running the command",
|
||||
)
|
||||
|
||||
switch cmd {
|
||||
case "entrypoint":
|
||||
err := EntryPoint(os.Args[2:])
|
||||
if err != nil {
|
||||
fmt.Println("error executing entrypoint command", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
case "run":
|
||||
err := run.Parse(os.Args[2:])
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
err = Run(detach, run.Args())
|
||||
if err != nil {
|
||||
fmt.Println("error running command in container", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
default:
|
||||
fmt.Println(usage)
|
||||
fmt.Println("run COMMAND: Start workspace container and run COMMAND within it")
|
||||
run.Usage()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue