leap_cli 1.6.2 → 1.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 36be7f0c765dbd1c64ca36079780ad6f44797fe0
4
+ data.tar.gz: 379a244c172b9a07d0f9b1a1635d47aa16bd68bc
5
+ SHA512:
6
+ metadata.gz: 079ed74cf97faa015438ecf0dbc4ac2e4bc50a0360e48b602597ef9e8a7e7959943872a498554ef38d455ba461ff65e481d444c25bd55d14e92b6f7abd842fed
7
+ data.tar.gz: 1ec35e8f043b0b0b4516a6fa447420f0d1eb0e42c062b40afb9aae9ab939c0ce50b97dcf5989a5aac7fd70d26aa88333a8e77c655dfa76d97d7573a616f77f20
data/bin/leap CHANGED
@@ -3,13 +3,20 @@
3
3
  if ARGV.include?('--debug') || ARGV.include?('-d')
4
4
  DEBUG=true
5
5
  begin
6
- require 'debugger'
6
+ if RUBY_VERSION =~ /^2/
7
+ require 'byebug'
8
+ else
9
+ require 'debugger'
10
+ end
7
11
  rescue LoadError
8
12
  end
9
13
  else
10
14
  DEBUG=false
11
15
  end
12
16
 
17
+ LEAP_CLI_BASE_DIR = File.expand_path('..', File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__))
18
+ ORIGINAL_ARGV = ARGV.dup
19
+
13
20
  begin
14
21
  require 'leap_cli'
15
22
  rescue LoadError
@@ -24,8 +31,7 @@ rescue LoadError
24
31
  # This allows you to run the command directly while developing the gem, and also lets you
25
32
  # run from anywhere (I like to link 'bin/leap' to /usr/local/bin/leap).
26
33
  #
27
- base_dir = File.expand_path('..', File.dirname(File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__))
28
- require File.join(base_dir, 'lib','leap_cli','load_paths')
34
+ require File.join(LEAP_CLI_BASE_DIR, 'lib','leap_cli','load_paths')
29
35
  require 'leap_cli'
30
36
  end
31
37
 
@@ -77,9 +83,16 @@ module LeapCli::Commands
77
83
  program_desc LeapCli::SUMMARY
78
84
  program_long_desc LeapCli::DESCRIPTION
79
85
 
80
- # handle --version ourselves
86
+ # handle --version ourselves (and not GLI)
81
87
  if ARGV.grep(/--version/).any?
82
88
  puts "leap #{LeapCli::VERSION}, ruby #{RUBY_VERSION}"
89
+ begin
90
+ commands_from('leap_cli/commands')
91
+ initialize_leap_cli(false, {:verbose => 2})
92
+ rescue StandardError => exc
93
+ puts exc.to_s
94
+ raise exc if DEBUG
95
+ end
83
96
  exit(0)
84
97
  end
85
98
 
@@ -88,9 +101,10 @@ module LeapCli::Commands
88
101
  def error_message(msg)
89
102
  end
90
103
 
91
- # load commands and run
104
+ # load commands
92
105
  commands_from('leap_cli/commands')
93
- ORIGINAL_ARGV = ARGV.dup
106
+
107
+ # run command
94
108
  begin
95
109
  exit_status = run(ARGV)
96
110
  exit(LeapCli::Util.exit_status || exit_status)
data/lib/leap/platform.rb CHANGED
@@ -1,5 +1,3 @@
1
- require 'versionomy'
2
-
3
1
  module Leap
4
2
 
5
3
  class Platform
@@ -34,24 +32,24 @@ module Leap
34
32
 
35
33
  self.instance_eval(&block)
36
34
 
37
- @version ||= Versionomy.parse("0.0")
35
+ @version ||= Gem::Version.new("0.0")
38
36
  end
39
37
 
40
38
  def version=(version)
41
- @version = Versionomy.parse(version)
39
+ @version = Gem::Version.new(version)
42
40
  end
43
41
 
44
42
  def compatible_cli=(range)
45
43
  @compatible_cli = range
46
- @minimum_cli_version = Versionomy.parse(range.first)
47
- @maximum_cli_version = Versionomy.parse(range.last)
44
+ @minimum_cli_version = Gem::Version.new(range.first)
45
+ @maximum_cli_version = Gem::Version.new(range.last)
48
46
  end
49
47
 
50
48
  #
51
49
  # return true if the cli_version is compatible with this platform.
52
50
  #
53
51
  def compatible_with_cli?(cli_version)
54
- cli_version = Versionomy.parse(cli_version)
52
+ cli_version = Gem::Version.new(cli_version)
55
53
  cli_version >= @minimum_cli_version && cli_version <= @maximum_cli_version
56
54
  end
57
55
 
@@ -62,16 +60,16 @@ module Leap
62
60
  if range.is_a? String
63
61
  range = range.split('..')
64
62
  end
65
- minimum_platform_version = Versionomy.parse(range.first)
66
- maximum_platform_version = Versionomy.parse(range.last)
63
+ minimum_platform_version = Gem::Version.new(range.first)
64
+ maximum_platform_version = Gem::Version.new(range.last)
67
65
  @version >= minimum_platform_version && @version <= maximum_platform_version
68
66
  end
69
67
 
70
68
  def major_version
71
- if @version.major == 0
72
- "#{@version.major}.#{@version.minor}"
69
+ if @version.segments.first == 0
70
+ @version.segments[0..1].join('.')
73
71
  else
74
- @version.major
72
+ @version.segments.first
75
73
  end
76
74
  end
77
75
 
data/lib/leap_cli.rb CHANGED
@@ -12,7 +12,7 @@ $:.unshift(File.expand_path('../leap_cli/override',__FILE__))
12
12
  # enforce the compatible versions here:
13
13
  require 'rubygems'
14
14
  gem 'net-ssh', '~> 2.7.0'
15
- gem 'gli', '~> 2.12.0'
15
+ gem 'gli', '~> 2.12', '>= 2.12.0'
16
16
 
17
17
  require 'leap/platform'
18
18
 
@@ -20,11 +20,13 @@ require 'leap_cli/version'
20
20
  require 'leap_cli/exceptions'
21
21
 
22
22
  require 'leap_cli/leapfile'
23
- require 'leap_cli/core_ext/hash'
24
23
  require 'leap_cli/core_ext/boolean'
24
+ require 'leap_cli/core_ext/deep_dup'
25
+ require 'leap_cli/core_ext/hash'
26
+ require 'leap_cli/core_ext/json'
25
27
  require 'leap_cli/core_ext/nil'
26
28
  require 'leap_cli/core_ext/string'
27
- require 'leap_cli/core_ext/json'
29
+ require 'leap_cli/core_ext/time'
28
30
  require 'leap_cli/core_ext/yaml'
29
31
 
30
32
  require 'leap_cli/log'
@@ -28,26 +28,11 @@ module LeapCli; module Commands
28
28
  cert.command :update do |update|
29
29
  update.switch 'force', :desc => 'Always generate new certificates', :negatable => false
30
30
  update.action do |global_options,options,args|
31
- assert_files_exist! :ca_cert, :ca_key, :msg => 'Run `leap cert ca` to create them'
32
- assert_config! 'provider.ca.server_certificates.bit_size'
33
- assert_config! 'provider.ca.server_certificates.digest'
34
- assert_config! 'provider.ca.server_certificates.life_span'
35
- assert_config! 'common.x509.use'
36
-
37
- nodes = manager.filter!(args)
38
- nodes.each_node do |node|
39
- warn_if_commercial_cert_will_soon_expire(node)
40
- if !node.x509.use
41
- remove_file!([:node_x509_key, node.name])
42
- remove_file!([:node_x509_cert, node.name])
43
- elsif options[:force] || cert_needs_updating?(node)
44
- generate_cert_for_node(node)
45
- end
46
- end
31
+ update_certificates(manager.filter!(args), options)
47
32
  end
48
33
  end
49
34
 
50
- cert.desc 'Creates a Diffie-Hellman parameter file.' # (needed for server-side of some TLS connections)
35
+ cert.desc 'Creates a Diffie-Hellman parameter file, needed for forward secret OpenVPN ciphers.' # (needed for server-side of some TLS connections)
51
36
  cert.command :dh do |dh|
52
37
  dh.action do |global_options,options,args|
53
38
  long_running do
@@ -102,7 +87,11 @@ module LeapCli; module Commands
102
87
  assert_config! 'provider.ca.server_certificates.bit_size'
103
88
  assert_config! 'provider.ca.server_certificates.digest'
104
89
  domain = options[:domain] || provider.domain
105
- assert_files_missing! [:commercial_key, domain], [:commercial_csr, domain], :msg => 'If you really want to create a new key and CSR, remove these files first.'
90
+
91
+ unless global_options[:force]
92
+ assert_files_missing! [:commercial_key, domain], [:commercial_csr, domain],
93
+ :msg => 'If you really want to create a new key and CSR, remove these files first or run with --force.'
94
+ end
106
95
 
107
96
  server_certificates = provider.ca.server_certificates
108
97
 
@@ -139,7 +128,7 @@ module LeapCli; module Commands
139
128
  cert = csr.to_cert
140
129
  cert.serial_number.number = cert_serial_number(domain)
141
130
  cert.not_before = yesterday
142
- cert.not_after = years_from_yesterday(1)
131
+ cert.not_after = yesterday.advance(:years => 1)
143
132
  cert.parent = ca_root
144
133
  cert.sign! domain_test_signing_profile
145
134
  write_file! [:commercial_cert, domain], cert.to_pem
@@ -158,6 +147,29 @@ module LeapCli; module Commands
158
147
  end
159
148
  end
160
149
 
150
+ protected
151
+
152
+ #
153
+ # will generate new certificates for the specified nodes, if needed.
154
+ #
155
+ def update_certificates(nodes, options={})
156
+ assert_files_exist! :ca_cert, :ca_key, :msg => 'Run `leap cert ca` to create them'
157
+ assert_config! 'provider.ca.server_certificates.bit_size'
158
+ assert_config! 'provider.ca.server_certificates.digest'
159
+ assert_config! 'provider.ca.server_certificates.life_span'
160
+ assert_config! 'common.x509.use'
161
+
162
+ nodes.each_node do |node|
163
+ warn_if_commercial_cert_will_soon_expire(node)
164
+ if !node.x509.use
165
+ remove_file!([:node_x509_key, node.name])
166
+ remove_file!([:node_x509_cert, node.name])
167
+ elsif options[:force] || cert_needs_updating?(node)
168
+ generate_cert_for_node(node)
169
+ end
170
+ end
171
+ end
172
+
161
173
  private
162
174
 
163
175
  def generate_new_certificate_authority(key_file, cert_file, common_name)
@@ -179,7 +191,7 @@ module LeapCli; module Commands
179
191
 
180
192
  # set expiration
181
193
  root.not_before = yesterday
182
- root.not_after = years_from_yesterday(provider.ca.life_span.to_i)
194
+ root.not_after = yesterday_advance(provider.ca.life_span)
183
195
 
184
196
  # generate private key
185
197
  root.serial_number.number = 1
@@ -203,12 +215,12 @@ module LeapCli; module Commands
203
215
  return true
204
216
  else
205
217
  cert = load_certificate_file([:node_x509_cert, node.name])
206
- if cert.not_after < months_from_yesterday(2)
218
+ if cert.not_after < Time.now.advance(:months => 2)
207
219
  log :updating, "cert for node '#{node.name}' because it will expire soon"
208
220
  return true
209
221
  end
210
222
  if cert.subject.common_name != node.domain.full
211
- log :updating, "cert for node '#{node.name}' because domain.full has changed"
223
+ log :updating, "cert for node '#{node.name}' because domain.full has changed (was #{cert.subject.common_name}, now #{node.domain.full})"
212
224
  return true
213
225
  end
214
226
  cert.openssl_body.extensions.each do |ext|
@@ -242,7 +254,7 @@ module LeapCli; module Commands
242
254
  if cert.not_after < Time.now.utc
243
255
  log :error, "the commercial certificate '#{path}' has EXPIRED! " +
244
256
  "You should renew it with `leap cert csr --domain #{domain}`."
245
- elsif cert.not_after < months_from_yesterday(2)
257
+ elsif cert.not_after < Time.now.advance(:months => 2)
246
258
  log :warning, "the commercial certificate '#{path}' will expire soon. "+
247
259
  "You should renew it with `leap cert csr --domain #{domain}`."
248
260
  end
@@ -261,7 +273,7 @@ module LeapCli; module Commands
261
273
 
262
274
  # set expiration
263
275
  cert.not_before = yesterday
264
- cert.not_after = years_from_yesterday(provider.ca.server_certificates.life_span.to_i)
276
+ cert.not_after = yesterday_advance(provider.ca.server_certificates.life_span)
265
277
 
266
278
  # generate key
267
279
  cert.key_material.generate_key(provider.ca.server_certificates.bit_size)
@@ -283,7 +295,7 @@ module LeapCli; module Commands
283
295
  cert.serial_number.number = cert_serial_number(provider.domain)
284
296
  cert.subject.common_name = [prefix, random_common_name(provider.domain)].join
285
297
  cert.not_before = yesterday
286
- cert.not_after = years_from_yesterday(1)
298
+ cert.not_after = yesterday.advance(:years => 1)
287
299
  cert.key_material.generate_key(1024) # just for testing, remember!
288
300
  cert.parent = client_ca_root
289
301
  cert.sign! client_test_signing_profile
@@ -492,16 +504,15 @@ module LeapCli; module Commands
492
504
  Time.utc t.year, t.month, t.day
493
505
  end
494
506
 
495
- def years_from_yesterday(num)
496
- t = yesterday
497
- Time.utc t.year + num, t.month, t.day
498
- end
499
-
500
- def months_from_yesterday(num)
501
- t = yesterday
502
- date = Date.new t.year, t.month, t.day
503
- date = date >> num # >> is months in the future operator
504
- Time.utc date.year, date.month, date.day
507
+ def yesterday_advance(string)
508
+ number, unit = string.split(' ')
509
+ unless ['years', 'months', 'days', 'hours', 'minutes'].include? unit
510
+ bail!("The time property '#{string}' is missing a unit (one of: years, months, days, hours, minutes).")
511
+ end
512
+ unless number.to_i.to_s == number
513
+ bail!("The time property '#{string}' is missing a number.")
514
+ end
515
+ yesterday.advance(unit.to_sym => number.to_i)
505
516
  end
506
517
 
507
518
  end; end
@@ -12,8 +12,12 @@ module LeapCli
12
12
  if !LeapCli.leapfile.environment.nil? && !environment.nil? && environment != LeapCli.leapfile.environment
13
13
  bail! "You cannot specify an ENVIRONMENT argument while the environment is pinned."
14
14
  end
15
- if environment && manager.environment_names.include?(environment)
16
- compile_hiera_files(manager.filter([environment]))
15
+ if environment
16
+ if manager.environment_names.include?(environment)
17
+ compile_hiera_files(manager.filter([environment]))
18
+ else
19
+ bail! "There is no environment named `#{environment}`."
20
+ end
17
21
  else
18
22
  compile_hiera_files(manager.filter)
19
23
  end
@@ -2,21 +2,32 @@ module LeapCli; module Commands
2
2
 
3
3
  desc 'Database commands.'
4
4
  command :db do |db|
5
- db.desc 'Destroy all the databases. If present, limit to FILTER nodes.'
5
+ db.desc 'Destroy one or more databases. If present, limit to FILTER nodes. For example `leap db destroy --db sessions,tokens testing`.'
6
6
  db.arg_name 'FILTER', :optional => true
7
7
  db.command :destroy do |destroy|
8
+ destroy.flag :db, :arg_name => "DATABASES", :desc => 'Comma separated list of databases to destroy (no space). Use "--db all" to destroy all databases.', :optional => false
8
9
  destroy.action do |global_options,options,args|
9
- say 'You are about to permanently destroy all database data.'
10
- return unless agree("Continue? ")
10
+ dbs = (options[:db]||"").split(',')
11
+ bail!('No databases specified') if dbs.empty?
11
12
  nodes = manager.filter(args)
12
13
  if nodes.any?
13
14
  nodes = nodes[:services => 'couchdb']
14
15
  end
15
16
  if nodes.any?
16
- ssh_connect(nodes, connect_options(options)) do |ssh|
17
- ssh.run('/etc/init.d/bigcouch stop && test ! -z "$(ls /opt/bigcouch/var/lib/ 2> /dev/null)" && rm -r /opt/bigcouch/var/lib/* && echo "db destroyed" || echo "db already destroyed"')
18
- ssh.run('grep ^seq_file /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -v')
17
+ unless global_options[:yes]
18
+ if dbs.include?('all')
19
+ say 'You are about to permanently destroy all database data for nodes [%s].' % nodes.keys.join(', ')
20
+ else
21
+ say 'You are about to permanently destroy databases [%s] for nodes [%s].' % [dbs.join(', '), nodes.keys.join(', ')]
22
+ end
23
+ bail! unless agree("Continue? ")
19
24
  end
25
+ if dbs.include?('all')
26
+ destroy_all_dbs(nodes)
27
+ else
28
+ destroy_dbs(nodes, dbs)
29
+ end
30
+ say 'You must run `leap deploy` in order to create the databases again.'
20
31
  else
21
32
  say 'No nodes'
22
33
  end
@@ -26,4 +37,29 @@ module LeapCli; module Commands
26
37
 
27
38
  private
28
39
 
40
+ def destroy_all_dbs(nodes)
41
+ ssh_connect(nodes) do |ssh|
42
+ ssh.run('/etc/init.d/bigcouch stop && test ! -z "$(ls /opt/bigcouch/var/lib/ 2> /dev/null)" && rm -r /opt/bigcouch/var/lib/* && echo "db destroyed" || echo "db already destroyed"')
43
+ ssh.run('grep ^seq_dir /etc/leap/tapicero.yaml | cut -f2 -d\" | xargs rm -rv')
44
+ end
45
+ end
46
+
47
+ def destroy_dbs(nodes, dbs)
48
+ nodes.each_node do |node|
49
+ ssh_connect(node) do |ssh|
50
+ dbs.each do |db|
51
+ ssh.run(DESTROY_DB_COMMAND % {:db => db})
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ DESTROY_DB_COMMAND = %{
58
+ if [ 200 = `curl -ns -w "%%{http_code}" -X GET "127.0.0.1:5984/%{db}" -o /dev/null` ]; then
59
+ echo "Result from DELETE /%{db}:" `curl -ns -X DELETE "127.0.0.1:5984/%{db}"`;
60
+ else
61
+ echo "Skipping db '%{db}': it does not exist or has already been deleted.";
62
+ fi
63
+ }
64
+
29
65
  end; end
@@ -1,3 +1,4 @@
1
+ require 'etc'
1
2
 
2
3
  module LeapCli
3
4
  module Commands
@@ -7,20 +8,17 @@ module LeapCli
7
8
  arg_name 'FILTER'
8
9
  command [:deploy, :d] do |c|
9
10
 
10
- # --fast
11
11
  c.switch :fast, :desc => 'Makes the deploy command faster by skipping some slow steps. A "fast" deploy can be used safely if you recently completed a normal deploy.',
12
12
  :negatable => false
13
13
 
14
- # --sync
15
- c.switch :sync, :desc => "Sync files, but don't actually apply recipes."
14
+ c.switch :sync, :desc => "Sync files, but don't actually apply recipes.", :negatable => false
16
15
 
17
- # --force
18
16
  c.switch :force, :desc => 'Deploy even if there is a lockfile.', :negatable => false
19
17
 
20
- # --dev
18
+ c.switch :downgrade, :desc => 'Allows deploy to run with an older platform version.', :negatable => false
19
+
21
20
  c.switch :dev, :desc => "Development mode: don't run 'git submodule update' before deploy.", :negatable => false
22
21
 
23
- # --tags
24
22
  c.flag :tags, :desc => 'Specify tags to pass through to puppet (overriding the default).',
25
23
  :arg_name => 'TAG[,TAG]'
26
24
 
@@ -49,11 +47,13 @@ module LeapCli
49
47
  environments = [nil]
50
48
  end
51
49
  environments.each do |env|
52
- check_platform_pinning(env)
50
+ check_platform_pinning(env, global)
53
51
  end
54
52
  # compile hiera files for all the nodes in every environment that is
55
53
  # being deployed and only those environments.
56
54
  compile_hiera_files(manager.filter(environments))
55
+ # update server certificates if needed
56
+ update_certificates(nodes)
57
57
 
58
58
  ssh_connect(nodes, connect_options(options)) do |ssh|
59
59
  ssh.leap.log :checking, 'node' do
@@ -69,7 +69,12 @@ module LeapCli
69
69
  end
70
70
  unless options[:sync]
71
71
  ssh.leap.log :applying, "puppet" do
72
- ssh.puppet.apply(:verbosity => [LeapCli.log_level,5].min, :tags => tags(options), :force => options[:force])
72
+ ssh.puppet.apply(:verbosity => [LeapCli.log_level,5].min,
73
+ :tags => tags(options),
74
+ :force => options[:force],
75
+ :info => deploy_info,
76
+ :downgrade => options[:downgrade]
77
+ )
73
78
  end
74
79
  end
75
80
  end
@@ -79,8 +84,34 @@ module LeapCli
79
84
  end
80
85
  end
81
86
 
87
+ desc 'Display recent deployment history for a set of nodes.'
88
+ long_desc 'The FILTER can be the name of a node, service, or tag.'
89
+ arg_name 'FILTER'
90
+ command [:history, :h] do |c|
91
+ c.flag :port, :desc => 'Override the default SSH port.',
92
+ :arg_name => 'PORT'
93
+ c.flag :ip, :desc => 'Override the default SSH IP address.',
94
+ :arg_name => 'IPADDRESS'
95
+ c.action do |global,options,args|
96
+ nodes = manager.filter!(args)
97
+ ssh_connect(nodes, connect_options(options)) do |ssh|
98
+ ssh.leap.history
99
+ end
100
+ end
101
+ end
102
+
82
103
  private
83
104
 
105
+ def forcible_prompt(forced, msg, prompt)
106
+ say(msg)
107
+ if forced
108
+ log :warning, "continuing anyway because of --force"
109
+ else
110
+ say "hint: use --force to skip this prompt."
111
+ quit!("OK. Bye.") unless agree(prompt)
112
+ end
113
+ end
114
+
84
115
  #
85
116
  # The currently activated provider.json could have loaded some pinning
86
117
  # information for the platform. If this is the case, refuse to deploy
@@ -94,7 +125,7 @@ module LeapCli
94
125
  # "commit": "e1d6280e0a8c565b7fb1a4ed3969ea6fea31a5e2..HEAD"
95
126
  # }
96
127
  #
97
- def check_platform_pinning(environment)
128
+ def check_platform_pinning(environment, global_options)
98
129
  provider = manager.env(environment).provider
99
130
  return unless provider['platform']
100
131
 
@@ -112,34 +143,46 @@ module LeapCli
112
143
  # check version
113
144
  if provider.platform['version']
114
145
  if !Leap::Platform.version_in_range?(provider.platform.version)
115
- say("The platform is pinned to a version range of '#{provider.platform.version}' "+
116
- "by the `platform.version` property in #{provider_json}, but the platform "+
117
- "(#{Path.platform}) has version #{Leap::Platform.version}.")
118
- quit!("OK. Bye.") unless agree("Do you really want to deploy from the wrong version? ")
146
+ forcible_prompt(
147
+ global_options[:force],
148
+ "The platform is pinned to a version range of '#{provider.platform.version}' "+
149
+ "by the `platform.version` property in #{provider_json}, but the platform "+
150
+ "(#{Path.platform}) has version #{Leap::Platform.version}.",
151
+ "Do you really want to deploy from the wrong version? "
152
+ )
119
153
  end
120
154
  end
121
155
 
122
156
  # check branch
123
157
  if provider.platform['branch']
124
158
  if !is_git_directory?(Path.platform)
125
- say("The platform is pinned to a particular branch by the `platform.branch` property "+
126
- "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.")
127
- quit!("OK. Bye.") unless agree("Do you really want to deploy anyway? ")
159
+ forcible_prompt(
160
+ global_options[:force],
161
+ "The platform is pinned to a particular branch by the `platform.branch` property "+
162
+ "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.",
163
+ "Do you really want to deploy anyway? "
164
+ )
128
165
  end
129
166
  unless provider.platform.branch == current_git_branch(Path.platform)
130
- say("The platform is pinned to branch '#{provider.platform.branch}' by the `platform.branch` property "+
131
- "in #{provider_json}, but the current branch is '#{current_git_branch(Path.platform)}' " +
132
- "(for directory '#{Path.platform}')")
133
- quit!("OK. Bye.") unless agree("Do you really want to deploy from the wrong branch? ")
167
+ forcible_prompt(
168
+ global_options[:force],
169
+ "The platform is pinned to branch '#{provider.platform.branch}' by the `platform.branch` property "+
170
+ "in #{provider_json}, but the current branch is '#{current_git_branch(Path.platform)}' " +
171
+ "(for directory '#{Path.platform}')",
172
+ "Do you really want to deploy from the wrong branch? "
173
+ )
134
174
  end
135
175
  end
136
176
 
137
177
  # check commit
138
178
  if provider.platform['commit']
139
179
  if !is_git_directory?(Path.platform)
140
- say("The platform is pinned to a particular commit range by the `platform.commit` property "+
141
- "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.")
142
- quit!("OK. Bye.") unless agree("Do you really want to deploy anyway? ")
180
+ forcible_prompt(
181
+ global_options[:force],
182
+ "The platform is pinned to a particular commit range by the `platform.commit` property "+
183
+ "in #{provider_json}, but the platform directory (#{Path.platform}) is not a git repository.",
184
+ "Do you really want to deploy anyway? "
185
+ )
143
186
  end
144
187
  current_commit = current_git_commit(Path.platform)
145
188
  Dir.chdir(Path.platform) do
@@ -150,10 +193,13 @@ module LeapCli
150
193
  commit_range = commit_range.split("\n")
151
194
  if !commit_range.include?(current_commit) &&
152
195
  provider.platform.commit.split('..').first != current_commit
153
- say("The platform is pinned via the `platform.commit` property in #{provider_json} " +
154
- "to a commit in the range #{provider.platform.commit}, but the current HEAD " +
155
- "(#{current_commit}) is not in that range.")
156
- quit!("OK. Bye.") unless agree("Do you really want to deploy from the wrong commit? ")
196
+ forcible_prompt(
197
+ global_options[:force],
198
+ "The platform is pinned via the `platform.commit` property in #{provider_json} " +
199
+ "to a commit in the range #{provider.platform.commit}, but the current HEAD " +
200
+ "(#{current_commit}) is not in that range.",
201
+ "Do you really want to deploy from the wrong commit? "
202
+ )
157
203
  end
158
204
  end
159
205
  end
@@ -177,17 +223,11 @@ module LeapCli
177
223
  #
178
224
  def sync_support_files(ssh)
179
225
  dest_dir = Leap::Platform.files_dir
180
- source_files = []
181
- if Path.defined?(:custom_puppet_dir) && file_exists?(:custom_puppet_dir)
182
- source_files += [:custom_puppet_dir, :custom_puppet_modules_dir, :custom_puppet_manifests_dir].collect{|path|
183
- Path.relative_path(path, Path.provider) + '/' # rsync needs trailing slash
184
- }
185
- ensure_dir :custom_puppet_modules_dir
186
- end
226
+ custom_files = build_custom_file_list
187
227
  ssh.rsync.update do |server|
188
228
  node = manager.node(server.host)
189
229
  files_to_sync = node.file_paths.collect {|path| Path.relative_path(path, Path.provider) }
190
- files_to_sync += source_files
230
+ files_to_sync += custom_files
191
231
  if files_to_sync.any?
192
232
  ssh.leap.log(files_to_sync.join(', ') + ' -> ' + node.name + ':' + dest_dir)
193
233
  {
@@ -282,5 +322,47 @@ module LeapCli
282
322
  tags.join(',')
283
323
  end
284
324
 
325
+ #
326
+ # a provider might have various customization files that should be sync'ed to the server.
327
+ # this method builds that list of files to sync.
328
+ #
329
+ def build_custom_file_list
330
+ custom_files = []
331
+ Leap::Platform.paths.keys.grep(/^custom_/).each do |path|
332
+ if file_exists?(path)
333
+ relative_path = Path.relative_path(path, Path.provider)
334
+ if dir_exists?(path)
335
+ custom_files << relative_path + '/' # rsync needs trailing slash
336
+ else
337
+ custom_files << relative_path
338
+ end
339
+ end
340
+ end
341
+ return custom_files
342
+ end
343
+
344
+ def deploy_info
345
+ info = []
346
+ info << "user: %s" % Etc.getpwuid(Process.euid).name
347
+ if is_git_directory?(Path.platform) && current_git_branch(Path.platform) != 'master'
348
+ info << "platform: %s (%s %s)" % [
349
+ Leap::Platform.version,
350
+ current_git_branch(Path.platform),
351
+ current_git_commit(Path.platform)[0..4]
352
+ ]
353
+ else
354
+ info << "platform: %s" % Leap::Platform.version
355
+ end
356
+ if is_git_directory?(LEAP_CLI_BASE_DIR)
357
+ info << "leap_cli: %s (%s %s)" % [
358
+ LeapCli::VERSION,
359
+ current_git_branch(LEAP_CLI_BASE_DIR),
360
+ current_git_commit(LEAP_CLI_BASE_DIR)[0..4]
361
+ ]
362
+ else
363
+ info << "leap_cli: %s" % LeapCli::VERSION
364
+ end
365
+ info.join(', ')
366
+ end
285
367
  end
286
368
  end