SlideShare una empresa de Scribd logo
1 de 58
Descargar para leer sin conexión
BATOU
         Multi-(Component|Environment|Host|Platform) deployment


                            Christian Theune <ct@gocept.com>




Wednesday, October 31, 12
Wednesday, October 31, 12
Wednesday, October 31, 12
INHALT


    • Motivation

    • Hello World

    • Tiefer            in den Kaninchenbau

    • Ausblick




Wednesday, October 31, 12
WARUM?




Wednesday, October 31, 12
Wednesday, October 31, 12
Wednesday, October 31, 12
Wednesday, October 31, 12
Wednesday, October 31, 12
Wednesday, October 31, 12
PARTY LIKE ITS ...

    • 1999: PHP             FTP-Uploads

    • 2001: Shell-Skripte         um Zope-Instanzen zu verwalten

    • 2003: Zope            2.4 “mkinstance”

    • 2006: zc.buildout

    • 2009: Fabric



Wednesday, October 31, 12
BATOU
                                VS

               Puppet, Chef    Fabric, Salt         JuJu




      Systemkonfiguration
         versus Service       Modellierung    Laufzeitumgebung
          deployment


Wednesday, October 31, 12
HELLO WORLD



                                  http://www.flickr.com/photos/oskay/472097903
Wednesday, October 31, 12
./.hg
                     ./buildout.cfg
                     ./bootstrap.py
                     ./components
                     ./components/hello
                     ./components/hello/component.py
                     ./environments
                     ./environments/dev.cfg
                     ./environments/prod.cfg



                                   $ find .
Wednesday, October 31, 12
from batou.component import Component
   from batou.lib.file import File

   class Hello(Component):

          def configure(self):
              self += File('hello',
                           content='Hello world')



                            components/hello/component.py
Wednesday, October 31, 12
[hosts]
   localhost = hello




                            environments/dev.cfg
Wednesday, October 31, 12
$ bin/batou-local dev localhost
   Updating Hello > File(hello) > Presence(hello)
   Updating Hello > File(hello) > Content(hello)




Wednesday, October 31, 12
./
                     ./components
                     ./environments
                     ...
                     ./work
                     ./work/hello
                     ./work/hello/hello




                                   $ find .
Wednesday, October 31, 12
$ bin/batou-local dev localhost




Wednesday, October 31, 12
$ cat "foo" > work/hello/hello
   $ bin/batou-local dev localhost
   Updating Hello > File(hello) > Content(hello)




Wednesday, October 31, 12
[environment]
   service_user = test
   host_domain = gocept.net

   [hosts]
   test01 = hello
   test02 = hello




                            environments/prod.cfg
Wednesday, October 31, 12
$ bin/batou-remote prod
   test02.gocept.net: connecting
   test01.gocept.net: connecting
   test01.gocept.net: bootstrapping
   test02.gocept.net: bootstrapping
   OK
   OK
   Deploying test01.gocept.net/hello
   Updating Hello > File(hello) > Presence(hello)
   Updating Hello > File(hello) > Content(hello)
   OK
   Deploying test02.gocept.net/hello
   Updating Hello > File(hello) > Presence(hello)
   Updating Hello > File(hello) > Content(hello)
   OK


Wednesday, October 31, 12
$ bin/batou-remote prod
   test02.gocept.net: connecting
   test01.gocept.net: connecting
   test01.gocept.net: bootstrapping
   test02.gocept.net: bootstrapping
   OK
   OK
   Deploying test01.gocept.net/hello
   OK
   Deploying test02.gocept.net/hello
   OK




Wednesday, October 31, 12
HELLO WORLD


    • Komponenten              und Environments

    • batou-local           im Konfiguration eines Hosts lokal zu realisieren

    • batou-remote            um eine ganze Umgebung zu deployen

    • Konvergenz            und Idempotenz



Wednesday, October 31, 12
IN DEN KANINCHENBAU



    • ein        Programm

    • verwaltet             mit Supervisor




Wednesday, October 31, 12
DAS PROGRAMM

                            #!/usr/bin/env python
                            import time
                            while True:
                                print 'Hello, world!'
                                time.sleep(1)




Wednesday, October 31, 12
KOMPONENTE
 from batou.component import Component
 from batou.lib.file import File

 class Hello(Component):

               def configure(self):
                   self += File('hello',
                       source='hello.py',
                       mode=0o755)

                            components/hello/component.py
Wednesday, October 31, 12
ENVIRONMENT



  [hosts]
  localhost = hello




                             environments/dev.cfg
Wednesday, October 31, 12
INSTALLATION



   $ bin/batou-local dev localhost
   Updating Hello > File(hello) > Presence(hello)
   Updating Hello > File(hello) > Content(hello)
   Updating Hello > File(hello) > Mode(hello)




Wednesday, October 31, 12
LÄUFT?


                 $ ./work/hello/hello
                 Hello, world!
                 Hello, world!
                 ^C




Wednesday, October 31, 12
Wednesday, October 31, 12
BUILDOUT


               [buildout]
               parts = supervisor

               [supervisor]
               recipe = collective.recipe.supervisor



                            components/supervisor/buildout.cfg
Wednesday, October 31, 12
BUILDOUT

            from batou.component import Component
            from batou.lib.buildout import Buildout

            class Supervisor(Component):

                            def configure(self):
                                self += Buildout('supervisor',
                                                 python='2.7')

                             components/supervisor/component.py
Wednesday, October 31, 12
SERVER-ADRESSE

    [buildout]
    parts = supervisor

    [supervisor]
    recipe = collective.recipe.supervisor
    port = {{component.address.listen}}
    serverurl =
        http://{{component.address.listen}}


                            components/supervisor/buildout.cfg
Wednesday, October 31, 12
SERVER-ADRESSE
            from batou.component import Component
            from batou.lib.buildout import Buildout
            from batou.utils import Address

            class Supervisor(Component):
                port = 9000
                def configure(self):
                    self.address = Address(
                        self.host.fqdn, self.port)
                    self += Buildout('supervisor',
                                     python='2.7')
                            components/supervisor/component.py
Wednesday, October 31, 12
NETZWERKADRESSEN

                        a = Address('localhost:631')
                        a = Address('localhost', '631')

                        str(a.connect) == 'localhost:631'
                        a.connect.host == 'localhost'
                        a.connect.port == '631'

                        str(a.listen) == '127.0.0.1:631'
                        a.listen.host == '127.0.0.1'
                        a.listen.port == '631'

Wednesday, October 31, 12
SERVER-ADRESSE
            from batou.component import Component
            from batou.lib.buildout import Buildout
            from batou.utils import Address

            class Supervisor(Component):
                port = 9000
                def configure(self):
                    self.address = Address(
                        self.host.fqdn, self.port)
                    self += Buildout('supervisor',
                                     python='2.7')
                            components/supervisor/component.py
Wednesday, October 31, 12
SERVER-ADRESSE

   [hosts]
   localhost = program, supervisor

   [component:supervisor]
   port = 6000




                              environments/dev.cfg
Wednesday, October 31, 12
WELCHE PROGRAMME
                           STARTEN?
 from batou.component import Component
 from batou.lib.file import File

 class Hello(Component):

        def configure(self):
          self += File('hello',
            source='hello.py', mode=0o755)
          self.provide('program',
            '{}/hello'.format(self.workdir))
                            components/hello/component.py
Wednesday, October 31, 12
WELCHE PROGRAMME
                           STARTEN?

 class Supervisor(Component):

        def configure(self):
          self.programs = self.require(
                        w
            'program', host=self.host)
          self += Buildout('supervisor',
                           python='2.7')


                            components/supervisor/component.py
Wednesday, October 31, 12
WELCHE PROGRAMME
                           STARTEN?
    [buildout]
    parts = supervisor
    [supervisor]
    recipe = collective.recipe.supervisor
    port = {{component.address.listen}}
    serverurl = ...
    programs =
    {%- for program in component.programs %}
        {{loop.index0}} prog{{loop.index}}
             {{program}} true
    {% endfor -%}
                            components/supervisor/buildout.cfg
Wednesday, October 31, 12
RESSOURCEN UND
                            ABHÄNGIGKEITEN


    • provide(key,             value)

    • require(key,             host=None) => [x, y, z]

    • require_one(key,             host=None) => x




Wednesday, October 31, 12
RESSOURCEN UND
                             ABHÄNGIGKEITEN

    • provide               ohne require

    • require               ohne provide

    • require_one               mit != 1 Element

    • Flapping              durch Sortieren vermeiden.

    • Dependencies                werden automatisch gefunden


Wednesday, October 31, 12
HOOK KOMPONENTEN
 from batou.component import Component
 from batou.lib.file import File

 class Hello(Component):

        def configure(self):
          self += File('hello',
            source='hello.py', mode=0o755)
          self += Program('hello', command='hello')

                            components/hello/component.py
Wednesday, October 31, 12
class Program(HookComponent):
  namevar = 'name'
  key = 'supervisor:Program'

      command = None
      program_template = '{name} {command} true'

      def configure(self):
        super(Program, self).configure()
        self.command = os.path.normpath(
          os.path.join(self.workdir, self.command))

      def format(self, supervisor):
        return self.program_template.format(
           name=self.name, command=self.command)
Wednesday, October 31, 12
HOOK COMPONENTS
 class Program(HookComponent):
   key = 'supervisor:Program'                         Kann eigentlich nicht
   ...                                                  hier leben - muss
                                                       importierbar sein!
 class Supervisor(Component):

        def configure(self):
          self.programs = self.require(
            Program.key, host=self.host)
          self += Buildout('supervisor',
                           python='2.7')
                            components/supervisor/component.py
Wednesday, October 31, 12
WELCHE PROGRAMME
                            STARTEN
[buildout]
parts = supervisor
[supervisor]
recipe = collective.recipe.supervisor
port = {{component.address.listen}}
serverurl = ...
programs =
{%- for program in component.programs %}
    {{loop.index0}} {{program.format}}
{% endfor -%}
                            components/supervisor/buildout.cfg
Wednesday, October 31, 12
SUPERVISOR STARTEN
 class Supervisor(Component):
   def configure(self):
     ...
   def verify(self):
     self.assert_file_is_current(
             'var/supervisord.pid',
             ['.batou.buildout.success'])
     self.assert_no_subcomponent_changes()

       def update(self):
         out, err = self.cmd('bin/supervisorctl pid')
          try:
            int(out)
          except ValueError:
            self.cmd('bin/supervisord')
          else:
            self.cmd('bin/supervisorctl reload')

Wednesday, October 31, 12
@REBOOT
   class Service(Component):
     namevar = 'executable'       Nur ein "bag".
     pidfile = None

   class Supervisor(Component):
     def configure(self):
       ...
       self += Service('bin/supervisord',
         pidfile='var/supervisord.pid')



Wednesday, October 31, 12
PLATTFORMEN
@platform('flyingcircus.io', Service)
class UserInit(Component):

       def configure(self):
         target = '/var/spool/init.d/{}/{}'.format(
           self.environment.service_user,
           basename(self.parent.executable))
         self += File(target,
                      source='init.sh',
                      is_template=True,
                      mode=0o755,
                      leading=True)
Wednesday, October 31, 12
PLATTFORMEN

  [environment]
  host_domain = flyingcircus.io
  platform = flyingcircus.io

  $ bin/batou-local --platform= 
    production test01 # keine Plattform!




Wednesday, October 31, 12
REVIEW
    • File              taucht häufig auf

    • Address

    • Jinja2-Templates

    • Environment             overrides

    • Ressourcen             + HookComponents

    • verify/update-Cycle

    • Plattform-Spezifika

Wednesday, October 31, 12
TIPPS

    • Komponenten            unabhängig von Host

    • Gemeinsamkeiten           in Komponenten bündeln

    • verify/update         so kurz wie nur möglich

    • je abstrakter eine Komponente desto unwarscheinlicher trifft
        man verify/update


Wednesday, October 31, 12
VORDEFINIERTE
                                   KOMPONENTEN

                            File    VirtualEnv    Buildout    zip



                    Secrets          Supervisor   Download   CMMI



                            git         svn         tar      cron


Wednesday, October 31, 12
FAZIT


    • modell-getrieben             aber pragmatisch

    • Konvergenz             und Idempotenz

    • Der Teufel            liegt im Detail. Immer wieder.




Wednesday, October 31, 12
AUSSICHT


    • Dokumentation

    • Bessere               Fehlermeldungen

    • Besserer              Status-Output

    • Alternativen             zu SSH/HG



Wednesday, October 31, 12
http://mobro.co/theuni


Wednesday, October 31, 12
FRAGEN?

    • http://bitbucket.org/gocept/batou

    • http://packages.python.org/batou




    • Bitte                 gebt mir Bierdeckelfeedback!



    • http://mobro.co/theuni

Wednesday, October 31, 12

Más contenido relacionado

La actualidad más candente

[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)
Evgeny Kaziak
 
2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku
ronnywang_tw
 
YAPC::Brasil 2009, POE
YAPC::Brasil 2009, POEYAPC::Brasil 2009, POE
YAPC::Brasil 2009, POE
Thiago Rondon
 

La actualidad más candente (20)

Puppet demo
Puppet demoPuppet demo
Puppet demo
 
Counting on God
Counting on GodCounting on God
Counting on God
 
Puppet modules for Fun and Profit
Puppet modules for Fun and ProfitPuppet modules for Fun and Profit
Puppet modules for Fun and Profit
 
[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)[JAM 1.2] Design & Multitasking (Andrew Solovey)
[JAM 1.2] Design & Multitasking (Andrew Solovey)
 
rake puppetexpert:create - Puppet Camp Silicon Valley 2014
rake puppetexpert:create - Puppet Camp Silicon Valley 2014rake puppetexpert:create - Puppet Camp Silicon Valley 2014
rake puppetexpert:create - Puppet Camp Silicon Valley 2014
 
How to host an app for $20 in 20min using buildout and hostout
How to host an app  for $20 in 20min using buildout and hostoutHow to host an app  for $20 in 20min using buildout and hostout
How to host an app for $20 in 20min using buildout and hostout
 
NodeJs
NodeJsNodeJs
NodeJs
 
Stanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet ModulesStanford Hackathon - Puppet Modules
Stanford Hackathon - Puppet Modules
 
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
 
Ansible
AnsibleAnsible
Ansible
 
2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku2012 coscup - Build your PHP application on Heroku
2012 coscup - Build your PHP application on Heroku
 
DevOps with Fabric
DevOps with FabricDevOps with Fabric
DevOps with Fabric
 
Making environment for_infrastructure_as_code
Making environment for_infrastructure_as_codeMaking environment for_infrastructure_as_code
Making environment for_infrastructure_as_code
 
Anatomy of a reusable module
Anatomy of a reusable moduleAnatomy of a reusable module
Anatomy of a reusable module
 
YAPC::Brasil 2009, POE
YAPC::Brasil 2009, POEYAPC::Brasil 2009, POE
YAPC::Brasil 2009, POE
 
Puppet @ Seat
Puppet @ SeatPuppet @ Seat
Puppet @ Seat
 
Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014Writing and Publishing Puppet Modules - PuppetConf 2014
Writing and Publishing Puppet Modules - PuppetConf 2014
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
 
Tutorial Puppet
Tutorial PuppetTutorial Puppet
Tutorial Puppet
 
Building a Cauldron for Chef to Cook In
Building a Cauldron for Chef to Cook InBuilding a Cauldron for Chef to Cook In
Building a Cauldron for Chef to Cook In
 

Destacado

Destacado (9)

batou - multi(component|host|environment|.*) deployment
batou - multi(component|host|environment|.*) deploymentbatou - multi(component|host|environment|.*) deployment
batou - multi(component|host|environment|.*) deployment
 
Modern, scalable deployment for plone
Modern, scalable deployment for ploneModern, scalable deployment for plone
Modern, scalable deployment for plone
 
Flying Circus Ceph Case Study (CEPH Usergroup Berlin)
Flying Circus Ceph Case Study (CEPH Usergroup Berlin)Flying Circus Ceph Case Study (CEPH Usergroup Berlin)
Flying Circus Ceph Case Study (CEPH Usergroup Berlin)
 
Backy - VM backup beyond bacula
Backy - VM backup beyond baculaBacky - VM backup beyond bacula
Backy - VM backup beyond bacula
 
Ppt of environment
Ppt of environmentPpt of environment
Ppt of environment
 
NixOS @ Hackspace Jena
NixOS @ Hackspace JenaNixOS @ Hackspace Jena
NixOS @ Hackspace Jena
 
Environment ppt
Environment pptEnvironment ppt
Environment ppt
 
Study: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving CarsStudy: The Future of VR, AR and Self-Driving Cars
Study: The Future of VR, AR and Self-Driving Cars
 
Hype vs. Reality: The AI Explainer
Hype vs. Reality: The AI ExplainerHype vs. Reality: The AI Explainer
Hype vs. Reality: The AI Explainer
 

Similar a Batou - multi-(host|component|environment|version|platform) deployment

Fabric-让部署变得简单
Fabric-让部署变得简单Fabric-让部署变得简单
Fabric-让部署变得简单
Eric Lo
 
Real world scala
Real world scalaReal world scala
Real world scala
lunfu zhong
 
ZopeSkel & Buildout packages
ZopeSkel & Buildout packagesZopeSkel & Buildout packages
ZopeSkel & Buildout packages
Quintagroup
 
CapitalCamp Features
CapitalCamp FeaturesCapitalCamp Features
CapitalCamp Features
Phase2
 

Similar a Batou - multi-(host|component|environment|version|platform) deployment (20)

Stupid Buildout Tricks
Stupid Buildout TricksStupid Buildout Tricks
Stupid Buildout Tricks
 
Continuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using HudsonContinuous Integration Testing for Plone Using Hudson
Continuous Integration Testing for Plone Using Hudson
 
Effective Python Package Management [PyCon Canada 2017]
Effective Python Package Management [PyCon Canada 2017]Effective Python Package Management [PyCon Canada 2017]
Effective Python Package Management [PyCon Canada 2017]
 
Acceptance & Integration Testing With Behat (PBC11)
Acceptance & Integration Testing With Behat (PBC11)Acceptance & Integration Testing With Behat (PBC11)
Acceptance & Integration Testing With Behat (PBC11)
 
Fabric-让部署变得简单
Fabric-让部署变得简单Fabric-让部署变得简单
Fabric-让部署变得简单
 
Plone pwns
Plone pwnsPlone pwns
Plone pwns
 
Docker Tutorial.pdf
Docker Tutorial.pdfDocker Tutorial.pdf
Docker Tutorial.pdf
 
Real world scala
Real world scalaReal world scala
Real world scala
 
Puppet Camp Chicago 2014: Docker and Puppet: 1+1=3 (Intermediate)
Puppet Camp Chicago 2014: Docker and Puppet: 1+1=3 (Intermediate)Puppet Camp Chicago 2014: Docker and Puppet: 1+1=3 (Intermediate)
Puppet Camp Chicago 2014: Docker and Puppet: 1+1=3 (Intermediate)
 
ZopeSkel & Buildout packages
ZopeSkel & Buildout packagesZopeSkel & Buildout packages
ZopeSkel & Buildout packages
 
Software Packaging for Cross OS Distribution
Software Packaging for Cross OS DistributionSoftware Packaging for Cross OS Distribution
Software Packaging for Cross OS Distribution
 
[Hands-on] Kubernetes | Nov 18, 2017
[Hands-on] Kubernetes | Nov 18, 2017[Hands-on] Kubernetes | Nov 18, 2017
[Hands-on] Kubernetes | Nov 18, 2017
 
Releasing and deploying python tools
Releasing and deploying python toolsReleasing and deploying python tools
Releasing and deploying python tools
 
Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010Macruby - RubyConf Presentation 2010
Macruby - RubyConf Presentation 2010
 
Ext JS 4: Advanced Expert Techniques
Ext JS 4: Advanced Expert TechniquesExt JS 4: Advanced Expert Techniques
Ext JS 4: Advanced Expert Techniques
 
Clouds and Tools: Cheat Sheets & Infographics
Clouds and Tools: Cheat Sheets & InfographicsClouds and Tools: Cheat Sheets & Infographics
Clouds and Tools: Cheat Sheets & Infographics
 
CapitalCamp Features
CapitalCamp FeaturesCapitalCamp Features
CapitalCamp Features
 
2009 cluster user training
2009 cluster user training2009 cluster user training
2009 cluster user training
 
Simple build tool
Simple build toolSimple build tool
Simple build tool
 
Kube Your Enthusiasm - Tyler Britten
Kube Your Enthusiasm - Tyler BrittenKube Your Enthusiasm - Tyler Britten
Kube Your Enthusiasm - Tyler Britten
 

Batou - multi-(host|component|environment|version|platform) deployment

  • 1. BATOU Multi-(Component|Environment|Host|Platform) deployment Christian Theune <ct@gocept.com> Wednesday, October 31, 12
  • 4. INHALT • Motivation • Hello World • Tiefer in den Kaninchenbau • Ausblick Wednesday, October 31, 12
  • 11. PARTY LIKE ITS ... • 1999: PHP FTP-Uploads • 2001: Shell-Skripte um Zope-Instanzen zu verwalten • 2003: Zope 2.4 “mkinstance” • 2006: zc.buildout • 2009: Fabric Wednesday, October 31, 12
  • 12. BATOU VS Puppet, Chef Fabric, Salt JuJu Systemkonfiguration versus Service Modellierung Laufzeitumgebung deployment Wednesday, October 31, 12
  • 13. HELLO WORLD http://www.flickr.com/photos/oskay/472097903 Wednesday, October 31, 12
  • 14. ./.hg ./buildout.cfg ./bootstrap.py ./components ./components/hello ./components/hello/component.py ./environments ./environments/dev.cfg ./environments/prod.cfg $ find . Wednesday, October 31, 12
  • 15. from batou.component import Component from batou.lib.file import File class Hello(Component):    def configure(self):        self += File('hello', content='Hello world') components/hello/component.py Wednesday, October 31, 12
  • 16. [hosts] localhost = hello environments/dev.cfg Wednesday, October 31, 12
  • 17. $ bin/batou-local dev localhost Updating Hello > File(hello) > Presence(hello) Updating Hello > File(hello) > Content(hello) Wednesday, October 31, 12
  • 18. ./ ./components ./environments ... ./work ./work/hello ./work/hello/hello $ find . Wednesday, October 31, 12
  • 19. $ bin/batou-local dev localhost Wednesday, October 31, 12
  • 20. $ cat "foo" > work/hello/hello $ bin/batou-local dev localhost Updating Hello > File(hello) > Content(hello) Wednesday, October 31, 12
  • 21. [environment] service_user = test host_domain = gocept.net [hosts] test01 = hello test02 = hello environments/prod.cfg Wednesday, October 31, 12
  • 22. $ bin/batou-remote prod test02.gocept.net: connecting test01.gocept.net: connecting test01.gocept.net: bootstrapping test02.gocept.net: bootstrapping OK OK Deploying test01.gocept.net/hello Updating Hello > File(hello) > Presence(hello) Updating Hello > File(hello) > Content(hello) OK Deploying test02.gocept.net/hello Updating Hello > File(hello) > Presence(hello) Updating Hello > File(hello) > Content(hello) OK Wednesday, October 31, 12
  • 23. $ bin/batou-remote prod test02.gocept.net: connecting test01.gocept.net: connecting test01.gocept.net: bootstrapping test02.gocept.net: bootstrapping OK OK Deploying test01.gocept.net/hello OK Deploying test02.gocept.net/hello OK Wednesday, October 31, 12
  • 24. HELLO WORLD • Komponenten und Environments • batou-local im Konfiguration eines Hosts lokal zu realisieren • batou-remote um eine ganze Umgebung zu deployen • Konvergenz und Idempotenz Wednesday, October 31, 12
  • 25. IN DEN KANINCHENBAU • ein Programm • verwaltet mit Supervisor Wednesday, October 31, 12
  • 26. DAS PROGRAMM #!/usr/bin/env python import time while True: print 'Hello, world!' time.sleep(1) Wednesday, October 31, 12
  • 27. KOMPONENTE from batou.component import Component from batou.lib.file import File class Hello(Component): def configure(self): self += File('hello', source='hello.py', mode=0o755) components/hello/component.py Wednesday, October 31, 12
  • 28. ENVIRONMENT [hosts] localhost = hello environments/dev.cfg Wednesday, October 31, 12
  • 29. INSTALLATION $ bin/batou-local dev localhost Updating Hello > File(hello) > Presence(hello) Updating Hello > File(hello) > Content(hello) Updating Hello > File(hello) > Mode(hello) Wednesday, October 31, 12
  • 30. LÄUFT? $ ./work/hello/hello Hello, world! Hello, world! ^C Wednesday, October 31, 12
  • 32. BUILDOUT [buildout] parts = supervisor [supervisor] recipe = collective.recipe.supervisor components/supervisor/buildout.cfg Wednesday, October 31, 12
  • 33. BUILDOUT from batou.component import Component from batou.lib.buildout import Buildout class Supervisor(Component): def configure(self): self += Buildout('supervisor', python='2.7') components/supervisor/component.py Wednesday, October 31, 12
  • 34. SERVER-ADRESSE [buildout] parts = supervisor [supervisor] recipe = collective.recipe.supervisor port = {{component.address.listen}} serverurl = http://{{component.address.listen}} components/supervisor/buildout.cfg Wednesday, October 31, 12
  • 35. SERVER-ADRESSE from batou.component import Component from batou.lib.buildout import Buildout from batou.utils import Address class Supervisor(Component): port = 9000 def configure(self): self.address = Address( self.host.fqdn, self.port) self += Buildout('supervisor', python='2.7') components/supervisor/component.py Wednesday, October 31, 12
  • 36. NETZWERKADRESSEN a = Address('localhost:631') a = Address('localhost', '631') str(a.connect) == 'localhost:631' a.connect.host == 'localhost' a.connect.port == '631' str(a.listen) == '127.0.0.1:631' a.listen.host == '127.0.0.1' a.listen.port == '631' Wednesday, October 31, 12
  • 37. SERVER-ADRESSE from batou.component import Component from batou.lib.buildout import Buildout from batou.utils import Address class Supervisor(Component): port = 9000 def configure(self): self.address = Address( self.host.fqdn, self.port) self += Buildout('supervisor', python='2.7') components/supervisor/component.py Wednesday, October 31, 12
  • 38. SERVER-ADRESSE [hosts] localhost = program, supervisor [component:supervisor] port = 6000 environments/dev.cfg Wednesday, October 31, 12
  • 39. WELCHE PROGRAMME STARTEN? from batou.component import Component from batou.lib.file import File class Hello(Component): def configure(self): self += File('hello', source='hello.py', mode=0o755) self.provide('program', '{}/hello'.format(self.workdir)) components/hello/component.py Wednesday, October 31, 12
  • 40. WELCHE PROGRAMME STARTEN? class Supervisor(Component): def configure(self): self.programs = self.require( w 'program', host=self.host) self += Buildout('supervisor', python='2.7') components/supervisor/component.py Wednesday, October 31, 12
  • 41. WELCHE PROGRAMME STARTEN? [buildout] parts = supervisor [supervisor] recipe = collective.recipe.supervisor port = {{component.address.listen}} serverurl = ... programs = {%- for program in component.programs %} {{loop.index0}} prog{{loop.index}} {{program}} true {% endfor -%} components/supervisor/buildout.cfg Wednesday, October 31, 12
  • 42. RESSOURCEN UND ABHÄNGIGKEITEN • provide(key, value) • require(key, host=None) => [x, y, z] • require_one(key, host=None) => x Wednesday, October 31, 12
  • 43. RESSOURCEN UND ABHÄNGIGKEITEN • provide ohne require • require ohne provide • require_one mit != 1 Element • Flapping durch Sortieren vermeiden. • Dependencies werden automatisch gefunden Wednesday, October 31, 12
  • 44. HOOK KOMPONENTEN from batou.component import Component from batou.lib.file import File class Hello(Component): def configure(self): self += File('hello', source='hello.py', mode=0o755) self += Program('hello', command='hello') components/hello/component.py Wednesday, October 31, 12
  • 45. class Program(HookComponent): namevar = 'name' key = 'supervisor:Program' command = None program_template = '{name} {command} true' def configure(self): super(Program, self).configure() self.command = os.path.normpath( os.path.join(self.workdir, self.command)) def format(self, supervisor): return self.program_template.format( name=self.name, command=self.command) Wednesday, October 31, 12
  • 46. HOOK COMPONENTS class Program(HookComponent): key = 'supervisor:Program' Kann eigentlich nicht ... hier leben - muss importierbar sein! class Supervisor(Component): def configure(self): self.programs = self.require( Program.key, host=self.host) self += Buildout('supervisor', python='2.7') components/supervisor/component.py Wednesday, October 31, 12
  • 47. WELCHE PROGRAMME STARTEN [buildout] parts = supervisor [supervisor] recipe = collective.recipe.supervisor port = {{component.address.listen}} serverurl = ... programs = {%- for program in component.programs %} {{loop.index0}} {{program.format}} {% endfor -%} components/supervisor/buildout.cfg Wednesday, October 31, 12
  • 48. SUPERVISOR STARTEN class Supervisor(Component): def configure(self): ... def verify(self): self.assert_file_is_current( 'var/supervisord.pid', ['.batou.buildout.success']) self.assert_no_subcomponent_changes() def update(self): out, err = self.cmd('bin/supervisorctl pid') try: int(out) except ValueError: self.cmd('bin/supervisord') else: self.cmd('bin/supervisorctl reload') Wednesday, October 31, 12
  • 49. @REBOOT class Service(Component): namevar = 'executable' Nur ein "bag". pidfile = None class Supervisor(Component): def configure(self): ... self += Service('bin/supervisord', pidfile='var/supervisord.pid') Wednesday, October 31, 12
  • 50. PLATTFORMEN @platform('flyingcircus.io', Service) class UserInit(Component): def configure(self): target = '/var/spool/init.d/{}/{}'.format( self.environment.service_user, basename(self.parent.executable)) self += File(target, source='init.sh', is_template=True, mode=0o755, leading=True) Wednesday, October 31, 12
  • 51. PLATTFORMEN [environment] host_domain = flyingcircus.io platform = flyingcircus.io $ bin/batou-local --platform= production test01 # keine Plattform! Wednesday, October 31, 12
  • 52. REVIEW • File taucht häufig auf • Address • Jinja2-Templates • Environment overrides • Ressourcen + HookComponents • verify/update-Cycle • Plattform-Spezifika Wednesday, October 31, 12
  • 53. TIPPS • Komponenten unabhängig von Host • Gemeinsamkeiten in Komponenten bündeln • verify/update so kurz wie nur möglich • je abstrakter eine Komponente desto unwarscheinlicher trifft man verify/update Wednesday, October 31, 12
  • 54. VORDEFINIERTE KOMPONENTEN File VirtualEnv Buildout zip Secrets Supervisor Download CMMI git svn tar cron Wednesday, October 31, 12
  • 55. FAZIT • modell-getrieben aber pragmatisch • Konvergenz und Idempotenz • Der Teufel liegt im Detail. Immer wieder. Wednesday, October 31, 12
  • 56. AUSSICHT • Dokumentation • Bessere Fehlermeldungen • Besserer Status-Output • Alternativen zu SSH/HG Wednesday, October 31, 12
  • 58. FRAGEN? • http://bitbucket.org/gocept/batou • http://packages.python.org/batou • Bitte gebt mir Bierdeckelfeedback! • http://mobro.co/theuni Wednesday, October 31, 12