Compare commits

..

14 Commits

Author SHA1 Message Date
Jerome Petazzoni
cacc6cd6d9 Fixes after Budapest edition 2016-05-03 02:38:16 -07:00
Jerome Petazzoni
2a35e4954c Last touch-ups 2016-04-26 15:40:45 -07:00
Jerome Petazzoni
feefd4e013 Update outline + last round of minor fixes 2016-04-26 14:05:20 -07:00
Jerome Petazzoni
8e1827a506 Another round of updates for CRAFT, almost there 2016-04-26 12:53:50 -07:00
Jerome Petazzoni
76689cd431 Updates for CRAFT (bring everything to Compose v2) 2016-04-26 06:20:11 -07:00
Jerome Petazzoni
7448474b92 Update for Berlin workshop 2016-04-21 22:25:00 -07:00
Jérôme Petazzoni
52a2e6f3e6 Bump swarm image version to 1.2; add Consul Compose file 2016-04-21 10:01:52 +00:00
Jerome Petazzoni
2b213a9821 Add reference to MobaXterm 2016-04-20 08:08:04 -07:00
Jerome Petazzoni
3ec61d706e Update versions 2016-04-20 08:07:50 -07:00
Jérôme Petazzoni
4fc9d64737 Add environment logic in autotest 2016-04-17 20:33:31 +00:00
Jérôme Petazzoni
e427c1aa38 Update test harness 2016-04-13 22:23:42 +00:00
Jérôme Petazzoni
169d1085a1 Update slides for automated testing 2016-04-13 22:23:35 +00:00
Jérôme Petazzoni
506c6ea61b Minor change in placeholder for GELF section 2016-04-13 21:49:02 +00:00
Jérôme Petazzoni
654de369ca Add autotest skeleton 2016-04-11 20:11:52 +00:00
20 changed files with 1795 additions and 1509 deletions

191
autotest/autotest.py Executable file
View File

@@ -0,0 +1,191 @@
#!/usr/bin/env python
import os
import re
import signal
import subprocess
import time
def print_snippet(snippet):
print(78*'-')
print(snippet)
print(78*'-')
class Snippet(object):
def __init__(self, slide, content):
self.slide = slide
self.content = content
self.actions = []
def __str__(self):
return self.content
class Slide(object):
current_slide = 0
def __init__(self, content):
Slide.current_slide += 1
self.number = Slide.current_slide
# Remove commented-out slides
# (remark.js considers ??? to be the separator for speaker notes)
content = re.split("\n\?\?\?\n", content)[0]
self.content = content
self.snippets = []
exercises = re.findall("\.exercise\[(.*)\]", content, re.DOTALL)
for exercise in exercises:
if "```" in exercise and "<br/>`" in exercise:
print("! Exercise on slide {} has both ``` and <br/>` delimiters, skipping."
.format(self.number))
print_snippet(exercise)
elif "```" in exercise:
for snippet in exercise.split("```")[1::2]:
self.snippets.append(Snippet(self, snippet))
elif "<br/>`" in exercise:
for snippet in re.findall("<br/>`(.*)`", exercise):
self.snippets.append(Snippet(self, snippet))
else:
print(" Exercise on slide {} has neither ``` or <br/>` delimiters, skipping."
.format(self.number))
def __str__(self):
text = self.content
for snippet in self.snippets:
text = text.replace(snippet.content, ansi("7")(snippet.content))
return text
def ansi(code):
return lambda s: "\x1b[{}m{}\x1b[0m".format(code, s)
slides = []
with open("index.html") as f:
content = f.read()
for slide in re.split("\n---?\n", content):
slides.append(Slide(slide))
is_editing_file = False
placeholders = {}
for slide in slides:
for snippet in slide.snippets:
content = snippet.content
# Multi-line snippets should be ```highlightsyntax...
# Single-line snippets will be interpreted as shell commands
if '\n' in content:
highlight, content = content.split('\n', 1)
else:
highlight = "bash"
content = content.strip()
# If the previous snippet was a file fragment, and the current
# snippet is not YAML or EDIT, complain.
if is_editing_file and highlight not in ["yaml", "edit"]:
print("! On slide {}, previous snippet was YAML, so what do what do?"
.format(slide.number))
print_snippet(content)
is_editing_file = False
if highlight == "yaml":
is_editing_file = True
elif highlight == "placeholder":
for line in content.split('\n'):
variable, value = line.split(' ', 1)
placeholders[variable] = value
elif highlight == "bash":
for variable, value in placeholders.items():
quoted = "`{}`".format(variable)
if quoted in content:
content = content.replace(quoted, value)
del placeholders[variable]
if '`' in content:
print("! The following snippet on slide {} contains a backtick:"
.format(slide.number))
print_snippet(content)
continue
print("_ "+content)
snippet.actions.append((highlight, content))
elif highlight == "edit":
print(". "+content)
snippet.actions.append((highlight, content))
elif highlight == "meta":
print("^ "+content)
snippet.actions.append((highlight, content))
else:
print("! Unknown highlight {!r} on slide {}.".format(highlight, slide.number))
if placeholders:
print("! Remaining placeholder values: {}".format(placeholders))
actions = sum([snippet.actions for snippet in sum([slide.snippets for slide in slides], [])], [])
# Strip ^{ ... ^} for now
def strip_curly_braces(actions, in_braces=False):
if actions == []:
return []
elif actions[0] == ("meta", "^{"):
return strip_curly_braces(actions[1:], True)
elif actions[0] == ("meta", "^}"):
return strip_curly_braces(actions[1:], False)
elif in_braces:
return strip_curly_braces(actions[1:], True)
else:
return [actions[0]] + strip_curly_braces(actions[1:], False)
actions = strip_curly_braces(actions)
background = []
cwd = os.path.expanduser("~")
env = {}
for current_action, next_action in zip(actions, actions[1:]+[("bash", "true")]):
if current_action[0] == "meta":
continue
print(ansi(7)(">>> {}".format(current_action[1])))
time.sleep(1)
popen_options = dict(shell=True, cwd=cwd, stdin=subprocess.PIPE, preexec_fn=os.setpgrp)
# The follow hack allows to capture the environment variables set by `docker-machine env`
# FIXME: this doesn't handle `unset` for now
if any([
"eval $(docker-machine env" in current_action[1],
"DOCKER_HOST" in current_action[1],
"COMPOSE_FILE" in current_action[1],
]):
popen_options["stdout"] = subprocess.PIPE
current_action[1] += "\nenv"
proc = subprocess.Popen(current_action[1], **popen_options)
proc.cmd = current_action[1]
if next_action[0] == "meta":
print(">>> {}".format(next_action[1]))
time.sleep(3)
if next_action[1] == "^C":
os.killpg(proc.pid, signal.SIGINT)
proc.wait()
elif next_action[1] == "^Z":
# Let the process run
background.append(proc)
elif next_action[1] == "^D":
proc.communicate()
proc.wait()
else:
print("! Unknown meta action {} after snippet:".format(next_action[1]))
print_snippet(next_action[1])
print(ansi(7)("<<< {}".format(current_action[1])))
else:
proc.wait()
if "stdout" in popen_options:
stdout, stderr = proc.communicate()
for line in stdout.split('\n'):
if line.startswith("DOCKER_"):
variable, value = line.split('=', 1)
env[variable] = value
print("=== {}={}".format(variable, value))
print(ansi(7)("<<< {} >>> {}".format(proc.returncode, current_action[1])))
if proc.returncode != 0:
print("Got non-zero status code; aborting.")
break
if current_action[1].startswith("cd "):
cwd = os.path.expanduser(current_action[1][3:])
for proc in background:
print("Terminating background process:")
print_snippet(proc.cmd)
proc.terminate()
proc.wait()

1
autotest/index.html Symbolic link
View File

@@ -0,0 +1 @@
../www/htdocs/index.html

View File

@@ -3,7 +3,7 @@ unset DOCKER_REGISTRY
unset DOCKER_HOST
unset COMPOSE_FILE
SWARM_IMAGE=${SWARM_IMAGE:-jpetazzo/swarm:1.1.3-rc2-debug-experimental}
SWARM_IMAGE=${SWARM_IMAGE:-swarm:1.2.0}
prepare_1_check_ssh_keys () {
for N in $(seq 1 5); do

12
consul/docker-compose.yml Normal file
View File

@@ -0,0 +1,12 @@
version: "2"
services:
bootstrap:
image: jpetazzo/consul
command: agent -server -bootstrap
container_name: bootstrap
server:
image: jpetazzo/consul
command: agent -server -join bootstrap -join server
client:
image: jpetazzo/consul
command: members -rpc-addr server:8400

View File

@@ -1,29 +1,26 @@
rng:
build: rng
ports:
- "8001:80"
version: "2"
hasher:
build: hasher
ports:
- "8002:80"
services:
rng:
build: rng
ports:
- "8001:80"
webui:
build: webui
links:
- redis
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
hasher:
build: hasher
ports:
- "8002:80"
redis:
image: redis
webui:
build: webui
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
worker:
build: worker
links:
- rng
- hasher
- redis
redis:
image: redis
worker:
build: worker

View File

@@ -1,44 +1,35 @@
rng1:
build: rng
version: "2"
rng2:
build: rng
services:
rng1:
build: rng
rng2:
build: rng
rng3:
build: rng
rng3:
build: rng
rng:
image: jpetazzo/hamba
command: 80 rng1:80 rng2:80 rng3:80
ports:
- "8001:80"
rng:
image: jpetazzo/hamba
links:
- rng1
- rng2
- rng3
command: 80 rng1 80 rng2 80 rng3 80
ports:
- "8001:80"
hasher:
build: hasher
ports:
- "8002:80"
hasher:
build: hasher
ports:
- "8002:80"
webui:
build: webui
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
webui:
build: webui
links:
- redis
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
redis:
image: jpetazzo/hamba
command: 6379 AA.BB.CC.DD:EEEEE
redis:
image: jpetazzo/hamba
command: 6379 AA.BB.CC.DD EEEEE
worker:
build: worker
links:
- rng
- hasher
- redis
worker:
build: worker

View File

@@ -1,43 +0,0 @@
rng1:
build: rng
rng2:
build: rng
rng3:
build: rng
rng0:
image: jpetazzo/hamba
links:
- rng1
- rng2
- rng3
command: 80 rng1 80 rng2 80 rng3 80
ports:
- "8001:80"
hasher:
build: hasher
ports:
- "8002:80"
webui:
build: webui
extra_hosts:
redis: A.B.C.D
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
#redis:
# image: redis
worker:
build: worker
links:
- rng0:rng
- hasher:hasher
extra_hosts:
redis: A.B.C.D

View File

@@ -1,44 +1,47 @@
rng:
build: rng
ports:
- "8001:80"
log_driver: gelf
log_opt:
gelf-address: "udp://XX.XX.XX.XX:XXXXX"
version: "2"
hasher:
build: hasher
ports:
- "8002:80"
log_driver: gelf
log_opt:
gelf-address: "udp://XX.XX.XX.XX:XXXXX"
services:
rng:
build: rng
ports:
- "8001:80"
logging:
driver: gelf
options:
gelf-address: udp://localhost:12201
webui:
build: webui
links:
- redis
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
log_driver: gelf
log_opt:
gelf-address: "udp://XX.XX.XX.XX:XXXXX"
hasher:
build: hasher
ports:
- "8002:80"
logging:
driver: gelf
options:
gelf-address: udp://localhost:12201
redis:
image: redis
log_driver: gelf
log_opt:
gelf-address: "udp://XX.XX.XX.XX:XXXXX"
webui:
build: webui
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
logging:
driver: gelf
options:
gelf-address: udp://localhost:12201
worker:
build: worker
links:
- rng
- hasher
- redis
log_driver: gelf
log_opt:
gelf-address: "udp://XX.XX.XX.XX:XXXXX"
redis:
image: redis
logging:
driver: gelf
options:
gelf-address: udp://localhost:12201
worker:
build: worker
logging:
driver: gelf
options:
gelf-address: udp://localhost:12201

View File

@@ -0,0 +1,26 @@
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

View File

@@ -1,43 +1,38 @@
rng1:
build: rng
version: "2"
rng2:
build: rng
services:
rng1:
build: rng
rng2:
build: rng
rng3:
build: rng
rng3:
build: rng
rng:
image: jpetazzo/hamba
command: 80 rng1:80 rng2:80 rng3:80
depends_on:
- rng1
- rng2
- rng3
ports:
- "8001:80"
rng:
image: jpetazzo/hamba
links:
- rng1
- rng2
- rng3
command: 80 rng1 80 rng2 80 rng3 80
ports:
- "8001:80"
hasher:
build: hasher
ports:
- "8002:80"
hasher:
build: hasher
ports:
- "8002:80"
webui:
build: webui
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
webui:
build: webui
links:
- redis
ports:
- "8000:80"
volumes:
- "./webui/files/:/files/"
redis:
image: redis
redis:
image: redis
worker:
build: worker
links:
- rng
- hasher
- redis
worker:
build: worker

View File

@@ -3,18 +3,14 @@ version: '2'
services:
rng:
build: rng
ports:
- 80
hasher:
build: hasher
ports:
- 80
webui:
build: webui
ports:
- 80
- "8000:80"
redis:
image: redis

View File

@@ -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 @praqma, "
var msg = ("I'm attending the @docker workshop at @scaleconf, "
+ "and my #DockerCoins mining rig is crunching "
+ speed.toFixed(1) + " hashes/second! W00T!");
$("#tweet").attr(

View File

@@ -1,56 +1,55 @@
elasticsearch:
image: elasticsearch
# If you need to acces ES directly, just uncomment those lines.
#ports:
# - "9200:9200"
# - "9300:9300"
version: "2"
logstash:
image: logstash
command: |
-e '
input {
# 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
}
}'
ports:
- 12201/udp
links:
- elasticsearch
services:
elasticsearch:
image: elasticsearch
# If you need to access ES directly, just uncomment those lines.
#ports:
# - "9200:9200"
# - "9300:9300"
kibana:
image: kibana
ports:
- 5601
links:
- elasticsearch
environment:
ELASTICSEARCH_URL: http://elasticsearch:9200
logstash:
image: logstash
command: |
-e '
input {
# 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
}
}'
ports:
- "12201:12201/udp"
kibana:
image: kibana
ports:
- "5601:5601"
environment:
ELASTICSEARCH_URL: http://elasticsearch:9200

View File

@@ -102,8 +102,7 @@ aws_kill_instances_by_tag() {
echo "Deleting instances with tag $TAG"
echo "$IDS" \
| xargs aws ec2 terminate-instances --instance-ids \
aws ec2 terminate-instances --instance-ids $IDS \
| grep ^TERMINATINGINSTANCES
}

View File

@@ -424,7 +424,7 @@ 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"
echo "trainer deploy $TAG <settings/somefile.yml>"
echo "trainer list $TAG"
;;
status)

View File

@@ -30,6 +30,6 @@ footer: >
url: http://container.training/
engine_version: get.docker.com
compose_version: 1.6.2
compose_version: 1.7.0
machine_version: 0.6.0
swarm_version: 1.2.0-rc1
swarm_version: 1.2.0

View File

@@ -8,7 +8,7 @@ instance_login: docker
instance_password: training
clustersize: 5 # Number of VMs per cluster
pagesize: 15 # Number of cards to print per page
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
@@ -30,6 +30,6 @@ footer: >
url: http://container.training/
engine_version: get.docker.com
compose_version: 1.6.2
compose_version: 1.7.0
machine_version: 0.6.0
swarm_version: 1.2.0-rc1
swarm_version: 1.2.0

View File

@@ -30,6 +30,6 @@ footer: >
url: http://container.training/
engine_version: test.docker.com
compose_version: 1.7.0-rc1
compose_version: 1.7.0-rc2
machine_version: 0.7.0-rc1
swarm_version: 1.2.0-rc1
swarm_version: 1.2.0-rc2

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB