itamae-mitsurin 0.50 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/itamae-mitsurin/cli.rb +0 -2
- data/lib/itamae-mitsurin/logger.rb +74 -20
- data/lib/itamae-mitsurin/mitsurin/base.rb +109 -0
- data/lib/itamae-mitsurin/mitsurin/base_task.rb +147 -0
- data/lib/itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/recipes/default.rb +0 -11
- data/lib/itamae-mitsurin/mitsurin/itamae_task.rb +44 -130
- data/lib/itamae-mitsurin/mitsurin/itamae_with_target_task.rb +64 -157
- data/lib/itamae-mitsurin/mitsurin/local_task.rb +57 -131
- data/lib/itamae-mitsurin/mitsurin/serverspec_task.rb +56 -81
- data/lib/itamae-mitsurin/mitsurin/serverspec_with_target_task.rb +80 -143
- data/lib/itamae-mitsurin/node.rb +0 -1
- data/lib/itamae-mitsurin/notification.rb +0 -1
- data/lib/itamae-mitsurin/recipe.rb +2 -5
- data/lib/itamae-mitsurin/resource.rb +1 -1
- data/lib/itamae-mitsurin/resource/base.rb +0 -12
- data/lib/itamae-mitsurin/resource/http_request.rb +23 -8
- data/lib/itamae-mitsurin/resource/s3_file.rb +33 -0
- data/lib/itamae-mitsurin/runner.rb +4 -5
- data/lib/itamae-mitsurin/version.txt +1 -1
- metadata +6 -221
- data/lib/itamae-mitsurin/mitsurin/itamae_with_git_task.rb +0 -159
- data/lib/itamae-mitsurin/mitsurin/task_base.rb +0 -100
- data/test/test_itamae-mitsurin.rb +0 -18
- data/test/test_itamae-mitsurin/ext/test_specinfra.rb +0 -39
- data/test/test_itamae-mitsurin/handler/test_base.rb +0 -40
- data/test/test_itamae-mitsurin/handler/test_debug.rb +0 -10
- data/test/test_itamae-mitsurin/handler/test_fluentd.rb +0 -44
- data/test/test_itamae-mitsurin/handler/test_json.rb +0 -22
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/.rspec +0 -2
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/Gemfile +0 -3
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/Rakefile +0 -2
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/environments/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/environments/sample.json +0 -7
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/keys/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/nodes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/nodes/sample01.json +0 -9
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/roles/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/attributes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/files/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/recipes/default.rb +0 -1
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/spec/default_spec.rb +0 -1
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/site-cookbooks/_base/_base/templates/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/spec/spec_helper.rb +0 -33
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/project/tmp-nodes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/attributes/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/files/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/recipes/default.rb +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/spec/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/templates/site-cookbooks/templates/.keep +0 -0
- data/test/test_itamae-mitsurin/mitsurin/creators/test_cookbook.rb +0 -24
- data/test/test_itamae-mitsurin/mitsurin/creators/test_project.rb +0 -24
- data/test/test_itamae-mitsurin/mitsurin/test_cli.rb +0 -56
- data/test/test_itamae-mitsurin/mitsurin/test_creators.rb +0 -19
- data/test/test_itamae-mitsurin/mitsurin/test_itamae_task.rb +0 -197
- data/test/test_itamae-mitsurin/mitsurin/test_itamae_with_git_task.rb +0 -213
- data/test/test_itamae-mitsurin/mitsurin/test_serverspec_task.rb +0 -123
- data/test/test_itamae-mitsurin/resource/test_aws_ebs_volume.rb +0 -84
- data/test/test_itamae-mitsurin/resource/test_base.rb +0 -374
- data/test/test_itamae-mitsurin/resource/test_directory.rb +0 -63
- data/test/test_itamae-mitsurin/resource/test_execute.rb +0 -26
- data/test/test_itamae-mitsurin/resource/test_file.rb +0 -176
- data/test/test_itamae-mitsurin/resource/test_gem_package.rb +0 -81
- data/test/test_itamae-mitsurin/resource/test_git.rb +0 -94
- data/test/test_itamae-mitsurin/resource/test_group.rb +0 -42
- data/test/test_itamae-mitsurin/resource/test_http_request.rb +0 -71
- data/test/test_itamae-mitsurin/resource/test_link.rb +0 -33
- data/test/test_itamae-mitsurin/resource/test_local_ruby_block.rb +0 -15
- data/test/test_itamae-mitsurin/resource/test_package.rb +0 -44
- data/test/test_itamae-mitsurin/resource/test_remote_directory.rb +0 -84
- data/test/test_itamae-mitsurin/resource/test_remote_file.rb +0 -54
- data/test/test_itamae-mitsurin/resource/test_service.rb +0 -69
- data/test/test_itamae-mitsurin/resource/test_template.rb +0 -53
- data/test/test_itamae-mitsurin/resource/test_user.rb +0 -93
- data/test/test_itamae-mitsurin/test_backend.rb +0 -297
- data/test/test_itamae-mitsurin/test_cli.rb +0 -88
- data/test/test_itamae-mitsurin/test_definition.rb +0 -40
- data/test/test_itamae-mitsurin/test_ext.rb +0 -1
- data/test/test_itamae-mitsurin/test_handler.rb +0 -21
- data/test/test_itamae-mitsurin/test_handler_proxy.rb +0 -38
- data/test/test_itamae-mitsurin/test_logger.rb +0 -124
- data/test/test_itamae-mitsurin/test_mitsurin.rb +0 -14
- data/test/test_itamae-mitsurin/test_node.rb +0 -74
- data/test/test_itamae-mitsurin/test_notification.rb +0 -46
- data/test/test_itamae-mitsurin/test_recipe.rb +0 -171
- data/test/test_itamae-mitsurin/test_recipe_children.rb +0 -86
- data/test/test_itamae-mitsurin/test_resource.rb +0 -73
- data/test/test_itamae-mitsurin/test_runner.rb +0 -124
- data/test/test_itamae-mitsurin/test_version.rb +0 -3
- data/test/test_itamae-mitsurin/version.txt +0 -1
- data/test_project/.rspec +0 -2
- data/test_project/Gemfile +0 -4
- data/test_project/Rakefile +0 -3
- data/test_project/environments/.keep +0 -0
- data/test_project/keys/.keep +0 -0
- data/test_project/nodes/.keep +0 -0
- data/test_project/nodes/test.json +0 -9
- data/test_project/roles/.keep +0 -0
- data/test_project/roles/test.json +0 -14
- data/test_project/site-cookbooks/_base/_base/attributes/.keep +0 -0
- data/test_project/site-cookbooks/_base/_base/files/.keep +0 -0
- data/test_project/site-cookbooks/_base/_base/recipes/default.rb +0 -1
- data/test_project/site-cookbooks/_base/_base/spec/default_spec.rb +0 -1
- data/test_project/site-cookbooks/_base/_base/templates/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/attributes/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/files/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/recipes/default.rb +0 -8
- data/test_project/site-cookbooks/a_test/directory/spec/.keep +0 -0
- data/test_project/site-cookbooks/a_test/directory/spec/default_spec.rb +0 -4
- data/test_project/site-cookbooks/a_test/directory/templates/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/attributes/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/files/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/recipes/default.rb +0 -2
- data/test_project/site-cookbooks/a_test/package/spec/.keep +0 -0
- data/test_project/site-cookbooks/a_test/package/spec/default_spec.rb +0 -4
- data/test_project/site-cookbooks/a_test/package/templates/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/attributes/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/files/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/a_test/service/spec/.keep +0 -0
- data/test_project/site-cookbooks/a_test/service/spec/default_spec.rb +0 -6
- data/test_project/site-cookbooks/a_test/service/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/b_test/git/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/git/spec/default_spec.rb +0 -5
- data/test_project/site-cookbooks/b_test/git/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/b_test/link/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/link/spec/default_spec.rb +0 -5
- data/test_project/site-cookbooks/b_test/link/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/files/remote_file.sh +0 -1
- data/test_project/site-cookbooks/b_test/remote_file/recipes/default.rb +0 -9
- data/test_project/site-cookbooks/b_test/remote_file/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/remote_file/spec/default_spec.rb +0 -7
- data/test_project/site-cookbooks/b_test/remote_file/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/attributes/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/files/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/recipes/default.rb +0 -5
- data/test_project/site-cookbooks/b_test/template/spec/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/spec/default_spec.rb +0 -7
- data/test_project/site-cookbooks/b_test/template/templates/.keep +0 -0
- data/test_project/site-cookbooks/b_test/template/templates/template.erb +0 -2
- data/test_project/site-cookbooks/c_test/execute/attributes/.keep +0 -0
- data/test_project/site-cookbooks/c_test/execute/files/.keep +0 -0
- data/test_project/site-cookbooks/c_test/execute/recipes/default.rb +0 -6
- data/test_project/site-cookbooks/c_test/execute/spec/.keep +0 -0
- data/test_project/site-cookbooks/c_test/execute/spec/default_spec.rb +0 -6
- data/test_project/site-cookbooks/c_test/execute/templates/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/attributes/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/files/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/recipes/default.rb +0 -10
- data/test_project/site-cookbooks/c_test/remote_directory/spec/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/spec/default_spec.rb +0 -20
- data/test_project/site-cookbooks/c_test/remote_directory/templates/.keep +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/templates/remote_dir/a.txt +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/templates/remote_dir/b.txt +0 -0
- data/test_project/site-cookbooks/c_test/remote_directory/templates/remote_dir/c.txt +0 -0
- data/test_project/site-cookbooks/d_spec/air/attributes/.keep +0 -0
- data/test_project/site-cookbooks/d_spec/air/files/.keep +0 -0
- data/test_project/site-cookbooks/d_spec/air/recipes/default.rb +0 -0
- data/test_project/site-cookbooks/d_spec/air/spec/.keep +0 -0
- data/test_project/site-cookbooks/d_spec/air/spec/default_spec.rb +0 -0
- data/test_project/site-cookbooks/d_spec/air/templates/.keep +0 -0
- data/test_project/spec/spec_helper.rb +0 -33
- data/test_project/tmp-nodes/.keep +0 -0
- data/test_project/tmp-nodes/test.json +0 -12
@@ -1,123 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'simple_color'
|
3
|
-
include Rake::DSL if defined? Rake::DSL
|
4
|
-
|
5
|
-
module Itamae
|
6
|
-
module Mitsurin
|
7
|
-
class ServerspecTask
|
8
|
-
|
9
|
-
class << self
|
10
|
-
|
11
|
-
task :spec => 'spec:all'
|
12
|
-
task :default => :spec
|
13
|
-
|
14
|
-
def self.get_roles(node_file)
|
15
|
-
roles = []
|
16
|
-
JSON.parse(File.read(node_file))['run_list'].each do |role|
|
17
|
-
roles << role.gsub(/role\[(.+)\]/, '\1') if /role\[(.+)\]/ === role
|
18
|
-
end
|
19
|
-
roles
|
20
|
-
end
|
21
|
-
|
22
|
-
def self.get_recipes(role)
|
23
|
-
recipes = []
|
24
|
-
JSON.parse(File.read("roles/#{role}.json"))['run_list'].each do |recipe|
|
25
|
-
if /recipe\[(.+)::(.+)\]/ === recipe
|
26
|
-
recipes << {recipe.gsub(/recipe\[(.+)::(.+)\]/, '\1') => recipe.gsub(/recipe\[(.+)::(.+)\]/, '\2')}
|
27
|
-
else
|
28
|
-
recipes << {recipe.gsub(/recipe\[(.+)\]/, '\1') => nil}
|
29
|
-
end
|
30
|
-
end
|
31
|
-
recipes
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.get_node_recipes(node_file)
|
35
|
-
recipes = []
|
36
|
-
JSON.parse(File.read(node_file))['run_list'].each do |recipe|
|
37
|
-
if /recipe\[(.+)::(.+)\]/ === recipe
|
38
|
-
recipes << {recipe.gsub(/recipe\[(.+)::(.+)\]/, '\1') => recipe.gsub(/recipe\[(.+)::(.+)\]/, '\2')}
|
39
|
-
else
|
40
|
-
recipes << {recipe.gsub(/recipe\[(.+)\]/, '\1') => nil} unless /role\[(.+)\]/ === recipe
|
41
|
-
end
|
42
|
-
end
|
43
|
-
recipes
|
44
|
-
end
|
45
|
-
|
46
|
-
color = SimpleColor.new
|
47
|
-
|
48
|
-
namespace :spec do
|
49
|
-
all = []
|
50
|
-
Dir.glob("tmp-nodes/**/*.json").each do |node_file|
|
51
|
-
|
52
|
-
file_name = File.basename(node_file, '.json')
|
53
|
-
node_attr = JSON.parse(File.read(node_file), symbolize_names: true)
|
54
|
-
|
55
|
-
desc "Spec to #{file_name}"
|
56
|
-
task node_attr[:environments][:hostname].split(".")[0] do
|
57
|
-
|
58
|
-
begin
|
59
|
-
recipes = []
|
60
|
-
get_roles(node_file).each do |role|
|
61
|
-
recipes << get_recipes(role)
|
62
|
-
end
|
63
|
-
get_node_recipes(node_file).each do |recipe|
|
64
|
-
recipes << recipe
|
65
|
-
end
|
66
|
-
rescue Exception => e
|
67
|
-
puts e.class.to_s + ", " + e.backtrace[0].to_s
|
68
|
-
puts "nodefile or role error, nodefile:#{node_file} reason:#{e.message}"
|
69
|
-
exit 1
|
70
|
-
else
|
71
|
-
recipes << {'_base' => nil}
|
72
|
-
recipes.flatten!
|
73
|
-
end
|
74
|
-
|
75
|
-
node_name = node_attr[:environments][:hostname]
|
76
|
-
ssh_user = node_attr[:environments][:ssh_user]
|
77
|
-
ssh_password = node_attr[:environments][:ssh_password]
|
78
|
-
sudo_password = node_attr[:environments][:sudo_password]
|
79
|
-
ssh_port = node_attr[:environments][:ssh_port]
|
80
|
-
ssh_key = node_attr[:environments][:ssh_key]
|
81
|
-
|
82
|
-
node_short = node_name.split(".")[0]
|
83
|
-
all << node_short
|
84
|
-
|
85
|
-
desc "Run spec to #{file_name}"
|
86
|
-
ENV['TARGET_HOST'] = node_name
|
87
|
-
ENV['NODE_FILE'] = node_file
|
88
|
-
ENV['SSH_PASSWORD'] = ssh_password
|
89
|
-
ENV['SUDO_PASSWORD'] = sudo_password
|
90
|
-
ENV['SSH_KEY'] = "keys/#{ssh_key}"
|
91
|
-
ENV['SSH_PORT'] = ssh_port
|
92
|
-
ENV['SSH_USER'] = ssh_user
|
93
|
-
|
94
|
-
specs = "bundle exec rspec"
|
95
|
-
|
96
|
-
# recipe load to_spec
|
97
|
-
spec_pattern = []
|
98
|
-
recipes.each do |spec_h|
|
99
|
-
if spec_h["#{spec_h.keys.join}"].nil?
|
100
|
-
spec_pattern <<
|
101
|
-
" #{Dir.glob("site-cookbooks/**/#{spec_h.keys.join}/spec/default_spec.rb").join}"
|
102
|
-
else
|
103
|
-
spec_pattern <<
|
104
|
-
" #{Dir.glob("site-cookbooks/**/#{spec_h.keys.join}/spec/#{spec_h["#{spec_h.keys.join}"]}_spec.rb").join}"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
spec_pattern.sort_by! {|item| File.dirname(item)}
|
108
|
-
specs << spec_pattern.join
|
109
|
-
run_list_noti = []
|
110
|
-
spec_pattern.each {|c_spec| run_list_noti << c_spec.split("/") [2]}
|
111
|
-
color.echos(:red ,%!Run Serverspec to \"#{node_name}\"!)
|
112
|
-
color.echos(:green, %!Run List to \"#{run_list_noti.uniq.join(", ")}\"!)
|
113
|
-
st = system specs
|
114
|
-
exit 1 unless st
|
115
|
-
end
|
116
|
-
task :all => all
|
117
|
-
task :default => :all
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'itamae-mitsurin'
|
2
|
-
require 'itamae-mitsurin/mitsurin'
|
3
|
-
|
4
|
-
module ItamaeMitsurin
|
5
|
-
module Resource
|
6
|
-
class AwsEbsVolume < Base
|
7
|
-
define_attribute :action, default: :create
|
8
|
-
define_attribute :name, type: String, default_name: true
|
9
|
-
define_attribute :availability_zone, type: String
|
10
|
-
define_attribute :device, type: String
|
11
|
-
define_attribute :instance_id, type: String
|
12
|
-
define_attribute :volume_type, type: String
|
13
|
-
define_attribute :size, type: Integer
|
14
|
-
|
15
|
-
def action_create(options)
|
16
|
-
ec2 = ::Aws::EC2::Client.new
|
17
|
-
volumes = ec2.describe_volumes(
|
18
|
-
{
|
19
|
-
filters: [
|
20
|
-
{
|
21
|
-
name: 'tag:Name',
|
22
|
-
values: [ attributes.name ],
|
23
|
-
},
|
24
|
-
],
|
25
|
-
}
|
26
|
-
).volumes
|
27
|
-
|
28
|
-
if volumes.empty?
|
29
|
-
@volume = ec2.create_volume(
|
30
|
-
size: attributes[:size], # attributes.size returns the size of attributes hash
|
31
|
-
availability_zone: attributes.availability_zone,
|
32
|
-
volume_type: attributes.volume_type,
|
33
|
-
)
|
34
|
-
|
35
|
-
ec2.create_tags(
|
36
|
-
{
|
37
|
-
resources: [ @volume.volume_id ],
|
38
|
-
tags: [
|
39
|
-
{
|
40
|
-
key: 'Name',
|
41
|
-
value: attributes.name,
|
42
|
-
},
|
43
|
-
],
|
44
|
-
}
|
45
|
-
)
|
46
|
-
|
47
|
-
updated!
|
48
|
-
sleep(3)
|
49
|
-
else
|
50
|
-
@volume = volumes[0]
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
def action_attach(options)
|
56
|
-
ec2 = ::Aws::EC2::Client.new
|
57
|
-
volumes = ec2.describe_volumes(
|
58
|
-
{
|
59
|
-
filters: [
|
60
|
-
{
|
61
|
-
name: 'tag:Name',
|
62
|
-
values: [ attributes.name ],
|
63
|
-
},
|
64
|
-
],
|
65
|
-
}
|
66
|
-
).volumes
|
67
|
-
|
68
|
-
unless volumes.empty?
|
69
|
-
@volume = ec2.attach_volume({
|
70
|
-
volume_id: @volume.volume_id,
|
71
|
-
instance_id: attributes.instance_id,
|
72
|
-
device: attributes.device
|
73
|
-
})
|
74
|
-
|
75
|
-
updated!
|
76
|
-
else
|
77
|
-
@volume = volumes[0]
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
@@ -1,374 +0,0 @@
|
|
1
|
-
require 'itamae-mitsurin'
|
2
|
-
require 'shellwords'
|
3
|
-
require 'hashie'
|
4
|
-
|
5
|
-
module ItamaeMitsurin
|
6
|
-
module Resource
|
7
|
-
class Base
|
8
|
-
class EvalContext
|
9
|
-
attr_reader :attributes
|
10
|
-
attr_reader :notifications
|
11
|
-
attr_reader :subscriptions
|
12
|
-
attr_reader :verify_commands
|
13
|
-
attr_reader :only_if_command
|
14
|
-
attr_reader :not_if_command
|
15
|
-
|
16
|
-
def initialize(resource)
|
17
|
-
@resource = resource
|
18
|
-
|
19
|
-
@attributes = Hashie::Mash.new
|
20
|
-
@notifications = []
|
21
|
-
@subscriptions = []
|
22
|
-
@verify_commands = []
|
23
|
-
end
|
24
|
-
|
25
|
-
def respond_to_missing?(method, include_private = false)
|
26
|
-
@resource.class.defined_attributes.has_key?(method) || super
|
27
|
-
end
|
28
|
-
|
29
|
-
def method_missing(method, *args, &block)
|
30
|
-
if @resource.class.defined_attributes[method]
|
31
|
-
if args.size == 1
|
32
|
-
return @attributes[method] = args.first
|
33
|
-
elsif args.size == 0 && block_given?
|
34
|
-
return @attributes[method] = block
|
35
|
-
elsif args.size == 0
|
36
|
-
return @attributes[method]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
super
|
41
|
-
end
|
42
|
-
|
43
|
-
def notifies(action, resource_desc, timing = :delay)
|
44
|
-
@notifications << Notification.create(@resource, action, resource_desc, timing)
|
45
|
-
end
|
46
|
-
|
47
|
-
def subscribes(action, resource_desc, timing = :delay)
|
48
|
-
@subscriptions << Subscription.create(@resource, action, resource_desc, timing)
|
49
|
-
end
|
50
|
-
|
51
|
-
def only_if(command)
|
52
|
-
@only_if_command = command
|
53
|
-
end
|
54
|
-
|
55
|
-
def not_if(command)
|
56
|
-
@not_if_command = command
|
57
|
-
end
|
58
|
-
|
59
|
-
def node
|
60
|
-
@resource.recipe.runner.node
|
61
|
-
end
|
62
|
-
|
63
|
-
def run_command(*args)
|
64
|
-
@resource.recipe.runner.backend.run_command(*args)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Experimental
|
68
|
-
def verify(command)
|
69
|
-
@verify_commands << command
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
@defined_attributes ||= {}
|
74
|
-
|
75
|
-
class << self
|
76
|
-
attr_reader :defined_attributes
|
77
|
-
attr_reader :supported_oses
|
78
|
-
|
79
|
-
def inherited(subclass)
|
80
|
-
subclass.instance_variable_set(
|
81
|
-
:@defined_attributes,
|
82
|
-
self.defined_attributes.dup
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
def define_attribute(name, options)
|
87
|
-
current = @defined_attributes[name.to_sym] || {}
|
88
|
-
@defined_attributes[name.to_sym] = current.merge(options)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
define_attribute :action, type: [Symbol, Array], required: true
|
93
|
-
define_attribute :user, type: String
|
94
|
-
define_attribute :cwd, type: String
|
95
|
-
|
96
|
-
attr_reader :recipe
|
97
|
-
attr_reader :resource_name
|
98
|
-
attr_reader :attributes
|
99
|
-
attr_reader :current_attributes
|
100
|
-
attr_reader :subscriptions
|
101
|
-
attr_reader :notifications
|
102
|
-
attr_reader :updated
|
103
|
-
|
104
|
-
def initialize(recipe, resource_name, &block)
|
105
|
-
clear_current_attributes
|
106
|
-
@recipe = recipe
|
107
|
-
@resource_name = resource_name
|
108
|
-
@updated = false
|
109
|
-
|
110
|
-
EvalContext.new(self).tap do |context|
|
111
|
-
context.instance_eval(&block) if block
|
112
|
-
@attributes = context.attributes
|
113
|
-
@notifications = context.notifications
|
114
|
-
@subscriptions = context.subscriptions
|
115
|
-
@only_if_command = context.only_if_command
|
116
|
-
@not_if_command = context.not_if_command
|
117
|
-
@verify_commands = context.verify_commands
|
118
|
-
end
|
119
|
-
|
120
|
-
process_attributes
|
121
|
-
end
|
122
|
-
|
123
|
-
def run(specific_action = nil)
|
124
|
-
runner.handler.event(:resource, resource_type: resource_type, resource_name: resource_name) do
|
125
|
-
ItamaeMitsurin.logger.debug "#{resource_type}[#{resource_name}]"
|
126
|
-
|
127
|
-
ItamaeMitsurin.logger.with_indent_if(ItamaeMitsurin.logger.debug?) do
|
128
|
-
if do_not_run_because_of_only_if?
|
129
|
-
ItamaeMitsurin.logger.debug "#{resource_type}[#{resource_name}] Execution skipped because of only_if attribute"
|
130
|
-
return
|
131
|
-
elsif do_not_run_because_of_not_if?
|
132
|
-
ItamaeMitsurin.logger.debug "#{resource_type}[#{resource_name}] Execution skipped because of not_if attribute"
|
133
|
-
return
|
134
|
-
end
|
135
|
-
|
136
|
-
[specific_action || attributes.action].flatten.each do |action|
|
137
|
-
run_action(action)
|
138
|
-
end
|
139
|
-
|
140
|
-
verify unless runner.dry_run?
|
141
|
-
if updated?
|
142
|
-
notify
|
143
|
-
runner.handler.event(:resource_updated)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
@updated = false
|
148
|
-
end
|
149
|
-
rescue Backend::CommandExecutionError
|
150
|
-
ItamaeMitsurin.logger.error "#{resource_type}[#{resource_name}] Failed."
|
151
|
-
exit 2
|
152
|
-
end
|
153
|
-
|
154
|
-
def action_nothing
|
155
|
-
# do nothing
|
156
|
-
end
|
157
|
-
|
158
|
-
def resource_type
|
159
|
-
self.class.name.split("::").last.scan(/[A-Z][^A-Z]+/).map(&:downcase).join('_')
|
160
|
-
end
|
161
|
-
|
162
|
-
private
|
163
|
-
|
164
|
-
alias_method :current, :current_attributes
|
165
|
-
|
166
|
-
def run_action(action)
|
167
|
-
runner.handler.event(:action, action: action) do
|
168
|
-
original_attributes = @attributes # preserve and restore later
|
169
|
-
@current_action = action
|
170
|
-
|
171
|
-
clear_current_attributes
|
172
|
-
|
173
|
-
ItamaeMitsurin.logger.debug "#{resource_type}[#{resource_name}] action: #{action}"
|
174
|
-
|
175
|
-
return if action == :nothing
|
176
|
-
|
177
|
-
ItamaeMitsurin.logger.with_indent_if(ItamaeMitsurin.logger.debug?) do
|
178
|
-
ItamaeMitsurin.logger.debug "(in pre_action)"
|
179
|
-
pre_action
|
180
|
-
|
181
|
-
ItamaeMitsurin.logger.debug "(in set_current_attributes)"
|
182
|
-
set_current_attributes
|
183
|
-
|
184
|
-
ItamaeMitsurin.logger.debug "(in show_differences)"
|
185
|
-
show_differences
|
186
|
-
|
187
|
-
method_name = "action_#{action}"
|
188
|
-
if runner.dry_run?
|
189
|
-
unless respond_to?(method_name)
|
190
|
-
ItamaeMitsurin.logger.error "action #{action.inspect} is unavailable"
|
191
|
-
end
|
192
|
-
else
|
193
|
-
args = [method_name]
|
194
|
-
if method(method_name).arity == 1
|
195
|
-
# for plugin compatibility
|
196
|
-
args << runner.options
|
197
|
-
end
|
198
|
-
|
199
|
-
public_send(*args)
|
200
|
-
end
|
201
|
-
|
202
|
-
if different?
|
203
|
-
updated!
|
204
|
-
runner.handler.event(:attribute_changed, from: @current_attributes, to: @attributes)
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
@current_action = nil
|
209
|
-
@attributes = original_attributes
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
def clear_current_attributes
|
214
|
-
@current_attributes = Hashie::Mash.new
|
215
|
-
end
|
216
|
-
|
217
|
-
def pre_action
|
218
|
-
# do nothing
|
219
|
-
end
|
220
|
-
|
221
|
-
def set_current_attributes
|
222
|
-
# do nothing
|
223
|
-
end
|
224
|
-
|
225
|
-
def different?
|
226
|
-
@current_attributes.each_pair.any? do |key, current_value|
|
227
|
-
!current_value.nil? &&
|
228
|
-
!@attributes[key].nil? &&
|
229
|
-
current_value != @attributes[key]
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
def show_differences
|
234
|
-
@current_attributes.each_pair do |key, current_value|
|
235
|
-
value = @attributes[key]
|
236
|
-
if current_value.nil? && value.nil?
|
237
|
-
# ignore
|
238
|
-
elsif current_value.nil? && !value.nil?
|
239
|
-
ItamaeMitsurin.logger.color :green do
|
240
|
-
ItamaeMitsurin.logger.info "#{resource_type}[#{resource_name}] #{key} will be '#{value}'"
|
241
|
-
end
|
242
|
-
elsif current_value == value || value.nil?
|
243
|
-
ItamaeMitsurin.logger.debug "#{resource_type}[#{resource_name}] #{key} will not change (current value is '#{current_value}')"
|
244
|
-
else
|
245
|
-
ItamaeMitsurin.logger.color :green do
|
246
|
-
ItamaeMitsurin.logger.info "#{resource_type}[#{resource_name}] #{key} will change from '#{current_value}' to '#{value}'"
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def process_attributes
|
253
|
-
self.class.defined_attributes.each_pair do |key, details|
|
254
|
-
@attributes[key] ||= @resource_name if details[:default_name]
|
255
|
-
@attributes[key] = details[:default] if details.has_key?(:default) && !@attributes.has_key?(key)
|
256
|
-
|
257
|
-
if details[:required] && !@attributes[key]
|
258
|
-
raise Resource::AttributeMissingError, "'#{key}' attribute is required but it is not set."
|
259
|
-
end
|
260
|
-
|
261
|
-
if @attributes[key] && details[:type]
|
262
|
-
valid_type = [details[:type]].flatten.any? do |type|
|
263
|
-
@attributes[key].is_a?(type)
|
264
|
-
end
|
265
|
-
unless valid_type
|
266
|
-
raise Resource::InvalidTypeError, "#{key} attribute should be #{details[:type]}."
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
def do_not_run_because_of_only_if?
|
273
|
-
@only_if_command &&
|
274
|
-
run_command(@only_if_command, error: false).exit_status != 0
|
275
|
-
end
|
276
|
-
|
277
|
-
def do_not_run_because_of_not_if?
|
278
|
-
@not_if_command &&
|
279
|
-
run_command(@not_if_command, error: false).exit_status == 0
|
280
|
-
end
|
281
|
-
|
282
|
-
def backend
|
283
|
-
runner.backend
|
284
|
-
end
|
285
|
-
|
286
|
-
def runner
|
287
|
-
recipe.runner
|
288
|
-
end
|
289
|
-
|
290
|
-
def node
|
291
|
-
runner.node
|
292
|
-
end
|
293
|
-
|
294
|
-
def run_command(*args)
|
295
|
-
unless args.last.is_a?(Hash)
|
296
|
-
args << {}
|
297
|
-
end
|
298
|
-
|
299
|
-
args.last[:user] ||= attributes.user
|
300
|
-
args.last[:cwd] ||= attributes.cwd
|
301
|
-
|
302
|
-
backend.run_command(*args)
|
303
|
-
end
|
304
|
-
|
305
|
-
def check_command(*args)
|
306
|
-
unless args.last.is_a?(Hash)
|
307
|
-
args << {}
|
308
|
-
end
|
309
|
-
|
310
|
-
args.last[:error] = false
|
311
|
-
|
312
|
-
run_command(*args).exit_status == 0
|
313
|
-
end
|
314
|
-
|
315
|
-
def run_specinfra(type, *args)
|
316
|
-
command = backend.get_command(type, *args)
|
317
|
-
|
318
|
-
if type.to_s.start_with?("check_")
|
319
|
-
check_command(command)
|
320
|
-
else
|
321
|
-
run_command(command)
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
def shell_escape(str)
|
326
|
-
str.shellescape
|
327
|
-
end
|
328
|
-
|
329
|
-
def updated!
|
330
|
-
ItamaeMitsurin.logger.debug "This resource is updated."
|
331
|
-
@updated = true
|
332
|
-
end
|
333
|
-
|
334
|
-
def updated?
|
335
|
-
@updated
|
336
|
-
end
|
337
|
-
|
338
|
-
def notify
|
339
|
-
(notifications + recipe.children.subscribing(self)).each do |notification|
|
340
|
-
message = "Notifying #{notification.action} to #{notification.action_resource.resource_type} resource '#{notification.action_resource.resource_name}'"
|
341
|
-
|
342
|
-
if notification.delayed?
|
343
|
-
message << " (delayed)"
|
344
|
-
elsif notification.immediately?
|
345
|
-
message << " (immediately)"
|
346
|
-
end
|
347
|
-
|
348
|
-
ItamaeMitsurin.logger.info message
|
349
|
-
|
350
|
-
if notification.instance_of?(Subscription)
|
351
|
-
ItamaeMitsurin.logger.info "(because it subscribes this resource)"
|
352
|
-
end
|
353
|
-
|
354
|
-
if notification.delayed?
|
355
|
-
@recipe.delayed_notifications << notification
|
356
|
-
elsif notification.immediately?
|
357
|
-
notification.run
|
358
|
-
end
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
def verify
|
363
|
-
return if @verify_commands.empty?
|
364
|
-
|
365
|
-
ItamaeMitsurin.logger.info "Verifying..."
|
366
|
-
ItamaeMitsurin.logger.with_indent do
|
367
|
-
@verify_commands.each do |command|
|
368
|
-
run_command(command)
|
369
|
-
end
|
370
|
-
end
|
371
|
-
end
|
372
|
-
end
|
373
|
-
end
|
374
|
-
end
|