Buildserver
Lets you easily compile bash scripts from Ruby to build server instances on your favorite Linux distro.
Installation
Add this line to your application's Gemfile:
gem 'buildserver'
And then execute:
$ bundle
Or install it yourself as:
$ gem install buildserver
Usage
Init a directory like this:
mkdir -p buildingblocks
touch buildingblocks/build.rb
cat > buildingblocks/build.rb << EOF
require 'buildserver'
require_relative 'blocks/base/builder'
buildserver = Buildserver::Buildserver.new
buildserver.add_instance('wilmut.example.com', '80.0.0.10', :jumphost)
buildserver.add_build_block(:base, Blocks::Base::Builder.new)
buildserver.build!
EOF
mkdir -p buildingblocks/blocks
mkdir -p buildingblocks/blocks/base
touch buildingblocks/blocks/base/builder.rb
cat > buildingblocks/blocks/base/builder.rb << EOF
require 'buildserver'
module Blocks
module Base
class Builder < Buildserver::BuildingBlock
def build(instance, instances)
run_command("apt-get update")
run_command("apt-get -y install aptitude")
run_command("aptitude -y full-upgrade")
# Set hostname
run_command("echo \"#{instance.hostname}\" > /etc/hostname")
run_command("echo -e \"\\n127.0.0.1 #{instance.hostname} #{instance.hostname}.local\\n\" >> /etc/hosts")
run_command("hostname -F /etc/hostname")
# Set ssh to only allow keys
run_command("sed -i \"/#PasswordAuthentication yes/PasswordAuthentication no/g\" /etc/ssh/sshd_config")
run_command("service ssh restart", :after)
end
def external_ports
[22]
end
end
end
end
EOF
Adding servers with roles:
buildserver.add_instance('m1.example.com', '80.0.0.1', :loadbalancer)
buildserver.add_instance('m2.example.com', '80.0.0.2', :utility)
buildserver.add_instance('m3.example.com', '80.0.0.3', :application)
Built-in Builder methods:
Templating
To install a template the following is possible:
template = template('haproxy.cfg.erb' {port: 80})
install_template(template, "/etc/haproxy/haproxy.cfg")
To append a template to a file use append_template
template = template('pg_hostfile.erb', {username: user.username})
append_template(template, user.username, '/etc/postgresql/9.3/main/pg_hba.conf')
User existence
To only do something if a user exists on the system:
if_user_exists?(@username) do
# Do stuff
end
And if the user don't exists:
if_user_dont_exists?(@username) do
run_command("adduser #{@username} --disabled-password --gecos \"\"")
end
Directory existence
Use if_directory_exists?(path)
or if_directory_dont_exists?(path)
if_directory_exists?("/etc/serf_handlers") do
template = template('serf_haproxy.rb')
install_template(template, "/etc/serf_handlers/serf_haproxy.rb")
end
# Installing RBENV
if_directory_dont_exists?("#{@home_dir}/.rbenv") do
run_command("su #{@username} -c \"cd #{@home_dir} && git clone https://github.com/sstephenson/rbenv.git #{@home_dir}/.rbenv\"")
end
File existence
Use if_file_exists?(path)
or if_file_dont_exists?(path)
if_file_exists?("/etc/nginx/sites-enabled/default") do
run_command("rm /etc/nginx/sites-enabled/default")
end
if_file_dont_exists?("/sbin/serf") do
run_command("cd /root")
run_command("wget https://dl.bintray.com/mitchellh/serf/0.6.2_linux_amd64.zip -O serf.zip")
run_command("unzip serf.zip")
run_command("mv serf /sbin/serf")
end
Example of a user builder with login through public-key from Github:
This takes advantage of the fact that Github exposes public-keys for users, you can see mine here: https://github.com/kaspergrubbe.keys
You use this builder like this:
require_relative 'blocks/user/builder'
buildserver.add_build_block(:base, Blocks::User::Builder.new('root', {home_dir: '/root', github_users: ['kaspergrubbe']}))
buildserver.add_build_block(:base, Blocks::User::Builder.new('kasper', {github_users: ['kaspergrubbe']}))
This is the code:
require 'buildserver'
module Blocks
module User
class Builder < Buildserver::BuildingBlock
def initialize(username, = {})
@username = username
@home_dir = .fetch(:home_dir, "/home/#{@username}")
@github_users = .fetch(:github_users, [])
end
def build(instance, instances)
if_user_dont_exists?(@username) do
run_command(" adduser #{@username} --disabled-password --gecos \"\"")
end
if !@github_users.nil?
run_command("touch #{@home_dir}/combined_keys")
@github_users.each do |github_user|
run_command("wget https://github.com/#{github_user}.keys -O - >> #{@home_dir}/combined_keys")
run_command("echo \"\" >> #{@home_dir}/combined_keys")
end
run_command("mv #{@home_dir}/combined_keys #{@home_dir}/.ssh/authorized_keys")
run_command("chown #{@username} #{@home_dir}/.ssh/authorized_keys")
run_command("chmod 644 #{@home_dir}/.ssh/authorized_keys")
end
# Enable color
run_command("sed -i \"s/#force_color_prompt=yes/force_color_prompt=yes/g\" #{@home_dir}/.bashrc")
end
end
end
end
Contributing
- Fork it ( https://github.com/Pidrock/buildserver/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request