goatos-base 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|