goatos-base 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,31 @@
1
+ require 'goatos/blends/helper'
2
+
3
+ module GoatOS
4
+ module Blends
5
+ module Slave
6
+ def add_slave_tasks(sched, options )
7
+
8
+ sched.ssh_task 'sudo apt-get update -y'
9
+
10
+ sched.ssh_task 'run chef' do
11
+ execute 'sudo chef-client --no-fork -o recipe[goatos::lxc_install]'
12
+ end
13
+
14
+ sched.ssh_task 'run chef' do
15
+ execute 'sudo chef-client --no-fork -o recipe[goatos::lxc_configure]'
16
+ end
17
+
18
+ sched.ssh_task 'reboot instance' do
19
+ execute 'sudo reboot'
20
+ ignore_failure true
21
+ end
22
+
23
+ sched.ruby_task 'sleep 90s' do
24
+ execute do |h|
25
+ sleep 90
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,74 @@
1
+ require 'goatos/blends/master'
2
+ require 'goatos/blends/slave'
3
+ require 'goatos/blends/helper'
4
+ require 'chef/knife/bootstrap'
5
+ require 'chef/knife/cookbook_upload'
6
+ require 'chef/knife/role_from_file'
7
+ require 'goatos/log'
8
+ require 'goatos/blends/bootstrap'
9
+
10
+ module GoatOS
11
+ module Builder
12
+ include Blends::Master
13
+ include Blends::Slave
14
+ include Blends::Bootstrapper
15
+
16
+ def build_master( options )
17
+ ssh_options = ssh_opts(options)
18
+ host = options[:host]
19
+ node_name = options[:name]
20
+ Blender.blend( 'build_master') do |sched|
21
+ sched.config(:ssh, ssh_options.merge(stdout: $stdout))
22
+ sched.members([ host])
23
+ add_master_tasks( sched, node_name, options )
24
+ add_bootstrap_tasks( sched, node_name, options )
25
+ add_sshkey_task(sched, node_name)
26
+ add_chef_run_task(sched, node_name, 'role[master]')
27
+ end
28
+ end
29
+
30
+ def build_slave( options )
31
+ ssh_options = ssh_opts(options)
32
+ host = options[:host]
33
+ node_name = options[:name]
34
+ Blender.blend( 'build_slave') do |sched|
35
+ sched.config(:ssh, ssh_options.merge(stdout: $stdout))
36
+ sched.members([ host])
37
+ add_bootstrap_tasks( sched, node_name, options )
38
+ add_slave_tasks( sched, options )
39
+ add_chef_run_task(sched, node_name, 'role[slave]')
40
+ end
41
+ end
42
+
43
+ def build_standalone( options )
44
+ ssh_options = ssh_opts(options)
45
+ host = options[:host]
46
+ node_name = options[:name]
47
+ Blender.blend( 'build_standalone') do |sched|
48
+ sched.config(:ssh, ssh_options.merge(stdout: $stdout))
49
+ sched.members([ host])
50
+ add_master_tasks( sched, node_name, options)
51
+ add_bootstrap_tasks( sched, node_name, options )
52
+ add_chef_run_task(sched, node_name, 'role[master]')
53
+ add_sshkey_task(sched, node_name)
54
+ sched.ruby_task 'avoid stale chef search' do
55
+ execute do |h|
56
+ sleep 10
57
+ end
58
+ end
59
+ add_slave_tasks( sched, options )
60
+ add_chef_run_task(sched, node_name, 'role[standalone]')
61
+ end
62
+ end
63
+
64
+ def ssh_opts(options)
65
+ ssh_options = {user: options[:user], port: options[:ssh_port]}
66
+ if options[:password]
67
+ ssh_options[:password] = options[:password]
68
+ elsif options[:key]
69
+ ssh_options[:keys] = Array( options[:key] )
70
+ end
71
+ ssh_options
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,190 @@
1
+ require 'goatos/log'
2
+ require 'highline/import'
3
+ require 'goatos/builder'
4
+ require 'goatos/cli/lxc'
5
+ require 'thor'
6
+ require 'thor/group'
7
+
8
+ module GoatOS
9
+ class CLI < Thor
10
+ include Builder
11
+
12
+ register GoatOS::CLI::Lxc, :lxc, 'lxc', 'Manage LXC lifecycle'
13
+
14
+ desc 'bootstrap -t HOSTNAME -u SSH_USER', 'Bootstrap a server'
15
+
16
+ option :host,
17
+ aliases: '-h',
18
+ required: true,
19
+ description: 'Host IP/FQDN'
20
+
21
+ option :name,
22
+ aliases: '-N',
23
+ description: 'chef node name of the node (default sauron)',
24
+ default: 'sauron'
25
+
26
+ option :type,
27
+ aliases: '-T',
28
+ default: 'standalone',
29
+ description: 'Type of bootstrap ("master", "slave" or "standalone")'
30
+
31
+ option :user,
32
+ aliases: '-u',
33
+ default: ENV['USER'],
34
+ description: 'SSH user name'
35
+
36
+ option :key,
37
+ aliases: '-i',
38
+ description: 'SSH identity key'
39
+
40
+ option :password,
41
+ aliases: '-P',
42
+ description: 'Password for ssh user',
43
+ type: :boolean
44
+
45
+ option :ssh_port,
46
+ aliases: '-p',
47
+ description: 'SSH Port',
48
+ type: :string,
49
+ default: '22'
50
+
51
+ option :environment,
52
+ aliases: '-E',
53
+ description: 'Chef environment',
54
+ type: :string,
55
+ default: '_default'
56
+
57
+ option :run_list,
58
+ aliases: '-r',
59
+ description: 'Chef run list',
60
+ type: :string
61
+
62
+ def bootstrap(cwd = Dir.pwd)
63
+ opts = options.dup
64
+ if options[:password]
65
+ password = ask('SSH Password: '){ |q| q.echo = false }
66
+ opts.merge!(password: password)
67
+ end
68
+ Dir.chdir(cwd) do
69
+ case options[:type]
70
+ when 'master'
71
+ build_master( opts )
72
+ when 'slave'
73
+ build_slave( opts )
74
+ when 'standalone'
75
+ build_standalone( opts )
76
+ else
77
+ abort 'only master, slave or standalone bootstrap is valid'
78
+ end
79
+ end
80
+ end
81
+
82
+ desc 'run-chef', 'Run chef across fleet'
83
+
84
+ option :user,
85
+ aliases: '-u',
86
+ default: ENV['USER'],
87
+ description: 'SSH user name'
88
+
89
+ option :key,
90
+ aliases: '-i',
91
+ description: 'SSH identity key'
92
+
93
+ option :password,
94
+ aliases: '-P',
95
+ description: 'Password for ssh user',
96
+ type: :boolean
97
+
98
+ option :filter,
99
+ aliases: '-f',
100
+ default: '*:*',
101
+ description: 'Search term to predicate host list'
102
+
103
+ option :attribute,
104
+ aliases: '-a',
105
+ default: 'ipaddress',
106
+ description: 'Node attribute to be used for ssh hostname'
107
+
108
+ option :run_list,
109
+ aliases: '-r',
110
+ description: 'Node attribute to be used for ssh hostname'
111
+
112
+ def run_chef
113
+ ssh_opts = { user: options[:user] }
114
+ if options[:password]
115
+ password = ask('SSH Password: '){ |q| q.echo = false }
116
+ ssh_opts[:password] = password
117
+ else
118
+ ssh_opts[:keys] = [ options[:key] ]
119
+ end
120
+
121
+ chef_opts= {
122
+ attribute: options[:attribute],
123
+ filter: options[:filter],
124
+ }
125
+ if options[:run_list]
126
+ chef_command = "sudo /opt/chef/bin/chef-client --no-fork -o #{options[:run_list]}"
127
+ else
128
+ chef_command = 'sudo /opt/chef/bin/chef-client --no-fork'
129
+ end
130
+
131
+ run_blender(
132
+ chef_command,
133
+ ssh_opts,
134
+ chef_opts
135
+ )
136
+ end
137
+
138
+ desc 'meta', 'Show lxc related metadata'
139
+ def meta
140
+ ssh_opts = {
141
+ keys: [ 'keys/goatos.rsa' ],
142
+ user: 'goatos'
143
+ }
144
+
145
+ chef_opts= {
146
+ attribute: options[:attribute],
147
+ filter: options[:filter],
148
+ }
149
+ if options[:show]
150
+ meta_command = '/opt/goatos/bin/goat-meta show'
151
+ elsif options[]
152
+ raise ArgumentError, 'Meta command not implemented'
153
+ end
154
+ run_blender(
155
+ meta_command,
156
+ ssh_opts,
157
+ chef_opts
158
+ )
159
+ end
160
+
161
+ desc 'init', 'Create GoatOS directory structure'
162
+ def init(cwd = Dir.pwd)
163
+ Dir.chdir(cwd) do
164
+ %w{cookbooks keys roles environments etc}.each do |dir|
165
+ unless File.exist?(dir)
166
+ Dir.mkdir(dir)
167
+ end
168
+ end
169
+ Dir["#{File.expand_path('../../../roles', __FILE__)}/*.rb"].each do |f|
170
+ FileUtils.cp( f, "roles/#{File.basename(f)}")
171
+ end
172
+ Dir["#{File.expand_path('../../../cookbooks', __FILE__)}/*"].each do |f|
173
+ FileUtils.cp_r( f, "cookbooks/#{File.basename(f)}")
174
+ end
175
+ end
176
+ end
177
+
178
+ no_commands do
179
+ def run_blender(command, ssh_opts, chef_opts)
180
+ Blender.blend('goatos_run_chef') do |sched|
181
+ sched.config(:chef, config_file: 'etc/knife.rb', attribute: chef_opts[:attribute])
182
+ sched.config(:ruby, stdout: $stdout)
183
+ sched.config(:ssh, ssh_opts.merge(stdout: $stdout))
184
+ sched.members(sched.search(:chef, chef_opts[:filter]))
185
+ sched.ssh_task command
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,162 @@
1
+ require 'thor'
2
+ require 'blender/chef'
3
+
4
+ module GoatOS
5
+ class CLI < Thor
6
+ class Lxc < Thor
7
+ class_option :filter,
8
+ aliases: '-f',
9
+ default: '*:*',
10
+ description: 'Search term to predicate host list'
11
+ class_option :attribute,
12
+ aliases: '-a',
13
+ default: 'ipaddress',
14
+ description: 'Node attribute to be used for ssh hostname'
15
+
16
+ desc 'lxc ls', 'list all lxc'
17
+ def ls
18
+ opts = options.dup
19
+ run_blender('lxc-ls --fancy', opts)
20
+ end
21
+
22
+ desc 'lxc start', 'start a container'
23
+ option :name,
24
+ aliases: '-N',
25
+ required: true,
26
+ description: 'Name of the container to start'
27
+ def start
28
+ opts = options.dup
29
+ commands = []
30
+ commands << "lxc-start -d -n #{opts[:name]}"
31
+ commands << "/opt/goatos/bin/goatos-meta converge #{opts[:name]}"
32
+ run_blender(commands, opts)
33
+ end
34
+
35
+ desc 'lxc stop', 'stop a container'
36
+ option :name,
37
+ aliases: '-N',
38
+ required: true,
39
+ description: 'Name of the container to stop'
40
+ def stop
41
+ opts = options.dup
42
+ command = [ 'lxc-stop' ]
43
+ command += ['-n', opts[:name]]
44
+ run_blender(command.join(' '), opts)
45
+ end
46
+
47
+ desc 'lxc destroy', 'destroy a container'
48
+ option :name,
49
+ aliases: '-N',
50
+ required: true,
51
+ description: 'Name of the container to destroy'
52
+ option :force,
53
+ aliases: '-f',
54
+ type: :boolean,
55
+ description: 'Force destroy (will shutdown a container if its running)'
56
+ def destroy
57
+ opts = options.dup
58
+ commands = [ "lxc-destroy -n #{opts[:name]}" ]
59
+ commands.first << ' -f' if opts[:force]
60
+ commands << "/opt/goatos/bin/goatos-meta delete #{options[:name]}"
61
+ run_blender(commands, opts)
62
+ end
63
+
64
+ desc 'lxc create', 'create a container'
65
+ option :template,
66
+ default: 'download',
67
+ aliases: '-t',
68
+ description: 'Template for building rootfs'
69
+ option :arch,
70
+ default: 'amd64',
71
+ aliases: '-a',
72
+ description: 'ARCH for the lxc'
73
+ option :distro,
74
+ default: 'ubuntu',
75
+ aliases: '-d',
76
+ description: 'Disro type to be used with download template'
77
+ option :release,
78
+ default: 'trusty',
79
+ aliases: '-r',
80
+ description: 'Release of a distribution (e.g lucid, precise, trusty for ubuntu)'
81
+ option :name,
82
+ required: true,
83
+ aliases: '-N',
84
+ description: 'Name of the container'
85
+ option :expose,
86
+ description: 'Network service this container will expose ct_port:protocol:host_port'
87
+ option :clone,
88
+ type: :string,
89
+ description: 'clone a stopped container'
90
+ option :chef_recipe,
91
+ type: :string,
92
+ aliases: '-R',
93
+ description: 'An chef recipe that will executed upon container start'
94
+ def create
95
+ opts = options.dup
96
+ commands = []
97
+ if options[:clone]
98
+ command = [ 'lxc-clone' ]
99
+ command += [ '-s', '-B', 'overlayfs' ]
100
+ command += [ opts[:clone], opts[:name] ]
101
+ commands = [ command.join(' ') ]
102
+ else
103
+ command = [ 'lxc-create']
104
+ command += ['-t', opts[:template]]
105
+ command += ['-n', opts[:name], '--']
106
+ command += ['-d', opts[:distro]]
107
+ command += ['-r', opts[:release]]
108
+ command += ['-a', opts[:arch]]
109
+ commands << command.join(' ')
110
+ end
111
+ command = [ "/opt/goatos/bin/goatos-meta add #{options[:name]}" ]
112
+ command += ['-t', opts[:template]]
113
+ command += ['-d', opts[:distro]]
114
+ command += ['-r', opts[:release]]
115
+ command += ['-a', opts[:arch]]
116
+ if opts[:chef_recipe]
117
+ command += ['-R', opts[:chef_recipe]]
118
+ end
119
+ if options[:expose]
120
+ command += ['-e', options[:expose]]
121
+ end
122
+ commands << command.join(' ')
123
+ run_blender( commands, opts )
124
+ end
125
+
126
+ desc 'meta ', 'Show lxc related metadata'
127
+ option :container,
128
+ type: :string,
129
+ description: 'Show metadata pertaining to only that container'
130
+ option :format,
131
+ type: :string,
132
+ description: 'Output format, can be text or json',
133
+ default: 'json'
134
+ def meta
135
+ if options[:container]
136
+ command = "/opt/goatos/bin/goatos-meta show #{options[:container]}"
137
+ else
138
+ command = '/opt/goatos/bin/goatos-meta list'
139
+ end
140
+ command << " -F #{options[:format]}"
141
+ run_blender(
142
+ command,
143
+ options
144
+ )
145
+ end
146
+
147
+ no_commands do
148
+ def run_blender(commands, opts)
149
+ Blender.blend('goatos_lxc') do |sched|
150
+ sched.config(:chef, config_file: 'etc/knife.rb', attribute: opts[:attribute])
151
+ sched.config(:ruby, stdout: $stdout)
152
+ sched.config(:ssh, stdout: $stdout, user: 'goatos', keys: ['keys/goatos.rsa'])
153
+ sched.members(sched.search(:chef, opts[:filter]))
154
+ Array(commands).each do |cmd|
155
+ sched.ssh_task cmd
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end