Quickstart
This is the 10 minute intro into BundleWrap. Fasten your seatbelt.
Installation
First, open a terminal and install BundleWrap:
pip install bundlewrap
Create a repository
Now you'll need to create your repository:
mkdir my_bundlewrap_repo
cd my_bundlewrap_repo
bw repo create
You will note that some files have been created. Let's check them out:
cat nodes.py
cat groups.py
The contents should be fairly self-explanatory, but you can always check the docs on these files if you want to go deeper.
At this point you will want to edit nodes.py
and maybe change "localhost" to the hostname of a system you have passwordless (including sudo) SSH access to.
~/.ssh/config
, so if ssh mynode.example.com sudo id
works without any password prompts in your terminal, you're good to go.If you want to keep working on "localhost", then the above still applies in that ssh localhost sudo id
needs to work without any password prompts. Verify that:
- an SSH daemon is listening on 127.0.0.1
- a relevant public key is in the
~/.ssh/authorized_keys
file - the
~/.ssh/authorized_keys
file is not world-writable - your user or group has
ALL=(ALL) NOPASSWD: ALL
set in the/etc/sudoers
file
Run a command
The first thing you can do is run a command on your army of one node:
bw -a run node-1 "uptime"
-a
switch tells bw to automatically trust unknown SSH host keys (when you're connecting to a new node). By default, only known host keys will be accepted.You should see something like this:
› node-1 20:16:26 up 34 days, 4:10, 0 users, load average: 0.00, 0.01, 0.05
✓ node-1 completed after 0.366s
Instead of a node name ("node-1" in this case) you can also use a group name (such as "all") from your groups.py
.
Create a bundle
BundleWrap stores node configuration in bundles. A bundle is a collection of items such as files, system packages or users. To create your first bundle, type:
bw repo bundle create mybundle
Now that you have created your bundle, it's important to tell BundleWrap which nodes will have this bundle. You can assign bundles to nodes using either groups.py
or nodes.py
, here we'll use the latter:
nodes = {
'node-1': {
'bundles': (
"mybundle",
),
'hostname': "mynode-1.local",
},
}
Create a file template
To manage a file, you need two things:
- a file item in your bundle
- a template for the file contents
Add this to your bundles/mybundle/items.py
:
files = {
'/etc/motd': {
'content_type': 'mako', # use the Mako template engine for this file
'source': "mymotd", # filename of the template
},
}
Then write the file template:
vim bundles/mybundle/files/mymotd
You can use this for example content:
Welcome to ${node.name}!
Note that the source
attribute in items.py
contains a path relative to the files
directory of your bundle.
Apply configuration
Now all that's left is to run bw apply
:
bw apply -i node-1
BundleWrap will ask to replace your previous MOTD:
i node-1 started at 2016-02-13 21:25:45
? node-1
? node-1 ╭─ file:/etc/motd
? node-1 │
? node-1 │ content
? node-1 │ --- <node>
? node-1 │ +++ <bundlewrap>
? node-1 │ @@ -1 +1 @@
? node-1 │ -your old motd
? node-1 │ +Welcome to node-1!
? node-1 │
? node-1 ╰─ Fix file:/etc/motd? [Y/n]
That completes the quickstart tutorial!
Further reading
Here are some suggestions on what to do next:
- set up SSH multiplexing for significantly better performance
- take a moment to think about what groups and bundles you will create
- read up on how a BundleWrap repository is laid out
- ...especially what types of items you can add to your bundles
- familiarize yourself with the Mako template language
- explore the command line interface
- follow @bundlewrap on Twitter
Have fun! If you have any questions, feel free to drop by on IRC or GitHub.