goatos-base 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +215 -0
- data/LICENSE.txt +14 -0
- data/README.md +92 -0
- data/Rakefile +2 -0
- data/bin/goatos +8 -0
- data/cookbooks/goatos/attributes/default.rb +2 -0
- data/cookbooks/goatos/files/default/goatos-meta.rb +184 -0
- data/cookbooks/goatos/files/default/test.rb +6 -0
- data/cookbooks/goatos/libraries/lwrp.rb +105 -0
- data/cookbooks/goatos/metadata.rb +3 -0
- data/cookbooks/goatos/recipes/default.rb +0 -0
- data/cookbooks/goatos/recipes/haproxy.rb +16 -0
- data/cookbooks/goatos/recipes/lxc_configure.rb +23 -0
- data/cookbooks/goatos/recipes/lxc_install.rb +61 -0
- data/cookbooks/goatos/recipes/master.rb +0 -0
- data/cookbooks/goatos/recipes/slave.rb +1 -0
- data/cookbooks/goatos/templates/default/haproxy.cfg.erb +20 -0
- data/cookbooks/goatos/templates/default/lxc.conf.erb +6 -0
- data/goatos-base.gemspec +33 -0
- data/lib/goatos/blends/bootstrap.rb +64 -0
- data/lib/goatos/blends/helper.rb +60 -0
- data/lib/goatos/blends/master.rb +73 -0
- data/lib/goatos/blends/slave.rb +31 -0
- data/lib/goatos/builder.rb +74 -0
- data/lib/goatos/cli.rb +190 -0
- data/lib/goatos/cli/lxc.rb +162 -0
- data/lib/goatos/log.rb +6 -0
- data/lib/goatos/version.rb +3 -0
- data/roles/master.rb +2 -0
- data/roles/slave.rb +2 -0
- data/roles/standalone.rb +2 -0
- metadata +218 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'chef/resource/lwrp_base'
|
2
|
+
require 'chef/provider/lwrp_base'
|
3
|
+
require 'chef/mixin/shell_out'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module GoatOS
|
7
|
+
module RecipeHelper
|
8
|
+
include Chef::Mixin::ShellOut
|
9
|
+
|
10
|
+
def subuid_info
|
11
|
+
::File.read('/etc/subuid').scan(/goatos:(\d+):(\d+)/).flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
def subgid_info
|
15
|
+
::File.read('/etc/subgid').scan(/goatos:(\d+):(\d+)/).flatten
|
16
|
+
end
|
17
|
+
|
18
|
+
def move_pids
|
19
|
+
uid, _ = subuid_info
|
20
|
+
gid, _ = subgid_info
|
21
|
+
shell_out!('cgm create all goatos')
|
22
|
+
shell_out!("cgm chown all goatos #{uid} #{gid}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module ProviderHelper
|
27
|
+
Listener = Struct.new(:name, :listen, :port, :mode, :ip)
|
28
|
+
def state_file
|
29
|
+
'/opt/goatos/goats.json'
|
30
|
+
end
|
31
|
+
|
32
|
+
def compute_listeners
|
33
|
+
return [] unless File.exists?(state_file)
|
34
|
+
listeners = []
|
35
|
+
metadata = JSON.parse(File.read(state_file))
|
36
|
+
metadata['containers'].each do |n, meta|
|
37
|
+
ct = LXC::Container.new(n, '/opt/goatos/.local/share/lxc')
|
38
|
+
if ct.running?
|
39
|
+
port, mode, listen = meta['expose'].split(':')
|
40
|
+
config = Listener.new(n, listen, port, mode, ct.ip_addresses.first)
|
41
|
+
listeners << config
|
42
|
+
else
|
43
|
+
Chef::Log.warn("LXC #{n} is absent, but its metadata is present")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
listeners
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Chef::Resource::HaproxyConfig < Chef::Resource::LWRPBase
|
52
|
+
self.resource_name = :haproxy_config
|
53
|
+
default_action :create
|
54
|
+
actions :create, :delete
|
55
|
+
attribute :path, kind_of: String, name_attribute: true, required: true
|
56
|
+
attribute :disable_on_empty, kind_of: [TrueClass, FalseClass], default: true
|
57
|
+
attribute :environment_file, kind_of: String, default: '/etc/default/haproxy'
|
58
|
+
end
|
59
|
+
|
60
|
+
class Chef::Provider::HaproxyConfig < Chef::Provider::LWRPBase
|
61
|
+
|
62
|
+
use_inline_resources
|
63
|
+
|
64
|
+
def whyrun_supported?
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
action :create do
|
69
|
+
require 'lxc'
|
70
|
+
extend GoatOS::ProviderHelper
|
71
|
+
|
72
|
+
listeners = compute_listeners
|
73
|
+
enabled = '1'
|
74
|
+
|
75
|
+
if listeners.empty? and new_resource.disable_on_empty
|
76
|
+
enabled = '0'
|
77
|
+
end
|
78
|
+
|
79
|
+
file new_resource.environment_file do
|
80
|
+
content "ENABLED=#{enabled}\n"
|
81
|
+
mode 0644
|
82
|
+
owner 'root'
|
83
|
+
group 'root'
|
84
|
+
end
|
85
|
+
|
86
|
+
template new_resource.path do
|
87
|
+
action :create
|
88
|
+
mode 0644
|
89
|
+
owner 'root'
|
90
|
+
group 'root'
|
91
|
+
source 'haproxy.cfg.erb'
|
92
|
+
variables(listeners: listeners)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
action :delete do
|
97
|
+
file new_resource.path do
|
98
|
+
action :delete
|
99
|
+
end
|
100
|
+
|
101
|
+
file new_resource.environment_file do
|
102
|
+
action :delete
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
package 'haproxy'
|
2
|
+
|
3
|
+
haproxy_config '/etc/haproxy/haproxy.cfg' do
|
4
|
+
environment_file '/etc/default/haproxy'
|
5
|
+
action :create
|
6
|
+
notifies :reload, 'service[haproxy]'
|
7
|
+
end
|
8
|
+
|
9
|
+
service 'haproxy' do
|
10
|
+
action [ :start, :enable]
|
11
|
+
supports(
|
12
|
+
restart: false,
|
13
|
+
reload: false,
|
14
|
+
status: false
|
15
|
+
)
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
extend GoatOS::RecipeHelper
|
2
|
+
u_start, u_range = subuid_info
|
3
|
+
g_start, g_range = subgid_info
|
4
|
+
|
5
|
+
template '/opt/goatos/.config/lxc/default.conf' do
|
6
|
+
owner node['goatos']['user']
|
7
|
+
group node['goatos']['group']
|
8
|
+
mode 0644
|
9
|
+
source 'lxc.conf.erb'
|
10
|
+
variables(
|
11
|
+
u_start: u_start,
|
12
|
+
u_range: u_range,
|
13
|
+
g_start: g_start,
|
14
|
+
g_range: g_range
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
file '/opt/goatos/.ssh/authorized_keys' do
|
19
|
+
owner node['goatos']['user']
|
20
|
+
group node['goatos']['group']
|
21
|
+
mode 0400
|
22
|
+
content search(:node, 'roles:master').first['goatos']['sshkey']
|
23
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
%w{ liblxc1 lxc lxc-dev lxc-templates python3-lxc cgmanager-utils build-essential}.each do |pkg|
|
3
|
+
package pkg do
|
4
|
+
action :install
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
%w{ruby-lxc serfx sshkey thor chef-lxc}.each do |gem_name|
|
10
|
+
gem_package gem_name do
|
11
|
+
gem_binary '/opt/chef/embedded/bin/gem'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
user 'goatos' do
|
16
|
+
home '/opt/goatos'
|
17
|
+
shell '/bin/bash'
|
18
|
+
supports(manage_home: true)
|
19
|
+
end
|
20
|
+
|
21
|
+
%w{
|
22
|
+
/opt/goatos/bin
|
23
|
+
/opt/goatos/.config
|
24
|
+
/opt/goatos/.local
|
25
|
+
/opt/goatos/.local/share
|
26
|
+
/opt/goatos/.cache
|
27
|
+
/opt/goatos/.ssh
|
28
|
+
/opt/goatos/lxc.conf.d
|
29
|
+
/opt/goatos/recipes
|
30
|
+
/opt/goatos/.config/lxc
|
31
|
+
/opt/goatos/.local/share/lxc
|
32
|
+
/opt/goatos/.local/share/lxcsnaps
|
33
|
+
/opt/goatos/.cache/lxc
|
34
|
+
}.each do |dir|
|
35
|
+
directory dir do
|
36
|
+
user node['goatos']['user']
|
37
|
+
group node['goatos']['group']
|
38
|
+
mode 0775
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
file '/etc/lxc/lxc-usernet' do
|
43
|
+
owner 'root'
|
44
|
+
group 'root'
|
45
|
+
mode 0644
|
46
|
+
content "#{node['goatos']['user']} veth lxcbr0 100\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
cookbook_file '/opt/goatos/bin/goatos-meta' do
|
50
|
+
source 'goatos-meta.rb'
|
51
|
+
mode 0700
|
52
|
+
user node['goatos']['user']
|
53
|
+
group node['goatos']['group']
|
54
|
+
end
|
55
|
+
|
56
|
+
cookbook_file '/opt/goatos/recipes/test.rb' do
|
57
|
+
source 'test.rb'
|
58
|
+
mode 0644
|
59
|
+
user node['goatos']['user']
|
60
|
+
group node['goatos']['group']
|
61
|
+
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
include_recipe 'goatos::haproxy'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
global
|
2
|
+
log /dev/log local0
|
3
|
+
log /dev/log local1 notice
|
4
|
+
chroot /var/lib/haproxy
|
5
|
+
user haproxy
|
6
|
+
group haproxy
|
7
|
+
daemon
|
8
|
+
|
9
|
+
defaults
|
10
|
+
log global
|
11
|
+
option dontlognull
|
12
|
+
contimeout 5000
|
13
|
+
clitimeout 50000
|
14
|
+
srvtimeout 50000
|
15
|
+
|
16
|
+
<% @listeners.each do |listener| %>
|
17
|
+
listen <%= listener.name.upcase %> :<%= listener.listen %>
|
18
|
+
mode <%= listener.mode %>
|
19
|
+
server <%= listener.name %> <%= listener.ip %>:<%= listener.port%>
|
20
|
+
<% end %>
|
data/goatos-base.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'goatos/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'goatos-base'
|
8
|
+
spec.version = GoatOS::VERSION.dup
|
9
|
+
spec.authors = ['Ranjib Dey']
|
10
|
+
spec.email = ['dey.ranjib@gmail.com']
|
11
|
+
spec.summary = %q{Distributed LXC automation suite using Chef and Blender}
|
12
|
+
spec.description = %q{Deploy and manage multi node LXC installation using Chef and Blender}
|
13
|
+
spec.homepage = 'https://github.com/goatos/base'
|
14
|
+
spec.license = 'Apache'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'thor'
|
22
|
+
spec.add_dependency 'chef'
|
23
|
+
spec.add_dependency 'pd-blender'
|
24
|
+
spec.add_dependency 'blender-chef'
|
25
|
+
spec.add_dependency 'sshkey'
|
26
|
+
|
27
|
+
|
28
|
+
spec.add_development_dependency 'bundler'
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
spec.add_development_dependency 'rspec'
|
31
|
+
spec.add_development_dependency 'rubocop'
|
32
|
+
spec.add_development_dependency 'yard'
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'goatos/blends/helper'
|
2
|
+
require 'sshkey'
|
3
|
+
|
4
|
+
module GoatOS
|
5
|
+
module Blends
|
6
|
+
module Bootstrapper
|
7
|
+
|
8
|
+
def add_bootstrap_tasks(sched, node_name, options)
|
9
|
+
sched.ruby_task "bootstrap #{node_name}" do
|
10
|
+
execute do |h|
|
11
|
+
extend Helper
|
12
|
+
puts 'Yolo'
|
13
|
+
knife Chef::Knife::Bootstrap, h do |config|
|
14
|
+
config[:ssh_user] = options[:user]
|
15
|
+
if options[:password]
|
16
|
+
config[:ssh_password] = options[:password]
|
17
|
+
config[:use_sudo_password] = true
|
18
|
+
elsif options[:key]
|
19
|
+
config[:identity_file] = options[:key]
|
20
|
+
end
|
21
|
+
config[:ssh_port] = options[:ssh_port].to_i
|
22
|
+
config[:chef_node_name] = node_name
|
23
|
+
config[:distro] = 'chef-full'
|
24
|
+
config[:use_sudo] = true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_sshkey_task(sched, node_name)
|
31
|
+
sched.ruby_task 'assign ssh key' do
|
32
|
+
execute do |h|
|
33
|
+
extend Helper
|
34
|
+
key = SSHKey.generate
|
35
|
+
File.open('keys/goatos.rsa', 'w') do |f|
|
36
|
+
f.write(key.private_key)
|
37
|
+
f.chmod(0600)
|
38
|
+
end
|
39
|
+
chef_node(node_name) do |node|
|
40
|
+
node.set['goatos']['sshkey'] = key.ssh_public_key
|
41
|
+
node.save
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_chef_run_task(sched, node_name, run_list)
|
48
|
+
sched.ruby_task 'run chef' do
|
49
|
+
execute do |h|
|
50
|
+
extend Helper
|
51
|
+
chef_node(node_name) do |node|
|
52
|
+
node.run_list.reset!
|
53
|
+
node.run_list << run_list
|
54
|
+
node.save
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
sched.ssh_task 'run chef' do
|
59
|
+
execute 'sudo chef-client --no-fork'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'chef/knife/bootstrap'
|
2
|
+
require 'chef/knife/cookbook_upload'
|
3
|
+
require 'chef/knife/role_from_file'
|
4
|
+
require 'goatos/log'
|
5
|
+
|
6
|
+
module GoatOS
|
7
|
+
module Blends
|
8
|
+
module Helper
|
9
|
+
extend self
|
10
|
+
def configure
|
11
|
+
if File.exist?('etc/knife.rb')
|
12
|
+
Log.info('Configuring using knife config')
|
13
|
+
Chef::Config.from_file 'etc/knife.rb'
|
14
|
+
else
|
15
|
+
Log.info('Configuring using raw values')
|
16
|
+
Chef::Config[:client_key] = 'keys/admin.pem'
|
17
|
+
Chef::Config[:node_name] = 'admin'
|
18
|
+
Chef::Config[:chef_server_url] = "https://#{Blender::Configuration[:goatos]['target']}"
|
19
|
+
Chef::Config[:validation_key] = 'keys/chef-validator.pem'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def knife(klass, *args)
|
24
|
+
configure
|
25
|
+
klass.load_deps
|
26
|
+
plugin = klass.new
|
27
|
+
plugin.name_args = args
|
28
|
+
yield plugin.config if block_given?
|
29
|
+
plugin.run
|
30
|
+
end
|
31
|
+
|
32
|
+
def chef_node(name)
|
33
|
+
configure
|
34
|
+
node = load_node(name)
|
35
|
+
yield node if block_given?
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_chef_node_run_list(name, run_list)
|
39
|
+
chef_node(name) do |node|
|
40
|
+
node.run_list.reset!
|
41
|
+
node.run_list << run_list
|
42
|
+
node.save
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def load_node(name)
|
47
|
+
configure
|
48
|
+
Chef::Node.load(name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_node(name, opts = {})
|
52
|
+
configure
|
53
|
+
node = load_node(name)
|
54
|
+
if opts[:attrs]
|
55
|
+
node[opts[:attrs]]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'goatos/blends/helper'
|
2
|
+
|
3
|
+
module GoatOS
|
4
|
+
module Blends
|
5
|
+
module Master
|
6
|
+
def add_master_tasks( sched, node_name, options )
|
7
|
+
sched.ssh_task 'sudo apt-get update -y'
|
8
|
+
|
9
|
+
sched.ssh_task 'download chef server' do
|
10
|
+
execute 'wget -c https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef-server_11.1.4-1_amd64.deb'
|
11
|
+
end
|
12
|
+
|
13
|
+
sched.ssh_task 'install chef server' do
|
14
|
+
execute 'sudo dpkg -i chef-server_11.1.4-1_amd64.deb'
|
15
|
+
end
|
16
|
+
|
17
|
+
sched.ssh_task 'reconfigure chef server' do
|
18
|
+
execute 'sudo chef-server-ctl reconfigure'
|
19
|
+
end
|
20
|
+
|
21
|
+
%w(admin.pem chef-validator.pem).each do |key|
|
22
|
+
printer = StringIO.new
|
23
|
+
sched.ssh_task "retrieve file '#{key}'" do
|
24
|
+
execute "sudo cat /etc/chef-server/#{key}"
|
25
|
+
driver_options(stdout: printer )
|
26
|
+
end
|
27
|
+
|
28
|
+
sched.ruby_task "store file '#{key}'" do
|
29
|
+
execute do |h|
|
30
|
+
File.open(File.join('keys', key), File::CREAT|File::RDWR|File::EXCL) do |f|
|
31
|
+
f.write(printer.string.gsub(/^blender sudo password:\s*$/,'').strip)
|
32
|
+
end
|
33
|
+
printer.rewind
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
sched.ruby_task 'wait 10s' do
|
39
|
+
execute do
|
40
|
+
sleep 10
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
sched.ruby_task 'save knife config' do
|
45
|
+
execute do |h|
|
46
|
+
File.open('etc/knife.rb', File::CREAT|File::RDWR|File::EXCL) do |f|
|
47
|
+
f.puts <<-EOF
|
48
|
+
cwd = File.expand_path('../../', __FILE__)
|
49
|
+
chef_server_url 'https://#{h}'
|
50
|
+
node_name 'admin'
|
51
|
+
client_key File.join(cwd, 'keys/admin.pem')
|
52
|
+
validation_key File.join(cwd, 'keys/chef-validator.pem')
|
53
|
+
EOF
|
54
|
+
end
|
55
|
+
sleep 10
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
sched.ruby_task 'upload cookbooks' do
|
60
|
+
execute do |h|
|
61
|
+
extend Helper
|
62
|
+
knife Chef::Knife::RoleFromFile, 'roles/slave.rb', 'roles/master.rb', 'roles/standalone.rb'
|
63
|
+
knife Chef::Knife::CookbookUpload do |config|
|
64
|
+
config[:cookbook_path] = 'cookbooks'
|
65
|
+
config[:all] = true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
driver_options(stdout: $stdout)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|