Add Vagrantfile for docker VM
Add puppet manifest for docker container host
Update to Docker version 1.2.0, build fa7b24f
Add puppet configuration for ldap container
Add Dockerfile for ldap container
Demonstrate the problem of no service management

Without this patch the LDAP service is not configured in the ldap
container.  This patch addresses the problem by adding the same Puppet
configuration from the shared VM to the ldap node classification.

This patch demonstrates the issue of no service management when the
docker container is being built.  There are basic operations, like
adding files, and running simple commands, but the overall task of
starting the LDAP service and then loading an initial set of data into
it is problematic in the Docker model of super-lightweight services.

There are two paths forward from here.  The same Puppet code should be
usable with a heavier, but still "light" container that has systemd and
looks more like a full VM or VPS.  The Puppet code could be modified to
work in conjunction with docker to load the data in multiple stages.

The problem looks like:

    Info: Class[Openldap::Server::Config]: Scheduling refresh of Class[Openldap::Server::Service]
    Info: Class[Openldap::Server::Service]: Scheduling refresh of Service[slapd]
    Error: /Service[slapd]: Could not evaluate: Could not find init script for 'slapd'
    Error: /Service[slapd]: Failed to call refresh: Could not find init script for 'slapd'
    Notice: /Stage[main]/Openldap::Server::Slapdconf/File[/etc/openldap/slapd.d]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Openldap::Server::Slapdconf/Openldap::Server::Database[dc=jeffmccune,dc=net]/File[/var/lib/ldap]: Dependency Service[slapd] has failures: true
    Error: /Service[slapd]: Could not find init script for 'slapd'
    Warning: /Stage[main]/Openldap::Server::Slapdconf/File[/etc/openldap/slapd.d]: Skipping because of failed dependencies
    Warning: /Stage[main]/Openldap::Server::Slapdconf/Openldap::Server::Database[dc=jeffmccune,dc=net]/File[/var/lib/ldap]: Skipping because of failed dependencies
    Warning: /Stage[main]/Openldap::Server::Slapdconf/Openldap::Server::Database[dc=jeffmccune,dc=net]/Openldap_database[dc=jeffmccune,dc=net]: Skipping because of failed dependencies
    Notice: /Stage[main]/Openldap::Server::Slapdconf/Openldap::Server::Database[dc=jeffmccune,dc=net]/Openldap_database[dc=jeffmccune,dc=net]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Packages/Package[ruby-devel]/ensure: created
    Warning: /Stage[main]/Site::Openldap/Exec[core schema]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/File[/etc/openldap/data]: Skipping because of failed dependencies
    Notice: /Stage[main]/Site::Openldap/Exec[core schema]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/jeff_user.ldif]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/groups.ldif]: Dependency Service[slapd] has failures: true
    Warning: /Stage[main]/Site::Openldap/File[/etc/openldap/data/jeff_user.ldif]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/File[/etc/openldap/data/groups.ldif]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/File[/etc/openldap/data/jeff_group.ldif]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/File[/etc/openldap/data/site.ldif]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/File[/etc/openldap/data/users.ldif]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/Exec[cosine schema]: Skipping because of failed dependencies
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/jeff_group.ldif]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/site.ldif]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/users.ldif]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/Exec[cosine schema]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/Exec[inetorgperson schema]: Dependency Service[slapd] has failures: true
    Warning: /Stage[main]/Site::Openldap/Exec[inetorgperson schema]: Skipping because of failed dependencies
    Notice: /Stage[main]/Site::Openldap/Exec[nis schema]: Dependency Service[slapd] has failures: true
    Warning: /Stage[main]/Site::Openldap/Exec[nis schema]: Skipping because of failed dependencies
    Notice: /Stage[main]/Site::Openldap/Exec[dc=jeffmccune,dc=net]: Dependency Service[slapd] has failures: true
    Warning: /Stage[main]/Site::Openldap/Exec[dc=jeffmccune,dc=net]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/Exec[ou=Groups]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/Exec[ou=Users]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/Exec[cn=jeff,ou=Groups]: Skipping because of failed dependencies
    Warning: /Stage[main]/Site::Openldap/Exec[uid=jeff,ou=Users]: Skipping because of failed dependencies
    Notice: /Stage[main]/Site::Openldap/Exec[ou=Groups]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/Exec[ou=Users]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/Exec[cn=jeff,ou=Groups]: Dependency Service[slapd] has failures: true
    Notice: /Stage[main]/Site::Openldap/Exec[uid=jeff,ou=Users]: Dependency Service[slapd] has failures: true
    Info: Creating state file /var/lib/puppet/state/state.yaml
    Notice: Finished catalog run in 32.12 seconds
Add centos7vps base image that works with puppet but fails with systemd

Without this patch puppet cannot successfully configure the LDAP service
in the docker container because there is no functional service
management framework.  The centos:centos7 image has the fakesystemd
package installed as a replacement for the real systemd package.

This patch addresses the problem by creating a new base image that has a
fully functional system management framework in the form of the real
systemd package.

Puppet is able to configure the LDAP service using this base image,
albeit as a process running in a container that has systemd running
already.

For example, the following works to stand up LDAP.  What remains is to
port this process over to the ldap/Dockerfile.

First, make sure you have the docker-enter command, installed into
/usr/local/bin using:

    $ docker run -v /usr/local/bin:/target jpetazzo/nsenter

Then, build the centos7vps base image, run it, and run puppet inside the
container.  Note that /puppet is mounted from the Vagrant VM into the container
at /puppet.  This directory is mounted as a shared filesystem with the host
relative to the Vagrantfile.

    $ docker build -t centos7vps .
    $ CID=$(docker run --privileged -v /puppet:/puppet -t -i -d centos7vps)
    $ sudo /usr/local/bin/docker-enter $CID

Inside the container:

    bash-4.2# puppet apply -v --node_name_value ldap --modulepath /puppet/modules /puppet/manifests/ldap.pp
    Info: Loading facts
    Notice: Compiled catalog for ldap in environment production in 1.05 seconds
    Info: Applying configuration version '1411075793'
    Notice: /Stage[main]/Site::Packages/Package[make]/ensure: created
    Notice: /Stage[main]/Site::Packages/Package[rubygem-bundler]/ensure: created
    Notice: /Stage[main]/Site::Packages/Package[gcc]/ensure: created
    Notice: /Stage[main]/Openldap::Server::Install/Package[openldap-servers]/ensure: created
    Notice: /Stage[main]/Site::Packages/Package[telnet]/ensure: created
    Notice: /Stage[main]/Openldap::Client::Config/Augeas[ldap.conf+base]/returns: executed successfully
    Notice: /Stage[main]/Openldap::Client::Config/Augeas[ldap.conf+uri]/returns: executed successfully
    Notice: /Stage[main]/Openldap::Client::Utils/Package[openldap-clients]/ensure: created
    Notice: /Stage[main]/Openldap::Server::Config/Shellvar[SLAPD_LDAPS]/ensure: created
    Notice: /Stage[main]/Openldap::Server::Config/Shellvar[SLAPD_LDAPI]/ensure: created
    Notice: /Stage[main]/Site::Packages/Package[sqlite-devel]/ensure: created
    Notice: /Stage[main]/Openldap::Server::Config/Shellvar[SLAPD_LDAP]/ensure: created
    Notice: /Stage[main]/Main/Node[ldap]/File[/identity.json]/ensure: defined content as '{md5}3fea1400bfa4716e51a28bced8f7e1fc'
    Notice: /Stage[main]/Openldap::Server::Config/Shellvar[SLAPD_URLS]/ensure: created
    Info: Class[Openldap::Server::Config]: Scheduling refresh of Class[Openldap::Server::Service]
    Info: Class[Openldap::Server::Service]: Scheduling refresh of Service[slapd]
    Notice: /Stage[main]/Openldap::Server::Service/Service[slapd]/ensure: ensure changed 'stopped' to 'running'
    Info: /Stage[main]/Openldap::Server::Service/Service[slapd]: Unscheduling refresh on Service[slapd]
    Notice: /Stage[main]/Openldap::Server::Slapdconf/File[/etc/openldap/slapd.d]/mode: mode changed '0700' to '0750'
    Notice: /Stage[main]/Openldap::Server::Slapdconf/Openldap::Server::Database[dc=jeffmccune,dc=net]/Openldap_database[dc=jeffmccune,dc=net]/ensure: created
    Notice: /Stage[main]/Site::Packages/Package[ruby-devel]/ensure: created
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data]/ensure: created
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/jeff_user.ldif]/ensure: defined content as '{md5}fd506aa952f7bc2eb90ea39bd73f5837'
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/groups.ldif]/ensure: defined content as '{md5}76d02e92946e5ecbdf375a32fe027d23'
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/jeff_group.ldif]/ensure: defined content as '{md5}4d320620378e9ac39d659e94ea45102d'
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/site.ldif]/ensure: defined content as '{md5}23d49a0d2d4ee0c9c7ab546639c45e9f'
    Notice: /Stage[main]/Site::Openldap/File[/etc/openldap/data/users.ldif]/ensure: defined content as '{md5}2e82c9608c202a00843d0c196d825a45'
    Notice: /Stage[main]/Site::Openldap/Exec[cosine schema]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[inetorgperson schema]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[nis schema]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[dc=jeffmccune,dc=net]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[ou=Groups]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[ou=Users]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[cn=jeff,ou=Groups]/returns: executed successfully
    Notice: /Stage[main]/Site::Openldap/Exec[uid=jeff,ou=Users]/returns: executed successfully
    Info: Creating state file /var/lib/puppet/state/state.yaml
    Notice: Finished catalog run in 30.15 seconds
Update ldap dockerfile to use centos7vps base image (REVISIT)

Without this patch the ldap Dockerfile does not build a suitable base
image for ldap because it starts from the centos:centos7 image which
contains a fake systemd package.

This patch addresses the problem by changing the ldap container build
file to use the centos7vps image which contains a functional systemd
implementation.

The build process is still incomplete because systemd is not running
during the docker build phase, however it will be running during the run
phase.

The puppet code still needs to be modified to account for systemd not
being present during build time.

REVISIT: With this change, does it still make sense to change the base
image to one that includes systemd?  It may make more sense to simply
override the Service[slapd] resource to use a start command that does
not rely on systemd.
Add `docker build` Dockerfile for ldap systemd container

Without this patch there is no single Dockerfile that implements a build
process that results in a working LDAP container.  This patch addresses
the problem by using the centos7vps base image, which includes systemd,
to build a LDAP service container.

The LDAP service can be started, mapping 389 on the host to 389 in the
container:

    CID=$(docker run -p 127.0.0.1:389:389 --privileged -d ldap_sysd)

This patch modifies the original Puppet code for the shared jenkins+ldap
VM overriding the Service[slapd] resource.  This is necessary because
Puppet defaults to systemd service management while systemd is not
running during the build phase.  The override manually starts the LDAP
process as a dependency of loading the initial schema and branches.

This approach differs from the approach of "side-loading" [1] the data
using two containers at runtime.

Details:

Start the service on port 389:

    $ CID=$(docker run -p 127.0.0.1:389:389 --privileged -d --name ldap ldap_sysd)

List the service:

    $ docker ps
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
    8c2daa7ca724        ldap_sysd:latest    "/usr/sbin/init"    3 seconds ago       Up 3 seconds        127.0.0.1:389->389/tcp   ldap

There are 5 processes using the systemd approach:

    $ sudo ps auxww --forest
    root      1378  1.1  0.4 645540 39092 ?        Ssl  11:33   0:21 /usr/bin/docker -d --selinux-enabled
    root      8493  0.0  0.0 180136  4864 ?        Sl   12:04   0:00  \_ docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 389 -container-ip 172.17.0.10 -container-port 389
    root      8499  0.0  0.0  44616  2696 ?        Ss   12:04   0:00  \_ /usr/sbin/init
    root      8528  0.0  0.0  42992  3872 ?        Ss   12:04   0:00      \_ /usr/lib/systemd/systemd-journald
    55        8578  0.2  9.1 856940 734732 ?       Ssl  12:04   0:00      \_ /usr/sbin/slapd -u ldap -h ldapi:/// ldap:///

Access the service:

    ldapsearch -h localhost -p 389 \
               -D cn=admin,dc=jeffmccune,dc=net \
               -w Password1 \
               -b dc=jeffmccune,dc=net

[1]: http://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/
Add Rakefile to build ldap_sysd base image
Add Rakefile to build centos7vps base image
Add Dockerfile for lightweight ldap with no systemd

Without this patch the only docker base image for ldap uses systemd.
This is a problem because it is not as lightweight as running ldap
without systemd and it goes against the principle of Docker [1], which
is to run as minimal of a container as possible.

This patch addresses the problem by taking the systemd enabled base
image as a starting point and replacing /usr/sbin/init with
/usr/sbin/slapd as the entry point of a running container.

The container no longer needs to be started in privileged mode.
Starting and stopping the container is also much faster without having
to go through systemd to start slapd.

Start the container:

    $ CID=$(docker run -p 127.0.0.1:10389:389 -d --name ldap2 ldap_lite)

List the containers:

    $ docker ps
    CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                      NAMES
    0dce5b7994ab        ldap_lite:latest    "/usr/sbin/slapd -u    47 seconds ago      Up 47 seconds       127.0.0.1:10389->389/tcp   ldap2
    8c2daa7ca724        0d0bfe8aafcf        "/usr/sbin/init"       49 minutes ago      Up 48 minutes       127.0.0.1:389->389/tcp     ldap

There are fewer processes running (2 without systemd compared to 6 with
systemd).  This table shows the comparison between the systemd container on 389
and the slapd container on 1039.

    /usr/bin/docker -d --selinux-enabled
     \_ docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 389 -container-ip 172.17.0.10 -container-port 389
     \_ /usr/sbin/init
     |   \_ /usr/lib/systemd/systemd-journald
     |   \_ /usr/sbin/slapd -u ldap -h ldapi:/// ldap:///
     |   \_ /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
     |   \_ /usr/lib/systemd/systemd-logind
     \_ docker-proxy -proto tcp -host-ip 127.0.0.1 -host-port 10389 -container-ip 172.17.0.21 -container-port 389
     \_ /usr/sbin/slapd -u ldap -h ldapi:/// ldap:/// -d 0

[1]: http://jpetazzo.github.io/2014/06/23/docker-ssh-considered-evil/
Add `rake run` task to the two ldap containers

Without this patch there is no easy way to start each of the systemd and
lightweight ldap containers.  This patch addresses the problem by adding
a rake run task to each build context.
Add build and run tasks for a jenkins systemd container

Without this patch there is no jenkins container build procedure.  This
is a problem because we need to build a jenkins base image prior to
running the jenkins service in a container.  This patch addresses the
problem by creating a Dockerfile and rake tasks to build the jenkins
base image and run the image.

The build phase contains the expected error of not being able to manage
the Service[jenkins] resource:

    Error: Could not start Service[jenkins]: Execution of '/usr/bin/systemctl start jenkins' returned 1: Failed to get D-Bus connection: No connection to service manager.
    Wrapped exception:
    Execution of '/usr/bin/systemctl start jenkins' returned 1: Failed to get D-Bus connection: No connection to service manager.
    Error: /Stage[main]/Jenkins::Service/Service[jenkins]/ensure: change from stopped to running failed: Could not start Service[jenkins]: Execution of '/usr/bin/systemctl start jenkins' returned 1: Failed to get D-Bus connection: No connection to service manager.
    Warning: /Stage[main]/Jenkins/Anchor[jenkins::end]: Skipping because of failed dependencies

Despite the error, jenkins runs in the resulting systemd enabled
container using `rake run`.
Cache packages in the systemd base image

Without this patch the build phase for the jenkins container takes a
long time because large packages need to be installed each time the
container is built.  This patch addresses the problem by installing the
packages in the centos7vps base image which will speed up puppet.
Make Service[jenkins] work in `docker build` (systemd)

Without this patch puppet does not successfully complete during the
`docker build` phase of the jenkins container.  This is a problem
because there should be no configuration errors present in the puppet
results.

The root cause of the problem is Puppet trying to manage the
Service[jenkins] when systemd is not running and operational.

This patch addresses the problem by overriding Class[jenkins::service].
The original module is modified from upstream because it specifically
guards against modifying a private class and uses resource class
declaration syntax which is problematic with class overrides.

With this patch applied, running `rake run` will run the jenkins
container in VPS systemd mode, which requires privileged access.  The
container will link to the ldap container and configure jenkins to
access the LDAP server at `ldap://ldap:389`
Remove systemd at runtime in jenkins:lite image

Without this patch the jenkins container runs from the jenkins:systemd
base image where the jenkins service starts up from systemd and docker
starts systemd as the initial entrypoint.

This is a problem because the container must run in privileged mode and
takes longer than necessary to start and stop the container.  There are
additional processes running, like systemd, journald, and dbus.

This patch addresses the problem by executing jenkins directly and
skipping over systemd in the container.

With this patch applied the two running containers take a minimal number
of processes:

    /usr/bin/docker -d --selinux-enabled
     \_ /usr/sbin/slapd -u ldap -h ldapi:/// ldap:/// -d 0
     \_ docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8080 -container-ip 172.17.0.57 -container-port 8080
     \_ java -DJENKINS_HOME=/var/lib/jenkins -jar /usr/lib/jenkins/jenkins.war
Update README
Merge branch 'docker'

* docker:
  Update README
  Remove systemd at runtime in jenkins:lite image
  Make Service[jenkins] work in `docker build` (systemd)
  Cache packages in the systemd base image
  Add build and run tasks for a jenkins systemd container
  Add `rake run` task to the two ldap containers
  Add Dockerfile for lightweight ldap with no systemd
  Add Rakefile to build centos7vps base image
  Add Rakefile to build ldap_sysd base image
  Add `docker build` Dockerfile for ldap systemd container
  Update ldap dockerfile to use centos7vps base image (REVISIT)
  Add centos7vps base image that works with puppet but fails with systemd
  Demonstrate the problem of no service management
  Add Dockerfile for ldap container
  Add puppet configuration for ldap container
  Update to Docker version 1.2.0, build fa7b24f
  Add puppet manifest for docker container host
  Add Vagrantfile for docker VM