diff --git a/cling/Dockerfile b/cling/Dockerfile
new file mode 100644
index 0000000..8214c4e
--- /dev/null
+++ b/cling/Dockerfile
@@ -0,0 +1,3 @@
+FROM xena/base
+
+ADD https://ecsft.cern.ch/dist/cling/current/cling-Ubuntu-14.04-64bit-2dc1fdc217.tar.bz2 /opt/cling
diff --git a/dev-vm/Dockerfile b/dev-vm/Dockerfile
new file mode 100644
index 0000000..2e821ee
--- /dev/null
+++ b/dev-vm/Dockerfile
@@ -0,0 +1,50 @@
+FROM flitter/init:latest
+
+USER root
+
+# Package installs
+RUN apt-get update && \
+ apt-get upgrade -qy && \
+ apt-get install -qy zsh git python wget build-essential libssl-dev vim tmux dtach dvtm cmake python-dev golang mercurial bzr
+
+RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Make user account
+RUN useradd --create-home xena && \
+ echo 'root:screencast' | chpasswd && \
+ echo 'xena:user' | chpasswd
+
+ENV HOME /home/xena
+ENV DOCKER YES
+ENV LANGUAGE en_US
+ENV LC_ALL en_US.UTF-8
+ENV LANG en_us.utf-8
+ENV LC_CTYPE en_US.UTF-8
+ENV GOPATH /home/xena/go
+ENV PATH /usr/local/go/bin:$PATH
+
+# To use Docker please pass the docker socket as a bind mount
+RUN wget https://get.docker.com/builds/Linux/x86_64/docker-latest -O /usr/local/bin/docker && \
+ chmod 555 /usr/local/bin/docker
+
+USER xena
+
+WORKDIR /home/xena
+
+# Dotfiles
+RUN mkdir code
+RUN git clone https://github.com/Xe/dotfiles code/dotfiles
+
+ADD setup.sh /home/xena/
+RUN bash setup.sh
+
+RUN vim +GoInstallBinaries +qall
+
+USER root
+
+RUN chsh xena -s /bin/zsh
+
+EXPOSE 22
+
+CMD ["/sbin/my_init", "setuser", "xena", "/bin/zsh"]
+
diff --git a/dev-vm/setup.sh b/dev-vm/setup.sh
new file mode 100755
index 0000000..17a8b84
--- /dev/null
+++ b/dev-vm/setup.sh
@@ -0,0 +1,44 @@
+#!/bin/bash -x
+
+# Install oh my zsh
+wget --no-check-certificate https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | bash
+
+function setlink
+{
+ ln -s $HOME/code/dotfiles/$1 $HOME/$1
+}
+
+rm ~/.zshrc
+
+#set links
+setlink .profile
+setlink .zshrc
+setlink .zsh
+setlink .vim
+setlink .vimrc
+setlink .cheat
+setlink .gitconfig
+setlink .tmux.conf
+
+# Setup vundle
+git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
+
+head -n 40 ~/.vimrc >> ~/.vimrc-temp
+
+vim -u ~/.vimrc-temp +PluginInstall +qall
+
+rm ~/.vimrc-temp
+
+(cd ~/.vim/bundle/YouCompleteMe; ./install.sh --clang-completer)
+(cd ~/.vim/bundle/vimproc.vim; make)
+
+vim +GoInstallBinaries
+
+# Golang stuff
+(mkdir -p ~/go/{pkg,bin,src})
+
+go get github.com/mattn/todo
+
+echo "Set up!"
+
+rm $0
diff --git a/firefox/Dockerfile b/firefox/Dockerfile
new file mode 100644
index 0000000..4a5eb89
--- /dev/null
+++ b/firefox/Dockerfile
@@ -0,0 +1,16 @@
+FROM ubuntu:14.04
+
+RUN apt-get update && apt-get install -y firefox
+
+# Replace 1000 with your user / group id
+RUN export uid=1000 gid=1000 && \
+ mkdir -p /home/developer && \
+ echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd && \
+ echo "developer:x:${uid}:" >> /etc/group && \
+ echo "developer ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/developer && \
+ chmod 0440 /etc/sudoers.d/developer && \
+ chown ${uid}:${gid} -R /home/developer
+
+USER developer
+ENV HOME /home/developer
+CMD /usr/bin/firefox
diff --git a/firefox/run.sh b/firefox/run.sh
new file mode 100755
index 0000000..9e5dba0
--- /dev/null
+++ b/firefox/run.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+docker run -ti --rm -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix -v /home/xena/Downloads:/home/developer/Downloads -v /home/xena/.mozilla:/home/developer/.mozilla xena/firefox
diff --git a/fleetbuilder/Dockerfile b/fleetbuilder/Dockerfile
new file mode 100644
index 0000000..4de2226
--- /dev/null
+++ b/fleetbuilder/Dockerfile
@@ -0,0 +1,6 @@
+FROM deis/go
+
+RUN mkdir /tmp/build && \
+ mkdir -p /go/src/github.com/coreos && cd /go/src/github.com/coreos && \
+ git clone http://github.com/coreos/fleet && cd fleet && \
+ ./build && cp bin/* /tmp/build
diff --git a/fleetbuilder/build/.gitkeep b/fleetbuilder/build/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/haskell/Dockerfile b/haskell/Dockerfile
new file mode 100644
index 0000000..80319f1
--- /dev/null
+++ b/haskell/Dockerfile
@@ -0,0 +1,3 @@
+FROM xena/base
+
+RUN apt-get update && apt-get install haskell-platform -y
diff --git a/hexchat/Dockerfile b/hexchat/Dockerfile
new file mode 100644
index 0000000..117b747
--- /dev/null
+++ b/hexchat/Dockerfile
@@ -0,0 +1,16 @@
+FROM ubuntu:14.04
+
+RUN apt-get update && apt-get install -y hexchat ca-certificates
+
+# Replace 1000 with your user / group id
+RUN export uid=1000 gid=1000 && \
+ mkdir -p /home/xena && \
+ echo "xena:x:${uid}:${gid}:Developer,,,:/home/xena:/bin/bash" >> /etc/passwd && \
+ echo "xena:x:${uid}:" >> /etc/group && \
+ echo "xena ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/xena && \
+ chmod 0440 /etc/sudoers.d/xena && \
+ chown ${uid}:${gid} -R /home/xena
+
+USER xena
+ENV HOME /home/xena
+CMD /usr/bin/hexchat
diff --git a/hexchat/run.sh b/hexchat/run.sh
new file mode 100755
index 0000000..fe6dbc1
--- /dev/null
+++ b/hexchat/run.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+docker run -dit -v /home/xena --name hexchat-data xena/hexchat /bin/bash
+docker run -ti -d --name hexchat -e DISPLAY=$DISPLAY --volumes-from hexchat-data -v /tmp/.X11-unix:/tmp/.X11-unix xena/hexchat
diff --git a/hosted-znc/Dockerfile b/hosted-znc/Dockerfile
new file mode 100644
index 0000000..16b3403
--- /dev/null
+++ b/hosted-znc/Dockerfile
@@ -0,0 +1,32 @@
+FROM ubuntu:14.04
+
+RUN apt-get update # ba393330-1508-11e4-8c21-0800200c9a66
+RUN apt-get -qqy upgrade # c4da4cc0-1508-11e4-8c21-0800200c9a66
+RUN apt-get build-dep -qqy znc-python # 3e582310-1509-11e4-8c21-0800200c9a66
+RUN apt-get install -qqy wget # 0501f510-150d-11e4-8c21-0800200c9a66
+RUN apt-get install -qqy libssl-dev # 4b7d79b0-150d-11e4-8c21-0800200c9a66
+RUN apt-get install -qqy git automake autoconf # 3bc47ee0-1514-11e4-8c21-0800200c9a66
+
+RUN adduser znc --disabled-password
+
+RUN cd /home/znc; mkdir src; cd src; git clone https://github.com/znc/znc; cd znc; bash ./autogen.sh ; bash ./configure --enable-openssl --prefix=/home/znc/znc --enable-python; make; make install # 79751510-150a-11e4-8c21-0800200c9a66
+
+ADD znc.conf /home/znc/.znc/configs/znc.conf
+
+ADD athemesasl.py /home/znc/znc/lib/znc/
+ADD athemeauth.py /home/znc/znc/lib/znc/
+
+RUN chmod -R 777 /home/znc
+
+USER znc
+
+EXPOSE 6667
+EXPOSE 6697
+EXPOSE 8080
+
+ENV HOME /home/znc
+
+RUN /home/znc/znc/bin/znc -p
+
+CMD /home/znc/znc/bin/znc -f
+
diff --git a/hosted-znc/athemeauth.py b/hosted-znc/athemeauth.py
new file mode 100644
index 0000000..aef947c
--- /dev/null
+++ b/hosted-znc/athemeauth.py
@@ -0,0 +1,103 @@
+from xmlrpc.client import ServerProxy, Fault
+
+import znc
+
+class Atheme:
+ def __init__(self, url):
+ self.url = url
+ self.proxy = ServerProxy(url)
+ self.cookie = "*"
+ self.username = "*"
+ self._privset = None
+
+ def login(self, username, password):
+ self.username = username
+ self.cookie = self.proxy.atheme.login(username, password)
+ self.privs()
+
+ def privs(self):
+ if self._privset is not None:
+ return self._privset
+
+ self._privset = self.proxy.atheme.privset(self.cookie, self.username).split()
+ return self._privset
+
+class athemeauth(znc.Module):
+ module_types = [znc.CModInfo.GlobalModule]
+
+ def __init__(self):
+ pass
+
+ def OnLoginAttempt(self, auth):
+ username = auth.GetUsername()
+ password = auth.GetPassword()
+
+ atheme = Atheme("http://173.10.70.249:8069/xmlrpc")
+ user = znc.CZNC.Get().FindUser(username)
+
+ if user != None:
+ if user.GetPass() != "::":
+ #Allow normal ZNC accounts to log in
+ return znc.CONTINUE
+
+ try:
+ atheme.login(username, password)
+
+ except Fault:
+ return znc.CONTINUE
+
+ if user == None:
+ myuser = znc.CUser(username)
+
+ auth.GetSocket().Write(":bnc.yolo-swag.com NOTICE * :*** Creating account for %s...\r\n" % username)
+ auth.GetSocket().Write(":bnc.yolo-swag.com NOTICE * :*** Thank you for supporting ShadowNET!\r\n")
+
+ baseuser = znc.CZNC.Get().FindUser("scrub")
+ baseuser.thisown = 0
+
+ s = znc.String()
+ s.thisown = 0
+
+ if not myuser.Clone(baseuser, s, False):
+ print("WTF?", s)
+ return znc.CONTINUE
+
+ if not znc.CZNC.Get().AddUser(myuser, s):
+ print("WTF?", s)
+ return znc.CONTINUE
+ user = myuser
+
+ user.SetPass("::", znc.CUser.HASH_MD5, "::")
+
+ #this is a new user, set up stuff
+ user.SetNick(username)
+ user.SetAltNick(username + "`")
+ user.SetIdent(username[:8])
+ user.SetRealName("ShadowNET hosted bnc user %s" % username)
+ user.SetDenySetBindHost(True)
+ user.SetQuitMsg("Shutting down!")
+ user.SetMaxNetworks(1)
+ user.SetAdmin(False)
+
+ #They are going to want a network to talk on.
+ user.AddNetwork("ShadowNET", s)
+ network = user.FindNetwork("ShadowNET")
+ network.AddServer("cyka.yolo-swag.com +6697")
+ network.AddChan("#lobby", True)
+ network.AddChan("#bnc", True)
+ network.JoinChans()
+
+ fout = open("/tmp/znc-cookie-%s" % username, "w")
+ fout.write(atheme.cookie)
+ fout.close()
+
+ znc.CZNC.Get().WriteConfig()
+
+ auth.GetSocket().Write(":bnc.yolo-swag.com NOTICE * :*** Welcome to the ShadowNET BNC %s!\r\n" % username)
+ auth.GetSocket().Write(":bnc.yolo-swag.com NOTICE * :*** Your IP address is %s and may be checked for proxies.\r\n" % auth.GetRemoteIP())
+
+ auth.AcceptLogin(user)
+ user.thisown = 0
+
+ return znc.HALT
+
diff --git a/hosted-znc/athemesasl.py b/hosted-znc/athemesasl.py
new file mode 100644
index 0000000..43b78b4
--- /dev/null
+++ b/hosted-znc/athemesasl.py
@@ -0,0 +1,31 @@
+import base64
+import znc
+
+class athemesasl(znc.Module):
+ module_types = [znc.CModInfo.UserModule]
+
+ def __init__(self):
+ self.description = "Atheme SASL"
+
+ def OnServerCapAvailable(self, scap):
+ self.cookie = self.getCookie()
+ self.username = self.GetUser().GetUserName()
+ return scap == "sasl"
+
+ def OnServerCapResult(self, scap, success):
+ if scap == "sasl":
+ if success:
+ self.PutIRC("AUTHENTICATE AUTHCOOKIE")
+ self.PutIRC("AUTHENTICATE " +
+ self.makeSaslAuthString(self.username, self.cookie))
+ self.PutUser(":bnc.yolo-swag.com NOTICE * :*** Authenticated over Atheme XMLRPC")
+
+ def makeSaslAuthString(self, username, cookie):
+ return (base64.b64encode(bytes("%s\0%s\0%s" %
+ (username, username, cookie), "utf-8"))).decode("utf-8")
+
+ def getCookie(self):
+ with open("/tmp/znc-cookie-%s" %
+ self.GetUser().GetUserName(), "r") as fin:
+ return fin.readline()
+
diff --git a/hosted-znc/znc.conf b/hosted-znc/znc.conf
new file mode 100644
index 0000000..a55a2db
--- /dev/null
+++ b/hosted-znc/znc.conf
@@ -0,0 +1,116 @@
+// WARNING
+//
+// Do NOT edit this file while ZNC is running!
+// Use webadmin or *controlpanel instead.
+//
+// Altering this file by hand will forfeit all support.
+//
+// But if you feel risky, you might want to read help on /znc saveconfig and /znc rehash.
+// Also check http://en.znc.in/wiki/Configuration
+
+AnonIPLimit = 10
+ConnectDelay = 5
+LoadModule = modpython
+LoadModule = webadmin
+LoadModule = athemeauth
+MaxBufferSize = 500
+ProtectWebSessions = true
+ServerThrottle = 5
+Skin = _default_
+StatusPrefix = *
+Version = 1.4
+
+
+AllowIRC = true
+AllowWeb = true
+IPv4 = true
+IPv6 = true
+Port = 6697
+SSL = true
+
+
+
+AllowIRC = true
+AllowWeb = true
+IPv4 = true
+IPv6 = true
+Port = 6667
+SSL = false
+
+
+
+AllowIRC = false
+AllowWeb = true
+IPv4 = true
+IPv6 = true
+Port = 8080
+SSL = false
+
+
+
+Admin = true
+AltNick = admin_
+AppendTimestamp = false
+AutoClearChanBuffer = true
+Buffer = 50
+ChanModes = +stn
+DenyLoadMod = false
+DenySetBindHost = false
+Ident = admin
+JoinTries = 10
+LoadModule = webadmin
+LoadModule = controlpanel
+MaxJoins = 0
+MaxNetworks = 1
+MultiClients = true
+Nick = admin
+PrependTimestamp = true
+QuitMsg = ZNC - http://znc.in
+RealName = Got ZNC?
+TimestampFormat = [%H:%M:%S]
+
+
+AltNick = admin2
+FloodBurst = 4
+FloodRate = 1.00
+IRCConnectEnabled = true
+Nick = admin
+RealName = ZNC Admin
+Server = cyka.yolo-swag.com +6697
+
+
+Method = sha256
+Hash = e05a4fe1776a4ef8051d627d3bd24520dde448be810506a839502d28c795931d
+Salt = ZpDUio3z5aDSk5uw5KUN
+
+
+
+
+
+Admin = false
+Allow = *
+AltNick = scrub
+AppendTimestamp = false
+AutoClearChanBuffer = true
+Buffer = 50
+DenyLoadMod = true
+DenySetBindHost = false
+Ident = scrub
+JoinTries = 0
+LoadModule = athemesasl
+LoadModule = missingmotd
+MaxJoins = 0
+MaxNetworks = 0
+MultiClients = true
+Nick = scrub
+PrependTimestamp = false
+QuitMsg = ZNC - http://znc.in
+RealName = scrub
+TimestampFormat = [%H:%M:%S]
+
+
+Hash = 1e129e4686588e8cf26006b95cb9cb3c16b38a569c82cfc2cc34d40fb7459392
+Method = SHA256
+Salt = 8xXjCYN5;)3;l1?jiu25
+
+
diff --git a/influxdb/Dockerfile b/influxdb/Dockerfile
new file mode 100644
index 0000000..d93a83b
--- /dev/null
+++ b/influxdb/Dockerfile
@@ -0,0 +1,13 @@
+FROM ubuntu:14.04
+
+RUN apt-get update
+RUN apt-get install busybox
+
+RUN busybox wget http://s3.amazonaws.com/influxdb/influxdb_latest_amd64.deb
+RUN sudo dpkg -i influxdb_latest_amd64.deb
+RUN rm influxdb_latest_amd64.deb
+
+EXPOSE 8086
+EXPOSE 8083
+
+CMD /usr/bin/influxdb -config /opt/influxdb/shared/config.toml
diff --git a/ircd-devel/Dockerfile b/ircd-devel/Dockerfile
new file mode 100644
index 0000000..8901909
--- /dev/null
+++ b/ircd-devel/Dockerfile
@@ -0,0 +1,9 @@
+FROM ubuntu:14.04
+
+RUN apt-get install build-essential
+RUN apt-get install git
+RUN apt-get install bison flex
+RUN apt-get install checkinstall
+
+CMD ["/bin/bash"]
+
diff --git a/lapis/Dockerfile b/lapis/Dockerfile
new file mode 100644
index 0000000..71b860b
--- /dev/null
+++ b/lapis/Dockerfile
@@ -0,0 +1,35 @@
+FROM flitter/init
+MAINTAINER Xena
+
+RUN apt-get update && \
+ apt-get -y install libreadline-dev libncurses5-dev libpcre3-dev libssl-dev perl make curl git-core
+
+# build/install OpenResty
+ENV SRC_DIR /opt
+ENV OPENRESTY_VERSION 1.7.7.1
+ENV OPENRESTY_PREFIX /app/openresty
+ENV LAPIS_VERSION 1.0.6
+
+RUN cd $SRC_DIR && curl -LO http://openresty.org/download/ngx_openresty-$OPENRESTY_VERSION.tar.gz \
+ && tar xzf ngx_openresty-$OPENRESTY_VERSION.tar.gz && cd ngx_openresty-$OPENRESTY_VERSION \
+ && ./configure --prefix=$OPENRESTY_PREFIX \
+ --with-luajit \
+ --with-http_realip_module \
+ && make && make install && rm -rf ngx_openresty-$OPENRESTY_VERSION*
+
+RUN apt-get -qqy install luarocks
+
+RUN luarocks install moonrocks && \
+ moonrocks install --server=http://rocks.moonscript.org/manifests/leafo lapis $LAPIS_VERSION && \
+ moonrocks install moonscript && \
+ moonrocks install lapis-console && \
+ moonrocks install yaml
+
+ADD prepare.moon /app/prepare.moon
+ADD lapis /etc/service/lapis/run
+ENTRYPOINT /sbin/my_init
+
+ONBUILD ADD app.yaml /app/
+ONBUILD RUN moon /app/prepare.moon /app/app.yaml
+ONBUILD ADD . /app/src
+ONBUILD RUN moonc /app/src
diff --git a/lapis/lapis b/lapis/lapis
new file mode 100755
index 0000000..8f0da67
--- /dev/null
+++ b/lapis/lapis
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+cd /app/src
+
+export LAPIS_OPENRESTY=/app/openresty/nginx/sbin/nginx
+
+lapis server docker
diff --git a/lapis/prepare.moon b/lapis/prepare.moon
new file mode 100644
index 0000000..a845d74
--- /dev/null
+++ b/lapis/prepare.moon
@@ -0,0 +1,24 @@
+yaml = require "yaml"
+
+manifest_path = ...
+
+error "Missing manifest_path" if not manifest_path
+
+strip = (str) -> str\match "^%s*(.-)%s*$"
+
+read_cmd = (cmd) ->
+ f = io.popen cmd, "r"
+ with strip f\read"*a"
+ f\close!
+
+fin = io.open manifest_path, "r"
+app = yaml.load fin\read "*a"
+fin\close!
+
+print "installing dependencies for #{app.name}..."
+
+for _, dep in pairs app.dependencies
+ print "installing dependency #{dep}"
+ read_cmd "moonrocks install #{dep}"
+
+print "done!"
diff --git a/lua/Dockerfile b/lua/Dockerfile
new file mode 100644
index 0000000..63ee25e
--- /dev/null
+++ b/lua/Dockerfile
@@ -0,0 +1,3 @@
+FROM xena/alpine
+
+RUN apk update && apk upgrade && apk add lua
diff --git a/minecraft/backup/Dockerfile b/minecraft/backup/Dockerfile
new file mode 100644
index 0000000..205660e
--- /dev/null
+++ b/minecraft/backup/Dockerfile
@@ -0,0 +1,6 @@
+FROM xena/alpine:edge
+
+ADD start.sh /
+
+CMD /start.sh
+
diff --git a/minecraft/backup/start.sh b/minecraft/backup/start.sh
new file mode 100755
index 0000000..7eb69da
--- /dev/null
+++ b/minecraft/backup/start.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+tar czf "/mnt/host/backup".tgz /minecraft/server/*
+
diff --git a/minecraft/data-ambassador/Dockerfile b/minecraft/data-ambassador/Dockerfile
new file mode 100644
index 0000000..71274ff
--- /dev/null
+++ b/minecraft/data-ambassador/Dockerfile
@@ -0,0 +1,6 @@
+FROM xena/alpine:3.0
+
+ADD setup.sh /setup.sh
+
+CMD /setup.sh
+
diff --git a/minecraft/data-ambassador/setup.sh b/minecraft/data-ambassador/setup.sh
new file mode 100755
index 0000000..67379b1
--- /dev/null
+++ b/minecraft/data-ambassador/setup.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+adduser minecraft -D
+
+chown -R minecraft /minecraft/server
+chmod -R 777 /minecraft/server
+
diff --git a/minecraft/data/Dockerfile b/minecraft/data/Dockerfile
new file mode 100644
index 0000000..69461b8
--- /dev/null
+++ b/minecraft/data/Dockerfile
@@ -0,0 +1,12 @@
+FROM busybox
+
+VOLUME /minecraft/server
+
+ADD bukkit.yml /minecraft/server/
+ADD server.properties /minecraft/server/
+ADD start.sh /minecraft/
+
+RUN chmod 777 /minecraft/start.sh
+RUN chmod 777 /minecraft/server
+
+CMD /minecraft/start.sh
diff --git a/minecraft/data/bukkit.yml b/minecraft/data/bukkit.yml
new file mode 100644
index 0000000..ced5c1a
--- /dev/null
+++ b/minecraft/data/bukkit.yml
@@ -0,0 +1,37 @@
+settings:
+ allow-end: true
+ warn-on-overload: true
+ permissions-file: permissions.yml
+ update-folder: update
+ ping-packet-limit: 100
+ use-exact-login-location: false
+ plugin-profiling: false
+ connection-throttle: 4000
+ query-plugins: true
+ deprecated-verbose: default
+ shutdown-message: Server closed
+spawn-limits:
+ monsters: 70
+ animals: 15
+ water-animals: 5
+ ambient: 15
+chunk-gc:
+ period-in-ticks: 600
+ load-threshold: 0
+ticks-per:
+ animal-spawns: 400
+ monster-spawns: 1
+ autosave: 6000
+auto-updater:
+ enabled: false
+ preferred-channel: beta
+ host: dl.bukkit.org
+ suggest-channels: true
+aliases: now-in-commands.yml
+database:
+ username: bukkit
+ isolation: SERIALIZABLE
+ driver: org.sqlite.JDBC
+ password: walrus
+ url: jdbc:sqlite:{DIR}{NAME}.db
+
diff --git a/minecraft/data/server.properties b/minecraft/data/server.properties
new file mode 100644
index 0000000..04ff5ea
--- /dev/null
+++ b/minecraft/data/server.properties
@@ -0,0 +1,33 @@
+generator-settings=
+op-permission-level=4
+allow-nether=true
+level-name=world
+enable-query=false
+allow-flight=false
+announce-player-achievements=true
+server-port=25565
+level-type=DEFAULT
+enable-rcon=false
+force-gamemode=false
+level-seed=
+server-ip=
+max-build-height=256
+spawn-npcs=true
+white-list=false
+spawn-animals=true
+snooper-enabled=true
+hardcore=false
+online-mode=true
+resource-pack=
+pvp=true
+difficulty=1
+enable-command-block=false
+player-idle-timeout=0
+gamemode=0
+max-players=10
+spawn-monsters=true
+view-distance=10
+generate-structures=true
+spawn-protection=16
+motd=A Minecraft Server
+
diff --git a/minecraft/data/start.sh b/minecraft/data/start.sh
new file mode 100644
index 0000000..c315182
--- /dev/null
+++ b/minecraft/data/start.sh
@@ -0,0 +1,2 @@
+adduser -D minecraft
+chown -R minecraft /minecraft/server
diff --git a/minecraft/minecraft.py b/minecraft/minecraft.py
new file mode 100755
index 0000000..271d76c
--- /dev/null
+++ b/minecraft/minecraft.py
@@ -0,0 +1,182 @@
+#!/usr/bin/python2
+
+# Copyright (C) 2014 Sam Dodrill All rights reserved.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty. In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source
+# distribution.
+#
+
+import baker
+import docker
+import json
+import os
+import subprocess
+import time
+
+client = docker.Client()
+
+@baker.command
+def build():
+ """
+ Builds the docker images
+ """
+
+ client.build(path="server", tag="xena/minecraft:server")
+ client.build(path="data", tag="xena/minecraft:data")
+ client.build(path="data-ambassador", tag="xena/minecraft:data-amb")
+ client.build(path="backup", tag="xena/minecraft:backup")
+
+@baker.command
+def establish(prefix):
+ """
+ Establish a server name and setup its data container.
+
+ The prefix prefixes the server container names.
+ """
+
+ spawn_data(prefix)
+
+ spawn(prefix)
+
+@baker.command
+def spawn(prefix):
+ """
+ Respawn a server with prefix name
+ """
+
+ server_id = client.create_container("xena/minecraft:server", name="%s-mc-server" % prefix,
+ ports=["25565"], stdin_open=True, tty=True)
+ client.start(server_id, publish_all_ports=True, volumes_from="%s-mc-data" % prefix)
+
+ print "Server %s started" % prefix
+
+ portinfo(prefix)
+
+@baker.command
+def spawn_data(prefix):
+ """
+ Spawns the data container for a minecraft server
+ """
+
+ data_id = client.create_container("xena/minecraft:data", name="%s-mc-data" % prefix,
+ detach=True)
+ client.start(data_id)
+
+ amb_id = client.create_container("xena/minecraft:data-amb", detach=False)
+ client.start(amb_id, volumes_from="%s-mc-data" % prefix)
+ client.wait(amb_id)
+ client.remove_container(amb_id)
+
+ print "Data for %s started and permissions set" % prefix
+
+@baker.command
+def addop(prefix, opname):
+ """
+ Arbitrarily add a server operator
+ """
+
+ subprocess.call(["bash", "scripts/addop.sh", opname, prefix])
+ print "Op %s on %s added." % (opname, prefix)
+
+@baker.command
+def portinfo(prefix):
+ """
+ Gets the local and nonpersistent ip/port numbers for a server at prefix
+ """
+
+ server_id = "%s-mc-server" % prefix
+
+ ip = None
+ port = None
+
+ container = client.inspect_container(server_id)
+ ip = container["NetworkSettings"]["IPAddress"]
+ port = container["NetworkSettings"]["Ports"]["25565/tcp"][0]["HostPort"]
+
+ print "IP: %s" % ip
+ print "Port: %s" % port
+
+@baker.command
+def logs(prefix):
+ """
+ Get logs for a prefix
+ """
+
+ subprocess.call(["docker", "logs", "%s-mc-server" % prefix])
+
+@baker.command
+def kill(prefix, purge=False):
+ """
+ Kills a minecraft server, optionally purging it
+ """
+
+ server_id = "%s-mc-server" % prefix
+
+ subprocess.call(["bash", "scripts/kill-server.sh", prefix])
+
+ client.stop(server_id)
+ client.remove_container(server_id)
+
+ print "stopped %s" % server_id
+
+ if purge:
+ data_id = "%s-mc-data" % prefix
+ client.stop(data_id)
+ client.remove_container(data_id)
+
+ print "Data for %s removed" % prefix
+
+@baker.command
+def backup(prefix, mega=False):
+ """
+ Backup a minecraft server.
+ """
+
+ subprocess.call(["bash", "scripts/backup.sh", prefix])
+ name = "%s-%s.tgz" % (prefix, time.time())
+ os.rename("backup.tgz", name)
+
+ print "Backup for %s written to %s." % (prefix, name)
+
+ if mega:
+ from mega import Mega
+
+ config = {}
+
+ with open(os.getenv("HOME") + "/.config/mineupload/conf.json", "r") as fin:
+ config = json.loads(fin.read())
+
+ username, password = config["u"], config["p"]
+
+ print "Logging into mega..."
+
+ mega = Mega({"verbose": True})
+ m = mega.login(username, password)
+
+ print "Uploading %s to mega..." % name
+
+ fpointer = m.upload(name)
+
+ print "URL: %s" % m.get_upload_link(fpointer)
+ print "Local copy removed"
+
+ os.remove(name)
+
+baker.run()
+
diff --git a/minecraft/scripts/addop.sh b/minecraft/scripts/addop.sh
new file mode 100755
index 0000000..6ac11b3
--- /dev/null
+++ b/minecraft/scripts/addop.sh
@@ -0,0 +1,17 @@
+OP="$1"
+PREFIX="$2"
+
+if [ "$OP" = "" ]
+then
+ exit -1
+fi
+
+if [ "$PREFIX" = "" ]
+then
+ exit -1
+fi
+
+echo "Trying to op $OP on $PREFIX"
+
+echo "op $OP" | docker attach "$PREFIX"-mc-server
+
diff --git a/minecraft/scripts/backup.sh b/minecraft/scripts/backup.sh
new file mode 100755
index 0000000..9feec18
--- /dev/null
+++ b/minecraft/scripts/backup.sh
@@ -0,0 +1 @@
+docker run --rm -v `pwd`:/mnt/host --volumes-from "$1"-mc-data xena/minecraft:backup
diff --git a/minecraft/scripts/kill-server.sh b/minecraft/scripts/kill-server.sh
new file mode 100755
index 0000000..cc4f23f
--- /dev/null
+++ b/minecraft/scripts/kill-server.sh
@@ -0,0 +1,10 @@
+PREFIX="$1"
+
+if [ "$PREFIX" = "" ]
+then
+ exit -1
+fi
+
+echo "save-all" | docker attach $PREFIX-mc-server
+echo "stop" | docker attach $PREFIX-mc-server
+
diff --git a/minecraft/scripts/megaupload.py b/minecraft/scripts/megaupload.py
new file mode 100644
index 0000000..eebf340
--- /dev/null
+++ b/minecraft/scripts/megaupload.py
@@ -0,0 +1,48 @@
+# Copyright (C) 2014 Sam Dodrill All rights reserved.
+#
+# This software is provided 'as-is', without any express or implied
+# warranty. In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+# claim that you wrote the original software. If you use this software
+# in a product, an acknowledgment in the product documentation would be
+# appreciated but is not required.
+#
+# 2. Altered source versions must be plainly marked as such, and must not be
+# misrepresented as being the original software.
+#
+# 3. This notice may not be removed or altered from any source
+# distribution.
+#
+
+from mega import Mega
+
+import json
+import os
+import sys
+
+mega = Mega()
+
+if len(sys.argv) > 2:
+ print "Need file to upload"
+ sys.exit(-1)
+
+fname = sys.argv[1]
+
+config = {}
+
+with open(os.getenv("HOME") + "/.config/mineupload/conf.json", "r") as fin:
+ config = json.loads(fin.read())
+
+username, password = config["u"], config["p"]
+
+m = mega.login(username, password)
+
+fpointer = m.upload(fname)
+print m.get_upload_link(fpointer)
+
diff --git a/minecraft/server/Dockerfile b/minecraft/server/Dockerfile
new file mode 100644
index 0000000..d824520
--- /dev/null
+++ b/minecraft/server/Dockerfile
@@ -0,0 +1,27 @@
+FROM ubuntu:14.04
+
+RUN apt-get update
+RUN apt-get -y upgrade
+
+RUN apt-get -y install openjdk-7-jre-headless
+
+RUN apt-get -y install wget
+
+RUN mkdir -p /minecraft/server
+
+RUN adduser minecraft --home /minecraft/user --disabled-password --gecos "Minecraft daemon"
+
+RUN chmod 777 /minecraft/server
+RUN chown minecraft /minecraft/server
+
+RUN wget -O /minecraft/server.jar http://dl.bukkit.org/latest-beta/craftbukkit-beta.jar
+
+EXPOSE 25565
+
+ADD start.sh /minecraft/start.sh
+RUN chmod 777 /minecraft/start.sh
+
+USER minecraft
+
+CMD /minecraft/start.sh
+
diff --git a/minecraft/server/start.sh b/minecraft/server/start.sh
new file mode 100644
index 0000000..1c53e34
--- /dev/null
+++ b/minecraft/server/start.sh
@@ -0,0 +1,4 @@
+cd /minecraft/server
+
+java -jar /minecraft/server.jar
+
diff --git a/moonscript/Dockerfile b/moonscript/Dockerfile
new file mode 100644
index 0000000..b6db9e5
--- /dev/null
+++ b/moonscript/Dockerfile
@@ -0,0 +1,8 @@
+FROM xena/base
+
+RUN apt-get update && apt-get upgrade -y && \
+ apt-get install --assume-yes liblua5.1-dev lua5.1 luajit luarocks \
+ build-essential make git mercurial wget curl
+
+RUN luarocks install --server=http://rocks.moonscript.org moonrocks
+RUN moonrocks install moonscript
diff --git a/niinix/Dockerfile b/niinix/Dockerfile
new file mode 100644
index 0000000..83d7f45
--- /dev/null
+++ b/niinix/Dockerfile
@@ -0,0 +1,15 @@
+FROM ubuntu:14.04
+
+RUN apt-get update
+RUN apt-get -qy upgrade
+RUN apt-get install -yq cron
+
+# Add init stuff
+ADD init/init /init
+ADD scripts/rc /etc/rc
+
+# Test app
+ADD app /app
+
+ENTRYPOINT /init
+
diff --git a/niinix/Makefile b/niinix/Makefile
new file mode 100644
index 0000000..c0e5acd
--- /dev/null
+++ b/niinix/Makefile
@@ -0,0 +1,14 @@
+all:
+ @echo "Please choose a make rule"
+
+init:
+ (cd init && make build)
+
+build:
+ @make init
+ docker build -t xena/niinix .
+
+clean:
+ cd init && make clean
+ docker rmi xena/niinix
+
diff --git a/niinix/app/bin/boot b/niinix/app/bin/boot
new file mode 100755
index 0000000..eb30c5f
--- /dev/null
+++ b/niinix/app/bin/boot
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+while true ; do
+ echo "Hello at $(date)"
+ sleep 5
+done
+
diff --git a/niinix/app/bin/entry b/niinix/app/bin/entry
new file mode 100755
index 0000000..90f3d75
--- /dev/null
+++ b/niinix/app/bin/entry
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+echo "This is the entry script at $(date)"
+
diff --git a/niinix/init/Makefile b/niinix/init/Makefile
new file mode 100644
index 0000000..7d79401
--- /dev/null
+++ b/niinix/init/Makefile
@@ -0,0 +1,5 @@
+build:
+ gcc -static -o init ./init.c
+
+clean:
+ rm init
diff --git a/niinix/init/init.c b/niinix/init/init.c
new file mode 100644
index 0000000..b757496
--- /dev/null
+++ b/niinix/init/init.c
@@ -0,0 +1,60 @@
+// https://gist.github.com/rofl0r/6168719
+
+#define _XOPEN_SOURCE 700
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void properly_clean_up(int signum)
+{
+ printf("init: %s Asked to die, terminating all processes\n", ctime(NULL));
+
+ kill(-1, SIGTERM);
+
+ pid_t err;
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ err = waitpid(-1, 0, 0);
+
+ if(err == -1) {
+ sleep(1);
+ } else {
+ break;
+ }
+ }
+
+ printf("init: %s Killing all remaining processes. See you on the other side.\n", ctime(NULL));
+
+ kill(-1, SIGKILL);
+ exit(signum);
+}
+
+int main()
+{
+ sigset_t set;
+ int status;
+
+ signal(SIGINT, properly_clean_up);
+ signal(SIGTERM, properly_clean_up);
+
+ if (getpid() != 1) return 1;
+
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, 0);
+
+ if (fork()) for (;;) wait(&status);
+
+ sigprocmask(SIG_UNBLOCK, &set, 0);
+
+ setsid();
+ setpgid(0, 0);
+
+ printf("init: %s starting up", ctime(NULL));
+
+ return execve("/etc/rc", (char *[]){ "rc", 0 }, (char *[]){ 0 });
+}
diff --git a/niinix/scripts/rc b/niinix/scripts/rc
new file mode 100755
index 0000000..d3ce710
--- /dev/null
+++ b/niinix/scripts/rc
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Start cron
+cron -L 7
+
+# Some deis containers need an extra entry step
+if [ -x /app/bin/entry ]
+then
+ /app/bin/entry
+
+ exitstatus="$?"
+
+ if [ "$exitstatus" != "0" ]; then
+ echo "The entry script failed"
+ exit $exitstatus
+ fi
+fi
+
+# Start the main container process
+/app/bin/boot
+
diff --git a/python-3.4/Dockerfile b/python-3.4/Dockerfile
new file mode 100644
index 0000000..68a6d2f
--- /dev/null
+++ b/python-3.4/Dockerfile
@@ -0,0 +1,3 @@
+FROM xena/base
+
+RUN apt-get update && apt-get -y install python3.4-dev python3.4
diff --git a/qo/Dockerfile b/qo/Dockerfile
new file mode 100644
index 0000000..ab8f923
--- /dev/null
+++ b/qo/Dockerfile
@@ -0,0 +1,3 @@
+FROM xena/base
+
+RUN setuser xena go get github.com/andlabs/qo
diff --git a/rtorrent/Dockerfile b/rtorrent/Dockerfile
new file mode 100644
index 0000000..f2c5728
--- /dev/null
+++ b/rtorrent/Dockerfile
@@ -0,0 +1,18 @@
+FROM xena/alpine:3.0
+
+RUN apk update
+RUN apk add rtorrent rsync openssh
+
+RUN adduser torrent -D -s /bin/sh
+RUN echo "torrent:torrent" | chpasswd
+
+RUN mkdir /torrents
+RUN chown torrent /torrents
+RUN chmod 777 /torrents
+
+ADD rtorrent.rc /home/torrent/.rtorrent.rc
+
+USER torrent
+
+VOLUME /torrents
+
diff --git a/rtorrent/rtorrent.rc b/rtorrent/rtorrent.rc
new file mode 100644
index 0000000..b5b0b11
--- /dev/null
+++ b/rtorrent/rtorrent.rc
@@ -0,0 +1,106 @@
+# Maximum and minimum number of peers to connect to per torrent.
+min_peers = 40
+max_peers = 100
+
+# Same as above but for seeding completed torrents (-1 = same as downloading)
+min_peers_seed = 10
+max_peers_seed = 50
+
+# Maximum number of simultanious uploads per torrent.
+max_uploads = 5
+
+# Global upload and download rate in KiB. "0" for unlimited.
+download_rate = 0
+upload_rate = 0
+
+# Default directory to save the downloaded torrents.
+#directory = ./
+directory = /torrents
+
+# Default session directory. Make sure you don't run multiple instance
+# of rtorrent using the same session directory. Perhaps using a
+# relative path?
+session = /torrents/session
+
+# Watch a directory for new torrents, and stop those that have been
+# deleted.
+schedule = watch_directory,5,5,load_start=/torrents/seed/*.torrent
+schedule = untied_directory,5,5,stop_untied=
+
+# Close torrents when diskspace is low.
+schedule = low_diskspace,5,60,close_low_diskspace=100M
+
+# Stop torrents when reaching upload ratio in percent,
+# when also reaching total upload in bytes, or when
+# reaching final upload ratio in percent.
+# example: stop at ratio 2.0 with at least 200 MB uploaded, or else ratio 20.0
+# schedule = ratio,60,60,stop_on_ratio=110,200M,200
+
+# The ip address reported to the tracker.
+#ip = 127.0.0.1
+#ip = rakshasa.no
+
+# The ip address the listening socket and outgoing connections is
+# bound to.
+#bind = 127.0.0.1
+#bind = rakshasa.no
+
+# Port range to use for listening.
+port_range = 6900-6999
+
+# Start opening ports at a random position within the port range.
+port_random = yes
+
+# Check hash for finished torrents. Might be usefull until the bug is
+# fixed that causes lack of diskspace not to be properly reported.
+check_hash = yes
+
+# Set whetever the client should try to connect to UDP trackers.
+use_udp_trackers = yes
+
+# Alternative calls to bind and ip that should handle dynamic ip's.
+#schedule = ip_tick,0,1800,ip=rakshasa
+#schedule = bind_tick,0,1800,bind=rakshasa
+
+# Encryption options, set to none (default) or any combination of the following:
+# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
+#
+# The example value allows incoming encrypted connections, starts unencrypted
+# outgoing connections but retries with encryption if they fail, preferring
+# plaintext to RC4 encryption after the encrypted handshake
+#
+encryption = allow_incoming,enable_retry,prefer_plaintext
+
+#
+# Do not modify the following parameters unless you know what you're doing.
+#
+
+# Hash read-ahead controls how many MB to request the kernel to read
+# ahead. If the value is too low the disk may not be fully utilized,
+# while if too high the kernel might not be able to keep the read
+# pages in memory thus end up trashing.
+#hash_read_ahead = 10
+
+# Interval between attempts to check the hash, in milliseconds.
+#hash_interval = 100
+
+# Number of attempts to check the hash while using the mincore status,
+# before forcing. Overworked systems might need lower values to get a
+# decent hash checking rate.
+#hash_max_tries = 10
+
+# Max number of files to keep open simultaniously.
+#max_open_files = 128
+
+# Number of sockets to simultaneously keep open.
+#max_open_sockets =
+
+# Example of scheduling commands: Switch between two ip's every 5
+# seconds.
+#schedule = "ip_tick1,5,10,ip=torretta"
+#schedule = "ip_tick2,10,10,ip=lampedusa"
+
+# Remove a scheduled event.
+#schedule_remove = "ip_tick1"
+
+#transmission-daemon is better for what it is worth
diff --git a/rust/Dockerfile b/rust/Dockerfile
new file mode 100644
index 0000000..d3618ca
--- /dev/null
+++ b/rust/Dockerfile
@@ -0,0 +1,5 @@
+FROM xena/base
+
+ADD . /var/setup/xena/rust
+
+RUN /var/setup/xena/rust/rustup.sh
diff --git a/rust/rustup.sh b/rust/rustup.sh
new file mode 100755
index 0000000..5ac654d
--- /dev/null
+++ b/rust/rustup.sh
@@ -0,0 +1,461 @@
+#!/bin/sh
+# Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+# file at the top-level directory of this distribution and at
+# http://rust-lang.org/COPYRIGHT.
+#
+# Licensed under the Apache License, Version 2.0 or the MIT license
+# , at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+
+msg() {
+ echo "rustup: $1"
+}
+
+step_msg() {
+ msg
+ msg "$1"
+ msg
+}
+
+warn() {
+ echo "rustup: WARNING: $1"
+}
+
+err() {
+ echo "rustup: error: $1"
+ exit 1
+}
+
+need_ok() {
+ if [ $? -ne 0 ]
+ then
+ err "$1"
+ fi
+}
+
+
+putvar() {
+ local T
+ eval T=\$$1
+ eval TLEN=\${#$1}
+ if [ $TLEN -gt 35 ]
+ then
+ printf "rustup: %-20s := %.35s ...\n" $1 "$T"
+ else
+ printf "rustup: %-20s := %s %s\n" $1 "$T" "$2"
+ fi
+}
+
+probe() {
+ local V=$1
+ shift
+ local P
+ local T
+ for P
+ do
+ T=$(which $P 2>&1)
+ if [ $? -eq 0 ]
+ then
+ VER0=$($P --version 2>/dev/null | head -1 \
+ | sed -e 's/[^0-9]*\([vV]\?[0-9.]\+[^ ]*\).*/\1/' )
+ if [ $? -eq 0 -a "x${VER0}" != "x" ]
+ then
+ VER="($VER0)"
+ else
+ VER=""
+ fi
+ break
+ else
+ VER=""
+ T=""
+ fi
+ done
+ eval $V=\$T
+ putvar $V "$VER"
+}
+
+probe_need() {
+ local V=$1
+ probe $*
+ eval VV=\$$V
+ if [ -z "$VV" ]
+ then
+ err "needed, but unable to find any of: $*"
+ fi
+}
+
+
+valopt() {
+ VAL_OPTIONS="$VAL_OPTIONS $1"
+
+ local OP=$1
+ local DEFAULT=$2
+ shift
+ shift
+ local DOC="$*"
+ if [ $HELP -eq 0 ]
+ then
+ local UOP=$(echo $OP | tr '[:lower:]' '[:upper:]' | tr '\-' '\_')
+ local V="CFG_${UOP}"
+ eval $V="$DEFAULT"
+ for arg in $CFG_ARGS
+ do
+ if echo "$arg" | grep -q -- "--$OP="
+ then
+ val=$(echo "$arg" | cut -f2 -d=)
+ eval $V=$val
+ fi
+ done
+ putvar $V
+ else
+ if [ -z "$DEFAULT" ]
+ then
+ DEFAULT=""
+ fi
+ OP="${OP}=[${DEFAULT}]"
+ printf " --%-30s %s\n" "$OP" "$DOC"
+ fi
+}
+
+opt() {
+ BOOL_OPTIONS="$BOOL_OPTIONS $1"
+
+ local OP=$1
+ local DEFAULT=$2
+ shift
+ shift
+ local DOC="$*"
+ local FLAG=""
+
+ if [ $DEFAULT -eq 0 ]
+ then
+ FLAG="enable"
+ else
+ FLAG="disable"
+ DOC="don't $DOC"
+ fi
+
+ if [ $HELP -eq 0 ]
+ then
+ for arg in $CFG_ARGS
+ do
+ if [ "$arg" = "--${FLAG}-${OP}" ]
+ then
+ OP=$(echo $OP | tr 'a-z-' 'A-Z_')
+ FLAG=$(echo $FLAG | tr 'a-z' 'A-Z')
+ local V="CFG_${FLAG}_${OP}"
+ eval $V=1
+ putvar $V
+ fi
+ done
+ else
+ if [ ! -z "$META" ]
+ then
+ OP="$OP=<$META>"
+ fi
+ printf " --%-30s %s\n" "$FLAG-$OP" "$DOC"
+ fi
+}
+
+flag() {
+ BOOL_OPTIONS="$BOOL_OPTIONS $1"
+
+ local OP=$1
+ shift
+ local DOC="$*"
+
+ if [ $HELP -eq 0 ]
+ then
+ for arg in $CFG_ARGS
+ do
+ if [ "$arg" = "--${OP}" ]
+ then
+ OP=$(echo $OP | tr 'a-z-' 'A-Z_')
+ local V="CFG_${OP}"
+ eval $V=1
+ putvar $V
+ fi
+ done
+ else
+ if [ ! -z "$META" ]
+ then
+ OP="$OP=<$META>"
+ fi
+ printf " --%-30s %s\n" "$OP" "$DOC"
+ fi
+}
+
+validate_opt () {
+ for arg in $CFG_ARGS
+ do
+ isArgValid=0
+ for option in $BOOL_OPTIONS
+ do
+ if test --disable-$option = $arg
+ then
+ isArgValid=1
+ fi
+ if test --enable-$option = $arg
+ then
+ isArgValid=1
+ fi
+ if test --$option = $arg
+ then
+ isArgValid=1
+ fi
+ done
+ for option in $VAL_OPTIONS
+ do
+ if echo "$arg" | grep -q -- "--$option="
+ then
+ isArgValid=1
+ fi
+ done
+ if [ "$arg" = "--help" ]
+ then
+ echo
+ echo "No more help available for Configure options,"
+ echo "check the Wiki or join our IRC channel"
+ break
+ else
+ if test $isArgValid -eq 0
+ then
+ err "Option '$arg' is not recognized"
+ fi
+ fi
+ done
+}
+
+probe_need CFG_CURL curl
+
+CFG_SRC_DIR="$(cd $(dirname $0) && pwd)/"
+CFG_SELF="$0"
+CFG_ARGS="$@"
+
+HELP=0
+if [ "$1" = "--help" ]
+then
+ HELP=1
+ shift
+ echo
+ echo "Usage: $CFG_SELF [options]"
+ echo
+ echo "Options:"
+ echo
+else
+ step_msg "processing $CFG_SELF args"
+fi
+
+OPTIONS=""
+BOOL_OPTIONS=""
+VAL_OPTIONS=""
+
+flag uninstall "only uninstall from the installation prefix"
+valopt prefix "" "set installation prefix"
+opt cargo 1 "install cargo with rust"
+
+if [ $HELP -eq 1 ]
+then
+ echo
+ exit 0
+fi
+
+step_msg "validating $CFG_SELF args"
+validate_opt
+
+
+# Platform detection copied from `configure`
+
+CFG_OSTYPE=$(uname -s)
+CFG_CPUTYPE=$(uname -m)
+
+if [ $CFG_OSTYPE = Darwin -a $CFG_CPUTYPE = i386 ]
+then
+ # Darwin's `uname -s` lies and always returns i386. We have to use sysctl
+ # instead.
+ if sysctl hw.optional.x86_64 | grep -q ': 1'
+ then
+ CFG_CPUTYPE=x86_64
+ fi
+fi
+
+# The goal here is to come up with the same triple as LLVM would,
+# at least for the subset of platforms we're willing to target.
+
+case $CFG_OSTYPE in
+
+ Linux)
+ CFG_OSTYPE=unknown-linux-gnu
+ ;;
+
+ FreeBSD)
+ CFG_OSTYPE=unknown-freebsd
+ ;;
+
+ Darwin)
+ CFG_OSTYPE=apple-darwin
+ ;;
+
+ MINGW32*)
+ CFG_OSTYPE=pc-mingw32
+ ;;
+# Thad's Cygwin identifers below
+
+# Vista 32 bit
+ CYGWIN_NT-6.0)
+ CFG_OSTYPE=pc-mingw32
+ CFG_CPUTYPE=i686
+ ;;
+
+# Vista 64 bit
+ CYGWIN_NT-6.0-WOW64)
+ CFG_OSTYPE=w64-mingw32
+ CFG_CPUTYPE=x86_64
+ ;;
+
+# Win 7 32 bit
+ CYGWIN_NT-6.1)
+ CFG_OSTYPE=pc-mingw32
+ CFG_CPUTYPE=i686
+ ;;
+
+# Win 7 64 bit
+ CYGWIN_NT-6.1-WOW64)
+ CFG_OSTYPE=w64-mingw32
+ CFG_CPUTYPE=x86_64
+ ;;
+
+# We do not detect other OS such as XP/2003 using 64 bit using uname.
+# If we want to in the future, we will need to use Cygwin - Chuck's csih helper in /usr/lib/csih/winProductName.exe or alternative.
+ *)
+ err "unknown OS type: $CFG_OSTYPE"
+ ;;
+esac
+
+
+case $CFG_CPUTYPE in
+ xscale | arm)
+ CFG_CPUTYPE=arm
+ ;;
+
+ x86_64 | x86-64 | x64 | amd64)
+ CFG_CPUTYPE=x86_64
+ ;;
+
+ *)
+ err "unknown CPU type: $CFG_CPUTYPE"
+esac
+
+HOST_TRIPLE="${CFG_CPUTYPE}-${CFG_OSTYPE}"
+
+# Is this a triple we have nightlies for?
+case $HOST_TRIPLE in
+
+ x86_64-unknown-linux-gnu)
+ ;;
+
+ i686-unknown-linux-gnu)
+ ;;
+
+ x86_64-apple-darwin)
+ ;;
+
+ i686-apple-darwin)
+ ;;
+
+ *)
+ err "rustup.sh doesn't work for host $HOST_TRIPLE"
+
+esac
+
+msg "host triple: ${HOST_TRIPLE}"
+
+PACKAGE_NAME=rust-nightly
+PACKAGE_NAME_AND_TRIPLE="${PACKAGE_NAME}-${HOST_TRIPLE}"
+TARBALL_NAME="${PACKAGE_NAME_AND_TRIPLE}.tar.gz"
+REMOTE_TARBALL="https://static.rust-lang.org/dist/${TARBALL_NAME}"
+TMP_DIR="./rustup-tmp-install"
+LOCAL_TARBALL="${TMP_DIR}/${TARBALL_NAME}"
+LOCAL_INSTALL_DIR="${TMP_DIR}/${PACKAGE_NAME_AND_TRIPLE}"
+LOCAL_INSTALL_SCRIPT="${LOCAL_INSTALL_DIR}/install.sh"
+
+CARGO_PACKAGE_NAME=cargo-nightly
+CARGO_PACKAGE_NAME_AND_TRIPLE="${CARGO_PACKAGE_NAME}-${HOST_TRIPLE}"
+CARGO_TARBALL_NAME="${CARGO_PACKAGE_NAME_AND_TRIPLE}.tar.gz"
+CARGO_REMOTE_TARBALL="https://static.rust-lang.org/cargo-dist/${CARGO_TARBALL_NAME}"
+CARGO_LOCAL_TARBALL="${TMP_DIR}/${CARGO_TARBALL_NAME}"
+CARGO_LOCAL_INSTALL_DIR="${TMP_DIR}/${CARGO_PACKAGE_NAME_AND_TRIPLE}"
+CARGO_LOCAL_INSTALL_SCRIPT="${CARGO_LOCAL_INSTALL_DIR}/install.sh"
+
+rm -Rf "${TMP_DIR}"
+need_ok "failed to remove temporary installation directory"
+
+mkdir -p "${TMP_DIR}"
+need_ok "failed to create create temporary installation directory"
+
+msg "downloading rust installer"
+"${CFG_CURL}" "${REMOTE_TARBALL}" > "${LOCAL_TARBALL}"
+if [ $? -ne 0 ]
+then
+ rm -Rf "${TMP_DIR}"
+ err "failed to download installer"
+fi
+
+if [ -z "${CFG_DISABLE_CARGO}" ]; then
+ msg "downloading cargo installer"
+ "${CFG_CURL}" "${CARGO_REMOTE_TARBALL}" > "${CARGO_LOCAL_TARBALL}"
+ if [ $? -ne 0 ]
+ then
+ rm -Rf "${TMP_DIR}"
+ err "failed to download cargo installer"
+ fi
+fi
+
+
+(cd "${TMP_DIR}" && tar xzf "${TARBALL_NAME}")
+if [ $? -ne 0 ]
+then
+ rm -Rf "${TMP_DIR}"
+ err "failed to unpack installer"
+fi
+
+MAYBE_UNINSTALL=
+if [ -n "${CFG_UNINSTALL}" ]
+then
+ MAYBE_UNINSTALL="--uninstall"
+fi
+
+MAYBE_PREFIX=
+if [ -n "${CFG_PREFIX}" ]
+then
+ MAYBE_PREFIX="--prefix=${CFG_PREFIX}"
+fi
+
+sh "${LOCAL_INSTALL_SCRIPT}" "${MAYBE_UNINSTALL}" "${MAYBE_PREFIX}"
+if [ $? -ne 0 ]
+then
+ rm -Rf "${TMP_DIR}"
+ err "failed to install Rust"
+fi
+
+if [ -z "${CFG_DISABLE_CARGO}" ]; then
+ (cd "${TMP_DIR}" && tar xzf "${CARGO_TARBALL_NAME}")
+ if [ $? -ne 0 ]
+ then
+ rm -Rf "${TMP_DIR}"
+ err "failed to unpack cargo installer"
+ fi
+
+ sh "${CARGO_LOCAL_INSTALL_SCRIPT}" "${MAYBE_UNINSTALL}" "${MAYBE_PREFIX}"
+ if [ $? -ne 0 ]
+ then
+ rm -Rf "${TMP_DIR}"
+ err "failed to install Cargo"
+ fi
+fi
+
+rm -Rf "${TMP_DIR}"
+need_ok "couldn't rm temporary installation directory"
diff --git a/starbound/Dockerfile b/starbound/Dockerfile
new file mode 100644
index 0000000..ddf8c5e
--- /dev/null
+++ b/starbound/Dockerfile
@@ -0,0 +1,10 @@
+FROM xena/starbound:seed
+
+EXPOSE 21025
+
+USER starbound
+
+ADD start.sh /home/starbound/
+
+CMD /home/starbound/start.sh
+
diff --git a/starbound/starrypy/Dockerfile b/starbound/starrypy/Dockerfile
new file mode 100644
index 0000000..3b74a96
--- /dev/null
+++ b/starbound/starrypy/Dockerfile
@@ -0,0 +1,13 @@
+FROM ubuntu:14.04
+
+RUN apt-get install python2.7 python-dev python-pip git python-sqlite python-twisted-words
+
+RUN git clone https://github.com/CarrotsAreMediocre/StarryPy
+
+USER root
+
+RUN pip install -r StarryPy/requirements.txt
+
+USER starbound
+
+
diff --git a/starbound/start.sh b/starbound/start.sh
new file mode 100755
index 0000000..99b9deb
--- /dev/null
+++ b/starbound/start.sh
@@ -0,0 +1,2 @@
+cd /home/starbound/starbound/linux64
+./starbound_server
diff --git a/weechat/Dockerfile b/weechat/Dockerfile
new file mode 100644
index 0000000..663e833
--- /dev/null
+++ b/weechat/Dockerfile
@@ -0,0 +1,12 @@
+FROM flitter/init
+
+RUN apt-get update && apt-get -y upgrade && apt-get -y install dvtm dtach weechat
+RUN useradd --create-home xena && echo 'xena:user' | chpasswd
+
+ADD start.sh /
+ADD http://repo.or.cz/w/dvtm.git/blob_plain/HEAD:/dvtm.info /tmp/
+RUN tic -s /tmp/dvtm.info
+
+ENV HOME /home/xena
+
+CMD /sbin/my_init setuser xena /start.sh
diff --git a/weechat/start.sh b/weechat/start.sh
new file mode 100755
index 0000000..e9773e5
--- /dev/null
+++ b/weechat/start.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+export TERM=dvtm
+
+dtach -A /tmp/weechat.dvtm -r winch dvtm 'weechat && killall dtach'