solokit 0.0.1 → 0.0.2
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.
- data/.gitignore +1 -0
- data/Gemfile.lock +17 -0
- data/Rakefile +4 -0
- data/lib/chef.rb +47 -45
- data/lib/configuration.rb +14 -13
- data/lib/solokit/version.rb +1 -1
- data/lib/ssh.rb +25 -24
- data/lib/user_json_generator.rb +75 -74
- metadata +6 -3
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/Gemfile.lock
ADDED
data/Rakefile
ADDED
data/lib/chef.rb
CHANGED
@@ -1,57 +1,59 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), 'ssh.rb'))
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module Solokit
|
4
|
+
class Chef
|
5
|
+
def initialize(ip, name, env, debug_ssh, user = 'root')
|
6
|
+
@ip, @name, @env = ip, name, env
|
7
|
+
@ssh = SSH.new(ip, user, debug_ssh)
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
def install
|
11
|
+
return true if installed?
|
12
|
+
puts "#{@name} (#{@env}): Installing chef..."
|
13
|
+
@ssh.run('export DEBIAN_FRONTEND=noninteractive; apt-get update && apt-get upgrade -y && apt-get install ruby ruby1.8-dev libopenssl-ruby wget rsync build-essential -y && wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz && tar xfz rubygems-1.3.7.tgz && cd rubygems-1.3.7 && ruby setup.rb && cd .. && rm -rf rubygems-1.3.7* && ln -s /usr/bin/gem1.8 /usr/bin/gem && gem install chef ohai --no-ri --no-rdoc')
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
16
|
+
def upload(root = "/")
|
17
|
+
@ssh.run("rm -rf #{root}var/chef-solo", false) &&
|
18
|
+
@ssh.run("rm -rf #{root}etc/chef", false) &&
|
19
|
+
upload_files("cookbooks/upstream/", "#{root}var/chef-solo/upstream-cookbooks") &&
|
20
|
+
upload_files("cookbooks/site/", "#{root}var/chef-solo/site-cookbooks") &&
|
21
|
+
(File.exists?("envs/#{@env}/cookbooks") ?
|
22
|
+
upload_files("envs/#{@env}/cookbooks/*", "#{root}var/chef-solo/site-cookbooks") :
|
23
|
+
true) &&
|
24
|
+
upload_files("chef/*", "#{root}etc/chef") &&
|
25
|
+
upload_files("envs/#{@env}/chef/", "#{root}etc/chef")
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
28
|
+
def run(debug = false, root = "/")
|
29
|
+
puts "\n#{@name} (#{@env}): Running chef..."
|
30
|
+
if debug
|
31
|
+
@ssh.run("#{custom_ruby_path(root)} chef-solo -c #{root}etc/chef/solo.rb -j #{root}etc/chef/#{@name}.json -l debug", false)
|
32
|
+
else
|
33
|
+
@ssh.run("#{custom_ruby_path(root)} chef-solo -c #{root}etc/chef/solo.rb -j #{root}etc/chef/#{@name}.json", false)
|
34
|
+
end
|
33
35
|
end
|
34
|
-
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
37
|
+
def self.provision!(env, host, config)
|
38
|
+
chef = Chef.new(host, "server", env, config.debug_ssh)
|
39
|
+
chef.install || raise("Chef install failed on #{env}")
|
40
|
+
chef.upload || raise("Chef upload failed on #{env}")
|
41
|
+
chef.run(config.debug_chef) || raise("Chef failed on #{env}")
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
def custom_ruby_path(root)
|
46
|
-
"PATH=\"#{root}ruby/bin:/sbin:$PATH\""
|
47
|
-
end
|
44
|
+
private
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
46
|
+
def custom_ruby_path(root)
|
47
|
+
"PATH=\"#{root}ruby/bin:/sbin:$PATH\""
|
48
|
+
end
|
53
49
|
|
54
|
-
|
55
|
-
|
50
|
+
def upload_files(from, to)
|
51
|
+
@ssh.run("mkdir -p #{to}") &&
|
52
|
+
@ssh.rsync(from, to, true)
|
53
|
+
end
|
54
|
+
|
55
|
+
def installed?
|
56
|
+
@ssh.run('gem list chef | grep chef')
|
57
|
+
end
|
56
58
|
end
|
57
59
|
end
|
data/lib/configuration.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
config = shared_config
|
8
|
-
envs.each do |env|
|
9
|
-
env_config_file = "envs/#{env}/config.yml"
|
3
|
+
module Solokit
|
4
|
+
class Configuration < OpenStruct
|
5
|
+
def initialize(*envs)
|
6
|
+
shared_config = YAML.load_file("config.yml")
|
10
7
|
|
11
|
-
config =
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
config = shared_config
|
9
|
+
envs.each do |env|
|
10
|
+
env_config_file = "envs/#{env}/config.yml"
|
11
|
+
|
12
|
+
config = File.exists?(env_config_file) ?
|
13
|
+
YAML.load_file(env_config_file).merge(config) :
|
14
|
+
config
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
+
super(config)
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
|
-
|
data/lib/solokit/version.rb
CHANGED
data/lib/ssh.rb
CHANGED
@@ -1,33 +1,34 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
module Solokit
|
2
|
+
class SSH
|
3
|
+
def initialize(ip, user, debug)
|
4
|
+
@ip, @user, @debug = ip, user, debug
|
5
|
+
end
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def run(command, quiet = true)
|
8
|
+
run_command("ssh #{ssh_opts} #{@user}@#{@ip} '#{command}' #{supress_output(quiet)}")
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
def rsync(source, target, quiet = false)
|
12
|
+
run_command("rsync -e 'ssh #{ssh_opts}' -az #{source} #{@user}@#{@ip}:#{target} #{supress_output(quiet)}")
|
13
|
+
end
|
13
14
|
|
14
|
-
|
15
|
+
private
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def supress_output(hide_stdout)
|
18
|
+
if @debug
|
19
|
+
""
|
20
|
+
else
|
21
|
+
"#{hide_stdout ? '2> /dev/null 1> /dev/null' : '2> /dev/null'}"
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def run_command(cmd)
|
26
|
+
puts "SSH | #{cmd}" if @debug
|
27
|
+
system(cmd)
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
30
|
+
def ssh_opts
|
31
|
+
"-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
|
data/lib/user_json_generator.rb
CHANGED
@@ -2,99 +2,100 @@ require 'yaml'
|
|
2
2
|
require 'active_support'
|
3
3
|
require 'active_support/json/encoding'
|
4
4
|
|
5
|
-
|
5
|
+
module Solokit
|
6
|
+
class UserJsonGenerator
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
def initialize(key_path, env, opts = {})
|
9
|
+
@key_path = key_path
|
9
10
|
|
10
|
-
|
11
|
+
data = YAML.load_file("users.yml")
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
@default_hash = data["default_hash"]
|
14
|
+
@users = data["users"]
|
15
|
+
@groups = data["groups"]
|
16
|
+
@env = data["envs"][env]
|
17
|
+
@opts = { :home => "/home" }.merge(opts)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def generate(target)
|
21
|
+
if ENV['DEBUG_USER_JSON']
|
22
|
+
require 'pp'
|
23
|
+
::PP.pp generate_json
|
24
|
+
exit 0
|
25
|
+
end
|
26
|
+
File.open(target, 'w') { |f| f.write(generate_json) }
|
24
27
|
end
|
25
|
-
File.open(target, 'w') { |f| f.write(generate_json) }
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
|
29
|
+
def self.generate!(env, opts = {})
|
30
|
+
UserJsonGenerator.new("public_keys", env, opts).generate("envs/#{env}/chef/roles/users.json")
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
+
private
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
def generate_json
|
36
|
+
{
|
37
|
+
:name => "Users",
|
38
|
+
:chef_type => "role",
|
39
|
+
:json_class => "Chef::Role",
|
40
|
+
:override_attributes => {
|
40
41
|
:users => env_users.inject({}) { |h, user|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
42
|
+
h[user] = {
|
43
|
+
:password => (@users[user] || {})["hash"] || @default_hash,
|
44
|
+
:home => (user == 'root' ? '/root' : [ @opts[:home], user ].join('/')),
|
45
|
+
:hidden_home => !!(@users[user] || {})["hidden_home"]
|
46
|
+
}; h
|
47
|
+
},
|
47
48
|
:ssh_keys => env_users.inject({}) { |h, user|
|
48
|
-
|
49
|
-
|
49
|
+
h[user] = get_keys(user); h
|
50
|
+
},
|
50
51
|
:authorization => {
|
51
|
-
|
52
|
-
|
52
|
+
:sudo => { :users => env_sudo_users }
|
53
|
+
}
|
53
54
|
},
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
:run_list => [ "recipe[users]", "recipe[sudo]" ]
|
56
|
+
}.send(ENV['DEBUG_USER_JSON'] ? 'to_hash' : 'to_json')
|
57
|
+
#.gsub(/\{/, "{\n").gsub(/\}/, "}\n")
|
58
|
+
end
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
def env_users
|
61
|
+
resolve_users(@env["users"].split)
|
62
|
+
end
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
def env_sudo_users
|
65
|
+
@env["sudo"] && resolve_users(@env["sudo"].split)
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
68
|
+
def resolve_users(list)
|
69
|
+
list.map { |item|
|
70
|
+
if item.include?("group")
|
71
|
+
fetch_group_users(item)
|
72
|
+
else
|
73
|
+
item
|
74
|
+
end
|
75
|
+
}.flatten
|
76
|
+
end
|
76
77
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
else
|
82
|
-
key_file = "#{@key_path}/#{key_name}.pub"
|
83
|
-
if File.exists?(key_file)
|
84
|
-
File.read(key_file).chomp
|
78
|
+
def get_keys(user)
|
79
|
+
(@users[user] || {})["keys"].to_s.split.map do |key_name|
|
80
|
+
if key_name.include?("group")
|
81
|
+
keys_from_group(key_name)
|
85
82
|
else
|
86
|
-
|
83
|
+
key_file = "#{@key_path}/#{key_name}.pub"
|
84
|
+
if File.exists?(key_file)
|
85
|
+
File.read(key_file).chomp
|
86
|
+
else
|
87
|
+
raise "Could not find key file: #{key_file}."
|
88
|
+
end
|
87
89
|
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
90
|
+
end.join("\n")
|
91
|
+
end
|
91
92
|
|
92
|
-
|
93
|
-
|
94
|
-
|
93
|
+
def fetch_group_users(name)
|
94
|
+
@groups[name.split('/').last].split
|
95
|
+
end
|
95
96
|
|
96
|
-
|
97
|
-
|
97
|
+
def keys_from_group(name)
|
98
|
+
@groups[name.split("/").last].split.map { |user| get_keys(user) }
|
99
|
+
end
|
98
100
|
end
|
99
101
|
end
|
100
|
-
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solokit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Joakim Kolsj\xC3\xB6"
|
@@ -58,10 +58,13 @@ extensions: []
|
|
58
58
|
extra_rdoc_files: []
|
59
59
|
|
60
60
|
files:
|
61
|
+
- .gitignore
|
61
62
|
- .rvmrc
|
62
63
|
- Gemfile
|
64
|
+
- Gemfile.lock
|
63
65
|
- LICENCE
|
64
66
|
- README
|
67
|
+
- Rakefile
|
65
68
|
- lib/chef.rb
|
66
69
|
- lib/configuration.rb
|
67
70
|
- lib/solokit.rb
|