json extension files for the experimental release of docker machine with extensions
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
generic
rexray
sample/wordpress
weave
README.md

README.md

Extensions for Docker Machine

Premise

Docker Machine gets you a "docker ready" host. It automatically configures the host OS to run Docker containers and can be joined to a Swarm cluster. But what about everything else that goes into daily operations? Configuration management, Docker Engine pluggable extensions, crazy security configurations, etc! Those are the things that can push Docker Machine that extra mile. Docker Machine with Extensions gives you the flexibility to configure your host, your way.

Closed PR #1881 is to address Proposal / Issue #1765. The discussion will continue on Issue #773 - Proposal: Machine Declaration.

Download the binaries: kacole2/machine/releases/tag/v0.4.1-ext Get the code: kacole2/machine/tree/feature/extension

Extensions Supported:

Generic Extensions

The Generic Extension capability allows the install any services and customize through a JSON file

Examples of each are in the folders on this repo.

Please contribute by creating .json files for anything that you want to install. Things like Nagios, NTP Settings, Security Templates, Agents for Chef, Puppet, or Mesos, etc!

Summary

Extensions for Docker Machine is a pluggable architecture to install Docker Engine Plugins as an additional command line argument.

docker-machine -D create --driver amazonec2 --amazonec2-access-key mykey --amazonec2-secret-key mysecretkey --amazonec2-vpc-id myvpcid --amazonec2-zone b --extension /Users/kcoleman/Desktop/extensions.json dev

The name of the .json file is arbitrary. This allows the creation of multiple .json files for different machines provisioned through Docker Machine. At this time, .json files are the only supported file types.

The .json file supports the following structure and fields:

{
    "extensions": [
        {
            "extension-name": {
                "version": "latest",
                "env": {
                    "any environment": "variables"
                },
                "params": {
                    "specific key values": "for extension customization"
                },
                "copy": {
                    "source path/file": "destination path/file"
                },
                "files": {
                    "filename for extension customization": {
                        "source": "source path/file",
                        "destination": "destination path/file"
                    }
                },
                "run": [
                    "commands",
                    "to",
                    "run"
                ],
                "validOS": [
                    "OSnames",
                    "ubuntu"
                ]
            }
        }
    ]
}

A generic installation of a service using only commands lines:

{
    "extensions": [
        {
            "generic": {
                "envs": {},
                "copy": {
                    "/Users/kcoleman/Desktop/rexconfig.yml": "/etc/rexray/config.yml"
                },
                "run": [
                    "curl -sSL https://dl.bintray.com/emccode/rexray/install | sh",
                    "sudo service rexray start"
                ],
                "validOS": [
                    "ubuntu",
                    "debian",
                    "centos",
                    "redhat"
                ]
            }
        }
    ]
}

A simple example of installing a service (Weave as an example):

//weave-node-01 (ie. 192.168.10.101)
{
    "extensions": [
        {
            "weave": {}
        }
    ]
}
//weave-node-02
{
    "extensions": [
        {
            "weave": {
                "params": {
                    "peer": "192.168.10.101"
                }
            }
        }
    ]
}

a more complex example with extensions running in priority:

{
    "extensions": [
        {
            "generic": {
                "copy": {
                    "/Users/kcoleman/Desktop/rexconfig.yml": "/etc/rexray/config_backup1.yml"
                }
            }
        },
        {
            "weave": {}
        },
        {
            "rexray": {
                "version": "latest",
                "files": {
                    "config.yaml": {
                        "source": "/Users/kcoleman/Desktop/rexconfig.yml",
                        "destination": "/etc/rexray/config.yml"
                    }
                }
            }
        },
        {
            "generic": {
                "copy": {
                    "/Users/kcoleman/Desktop/rexconfig2.yml": "/etc/rexray/config_backup3.yml"
                }
            }
        }
    ]
}

Deeper Dive

The .json file is read from a local resource into memory.

The name of the extension is checked to see if a registered extension exists. If there is a matching registered extension, the paramters in the .json file are passed on.

  • version will set the value from nil to a string in the extInfo struct. If it's not specified and the value nil is passed along, the extension's .go file will have a default or latest version specified. Versioning allows consistent deployment of the extension in the case that a specific docker-engine version is being specified in the docker machine command. Each extension is responsible for the implementation of installing different versions.
  • env is a set of key:value pairs that can call the utils.go function appendEnvFile to set environment variables on the host.
  • params is any set of key:value pairs that an extension can use for customization. These pairs are passed on to the extension's interface where the extension can use them any way it wishes. Such use cases include commands to run or local variables for configuration.
  • copy is a key:value pair that will take the source and destination and transfer the files using docker-machine scp. This takes no priority and files can be transferred at will when called.
  • files is a nested set of key:value pairs for the transfering of files using the docker-machine scp command. This function is used for customizing extensions. The name specified in the .json file must match in the function called. This allows you to transfer files at any time in your code. This gives you the freedom and flexibiltiy to transfer files when a function may need them. Files can be transferred from the local system to remote systems or between remote systems. Use cases include configuration files or binaries to be copied. There is a generic function in utils.go that will take the source and destination keys to transfer files.
  • run is an array of commands that will be run in sequential order. These are piped into the provisioner.SSHCommand().
  • validOS is an array of supported Operating Systems to check. This also allows your to run commands based on the type of OS that is detected from the .json file.

Before the installation begins, the .json file is parsed to make sure there is valid JSON. This is denoted in the host.go file.

if h.HostOptions.ExtensionOptions.File != "" {
    if err := extension.ParseExtensionFile(*h.HostOptions.ExtensionOptions); err != nil {
      return err
    }
  }

The installation of any extension is performed as the final step during the docker-machine configuration process. This is denoted in the host.go file. It checks to see if the --extension flag isn't empty:

if h.HostOptions.ExtensionOptions.File != "" {
      if err := extension.ExtensionInstall(*h.HostOptions.ExtensionOptions, provisioner); err != nil {
        return err
      }
    }