ALMA Observatory
Atacama Large Millimeter/submillimeter Array
66 antennas
Blackbox deployments
Docker
Ansible
Buildout
App
Buildout is a Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.
Ansible is the simplest way to automate apps and IT infrastructure. Application Deployment + Configuration Management + Continuous Delivery.
www.stacklab.io/ep2015
docker pull aaguirre/ep2015
https://slides.com/aaguirre/deck
home
├── lab01
│ └── env
├── lab02
│ ├── bin
│ ├── develop-eggs
│ ├── eggs
│ ├── parts
│ └── src
├── lab03
│ ├── bin
│ ├── develop-eggs
│ ├── eggs
│ ├── parts
│ └── src
├── lab04
│ ├── ansible
│ ├── app
│ └── env
├── lab05
│ ├── ansible
│ ├── docker -> /etc/offline/docker
│ └── env
└── lab06
├── env
└── my.app
Installing Pyramid
Lab 01
cd /home/lab01/
virtualenv env
source env/bin/activate (deactivate)
pip install pyramid
pcreate -s starter my.app
cd my.app/
python setup.py develop
pserve development.ini
http://52.28.125.90:<port>
Lab 01
python setup.py test -q
pcreate -l (list available templates)
pshell development.ini
Installing Pyramid using Buildout
Lab 02
Buildout is a Python-based build system for creating, assembling and deploying applications from multiple parts, some of which may be non-Python-based. It lets you create a buildout configuration and reproduce the same software later.
Lab 02
cd /home/lab02/
[buildout]
extends =
versions.cfg
show-picked-versions = true
versions = versions
eggs-directory = eggs
parts =
pyramid
[pyramid]
recipe = zc.recipe.egg
dependent-scripts = true
eggs =
pyramid
interpreter = py
Lab 02
#curl -O https://bootstrap.pypa.io/bootstrap-buildout.py
python bootstrap-buildout.py
bin/buildout -o
ls bin/
Lab 02
Creating a project inside buildout
# bin/pcreate -s starter src/my.app
Lab 02
Creating a project inside buildout
[buildout]
extends =
versions.cfg
show-picked-versions = true
develop =
src/my.app
versions = versions
eggs-directory = eggs
parts =
pyramid
my.app
[pyramid]
recipe = zc.recipe.egg
dependent-scripts = true
eggs =
pyramid
interpreter = py
Lab 02
Running buildout
bin/buildout -o
bin/pserve src/my.app/development.ini
http://52.28.125.90:<port>
Using buildout + git (or svn, cvs, etc)
Lab 03
[buildout]
extends =
versions.cfg
show-picked-versions = true
versions = versions
extensions =
mr.developer
sources = sources
always-checkout = force
auto-checkout =
my.app
eggs-directory = eggs
parts =
app
[sources]
my.app = git https://github.com/aaguirre/ep2015.app1.git
[app]
recipe = zc.recipe.egg
dependent-scripts = true
eggs =
my.app
interpreter = py
cd /home/lab03/
Lab 03
bin/buildout -o
bin/pserve src/my.app/development.ini
Using ansible to deploy
Lab 04
Ansible is the simplest way to automate apps and IT infrastructure. Application Deployment + Configuration Management + Continuous Delivery.
Ansible
Ansible Client
Host 1
Host 2
Host 3
Host 4
Host 5
Lab 04
cd /home/lab04/
ansible/
app/
env/ (source env/bin/activate)
Lab 04
├── group_vars
│ └── all
├── hosts
├── play.yml
└── roles
└── myapp
├── files
│ ├── bootstrap-buildout.py
│ ├── buildout.cfg
│ └── versions.cfg
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
└── vars
└── main.yml
cd /home/lab04/
Lab 04
- name: start myapp
command: bin/pserve src/my.app/development.ini --daemon --pid=app.pid
args:
chdir: "{{ installation_path }}"
notify:
- wait for service
- name: wait for service
wait_for: port=6543 delay=20
handlers/main.yml
Lab 04
ansible-playbook -i hosts play.yml
handlers/main.yml
Lab 04
- name: Copy buildout file to the destination directory
copy: src=buildout.cfg dest={{ installation_path }}
- name: Copy versions file to the destination directory
copy: src=versions.cfg dest={{ installation_path }}
- name: Copy boostrap.py file to the destination directory
copy: src=bootstrap-buildout.py dest={{ installation_path }}
- name: Run Bootstrap
command: "{{ python_path }}/python bootstrap-buildout.py"
args:
chdir: "{{ installation_path }}"
- name: Run buildout
command: bin/buildout -o
args:
chdir: "{{ installation_path }}"
notify:
- start myapp
tasks/main.yml
pkill pserve
Using Docker (+ ansible)
Lab 05
Lab 05
CENTOS 6.6
SSH Server
Buildout
Supervisor
Dockerfile
6543
22
Lab 05
Lab 05
docker build
docker pull
docker run
Lab 05
docker ps (list active containers)
docker ps -a (list all containers)
docker images (list all images)
docker rm <container>
docker rmi <container>
Lab 05
Lab 05
docker build -t imyapp:latest .
docker run -d -p 6543:6543 imyapp:latest
docker stop <container-id>
cd /home/lab05/docker/
Lab 05
pkill docker
rm -rf /var/lib/docker/*
cp -r /etc/offline/dockerdata/* /var/lib/docker/
supervisorctl restart wrapdocker
cd /home/lab05/docker/
Ansible
Ansible Client
Container
Docker
Container
Docker
Container
Docker
Container
Docker
Container
Docker
Lab 05
Lab 05
- name: pre
command: ls
ignore_errors: yes
- name: run my application image
docker:
name: "myapp2"
state: started
image: "imyapp:latest"
ports:
- "6543:6543"
cd /home/lab05/ansible/
Fullstack app
(or service)
Client
Dependency Injection
Interface
Service
Service
Service
from zope.interface import Interface
class INotification(Interface):
""" Service responsible of sending notifications ."""
def send(self, message): pass
@subscriber(NewNotification)
@greenlet
def new_notification(event):
utilities = event.request.registry.getUtilitiesFor(INotification)
for name, utility in utilities:
utility.send(event.message )
config.registry.registerUtility(MailService(settings), INotification, 'mail')
config.registry.registerUtility(Facebook(settings), INotification, 'facebook')
config.registry.registerUtility(Twitter(settings), INotification, 'twitter')
from portal.interfaces import IMailSender
from pyramid_mailer import mailer_factory_from_settings
from pyramid_mailer.message import Message
from zope.interface import implements
class MailService(object):
implements(IMailSender)
def __init__(self, settings):
self.settings = settings
self.mailer = mailer_factory_from_settings(settings)
def send(self, message):
mail = Message(subject=self.settings['subject'],
recipients=[self.settings['to']],
body=message,
sender=self.settings['mail.default_sender'],
extra_headers=dict(From=self.settings['mail.from'])
)
self.mailer.send_immediately(mail, fail_silently=False)
docker pull aaguirre/ep2015
https://slides.com/aaguirre/deck
twitter.com/alvaro_aguirre