Compare commits
59 Commits
2016-05-17
...
2016-09-20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c745459c | ||
|
|
04dec2e196 | ||
|
|
0f8c189786 | ||
|
|
81cc14d47b | ||
|
|
060b2377d5 | ||
|
|
1e77736987 | ||
|
|
bf2b4b7eb7 | ||
|
|
8396f13a4a | ||
|
|
571097f369 | ||
|
|
b1110db8ca | ||
|
|
b73a628f05 | ||
|
|
a07795565d | ||
|
|
c4acbfd858 | ||
|
|
ddbda14e14 | ||
|
|
ad4ea8659b | ||
|
|
8d7f27d60d | ||
|
|
9f21c7279c | ||
|
|
53ae221632 | ||
|
|
6719bcda87 | ||
|
|
40e0c96c91 | ||
|
|
2c8664e58d | ||
|
|
1e5cee2456 | ||
|
|
29b8f53ae0 | ||
|
|
451f68db1d | ||
|
|
5a4d10ed1a | ||
|
|
06d5dc7846 | ||
|
|
b63eb0fa40 | ||
|
|
117e2a9ba2 | ||
|
|
d2f6e88fd1 | ||
|
|
c742c39ed9 | ||
|
|
1f2b931b01 | ||
|
|
e351ede294 | ||
|
|
9ffbfacca8 | ||
|
|
60524d2ff3 | ||
|
|
7001c05ec0 | ||
|
|
5d4414723d | ||
|
|
d31f0980a2 | ||
|
|
6649e97b1e | ||
|
|
06b8cbc964 | ||
|
|
6992c85d5e | ||
|
|
313d46ac47 | ||
|
|
5a5db2ad7f | ||
|
|
1ae29909c8 | ||
|
|
6747480869 | ||
|
|
9ba359e67a | ||
|
|
4c34f6be9b | ||
|
|
a747058a72 | ||
|
|
a2b77ff63b | ||
|
|
5c600a05d0 | ||
|
|
340fcd4de2 | ||
|
|
96d5e69c77 | ||
|
|
3b3825a83a | ||
|
|
74e815a706 | ||
|
|
2e4417f502 | ||
|
|
a4970dbfd5 | ||
|
|
5d6a35e116 | ||
|
|
943c15a3c8 | ||
|
|
4dad732c15 | ||
|
|
bb7cadf701 |
11
README.md
@@ -17,16 +17,11 @@ at multiple conferences and events like:
|
||||
|
||||
## Slides
|
||||
|
||||
The slides are in the `www/htdocs` directory.
|
||||
The slides are in the `docs` directory.
|
||||
|
||||
The recommended way to view them is to:
|
||||
|
||||
- have a Docker host
|
||||
- clone this repository to your Docker host
|
||||
- `cd www && docker-compose up -d`
|
||||
- this will start a web server on port 80
|
||||
- point your browser at your Docker host and enjoy
|
||||
To view them locally open `docs/index.html` in your browser.
|
||||
|
||||
To view them online open https://jpetazzo.github.io/orchestration-workshop/ in your browser.
|
||||
|
||||
## Sample code
|
||||
|
||||
|
||||
@@ -16,9 +16,11 @@ if not registry:
|
||||
# Get the name of the current directory.
|
||||
project_name = os.path.basename(os.path.realpath("."))
|
||||
|
||||
# Generate a Docker image tag, using the UNIX timestamp.
|
||||
# (i.e. number of seconds since January 1st, 1970)
|
||||
version = str(int(time.time()))
|
||||
# Version used to tag the generated Docker image, using the UNIX timestamp or the given version.
|
||||
if "VERSION" not in os.environ:
|
||||
version = str(int(time.time()))
|
||||
else:
|
||||
version = os.environ["VERSION"]
|
||||
|
||||
# Execute "docker-compose build" and abort if it fails.
|
||||
subprocess.check_call(["docker-compose", "-f", "docker-compose.yml", "build"])
|
||||
@@ -33,7 +35,7 @@ push_operations = dict()
|
||||
for service_name, service in compose_file.services.items():
|
||||
if "build" in service:
|
||||
compose_image = "{}_{}".format(project_name, service_name)
|
||||
registry_image = "{}/{}_{}:{}".format(registry, project_name, service_name, version)
|
||||
registry_image = "{}/{}:{}".format(registry, compose_image, version)
|
||||
# Re-tag the image so that it can be uploaded to the registry.
|
||||
subprocess.check_call(["docker", "tag", compose_image, registry_image])
|
||||
# Spawn "docker push" to upload the image.
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
cadvisor:
|
||||
image: google/cadvisor
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "/:/rootfs:ro"
|
||||
- "/var/run:/var/run:rw"
|
||||
- "/sys:/sys:ro"
|
||||
- "/var/lib/docker/:/var/lib/docker:ro"
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
cadvisor:
|
||||
image: google/cadvisor
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- "/:/rootfs:ro"
|
||||
- "/var/run:/var/run:rw"
|
||||
- "/sys:/sys:ro"
|
||||
- "/var/lib/docker/:/var/lib/docker:ro"
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng:
|
||||
build: rng
|
||||
ports:
|
||||
- "8001:80"
|
||||
|
||||
hasher:
|
||||
build: hasher
|
||||
ports:
|
||||
- "8002:80"
|
||||
|
||||
webui:
|
||||
build: webui
|
||||
ports:
|
||||
- "8000:80"
|
||||
volumes:
|
||||
- "./webui/files/:/files/"
|
||||
|
||||
redis:
|
||||
image: jpetazzo/hamba
|
||||
command: 6379 AA.BB.CC.DD:EEEEE
|
||||
|
||||
worker:
|
||||
build: worker
|
||||
|
||||
@@ -1,30 +1,21 @@
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng1:
|
||||
build: rng
|
||||
rng2:
|
||||
build: rng
|
||||
rng3:
|
||||
build: rng
|
||||
|
||||
rng:
|
||||
image: jpetazzo/hamba
|
||||
command: 80 rng1:80 rng2:80 rng3:80
|
||||
depends_on:
|
||||
- rng1
|
||||
- rng2
|
||||
- rng3
|
||||
build: rng
|
||||
image: ${REGISTRY_SLASH}rng${COLON_TAG}
|
||||
ports:
|
||||
- "8001:80"
|
||||
|
||||
hasher:
|
||||
build: hasher
|
||||
image: ${REGISTRY_SLASH}hasher${COLON_TAG}
|
||||
ports:
|
||||
- "8002:80"
|
||||
|
||||
webui:
|
||||
build: webui
|
||||
image: ${REGISTRY_SLASH}webui${COLON_TAG}
|
||||
ports:
|
||||
- "8000:80"
|
||||
volumes:
|
||||
@@ -35,4 +26,5 @@ services:
|
||||
|
||||
worker:
|
||||
build: worker
|
||||
image: ${REGISTRY_SLASH}worker${COLON_TAG}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
version: "2"
|
||||
|
||||
services:
|
||||
rng:
|
||||
build: rng
|
||||
ports:
|
||||
- "80"
|
||||
|
||||
hasher:
|
||||
build: hasher
|
||||
ports:
|
||||
- "8002:80"
|
||||
|
||||
webui:
|
||||
build: webui
|
||||
ports:
|
||||
- "8000:80"
|
||||
volumes:
|
||||
- "./webui/files/:/files/"
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
|
||||
worker:
|
||||
build: worker
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
rng:
|
||||
build: rng
|
||||
|
||||
hasher:
|
||||
build: hasher
|
||||
|
||||
webui:
|
||||
build: webui
|
||||
ports:
|
||||
- "8000:80"
|
||||
|
||||
redis:
|
||||
image: redis
|
||||
|
||||
worker:
|
||||
build: worker
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
hasher: 80
|
||||
redis: 6379
|
||||
rng: 80
|
||||
webui: 80
|
||||
|
||||
@@ -50,7 +50,7 @@ function refresh () {
|
||||
points.push({ x: s2.now, y: speed });
|
||||
}
|
||||
$("#speed").text("~" + speed.toFixed(1) + " hashes/second");
|
||||
var msg = ("I'm attending the @docker workshop at @scaleconf, "
|
||||
var msg = ("I'm attending the @docker workshop at #LinuxCon, "
|
||||
+ "and my #DockerCoins mining rig is crunching "
|
||||
+ speed.toFixed(1) + " hashes/second! W00T!");
|
||||
$("#tweet").attr(
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
4
docs/docker-service-create.svg
Normal file
|
After Width: | Height: | Size: 680 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 252 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 901 KiB After Width: | Height: | Size: 901 KiB |
|
Before Width: | Height: | Size: 575 KiB After Width: | Height: | Size: 575 KiB |
|
Before Width: | Height: | Size: 205 KiB After Width: | Height: | Size: 205 KiB |
40
docs/extract-section-titles.py
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Extract and print level 1 and 2 titles from workshop slides.
|
||||
"""
|
||||
|
||||
with open("htdocs/index.html", "r") as f:
|
||||
data = f.read()
|
||||
|
||||
# @jpetazzo abuses "class: title" to make a point sometimes
|
||||
skip = [
|
||||
"Why?",
|
||||
"---",
|
||||
"But ...",
|
||||
"WHY?!?",
|
||||
]
|
||||
|
||||
# Ditch linebreaks from main section titles
|
||||
replace = [
|
||||
"<br/>",
|
||||
]
|
||||
|
||||
# remove blank lines
|
||||
sections = [x for x in data.split('\n') if x] # and x not in skip]
|
||||
sections = "\n".join(sections)
|
||||
sections = sections.split('class: title')
|
||||
del(sections[0]) # delete the CSS frontmatter
|
||||
|
||||
for section in sections:
|
||||
lines = [x for x in section.split("\n") if x]
|
||||
|
||||
if lines[0] not in skip:
|
||||
title = lines[0]
|
||||
title = title.replace("<br/> ", "")
|
||||
title = title.replace("# ", "")
|
||||
del(lines[0])
|
||||
print("{}".format(title))
|
||||
|
||||
titles = [x[2:] for x in lines if x.startswith("# ")]
|
||||
for title in titles:
|
||||
print("\t{}".format(title))
|
||||
3491
docs/index.html
Normal file
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
14
docs/remark-0.13.min.js
vendored
Normal file
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
BIN
docs/swarm-mode.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
34
elk/logstash.conf
Normal file
@@ -0,0 +1,34 @@
|
||||
input {
|
||||
# Listens on 514/udp and 514/tcp by default; change that to non-privileged port
|
||||
syslog { port => 51415 }
|
||||
# Default port is 12201/udp
|
||||
gelf { }
|
||||
# This generates one test event per minute.
|
||||
# It is great for debugging, but you might
|
||||
# want to remove it in production.
|
||||
heartbeat { }
|
||||
}
|
||||
# The following filter is a hack!
|
||||
# The "de_dot" filter would be better, but it
|
||||
# is not pre-installed with logstash by default.
|
||||
filter {
|
||||
ruby {
|
||||
code => "
|
||||
event.to_hash.keys.each { |k| event[ k.gsub('.','_') ] = event.remove(k) if k.include?'.' }
|
||||
"
|
||||
}
|
||||
}
|
||||
output {
|
||||
elasticsearch {
|
||||
hosts => ["elasticsearch:9200"]
|
||||
}
|
||||
# This will output every message on stdout.
|
||||
# It is great when testing your setup, but in
|
||||
# production, it will probably cause problems;
|
||||
# either by filling up your disks, or worse,
|
||||
# by creating logging loops! BEWARE!
|
||||
stdout {
|
||||
codec => rubydebug
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ Virtualbox, Vagrant and Ansible
|
||||
Run the following commands:
|
||||
|
||||
$ vagrant up
|
||||
$ chmod 600 private-key
|
||||
$ ansible-playbook provisioning.yml
|
||||
|
||||
And that's it! Now you should be able to ssh on `node1` using:
|
||||
|
||||
2
prepare-local/Vagrantfile
vendored
@@ -25,7 +25,7 @@ Vagrant.configure('2') do |config|
|
||||
check_dependency 'vagrant-vbguest'
|
||||
|
||||
config.vm.box = settings['default_box']
|
||||
config.vm.box_url = settings['default_box_url']
|
||||
# config.vm.box_url = settings['default_box_url']
|
||||
config.ssh.forward_agent = true
|
||||
config.ssh.insert_key = settings['ssh_insert_key']
|
||||
config.vm.box_check_update = true
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
sudo: true
|
||||
vars_files:
|
||||
- vagrant.yml
|
||||
|
||||
tasks:
|
||||
|
||||
- name: clean up the home folder
|
||||
@@ -37,8 +38,7 @@
|
||||
repo: "{{ item }}"
|
||||
state: present
|
||||
with_items:
|
||||
- deb http://http.debian.net/debian wheezy-backports main
|
||||
- deb https://apt.dockerproject.org/repo {{ ansible_lsb.id|lower }}-{{ ansible_lsb.codename }} main
|
||||
- deb https://apt.dockerproject.org/repo ubuntu-trusty main
|
||||
|
||||
- name: installing docker
|
||||
apt:
|
||||
@@ -76,28 +76,16 @@
|
||||
name: virtualenv
|
||||
state: latest
|
||||
|
||||
- name: creating docker-compose folder
|
||||
- name: Install Docker Compose via PIP
|
||||
pip: name=docker-compose
|
||||
|
||||
- name:
|
||||
file:
|
||||
path: /opt/docker-compose
|
||||
state: directory
|
||||
register: docker_compose_folder
|
||||
|
||||
- name: creating virtualenv for docker-compose
|
||||
shell: virtualenv /opt/docker-compose
|
||||
when: docker_compose_folder is defined and docker_compose_folder.changed
|
||||
|
||||
- name: installing docker-compose
|
||||
pip:
|
||||
name: docker-compose
|
||||
state: latest
|
||||
virtualenv: /opt/docker-compose
|
||||
|
||||
- name: making the docker-compose command available to user
|
||||
lineinfile:
|
||||
dest: .bashrc
|
||||
line: "alias docker-compose='/opt/docker-compose/bin/docker-compose'"
|
||||
state: present
|
||||
regexp: '^alias docker-compose=.*$'
|
||||
path="/usr/local/bin/docker-compose"
|
||||
state=file
|
||||
mode=0755
|
||||
owner=vagrant
|
||||
group=docker
|
||||
|
||||
- name: building the /etc/hosts file with all nodes
|
||||
lineinfile:
|
||||
@@ -140,3 +128,5 @@
|
||||
line: "127.0.0.1 localhost {{ inventory_hostname }}"
|
||||
- regexp: '^127\.0\.1\.1'
|
||||
line: "127.0.1.1 {{ inventory_hostname }}"
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
vagrant:
|
||||
|
||||
default_box: debian-7.2.0
|
||||
default_box_url: https://dl.dropboxusercontent.com/u/197673519/debian-7.2.0.box
|
||||
default_box: ubuntu/trusty64
|
||||
default_box_check_update: true
|
||||
ssh_insert_key: false
|
||||
min_memory: 256
|
||||
@@ -12,7 +10,7 @@ instances:
|
||||
|
||||
- hostname: node1
|
||||
private_ip: 10.10.10.10
|
||||
memory: 512
|
||||
memory: 1512
|
||||
cores: 1
|
||||
mounts:
|
||||
- host_path: ../
|
||||
@@ -39,3 +37,6 @@ instances:
|
||||
private_ip: 10.10.10.50
|
||||
memory: 512
|
||||
cores: 1
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,52 +1,30 @@
|
||||
FROM debian:jessie
|
||||
MAINTAINER AJ Bowen <aj@soulshake.net>
|
||||
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y ca-certificates
|
||||
RUN apt-get install -y groff
|
||||
RUN apt-get install -y less
|
||||
RUN apt-get install -y python python-pip
|
||||
RUN apt-get install -y python-docutils
|
||||
RUN apt-get install -y sudo
|
||||
RUN apt-get install -y \
|
||||
RUN apt-get update && apt-get install -y \
|
||||
wkhtmltopdf \
|
||||
bsdmainutils \
|
||||
ca-certificates \
|
||||
curl \
|
||||
groff \
|
||||
jq \
|
||||
less \
|
||||
man \
|
||||
pssh \
|
||||
ssh
|
||||
python \
|
||||
python-pip \
|
||||
python-docutils \
|
||||
ssh \
|
||||
--no-install-recommends \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN pip install awscli
|
||||
RUN pip install \
|
||||
awscli \
|
||||
pdfkit \
|
||||
PyYAML \
|
||||
termcolor
|
||||
|
||||
RUN apt-get install -y wkhtmltopdf
|
||||
|
||||
ENV HOME /home/user
|
||||
|
||||
RUN useradd --create-home --home-dir $HOME user \
|
||||
&& mkdir -p $HOME/.config/gandi \
|
||||
&& chown -R user:user $HOME
|
||||
|
||||
RUN echo "user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
# Replace 1000 with your user / group id
|
||||
#RUN export uid=1000 gid=1000 && \
|
||||
# mkdir -p /home/user && \
|
||||
# mkdir -p /etc/sudoers.d && \
|
||||
# echo "user:x:${uid}:${gid}:user,,,:/home/user:/bin/bash" >> /etc/passwd && \
|
||||
# echo "user:x:${uid}:" >> /etc/group && \
|
||||
# echo "user ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/user && \
|
||||
# chmod 0440 /etc/sudoers.d/user && \
|
||||
# chown ${uid}:${gid} -R /home/user
|
||||
|
||||
WORKDIR $HOME
|
||||
RUN echo "alias ll='ls -lahF'" >> /home/user/.bashrc
|
||||
RUN echo "export PATH=$PATH:/home/user/bin" >> /home/user/.bashrc
|
||||
RUN mkdir -p /home/user/bin
|
||||
RUN ln -s /home/user/prepare-vms/scripts/trainer-cli /home/user/bin/trainer-cli
|
||||
USER user
|
||||
RUN echo "alias ll='ls -lahF'" >> /root/.bashrc
|
||||
ENTRYPOINT ["/root/prepare-vms/scripts/trainer-cli"]
|
||||
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
# Trainer tools to prepare VMs for Docker workshops
|
||||
|
||||
There are several options for using these tools:
|
||||
## 1. Prerequisites
|
||||
|
||||
### Clone the repo
|
||||
* [Docker](https://docs.docker.com/engine/installation/)
|
||||
* [Docker Compose](https://docs.docker.com/compose/install/)
|
||||
|
||||
$ git clone https://github.com/soulshake/prepare-vms.git
|
||||
$ cd prepare-vms
|
||||
## 2. Clone the repo
|
||||
|
||||
$ git clone https://github.com/jpetazzo/orchestration-workshop.git
|
||||
$ cd orchestration-workshop/prepare-vms
|
||||
$ docker-compose build
|
||||
$ mkdir $HOME/bin && ln -s `pwd`/trainer $HOME/bin/trainer
|
||||
$ ./trainer <commands> # See "Summary of commands" section below
|
||||
|
||||
### Via the image
|
||||
|
||||
$ docker pull soulshake/prepare-vms
|
||||
|
||||
### Submodule
|
||||
|
||||
This repo can be added as a submodule in the repo of the Docker workshop:
|
||||
|
||||
$ git submodule add https://github.com/soulshake/prepare-vms.git
|
||||
|
||||
## Setup
|
||||
|
||||
### Export needed envvars
|
||||
## 3. Preparing the environment
|
||||
|
||||
Required environment variables:
|
||||
|
||||
@@ -29,46 +20,49 @@ Required environment variables:
|
||||
* `AWS_SECRET_ACCESS_KEY`
|
||||
* `AWS_DEFAULT_REGION`
|
||||
|
||||
### 4. Update settings.yaml
|
||||
|
||||
|
||||
### Update settings.yaml
|
||||
|
||||
If you have more than one workshop:
|
||||
|
||||
$ cp settings.yaml settings/YOUR_WORKSHOP_NAME-settings.yaml
|
||||
$ ln -s settings/YOUR_WORKSHOP_NAME-settings.yaml `pwd`/settings.yaml
|
||||
|
||||
Update the `settings.yaml` as needed. This is the file that will be used to generate cards.
|
||||
Then pass `settings/YOUR_WORKSHOP_NAME-settings.yaml` as an argument to `deploy`, `cards`, etc.
|
||||
|
||||
## Usage
|
||||
|
||||
### Summary
|
||||
|
||||
Summary of steps to launch a batch of instances for a workshop:
|
||||
|
||||
* Export the environment variables needed by the AWS CLI (see **Requirements** below)
|
||||
* `trainer start NUMBER_OF_VMS` to create AWS instances
|
||||
* `trainer deploy TAG` to run `scripts/postprep.rc` via parallel-ssh
|
||||
* `trainer pull-images TAG` to pre-pull a bunch of Docker images
|
||||
* `trainer test TAG`
|
||||
* `trainer cards TAG` to generate a PDF and an HTML file you can print
|
||||
### Summary of commands
|
||||
|
||||
The `trainer` script can be executed directly.
|
||||
|
||||
Summary of steps to launch a batch of instances for a workshop:
|
||||
|
||||
* Export the environment variables needed by the AWS CLI (see **2. Preparing the environment** above)
|
||||
* `./trainer start N` (where `N` is the number of AWS instances to create)
|
||||
* `./trainer list` to view the list of tags
|
||||
* `./trainer list TAG` to view the instances with a given `TAG`
|
||||
* `./trainer deploy TAG settings/somefile.yaml` to run `scripts/postprep.rc` via parallel-ssh
|
||||
* `./trainer pull-images TAG` to pre-pull a bunch of Docker images to the instances
|
||||
* `./trainer test TAG`
|
||||
* `./trainer cards TAG settings/somefile.yaml` to generate a PDF and an HTML file you can print and cut to hand out cards with connection information to attendees
|
||||
|
||||
`./trainer` will run locally if all its dependencies are fulfilled; otherwise it will run in a Docker container.
|
||||
|
||||
It will check for the necessary environment variables. Then, if all its dependencies are installed
|
||||
locally, it will execute `trainer-cli`. If not, it will look for a local Docker image
|
||||
tagged `soulshake/trainer-tools`. If found, it will run in a container. If not found,
|
||||
the user will be prompted to either install the missing dependencies or download
|
||||
the Docker image.
|
||||
tagged `preparevms_prepare-vms` (created automatically when you run `docker-compose build`).
|
||||
If found, it will run in a container. If not found, the user will be prompted to
|
||||
either install the missing dependencies or run `docker-compose build`.
|
||||
|
||||
## Detailed usage
|
||||
|
||||
### Start some VMs
|
||||
|
||||
$ trainer start 10
|
||||
$ ./trainer start 10
|
||||
|
||||
A few things will happen:
|
||||
|
||||
* Your local SSH key will be synced
|
||||
* AWS instances will be created and tagged
|
||||
* A directory will be created
|
||||
|
||||
Details below.
|
||||
|
||||
#### Sync of SSH keys
|
||||
|
||||
When the `start` command is run, your local RSA SSH public key will be added to your AWS EC2 keychain.
|
||||
@@ -93,31 +87,31 @@ If you create new VMs, the symlinked file will be overwritten.
|
||||
|
||||
Instances can be deployed manually using the `deploy` command:
|
||||
|
||||
$ trainer deploy TAG
|
||||
$ ./trainer deploy TAG settings/somefile.yaml
|
||||
|
||||
The `postprep.rc` file will be copied via parallel-ssh to all of the VMs and executed.
|
||||
|
||||
### Pre-pull images
|
||||
|
||||
$ trainer pull-images TAG
|
||||
$ ./trainer pull-images TAG
|
||||
|
||||
### Generate cards
|
||||
|
||||
$ trainer cards TAG
|
||||
$ ./trainer cards TAG settings/somefile.yaml
|
||||
|
||||
### List tags
|
||||
|
||||
$ trainer list
|
||||
$ ./trainer list
|
||||
|
||||
### List VMs
|
||||
|
||||
$ trainer list TAG
|
||||
$ ./trainer list TAG
|
||||
|
||||
This will print a human-friendly list containing some information about each instance.
|
||||
|
||||
### Stop and destroy VMs
|
||||
|
||||
$ trainer stop TAG
|
||||
$ ./trainer stop TAG
|
||||
|
||||
## ToDo
|
||||
|
||||
|
||||
@@ -1,38 +1,26 @@
|
||||
prepare-vms:
|
||||
build: .
|
||||
container_name: prepare-vms
|
||||
working_dir: /home/user/prepare-vms
|
||||
volumes:
|
||||
- $HOME/.aws/:$HOME.aws/
|
||||
- $HOME/.ssh/:/home/user/.ssh/
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
#- /home:/home
|
||||
- /tmp/.X11-unix:/tmp/.X11-unix
|
||||
- $SSH_AUTH_DIRNAME:$SSH_AUTH_DIRNAME
|
||||
- $SCRIPT_DIR/:/home/user/prepare-vms/
|
||||
#- $SCRIPT_DIR/:$HOME/prepare-vms/
|
||||
#- $HOME/trainer-tools/
|
||||
#- $(dirname $SSH_AUTH_SOCK):$(dirname $SSH_AUTH_SOCK)
|
||||
#- /etc/passwd:/etc/passwd:ro
|
||||
#- /etc/group:/etc/group:ro
|
||||
#- /run/user:/run/user
|
||||
environment:
|
||||
HOME: /home/user
|
||||
#SCRIPT_DIR: /home/aj/git/prepare-vms
|
||||
SCRIPT_DIR: /home/user/prepare-vms
|
||||
HOME: /home/user
|
||||
SSH_AUTH_SOCK: ${SSH_AUTH_SOCK}
|
||||
SSH_AGENT_PID: ${SSH_AGENT_PID}
|
||||
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
|
||||
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
|
||||
DISPLAY: ${DISPLAY}
|
||||
USER: ${USER}
|
||||
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
|
||||
AWS_DEFAULT_OUTPUT:
|
||||
AWS_INSTANCE_TYPE: ${AWS_INSTANCE_TYPE}
|
||||
AWS_VPC_ID: ${AWS_VPC_ID}
|
||||
entrypoint: /home/user/prepare-vms/scripts/trainer-cli
|
||||
#entrypoint: trainer
|
||||
version: "2"
|
||||
|
||||
#AWS_DEFAULT_PROFILE: ${AWS_DEFAULT_PROFILE}
|
||||
#command: /home/user/prepare-vms/trainer-cli
|
||||
services:
|
||||
prepare-vms:
|
||||
build: .
|
||||
container_name: prepare-vms
|
||||
working_dir: /root/prepare-vms
|
||||
volumes:
|
||||
- $HOME/.aws/:/root/.aws/
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /tmp/.X11-unix:/tmp/.X11-unix
|
||||
- $SSH_AUTH_DIRNAME:$SSH_AUTH_DIRNAME
|
||||
- $PWD/:/root/prepare-vms/
|
||||
environment:
|
||||
SCRIPT_DIR: /root/prepare-vms
|
||||
DISPLAY: ${DISPLAY}
|
||||
SSH_AUTH_SOCK: ${SSH_AUTH_SOCK}
|
||||
SSH_AGENT_PID: ${SSH_AGENT_PID}
|
||||
AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
|
||||
AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
|
||||
AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
|
||||
AWS_DEFAULT_OUTPUT: json
|
||||
AWS_INSTANCE_TYPE: ${AWS_INSTANCE_TYPE}
|
||||
AWS_VPC_ID: ${AWS_VPC_ID}
|
||||
USER: ${USER}
|
||||
entrypoint: /root/prepare-vms/scripts/trainer-cli
|
||||
|
||||
BIN
prepare-vms/docker.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
@@ -13,7 +13,7 @@ def prettify(l):
|
||||
return ret
|
||||
|
||||
|
||||
# Read settings from settings.yaml
|
||||
# Read settings from user-provided settings file
|
||||
with open(sys.argv[1]) as f:
|
||||
data = f.read()
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ system("sudo chmod +x /usr/local/bin/docker-prompt")
|
||||
|
||||
# Fancy prompt courtesy of @soulshake.
|
||||
system("""sudo -u docker tee -a /home/docker/.bashrc <<SQRL
|
||||
export PS1='\e[1m\e[32m[\h] \e[34m(\\\$(docker-prompt)) \e[35m\u@{}\e[33m \w\e[0m\n$ '
|
||||
export PS1='\e[1m\e[31m[\h] \e[32m(\\\$(docker-prompt)) \e[34m\u@{}\e[35m \w\e[0m\n$ '
|
||||
SQRL""".format(ipv4))
|
||||
|
||||
# Custom .vimrc
|
||||
|
||||
@@ -11,8 +11,9 @@ pssh () {
|
||||
}
|
||||
|
||||
echo "[parallel-ssh] $@"
|
||||
export PSSH=$(which pssh || which parallel-ssh)
|
||||
|
||||
parallel-ssh -h $HOSTFILE -l ubuntu \
|
||||
$PSSH -h $HOSTFILE -l ubuntu \
|
||||
--par 100 \
|
||||
-O LogLevel=ERROR \
|
||||
-O UserKnownHostsFile=/dev/null \
|
||||
|
||||
@@ -7,7 +7,7 @@ export AWS_DEFAULT_OUTPUT=text
|
||||
|
||||
greet() {
|
||||
hello=$(aws iam get-user --query 'User.UserName')
|
||||
echo "Greetings, $hello!"
|
||||
echo "Greetings, $hello/${USER}!"
|
||||
}
|
||||
|
||||
deploy_hq(){
|
||||
@@ -53,8 +53,8 @@ deploy_tag(){
|
||||
source scripts/postprep.rc
|
||||
echo "Finished deploying $TAG."
|
||||
echo "You may want to run one of the following commands:"
|
||||
echo "trainer pull-images $TAG"
|
||||
echo "trainer cards $TAG"
|
||||
echo "./trainer pull-images $TAG"
|
||||
echo "./trainer cards $TAG <settings/somefile.yaml>"
|
||||
}
|
||||
|
||||
link_tag() {
|
||||
@@ -69,7 +69,6 @@ pull_tag(){
|
||||
TAG=$1
|
||||
need_tag $TAG
|
||||
link_tag $TAG
|
||||
cards_file=ips.html
|
||||
if [ ! -s $IPS_FILE ]; then
|
||||
echo "Nonexistent or empty IPs file $IPS_FILE"
|
||||
fi
|
||||
@@ -90,7 +89,7 @@ pull_tag(){
|
||||
echo "Finished pulling images for $TAG"
|
||||
|
||||
echo "You may now want to run:"
|
||||
echo "trainer cards $TAG"
|
||||
echo "./trainer cards $TAG <settings/somefile.yaml>"
|
||||
}
|
||||
|
||||
wait_until_tag_is_running() {
|
||||
@@ -129,7 +128,7 @@ test_tag(){
|
||||
ip=$(shuf -n 1 $ips_file)
|
||||
test_vm $ip
|
||||
echo "Tests complete. You may want to run one of the following commands:"
|
||||
echo "trainer cards $TAG"
|
||||
echo "./trainer cards $TAG <settings/somefile.yaml>"
|
||||
}
|
||||
|
||||
test_vm() {
|
||||
@@ -149,7 +148,6 @@ test_vm() {
|
||||
"docker-machine version" \
|
||||
"docker images" \
|
||||
"docker ps" \
|
||||
"which fig" \
|
||||
"curl --silent localhost:55555" \
|
||||
"sudo ls -la /mnt/ | grep docker" \
|
||||
"env" \
|
||||
@@ -276,7 +274,7 @@ run_cli() {
|
||||
scripts/find-ubuntu-ami.sh -r $AWS_DEFAULT_REGION $*
|
||||
echo
|
||||
echo "Protip:"
|
||||
echo "trainer ami -a amd64 -v 16.04 -t hvm:ebs -N | grep -v ^REGION | cut -d\" \" -f15"
|
||||
echo "./trainer ami -a amd64 -v 16.04 -t hvm:ebs -N | grep -v ^REGION | cut -d\" \" -f15"
|
||||
echo
|
||||
echo "Suggestions:"
|
||||
suggest_amis
|
||||
@@ -333,8 +331,8 @@ run_cli() {
|
||||
describe_tag $TAG
|
||||
tag_is_reachable $TAG
|
||||
echo "You may be interested in running one of the following commands:"
|
||||
echo "trainer ips $TAG"
|
||||
echo "trainer deploy $TAG <settings/somefile.yaml>"
|
||||
echo "./trainer ips $TAG"
|
||||
echo "./trainer deploy $TAG <settings/somefile.yaml>"
|
||||
;;
|
||||
opensg)
|
||||
aws ec2 authorize-security-group-ingress \
|
||||
@@ -427,8 +425,8 @@ run_cli() {
|
||||
echo "$IPS" > tags/$TAG/ips.txt
|
||||
link_tag $TAG
|
||||
echo "To deploy or kill these instances, run one of the following:"
|
||||
echo "trainer deploy $TAG <settings/somefile.yml>"
|
||||
echo "trainer list $TAG"
|
||||
echo "./trainer deploy $TAG <settings/somefile.yaml>"
|
||||
echo "./trainer list $TAG"
|
||||
;;
|
||||
status)
|
||||
greet && echo
|
||||
@@ -466,7 +464,7 @@ run_cli() {
|
||||
;;
|
||||
*)
|
||||
echo "
|
||||
trainer COMMAND [n-instances|tag]
|
||||
./trainer <command> [n-instances|tag] [settings/file.yaml]
|
||||
|
||||
Core commands:
|
||||
start n Start n instances
|
||||
@@ -485,7 +483,7 @@ Extras:
|
||||
|
||||
Beta:
|
||||
ami Look up Amazon Machine Images
|
||||
cards Generate cards
|
||||
cards FILE Generate cards
|
||||
opensg Modify AWS security groups
|
||||
"
|
||||
;;
|
||||
|
||||
@@ -10,9 +10,7 @@ instance_password: training
|
||||
clustersize: 1 # Number of VMs per cluster
|
||||
pagesize: 15 # Number of cards to print per page
|
||||
|
||||
#background_image: https://myapps.developer.ubuntu.com/site_media/appmedia/2014/12/swarm.png
|
||||
background_image: http://www.yellosoft.us/public/images/docker.png
|
||||
#background_image: ../media/swarm.png
|
||||
background_image: https://www.docker.com/sites/default/files/Engine.png
|
||||
|
||||
# To be printed on the cards:
|
||||
blurb: >
|
||||
|
||||
@@ -10,8 +10,7 @@ instance_password: training
|
||||
clustersize: 5 # Number of VMs per cluster
|
||||
pagesize: 12 # Number of cards to print per page
|
||||
|
||||
#background_image: https://myapps.developer.ubuntu.com/site_media/appmedia/2014/12/swarm.png
|
||||
background_image: http://www.yellosoft.us/public/images/docker.png
|
||||
background_image: https://www.docker.com/sites/default/files/Engine.png
|
||||
#background_image: ../media/swarm.png
|
||||
|
||||
# To be printed on the cards:
|
||||
@@ -30,6 +29,6 @@ footer: >
|
||||
url: http://container.training/
|
||||
|
||||
engine_version: get.docker.com
|
||||
compose_version: 1.7.1
|
||||
machine_version: 0.6.0
|
||||
swarm_version: 1.2.2
|
||||
compose_version: 1.8.0
|
||||
machine_version: 0.8.0
|
||||
swarm_version: 1.2.4
|
||||
|
||||
@@ -30,6 +30,6 @@ footer: >
|
||||
url: http://container.training/
|
||||
|
||||
engine_version: test.docker.com
|
||||
compose_version: 1.7.0-rc2
|
||||
machine_version: 0.7.0-rc1
|
||||
swarm_version: 1.2.0-rc2
|
||||
compose_version: 1.8.0-rc1
|
||||
machine_version: 0.8.0-rc1
|
||||
swarm_version: latest
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
TRAINER_IMAGE="soulshake/prepare-vms"
|
||||
TRAINER_IMAGE="preparevms_prepare-vms"
|
||||
|
||||
DEPENDENCIES="
|
||||
aws
|
||||
@@ -71,11 +71,10 @@ if check_dependencies; then
|
||||
elif check_image; then
|
||||
check_ssh_auth_sock
|
||||
export SSH_AUTH_DIRNAME=$(dirname $SSH_AUTH_SOCK)
|
||||
docker-compose -f docker-compose.yml run prepare-vms "$@"
|
||||
docker-compose run prepare-vms "$@"
|
||||
else
|
||||
echo "Some dependencies are missing, and docker image $TRAINER_IMAGE doesn't exist locally."
|
||||
echo "Please do one of the following: "
|
||||
echo "- run \`docker build -t soulshake/prepare-vms .\`"
|
||||
echo "- run \`docker pull soulshake/prepare-vms\`"
|
||||
echo "- run \`docker-compose build\`"
|
||||
echo "- install missing dependencies"
|
||||
fi
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
www:
|
||||
image: nginx
|
||||
ports:
|
||||
- "8080:80"
|
||||
volumes:
|
||||
- "./htdocs:/usr/share/nginx/html"
|
||||
|
Before Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 120 KiB |
|
Before Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 163 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 148 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 138 KiB |
|
Before Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 119 KiB |