corl 0.5.15 → 0.5.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c360e505e5eaa8bdea103dad27a7868f06655153
4
- data.tar.gz: 8cf2016ccc74e060bfa91372e7b54481b1a06a83
3
+ metadata.gz: 6525066ff89087597683642d763aaf33dc8d4f30
4
+ data.tar.gz: 4d6ffa51014c3f8316a118ef6f5b8476da2e0b0b
5
5
  SHA512:
6
- metadata.gz: f16e3bfa746c95710bd6e6b5aa0374e0de28ff8fe98374d76f237b74dbc9fdc341cc7880fbf5e4a5504122f739a7b337b19224340377e5f25d130acb01606ee3
7
- data.tar.gz: f4e9f8fe0ca6e9478ae96018b346fcbb5ae509d10de97146cae1520b18787ec16ec673fa0f4ab46de9c795b0b3354abd4fff4a4ce36dc719b040e938382b6214
6
+ metadata.gz: 668c3569ee4d16da744d12da994f72565fa0b01b90c254359b5315fe28c7d5d313d351b8d3e061d45b5cfd3e316aed13522da50812aab605ba2774c6de72dee2
7
+ data.tar.gz: b4b76ae9c30d0993a305ce6f872159861bdbd898763f66bb614a20d16def26556e1feb717050834fa13bf63d4cc01f080794f6c3a45acc53b27aafc213ccf636
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.15
1
+ 0.5.16
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: corl 0.5.15 ruby lib
5
+ # stub: corl 0.5.16 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "corl"
9
- s.version = "0.5.15"
9
+ s.version = "0.5.16"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Adrian Webb"]
14
- s.date = "2015-02-19"
14
+ s.date = "2015-02-26"
15
15
  s.description = "Framework that provides a simple foundation for growing organically in the cloud"
16
16
  s.email = "adrian.webb@coralnexus.com"
17
17
  s.executables = ["corl"]
@@ -78,8 +78,10 @@ Gem::Specification.new do |s|
78
78
  "lib/core/mod/fog_rackspace_server.rb",
79
79
  "lib/core/mod/hiera_backend.rb",
80
80
  "lib/core/plugin/agent.rb",
81
+ "lib/core/plugin/agent_wrapper.rb",
81
82
  "lib/core/plugin/builder.rb",
82
83
  "lib/core/plugin/cloud_action.rb",
84
+ "lib/core/plugin/cloud_action_wrapper.rb",
83
85
  "lib/core/plugin/configuration.rb",
84
86
  "lib/core/plugin/fog_machine.rb",
85
87
  "lib/core/plugin/fog_node.rb",
@@ -106,6 +108,7 @@ Gem::Specification.new do |s|
106
108
  "lib/facter/custom_facts.rb",
107
109
  "lib/facter/vagrant_exists.rb",
108
110
  "lib/hiera/corl_logger.rb",
111
+ "lib/nucleon/action/agent/manager.rb",
109
112
  "lib/nucleon/action/network/config.rb",
110
113
  "lib/nucleon/action/network/create.rb",
111
114
  "lib/nucleon/action/network/images.rb",
@@ -117,11 +120,15 @@ Gem::Specification.new do |s|
117
120
  "lib/nucleon/action/network/vagrantfile.rb",
118
121
  "lib/nucleon/action/node/IP.rb",
119
122
  "lib/nucleon/action/node/SSH.rb",
123
+ "lib/nucleon/action/node/agent/status.rb",
124
+ "lib/nucleon/action/node/agent/stop.rb",
125
+ "lib/nucleon/action/node/agents.rb",
120
126
  "lib/nucleon/action/node/authorize.rb",
121
127
  "lib/nucleon/action/node/bootstrap.rb",
122
128
  "lib/nucleon/action/node/build.rb",
123
129
  "lib/nucleon/action/node/cache.rb",
124
130
  "lib/nucleon/action/node/destroy.rb",
131
+ "lib/nucleon/action/node/download.rb",
125
132
  "lib/nucleon/action/node/exec.rb",
126
133
  "lib/nucleon/action/node/fact.rb",
127
134
  "lib/nucleon/action/node/facts.rb",
@@ -139,6 +146,7 @@ Gem::Specification.new do |s|
139
146
  "lib/nucleon/action/node/start.rb",
140
147
  "lib/nucleon/action/node/status.rb",
141
148
  "lib/nucleon/action/node/stop.rb",
149
+ "lib/nucleon/action/node/upload.rb",
142
150
  "lib/nucleon/action/plugin/create.rb",
143
151
  "lib/nucleon/action/plugin/list.rb",
144
152
  "lib/nucleon/action/plugins.rb",
@@ -59,12 +59,11 @@ class Agent < Nucleon.plugin_class(:nucleon, :cloud_action)
59
59
  def execute(use_network = true, &block)
60
60
  super do |node|
61
61
  ensure_network do
62
- add_agent(node)
63
-
64
62
  trap(:INT) do
65
63
  safe_exit
66
64
  end
67
65
 
66
+ add_agent(node)
68
67
  block.call(node)
69
68
  remove_agent(node) if myself.status == code.success
70
69
  end
@@ -75,12 +74,19 @@ class Agent < Nucleon.plugin_class(:nucleon, :cloud_action)
75
74
  # Utilities
76
75
 
77
76
  def add_agent(node)
78
- settings[:pid] = Process.pid
77
+ args = []
78
+
79
+ ARGV.each do |arg|
80
+ args << ( arg =~ /^\-/ ? arg : "'#{arg}'" )
81
+ end
79
82
 
80
- stored_config = Util::Data.clean(settings.export)
81
- stored_config = Util::Data.rm_keys(stored_config, [ :node_provider, :nodes, :color, :version ])
83
+ agent_config = Config.new({
84
+ :pid => Process.pid,
85
+ :args => args.join(' ')
86
+ }).import(Util::Data.clean(settings.export))
82
87
 
83
- node.add_agent(plugin_provider, stored_config)
88
+ agent_config = Util::Data.rm_keys(agent_config.export, [ :node_provider, :nodes, :color, :version ])
89
+ node.add_agent(plugin_provider, agent_config)
84
90
  end
85
91
  protected :add_agent
86
92
 
@@ -0,0 +1,26 @@
1
+
2
+ nucleon_require(File.dirname(__FILE__), :agent)
3
+
4
+ #---
5
+
6
+ module Nucleon
7
+ module Plugin
8
+ class AgentWrapper < Nucleon.plugin_class(:nucleon, :agent)
9
+
10
+ #-----------------------------------------------------------------------------
11
+ # Operations
12
+
13
+ def execute(use_network = true, &block)
14
+ super do |node|
15
+ bin_dir = File.join(network.directory, 'bin')
16
+ bin_dir = ( File.directory?(bin_dir) ? bin_dir : network.directory )
17
+
18
+ Dir.chdir(bin_dir) do
19
+ result = node.exec({ :commands => [ block.call(node) ] }).first
20
+ myself.status = result.status
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+
2
+ nucleon_require(File.dirname(__FILE__), :cloud_action)
3
+
4
+ #---
5
+
6
+ module Nucleon
7
+ module Plugin
8
+ class CloudActionWrapper < Nucleon.plugin_class(:nucleon, :cloud_action)
9
+
10
+ #-----------------------------------------------------------------------------
11
+ # Operations
12
+
13
+ def execute(use_network = true, &block)
14
+ super do |node|
15
+ bin_dir = File.join(network.directory, 'bin')
16
+ bin_dir = ( File.directory?(bin_dir) ? bin_dir : network.directory )
17
+
18
+ Dir.chdir(bin_dir) do
19
+ result = node.exec({ :commands => [ block.call(node) ] }).first
20
+ myself.status = result.status
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -176,6 +176,7 @@ class Configuration < Nucleon.plugin_class(:nucleon, :base)
176
176
  config.import(properties, method_config)
177
177
  end
178
178
  end
179
+ success = cache.load if success
179
180
  else
180
181
  logger.warn("Loading of source configuration failed")
181
182
  end
@@ -195,6 +196,7 @@ class Configuration < Nucleon.plugin_class(:nucleon, :base)
195
196
 
196
197
  success = yield(method_config) if block_given?
197
198
  end
199
+ success = cache.save if success
198
200
  else
199
201
  logger.warn("Can not save source configuration")
200
202
  end
@@ -377,31 +377,63 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
377
377
  #---
378
378
 
379
379
  def agents
380
- hash(myself[:agents])
380
+ if local?
381
+ agents = cache_setting([ :agents ], {}, :hash)
382
+ else
383
+ agents = remote_cache_setting([ :agents ], {}, :hash)
384
+ end
385
+ Util::Data.symbol_map(agents)
381
386
  end
382
387
 
383
388
  def agent(provider)
384
- search([ :agents, provider ], {}, :hash)
389
+ if local?
390
+ agent = cache_setting([ :agents, provider ], {}, :hash)
391
+ else
392
+ agent = remote_cache_setting([ :agents, provider ], {}, :hash)
393
+ end
394
+ Util::Data.symbol_map(agent)
385
395
  end
386
396
 
387
- def add_agent(provider, settings)
388
- set_setting([ :agents, provider ], Config.new(settings).export)
397
+ def agent_running(provider)
398
+ if local?
399
+ agent_options = agent(provider)
400
+ return false unless agent_options.has_key?(:pid)
389
401
 
390
- save({
391
- :message => "Agent #{provider} starting up on #{plugin_provider} #{plugin_name}",
392
- :remote => extension_set(:add_agent_remote, :edit),
393
- :push => true
394
- })
402
+ Process.kill(0, agent_options[:pid].to_i)
403
+ true
404
+ else
405
+ result = run.node_agents
406
+
407
+ if result.status == code.success
408
+ result_data = Util::Data.parse_json(result.errors)
409
+ running = Util::Data.value(result_data[provider.to_s]["running"], false)
410
+ end
411
+ return running
412
+ end
413
+ rescue Errno::ESRCH # No process (local)
414
+ false
415
+ rescue Errno::EPERM # The process exists, but no permission to send signal to it (local)
416
+ true
395
417
  end
396
418
 
397
- def remove_agent(provider)
398
- delete_setting([ :agents, provider ])
419
+ def add_agent(provider, options)
420
+ if local?
421
+ set_cache_setting([ :agents, provider ], Config.new(options).export)
422
+ else
423
+ remote_set_cache_setting([ :agents, provider ], Config.new(options).export)
424
+ end
425
+ end
399
426
 
400
- save({
401
- :message => "Agent #{provider} shutting down on #{plugin_provider} #{plugin_name}",
402
- :remote => extension_set(:remove_agent_remote, :edit),
403
- :push => true
404
- })
427
+ def remove_agent(provider)
428
+ if local?
429
+ agent_options = agent(provider)
430
+ if agent_options && agent_running(provider)
431
+ Process.kill("SIGINT", agent_options[:pid].to_i)
432
+ end
433
+ delete_cache_setting([ :agents, provider ])
434
+ else
435
+ remote_delete_cache_setting([ :agents, provider ])
436
+ end
405
437
  end
406
438
 
407
439
  #-----------------------------------------------------------------------------
@@ -715,6 +747,7 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
715
747
  config = Config.ensure(options)
716
748
  hook_config = Config.new({ :local_path => local_path, :remote_path => remote_path, :config => config }, {}, true, false)
717
749
  quiet = config.get(:quiet, false)
750
+ progress = config.get(:progress, true)
718
751
 
719
752
  if extension_check(:download, hook_config)
720
753
  logger.info("Downloading from #{plugin_name}")
@@ -725,7 +758,7 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
725
758
  active_machine = local? ? local_machine : machine
726
759
 
727
760
  success = active_machine.download(remote_path, local_path, config.export) do |name, received, total|
728
- info("#{name}: Sent #{received} of #{total}", { :i18n => false }) unless quiet
761
+ info("#{name}: Sent #{received} of #{total}", { :i18n => false }) if progress && ! quiet
729
762
  yield(:progress, { :name => name, :received => received, :total => total })
730
763
  end
731
764
 
@@ -754,6 +787,7 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
754
787
  config = Config.ensure(options)
755
788
  hook_config = Config.new({ :local_path => local_path, :remote_path => remote_path, :config => config }, {}, true, false)
756
789
  quiet = config.get(:quiet, false)
790
+ progress = config.get(:progress, true)
757
791
 
758
792
  if extension_check(:upload, hook_config)
759
793
  logger.info("Uploading to #{plugin_name}")
@@ -764,7 +798,7 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
764
798
  active_machine = local? ? local_machine : machine
765
799
 
766
800
  success = active_machine.upload(local_path, remote_path, config.export) do |name, sent, total|
767
- info("#{name}: Sent #{sent} of #{total}", { :i18n => false }) unless quiet
801
+ info("#{name}: Sent #{sent} of #{total}", { :i18n => false }) if progress && ! quiet
768
802
  yield(:progress, { :name => name, :sent => sent, :total => total })
769
803
  end
770
804
 
@@ -788,7 +822,7 @@ class Node < Nucleon.plugin_class(:nucleon, :base)
788
822
 
789
823
  def send_files(local_path, remote_path, files = nil, permission = '0644', options = {}, &code)
790
824
  local_path = File.expand_path(local_path)
791
- return false unless File.directory?(local_path)
825
+ return false unless File.directory?(local_path) || File.exists?(local_path)
792
826
 
793
827
  success = true
794
828
 
@@ -42,59 +42,61 @@ vagrant_exists = defined?(Vagrant) == 'constant' && Vagrant.class == Module
42
42
  #
43
43
  # For agent options processed here, see lib/core/plugin/agent.rb
44
44
  #
45
- action_start_index = vagrant_exists ? 1 : 0
46
-
47
- if ARGV[action_start_index].to_sym == :agent
48
- remote_exec = false
49
-
50
- log = true
51
- truncate_log = true
52
-
53
- log_file = nil
54
- agent_provider = []
55
- process_log_file_value = false
56
-
57
- first_option_found = false
58
-
59
- # Argument processing
60
- ARGV[(action_start_index + 1)..-1].each do |arg|
61
- first_option_found = true if arg[0] == '-'
62
-
63
- if arg =~ /^\-\-nodes\=?/
64
- remote_exec = true
65
- elsif arg == "--no-log"
66
- log = false
67
- elsif arg == "--no-truncate_log"
68
- truncate_log = false
69
- elsif arg =~ /^\-\-log_file(?=\=(.*))?/
70
- if $1
71
- log_file = $1
72
- else
73
- process_log_file_value = true
45
+ unless vagrant_exists
46
+ action_start_index = 0
47
+
48
+ if ARGV[action_start_index].to_sym == :agent
49
+ remote_exec = false
50
+
51
+ log = true
52
+ truncate_log = true
53
+
54
+ log_file = nil
55
+ agent_provider = []
56
+ process_log_file_value = false
57
+
58
+ first_option_found = false
59
+
60
+ # Argument processing
61
+ ARGV[(action_start_index + 1)..-1].each do |arg|
62
+ first_option_found = true if arg[0] == '-'
63
+
64
+ if arg =~ /^\-\-nodes\=?/
65
+ remote_exec = true
66
+ elsif arg == "--no-log"
67
+ log = false
68
+ elsif arg == "--no-truncate_log"
69
+ truncate_log = false
70
+ elsif arg =~ /^\-\-log_file(?=\=(.*))?/
71
+ if $1
72
+ log_file = $1
73
+ else
74
+ process_log_file_value = true
75
+ end
76
+ elsif process_log_file_value
77
+ log_file = arg
78
+ process_log_file_value = false
79
+ elsif ! first_option_found
80
+ agent_provider << arg
74
81
  end
75
- elsif process_log_file_value
76
- log_file = arg
77
- process_log_file_value = false
78
- elsif ! first_option_found
79
- agent_provider << arg
80
82
  end
81
- end
82
83
 
83
- # TODO: Need better way to share with base agent default log file. (mixin?)
84
- log_file = "/var/log/corl/agent_#{agent_provider.join('_')}.log" unless log_file
84
+ # TODO: Need better way to share with base agent default log file. (mixin?)
85
+ log_file = "/var/log/corl/agent_#{agent_provider.join('_')}.log" unless log_file
85
86
 
86
- unless remote_exec || vagrant_exists
87
- # Daemonize process
88
- Process.daemon
87
+ unless remote_exec
88
+ # Daemonize process
89
+ Process.daemon
89
90
 
90
- # Log all output, or not
91
- if log
92
- FileUtils.mkdir_p('/var/log/corl')
93
- File.write(log_file, '') if truncate_log
91
+ # Log all output, or not
92
+ if log
93
+ FileUtils.mkdir_p('/var/log/corl')
94
+ File.write(log_file, '') if truncate_log
94
95
 
95
- $stderr.reopen(log_file, 'a')
96
- $stdout.reopen($stderr)
97
- $stdout.sync = $stderr.sync = true
96
+ $stderr.reopen(log_file, 'a')
97
+ $stdout.reopen($stderr)
98
+ $stdout.sync = $stderr.sync = true
99
+ end
98
100
  end
99
101
  end
100
102
  end
@@ -0,0 +1,75 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Agent
5
+ class Manager < Nucleon.plugin_class(:nucleon, :agent)
6
+
7
+ #-----------------------------------------------------------------------------
8
+ # Info
9
+
10
+ def self.describe
11
+ super(nil, :manager, 1100)
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Settings
16
+
17
+ def configure
18
+ super do
19
+ codes :network_failure
20
+
21
+ register_int :sleep_interval, 15
22
+ register_int :network_retries, 3
23
+ register_int :agent_restart_retries, 2
24
+ end
25
+ end
26
+
27
+ #---
28
+
29
+ def arguments
30
+ [ :sleep_interval ]
31
+ end
32
+
33
+ #-----------------------------------------------------------------------------
34
+ # Operations
35
+
36
+ def execute
37
+ super do |node|
38
+ ensure_node(node) do
39
+ network_retry = 0
40
+ agent_restart_retry = {}
41
+
42
+ while status == code.success
43
+ if network.load({ :remote => settings[:net_remote], :pull => true })
44
+ network_retry = 0
45
+
46
+ node.agents.each do |provider, agent_options|
47
+ agent_restart_retry[provider] = 0 unless agent_restart_retry.has_key?(provider)
48
+
49
+ unless provider == :agent_manager || node.agent_running(provider)
50
+ if agent_restart_retry[provider] < settings[:agent_restart_retries]
51
+ command = "corl #{agent_options[:args]} --log_level=warn"
52
+ result = node.exec({ :commands => [ command ] }).first
53
+
54
+ if result.status == code.success
55
+ agent_restart_retry[provider] = 0
56
+ else
57
+ agent_restart_retry[provider] += 1
58
+ end
59
+ end
60
+ end
61
+ end
62
+ elsif network_retry < settings[:network_retries]
63
+ network_retry += 1
64
+ else
65
+ myself.status = code.network_failure
66
+ end
67
+ sleep settings[:sleep_interval]
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,53 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Node
5
+ module Agent
6
+ class Status < Nucleon.plugin_class(:nucleon, :cloud_action)
7
+
8
+ #-----------------------------------------------------------------------------
9
+ # Info
10
+
11
+ def self.describe
12
+ super([ :node, :agent ], :status, 650)
13
+ end
14
+
15
+ #-----------------------------------------------------------------------------
16
+ # Settings
17
+
18
+ def configure
19
+ super do
20
+ register_array :provider, nil
21
+ register_translator :format, :json
22
+ end
23
+ end
24
+
25
+ #---
26
+
27
+ def arguments
28
+ [ :provider ]
29
+ end
30
+
31
+ #-----------------------------------------------------------------------------
32
+ # Operations
33
+
34
+ def execute
35
+ super do |node|
36
+ ensure_node(node) do
37
+ translator = CORL.translator({}, settings[:format])
38
+
39
+ agent_provider = "agent_#{settings[:provider].join('_')}"
40
+ agent_record = node.agent(agent_provider)
41
+
42
+ agent_record[:running] = node.agent_running(agent_provider) unless agent_record.empty?
43
+
44
+ myself.result = agent_record
45
+ $stderr.puts translator.generate(result) unless result.empty?
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Node
5
+ module Agent
6
+ class Stop < Nucleon.plugin_class(:nucleon, :cloud_action)
7
+
8
+ #-----------------------------------------------------------------------------
9
+ # Info
10
+
11
+ def self.describe
12
+ super([ :node, :agent ], :stop, 640)
13
+ end
14
+
15
+ #-----------------------------------------------------------------------------
16
+ # Settings
17
+
18
+ def configure
19
+ super do
20
+ register_array :provider, nil
21
+ end
22
+ end
23
+
24
+ #---
25
+
26
+ def arguments
27
+ [ :provider ]
28
+ end
29
+
30
+ #-----------------------------------------------------------------------------
31
+ # Operations
32
+
33
+ def execute
34
+ super do |node|
35
+ ensure_node(node) do
36
+ node.remove_agent("agent_#{settings[:provider].join('_')}")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Node
5
+ class Agents < Nucleon.plugin_class(:nucleon, :cloud_action)
6
+
7
+ #-----------------------------------------------------------------------------
8
+ # Info
9
+
10
+ def self.describe
11
+ super(:node, :agents, 800)
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Settings
16
+
17
+ def configure
18
+ super do
19
+ register_translator :format, :json
20
+ end
21
+ end
22
+
23
+ #-----------------------------------------------------------------------------
24
+ # Operations
25
+
26
+ def execute
27
+ super do |node|
28
+ ensure_node(node) do
29
+ translator = CORL.translator({}, settings[:format])
30
+ agent_records = node.agents
31
+
32
+ agent_records.each do |provider, agent_options|
33
+ agent_records[provider][:running] = node.agent_running(provider)
34
+ end
35
+
36
+ myself.result = agent_records
37
+ $stderr.puts translator.generate(result) unless result.empty?
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,82 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Node
5
+ class Download < Nucleon.plugin_class(:nucleon, :cloud_action)
6
+
7
+ #-----------------------------------------------------------------------------
8
+ # Info
9
+
10
+ def self.describe
11
+ super(:node, :download, 500)
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Settings
16
+
17
+ def configure
18
+ super do
19
+ register_str :remote_path, nil
20
+ register_str :local_path, nil
21
+
22
+ register_bool :progress, true
23
+
24
+ register_array :download_nodes, nil do |values|
25
+ if values.nil?
26
+ warn('download_nodes_empty')
27
+ next false
28
+ end
29
+
30
+ node_plugins = CORL.loaded_plugins(:CORL, :node)
31
+ success = true
32
+
33
+ values.each do |value|
34
+ if info = CORL.plugin_class(:CORL, :node).translate_reference(value)
35
+ if ! node_plugins.keys.include?(info[:provider].to_sym) || info[:name].empty?
36
+ warn('download_nodes', { :value => value, :node_provider => info[:provider], :name => info[:name] })
37
+ success = false
38
+ end
39
+ end
40
+ end
41
+ success
42
+ end
43
+ end
44
+ end
45
+
46
+ #---
47
+
48
+ def ignore
49
+ [ :nodes, :parallel ]
50
+ end
51
+
52
+ def arguments
53
+ [ :remote_path, :local_path, :upload_nodes ]
54
+ end
55
+
56
+ #-----------------------------------------------------------------------------
57
+ # Operations
58
+
59
+ def execute
60
+ super do |local_node|
61
+ ensure_network do
62
+ batch_success = network.batch(settings[:download_nodes], settings[:node_provider], false) do |node|
63
+ render_options = { :id => node.id, :hostname => node.hostname, :remote_path => settings[:remote_path], :local_path => settings[:local_path] }
64
+
65
+ info('start', render_options)
66
+ success = node.download(settings[:remote_path], settings[:local_path], { :progress => settings[:progress] })
67
+
68
+ if success
69
+ success('complete', render_options)
70
+ else
71
+ error('failure', render_options)
72
+ end
73
+ success
74
+ end
75
+ myself.status = code.batch_error unless batch_success
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,83 @@
1
+
2
+ module Nucleon
3
+ module Action
4
+ module Node
5
+ class Upload < Nucleon.plugin_class(:nucleon, :cloud_action)
6
+
7
+ #-----------------------------------------------------------------------------
8
+ # Info
9
+
10
+ def self.describe
11
+ super(:node, :upload, 500)
12
+ end
13
+
14
+ #-----------------------------------------------------------------------------
15
+ # Settings
16
+
17
+ def configure
18
+ super do
19
+ register_str :local_path, nil
20
+ register_str :remote_path, nil
21
+ register_str :file_mode, '0755'
22
+
23
+ register_bool :progress, true
24
+
25
+ register_array :upload_nodes, nil do |values|
26
+ if values.nil?
27
+ warn('upload_nodes_empty')
28
+ next false
29
+ end
30
+
31
+ node_plugins = CORL.loaded_plugins(:CORL, :node)
32
+ success = true
33
+
34
+ values.each do |value|
35
+ if info = CORL.plugin_class(:CORL, :node).translate_reference(value)
36
+ if ! node_plugins.keys.include?(info[:provider].to_sym) || info[:name].empty?
37
+ warn('upload_nodes', { :value => value, :node_provider => info[:provider], :name => info[:name] })
38
+ success = false
39
+ end
40
+ end
41
+ end
42
+ success
43
+ end
44
+ end
45
+ end
46
+
47
+ #---
48
+
49
+ def ignore
50
+ [ :nodes ]
51
+ end
52
+
53
+ def arguments
54
+ [ :local_path, :remote_path, :upload_nodes ]
55
+ end
56
+
57
+ #-----------------------------------------------------------------------------
58
+ # Operations
59
+
60
+ def execute
61
+ super do |local_node|
62
+ ensure_network do
63
+ batch_success = network.batch(settings[:upload_nodes], settings[:node_provider], settings[:parallel]) do |node|
64
+ render_options = { :id => node.id, :hostname => node.hostname, :local_path => settings[:local_path], :remote_path => settings[:remote_path] }
65
+
66
+ info('start', render_options)
67
+ success = node.send_files(settings[:local_path], settings[:remote_path], nil, settings[:file_mode], { :progress => settings[:progress] })
68
+
69
+ if success
70
+ success('complete', render_options)
71
+ else
72
+ error('failure', render_options)
73
+ end
74
+ success
75
+ end
76
+ myself.status = code.batch_error unless batch_success
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -667,6 +667,36 @@ en:
667
667
  info:
668
668
  start: |-
669
669
  Destroying %{provider} machine %{name}
670
+ upload:
671
+ description: |-
672
+ Upload a file or directory to a specified location on remote nodes
673
+ help: |-
674
+ Upload a file or directory to a specified location on remote nodes
675
+ options:
676
+ upload_nodes: |-
677
+ Nodes to upload file or directory to
678
+ local_path: |-
679
+ Local file or directory to upload to nodes (default %{default_value})
680
+ remote_path: |-
681
+ Remote path to upload local file or directory to (default %{default_value})
682
+ file_mode: |-
683
+ File mode to set for remote file or directory uploaded (default %{default_value})
684
+ progress: |-
685
+ Show upload progress (default %{default_value})
686
+ info:
687
+ start: |-
688
+ Starting upload of %{local_path} to %{remote_path} on %{hostname} (id %{id})
689
+ success:
690
+ complete: |-
691
+ Upload completed
692
+ warn:
693
+ upload_nodes_empty: |-
694
+ Nodes must be specified in order to run the upload action
695
+ upload_nodes: |-
696
+ Provider %{node_provider} node %{name} is not a valid node to upload (%{value} given)
697
+ error:
698
+ failure: |-
699
+ Upload failed
670
700
  ip:
671
701
  description: |-
672
702
  Return the public IP address for nodes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.15
4
+ version: 0.5.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Webb
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-19 00:00:00.000000000 Z
11
+ date: 2015-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nucleon
@@ -238,8 +238,10 @@ files:
238
238
  - lib/core/mod/fog_rackspace_server.rb
239
239
  - lib/core/mod/hiera_backend.rb
240
240
  - lib/core/plugin/agent.rb
241
+ - lib/core/plugin/agent_wrapper.rb
241
242
  - lib/core/plugin/builder.rb
242
243
  - lib/core/plugin/cloud_action.rb
244
+ - lib/core/plugin/cloud_action_wrapper.rb
243
245
  - lib/core/plugin/configuration.rb
244
246
  - lib/core/plugin/fog_machine.rb
245
247
  - lib/core/plugin/fog_node.rb
@@ -266,6 +268,7 @@ files:
266
268
  - lib/facter/custom_facts.rb
267
269
  - lib/facter/vagrant_exists.rb
268
270
  - lib/hiera/corl_logger.rb
271
+ - lib/nucleon/action/agent/manager.rb
269
272
  - lib/nucleon/action/network/config.rb
270
273
  - lib/nucleon/action/network/create.rb
271
274
  - lib/nucleon/action/network/images.rb
@@ -277,11 +280,15 @@ files:
277
280
  - lib/nucleon/action/network/vagrantfile.rb
278
281
  - lib/nucleon/action/node/IP.rb
279
282
  - lib/nucleon/action/node/SSH.rb
283
+ - lib/nucleon/action/node/agent/status.rb
284
+ - lib/nucleon/action/node/agent/stop.rb
285
+ - lib/nucleon/action/node/agents.rb
280
286
  - lib/nucleon/action/node/authorize.rb
281
287
  - lib/nucleon/action/node/bootstrap.rb
282
288
  - lib/nucleon/action/node/build.rb
283
289
  - lib/nucleon/action/node/cache.rb
284
290
  - lib/nucleon/action/node/destroy.rb
291
+ - lib/nucleon/action/node/download.rb
285
292
  - lib/nucleon/action/node/exec.rb
286
293
  - lib/nucleon/action/node/fact.rb
287
294
  - lib/nucleon/action/node/facts.rb
@@ -299,6 +306,7 @@ files:
299
306
  - lib/nucleon/action/node/start.rb
300
307
  - lib/nucleon/action/node/status.rb
301
308
  - lib/nucleon/action/node/stop.rb
309
+ - lib/nucleon/action/node/upload.rb
302
310
  - lib/nucleon/action/plugin/create.rb
303
311
  - lib/nucleon/action/plugin/list.rb
304
312
  - lib/nucleon/action/plugins.rb