Compare commits

...

No commits in common. 'gh-pages' and 'better-tests' have entirely different histories.

  1. 7
      .gitignore
  2. 53
      .travis.yml
  3. 19
      LICENSE
  4. 1
      MANIFEST.in
  5. 212
      README.md
  6. 4
      assets/fonts/font-awesome.css
  7. 13
      assets/fonts/material-icons.css
  8. BIN
      assets/fonts/specimen/FontAwesome.ttf
  9. BIN
      assets/fonts/specimen/FontAwesome.woff
  10. BIN
      assets/fonts/specimen/FontAwesome.woff2
  11. BIN
      assets/fonts/specimen/MaterialIcons-Regular.ttf
  12. BIN
      assets/fonts/specimen/MaterialIcons-Regular.woff
  13. BIN
      assets/fonts/specimen/MaterialIcons-Regular.woff2
  14. BIN
      assets/images/favicon.png
  15. 20
      assets/images/icons/bitbucket.1b09e088.svg
  16. 18
      assets/images/icons/github.f0b8504a.svg
  17. 38
      assets/images/icons/gitlab.6dd19c00.svg
  18. 1
      assets/javascripts/application.e72fd936.js
  19. 1
      assets/javascripts/lunr/lunr.da.js
  20. 1
      assets/javascripts/lunr/lunr.de.js
  21. 1
      assets/javascripts/lunr/lunr.du.js
  22. 1
      assets/javascripts/lunr/lunr.es.js
  23. 1
      assets/javascripts/lunr/lunr.fi.js
  24. 1
      assets/javascripts/lunr/lunr.fr.js
  25. 1
      assets/javascripts/lunr/lunr.hu.js
  26. 1
      assets/javascripts/lunr/lunr.it.js
  27. 1
      assets/javascripts/lunr/lunr.jp.js
  28. 1
      assets/javascripts/lunr/lunr.multi.js
  29. 1
      assets/javascripts/lunr/lunr.no.js
  30. 1
      assets/javascripts/lunr/lunr.pt.js
  31. 1
      assets/javascripts/lunr/lunr.ro.js
  32. 1
      assets/javascripts/lunr/lunr.ru.js
  33. 1
      assets/javascripts/lunr/lunr.stemmer.support.js
  34. 1
      assets/javascripts/lunr/lunr.sv.js
  35. 1
      assets/javascripts/lunr/lunr.tr.js
  36. 1
      assets/javascripts/lunr/tinyseg.js
  37. 1
      assets/javascripts/modernizr.1aa3b519.js
  38. 1176
      assets/stylesheets/application-palette.22915126.css
  39. 2552
      assets/stylesheets/application.451f80e5.css
  40. 2
      cli/__init__.py
  41. 156
      cli/command.py
  42. 576
      index.html
  43. 6
      kubernetes_aws.md
  44. 475
      kubernetes_aws/index.html
  45. 11
      kubernetes_dok.md
  46. 465
      kubernetes_dok/index.html
  47. 7
      kubernetes_gcp.md
  48. 475
      kubernetes_gcp/index.html
  49. 6
      kubernetes_minikube.md
  50. 460
      kubernetes_minikube/index.html
  51. 17
      requirements-to-freeze.txt
  52. 4
      requirements.txt
  53. 16
      scripts/install_minikube.sh
  54. 2986
      search/lunr.js
  55. 96
      search/main.js
  56. 1
      search/search_index.json
  57. 128
      search/worker.js
  58. 29
      setup.py
  59. 28
      sitemap.xml
  60. BIN
      sitemap.xml.gz
  61. 60
      test/Readme.md
  62. 93
      test/Snakefile
  63. 22
      test/fixcoredns.yml
  64. 11
      test/fixkubedns.yml
  65. 3
      test/params-blue.json
  66. 3
      test/params-red.json
  67. 66
      test/test_byok8s.py
  68. 3
      test/workflow-alpha.json
  69. 3
      test/workflow-gamma.json
  70. 3
      test/workflow-zeta.json

7
.gitignore vendored

@ -0,0 +1,7 @@
__pycache__
.snakemake/
vp/
*.egg-info/
build/
dist/
test/*.txt

53
.travis.yml

@ -0,0 +1,53 @@
# https://raw.githubusercontent.com/LiliC/travis-minikube/minikube-30-kube-1.12/.travis.yml
language: python
python:
- "3.6"
sudo: required
# We need the systemd for the kubeadm and it's default from 16.04+
dist: xenial
# This moves Kubernetes specific config files.
env:
- CHANGE_MINIKUBE_NONE_USER=true
install:
# Install byok8s requirements (snakemake, python-kubernetes)
- pip install -r requirements.txt
# Install byok8s cli tool
- python setup.py build install
before_script:
# Do everything from test/
- cd test
# Make root mounted as rshared to fix kube-dns issues.
- sudo mount --make-rshared /
# Download kubectl, which is a requirement for using minikube.
- curl -Lo kubectl https://storage.googleapis.com/kubernetes-release/release/v1.12.0/bin/linux/amd64/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
# Download minikube.
- curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.30.0/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
- sudo minikube start --vm-driver=none --bootstrapper=kubeadm --kubernetes-version=v1.12.0
# Fix the kubectl context, as it's often stale.
- minikube update-context
# Wait for Kubernetes to be up and ready.
- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done
################
## easy test
script:
- kubectl cluster-info
# Verify kube-addon-manager.
# kube-addon-manager is responsible for managing other kubernetes components, such as kube-dns, dashboard, storage-provisioner..
- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl -n kube-system get pods -lcomponent=kube-addon-manager -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1;echo "waiting for kube-addon-manager to be available"; kubectl get pods --all-namespaces; done
# Wait for kube-dns to be ready.
- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl -n kube-system get pods -lk8s-app=kube-dns -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1;echo "waiting for kube-dns to be available"; kubectl get pods --all-namespaces; done
# Create example Redis deployment on Kubernetes.
- kubectl run travis-example --image=redis --labels="app=travis-example"
# Make sure created pod is scheduled and running.
- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl -n default get pods -lapp=travis-example -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1;echo "waiting for travis-example deployment to be available"; kubectl get pods -n default; done
#
################
## harder
- byok8s --s3-bucket=cmr-0123 -f workflow-alpha params-blue

19
LICENSE

@ -0,0 +1,19 @@
Copyright (c) 2019 Charles Reid
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1
MANIFEST.in

@ -0,0 +1 @@
include cli/Snakefile

212
README.md

@ -0,0 +1,212 @@
# 2019-snakemake-byok8s
[![travis](https://img.shields.io/travis/charlesreid1/2019-snakemake-byok8s.svg)](https://travis-ci.org/charlesreid1/2019-snakemake-byok8s)
[![license](https://img.shields.io/github/license/charlesreid1/2019-snakemake-byok8s.svg)](https://github.com/charlesreid1/2019-snakemake-byok8s/blob/master/LICENSE)
# Overview
This is an example of a Snakemake workflow that:
- is a command line utility
- is bundled as a Python package
- is designed to run on a Kubernetes cluster
- can be tested locally or with Travis CI using minikube
Snakemake functionality is provided through
a command line tool called `byok8s`, so that
it allows you to do this (abbreviated for clarity):
```
# Create virtual k8s cluster
minikube start
# Run the workflow
byok8s --s3-bucket=mah-s3-bukkit my-workflowfile my-paramsfile
# Clean up the virtual k8s cluster
minikube stop
```
Snakemake workflows are provided via a Snakefile by
the user. Snakemake runs tasks on the Kubernetes (k8s)
cluster. The approach is for the user to provide
their own Kubernetes cluster (byok8s = Bring Your
Own Kubernetes).
The example above uses [`minikube`](https://github.com/kubernetes/minikube)
to make a virtual k8s cluster, useful for testing.
For real workflows, your options for
kubernetes clusters are cloud providers:
- AWS EKS (Elastic Container Service)
- GCP GKE (Google Kuberntes Engine)
- Digital Ocean Kubernetes service
- etc...
The Travis CI tests utilize minikube to run
test workflows.
# Quickstart
This runs through the installation and usage
of `2019-snakemake-byok8s`.
Step 1: Set up Kubernetes cluster with `minikube`.
Step 2: Install `byok8s`.
Step 3: Run the `byok8s` workflow using the Kubernetes cluster.
Step 4: Tear down Kubernetes cluster with `minikube`.
## Step 1: Set Up Virtual Kubernetes Cluster
For the purposes of the quickstart, we will walk
through how to set up a local, virtual Kubernetes
cluster using `minikube`.
Start by installing minikube:
```
scripts/install_minikube.sh
```
Once it is installed, you can start up a kubernetes cluster
with minikube using the following commands:
```
cd test
minikube start
```
NOTE: If you are running on AWS, run this command first
```
minikube config set vm-driver none
```
to set the the vm driver to none and use native Docker to run stuff.
If you are running on AWS, the DNS in the minikube
kubernetes cluster will not work, so run this command
to fix the DNS settings (should be run from the
`test/` directory):
```
kubectl apply -f fixcoredns.yml
kubectl delete --all pods --namespace kube-system
```
## Step 2: Install byok8s
Start by setting up a python virtual environment,
and install the required packages into the
virtual environment:
```
pip install -r requirements.txt
```
This installs snakemake and kubernetes Python
modules. Now install the `byok8s` command line
tool:
```
python setup.py build install
```
Now you can run:
```
which byok8s
```
and you should see `byok8s` in your virtual
environment's `bin/` directory.
This command line utility will expect a kubernetes
cluster to be set up before it is run.
Setting up a kubernetes cluster will create...
(fill in more info here)...
Snakemake will automatically create the pods
in the cluster, so you just need to allocate
a kubernetes cluster.
## Step 3: Run byok8s
Now you can run the workflow with the `byok8s` command.
This submits the Snakemake workflow jobs to the Kubernetes
cluster that minikube created.
You should have your workflow in a `Snakefile` in the
current directory. Use the `--snakefile` flag if it is
named something other than `Snakefile`.
You will also need to specify your AWS credentials
via the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
environment variables. These are used to to access
S3 buckets for file I/O.
Finally, you will need to create an S3 bucket for
Snakemake to use for file I/O. Pass the name of the
bucket using the `--s3-bucket` flag.
Start by exporting these two vars (careful to
scrub them from bash history):
```
export AWS_ACCESS_KEY_ID=XXXXX
export AWS_SECRET_ACCESS_KEY=XXXXX
```
Run the alpha workflow with blue params:
```
byok8s --s3-bucket=mah-bukkit workflow-alpha params-blue
```
Run the alpha workflow with red params:
```
byok8s --s3-bucket=mah-bukkit workflow-alpha params-red
```
Run the gamma workflow with red params, &c:
```
byok8s --s3-bucket=mah-bukkit workflow-gamma params-red
```
(NOTE: May want to let the user specify
input and output directories with flags.)
All input files are searched for relative to the working
directory.
## Step 4: Tear Down Kubernetes Cluster
The last step once the workflow has been finished,
is to tear down the kubernetes cluster. The virtual
kubernetes cluster created by minikube can be torn
down with the following command:
```
minikube stop
```
# Using Kubernetes with Cloud Providers
| Cloud Provider | Kubernetes Service | Guide |
|-----------------------------|---------------------------------|----------------------------------------------|
| Minikube (on AWS EC2) | Minikube | [Minikube AWS Guide](kubernetes_minikube.md) |
| Google Cloud Platform (GCP) | Google Container Engine (GKE) | [GCP GKE Guide](kubernetes_gcp.md) |
| Amazon Web Services (AWS) | Elastic Container Service (EKS) | [AWS EKS Guide](kubernetes_aws.md) |
| Digital Ocean (DO) | DO Kubernetes (DOK) | [DO DOK Guide](kubernetes_dok.md) |

4
assets/fonts/font-awesome.css vendored

File diff suppressed because one or more lines are too long

13
assets/fonts/material-icons.css

@ -1,13 +0,0 @@
/*!
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
* DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
* SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
* LIMITATIONS UNDER THE LICENSE.
*/@font-face{font-family:"Material Icons";font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url("specimen/MaterialIcons-Regular.woff2") format("woff2"),url("specimen/MaterialIcons-Regular.woff") format("woff"),url("specimen/MaterialIcons-Regular.ttf") format("truetype")}

BIN
assets/fonts/specimen/FontAwesome.ttf

Binary file not shown.

BIN
assets/fonts/specimen/FontAwesome.woff

Binary file not shown.

BIN
assets/fonts/specimen/FontAwesome.woff2

Binary file not shown.

BIN
assets/fonts/specimen/MaterialIcons-Regular.ttf

Binary file not shown.

BIN
assets/fonts/specimen/MaterialIcons-Regular.woff

Binary file not shown.

BIN
assets/fonts/specimen/MaterialIcons-Regular.woff2

Binary file not shown.

BIN
assets/images/favicon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 521 B

20
assets/images/icons/bitbucket.1b09e088.svg

@ -1,20 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="352" height="448"
viewBox="0 0 352 448" id="__bitbucket">
<path fill="currentColor" d="M203.75 214.75q2 15.75-12.625 25.25t-27.875
1.5q-9.75-4.25-13.375-14.5t-0.125-20.5 13-14.5q9-4.5 18.125-3t16 8.875
6.875 16.875zM231.5 209.5q-3.5-26.75-28.25-41t-49.25-3.25q-15.75
7-25.125 22.125t-8.625 32.375q1 22.75 19.375 38.75t41.375 14q22.75-2
38-21t12.5-42zM291.25
74q-5-6.75-14-11.125t-14.5-5.5-17.75-3.125q-72.75-11.75-141.5 0.5-10.75
1.75-16.5 3t-13.75 5.5-12.5 10.75q7.5 7 19 11.375t18.375 5.5 21.875
2.875q57 7.25 112 0.25 15.75-2 22.375-3t18.125-5.375 18.75-11.625zM305.5
332.75q-2 6.5-3.875 19.125t-3.5 21-7.125 17.5-14.5 14.125q-21.5
12-47.375 17.875t-50.5 5.5-50.375-4.625q-11.5-2-20.375-4.5t-19.125-6.75-18.25-10.875-13-15.375q-6.25-24-14.25-73l1.5-4
4.5-2.25q55.75 37 126.625 37t126.875-37q5.25 1.5 6 5.75t-1.25 11.25-2
9.25zM350.75 92.5q-6.5 41.75-27.75 163.75-1.25 7.5-6.75 14t-10.875
10-13.625 7.75q-63 31.5-152.5
22-62-6.75-98.5-34.75-3.75-3-6.375-6.625t-4.25-8.75-2.25-8.5-1.5-9.875-1.375-8.75q-2.25-12.5-6.625-37.5t-7-40.375-5.875-36.875-5.5-39.5q0.75-6.5
4.375-12.125t7.875-9.375 11.25-7.5 11.5-5.625 12-4.625q31.25-11.5
78.25-16 94.75-9.25 169 12.5 38.75 11.5 53.75 30.5 4 5 4.125
12.75t-1.375 13.5z" />
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

18
assets/images/icons/github.f0b8504a.svg

@ -1,18 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

38
assets/images/icons/gitlab.6dd19c00.svg

@ -1,38 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500"
viewBox="0 0 500 500" id="__gitlab">
<g transform="translate(156.197863, 1.160267)">
<path fill="currentColor"
d="M93.667,473.347L93.667,473.347l90.684-279.097H2.983L93.667,
473.347L93.667,473.347z" />
</g>
<g transform="translate(28.531199, 1.160800)" opacity="0.7">
<path fill="currentColor"
d="M221.333,473.345L130.649,194.25H3.557L221.333,473.345L221.333,
473.345z" />
</g>
<g transform="translate(0.088533, 0.255867)" opacity="0.5">
<path fill="currentColor"
d="M32,195.155L32,195.155L4.441,279.97c-2.513,7.735,0.24,16.21,6.821,
20.99l238.514,173.29 L32,195.155L32,195.155z" />
</g>
<g transform="translate(29.421866, 280.255593)">
<path fill="currentColor"
d="M2.667-84.844h127.092L75.14-252.942c-2.811-8.649-15.047-8.649-17.856,
0L2.667-84.844 L2.667-84.844z" />
</g>
<g transform="translate(247.197860, 1.160800)" opacity="0.7">
<path fill="currentColor"
d="M2.667,473.345L93.351,194.25h127.092L2.667,473.345L2.667,
473.345z" />
</g>
<g transform="translate(246.307061, 0.255867)" opacity="0.5">
<path fill="currentColor"
d="M221.334,195.155L221.334,195.155l27.559,84.815c2.514,7.735-0.24,
16.21-6.821,20.99 L3.557,474.25L221.334,195.155L221.334,195.155z" />
</g>
<g transform="translate(336.973725, 280.255593)">
<path fill="currentColor"
d="M130.667-84.844H3.575l54.618-168.098c2.811-8.649,15.047-8.649,
17.856,0L130.667-84.844 L130.667-84.844z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

1
assets/javascripts/application.e72fd936.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.da.js

@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,i,n;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=(r=e.stemmerSupport.Among,i=e.stemmerSupport.SnowballProgram,n=new function(){var e,n,t,s=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],o=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new i;function l(){var e,r=c.limit-c.cursor;c.cursor>=n&&(e=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var r,i=c.cursor;return function(){var r,i=c.cursor+3;if(n=c.limit,0<=i&&i<=c.limit){for(e=i;;){if(r=c.cursor,c.in_grouping(d,97,248)){c.cursor=r;break}if(c.cursor=r,r>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(n=c.cursor)<e&&(n=e)}}(),c.limit_backward=i,c.cursor=c.limit,function(){var e,r;if(c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,t=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig")&&c.slice_del()),c.cursor=c.limit-t,c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from("løs")}}(),c.cursor=c.limit,c.cursor>=n&&(r=c.limit_backward,c.limit_backward=n,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,t=c.slice_to(t),c.limit_backward=r,c.eq_v_b(t)&&c.slice_del()):c.limit_backward=r),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}});

1
assets/javascripts/lunr/lunr.de.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.du.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.es.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.fi.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.fr.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.hu.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.it.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.jp.js

@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r="2"==e.version[0];e.jp=function(){this.pipeline.reset(),this.pipeline.add(e.jp.stopWordFilter,e.jp.stemmer),r?this.tokenizer=e.jp.tokenizer:(e.tokenizer&&(e.tokenizer=e.jp.tokenizer),this.tokenizerFn&&(this.tokenizerFn=e.jp.tokenizer))};var t=new e.TinySegmenter;e.jp.tokenizer=function(n){if(!arguments.length||null==n||null==n)return[];if(Array.isArray(n))return n.map(function(t){return r?new e.Token(t.toLowerCase()):t.toLowerCase()});for(var i=n.toString().toLowerCase().replace(/^\s+/,""),o=i.length-1;o>=0;o--)if(/\S/.test(i.charAt(o))){i=i.substring(0,o+1);break}return t.segment(i).filter(function(e){return!!e}).map(function(t){return r?new e.Token(t):t})},e.jp.stemmer=function(e){return e},e.Pipeline.registerFunction(e.jp.stemmer,"stemmer-jp"),e.jp.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",e.jp.stopWordFilter=function(t){if(-1===e.jp.stopWordFilter.stopWords.indexOf(r?t.toString():t))return t},e.jp.stopWordFilter=e.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),e.Pipeline.registerFunction(e.jp.stopWordFilter,"stopWordFilter-jp")}});

1
assets/javascripts/lunr/lunr.multi.js

@ -1 +0,0 @@
!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){e.multiLanguage=function(){for(var i=Array.prototype.slice.call(arguments),t=i.join("-"),r="",n=[],s=[],p=0;p<i.length;++p)"en"==i[p]?(r+="\\w",n.unshift(e.stopWordFilter),n.push(e.stemmer),s.push(e.stemmer)):(r+=e[i[p]].wordCharacters,n.unshift(e[i[p]].stopWordFilter),n.push(e[i[p]].stemmer),s.push(e[i[p]].stemmer));var o=e.trimmerSupport.generateTrimmer(r);return e.Pipeline.registerFunction(o,"lunr-multi-trimmer-"+t),n.unshift(o),function(){this.pipeline.reset(),this.pipeline.add.apply(this.pipeline,n),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add.apply(this.searchPipeline,s))}}}});

1
assets/javascripts/lunr/lunr.no.js

@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,i;e.no=function(){this.pipeline.reset(),this.pipeline.add(e.no.trimmer,e.no.stopWordFilter,e.no.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.no.stemmer))},e.no.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.no.trimmer=e.trimmerSupport.generateTrimmer(e.no.wordCharacters),e.Pipeline.registerFunction(e.no.trimmer,"trimmer-no"),e.no.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,i=new function(){var e,i,t=[new r("a",-1,1),new r("e",-1,1),new r("ede",1,1),new r("ande",1,1),new r("ende",1,1),new r("ane",1,1),new r("ene",1,1),new r("hetene",6,1),new r("erte",1,3),new r("en",-1,1),new r("heten",9,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",12,1),new r("s",-1,2),new r("as",14,1),new r("es",14,1),new r("edes",16,1),new r("endes",16,1),new r("enes",16,1),new r("hetenes",19,1),new r("ens",14,1),new r("hetens",21,1),new r("ers",14,1),new r("ets",14,1),new r("et",-1,1),new r("het",25,1),new r("ert",-1,3),new r("ast",-1,1)],o=[new r("dt",-1,-1),new r("vt",-1,-1)],s=[new r("leg",-1,1),new r("eleg",0,1),new r("ig",-1,1),new r("eig",2,1),new r("lig",2,1),new r("elig",4,1),new r("els",-1,1),new r("lov",-1,1),new r("elov",7,1),new r("slov",7,1),new r("hetslov",9,1)],a=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],m=[119,125,149,1],l=new n;this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var r,n,u,d,c=l.cursor;return function(){var r,n=l.cursor+3;if(i=l.limit,0<=n||n<=l.limit){for(e=n;;){if(r=l.cursor,l.in_grouping(a,97,248)){l.cursor=r;break}if(r>=l.limit)return;l.cursor=r+1}for(;!l.out_grouping(a,97,248);){if(l.cursor>=l.limit)return;l.cursor++}(i=l.cursor)<e&&(i=e)}}(),l.limit_backward=c,l.cursor=l.limit,function(){var e,r,n;if(l.cursor>=i&&(r=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,e=l.find_among_b(t,29),l.limit_backward=r,e))switch(l.bra=l.cursor,e){case 1:l.slice_del();break;case 2:n=l.limit-l.cursor,l.in_grouping_b(m,98,122)?l.slice_del():(l.cursor=l.limit-n,l.eq_s_b(1,"k")&&l.out_grouping_b(a,97,248)&&l.slice_del());break;case 3:l.slice_from("er")}}(),l.cursor=l.limit,n=l.limit-l.cursor,l.cursor>=i&&(r=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,l.find_among_b(o,2)?(l.bra=l.cursor,l.limit_backward=r,l.cursor=l.limit-n,l.cursor>l.limit_backward&&(l.cursor--,l.bra=l.cursor,l.slice_del())):l.limit_backward=r),l.cursor=l.limit,l.cursor>=i&&(d=l.limit_backward,l.limit_backward=i,l.ket=l.cursor,(u=l.find_among_b(s,11))?(l.bra=l.cursor,l.limit_backward=d,1==u&&l.slice_del()):l.limit_backward=d),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}});

1
assets/javascripts/lunr/lunr.pt.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.ro.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.ru.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/lunr.stemmer.support.js

@ -1 +0,0 @@
!function(r,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():t()(r.lunr)}(this,function(){return function(r){r.stemmerSupport={Among:function(r,t,i,s){if(this.toCharArray=function(r){for(var t=r.length,i=new Array(t),s=0;s<t;s++)i[s]=r.charCodeAt(s);return i},!r&&""!=r||!t&&0!=t||!i)throw"Bad Among initialisation: s:"+r+", substring_i: "+t+", result: "+i;this.s_size=r.length,this.s=this.toCharArray(r),this.substring_i=t,this.result=i,this.method=s},SnowballProgram:function(){var r;return{bra:0,ket:0,limit:0,cursor:0,limit_backward:0,setCurrent:function(t){r=t,this.cursor=0,this.limit=t.length,this.limit_backward=0,this.bra=this.cursor,this.ket=this.limit},getCurrent:function(){var t=r;return r=null,t},in_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e<=s&&e>=i&&t[(e-=i)>>3]&1<<(7&e))return this.cursor++,!0}return!1},in_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e<=s&&e>=i&&t[(e-=i)>>3]&1<<(7&e))return this.cursor--,!0}return!1},out_grouping:function(t,i,s){if(this.cursor<this.limit){var e=r.charCodeAt(this.cursor);if(e>s||e<i)return this.cursor++,!0;if(!(t[(e-=i)>>3]&1<<(7&e)))return this.cursor++,!0}return!1},out_grouping_b:function(t,i,s){if(this.cursor>this.limit_backward){var e=r.charCodeAt(this.cursor-1);if(e>s||e<i)return this.cursor--,!0;if(!(t[(e-=i)>>3]&1<<(7&e)))return this.cursor--,!0}return!1},eq_s:function(t,i){if(this.limit-this.cursor<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor+s)!=i.charCodeAt(s))return!1;return this.cursor+=t,!0},eq_s_b:function(t,i){if(this.cursor-this.limit_backward<t)return!1;for(var s=0;s<t;s++)if(r.charCodeAt(this.cursor-t+s)!=i.charCodeAt(s))return!1;return this.cursor-=t,!0},find_among:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=t[a],m=l;m<_.s_size;m++){if(n+l==u){f=-1;break}if(f=r.charCodeAt(n+l)-_.s[m])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){if(o>=(_=t[s]).s_size){if(this.cursor=n+_.s_size,!_.method)return _.result;var b=_.method();if(this.cursor=n+_.s_size,b)return _.result}if((s=_.substring_i)<0)return 0}},find_among_b:function(t,i){for(var s=0,e=i,n=this.cursor,u=this.limit_backward,o=0,h=0,c=!1;;){for(var a=s+(e-s>>1),f=0,l=o<h?o:h,_=(m=t[a]).s_size-1-l;_>=0;_--){if(n-l==u){f=-1;break}if(f=r.charCodeAt(n-1-l)-m.s[_])break;l++}if(f<0?(e=a,h=l):(s=a,o=l),e-s<=1){if(s>0||e==s||c)break;c=!0}}for(;;){var m;if(o>=(m=t[s]).s_size){if(this.cursor=n-m.s_size,!m.method)return m.result;var b=m.method();if(this.cursor=n-m.s_size,b)return m.result}if((s=m.substring_i)<0)return 0}},replace_s:function(t,i,s){var e=s.length-(i-t),n=r.substring(0,t),u=r.substring(i);return r=n+s+u,this.limit+=e,this.cursor>=i?this.cursor+=e:this.cursor>t&&(this.cursor=t),e},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>r.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),r.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}});

1
assets/javascripts/lunr/lunr.sv.js

@ -1 +0,0 @@
!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,n,t;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=(r=e.stemmerSupport.Among,n=e.stemmerSupport.SnowballProgram,t=new function(){var e,t,i=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],s=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new n;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var r,n=m.cursor;return function(){var r,n=m.cursor+3;if(t=m.limit,0<=n||n<=m.limit){for(e=n;;){if(r=m.cursor,m.in_grouping(o,97,246)){m.cursor=r;break}if(m.cursor=r,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)<e&&(t=e)}}(),m.limit_backward=n,m.cursor=m.limit,function(){var e,r=m.limit_backward;if(m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,r=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=r),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from("lös");break;case 3:m.slice_from("full")}m.limit_backward=r}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return t.setCurrent(e),t.stem(),t.getCurrent()}):(t.setCurrent(e),t.stem(),t.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}});

1
assets/javascripts/lunr/lunr.tr.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/lunr/tinyseg.js

File diff suppressed because one or more lines are too long

1
assets/javascripts/modernizr.1aa3b519.js

File diff suppressed because one or more lines are too long

1176
assets/stylesheets/application-palette.22915126.css

File diff suppressed because it is too large Load Diff

2552
assets/stylesheets/application.451f80e5.css

File diff suppressed because it is too large Load Diff

2
cli/__init__.py

@ -0,0 +1,2 @@
_program = "byok8s"
__version__ = "0.1.0"

156
cli/command.py

@ -0,0 +1,156 @@
"""
Command line interface driver for snakemake workflows
"""
import argparse
import os.path
import snakemake
import sys
import pprint
import json
import subprocess
from . import _program
thisdir = os.path.abspath(os.path.dirname(__file__))
cwd = os.getcwd()
def main(sysargs = sys.argv[1:]):
descr = ''
usg = '''byok8s [--FLAGS] <workflowfile> <paramsfile> [<target>]
byok8s: run snakemake workflows on your own kubernetes
cluster, using the given workflow name & parameters file.
byok8s requires an S3 bucket be used for file I/O. Set
AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY env vars.
'''
parser = argparse.ArgumentParser(
prog = _program,
description=descr,
usage = usg
)
parser.add_argument('workflowfile')
parser.add_argument('paramsfile')
parser.add_argument('-k', '--k8s-namespace',default='default', help='Namespace of Kubernetes cluster, if not "default"')
parser.add_argument('-s', '--snakefile', default='Snakefile', help='Relative path to Snakemake Snakefile, if not "Snakefile"')
parser.add_argument('-b', '--s3-bucket', help='Name of S3 bucket to use for Snakemake file I/O (REQUIRED)')
parser.add_argument('-n', '--dry-run', action='store_true', help='Do a dry run of the workflow commands (no commands executed)')
parser.add_argument('-f', '--force', action='store_true', help='Force Snakemake rules to be re-run')
# NOTE: You MUST use S3 buckets, GCS buckets are not supported.
# That's because GCP requires credentials to be stored in a file,
# and we can only pass environment variables into k8s containers.
args = parser.parse_args(sysargs)
# find the Snakefile
s1 = os.path.join(cwd,args.snakefile)
if os.path.isfile(s1):
# user has provided a relative path
# to a Snakefile. top priority.
snakefile = os.path.join(cwd,args.snakefile)
else:
msg = 'Error: cannot find Snakefile at {}\n'.format(s1)
sys.stderr.write(msg)
sys.exit(-1)
# find the workflow config file
w1 = os.path.join(cwd,args.workflowfile)
w2 = os.path.join(cwd,args.workflowfile+'.json')
# TODO: yaml
if os.path.isfile(w1):
# user has provided the full filename
workflowfile = w1
elif os.path.isfile(w2):
# user has provided the prefix of the
# json filename
workflowfile = w2
else:
msg = ['Error: cannot find workflowfile (workflow configuration file) at any of the following locations:\n']
msg += ['{}'.format(j) for j in [w1,w2]]
sys.stderr.write(msg)
sys.exit(-1)
# find the workflow params file
p1 = os.path.join(cwd,args.paramsfile)
p2 = os.path.join(cwd,args.paramsfile+'.json')
# TODO: yaml
if os.path.isfile(p1):
paramsfile = p1
elif os.path.isfile(p2):
paramsfile = p2
else:
msg = ['Error: cannot find paramsfile (workflow parameters file) at any of the following locations:\n']
msg += ['{}'.format(j) for j in [p1,p2]]
sys.stderr.write(msg)
sys.exit(-1)
with open(paramsfile,'r') as f:
config = json.load(f)
with open(workflowfile, 'r') as fp:
workflow_info = json.load(fp)
# get the kubernetes namespace
kube_ns = 'default'
if args.k8s_namespace is not None and len(args.k8s_namespace)>0:
kube_ns = args.k8s_namespace
# verify the user has set the AWS env variables
if not (os.environ['AWS_ACCESS_KEY_ID'] and os.environ['AWS_SECRET_ACCESS_KEY']):
msg = 'Error: the environment variables AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be set to allow the k8s cluster to access an S3 bucket for i/o.'
sys.stderr.write(msg)
sys.exit(-1)
# verify the user has provided a bucket name
if not args.s3_bucket:
msg = 'Error: no S3 bucket specified with --s3-bucket. This must be set to allow the k8s cluster to access an S3 bucket for i/o.'
sys.stderr.write(msg)
sys.exit(-1)
else:
mah_bukkit = args.s3_bucket
target = workflow_info['workflow_target']
print('--------')
print('details!')
print('\tsnakefile: {}'.format(snakefile))
print('\tconfig: {}'.format(workflowfile))
print('\tparams: {}'.format(paramsfile))
print('\ttarget: {}'.format(target))
print('\tk8s namespace: {}'.format(kube_ns))
print('--------')
# Note: we comment out configfile=paramsfile below,
# because we have problems passing files into k8s clusters.
# run byok8s!!
status = snakemake.snakemake(snakefile,
#configfile=paramsfile,
assume_shared_fs=False,
default_remote_provider='S3',
default_remote_prefix=mah_bukkit,
kubernetes_envvars=['AWS_ACCESS_KEY_ID','AWS_SECRET_ACCESS_KEY'],
targets=[target],
printshellcmds=True,
verbose = True,
dryrun=args.dry_run,
forceall=args.force,
kubernetes=kube_ns,
config=config)
if status: # translate "success" into shell exit code of 0
return 0
return 1
if __name__ == '__main__':
main()

576
index.html

@ -1,576 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://charlesreid1.github.io/2019-snakemake-byok8s/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching pages">
<meta name="lang:search.result.one" content="1 matching page">
<meta name="lang:search.result.other" content="# matching page">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href=".">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.3">
<title>2019-snakemake-byok8s</title>
<link rel="stylesheet" href="assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#2196f3">
<script src="assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="assets/fonts/material-icons.css">
<link rel="stylesheet" href="css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="blue">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#2019-snakemake-byok8s" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-header-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
2019-snakemake-byok8s
</span>
<span class="md-header-nav__topic">
Index
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search this site" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching this site
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
2019-snakemake-byok8s
</label>
<div class="md-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<a href="." title="Index" class="md-nav__link md-nav__link--active">
Index
</a>
</li>
<li class="md-nav__item">
<a href="kubernetes_minikube/" title="K8s with Minikube" class="md-nav__link">
K8s with Minikube
</a>
</li>
<li class="md-nav__item">
<a href="kubernetes_aws/" title="K8s with AWS" class="md-nav__link">
K8s with AWS
</a>
</li>
<li class="md-nav__item">
<a href="kubernetes_gcp/" title="K8s with GCP" class="md-nav__link">
K8s with GCP
</a>
</li>
<li class="md-nav__item">
<a href="kubernetes_dok/" title="K8s with DigitalOcean" class="md-nav__link">
K8s with DigitalOcean
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="2019-snakemake-byok8s">2019-snakemake-byok8s<a class="headerlink" href="#2019-snakemake-byok8s" title="Permanent link">&para;</a></h1>
<p><a href="https://travis-ci.org/charlesreid1/2019-snakemake-byok8s"><img alt="travis" src="https://img.shields.io/travis/charlesreid1/2019-snakemake-byok8s.svg" /></a>
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s/blob/master/LICENSE"><img alt="license" src="https://img.shields.io/github/license/charlesreid1/2019-snakemake-byok8s.svg" /></a></p>
<h1 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h1>
<p>This is an example of a Snakemake workflow that:</p>
<ul>
<li>is a command line utility</li>
<li>is bundled as a Python package</li>
<li>is designed to run on a Kubernetes cluster</li>
<li>can be tested locally or with Travis CI using minikube</li>
</ul>
<p>Snakemake functionality is provided through
a command line tool called <code>byok8s</code>, so that
it allows you to do this (abbreviated for clarity):</p>
<pre class="codehilite"><code># Create virtual k8s cluster
minikube start
# Run the workflow
byok8s --s3-bucket=mah-s3-bukkit my-workflowfile my-paramsfile
# Clean up the virtual k8s cluster
minikube stop</code></pre>
<p>Snakemake workflows are provided via a Snakefile by
the user. Snakemake runs tasks on the Kubernetes (k8s)
cluster. The approach is for the user to provide
their own Kubernetes cluster (byok8s = Bring Your
Own Kubernetes).</p>
<p>The example above uses <a href="https://github.com/kubernetes/minikube"><code>minikube</code></a>
to make a virtual k8s cluster, useful for testing.</p>
<p>For real workflows, your options for
kubernetes clusters are cloud providers:</p>
<ul>
<li>AWS EKS (Elastic Container Service)</li>
<li>GCP GKE (Google Kuberntes Engine)</li>
<li>Digital Ocean Kubernetes service</li>
<li>etc...</li>
</ul>
<p>The Travis CI tests utilize minikube to run
test workflows.</p>
<h1 id="quickstart">Quickstart<a class="headerlink" href="#quickstart" title="Permanent link">&para;</a></h1>
<p>This runs through the installation and usage
of <code>2019-snakemake-byok8s</code>.</p>
<p>Step 1: Set up Kubernetes cluster with <code>minikube</code>.</p>
<p>Step 2: Install <code>byok8s</code>.</p>
<p>Step 3: Run the <code>byok8s</code> workflow using the Kubernetes cluster. </p>
<p>Step 4: Tear down Kubernetes cluster with <code>minikube</code>.</p>
<h2 id="step-1-set-up-virtual-kubernetes-cluster">Step 1: Set Up Virtual Kubernetes Cluster<a class="headerlink" href="#step-1-set-up-virtual-kubernetes-cluster" title="Permanent link">&para;</a></h2>
<p>For the purposes of the quickstart, we will walk
through how to set up a local, virtual Kubernetes
cluster using <code>minikube</code>.</p>
<p>Start by installing minikube:</p>
<pre class="codehilite"><code>scripts/install_minikube.sh</code></pre>
<p>Once it is installed, you can start up a kubernetes cluster
with minikube using the following commands:</p>
<pre class="codehilite"><code>cd test
minikube start</code></pre>
<p>NOTE: If you are running on AWS, run this command first</p>
<pre class="codehilite"><code>minikube config set vm-driver none</code></pre>
<p>to set the the vm driver to none and use native Docker to run stuff.</p>
<p>If you are running on AWS, the DNS in the minikube
kubernetes cluster will not work, so run this command
to fix the DNS settings (should be run from the
<code>test/</code> directory):</p>
<pre class="codehilite"><code>kubectl apply -f fixcoredns.yml
kubectl delete --all pods --namespace kube-system</code></pre>
<h2 id="step-2-install-byok8s">Step 2: Install byok8s<a class="headerlink" href="#step-2-install-byok8s" title="Permanent link">&para;</a></h2>
<p>Start by setting up a python virtual environment,
and install the required packages into the
virtual environment:</p>
<pre class="codehilite"><code>pip install -r requirements.txt</code></pre>
<p>This installs snakemake and kubernetes Python
modules. Now install the <code>byok8s</code> command line
tool:</p>
<pre class="codehilite"><code>python setup.py build install</code></pre>
<p>Now you can run:</p>
<pre class="codehilite"><code>which byok8s</code></pre>
<p>and you should see <code>byok8s</code> in your virtual
environment's <code>bin/</code> directory.</p>
<p>This command line utility will expect a kubernetes
cluster to be set up before it is run. </p>
<p>Setting up a kubernetes cluster will create...
(fill in more info here)...</p>
<p>Snakemake will automatically create the pods
in the cluster, so you just need to allocate
a kubernetes cluster.</p>
<h2 id="step-3-run-byok8s">Step 3: Run byok8s<a class="headerlink" href="#step-3-run-byok8s" title="Permanent link">&para;</a></h2>
<p>Now you can run the workflow with the <code>byok8s</code> command.
This submits the Snakemake workflow jobs to the Kubernetes
cluster that minikube created.</p>
<p>You should have your workflow in a <code>Snakefile</code> in the
current directory. Use the <code>--snakefile</code> flag if it is
named something other than <code>Snakefile</code>.</p>
<p>You will also need to specify your AWS credentials
via the <code>AWS_ACCESS_KEY_ID</code> and <code>AWS_SECRET_ACCESS_KEY</code>
environment variables. These are used to to access
S3 buckets for file I/O.</p>
<p>Finally, you will need to create an S3 bucket for
Snakemake to use for file I/O. Pass the name of the
bucket using the <code>--s3-bucket</code> flag.</p>
<p>Start by exporting these two vars (careful to
scrub them from bash history):</p>
<pre class="codehilite"><code>export AWS_ACCESS_KEY_ID=XXXXX
export AWS_SECRET_ACCESS_KEY=XXXXX</code></pre>
<p>Run the alpha workflow with blue params:</p>
<pre class="codehilite"><code>byok8s --s3-bucket=mah-bukkit workflow-alpha params-blue</code></pre>
<p>Run the alpha workflow with red params:</p>
<pre class="codehilite"><code>byok8s --s3-bucket=mah-bukkit workflow-alpha params-red</code></pre>
<p>Run the gamma workflow with red params, &amp;c:</p>
<pre class="codehilite"><code>byok8s --s3-bucket=mah-bukkit workflow-gamma params-red</code></pre>
<p>(NOTE: May want to let the user specify
input and output directories with flags.)</p>
<p>All input files are searched for relative to the working
directory.</p>
<h2 id="step-4-tear-down-kubernetes-cluster">Step 4: Tear Down Kubernetes Cluster<a class="headerlink" href="#step-4-tear-down-kubernetes-cluster" title="Permanent link">&para;</a></h2>
<p>The last step once the workflow has been finished,
is to tear down the kubernetes cluster. The virtual
kubernetes cluster created by minikube can be torn
down with the following command:</p>
<pre class="codehilite"><code>minikube stop</code></pre>
<h1 id="using-kubernetes-with-cloud-providers">Using Kubernetes with Cloud Providers<a class="headerlink" href="#using-kubernetes-with-cloud-providers" title="Permanent link">&para;</a></h1>
<table>
<thead>
<tr>
<th>Cloud Provider</th>
<th>Kubernetes Service</th>
<th>Guide</th>
</tr>
</thead>
<tbody>
<tr>
<td>Minikube (on AWS EC2)</td>
<td>Minikube</td>
<td><a href="kubernetes_minikube/">Minikube AWS Guide</a></td>
</tr>
<tr>
<td>Google Cloud Platform (GCP)</td>
<td>Google Container Engine (GKE)</td>
<td><a href="kubernetes_gcp/">GCP GKE Guide</a></td>
</tr>
<tr>
<td>Amazon Web Services (AWS)</td>
<td>Elastic Container Service (EKS)</td>
<td><a href="kubernetes_aws/">AWS EKS Guide</a></td>
</tr>
<tr>
<td>Digital Ocean (DO)</td>
<td>DO Kubernetes (DOK)</td>
<td><a href="kubernetes_dok/">DO DOK Guide</a></td>
</tr>
</tbody>
</table>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="kubernetes_minikube/" title="K8s with Minikube" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
K8s with Minikube
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT license</a>
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:"."}})</script>
<script src="search/main.js"></script>
</body>
</html>

6
kubernetes_aws.md

@ -0,0 +1,6 @@
# Kubernetes on AWS
## Elastic Container Service
## Quickstart

475
kubernetes_aws/index.html

@ -1,475 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_aws/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching pages">
<meta name="lang:search.result.one" content="1 matching page">
<meta name="lang:search.result.other" content="# matching page">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.3">
<title>K8s with AWS - 2019-snakemake-byok8s</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#2196f3">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="blue">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#kubernetes-on-aws" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-header-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
2019-snakemake-byok8s
</span>
<span class="md-header-nav__topic">
K8s with AWS
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search this site" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching this site
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
2019-snakemake-byok8s
</label>
<div class="md-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Index" class="md-nav__link">
Index
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_minikube/" title="K8s with Minikube" class="md-nav__link">
K8s with Minikube
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
K8s with AWS
</label>
<a href="./" title="K8s with AWS" class="md-nav__link md-nav__link--active">
K8s with AWS
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#elastic-container-service" title="Elastic Container Service" class="md-nav__link">
Elastic Container Service
</a>
</li>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../kubernetes_gcp/" title="K8s with GCP" class="md-nav__link">
K8s with GCP
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_dok/" title="K8s with DigitalOcean" class="md-nav__link">
K8s with DigitalOcean
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#elastic-container-service" title="Elastic Container Service" class="md-nav__link">
Elastic Container Service
</a>
</li>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="kubernetes-on-aws">Kubernetes on AWS<a class="headerlink" href="#kubernetes-on-aws" title="Permanent link">&para;</a></h1>
<h2 id="elastic-container-service">Elastic Container Service<a class="headerlink" href="#elastic-container-service" title="Permanent link">&para;</a></h2>
<h2 id="quickstart">Quickstart<a class="headerlink" href="#quickstart" title="Permanent link">&para;</a></h2>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../kubernetes_minikube/" title="K8s with Minikube" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
K8s with Minikube
</span>
</div>
</a>
<a href="../kubernetes_gcp/" title="K8s with GCP" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
K8s with GCP
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT license</a>
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

11
kubernetes_dok.md

@ -0,0 +1,11 @@
# Kubernetes on Digital Ocean
## Digital Ocean Kubernetes
(Use web interface to set up a Kubernetes cluster,
then use `kubectl` to connect with Digital Ocean
via Digital Ocean credentials.)
## Quickstart
[link](https://www.digitalocean.com/docs/kubernetes/how-to/connect-with-kubectl/)

465
kubernetes_dok/index.html

@ -1,465 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_dok/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching pages">
<meta name="lang:search.result.one" content="1 matching page">
<meta name="lang:search.result.other" content="# matching page">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.3">
<title>K8s with DigitalOcean - 2019-snakemake-byok8s</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#2196f3">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="blue">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#kubernetes-on-digital-ocean" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-header-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
2019-snakemake-byok8s
</span>
<span class="md-header-nav__topic">
K8s with DigitalOcean
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search this site" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching this site
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
2019-snakemake-byok8s
</label>
<div class="md-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Index" class="md-nav__link">
Index
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_minikube/" title="K8s with Minikube" class="md-nav__link">
K8s with Minikube
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_aws/" title="K8s with AWS" class="md-nav__link">
K8s with AWS
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_gcp/" title="K8s with GCP" class="md-nav__link">
K8s with GCP
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
K8s with DigitalOcean
</label>
<a href="./" title="K8s with DigitalOcean" class="md-nav__link md-nav__link--active">
K8s with DigitalOcean
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#digital-ocean-kubernetes" title="Digital Ocean Kubernetes" class="md-nav__link">
Digital Ocean Kubernetes
</a>
</li>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#digital-ocean-kubernetes" title="Digital Ocean Kubernetes" class="md-nav__link">
Digital Ocean Kubernetes
</a>
</li>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="kubernetes-on-digital-ocean">Kubernetes on Digital Ocean<a class="headerlink" href="#kubernetes-on-digital-ocean" title="Permanent link">&para;</a></h1>
<h2 id="digital-ocean-kubernetes">Digital Ocean Kubernetes<a class="headerlink" href="#digital-ocean-kubernetes" title="Permanent link">&para;</a></h2>
<p>(Use web interface to set up a Kubernetes cluster,
then use <code>kubectl</code> to connect with Digital Ocean
via Digital Ocean credentials.)</p>
<h2 id="quickstart">Quickstart<a class="headerlink" href="#quickstart" title="Permanent link">&para;</a></h2>
<p><a href="https://www.digitalocean.com/docs/kubernetes/how-to/connect-with-kubectl/">link</a></p>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../kubernetes_gcp/" title="K8s with GCP" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
K8s with GCP
</span>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT license</a>
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

7
kubernetes_gcp.md

@ -0,0 +1,7 @@
# Kubernetes on Google Cloud Platform
## Google Container Engine
## Quickstart

475
kubernetes_gcp/index.html

@ -1,475 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_gcp/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching pages">
<meta name="lang:search.result.one" content="1 matching page">
<meta name="lang:search.result.other" content="# matching page">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.3">
<title>K8s with GCP - 2019-snakemake-byok8s</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#2196f3">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="blue">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#kubernetes-on-google-cloud-platform" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-header-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
2019-snakemake-byok8s
</span>
<span class="md-header-nav__topic">
K8s with GCP
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search this site" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching this site
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
2019-snakemake-byok8s
</label>
<div class="md-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Index" class="md-nav__link">
Index
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_minikube/" title="K8s with Minikube" class="md-nav__link">
K8s with Minikube
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_aws/" title="K8s with AWS" class="md-nav__link">
K8s with AWS
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
K8s with GCP
</label>
<a href="./" title="K8s with GCP" class="md-nav__link md-nav__link--active">
K8s with GCP
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#google-container-engine" title="Google Container Engine" class="md-nav__link">
Google Container Engine
</a>
</li>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../kubernetes_dok/" title="K8s with DigitalOcean" class="md-nav__link">
K8s with DigitalOcean
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#google-container-engine" title="Google Container Engine" class="md-nav__link">
Google Container Engine
</a>
</li>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="kubernetes-on-google-cloud-platform">Kubernetes on Google Cloud Platform<a class="headerlink" href="#kubernetes-on-google-cloud-platform" title="Permanent link">&para;</a></h1>
<h2 id="google-container-engine">Google Container Engine<a class="headerlink" href="#google-container-engine" title="Permanent link">&para;</a></h2>
<h2 id="quickstart">Quickstart<a class="headerlink" href="#quickstart" title="Permanent link">&para;</a></h2>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../kubernetes_aws/" title="K8s with AWS" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
K8s with AWS
</span>
</div>
</a>
<a href="../kubernetes_dok/" title="K8s with DigitalOcean" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
K8s with DigitalOcean
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT license</a>
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

6
kubernetes_minikube.md

@ -0,0 +1,6 @@
# Minikube on AWS EC2 Nodes
## Quickstart

460
kubernetes_minikube/index.html

@ -1,460 +0,0 @@
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_minikube/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching pages">
<meta name="lang:search.result.one" content="1 matching page">
<meta name="lang:search.result.other" content="# matching page">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="..">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.3">
<title>K8s with Minikube - 2019-snakemake-byok8s</title>
<link rel="stylesheet" href="../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#2196f3">
<script src="../assets/javascripts/modernizr.1aa3b519.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../assets/fonts/material-icons.css">
<link rel="stylesheet" href="../css/custom.css">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="blue">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="../#minikube-on-aws-ec2-nodes" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-header-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
2019-snakemake-byok8s
</span>
<span class="md-header-nav__topic">
K8s with Minikube
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search this site" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching this site
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://charlesreid1.github.io/2019-snakemake-byok8s" title="2019-snakemake-byok8s" class="md-nav__button md-logo">
<i class="md-icon">dns</i>
</a>
2019-snakemake-byok8s
</label>
<div class="md-nav__source">
<a href="https://github.com/charlesreid1/2019-snakemake-byok8s" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__repository">
2019-snakemake-byok8s
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." title="Index" class="md-nav__link">
Index
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
K8s with Minikube
</label>
<a href="./" title="K8s with Minikube" class="md-nav__link md-nav__link--active">
K8s with Minikube
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../kubernetes_aws/" title="K8s with AWS" class="md-nav__link">
K8s with AWS
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_gcp/" title="K8s with GCP" class="md-nav__link">
K8s with GCP
</a>
</li>
<li class="md-nav__item">
<a href="../kubernetes_dok/" title="K8s with DigitalOcean" class="md-nav__link">
K8s with DigitalOcean
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#quickstart" title="Quickstart" class="md-nav__link">
Quickstart
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<h1 id="minikube-on-aws-ec2-nodes">Minikube on AWS EC2 Nodes<a class="headerlink" href="#minikube-on-aws-ec2-nodes" title="Permanent link">&para;</a></h1>
<h2 id="quickstart">Quickstart<a class="headerlink" href="#quickstart" title="Permanent link">&para;</a></h2>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href=".." title="Index" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Index
</span>
</div>
</a>
<a href="../kubernetes_aws/" title="K8s with AWS" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
K8s with AWS
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 <a href="https://charlesreid1.com">Charles Reid</a>, released under the <a href="https://opensource.org/licenses/MIT">MIT license</a>
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
</div>
</div>
</footer>
</div>
<script src="../assets/javascripts/application.e72fd936.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:".."}})</script>
<script src="../search/main.js"></script>
</body>
</html>

17
requirements-to-freeze.txt

@ -0,0 +1,17 @@
appdirs==1.4.3
certifi==2018.11.29
chardet==3.0.4
ConfigArgParse==0.14.0
datrie==0.7.1
docutils==0.14
gitdb2==2.0.5
GitPython==2.1.11
idna==2.8
jsonschema==2.6.0
PyYAML>=4.2b1
ratelimiter==1.2.0.post0
requests==2.21.0
smmap2==2.0.5
snakemake==5.4.0
urllib3==1.24.1
wrapt==1.11.0

4
requirements.txt

@ -0,0 +1,4 @@
snakemake>=5.4.0
kubernetes
moto
boto3

16
scripts/install_minikube.sh

@ -0,0 +1,16 @@
#!/bin/bash
#
# Install minikube
#
# https://github.com/kubernetes/minikube
if [[ "$OSTYPE" == "linux-gnu" ]]; then
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
&& sudo install minikube-linux-amd64 /usr/local/bin/minikube
elif [[ "$OSTYPE" == "darwin"* ]]; then
brew install kubernetes-cli
brew cask install minikube
else
echo "I pity the foo who use your operating system"
fi

2986
search/lunr.js

File diff suppressed because it is too large Load Diff

96
search/main.js

@ -1,96 +0,0 @@
function getSearchTermFromLocation() {
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == 'q') {
return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20'));
}
}
}
function joinUrl (base, path) {
if (path.substring(0, 1) === "/") {
// path starts with `/`. Thus it is absolute.
return path;
}
if (base.substring(base.length-1) === "/") {
// base ends with `/`
return base + path;
}
return base + "/" + path;
}
function formatResult (location, title, summary) {
return '<article><h3><a href="' + joinUrl(base_url, location) + '">'+ title + '</a></h3><p>' + summary +'</p></article>';
}
function displayResults (results) {
var search_results = document.getElementById("mkdocs-search-results");
while (search_results.firstChild) {
search_results.removeChild(search_results.firstChild);
}
if (results.length > 0){
for (var i=0; i < results.length; i++){
var result = results[i];
var html = formatResult(result.location, result.title, result.summary);
search_results.insertAdjacentHTML('beforeend', html);
}
} else {
search_results.insertAdjacentHTML('beforeend', "<p>No results found</p>");
}
}
function doSearch () {
var query = document.getElementById('mkdocs-search-query').value;
if (query.length > 2) {
if (!window.Worker) {
displayResults(search(query));
} else {
searchWorker.postMessage({query: query});
}
} else {
// Clear results for short queries
displayResults([]);
}
}
function initSearch () {
var search_input = document.getElementById('mkdocs-search-query');
if (search_input) {
search_input.addEventListener("keyup", doSearch);
}
var term = getSearchTermFromLocation();
if (term) {
search_input.value = term;
doSearch();
}
}
function onWorkerMessage (e) {
if (e.data.allowSearch) {
initSearch();
} else if (e.data.results) {
var results = e.data.results;
displayResults(results);
}
}
if (!window.Worker) {
console.log('Web Worker API not supported');
// load index in main thread
$.getScript(joinUrl(base_url, "search/worker.js")).done(function () {
console.log('Loaded worker');
init();
window.postMessage = function (msg) {
onWorkerMessage({data: msg});
};
}).fail(function (jqxhr, settings, exception) {
console.error('Could not load worker.js');
});
} else {
// Wrap search in a web worker
var searchWorker = new Worker(joinUrl(base_url, "search/worker.js"));
searchWorker.postMessage({init: true});
searchWorker.onmessage = onWorkerMessage;
}

1
search/search_index.json

File diff suppressed because one or more lines are too long

128
search/worker.js

@ -1,128 +0,0 @@
var base_path = 'function' === typeof importScripts ? '.' : '/search/';
var allowSearch = false;
var index;
var documents = {};
var lang = ['en'];
var data;
function getScript(script, callback) {
console.log('Loading script: ' + script);
$.getScript(base_path + script).done(function () {
callback();
}).fail(function (jqxhr, settings, exception) {
console.log('Error: ' + exception);
});
}
function getScriptsInOrder(scripts, callback) {
if (scripts.length === 0) {
callback();
return;
}
getScript(scripts[0], function() {
getScriptsInOrder(scripts.slice(1), callback);
});
}
function loadScripts(urls, callback) {
if( 'function' === typeof importScripts ) {
importScripts.apply(null, urls);
callback();
} else {
getScriptsInOrder(urls, callback);
}
}
function onJSONLoaded () {
data = JSON.parse(this.responseText);
var scriptsToLoad = ['lunr.js'];
if (data.config && data.config.lang && data.config.lang.length) {
lang = data.config.lang;
}
if (lang.length > 1 || lang[0] !== "en") {
scriptsToLoad.push('lunr.stemmer.support.js');
if (lang.length > 1) {
scriptsToLoad.push('lunr.multi.js');
}
for (var i=0; i < lang.length; i++) {
if (lang[i] != 'en') {
scriptsToLoad.push(['lunr', lang[i], 'js'].join('.'));
}
}
}
loadScripts(scriptsToLoad, onScriptsLoaded);
}
function onScriptsLoaded () {
console.log('All search scripts loaded, building Lunr index...');
if (data.config && data.config.separator && data.config.separator.length) {
lunr.tokenizer.separator = new RegExp(data.config.separator);
}
if (data.index) {
index = lunr.Index.load(data.index);
data.docs.forEach(function (doc) {
documents[doc.location] = doc;
});
console.log('Lunr pre-built index loaded, search ready');
} else {
index = lunr(function () {
if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
this.use(lunr[lang[0]]);
} else if (lang.length > 1) {
this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility
}
this.field('title');
this.field('text');
this.ref('location');
for (var i=0; i < data.docs.length; i++) {
var doc = data.docs[i];
this.add(doc);
documents[doc.location] = doc;
}
});
console.log('Lunr index built, search ready');
}
allowSearch = true;
postMessage({allowSearch: allowSearch});
}
function init () {
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", onJSONLoaded);
var index_path = base_path + '/search_index.json';
if( 'function' === typeof importScripts ){
index_path = 'search_index.json';
}
oReq.open("GET", index_path);
oReq.send();
}
function search (query) {
if (!allowSearch) {
console.error('Assets for search still loading');
return;
}
var resultDocuments = [];
var results = index.search(query);
for (var i=0; i < results.length; i++){
var result = results[i];
doc = documents[result.ref];
doc.summary = doc.text.substring(0, 200);
resultDocuments.push(doc);
}
return resultDocuments;
}
if( 'function' === typeof importScripts ) {
onmessage = function (e) {
if (e.data.init) {
init();
} else if (e.data.query) {
postMessage({ results: search(e.data.query) });
} else {
console.error("Worker - Unrecognized message: " + e);
}
};
}

29
setup.py

@ -0,0 +1,29 @@
from setuptools import setup, find_packages
import glob
import os
with open('requirements.txt') as f:
required = [x for x in f.read().splitlines() if not x.startswith("#")]
# Note: the _program variable is set in __init__.py.
# it determines the name of the package/final command line tool.
from cli import __version__, _program
setup(name='byok8s',
version=__version__,
packages=['cli'],
test_suite='pytest.collector',
tests_require=['pytest'],
description='byok8s command line interface',
url='https://charlesreid1.github.io/2019-snakemake-byok8s',
author='@charlesreid1',
author_email='cmreid@ucdavis.edu',
license='MIT',
entry_points="""
[console_scripts]
{program} = cli.command:main
""".format(program = _program),
install_requires=required,
include_package_data=True,
keywords=[],
zip_safe=False)

28
sitemap.xml

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://charlesreid1.github.io/2019-snakemake-byok8s/</loc>
<lastmod>2019-01-26</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_minikube/</loc>
<lastmod>2019-01-26</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_aws/</loc>
<lastmod>2019-01-26</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_gcp/</loc>
<lastmod>2019-01-26</lastmod>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://charlesreid1.github.io/2019-snakemake-byok8s/kubernetes_dok/</loc>
<lastmod>2019-01-26</lastmod>
<changefreq>daily</changefreq>
</url>
</urlset>

BIN
sitemap.xml.gz

Binary file not shown.

60
test/Readme.md

@ -0,0 +1,60 @@
# 2019-snakemake-byok8s tests
This guide assumes you have minikube installed. (See `../scripts/` directory...)
We will need to fix a problem with a DNS setting in Kubernetes if we are on
an AWS EC2 node, so we'll walk through how to do that first.
Then we'll cover how to start a Kubernetes cluster and run a simple test.
## Fix k8s DNS problem
If you are running on EC2, you will have
to fix the DNS settings inside the container
by patching the `kube-dns` container that
runs as part of Kubernetes.
Apply the DNS fix to the container,
```
kubernetes apply -f fixcoredns.yml
```
(If you are using an older version of minikube + kubernetes
that uses kube-dns, use `fixkubedns.yml` instead.)
## Start (restart) cluster
If you don't already have a Kubernetes cluster running,
start one with minikube:
```
minikube start
# or, if on ec2,
sudo minikube start
```
If you have a Kubernetes pod currently running,
you can delete all of the kube-system pods, and
they will automatically respawn, including the
(now-fixed) kube-dns container:
```
kubernetes delete --all pods --namespace kube-system
```
## Running tests
Now that DNS is fixed, the host and container can
properly communicate, which is required for Kubernetes
to return files it has created.

93
test/Snakefile

@ -0,0 +1,93 @@
name = config['name']
rule rulename1:
input:
"alpha.txt"
rule target1:
output:
"alpha.txt"
shell:
"echo alpha {name} > {output}"
rule target2:
output:
"gamma.txt"
shell:
"echo gamma {name} > {output}"
# A somewhat contrived workflow:
#
# zetaA workflow
#
# +---- (sleepy process) -- (sleepy process) -- (sleepy process) --+
# | |
# target3 <---+ +---<----
# | |
# +-----------( sleepy process ) ------ ( sleepy process ) --------+
#
# zetaB workflow
rule target3:
input:
"zetaA.txt", "zetaB.txt"
output:
"zeta.txt"
shell:
"cat {input[0]} {input[1]} > {output}"
rule target3sleepyA1:
output:
touch(".zetaA1")
shell:
"""
sleep 3s
echo zeta_A1 {name} > zetaA.txt
"""
rule target3sleepyA2:
input:
".zetaA1"
output:
touch(".zetaA2")
shell:
"""
sleep 3s
echo zeta_A2 {name} >> zetaA.txt
rm -f .zetaA1
"""
rule target3sleepyA3:
input:
".zetaA2"
output:
"zetaA.txt"
shell:
"""
sleep 3s
echo zeta_A3 {name} >> {output}
rm -f .zetaA2
"""
rule target3sleepyB1:
output:
touch(".zetaB1")
shell:
"""
sleep 4s
echo zeta_B1 {name} > zetaB.txt
"""
rule target3sleepyB2:
input:
".zetaB1"
output:
"zetaB.txt"
shell:
"""
sleep 4s
echo zeta_B2 {name} >> {output}
rm -f .zetaB1
"""

22
test/fixcoredns.yml

@ -0,0 +1,22 @@
kind: ConfigMap
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health
kubernetes cluster.local in-addr.arpa ip6.arpa {
upstream 8.8.8.8 8.8.4.4
pods insecure
fallthrough in-addr.arpa ip6.arpa
}
proxy . 8.8.8.8 8.8.4.4
cache 30
reload
}
metadata:
creationTimestamp: 2019-01-25T22:55:15Z
name: coredns
namespace: kube-system
#resourceVersion: "198"
#selfLink: /api/v1/namespaces/kube-system/configmaps/coredns

11
test/fixkubedns.yml

@ -0,0 +1,11 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: kube-dns
namespace: kube-system
labels:
addonmanager.kubernetes.io/mode: EnsureExists
data:
upstreamNameservers: |-
["8.8.8.8", "8.8.4.4"]

3
test/params-blue.json

@ -0,0 +1,3 @@
{
"name": "blue"
}

3
test/params-red.json

@ -0,0 +1,3 @@
{
"name": "red"
}

66
test/test_byok8s.py

@ -0,0 +1,66 @@
from unittest import TestCase
from subprocess import call, Popen, PIPE
import os
import shutil, tempfile
from os.path import isdir, join
"""
test byok8s
This tests the byok8s command line utility,
and assumes you have already set up your
k8s cluster using e.g. minikube.
"""
class TestByok8s(TestCase):
"""
simple byok8s test class
This uses the subprocess PIPE var
to capture system input and output,
since we are running byok8s from the
command line directly using subprocess.
"""
@classmethod
def setUpClass(self):
"""
set up a byok8s workflow test.
"""
# verify that a kubernetes cluster is running
pass
def test_alpha(self):
"""
test alpha workflow
"""
workflows = ['workflow-alpha','workflow-gamma','workflow-zeta']
params = ['params-red','params-blue']
pwd = os.path.abspath(os.path.dirname(__file__))
for workflow in workflows:
for param in params:
command = ['byok8s',workflow,param]
p = Popen(command, cwd=pwd, stdout=PIPE, stderr=PIPE).communicate()
p_out = p[0].decode('utf-8').strip()
p_err = p[1].decode('utf-8').strip()
self.assertIn('details',p_out)
# clean up
call(['rm','-f','*.txt'])
@classmethod
def tearDownClass(self):
"""
clean up after the tests
"""
pass

3
test/workflow-alpha.json

@ -0,0 +1,3 @@
{
"workflow_target": "target1"
}

3
test/workflow-gamma.json

@ -0,0 +1,3 @@
{
"workflow_target": "target2"
}

3
test/workflow-zeta.json

@ -0,0 +1,3 @@
{
"workflow_target": "target3"
}
Loading…
Cancel
Save