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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ef8161f2a0c107b2e4be02aac54c620d2607bbf0
4
+ data.tar.gz: 0674b85e3d506ee888ab48422e64ec889141433c
5
+ SHA512:
6
+ metadata.gz: 95d3b419c21adb663c40e7606b2e4becb68d663bcf67e09f4913f63f74bc9eb7da929547827340c288ad610c51709f90505babf13f880f1833fa52ef070c77b5
7
+ data.tar.gz: 176f308c9cfc1d9f5335824d84e2170ba215863ebe6804d62693ffce4384f0f4f0a5fa614b12c430aaa6f79664b512b914ea4e96554b42f945488f0a9fb369bf
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'blender', github: 'PagerDuty/blender'
5
+ gem 'chef'
6
+ gem 'blender-chef', github: 'PagerDuty/blender-chef'
7
+ gem 'irbtools'
8
+ gem 'pry'
@@ -0,0 +1,215 @@
1
+ GIT
2
+ remote: git://github.com/PagerDuty/blender-chef.git
3
+ revision: 8ccae9b31e09bef8db01bf1d0410cbdf8798e1df
4
+ specs:
5
+ blender-chef (0.0.1)
6
+ blender
7
+ chef
8
+
9
+ GIT
10
+ remote: git://github.com/PagerDuty/blender.git
11
+ revision: 84502879c0045bd54610d97c5adc63d6bb1816b0
12
+ specs:
13
+ blender (0.0.1)
14
+ highline
15
+ mixlib-log
16
+ mixlib-shellout
17
+ net-ssh
18
+ rufus-scheduler
19
+ thor
20
+
21
+ PATH
22
+ remote: .
23
+ specs:
24
+ goatos-base (0.0.1)
25
+ blender-chef
26
+ chef
27
+ pd-blender
28
+ sshkey
29
+ thor
30
+
31
+ GEM
32
+ remote: https://rubygems.org/
33
+ specs:
34
+ alias (0.2.3)
35
+ ast (2.0.0)
36
+ awesome_print (1.2.0)
37
+ binding.repl (1.0.4.1)
38
+ boson (1.2.4)
39
+ boson-more (0.2.2)
40
+ boson (>= 1.2.0)
41
+ chef (11.14.6)
42
+ chef-zero (~> 2.1, >= 2.1.4)
43
+ diff-lcs (~> 1.2, >= 1.2.4)
44
+ erubis (~> 2.7)
45
+ ffi-yajl (~> 1.0)
46
+ highline (~> 1.6, >= 1.6.9)
47
+ mime-types (~> 1.16)
48
+ mixlib-authentication (~> 1.3)
49
+ mixlib-cli (~> 1.4)
50
+ mixlib-config (~> 2.0)
51
+ mixlib-log (~> 1.3)
52
+ mixlib-shellout (~> 1.4)
53
+ net-ssh (~> 2.6)
54
+ net-ssh-multi (~> 1.1)
55
+ ohai (~> 7.2)
56
+ plist (~> 3.1.0)
57
+ pry (~> 0.9)
58
+ rest-client (>= 1.0.4, <= 1.6.7)
59
+ chef-zero (2.2)
60
+ hashie (~> 2.0)
61
+ json
62
+ mixlib-log (~> 1.3)
63
+ rack
64
+ clipboard (1.0.5)
65
+ coderay (1.1.0)
66
+ debugging (1.0.1)
67
+ binding.repl (~> 1)
68
+ paint (~> 0, >= 0.8.7)
69
+ diff-lcs (1.2.5)
70
+ erubis (2.7.0)
71
+ every_day_irb (1.6.1)
72
+ fancy_irb (0.7.3)
73
+ paint (>= 0.8.1)
74
+ unicode-display_width (>= 0.1.1)
75
+ ffi (1.9.3)
76
+ ffi-yajl (1.0.2)
77
+ ffi (~> 1.5)
78
+ libyajl2 (~> 1.0)
79
+ g (1.7.2)
80
+ hashie (2.1.2)
81
+ highline (1.6.21)
82
+ hirb (0.7.2)
83
+ interactive_editor (0.0.10)
84
+ spoon (>= 0.0.1)
85
+ ipaddress (0.8.0)
86
+ irbtools (1.6.1)
87
+ alias (~> 0.2.3)
88
+ awesome_print (~> 1.2)
89
+ binding.repl (>= 1.0.1)
90
+ boson (~> 1.2.4)
91
+ boson-more (~> 0.2.2)
92
+ clipboard (~> 1.0.5)
93
+ coderay (~> 1.1.0)
94
+ debugging (~> 1.0)
95
+ every_day_irb (>= 1.6.1)
96
+ fancy_irb (>= 0.7.3)
97
+ g (>= 1.7.2)
98
+ hirb (~> 0.7)
99
+ interactive_editor (>= 0.0.10)
100
+ method_locator (>= 0.0.4)
101
+ method_source (>= 0.8.2)
102
+ methodfinder (>= 1.2.5)
103
+ ori (~> 0.1.0)
104
+ os (~> 0.9)
105
+ paint (>= 0.8.7)
106
+ ruby_engine (~> 1.0)
107
+ ruby_info (~> 1.0)
108
+ ruby_version (~> 1.0)
109
+ wirb (>= 1.0.3)
110
+ json (1.8.1)
111
+ libyajl2 (1.0.1)
112
+ method_locator (0.0.4)
113
+ method_source (0.8.2)
114
+ methodfinder (2.0.0)
115
+ mime-types (1.25.1)
116
+ mixlib-authentication (1.3.0)
117
+ mixlib-log
118
+ mixlib-cli (1.5.0)
119
+ mixlib-config (2.1.0)
120
+ mixlib-log (1.6.0)
121
+ mixlib-shellout (1.4.0)
122
+ net-ssh (2.9.1)
123
+ net-ssh-gateway (1.2.0)
124
+ net-ssh (>= 2.6.5)
125
+ net-ssh-multi (1.2.0)
126
+ net-ssh (>= 2.6.5)
127
+ net-ssh-gateway (>= 1.2.0)
128
+ ohai (7.2.4)
129
+ ffi (~> 1.9)
130
+ ffi-yajl (~> 1.0)
131
+ ipaddress
132
+ mime-types (~> 1.16)
133
+ mixlib-cli
134
+ mixlib-config (~> 2.0)
135
+ mixlib-log
136
+ mixlib-shellout (~> 1.2)
137
+ systemu (~> 2.6.4)
138
+ wmi-lite (~> 1.0)
139
+ ori (0.1.0)
140
+ os (0.9.6)
141
+ paint (0.8.7)
142
+ parser (2.2.0.pre.4)
143
+ ast (>= 1.1, < 3.0)
144
+ slop (~> 3.4, >= 3.4.5)
145
+ pd-blender (0.0.1)
146
+ highline
147
+ mixlib-log
148
+ mixlib-shellout
149
+ net-ssh
150
+ rufus-scheduler
151
+ thor
152
+ plist (3.1.0)
153
+ powerpack (0.0.9)
154
+ pry (0.10.1)
155
+ coderay (~> 1.1.0)
156
+ method_source (~> 0.8.1)
157
+ slop (~> 3.4)
158
+ rack (1.5.2)
159
+ rainbow (2.0.0)
160
+ rake (10.3.2)
161
+ rest-client (1.6.7)
162
+ mime-types (>= 1.16)
163
+ rspec (3.0.0)
164
+ rspec-core (~> 3.0.0)
165
+ rspec-expectations (~> 3.0.0)
166
+ rspec-mocks (~> 3.0.0)
167
+ rspec-core (3.0.4)
168
+ rspec-support (~> 3.0.0)
169
+ rspec-expectations (3.0.4)
170
+ diff-lcs (>= 1.2.0, < 2.0)
171
+ rspec-support (~> 3.0.0)
172
+ rspec-mocks (3.0.4)
173
+ rspec-support (~> 3.0.0)
174
+ rspec-support (3.0.4)
175
+ rubocop (0.25.0)
176
+ parser (>= 2.2.0.pre.4, < 3.0)
177
+ powerpack (~> 0.0.6)
178
+ rainbow (>= 1.99.1, < 3.0)
179
+ ruby-progressbar (~> 1.4)
180
+ ruby-progressbar (1.5.1)
181
+ ruby_engine (1.0.1)
182
+ ruby_info (1.0.1)
183
+ ruby_version (1.0.1)
184
+ rufus-scheduler (3.0.8)
185
+ tzinfo
186
+ slop (3.6.0)
187
+ spoon (0.0.4)
188
+ ffi
189
+ sshkey (1.6.1)
190
+ systemu (2.6.4)
191
+ thor (0.19.1)
192
+ thread_safe (0.3.4)
193
+ tzinfo (1.2.2)
194
+ thread_safe (~> 0.1)
195
+ unicode-display_width (0.1.1)
196
+ wirb (1.0.3)
197
+ paint (~> 0.8)
198
+ wmi-lite (1.0.0)
199
+ yard (0.8.7.4)
200
+
201
+ PLATFORMS
202
+ ruby
203
+
204
+ DEPENDENCIES
205
+ blender!
206
+ blender-chef!
207
+ bundler
208
+ chef
209
+ goatos-base!
210
+ irbtools
211
+ pry
212
+ rake
213
+ rspec
214
+ rubocop
215
+ yard
@@ -0,0 +1,14 @@
1
+ Copyright:: Copyright (c) Ranjib Dey, ranjib@linux.com.
2
+ License:: Apache License, Version 2.0
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
@@ -0,0 +1,92 @@
1
+ ### Description
2
+ GoatOS is a distributed LXC automation suite. It uses Chef for configuration
3
+ managemenbt and Blender for orchestration.
4
+
5
+ With GoatOS you can set up ubuntu 14.04 servers to run unprivileged LXC
6
+ containers. GoatOS automates
7
+ - bootstrapping/provisioning LXC hosts, chef servers etc (using SSH).
8
+ - container life cycle management (create, start, stop, destroy)
9
+ - exposing network services from containers to outside (using haproxy)
10
+ - customizing container with familiar chef DSL
11
+
12
+ ### Installation
13
+ ```sh
14
+ gem install goatos-base
15
+ ```
16
+
17
+ ### Usage
18
+ #### Setup
19
+ ```sh
20
+ goatos init
21
+ ```
22
+ Typical GoatOS clusters are composed of one master and multiple slaves. Master
23
+ hosts chef server, which act as configuration artifact repository and metadata
24
+ source, while the slave nodes run unprivileged LXC instances. Master and slave
25
+ host customization can be done via chef, while container management is done on
26
+ demand via blender.
27
+
28
+ `GoatOS Base` can be installed in a single host ( standalone mode) as well. For
29
+ this create a virtual box vm (or ec2 instance) with ubuntu 14.04. Create an user
30
+ with sudo access and bootstrap the instance with following command:
31
+
32
+ ```sh
33
+ goatos bootstrap -h 192.168.1.49 -u ubuntu -i ssh_key.rsa
34
+ ```
35
+
36
+ Note: GoatOS installer will ask for ssh password when `-P` flag is passed, instead of the `-i` flag.
37
+
38
+ This will install chef server, LXC and a goatos specific ssh keypair on the
39
+ instance. Chef and ssh configuration will be stored locally for downstream automation.
40
+ You should have chef's admin and validation key along with goatos specific ssh key on
41
+ the `keys` directory in your current directory. This will also generate a knife config
42
+ in `etc` directory for chef (you invoke all regular knife commands by passing
43
+ -c etc/knife.rb, hence forth).
44
+
45
+
46
+ Next you can check conatiners present on the goatos fleet like this:
47
+
48
+ ```sh
49
+ goatos lxc ls
50
+ ```
51
+ This will use the ssh credentials (`goatos` user and an rsa key) generate via bootstrap.
52
+
53
+ To create a container, use the `goatos lxc create` command.
54
+ ```sh
55
+ goatos lxc create -N ct01
56
+ ```
57
+ This will create an ubunu 14.04 container. Additional flags can be used to create container
58
+ specify other distro, release, archtecture. You can specify network services that you want
59
+ to expose from the container using the `--expose` flag.
60
+
61
+ ```sh
62
+ goatos lxc create -N ct01 --expose 22:tcp:2201
63
+ ```
64
+ Above command will save the '22:tcp:2201' as metadata for the container. This metadata is
65
+ processed by chef runs that controls the host running container to expose outside using haproxy.
66
+ The string `22:tcp:2201` express the intent to expose port 22 (SSH i.e) of container on port
67
+ 2201 on the host. Following goatos command will propagate these changes via chef.
68
+
69
+ ```sh
70
+ bundle exec goatos run-chef -u USER -i key.rsa
71
+ ```
72
+ You should be able to ssh into one of the container directly by `ssh -p 2201 HOST_IP`. Note,
73
+ the default container have a prebaked user with name `ubuntu` and password `ubuntu`
74
+
75
+
76
+ For multinode cluster, you can bootstrap the master with `-T master` option,
77
+ which will direct goatos to install only chef server specific components
78
+ in the target host. While rest of the instanec can be bootstrapped with
79
+ `-T slave` option, which will direct goatos to use local knife config (generated
80
+ via master bootstrap process) and install only LXC specific tooling.
81
+
82
+
83
+ ## License
84
+ [Apache 2](http://www.apache.org/licenses/LICENSE-2.0)
85
+
86
+ ## Contributing
87
+
88
+ 1. Fork it ( https://github.com/PagerDuty/blender/fork )
89
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
90
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
91
+ 4. Push to the branch (`git push origin my-new-feature`)
92
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require 'bundler/gem_tasks'
2
+
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set ft=ruby:
3
+
4
+ require 'blender'
5
+ require 'goatos/cli'
6
+
7
+
8
+ GoatOS::CLI.start(ARGV)
@@ -0,0 +1,2 @@
1
+ default['goatos']['user'] = 'goatos'
2
+ default['goatos']['group'] = 'goatos'
@@ -0,0 +1,184 @@
1
+ #!/opt/chef/embedded/bin/ruby
2
+
3
+ require 'lxc'
4
+ require 'json'
5
+ require 'thor'
6
+ require 'mixlib/shellout'
7
+ require 'chef/application/lxc'
8
+
9
+ module GoatOS
10
+ module Meta
11
+ CtMetadata = Struct.new(
12
+ :name,
13
+ :template,
14
+ :release,
15
+ :arch,
16
+ :distro,
17
+ :expose,
18
+ :chef_recipe
19
+ ) do
20
+ if RUBY_VERSION < '2.1.1'
21
+ def to_h
22
+ Hash[ each_pair.to_a ]
23
+ end
24
+ end
25
+ end
26
+ class JSONStore
27
+ attr_reader :state_file
28
+ def initialize(state_file = '/opt/goatos/goats.json')
29
+ @state_file = state_file
30
+ @metadata = nil
31
+ end
32
+ def metadata
33
+ @metadata ||= fetch_metadata
34
+ end
35
+ def fetch_metadata
36
+ collection = { 'containers'=> {}, 'last_updated' => nil }
37
+ if File.exists?(state_file)
38
+ data = JSON.parse(File.read(state_file))
39
+ data['containers'].each do |name, meta|
40
+ collection['containers'][name] = CtMetadata.new(*meta.values)
41
+ end
42
+ collection['last_updated'] = data['last_updated']
43
+ end
44
+ collection
45
+ end
46
+ def add(name, meta)
47
+ unless get(name).nil?
48
+ raise RuntimeError, "Container '#{name}' already present"
49
+ end
50
+ metadata['containers'][name]= meta
51
+ write_to_disk
52
+ end
53
+
54
+ def write_to_disk
55
+ cts = {'containers'=> {}}
56
+ metadata['containers'].each do |n, meta|
57
+ cts['containers'][n] = meta.to_h
58
+ end
59
+ cts['last_updated'] = Time.now
60
+ File.open(state_file, 'w') do |f|
61
+ f.write(JSON.pretty_generate(cts))
62
+ end
63
+ end
64
+
65
+ def get(name)
66
+ metadata['containers'][name]
67
+ end
68
+ def delete(name)
69
+ metadata['containers'].delete(name)
70
+ write_to_disk
71
+ end
72
+ def list
73
+ metadata['containers']
74
+ end
75
+ end
76
+ class CLI < Thor
77
+ class_option :format,
78
+ type: :string,
79
+ aliases: '-F',
80
+ description: 'Format output(test or json)',
81
+ default: 'text'
82
+
83
+ desc 'converge CONTAINER', 'Converge a chef recipe inside the container'
84
+ def converge(container)
85
+ store = JSONStore.new
86
+ recipe = store.get(container).chef_recipe
87
+ recipe_path = "/opt/goatos/recipes/#{recipe}.rb"
88
+ recipe_text = File.read(recipe_path)
89
+ Chef::Config[:solo] = true
90
+ ct = ::LXC::Container.new(container)
91
+ Chef::Log.init(STDOUT)
92
+ Chef::Log.level = :info
93
+ client = Class.new(Chef::Client) do
94
+ def run_ohai
95
+ ohai.run_plugins
96
+ end
97
+ end.new
98
+ client.ohai.load_plugins
99
+ ct.execute do
100
+ client.run_ohai
101
+ client.load_node
102
+ client.build_node
103
+ run_context = Chef::RunContext.new(client.node, {}, client.events)
104
+ recipe = Chef::Recipe.new('goatos_lxc', recipe, run_context)
105
+ recipe.instance_eval(recipe_text, recipe_path, 1)
106
+ runner = Chef::Runner.new(run_context)
107
+ runner.converge
108
+ end
109
+ end
110
+
111
+ desc 'list', 'list all the metadata'
112
+ def list
113
+ store = JSONStore.new
114
+ list = store.list
115
+ case options[:format]
116
+ when 'text'
117
+ list.each do |name, meta|
118
+ puts "#{name} | Metadata: #{meta.inspect}"
119
+ end
120
+ when 'json'
121
+ puts JSON.pretty_generate(list)
122
+ end
123
+ end
124
+
125
+ desc 'show NAME', 'show metadata of a single container'
126
+ def show(name)
127
+ store = JSONStore.new
128
+ meta = store.get(name)
129
+ case options[:format]
130
+ when 'text'
131
+ puts "#{name} | Metadata: #{meta.inspect}"
132
+ when 'json'
133
+ puts JSON.pretty_generate(meta.to_h)
134
+ end
135
+ end
136
+
137
+ desc 'add NAME', 'Add a container info in the metadata'
138
+ option :template,
139
+ default: 'download',
140
+ aliases: '-t',
141
+ description: 'Template for building rootfs'
142
+ option :arch,
143
+ default: 'amd64',
144
+ aliases: '-a',
145
+ description: 'ARCH for the lxc'
146
+ option :distro,
147
+ default: 'ubuntu',
148
+ aliases: '-d',
149
+ description: 'Disro type to be used with download template'
150
+ option :chef_recipe,
151
+ aliases: '-R',
152
+ description: 'A chef recipe that will be executed upon container start'
153
+ option :release,
154
+ default: 'trusty',
155
+ aliases: '-r',
156
+ description: 'Release of a distribution (e.g lucid, precise, trusty for ubuntu)'
157
+ option :expose,
158
+ aliases: '-e',
159
+ description: 'Expose container port'
160
+ def add(name)
161
+ store = JSONStore.new
162
+ meta = CtMetadata.new(
163
+ name,
164
+ options[:template],
165
+ options[:release],
166
+ options[:arch],
167
+ options[:distro],
168
+ options[:expose],
169
+ options[:chef_recipe]
170
+ )
171
+ store.add(name, meta)
172
+ end
173
+ desc 'delte CONTAINER_NAME', 'delete container meta data'
174
+ def delete(name)
175
+ store = JSONStore.new
176
+ store.delete(name)
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ if $0 == __FILE__
183
+ GoatOS::Meta::CLI.start(ARGV)
184
+ end