serverkit 0.1.0 → 0.2.0
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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +21 -11
- data/example/recipes/dotfiles.yml.erb +4 -4
- data/lib/readable_validator.rb +1 -1
- data/lib/serverkit/actions/apply.rb +14 -12
- data/lib/serverkit/actions/base.rb +34 -16
- data/lib/serverkit/actions/check.rb +10 -8
- data/lib/serverkit/actions/inspect.rb +2 -7
- data/lib/serverkit/actions/validate.rb +2 -6
- data/lib/serverkit/command.rb +1 -1
- data/lib/serverkit/loaders/base_loader.rb +0 -1
- data/lib/serverkit/loaders/recipe_loader.rb +7 -20
- data/lib/serverkit/variables.rb +11 -3
- data/lib/serverkit/version.rb +1 -1
- data/serverkit.gemspec +1 -0
- metadata +15 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 612a45453d00dd4da8b327be21c8513dfb920292
|
4
|
+
data.tar.gz: 4beb20763b868203c302697f114b508c5f5f4cd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4172b07769a11c4002e67caff3cb009262912e188b583893e4a9bf00a3a9432934088ae1c2c4df5bcf433a9e8621eaa1e33c122aab7547d03f118b39d0511ae6
|
7
|
+
data.tar.gz: 5068bbb81ac75922f293ff2061a41a22de161acfadf5fb64efd3100906e37014202fedec6604ecd748d1a5b716e3834e303e113be12b27c78ccee969d5610093
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 0.2.0
|
2
|
+
- Support multiple hosts
|
3
|
+
- Change `--host=` option to `--hosts=`
|
4
|
+
- Change variables use on ERB template
|
5
|
+
- Force recipe validation on all actions
|
6
|
+
|
1
7
|
## 0.1.0
|
2
8
|
- Support execution over SSH with --host option
|
3
9
|
- Remove --recipe=... option and require recipe path in 2nd command-line argument
|
data/README.md
CHANGED
@@ -62,12 +62,12 @@ Shows the difference between your recipe and the state of the target host.
|
|
62
62
|
|
63
63
|
```
|
64
64
|
$ serverkit check recipe.yml
|
65
|
-
[OK] install_mysql
|
66
|
-
[OK] install_redis
|
67
|
-
[OK] install_licecap
|
68
|
-
[OK] install_alfred
|
69
|
-
[NG] clone_dotfiles
|
70
|
-
[NG] symlink_zshrc
|
65
|
+
[ OK ] install_mysql
|
66
|
+
[ OK ] install_redis
|
67
|
+
[ OK ] install_licecap
|
68
|
+
[ OK ] install_alfred
|
69
|
+
[ NG ] clone_dotfiles
|
70
|
+
[ NG ] symlink_zshrc
|
71
71
|
```
|
72
72
|
|
73
73
|
### serverkit apply
|
@@ -83,6 +83,16 @@ $ serverkit apply recipe.yml
|
|
83
83
|
[DONE] symlink_zshrc
|
84
84
|
```
|
85
85
|
|
86
|
+
### SSH support
|
87
|
+
Use `--hosts=` option to execute serverkit over SSH.
|
88
|
+
Serverkit does not require any installation on server-side.
|
89
|
+
If you want to specify SSH configuration, write it into your ~/.ssh/config.
|
90
|
+
|
91
|
+
```
|
92
|
+
$ serverkit apply recipe.yml --hosts=alpha.example.com
|
93
|
+
$ serverkit apply recipe.yml --hosts=alpha.example.com,bravo.example.com
|
94
|
+
```
|
95
|
+
|
86
96
|
## Recipe
|
87
97
|
A recipe describes the desired state of your server.
|
88
98
|
It is mostly a collection of resources, defined using certain patterns.
|
@@ -115,7 +125,7 @@ $ serverkit apply recipes/
|
|
115
125
|
When using ERB recipe, you can also give optional variables file
|
116
126
|
that defines configurations in a Hash object for ERB template.
|
117
127
|
It supports similar format variation with Recipe.
|
118
|
-
In ERB template, you can use given variables via
|
128
|
+
In ERB template, you can use given variables via methods named after its keys.
|
119
129
|
|
120
130
|
### Example
|
121
131
|
This is an example recipe to install some packages, clone a git repository, and create a symlink.
|
@@ -137,12 +147,12 @@ resources:
|
|
137
147
|
name: redis
|
138
148
|
- id: clone_dotfiles
|
139
149
|
type: git
|
140
|
-
repository: git@github.com:<%=
|
141
|
-
path: /Users/<%=
|
150
|
+
repository: git@github.com:<%= dotfiles_repository %>.git
|
151
|
+
path: /Users/<%= user %>/src/github.com/<%= dotfiles_repository %>
|
142
152
|
- id: symlink_zshrc
|
143
153
|
type: symlink
|
144
|
-
source: /Users/<%=
|
145
|
-
destination: /Users/<%=
|
154
|
+
source: /Users/<%= user %>/.zshrc
|
155
|
+
destination: /Users/<%= user %>/src/github.com/<%= dotfiles_repository %>/.zshrc
|
146
156
|
```
|
147
157
|
|
148
158
|
## Resource
|
@@ -1,9 +1,9 @@
|
|
1
1
|
resources:
|
2
2
|
- id: clone_dotfiles
|
3
3
|
type: git
|
4
|
-
repository: git@github.com:<%=
|
5
|
-
path: /Users/<%=
|
4
|
+
repository: git@github.com:<%= dotfiles_github_repository %>.git
|
5
|
+
path: /Users/<%= user %>/src/github.com/<%= dotfiles_github_repository %>
|
6
6
|
- id: symlink_zshrc
|
7
7
|
type: symlink
|
8
|
-
source: /Users/<%=
|
9
|
-
destination: /Users/<%=
|
8
|
+
source: /Users/<%= user %>/.zshrc
|
9
|
+
destination: /Users/<%= user %>/src/github.com/<%= dotfiles_github_repository %>/linked/.zshrc
|
data/lib/readable_validator.rb
CHANGED
@@ -2,7 +2,7 @@ require "active_model"
|
|
2
2
|
|
3
3
|
class ReadableValidator < ActiveModel::EachValidator
|
4
4
|
def validate_each(record, attribute, value)
|
5
|
-
|
5
|
+
if !value.nil? && !File.readable?(value)
|
6
6
|
record.errors.add(attribute, "can't be unreadable path")
|
7
7
|
end
|
8
8
|
end
|
@@ -1,22 +1,24 @@
|
|
1
1
|
require "serverkit/actions/base"
|
2
|
+
require "thread"
|
2
3
|
|
3
4
|
module Serverkit
|
4
5
|
module Actions
|
5
6
|
class Apply < Base
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
def run
|
8
|
+
backends.map do |backend|
|
9
|
+
Thread.new do
|
10
|
+
recipe.resources.map(&:dup).each do |resource|
|
11
|
+
resource.backend = backend
|
12
|
+
if resource.check
|
13
|
+
puts "[SKIP] #{resource.id} on #{host_for(backend)}"
|
14
|
+
else
|
15
|
+
resource.apply
|
16
|
+
result = resource.check ? "DONE" : "FAIL"
|
17
|
+
puts "[#{result}] #{resource.id} on #{host_for(backend)}"
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
|
-
end
|
21
|
+
end.each(&:join)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -14,48 +14,65 @@ module Serverkit
|
|
14
14
|
@argv = argv
|
15
15
|
end
|
16
16
|
|
17
|
+
def call
|
18
|
+
setup
|
19
|
+
run
|
20
|
+
end
|
21
|
+
|
17
22
|
private
|
18
23
|
|
19
24
|
def abort_with_errors
|
20
25
|
abort recipe.errors.map { |error| "Error: #{error}" }.join("\n")
|
21
26
|
end
|
22
27
|
|
23
|
-
# @return [Specinfra::Backend::Base]
|
24
|
-
def
|
25
|
-
|
28
|
+
# @return [Array<Specinfra::Backend::Base>]
|
29
|
+
def backends
|
30
|
+
if options[:hosts]
|
31
|
+
hosts.map do |host|
|
32
|
+
backend_class.new(
|
33
|
+
disable_sudo: true,
|
34
|
+
host: host,
|
35
|
+
ssh_options: {
|
36
|
+
user: ssh_user_for(host),
|
37
|
+
},
|
38
|
+
)
|
39
|
+
end
|
40
|
+
else
|
41
|
+
[backend_class.new]
|
42
|
+
end
|
26
43
|
end
|
27
44
|
|
28
45
|
def backend_class
|
29
|
-
if
|
46
|
+
if options[:hosts]
|
30
47
|
Specinfra::Backend::Ssh
|
31
48
|
else
|
32
49
|
Specinfra::Backend::Exec
|
33
50
|
end
|
34
51
|
end
|
35
52
|
|
36
|
-
def
|
37
|
-
|
38
|
-
disable_sudo: true,
|
39
|
-
host: host,
|
40
|
-
ssh_options: {
|
41
|
-
user: ssh_user,
|
42
|
-
},
|
43
|
-
}
|
53
|
+
def hosts
|
54
|
+
options[:hosts].split(",")
|
44
55
|
end
|
45
56
|
|
46
|
-
|
47
|
-
|
57
|
+
# @param [Specinfra::Backend::Base]
|
58
|
+
# @return [String]
|
59
|
+
def host_for(backend)
|
60
|
+
backend.get_config(:host) || "localhost"
|
48
61
|
end
|
49
62
|
|
50
63
|
# @return [Slop] Command-line options
|
51
64
|
def options
|
52
65
|
@options ||= Slop.parse!(@argv, help: true) do
|
53
66
|
banner "Usage: serverkit ACTION [options]"
|
54
|
-
on "--
|
67
|
+
on "--hosts=", "Pass hostname to execute command over SSH"
|
55
68
|
on "--variables=", "Path to variables file for ERB recipe"
|
56
69
|
end
|
57
70
|
end
|
58
71
|
|
72
|
+
def setup
|
73
|
+
abort_with_errors unless recipe.valid?
|
74
|
+
end
|
75
|
+
|
59
76
|
# @return [Serverkit::Recipe]
|
60
77
|
def recipe
|
61
78
|
@recipe ||= Loaders::RecipeLoader.new(recipe_path, variables_path: options[:variables]).load
|
@@ -66,8 +83,9 @@ module Serverkit
|
|
66
83
|
@argv[1] or raise Errors::MissingRecipePathArgumentError
|
67
84
|
end
|
68
85
|
|
86
|
+
# @param [String] host
|
69
87
|
# @return [String] User name used on SSH
|
70
|
-
def
|
88
|
+
def ssh_user_for(host)
|
71
89
|
Net::SSH::Config.for(host)[:user] || Etc.getlogin
|
72
90
|
end
|
73
91
|
end
|
@@ -1,17 +1,19 @@
|
|
1
1
|
require "serverkit/actions/base"
|
2
|
+
require "thread"
|
2
3
|
|
3
4
|
module Serverkit
|
4
5
|
module Actions
|
5
6
|
class Check < Base
|
6
|
-
def
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
def run
|
8
|
+
backends.map do |backend|
|
9
|
+
Thread.new do
|
10
|
+
recipe.resources.map(&:dup).each do |resource|
|
11
|
+
resource.backend = backend
|
12
|
+
result = resource.check ? "OK" : "NG"
|
13
|
+
puts "[ #{result} ] #{resource.id} on #{host_for(backend)}"
|
14
|
+
end
|
13
15
|
end
|
14
|
-
end
|
16
|
+
end.each(&:join)
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -1,15 +1,10 @@
|
|
1
1
|
require "serverkit/actions/base"
|
2
|
-
require "yaml"
|
3
2
|
|
4
3
|
module Serverkit
|
5
4
|
module Actions
|
6
5
|
class Inspect < Base
|
7
|
-
def
|
8
|
-
|
9
|
-
puts JSON.pretty_generate(recipe.to_hash)
|
10
|
-
else
|
11
|
-
abort_with_errors
|
12
|
-
end
|
6
|
+
def run
|
7
|
+
puts JSON.pretty_generate(recipe.to_hash)
|
13
8
|
end
|
14
9
|
end
|
15
10
|
end
|
data/lib/serverkit/command.rb
CHANGED
@@ -28,7 +28,7 @@ module Serverkit
|
|
28
28
|
else
|
29
29
|
raise Errors::UnknownActionNameError
|
30
30
|
end
|
31
|
-
rescue Errors::Base, Slop::MissingOptionError => exception
|
31
|
+
rescue Errors::Base, Slop::MissingArgumentError, Slop::MissingOptionError => exception
|
32
32
|
abort "Error: #{exception}"
|
33
33
|
end
|
34
34
|
|
@@ -5,7 +5,7 @@ require "serverkit/recipe"
|
|
5
5
|
module Serverkit
|
6
6
|
module Loaders
|
7
7
|
class RecipeLoader < BaseLoader
|
8
|
-
|
8
|
+
DEFAULT_VARIABLES_DATA = {}
|
9
9
|
|
10
10
|
# @param [String] path
|
11
11
|
# @param [String, nil] variables_path
|
@@ -17,8 +17,9 @@ module Serverkit
|
|
17
17
|
private
|
18
18
|
|
19
19
|
# @note Override
|
20
|
+
# @return [Binding]
|
20
21
|
def binding_for_erb
|
21
|
-
|
22
|
+
variables.to_mash.binding
|
22
23
|
end
|
23
24
|
|
24
25
|
# @note Override to pass @variables_path
|
@@ -45,30 +46,16 @@ module Serverkit
|
|
45
46
|
Serverkit::Recipe
|
46
47
|
end
|
47
48
|
|
48
|
-
# @return [
|
49
|
-
def
|
49
|
+
# @return [Serverkit::Variables]
|
50
|
+
def variables
|
50
51
|
@variables ||= begin
|
51
52
|
if has_variables_path?
|
52
|
-
load_variables
|
53
|
+
load_variables
|
53
54
|
else
|
54
|
-
|
55
|
+
Variables.new(DEFAULT_VARIABLES_DATA.dup)
|
55
56
|
end
|
56
57
|
end
|
57
58
|
end
|
58
|
-
|
59
|
-
class ErbBindingContext
|
60
|
-
attr_reader :variables
|
61
|
-
|
62
|
-
# @param [hash] variables
|
63
|
-
def initialize(variables)
|
64
|
-
@variables = variables
|
65
|
-
end
|
66
|
-
|
67
|
-
# @note Change method visibility to public
|
68
|
-
def binding
|
69
|
-
super
|
70
|
-
end
|
71
|
-
end
|
72
59
|
end
|
73
60
|
end
|
74
61
|
end
|
data/lib/serverkit/variables.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "active_support/core_ext/hash/deep_merge"
|
2
|
+
require "hashie/mash"
|
2
3
|
|
3
4
|
module Serverkit
|
4
5
|
class Variables
|
@@ -23,9 +24,16 @@ module Serverkit
|
|
23
24
|
)
|
24
25
|
end
|
25
26
|
|
26
|
-
# @return [
|
27
|
-
def
|
28
|
-
@variables_data.dup
|
27
|
+
# @return [Hashie::Mash]
|
28
|
+
def to_mash
|
29
|
+
BindableMash.new(@variables_data.dup)
|
30
|
+
end
|
31
|
+
|
32
|
+
class BindableMash < Hashie::Mash
|
33
|
+
# @note Override visibility from private to public
|
34
|
+
def binding
|
35
|
+
super
|
36
|
+
end
|
29
37
|
end
|
30
38
|
end
|
31
39
|
end
|
data/lib/serverkit/version.rb
CHANGED
data/serverkit.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
|
19
19
|
spec.add_runtime_dependency "activemodel"
|
20
20
|
spec.add_runtime_dependency "activesupport"
|
21
|
+
spec.add_runtime_dependency "hashie"
|
21
22
|
spec.add_runtime_dependency "highline"
|
22
23
|
spec.add_runtime_dependency "slop", "~> 3.4"
|
23
24
|
spec.add_runtime_dependency "specinfra"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: serverkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: hashie
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: highline
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|