bosh-bootstrap 0.8.2 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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