roost

System provisioning toolkit.

npm install roost
46 downloads in the last week
103 downloads in the last month
 ______    _______  _______  _______  _______ 
|    _ |  |       ||       ||       ||       |
|   | ||  |   _   ||   _   ||  _____||_     _|
|   |_||_ |  | |  ||  | |  || |_____   |   |  
|    __  ||  |_|  ||  |_|  ||_____  |  |   |  
|   |  | ||       ||       | _____| |  |   |  
|___|  |_||_______||_______||_______|  |___|  

by Websecurify

Introduction

Roost is a provisioning system similar to puppet and chef but heavily inspired by the clean and unobtrusive design of the nodejs module eco-system. It is also a bit like grunt but without the added complexity.

Originally Roost was written in JavaScript but for better readability and reduced complexity, it is now written in CoffeeScript.

The Basics

Roost is configured through a simple manifest file, typically called roost.json, however other names can be used too. The file is used to describes how a system is provisioned, i.e what commands, packages, services and other characteristics a system needs to adhere to.

When running roost without any command-line parameters it will try to look for the manifest file inside the current working directory. With the -f|--file option you can specify any arbitrary file or directory to be used by roost. For example:

roost -f /path/to/folder     # /path/to/folder/roost.json will be loaded
roost -f /path/to/file         # /path/to/file will be loaded

Roost has the concept of targets. The default target is local:. You can use ssh: too. The target specifies what system will be provisioned. Here is an example:

roost                                                             # provisions the local system
roost 'ssh://username@host;privateKey=/path/to/private/key'     # will provision a remote host over ssh

In case you are not sure what you are doing, you can also try dry-running by using the -d|--dry option. For example:

roost -d     # will output information on what will happen if run the command for real

Verbose messaging can be achieved via the -v|--verbose flags. Use the -c|--colorize flag to make the colorful. For example:

roost -vvv         # achieves debug level logging
roost -vvv -c     # achieves debug level logging but with colorization

Basic roost.json File Structure

The following snippet describes the basic structure of the roost manifest file.

{
    "plugins": [
        "plugin-name"
    ],

    "bootstrap": [
        "command"
    ],

    "files": [
        "remote": {
            "source": "local",
            "content": "content"
        }
    ],

    "packages": {
        "package": "version|installed|purged"
    },

    "services": {
        "service": "running|stopped"
    },

    "commands": [
        "command"
    ],

    "tasks": [
        "task": {
            "commands": [
                "command"
            ]
        },

        "default": {
            "require": ["task"]
        }
    ]
}

Apt can be configured with the following directive:

{
    "apt": {
        "update": true     // true or false for auto updating the system before installing extra packages
    }
}

Order Of Execution

Roost does not expose means by which you can configure the order of execution of things. The order is already chosen for you in advance, which is:

  • plugins
  • bootstrap
  • files
  • packages
  • services
  • commands
  • tasks

This order is not finalised but this is what it is at the moment. The order of execution is pre-selected to avoid confusion and to provide some level of consistency. You can choose your own arbitary order by using tasks.

Tasks are esentially mini roost config files and they can nest inside the same roost directives as the ones described previously. Tasks can also provide dependencies. For example:

{
    "tasks": {
        "Another Task": {
            "commands": [
                "another command"
            ]
        },

        "Some Task": {
            "require": ["Another Task"]

            "commands": [
                "some command"
            ]
        }
    }
}

This level of nesting can go as much as you like. For example:

{
    "tasks": {
        "Another Task": {
            "commands": [
                "another command"
            ],

            {
                "tasks": {
                    "Another Task": {
                        "commands": [
                            "another command"
                        ]
                    },

                    "Some Task": {
                        "require": ["Another Task"]

                        "commands": [
                            "some command"
                        ]
                    }
                }
            }
        },

        "Some Task": {
            "require": ["Another Task"]

            "commands": [
                "some command"
            ]
        }
    }
}

There are virtually no limits.

The Plugin System

The plugin system of roost is essentially the nodejs module system. You can load plugins by declaring them inside the roost manifest file as illustrated previously. The plugin must be either installed globally via npm or locally inside the node_modules folder structure.

Each plugin must export a function called getRoost or roost. Function getRoost is used to get an object that must export the function roost. The function expects two parameters: the manifest file and the target. Once the function is invoked the plugin will be able to traverse the manifest file for declarations it recognizes and execute actions via the target. A plugin may even augment the manifest structure if desired, i.e. a plugin my install more packages by simply extending the "packages" directive.

Two functions exist in the target that are useful to plugin developers: exec and spawn. Use exec to launch any shell command. Use spawn to launch an executable with a fine-grain control over the process.

For examples and inspiration check out the project source code.

Embedding Into Other Projects

Roost can be easily embedded into other projects. Check out bin/roost and lib/roost.coffee for inspiration. Just copy and paste the parts that you need. The whole project has been designed to be easily embedable so that it can live as part of larger and more complex systems.

You can also have a look at Vortex, which embeds roost as the default provisioner.

Project Status and Future Plans

The project is new and immature in some ways. We hope to change this in the upcoming months. At the moment only ubuntu/debian is supported for the packages and the services directives. Please fork it as much as you want and send us patches. We are keen to make something out of this.

Roost, although open source, is commercially backed by Websecurify. We are just starting to use it internally to manage our infrastructure. It is also the default provisioner for Vortex, which is pretty decent virtual machine management toolki. We are committed to support it in the foreseeable future so you can be assured that it is actually used to satisfy real needs.

How To Contribute

Fork the project. Improve it. Send us the patches. Write some plugins and spread the news. We are happy to help with any technical queries you may have.

We want to support the community to create all kinds of ready-made systems. Share your roost files for the world to see. Get in touch if you want them to be included as part of the default distribution.

Roost Plugins You Can Use

The easiest way to install these plugins is to create a package.json file and declare the modules just as you usually do. Execute npm install inside the same folder than use roost to load the plugins that you need. It is as simple as that.

npm loves you