bosh-bootstrap 0.8.2 → 0.9.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.
Files changed (96) hide show
  1. data/.gitignore +0 -1
  2. data/.travis.yml +24 -3
  3. data/ChangeLog.md +8 -0
  4. data/Gemfile +5 -3
  5. data/Guardfile +3 -3
  6. data/Rakefile +21 -5
  7. data/lib/bosh/providers/aws.rb +67 -27
  8. data/lib/bosh/providers/base_provider.rb +27 -0
  9. data/lib/bosh/providers/openstack.rb +16 -6
  10. data/lib/bosh-bootstrap/cli.rb +166 -61
  11. data/lib/bosh-bootstrap/commander/remote_script_command.rb +7 -4
  12. data/lib/bosh-bootstrap/commander/remote_server.rb +12 -10
  13. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/bosh_micro_deploy +5 -1
  14. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/download_micro_bosh_stemcell +12 -6
  15. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy.rb +4 -1
  16. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/configure_git +4 -9
  17. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/create_vcap_user +1 -1
  18. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_base_packages +12 -2
  19. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_bosh +3 -45
  20. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_bosh_by_gem_install +54 -0
  21. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_hub +26 -0
  22. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_ruby +10 -15
  23. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_useful_gems +1 -1
  24. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/validate_bosh_deployer +0 -5
  25. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm.rb +21 -15
  26. data/lib/bosh-bootstrap/stages/{stage_prepare_inception_vm → stage_salted_password}/convert_salted_password +0 -0
  27. data/lib/bosh-bootstrap/stages/stage_salted_password.rb +51 -0
  28. data/lib/bosh-bootstrap/stages/stage_setup_new_bosh.rb +0 -1
  29. data/lib/bosh-bootstrap/stages/stage_validate_inception_vm.rb +1 -1
  30. data/lib/bosh-bootstrap/stages.rb +1 -0
  31. data/lib/bosh-bootstrap/version.rb +1 -1
  32. data/spec/{functional → integration}/.gitkeep +0 -0
  33. data/spec/integration/aws/aws_basic_spec.rb +39 -0
  34. data/spec/integration/aws/aws_edge_prebuilt_ami_spec.rb +46 -0
  35. data/spec/integration/aws/aws_edge_prebuilt_spec.rb +46 -0
  36. data/spec/integration/aws/aws_edge_spec.rb +45 -0
  37. data/spec/integration/aws/aws_helpers.rb +79 -0
  38. data/spec/spec_helper.rb +6 -0
  39. data/spec/unit/aws_spec.rb +28 -6
  40. data/spec/unit/bosh/providers/aws_spec.rb +14 -0
  41. data/spec/unit/cli_spec.rb +10 -8
  42. data/vendor/cache/POpen4-0.1.4.gem +0 -0
  43. data/vendor/cache/Platform-0.4.0.gem +0 -0
  44. data/vendor/cache/activesupport-3.2.8.gem +0 -0
  45. data/vendor/cache/awesome_print-1.1.0.gem +0 -0
  46. data/vendor/cache/aws-s3-0.6.3.gem +0 -0
  47. data/vendor/cache/blobstore_client-0.4.0.gem +0 -0
  48. data/vendor/cache/bosh_cli-1.0.3.gem +0 -0
  49. data/vendor/cache/bosh_common-0.5.4.gem +0 -0
  50. data/vendor/cache/builder-3.1.4.gem +0 -0
  51. data/vendor/cache/coderay-1.0.8.gem +0 -0
  52. data/vendor/cache/diff-lcs-1.1.3.gem +0 -0
  53. data/vendor/cache/escape-0.0.4.gem +0 -0
  54. data/vendor/cache/excon-0.17.0.gem +0 -0
  55. data/vendor/cache/fog-1.8.0.gem +0 -0
  56. data/vendor/cache/formatador-0.2.4.gem +0 -0
  57. data/vendor/cache/guard-1.6.2.gem +0 -0
  58. data/vendor/cache/guard-rspec-2.4.0.gem +0 -0
  59. data/vendor/cache/highline-1.6.15.gem +0 -0
  60. data/vendor/cache/httpclient-2.2.4.gem +0 -0
  61. data/vendor/cache/i18n-0.6.1.gem +0 -0
  62. data/vendor/cache/json_pure-1.6.8.gem +0 -0
  63. data/vendor/cache/listen-0.7.2.gem +0 -0
  64. data/vendor/cache/log4r-1.1.10.gem +0 -0
  65. data/vendor/cache/lumberjack-1.0.2.gem +0 -0
  66. data/vendor/cache/method_source-0.8.1.gem +0 -0
  67. data/vendor/cache/mime-types-1.21.gem +0 -0
  68. data/vendor/cache/multi_json-1.1.0.gem +0 -0
  69. data/vendor/cache/net-scp-1.0.4.gem +0 -0
  70. data/vendor/cache/net-ssh-2.2.2.gem +0 -0
  71. data/vendor/cache/net-ssh-gateway-1.1.0.gem +0 -0
  72. data/vendor/cache/netaddr-1.5.0.gem +0 -0
  73. data/vendor/cache/nokogiri-1.5.6-java.gem +0 -0
  74. data/vendor/cache/nokogiri-1.5.6.gem +0 -0
  75. data/vendor/cache/open4-1.3.0.gem +0 -0
  76. data/vendor/cache/progressbar-0.9.2.gem +0 -0
  77. data/vendor/cache/pry-0.9.11.4-java.gem +0 -0
  78. data/vendor/cache/pry-0.9.11.4.gem +0 -0
  79. data/vendor/cache/rake-10.0.3.gem +0 -0
  80. data/vendor/cache/rb-fsevent-0.9.3.gem +0 -0
  81. data/vendor/cache/redcard-1.0.0.gem +0 -0
  82. data/vendor/cache/rspec-2.12.0.gem +0 -0
  83. data/vendor/cache/rspec-core-2.12.2.gem +0 -0
  84. data/vendor/cache/rspec-expectations-2.12.1.gem +0 -0
  85. data/vendor/cache/rspec-mocks-2.12.2.gem +0 -0
  86. data/vendor/cache/ruby-atmos-pure-1.0.5.gem +0 -0
  87. data/vendor/cache/ruby-hmac-0.4.0.gem +0 -0
  88. data/vendor/cache/settingslogic-2.0.9.gem +0 -0
  89. data/vendor/cache/slop-3.4.3.gem +0 -0
  90. data/vendor/cache/spoon-0.0.1.gem +0 -0
  91. data/vendor/cache/terminal-table-1.4.5.gem +0 -0
  92. data/vendor/cache/thor-0.17.0.gem +0 -0
  93. data/vendor/cache/uuidtools-2.1.3.gem +0 -0
  94. data/vendor/cache/xml-simple-1.1.2.gem +0 -0
  95. metadata +72 -7
  96. data/lib/bosh-bootstrap/stages/stage_setup_new_bosh/cleanup_permissions +0 -14
@@ -18,26 +18,29 @@ module Bosh::Bootstrap
18
18
  include Bosh::Bootstrap::Helpers::SettingsSetter
19
19
  include FileUtils
20
20
 
21
+ AWS_JENKINS_BUCKET = "bosh-jenkins-artifacts"
22
+
21
23
  attr_reader :fog_credentials
22
24
  attr_reader :server
23
25
 
24
26
  desc "deploy", "Bootstrap Micro BOSH, and optionally an Inception VM"
27
+ method_option :"edge-prebuilt", :type => :boolean, :desc => "Use AWS us-east-1 gems & prebuilt AMIs"
28
+ method_option :"edge", :type => :boolean, :desc => "Use pre-built gems; create microbosh from source [temporary default]"
25
29
  method_option :fog, :type => :string, :desc => "fog config file (default: ~/.fog)"
26
30
  method_option :"upgrade-deps", :type => :boolean, :desc => "Force upgrade dependencies, packages & gems"
27
- method_option :"edge-deployer", :type => :boolean, :desc => "Install bosh deployer from git instead of rubygems"
28
- method_option :"stable-stemcell", :type => :boolean, :desc => "Use recent stable microbosh stemcell"
29
- method_option :"latest-stemcell", :type => :boolean, :desc => "Use latest microbosh stemcell; possibly not tagged stable [default]"
30
- method_option :"edge-stemcell", :type => :boolean, :desc => "Create custom stemcell from BOSH git source"
31
31
  def deploy
32
32
  migrate_old_settings
33
33
  load_deploy_options # from method_options above
34
34
 
35
35
  deploy_stage_1_choose_infrastructure_provider
36
+ load_provider_specific_options
37
+
36
38
  deploy_stage_2_bosh_configuration
37
39
  deploy_stage_3_create_allocate_inception_vm
38
40
  deploy_stage_4_prepare_inception_vm
39
- deploy_stage_5_deploy_micro_bosh
40
- deploy_stage_6_setup_new_bosh
41
+ deploy_stage_5_salted_password
42
+ deploy_stage_6_deploy_micro_bosh
43
+ deploy_stage_7_setup_new_bosh
41
44
  end
42
45
 
43
46
  desc "upgrade-inception", "Upgrade inception VM with latest packages, gems, security group ports"
@@ -96,6 +99,7 @@ module Bosh::Bootstrap
96
99
 
97
100
  no_tasks do
98
101
  DEFAULT_INCEPTION_VOLUME_SIZE = 32 # Gb
102
+ DEFAULT_MICROBOSH_VOLUME_SIZE = 16 # Gb
99
103
 
100
104
  def deploy_stage_1_choose_infrastructure_provider
101
105
  header "Stage 1: Choose infrastructure"
@@ -161,13 +165,17 @@ module Bosh::Bootstrap
161
165
  confirm "Micro BOSH instance type will be #{settings[:bosh_resources_cloud_properties]["instance_type"]}"
162
166
 
163
167
  unless settings[:bosh]
164
- say "Defaulting to 16Gb persistent disk for BOSH"
165
168
  password = settings.bosh_password # FIXME dual use of password?
166
169
  settings[:bosh] = {}
167
170
  settings[:bosh][:password] = password
168
- settings[:bosh][:persistent_disk] = 16384
171
+ if openstack?
172
+ settings[:bosh][:persistent_disk] = prompt_for_disk_space("Micro BOSH VM", DEFAULT_MICROBOSH_VOLUME_SIZE) * 1024
173
+ else
174
+ settings[:bosh][:persistent_disk] = DEFAULT_MICROBOSH_VOLUME_SIZE * 1024
175
+ end
169
176
  save_settings!
170
177
  end
178
+ confirm "Micro BOSH persistent disk size will be #{settings.bosh.persistent_disk} Mb"
171
179
 
172
180
  unless settings[:bosh]["ip_address"]
173
181
  if vpc?
@@ -242,6 +250,8 @@ module Bosh::Bootstrap
242
250
  create_inception_key_pair
243
251
  end
244
252
  recreate_local_ssh_keys_for_inception_vm
253
+ create_security_group_for_inception_vm
254
+
245
255
  aws? ? boot_aws_inception_vm : boot_openstack_inception_vm
246
256
  end
247
257
  # If successfully validate inception VM, then save those settings.
@@ -267,9 +277,6 @@ module Bosh::Bootstrap
267
277
  unless run_server(Bosh::Bootstrap::Stages::StagePrepareInceptionVm.new(settings).commands)
268
278
  error "Failed to complete Stage 4: Preparing the Inception VM"
269
279
  end
270
- # Settings are updated by this stage
271
- # it generates a salted password from settings.bosh.password
272
- # and stores it in settings.bosh.salted_password
273
280
  settings["inception"]["prepared"] = true
274
281
  save_settings!
275
282
  else
@@ -277,23 +284,42 @@ module Bosh::Bootstrap
277
284
  end
278
285
  end
279
286
 
280
- def deploy_stage_5_deploy_micro_bosh
281
- header "Stage 5: Deploying micro BOSH"
287
+ def deploy_stage_5_salted_password
288
+ unless settings["bosh"] && settings["bosh"]["salted_password"]
289
+ header "Stage 5: Generate salted password"
290
+ recreate_local_ssh_keys_for_inception_vm
291
+
292
+ unless run_server(Bosh::Bootstrap::Stages::SaltedPassword.new(settings).commands)
293
+ error "Failed to complete Stage 5: Generate salted password"
294
+ end
295
+ save_settings!
296
+ else
297
+ header "Stage 5: Generate salted password", skipping: "Already generated salted password"
298
+ end
299
+ end
300
+
301
+ def deploy_stage_6_deploy_micro_bosh
302
+ header "Stage 6: Deploying micro BOSH"
282
303
  recreate_local_ssh_keys_for_inception_vm
304
+ switch_to_prebuilt_microbosh_ami_if_available
283
305
 
284
306
  unless run_server(Bosh::Bootstrap::Stages::MicroBoshDeploy.new(settings).commands)
285
- error "Failed to complete Stage 5: Deploying micro BOSH"
307
+ error "Failed to complete Stage 6: Deploying micro BOSH"
286
308
  end
309
+ # Settings are updated by this stage
310
+ # it generates a salted password from settings.bosh.password
311
+ # and stores it in settings.bosh.salted_password
312
+ save_settings!
287
313
 
288
314
  confirm "Successfully built micro BOSH"
289
315
  end
290
316
 
291
- def deploy_stage_6_setup_new_bosh
317
+ def deploy_stage_7_setup_new_bosh
292
318
  # TODO change to a polling test of director being available
293
319
  say "Pausing to wait for BOSH Director..."
294
320
  sleep 5
295
321
 
296
- header "Stage 6: Setup bosh"
322
+ header "Stage 7: Setup bosh"
297
323
  unless run_server(Bosh::Bootstrap::Stages::SetupNewBosh.new(settings).commands)
298
324
  error "Failed to complete Stage 6: Setup bosh"
299
325
  end
@@ -380,13 +406,13 @@ module Bosh::Bootstrap
380
406
  end
381
407
 
382
408
  def ensure_inception_vm
383
- unless settings[:inception]
409
+ unless settings["inception"]
384
410
  say "No inception VM being used", :yellow
385
411
  exit 0
386
412
  end
387
413
  end
388
414
  def ensure_inception_vm_has_launched
389
- unless settings.inception[:host]
415
+ unless settings.inception["host"]
390
416
  exit "Inception VM has not finished launching; run to complete: #{self.class.banner_base} deploy"
391
417
  end
392
418
  end
@@ -458,29 +484,7 @@ module Bosh::Bootstrap
458
484
  def load_deploy_options
459
485
  settings["fog_path"] = File.expand_path(options[:fog] || "~/.fog")
460
486
 
461
- settings["git"] ||= {}
462
- settings["git"]["name"] ||= `git config user.name`.strip
463
- settings["git"]["email"] ||= `git config user.email`.strip
464
- if settings["git"]["name"].empty? || settings["git"]["email"].empty?
465
- error "Cannot find your git identity. Please set git user.name and user.email before proceeding"
466
- end
467
-
468
- settings["bosh_git_source"] = options[:"edge-deployer"] # use bosh git repo instead of rubygems
469
-
470
- # determine which micro-bosh stemcell to download/create
471
- if options[:"stable-stemcell"]
472
- settings["micro_bosh_stemcell_type"] = "stable"
473
- settings["micro_bosh_stemcell_name"] = nil # force name to be refetched
474
- elsif options[:"latest-stemcell"]
475
- settings["micro_bosh_stemcell_type"] = "latest"
476
- settings["micro_bosh_stemcell_name"] = nil # force name to be refetched
477
- elsif options[:"edge-stemcell"]
478
- settings["micro_bosh_stemcell_type"] = "custom"
479
- settings["micro_bosh_stemcell_name"] = "custom"
480
- end
481
- # may have already been set from previous deploy run
482
- # default to "latest" for both AWS and OpenStack at the moment (no useful stable stemcells)
483
- settings["micro_bosh_stemcell_type"] ||= "latest"
487
+ prompt_git_user_information
484
488
 
485
489
  # once a stemcell is downloaded or created; these fields above should
486
490
  # be uploaded with values such as:
@@ -494,6 +498,42 @@ module Bosh::Bootstrap
494
498
  save_settings!
495
499
  end
496
500
 
501
+ def load_provider_specific_options
502
+ # before deploy stage - need to change type => ami if AWS us-east-1?
503
+ if options[:"edge-prebuilt"] || settings.delete("edge-prebuilt")
504
+ if aws?
505
+ settings["micro_bosh_stemcell_type"] = "edge-prebuilt"
506
+ settings["micro_bosh_stemcell_name"] = "edge-prebuilt"
507
+ else
508
+ error "Currently --edge-prebuilt is not available for #{bosh_provider} :("
509
+ end
510
+ elsif options[:"edge"] || settings.delete("edge")
511
+ settings["micro_bosh_stemcell_type"] = "custom"
512
+ settings["micro_bosh_stemcell_name"] = "custom"
513
+ else
514
+ if settings["fog_credentials"] && aws?
515
+ # currently defaulting to latest prebuilt stemcells/amis until 1.5.0 is released
516
+ settings["micro_bosh_stemcell_type"] = "edge-prebuilt"
517
+ settings["micro_bosh_stemcell_name"] = "edge-prebuilt"
518
+ else
519
+ settings["micro_bosh_stemcell_type"] = "custom"
520
+ settings["micro_bosh_stemcell_name"] = "custom"
521
+ end
522
+ end
523
+ end
524
+
525
+ def prompt_git_user_information
526
+ settings["git"] ||= {}
527
+ settings["git"]["name"] ||= `git config user.name`.strip
528
+ while settings["git"]["name"].empty?
529
+ settings["git"]["name"] = hl.ask("What is your name? (to setup git on inception VM) ")
530
+ end
531
+ settings["git"]["email"] ||= `git config user.email`.strip
532
+ while settings["git"]["email"].empty?
533
+ settings["git"]["email"] = hl.ask("What is your email? (to setup git on inception VM) ")
534
+ end
535
+ end
536
+
497
537
  # Displays a prompt for known IaaS that are configured
498
538
  # within .fog config file.
499
539
  #
@@ -752,13 +792,11 @@ module Bosh::Bootstrap
752
792
  nats_server: 4222,
753
793
  message_bus: 6868,
754
794
  blobstore: 25250,
755
- bosh_director: 25555
795
+ bosh_director: 25555,
796
+ bosh_registry: 25777
756
797
  }
757
- if aws?
758
- ports[:aws_registry] = 25777
759
- elsif openstack?
760
- ports[:openstack_registry] = 25889
761
- end
798
+ # TODO: New stemcells to be released will use 25777, so this can be deleted
799
+ ports[:openstack_registry] = 25889 if openstack?
762
800
 
763
801
  provider.create_security_group(security_group_name, "microbosh", ports)
764
802
 
@@ -770,6 +808,27 @@ module Bosh::Bootstrap
770
808
  save_settings!
771
809
  end
772
810
 
811
+ # Creates a security group for the inception VM allowing SSH access & ICMP traffic
812
+ #
813
+ # Adds settings:
814
+ # * inception.security_group
815
+ def create_security_group_for_inception_vm
816
+
817
+ return if settings["inception"]["security_group"]
818
+
819
+ ports = {
820
+ ssh_access: 22,
821
+ ping: { protocol: "icmp", ports: (-1..-1) }
822
+ }
823
+ security_group_name = "#{settings.bosh_name}-inception-vm"
824
+
825
+ provider.create_security_group(security_group_name, "inception-vm", ports)
826
+
827
+ settings["inception"] ||= {}
828
+ settings["inception"]["security_group"] = security_group_name
829
+ save_settings!
830
+ end
831
+
773
832
  # Creates a key pair, and stores the private key in settings manifest.
774
833
  # Also sets up the bosh_cloud_properties for the remote server
775
834
  # to have the .pem key installed.
@@ -868,6 +927,7 @@ module Bosh::Bootstrap
868
927
  key_name = settings["inception"]["key_pair"]["name"]
869
928
  say "Provisioning #{size} for inception VM..."
870
929
  inception_vm_attributes = {
930
+ :groups => [settings["inception"]["security_group"]],
871
931
  :key_name => key_name,
872
932
  :private_key_path => inception_vm_private_key_path,
873
933
  :flavor_id => size,
@@ -979,15 +1039,18 @@ module Bosh::Bootstrap
979
1039
  server = fog_compute.servers.create(
980
1040
  :name => "Inception VM",
981
1041
  :key_name => key_name,
1042
+ :private_key_path => inception_vm_private_key_path,
982
1043
  :flavor_ref => inception_flavor.id,
983
1044
  :image_ref => inception_image.id,
1045
+ :security_groups => [settings["inception"]["security_group"]],
984
1046
  :username => username
985
1047
  )
1048
+ server.wait_for { ready? }
986
1049
  unless server
987
1050
  error "Something mysteriously cloudy happened and fog could not provision a VM. Please check your limits."
988
1051
  end
989
- server.wait_for { ready? }
990
1052
 
1053
+ settings["inception"].delete("create_new")
991
1054
  settings["inception"]["server_id"] = server.id
992
1055
  settings["inception"]["username"] = username
993
1056
  save_settings!
@@ -1008,17 +1071,14 @@ module Bosh::Bootstrap
1008
1071
  unless server.public_ip_address
1009
1072
  server.addresses["public"] = [settings["inception"]["ip_address"]]
1010
1073
  end
1011
- unless server.public_key_path
1012
- server.public_key_path = public_key_path
1013
- end
1014
1074
  unless server.private_key_path
1015
- server.private_key_path = private_key_path
1075
+ server.private_key_path = inception_vm_private_key_path
1016
1076
  end
1017
1077
  server.username = settings["inception"]["username"]
1018
1078
  Fog.wait_for(60) { server.sshable? }
1019
1079
 
1020
1080
  unless settings["inception"]["disk_size"]
1021
- disk_size = DEFAULT_INCEPTION_VOLUME_SIZE # Gb
1081
+ disk_size = prompt_for_disk_space("Inception VM", DEFAULT_INCEPTION_VOLUME_SIZE)
1022
1082
  device = "/dev/vdc"
1023
1083
  provision_and_mount_volume(server, disk_size, device)
1024
1084
 
@@ -1057,6 +1117,13 @@ module Bosh::Bootstrap
1057
1117
  server.reload
1058
1118
  end
1059
1119
 
1120
+ def prompt_for_disk_space(disk_for, default_size = nil)
1121
+ hl.ask("Size of disk for #{disk_for} (in Gb): ", Integer) do |q|
1122
+ q.default = default_size if default_size
1123
+ q.in = 1..1024
1124
+ end
1125
+ end
1126
+
1060
1127
  # Provision a volume for a specific device (unless already provisioned)
1061
1128
  # Request that the +server+ mount the volume at the +device+ location.
1062
1129
  #
@@ -1068,10 +1135,15 @@ module Bosh::Bootstrap
1068
1135
  end
1069
1136
 
1070
1137
  # Format and mount the volume
1071
- say "Mounting persistent disk as volume on inception VM..."
1072
- run_ssh_command_until_successful server, "sudo mkfs.ext4 #{device} -F"
1073
- run_ssh_command_until_successful server, "sudo mkdir -p /var/vcap/store"
1074
- run_ssh_command_until_successful server, "sudo mount #{device} /var/vcap/store"
1138
+ if aws?
1139
+ say "Skipping volume mounting on AWS 12.10 inception VM until its fixed", [:yellow, :bold]
1140
+ run_ssh_command_until_successful server, "sudo mkdir -p /var/vcap/store"
1141
+ else
1142
+ say "Mounting persistent disk as volume on inception VM..."
1143
+ run_ssh_command_until_successful server, "sudo mkfs.ext4 #{device} -F"
1144
+ run_ssh_command_until_successful server, "sudo mkdir -p /var/vcap/store"
1145
+ run_ssh_command_until_successful server, "sudo mount #{device} /var/vcap/store"
1146
+ end
1075
1147
  end
1076
1148
 
1077
1149
  def run_ssh_command_until_successful(server, cmd)
@@ -1130,7 +1202,8 @@ module Bosh::Bootstrap
1130
1202
  end
1131
1203
 
1132
1204
  def aws?
1133
- settings.fog_credentials.provider == "AWS"
1205
+ (settings["fog_credentials"] && settings["fog_credentials"]["provider"] == "AWS") ||
1206
+ (settings["bosh_provider"] == "aws")
1134
1207
  end
1135
1208
 
1136
1209
  def vpc?
@@ -1138,14 +1211,28 @@ module Bosh::Bootstrap
1138
1211
  end
1139
1212
 
1140
1213
  def openstack?
1141
- settings.fog_credentials.provider == "OpenStack"
1214
+ (settings["fog_credentials"] && settings["fog_credentials"]["provider"] == "OpenStack") ||
1215
+ (settings["bosh_provider"] == "openstack")
1142
1216
  end
1143
1217
 
1144
1218
  def prompt_for_bosh_credentials
1145
- prompt = hl
1146
1219
  say "Please enter a user/password for the BOSH that will be created."
1220
+ prompt = hl
1221
+ password_confirmation = nil
1147
1222
  settings[:bosh_username] = prompt.ask("BOSH username: ") { |q| q.default = `whoami`.strip }
1148
- settings[:bosh_password] = prompt.ask("BOSH password: ") { |q| q.echo = "x" }
1223
+ while password_confirmation.nil? || settings[:bosh_password] == "" || settings[:bosh_password] != password_confirmation
1224
+ settings[:bosh_password] = prompt.ask("BOSH password: ") { |q| q.echo = "x" }
1225
+ if settings[:bosh_password] == ""
1226
+ say "Please enter a password"
1227
+ next
1228
+ end
1229
+ password_confirmation = prompt.ask("Confirm BOSH password: ") { |q| q.echo = "x" }
1230
+ unless settings[:bosh_password] == password_confirmation
1231
+ say "Password do not match. Try Again"
1232
+ password_confirmation = nil
1233
+ end
1234
+ end
1235
+
1149
1236
  save_settings!
1150
1237
  end
1151
1238
 
@@ -1161,6 +1248,24 @@ module Bosh::Bootstrap
1161
1248
  "0.8.1"
1162
1249
  end
1163
1250
 
1251
+ def switch_to_prebuilt_microbosh_ami_if_available
1252
+ if ami = latest_prebuilt_microbosh_ami
1253
+ say "Switching to using prebuilt AMI for bonus speed!", :green
1254
+ settings["micro_bosh_stemcell_type"] = "ami"
1255
+ settings["micro_bosh_stemcell_name"] = ami
1256
+ save_settings!
1257
+ end
1258
+ end
1259
+
1260
+ # return the latest prebuilt microbosh AMI if it is available for target region
1261
+ def latest_prebuilt_microbosh_ami
1262
+ if aws? && settings["region_code"] == "us-east-1"
1263
+ Net::HTTP.get("#{AWS_JENKINS_BUCKET}.s3.amazonaws.com", "/last_successful_micro-bosh-stemcell_ami").strip
1264
+ else
1265
+ nil
1266
+ end
1267
+ end
1268
+
1164
1269
  def latest_micro_bosh_stemcell_name
1165
1270
  stemcell_filter_tags = ['micro', provider_name]
1166
1271
  if settings["micro_bosh_stemcell_type"] == "stable"
@@ -11,22 +11,25 @@ module Bosh::Bootstrap::Commander
11
11
  attr_reader :full_past_tense # e.g. "installed packages"
12
12
 
13
13
  # Optional:
14
- attr_reader :specific_run_as_user # e.g. ubuntu
14
+ attr_reader :ssh_username # e.g. ubuntu or vcap
15
+ attr_reader :run_as_root
15
16
  attr_reader :settings # settings manifest (result of script might get stored back)
16
17
  attr_reader :save_output_to_settings_key # e.g. bosh.salted_password
17
18
 
18
19
  def initialize(command, description, script, full_present_tense=nil, full_past_tense=nil, options={})
19
20
  super(command, description, full_present_tense, full_past_tense)
20
21
  @script = script
21
- @specific_run_as_user = options[:user]
22
+ @ssh_username = options[:ssh_username]
23
+ @run_as_root = options[:run_as_root]
22
24
  @settings = options[:settings]
23
25
  @save_output_to_settings_key = options[:save_output_to_settings_key]
24
26
  end
25
27
 
26
28
  # Invoke this command to call back upon +server.run_script+
27
29
  def perform(server)
28
- server.run_script(self, script, :user => specific_run_as_user,
29
- :settings => settings, :save_output_to_settings_key => save_output_to_settings_key)
30
+ server.run_script(self, script,
31
+ ssh_username: ssh_username, run_as_root: run_as_root,
32
+ settings: settings, save_output_to_settings_key: save_output_to_settings_key)
30
33
  end
31
34
 
32
35
  # Provide a filename that represents this Command
@@ -5,12 +5,12 @@ class Bosh::Bootstrap::Commander::RemoteServer
5
5
 
6
6
  attr_reader :host
7
7
  attr_reader :private_key_path
8
- attr_reader :default_username
8
+ attr_reader :default_ssh_username
9
9
  attr_reader :logfile
10
10
 
11
11
  def initialize(host, private_key_path, logfile=STDERR)
12
12
  @host, @private_key_path, @logfile = host, private_key_path, logfile
13
- @default_username = "vcap" # unless overridden by a Command (before vcap exists)
13
+ @default_ssh_username = "vcap" # unless overridden by a Command (before vcap exists)
14
14
  end
15
15
 
16
16
  # Execute the +Command+ objects, in sequential order
@@ -42,13 +42,14 @@ class Bosh::Bootstrap::Commander::RemoteServer
42
42
  # Stores the last line of stripped STDOUT/STDERR into a settings field,
43
43
  # if :settings & :save_output_to_settings_key => "x.y.z" provided
44
44
  def run_script(command, script, options={})
45
- run_as_user = options[:user] || default_username
45
+ ssh_username = options[:ssh_username] || default_ssh_username
46
+ run_as_root = options[:run_as_root]
46
47
  settings = options[:settings]
47
48
  settings_key = options[:save_output_to_settings_key]
48
49
 
49
50
  remote_path = remote_tmp_script_path(command)
50
- upload_file(command, remote_path, script, run_as_user)
51
- output, status = run_remote_script(remote_path, run_as_user)
51
+ upload_file(command, remote_path, script, ssh_username)
52
+ output, status = run_remote_script(remote_path, ssh_username, run_as_root)
52
53
  output =~ /^(.*)\Z/
53
54
  last_line = $1
54
55
  # store output into a settings field, if requested
@@ -70,8 +71,8 @@ class Bosh::Bootstrap::Commander::RemoteServer
70
71
  end
71
72
 
72
73
  # Upload a file (put a file into the remote server's filesystem)
73
- def upload_file(command, remote_path, contents, upload_as_user=nil)
74
- upload_as_user ||= default_username
74
+ def upload_file(command, remote_path, contents, ssh_username=nil)
75
+ upload_as_user = ssh_username || default_ssh_username
75
76
  run_remote_command("mkdir -p #{File.dirname(remote_path)}", upload_as_user)
76
77
  Tempfile.open("remote_script") do |file|
77
78
  file << contents
@@ -98,13 +99,14 @@ class Bosh::Bootstrap::Commander::RemoteServer
98
99
  # * status (true = success)
99
100
  #
100
101
  # TODO catch exceptions http://learnonthejob.blogspot.com/2010/08/exception-handling-for-netssh.html
101
- def run_remote_script(remote_path, username)
102
+ def run_remote_script(remote_path, ssh_username, run_as_root)
103
+ sudo = run_as_root ? "sudo " : ""
102
104
  commands = [
103
105
  "chmod +x #{remote_path}",
104
- "bash -lc 'sudo /usr/bin/env PATH=$PATH #{remote_path}'"
106
+ "bash -lc '#{sudo}/usr/bin/env PATH=$PATH #{remote_path}'"
105
107
  ]
106
108
  script_output = ""
107
- results = Fog::SSH.new(host, username, keys: private_keys).run(commands) do |stdout, stderr|
109
+ results = Fog::SSH.new(host, ssh_username, keys: private_keys).run(commands) do |stdout, stderr|
108
110
  [stdout, stderr].flatten.each do |data|
109
111
  logfile << data
110
112
  script_output << data
@@ -7,6 +7,7 @@
7
7
  # (thus /var/vcap/store/microboshes/deployments/$BOSH_NAME/micro_bosh.yml exists)
8
8
  # * $MICRO_BOSH_STEMCELL_NAME - public stemcell name at
9
9
  # /var/vcap/store/stemcells/$MICRO_BOSH_STEMCELL_NAME
10
+ # * $MICRO_BOSH_STEMCELL_TYPE - what type of stemcell (ami vs tgz)
10
11
 
11
12
  set -e # exit immediately if a simple command exits with a non-zero status
12
13
  set -u # report the usage of uninitialized variables
@@ -22,6 +23,9 @@ bosh -n micro deployment $BOSH_NAME
22
23
  if [[ "${MICRO_BOSH_STEMCELL_NAME}" == "custom" ]]; then
23
24
  MICRO_BOSH_STEMCELL_PATH=$(ls -t /var/tmp/bosh/bosh_agent-*/work/work/*.tgz | sort | tail -n 1)
24
25
  echo "Custom stemcell path $MICRO_BOSH_STEMCELL_PATH"
26
+ elif [[ "${MICRO_BOSH_STEMCELL_TYPE}" == "ami" ]]; then
27
+ echo "Using AMI ${MICRO_BOSH_STEMCELL_NAME}"
28
+ MICRO_BOSH_STEMCELL_PATH=${MICRO_BOSH_STEMCELL_NAME}
25
29
  else
26
30
  echo "Downloaded stemcell path $MICRO_BOSH_STEMCELL_PATH"
27
31
  fi
@@ -56,7 +60,7 @@ else
56
60
  # determine if re-deploy, update, or delete&deploy
57
61
 
58
62
  stemcell_cid=$(echo $deployment | jazor stemcell_cid)
59
- vm_cid=$(echo $deployment | jazor vm_id)
63
+ vm_cid=$(echo $deployment | jazor vm_cid)
60
64
  disk_cid=$(echo $deployment | jazor disk_cid)
61
65
 
62
66
  if [[ $stemcell_cid == "" && $vm_cid == "" && $disk_cid == "" ]]; then
@@ -5,6 +5,7 @@
5
5
  # Required:
6
6
  # * $MICRO_BOSH_STEMCELL_NAME - public stemcell name to be downloaded
7
7
  # - if 'custom' the create stemcell from BOSH source
8
+ # * $MICRO_BOSH_STEMCELL_TYPE - what type of stemcell (ami vs tgz)
8
9
  #
9
10
  # Optional:
10
11
  # * $PROVIDER - required for 'custom' $MICRO_BOSH_STEMCELL_NAME; e.g. aws, openstack
@@ -13,17 +14,13 @@
13
14
  set -e # exit immediately if a simple command exits with a non-zero status
14
15
  set -u # report the usage of uninitialized variables
15
16
 
16
- if [[ $EUID -ne 0 ]]; then
17
- echo "ERROR: This script must be run as root" 1>&2
18
- exit 1
19
- fi
20
-
21
17
  if [[ "${MICRO_BOSH_STEMCELL_NAME}X" == "X" ]]; then
22
18
  echo 'INTERNAL ERROR: Missing $MICRO_BOSH_STEMCELL_NAME environment variable'
23
19
  exit 1
24
20
  fi
25
21
 
26
22
  STEMCELLS_DIR=/var/vcap/store/stemcells
23
+ LAST_SUCCESSFUL_MICROBOSH_STEMCELL_URL=http://bosh-jenkins-artifacts.s3.amazonaws.com/last_successful_micro-bosh-stemcell.tgz
27
24
 
28
25
  if [[ "${MICRO_BOSH_STEMCELL_NAME}" == "custom" ]]; then
29
26
 
@@ -63,9 +60,18 @@ if [[ "${MICRO_BOSH_STEMCELL_NAME}" == "custom" ]]; then
63
60
 
64
61
  echo "Copying to stemcells folder..."
65
62
  MICRO_BOSH_STEMCELL_PATH=$(ls -t /var/tmp/bosh/bosh_agent-*/work/work/*.tgz | sort | tail -n 1)
66
- mv $MICRO_BOSH_STEMCELL_PATH $STEMCELLS_DIR
63
+ sudo mv $MICRO_BOSH_STEMCELL_PATH $STEMCELLS_DIR
64
+ sudo chown vcap:vcap -R $STEMCELLS_DIR
67
65
  MICRO_BOSH_STEMCELL_NAME=$(basename $MICRO_BOSH_STEMCELL_PATH)
68
66
 
67
+ elif [[ "${MICRO_BOSH_STEMCELL_TYPE}" == "edge-prebuilt" ]]; then
68
+ cd $STEMCELLS_DIR
69
+ curl -O $LAST_SUCCESSFUL_MICROBOSH_STEMCELL_URL
70
+ MICRO_BOSH_STEMCELL_NAME=$(basename $LAST_SUCCESSFUL_MICROBOSH_STEMCELL_URL)
71
+
72
+ elif [[ "${MICRO_BOSH_STEMCELL_TYPE}" == "ami" ]]; then
73
+ echo "Using AMI ${MICRO_BOSH_STEMCELL_NAME}, so there is nothing to download."
74
+
69
75
  elif [[ -f $STEMCELLS_DIR/$MICRO_BOSH_STEMCELL_NAME ]]; then
70
76
  echo "Stemcell $(pwd)/$MICRO_BOSH_STEMCELL_NAME already exists."
71
77
 
@@ -15,8 +15,10 @@ module Bosh::Bootstrap::Stages
15
15
  @commands ||= Bosh::Bootstrap::Commander::Commands.new do |server|
16
16
  server.download "micro-bosh stemcell", script("download_micro_bosh_stemcell",
17
17
  "MICRO_BOSH_STEMCELL_NAME" => settings.micro_bosh_stemcell_name,
18
+ "MICRO_BOSH_STEMCELL_TYPE" => settings.micro_bosh_stemcell_type,
18
19
  "PROVIDER" => settings.bosh_provider),
19
- :settings => settings, :save_output_to_settings_key => "micro_bosh_stemcell_name"
20
+ :settings => settings,
21
+ :save_output_to_settings_key => "micro_bosh_stemcell_name"
20
22
  server.upload_file \
21
23
  "/var/vcap/store/microboshes/deployments/#{settings.bosh_name}/micro_bosh.yml",
22
24
  micro_bosh_manifest
@@ -26,6 +28,7 @@ module Bosh::Bootstrap::Stages
26
28
  server.deploy "micro bosh", script("bosh_micro_deploy",
27
29
  "BOSH_NAME" => settings.bosh_name,
28
30
  "MICRO_BOSH_STEMCELL_NAME" => settings.micro_bosh_stemcell_name,
31
+ "MICRO_BOSH_STEMCELL_TYPE" => settings.micro_bosh_stemcell_type,
29
32
  "BOSH_HOST" => settings.bosh.ip_address,
30
33
  "BOSH_USERNAME" => settings.bosh_username,
31
34
  "BOSH_PASSWORD" => settings.bosh_password)
@@ -10,11 +10,6 @@
10
10
 
11
11
  set -e # exit immediately if a simple command exits with a non-zero status
12
12
 
13
- if [[ $EUID -ne 0 ]]; then
14
- echo "ERROR: This script must be run as root" 1>&2
15
- exit 1
16
- fi
17
-
18
13
  if [[ "${GIT_USER_NAME}X" == "X" ]]; then
19
14
  echo 'ERROR please provide $GIT_USER_NAME'
20
15
  exit 1
@@ -24,7 +19,7 @@ if [[ "${GIT_USER_EMAIL}X" == "X" ]]; then
24
19
  exit 1
25
20
  fi
26
21
 
27
- cd ~vcap
28
- chpst -u vcap:vcap git config -f ~vcap/.gitconfig user.name "${GIT_USER_NAME}"
29
- chpst -u vcap:vcap git config -f ~vcap/.gitconfig user.email "${GIT_USER_EMAIL}"
30
- chpst -u vcap:vcap git config -f ~vcap/.gitconfig color.ui true
22
+ cd ~
23
+ git config -f .gitconfig user.name "${GIT_USER_NAME}"
24
+ git config -f .gitconfig user.email "${GIT_USER_EMAIL}"
25
+ git config -f .gitconfig color.ui true
@@ -43,7 +43,7 @@ mkdir -p ${store_dir}
43
43
  chown vcap:vcap ${store_dir}
44
44
 
45
45
  # setup common folders used by bosh-bootstrap or bosh deployments
46
- for path in microboshes microboshes/deployments deployments releases repos stemcells tmp bosh_cache
46
+ for path in microboshes microboshes/deployments deployments releases repos stemcells inception tmp bosh_cache
47
47
  do
48
48
  echo "creating /var/vcap/store/${path}"
49
49
  mkdir -p ${store_dir}/${path}
@@ -8,13 +8,23 @@ fi
8
8
  set -e # exit immediately if a simple command exits with a non-zero status
9
9
 
10
10
  apt-get install python-software-properties
11
- add-apt-repository ppa:keithw/mosh
11
+ if [ "$(lsb_release --release --short)" == '10.04' ]; then
12
+ add-apt-repository ppa:keithw/mosh
13
+ else
14
+ add-apt-repository -y ppa:keithw/mosh
15
+ fi
12
16
 
13
17
  apt-get update
14
18
  apt-get install build-essential libsqlite3-dev curl rsync git-core \
15
19
  tmux mosh \
16
20
  libmysqlclient-dev libxml2-dev libxslt-dev libpq-dev libsqlite3-dev \
17
21
  runit \
18
- genisoimage mkpasswd \
22
+ genisoimage \
19
23
  debootstrap kpartx qemu-kvm \
20
24
  vim -y
25
+
26
+ if [ "$(lsb_release --release --short)" == '10.04' ]; then
27
+ apt-get install mkpasswd -y
28
+ else
29
+ apt-get install whois -y
30
+ fi