#! /bin/bash

set -eux

# Cleanup the file system a bit
rm -rf /var/cache/dnf /var/cache/yum
xfs_growfs /

echo foobar | passwd --stdin root

printf "\nLOGIN\n  User: root/admin  Password: foobar\n\n" >> /etc/issue
printf "SSH ACCESS\n  $ ssh root@10.111.112.101\n  Password: foobar\n\n" >> /etc/issue
printf "OPENSHIFT CONSOLE\n  https://10.111.112.101:8443\n  Login: scruffy  Password: scruffy\n\n" >> /etc/issue
printf "OPENSHIFT LISTENING ON LOCALHOST\n  $ ssh -NL 8443:localhost:8443 root@10.111.112.101\n\n" >> /etc/issue

# Disable these things
ln -sf ../selinux/config /etc/sysconfig/selinux
printf 'SELINUX=permissive\nSELINUXTYPE=targeted\n' > /etc/selinux/config
setenforce 0
systemctl stop firewalld
dnf -y remove firewalld
iptables -F

# Wait for x for many minutes
function wait() {
    for i in $(seq 1 100); do
        if eval "$@"; then
            return 0
        fi
        sleep 6
    done
    exit 6
}

wait dnf -y install docker python libselinux-python

hostnamectl set-hostname f1.cockpit.lan

# Setup a nfs server
wait dnf install -y nfs-utils
mkdir /nfsexport
echo "/nfsexport *(rw,sync)" > /etc/exports

# This name is put into /etc/hosts later
echo "INSECURE_REGISTRY='--insecure-registry registry:5000'" >> /etc/sysconfig/docker
systemctl enable docker

# HACK: docker falls over regularly, print its log if it does
systemctl start docker || journalctl -u docker

# Can't use latest because release on older versions are done out of order
VERSION=$(curl -s https://api.github.com/repos/openshift/origin/releases | LC_ALL=C.UTF-8 python3 -c "import json, sys; obj=json.load(sys.stdin); releases = [x.get('tag_name', '') for x in obj if not x.get('prerelease')]; print(sorted (releases, reverse=True)[0])")

# origin is too rotund to build in a normal sized VM. The linker
# step runs out of memory. In addition origin has no Fedora packages
docker pull "openshift/origin:$VERSION"
container=$(docker create "openshift/origin:$VERSION")
docker cp $container:/usr/bin - | tar -C /usr -xf - bin/openshift bin/oc bin/oadm bin/kubectl

# Runs a master if on the right address, otherwise runs a node
cat > /openshift-prep <<EOF
#!/bin/sh -ex
if /usr/sbin/ip addr | /usr/bin/grep -i "52:54:00:9e:00:f1"; then
    /usr/bin/hostnamectl set-hostname f1.cockpit.lan
    # HACK: work around https://bugzilla.redhat.com/show_bug.cgi?id=1401561
    /usr/bin/systemd-tmpfiles --create /usr/lib/tmpfiles.d/rpcbind.conf
    /usr/bin/systemctl enable rpcbind
    /usr/bin/systemctl start rpcbind
    /usr/bin/systemctl start nfs-server
    cmd="/usr/bin/openshift start --master=10.111.112.101"
else
    /usr/bin/hostnamectl set-hostname node-\$(/usr/bin/cat /sys/devices/virtual/dmi/id/product_uuid)
    cmd="/usr/bin/openshift start node --kubeconfig=/openshift.local.config/node-f1.cockpit.lan/node.kubeconfig"
fi
echo "#!/bin/sh -ex
\$cmd" > /openshift-run
EOF

chmod +x /openshift-prep
touch /openshift-run
chmod +x /openshift-run

cat > /etc/systemd/system/openshift.service <<EOF
[Unit]
Description=Openshift
Wants=network-online.target
After=network-online.target docker.service
Requires=docker.service
[Service]
ExecStartPre=/openshift-prep
ExecStart=/openshift-run
Restart=always
RestartSec=60
[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable systemd-networkd-wait-online
systemctl enable openshift
systemctl start openshift || journalctl -u openshift

# Now pull all the images we're going to use with openshift
docker pull "openshift/origin-deployer:$VERSION"
docker pull "openshift/origin-docker-registry:$VERSION"
docker pull "openshift/origin-pod:$VERSION"

mkdir -p /root/.kube
cp /openshift.local.config/master/admin.kubeconfig /root/.kube/config

# Check if we can connect to openshift
wait oc get namespaces

wait oc get scc/restricted

# Tell openshift to allow root containers by default. Otherwise most
# development examples just plain fail to work
oc patch scc restricted -p '{ "runAsUser": { "type": "RunAsAny" } }'

# Tell openshift to allow logins from the openshift web console on a localhost system
oc patch oauthclient/openshift-web-console -p '{"redirectURIs":["https://10.111.112.101:8443/console/", "https://localhost:9000/"]}'

# Deploy the registry
# --credentials deprecated
oadm registry

function endpoint_has_address() {
    oc get endpoints $1 --template='{{.subsets}}' | grep -q addresses
}

function images_has() {
    oc get images | grep -q "$1"
}

# Wait for registry deployment to happen
wait oc get endpoints docker-registry
wait endpoint_has_address docker-registry

# Load in some remote images
echo '{"apiVersion":"v1","kind":"ImageStream","metadata": {"name":"busybox"},"spec":{"dockerImageRepository": "busybox"}}' > /tmp/imagestream.json
oc create -f /tmp/imagestream.json

# Get registry address and configure docker for it
address="$(oc get services docker-registry | tail -n1 | awk -v N=2 '{print $N}')"
echo "$address     registry registry.cockpit.lan" >> /etc/hosts

# Log in as another user
printf "scruffy\r\nscruffy\r\n" | oc login
oc new-project marmalade

token=$(oc whoami -t)
docker login -p "$token" -e silly@email.com -u unneeded registry:5000

echo '{"apiVersion":"v1","kind":"ImageStream","metadata": {"name":"busybee"}}' > /tmp/imagestream.json
oc create -f /tmp/imagestream.json
echo '{"apiVersion":"v1","kind":"ImageStream","metadata": {"name":"juggs"}}' > /tmp/imagestream.json
oc create -f /tmp/imagestream.json
echo '{"apiVersion":"v1","kind":"ImageStream","metadata": {"name":"origin"}}' > /tmp/imagestream.json
oc create -f /tmp/imagestream.json

# Get ready to push busybox into place
docker pull busybox
docker tag busybox registry:5000/marmalade/busybee:latest
docker tag busybox registry:5000/marmalade/busybee:0.x
docker push registry:5000/marmalade/busybee

cd /tmp
printf '#!/bin/sh\necho hello from container\nsleep 100000\n' > echo-script
printf 'FROM busybox\nMAINTAINER cockpit@example.com\nEXPOSE 8888\nADD echo-script /\nRUN chmod +x /echo-script\nCMD \"/echo-script\"' > Dockerfile
docker build -t registry:5000/marmalade/juggs:latest .
printf "FROM registry:5000/marmalade/juggs:latest\nVOLUME /test\nVOLUME /another\nWORKDIR /tmp" > Dockerfile
docker build -t registry:5000/marmalade/juggs:2.11 .
cp /usr/bin/openshift .
printf "FROM registry:5000/marmalade/juggs:latest\nADD openshift /usr/bin\nUSER nobody:wheel\nENTRYPOINT [\"top\", \"-b\"]\nCMD [\"-c\"]" > Dockerfile
docker build -t registry:5000/marmalade/juggs:2.5 .
printf "FROM registry:5000/marmalade/juggs:2.5\nSTOPSIGNAL SIGKILL\nONBUILD ADD . /app/src\nARG hello=test\nARG simple\nLABEL Test=Value\nLABEL version=\"1.0\"" > Dockerfile
docker build -t registry:5000/marmalade/juggs:2.8 .
printf "FROM registry:5000/marmalade/juggs:2.8\nLABEL description=\"This is a test description of an image. It can be as long as a paragraph, featuring a nice brogrammer sales pitch.\"\nLABEL name=\"Juggs Image\"\nLABEL build-date=2016-03-04\nLABEL url=\"http://hipsum.co/\"" > Dockerfile
docker build -t registry:5000/marmalade/juggs:2.9 .

docker push registry:5000/marmalade/juggs

# Tag this image twice
docker tag docker.io/busybox:latest registry:5000/marmalade/origin
docker push registry:5000/marmalade/origin
docker tag "openshift/origin:$VERSION" registry:5000/marmalade/origin
docker push registry:5000/marmalade/origin

oc new-project pizzazz

# Some big image streams
for i in $(seq 1 15); do
    for j in $(seq 1 10); do
        docker tag docker.io/busybox:latest registry:5000/pizzazz/stream$i:tag$j
    done
    docker push registry:5000/pizzazz/stream$i
done

# And a monster sized one
for j in $(seq 1 100); do
    docker tag docker.io/busybox:latest registry:5000/pizzazz/monster:tag$j
done
docker push registry:5000/pizzazz/monster

# Use the admin context by default
oc config use-context default/10-111-112-101:8443/system:admin

# Some roles for testing against
oc patch --namespace=marmalade policybinding ':default' -p '{"roleBindings":[{"name":"admin","roleBinding":{"metadata":{"name":"admin","namespace":"marmalade"},"userNames":["scruffy"],"groupNames":null,"subjects":[{"kind":"User","name":"scruffy"}],"roleRef":{"name":"admin"}}},{"name":"registry-editor","roleBinding":{"metadata":{"name":"registry-editor","namespace":"marmalade","resourceVersion":"1"},"userNames":["scruffy","amanda"],"groupNames":null,"subjects":[{"kind":"User","name":"scruffy"},{"kind":"User","name":"amanda"}],"roleRef":{"name":"registry-editor"}}},{"name":"registry-viewer","roleBinding":{"metadata":{"name":"registry-viewer","namespace":"marmalade","resourceVersion":"1"},"userNames":["scruffy","tom","amanda"],"groupNames":["sports"],"subjects":[{"kind":"User","name":"scruffy"},{"kind":"User","name":"tom"},{"kind":"User","name":"amanda"},{"kind":"Group","name":"sports"}],"roleRef":{"name":"registry-viewer"}}}]}'

# For testing the Cockpit OAuth client
printf '{"kind":"OAuthClient","apiVersion":"v1","metadata":{"name":"cockpit-oauth-devel"},"respondWithChallenges":false,"secret":"secret","allowAnyScope":true,"redirectURIs":["http://localhost:9001"] }' | oc create -f -

# Wait for it to download
wait images_has busybox

# Setup basics for building images
docker build -t cockpit/base /var/tmp/cockpit-base

# Print out the kubeconfig file for copy paste
echo "---------------------------------------------------------------"
cat /root/.kube/config

# Wait a bit in case an operator wants to copy some info
sleep 20

# Use standard locations for kubelet kubeconfig. f1.cockpit.lan is the master hostname, which
# is its own node and we just copy that for the others
mkdir -p /var/lib/kubelet
cp /openshift.local.config/node-f1.cockpit.lan/node.kubeconfig /var/lib/kubelet/kubeconfig

# Turn this on in sshd_config, not in use until binary is in place
printf 'AuthorizedKeysCommand /usr/local/bin/authorized-kube-keys --kubeconfig=/var/lib/kubelet/kubeconfig\nAuthorizedKeysCommandUser root' >> /etc/ssh/sshd_config

# Pull down remaining images
/var/lib/testvm/docker-images.setup

# reduce image size
dnf clean all
/var/lib/testvm/zero-disk.setup
