Initial Commit

master
Hugo Thunnissen 2 years ago
commit 399298133c

1
.gitignore vendored

@ -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,3 @@
module git.snorba.art/hugo/workspace
go 1.18

@ -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…
Cancel
Save