Bombardier at a glance — Bombardier v1.00 documentation

### Navigation

- index
- Bombardier v1.00 documentation »

# Bombardier at a glance

Bombardier provides all of the components of a mature change management system for production datacenters:

> - A package format for delivering application binary data and application setup script files
> - A cross-platform scripting language and libraries for package installation, configuration, verification, and uninstallation (basically Python)
> - A centralized Configuration Management Database (CMDB) for keeping track of all configuration items (CIs), with a means for packages that are being delivered to a target system to read configuration items for that package
> - A means for storing and tracking all packages in the system in a Definitive Software Library (DSL)
> - A central console for managing all network operations on all servers in a network using a scriptable command-line interface.

The goal of this document is to give you enough technical specifics to understand how Bombardier works, but this isn’t intended to be a tutorial or reference – but we’ve got both! When you’re ready to start a project, you can start with the tutorial or dive right into more detailed documentation.

## Design your Packages

A set of software packages are the heart of a Bombardier system. When thinking about rolling out Bombardier, ask yourself: What components of my datacenter are...

> - configuration-intensive,
> - change frequently, and
> - are critical to keeping my customers happy?

Perhaps this starts with a core website or an LDAP directory or a backend database system. Bombardier is perfect for managing all these things, and many more. Start with the components of the system which make you the most nervous, which have the most mystery around them and “tribal knowledge” around their installation, configuration, and maintenance. However, it may be easiest to tackle some simple and well-defined problems first: perhaps your SVN repository.

Most datacenters have large, dark, frightening silos of murky know-how around managing certain services. Bombardier is typically used like a flash-light to shine light in each of these murky areas one at a time to verify and prove that installation and configuration processes are known and repeatable and to then provide a simple and universal tool for their ongoing management. As you tackle these areas of your datacenter one at a time, the process will gain momentum: administrators will wonder why it took so long to organize these processes, they will demand that all critical components be packaged, and you will see a gradual relief spread over your IT staff as they begin to realize that they know how to perform any type of maintenance in the datacenter quickly, efficiently, and flawlessly whenever needed.

### Not everything needs to be packaged

Once you start converting things into packages, it can be tempting to have Bombardier manage everything. But there are quite a few software components that don’t need to be packaged at all. For example, if your operating system has a good software distribution system of its own such as Yum or APT, it will probably be preferable to use this system for installing run-of-the-mill utilities such as screen or vim; things that don’t take any configuration, don’t provide any end-value to your customers, and pose almost no risk to causing a problem with the healthy operating of other things on the server, such as Apache HTTPD. Bombardier packages are really only useful for managing highly critical software components that provide value to someone outside your company or department.

## What a package looks like

### metadata

A package consists of two things: metadata and a Python class. The metadata describes the package– what it does, what configuration data it needs, what dependencies it has, etc. An example of package metadata is this:

    class_name: SvnServer.SvnServer
    configuration:
      fqdn: ''
      ip_address: ''
      ldap:
        admin_email: admin@test.com
        admin_pass: abc123
        admin_user: admin
        backup_dir: NOT_CONFIGURED
        base: dc=mycompany,dc=com
        groupOu: UNKNOWN
        ignore_users: []
        password_complexity: '100'
        port: '389'
        schema: {}
        userOu: UNKNOWN
        users: {}
      ssl_cert: ''
      ssl_key: ''
      svn:
        admin_pass: NONE
        daemon_group: www-data
        daemon_user: www-data
        friendly_email: The SVN admins
        lock_dir: /var/lock/apache2
        log_dir: /var/log/apache2
        name: Un-named repository
        ou: UKNOWN
        repositories: []
        repository_root: ''
        rights: {}
        server_port: '443'
        server_root: /etc/apache2
    dependencies:
    - LdapServer
    executables:
    - configure
    - generate_auth_files
    - install
    - start
    - stop
    - uninstall
    - verify
    injectors:
      LdapManager:
        path: /var/deploy/repos/injectors/LdapManager-526.tar.gz
        svn: https://svn.ge-is-beta.com/icontrol/src/trunk/libs/LdapManager
        version: '526'
      apache_templates:
        path: /var/deploy/repos/injectors/apache_templates-526.tar.gz
        svn: https://svn.ge-is-beta.com/icontrol/src/trunk/injector/apache_templates/
        version: '526'
      sousaphone:
        path: /var/deploy/repos/injectors/sousaphone-526.tar.gz
        svn: https://svn.ge-is-beta.com/icontrol/src/trunk/injector/sousaphone/
        version: '526'
    libs:
      LdapManager:
        path: /var/deploy/repos/libs/LdapManager-526.tar.gz
        svn: https://svn.ge-is-beta.com/icontrol/src/trunk/libs/LdapManager
        version: '526'
      SvnServer:
        path: /var/deploy/repos/libs/SvnServer-526.tar.gz
    package-version: 5
    release: 26

This metadata defines what configuration data the package requires (in this case, test.directory and test.value), what executables it provides (more on this later). What Python libraries are required to install and manage this package (under libs), and what supplementary files should be shipped with the package (typically these are the files that will actually get installed onto the server), which are called “injectors.”

### Class file

The class that is responsible for installing, configuring, verifying and uninstalling the package needs to be called out under the class_name directive in the package metadata. This class can be part of the package, under the libs directory. Here’s a quick example of a class:

    class SvnServer(SpkgV5):
        "Class for SVN/Apache installation"

        def __init__(self, config):
            SpkgV5.__init__(self, config)

            self.debug = "False"
            domain_white_list = config.listobj("svn.domain_white_list", [], optional=True)
            self.domain_white_list = ','.join(domain_white_list)
            self.friendly_email = config.string('svn.friendly_email', "The SVN admins")
            self.fqdn = config.string('fqdn')
            self.company = config.string("svn.company_name", optional=True)
            if not self.company:
                self.company = self.fqdn
            self.days_before_token_expiration = config.string("svn.days_before_token_expiration",
                                                              "2", optional=True)
            self.server_root = config.string("svn.server_root", "/etc/apache2")
            self.lock_dir = config.string("svn.lock_dir", '/var/lock/apache2')
            self.daemon_user = config.string("svn.daemon_user", 'www-data')
            self.daemon_group = config.string("svn.daemon_group", 'www-data')
            self.log_dir = config.string("svn.log_dir", '/var/log/apache2')
            self.admin_pass = config.string("svn.admin_pass", "NONE")
            self.server_port = config.string("svn.server_port", '443')

        def configure(self):
            "Standard configuration method for a package"
            self.stop()
            self._info("Current directory: %s" % os.getcwd())
            sites_dir = os.path.join(self.server_root, "sites-enabled")
            if not os.path.isdir(sites_dir):
                os.system("mkdir -p %s" % sites_dir)
            config_file = os.path.join(self.server_root, 'apache2.conf')
            template_file = "apache_templates/apache-svn.template"
            status1 = self._modify_template(template_file, config_file)
            self._info("Creating repository configuration")
            status2 = self._create_repositories()
            self._info("Generating authorization file...")
            status3 = self.generate_auth_files()
            if [status1, status2, status3] == 3 * [OK]:
                return OK
            return FAIL

## Install it

Packages have to get installed on a computer somewhere in order for them to be useful. We call the computers that are part of the datacenter “machines” in order to distinguish them from the Bombardier server.

### Set up a machine

A machine has a metadata file similar to the package just shown. Here’s an example of a miniumum machine configuration file for a machine svn_server:

    default_user: root
    ip_address: 10.10.1.70
    platform: linux

If you’re going to install the SVN package on this server, you’ll have to add the configuration values to it that the package requires (not shown). Finally, you’ll need to actually install the package onto the remote server:

    ( machine svn_server )> inst svn
    >>> Job name: admin@svn_server-10
      |  admin@svn_server-10 | Package SvnServer does not have a priority (assuming 100)
      | admin@svn_server-10 | Packages remaining to install (in order): ['SvnServer']
      | admin@svn_server-10 | Currently installing package priority 100 [SvnServer]
      | admin@svn_server-10 | svn_server installing SvnServer-27
      | admin@svn_server-10 | [injectors]|Template: settings.template
      | admin@svn_server-10 | [injectors]|Created: sousaphone/settings.py
      | admin@svn_server-10 | [injectors]|Installing the sousaphone webapp libraries...
      | admin@svn_server-10 | [injectors]|Template: sousaphone/header.html.template
      | admin@svn_server-10 | [injectors]|Created: /var/www/templates/header.html
      | admin@svn_server-10 | [injectors]|Template: sousaphone/password_policy.html.template
      | admin@svn_server-10 | [injectors]|Created: /var/www/site_media/password_policy.html
      |  admin@svn_server-10 | [injectors]|No PID file: /var/lock/apache2/apache.pid
      | admin@svn_server-10 | [injectors]|Current directory: /opt/spkg/svn_server/packages/SvnServer-27/injectors
      | admin@svn_server-10 | [injectors]|Template: apache_templates/apache-svn.template
      | admin@svn_server-10 | [injectors]|Created: /etc/apache2/apache2.conf
      | admin@svn_server-10 | [injectors]|Creating repository configuration
      | admin@svn_server-10 | [injectors]|Generating authorization file...
      | admin@svn_server-10 | install OK: SvnServer-27
      | admin@svn_server-10 | Verifying package SvnServer-27
      | admin@svn_server-10 | verify OK: SvnServer-27
      | svn_server | Finished install for SvnServer.
      | svn_server | Finished install for SvnServer.
    >>> Joining...
     info:
       Generated /etc/apache2/devel
       Generated /etc/apache2/partner
       Generated /etc/apache2/admin

    ( machine svn_server )> exec svn start
    >>> Job name: admin@svn_server-11
      | admin@svn_server-11 | Using SvnServer
      |  admin@svn_server-11 | Package SvnServer does not have a priority (assuming 100)
      | admin@svn_server-11 | Executing (start) inside package (SvnServer-27)
      | admin@svn_server-11 | [injectors]|Waiting for apache2 to start...
      | admin@svn_server-11 | start OK: SvnServer-27
      | svn_server | Finished execute for SvnServer.
      | svn_server | Finished execute for SvnServer.
    >>> Joining...
     time to start: 0

    ( machine svn_server )>

## Enjoy the free API

With that, you’ve got a free, and rich, Python API to write installation and configuration packages however you like. Bombardier also provides quite a bit of assistance on the remote machine side for making packages easier to create. For example, you’ll notice that the class SvnServer inherited from SpkgV5. With this inheritence you get the following:

### config object

A “config” object is passed into your constructor. This object provides your installer class with all the information that the administrator has configured for this machine. For example, if you want to know what daemon the Apache server should be configured to run as, you can request the information from the config object in the following way:

    apache_user = config.string("svn.daemon_user")

### logging methods

If you want to report-out the the user-interface anything of interest that happens during the installation, you can use the build-in logging methods:

> - self._debug()
> - self._info()
> - self._warning()
> - self._error()
> - self._critical()

While the installation is proceeding, the administrator running the package commands will be able to see what’s going on with the installation, and the details of the package actions will be recorded in Bombardier’s permanent log file for forensic analysis if that’s ever necessary.

### standard interface methods

Each package installation class must provide the following standard interface methods:

install()
  This method is called on the class when the user wants to install the package
configure()
  This method is called on the class when the user wants to make a configuration change to an already-installed system. Configuration is supported on already-installed systems and provides for those changes that you can make to a ‘live’ system.
verify()
  This method is used to verify that the software is deployed as-designed.
uninstall()
  This method is used when a package is to be removed (uninstalled) from the system. The package should provide for idempotance, meaning that the system should be left in exactly the same state after being uninstalled that it was before the package was installed.

### additional interface methods

Any non-public methods (methods that don’t start with an underscore) in your class will also be made available to the administrator for performing specific functions with that package. For example, `start`, `stop`, and `backup` are often added as public methods to a package class to start services and backup data.

## This is just the surface

This has been only a quick overview of Bombardier’s functionality. Some more useful features:

> - The Bombardier CLI :ref:` <topics-cli>` that provides for a great and simple command-line user experience.

The next obvious steps are for you to download Bombardier, read the tutorial. Thanks for your interest!

### Navigation

- index
- Bombardier v1.00 documentation »