bosh-bootstrap 0.5.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 (47) hide show
  1. data/.gitignore +18 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +318 -0
  5. data/Rakefile +1 -0
  6. data/bin/bosh-bootstrap +8 -0
  7. data/bosh-bootstrap.gemspec +34 -0
  8. data/lib/bosh-bootstrap.rb +10 -0
  9. data/lib/bosh-bootstrap/cli.rb +1024 -0
  10. data/lib/bosh-bootstrap/commander.rb +9 -0
  11. data/lib/bosh-bootstrap/commander/README.md +47 -0
  12. data/lib/bosh-bootstrap/commander/command.rb +25 -0
  13. data/lib/bosh-bootstrap/commander/commands.rb +80 -0
  14. data/lib/bosh-bootstrap/commander/local_server.rb +68 -0
  15. data/lib/bosh-bootstrap/commander/remote_script_command.rb +48 -0
  16. data/lib/bosh-bootstrap/commander/remote_server.rb +121 -0
  17. data/lib/bosh-bootstrap/commander/upload_command.rb +17 -0
  18. data/lib/bosh-bootstrap/helpers.rb +2 -0
  19. data/lib/bosh-bootstrap/helpers/fog_setup.rb +50 -0
  20. data/lib/bosh-bootstrap/helpers/settings.rb +36 -0
  21. data/lib/bosh-bootstrap/stages.rb +8 -0
  22. data/lib/bosh-bootstrap/stages/stage_micro_bosh_delete.rb +90 -0
  23. data/lib/bosh-bootstrap/stages/stage_micro_bosh_delete/bosh_micro_delete +19 -0
  24. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy.rb +135 -0
  25. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/bosh_micro_deploy +36 -0
  26. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/download_micro_bosh_stemcell +132 -0
  27. data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/install_key_pair_for_user +23 -0
  28. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm.rb +52 -0
  29. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/convert_salted_password +9 -0
  30. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/create_vcap_user +79 -0
  31. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_base_packages +13 -0
  32. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_bosh +54 -0
  33. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_ruby +33 -0
  34. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_useful_gems +24 -0
  35. data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/validate_bosh_deployer +21 -0
  36. data/lib/bosh-bootstrap/stages/stage_setup_new_bosh.rb +52 -0
  37. data/lib/bosh-bootstrap/stages/stage_setup_new_bosh/cleanup_permissions +14 -0
  38. data/lib/bosh-bootstrap/stages/stage_setup_new_bosh/setup_bosh_user +29 -0
  39. data/lib/bosh-bootstrap/stages/stage_validate_inception_vm.rb +39 -0
  40. data/lib/bosh-bootstrap/stages/stage_validate_inception_vm/validate_ubuntu +6 -0
  41. data/lib/bosh-bootstrap/version.rb +5 -0
  42. data/lib/bosh/providers.rb +21 -0
  43. data/lib/bosh/providers/README.md +5 -0
  44. data/lib/bosh/providers/aws.rb +77 -0
  45. data/lib/bosh/providers/base_provider.rb +20 -0
  46. data/lib/bosh/providers/openstack.rb +40 -0
  47. metadata +239 -0
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Creates a local /home/vcap/.ssh/$KEY_PAIR_NAME.pem file
4
+ # from the key pair private key ($PRIVATE_KEY)
5
+ #
6
+ # Requires:
7
+ # * ENV['KEY_PAIR_NAME']
8
+ # * ENV['PRIVATE_KEY']
9
+ #
10
+ # Optional:
11
+ # * ENV['TARGET_USER'] (default: vcap)
12
+
13
+ user = ENV['TARGET_USER'] || 'vcap'
14
+ key_pair_name = ENV['KEY_PAIR_NAME']
15
+ private_key = ENV['PRIVATE_KEY']
16
+
17
+ keyfile_path = "/home/#{user}/.ssh/#{key_pair_name}.pem"
18
+ split_private_key = private_key.split(/\n/)
19
+ File.open(keyfile_path, "w") do |f|
20
+ split_private_key.each {|line| f.puts line}
21
+ f.chmod 0600
22
+ end
23
+
@@ -0,0 +1,52 @@
1
+ module Bosh::Bootstrap::Stages
2
+ class StagePrepareInceptionVm
3
+ attr_reader :settings
4
+
5
+ def initialize(settings)
6
+ @settings = settings
7
+ end
8
+
9
+ def commands
10
+ @commands ||= Bosh::Bootstrap::Commander::Commands.new do |server|
11
+ # using inception VM username login, create a vcap user with same authorizations
12
+ server.create "vcap user", script("create_vcap_user", "ORIGUSER" => settings.inception.username),
13
+ :user => settings.inception.username
14
+ # install base Ubuntu packages used for bosh micro deployer
15
+ server.install "base packages", script("install_base_packages")
16
+ server.install "ruby 1.9.3", script("install_ruby", "UPGRADE" => settings[:upgrade_deps])
17
+ server.install "useful ruby gems", script("install_useful_gems", "UPGRADE" => settings[:upgrade_deps])
18
+ server.install "bosh", script("install_bosh",
19
+ "UPGRADE" => settings[:upgrade_deps],
20
+ "INSTALL_BOSH_FROM_SOURCE" => settings["bosh_git_source"] || "")
21
+ # use inception VM to generate a salted password (local machine may not have mkpasswd)
22
+ server.capture_value "salted password", script("convert_salted_password", "PASSWORD" => settings.bosh.password),
23
+ :settings => settings, :save_output_to_settings_key => "bosh.salted_password"
24
+ server.validate "bosh deployer", script("validate_bosh_deployer")
25
+ end
26
+ end
27
+
28
+ private
29
+ def stage_name
30
+ "stage_prepare_inception_vm"
31
+ end
32
+
33
+ # Loads local script
34
+ # If +variables+, then injects KEY=VALUE environment
35
+ # variables into bash scripts.
36
+ def script(segment_name, variables={})
37
+ path = File.expand_path("../#{stage_name}/#{segment_name}", __FILE__)
38
+ if File.exist?(path)
39
+ script = File.read(path)
40
+ if variables.keys.size > 0
41
+ inline_variables = "#!/usr/bin/env bash\n\n"
42
+ variables.each { |name, value| inline_variables << "#{name}=#{value}\n" }
43
+ script.gsub!("#!/usr/bin/env bash", inline_variables)
44
+ end
45
+ script
46
+ else
47
+ Thor::Base.shell.new.say_status "error", "Missing script lib/bosh-bootstrap/stages/#{stage_name}/#{segment_name}", :red
48
+ exit 1
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Convert $PASSWORD into a salted password
4
+ # and return via STDOUT
5
+ #
6
+ # Requires:
7
+ # * $PASSWORD
8
+
9
+ mkpasswd -m sha-512 $PASSWORD
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Create vcap user & public keys
4
+ # Re-use new public keys for root user
5
+ #
6
+ # Requires:
7
+ # * $ORIGUSER - another local user with authorized_keys for SSH access; will be copied to vcap user
8
+
9
+ if [[ $EUID -ne 0 ]]; then
10
+ echo "ERROR: This script must be run as root" 1>&2
11
+ exit 1
12
+ fi
13
+
14
+ groupadd vcap
15
+ useradd vcap -m --shell /bin/bash -g vcap
16
+ mkdir -p /home/vcap/.ssh
17
+ chown -R vcap:vcap /home/vcap/.ssh
18
+ chmod 700 /home/vcap/.ssh
19
+
20
+ if [[ -f /home/vcap/.ssh/id_rsa ]]
21
+ then
22
+ echo "public keys for vcap already exist, skipping..."
23
+ else
24
+ echo "creating public keys for vcap/root user..."
25
+ su -c "ssh-keygen -f ~/.ssh/id_rsa -N ''" vcap
26
+ fi
27
+
28
+ # Include same public keys for root user
29
+ echo "copy vcap public keys to root user..."
30
+ mkdir -p ~/.ssh/
31
+ cp ~vcap/.ssh/id_rsa* ~/.ssh/
32
+
33
+ bosh_app_dir=/var/vcap
34
+ mkdir -p ${bosh_app_dir}
35
+
36
+ # setup common folder for all folder/data
37
+ # this is what could/should be mounted as a separate persistent disk
38
+ # which is what is done for you if bosh-bootstrap creates the inception
39
+ # server for you.
40
+
41
+ store_dir=/var/vcap/store
42
+ mkdir -p ${store_dir}
43
+ chown vcap:vcap ${store_dir}
44
+
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
47
+ do
48
+ echo "creating /var/vcap/store/${path}"
49
+ mkdir -p ${store_dir}/${path}
50
+ chown vcap:vcap ${store_dir}/${path}
51
+ done
52
+
53
+ if [[ $(grep "vcap ALL=(ALL) NOPASSWD:ALL" /etc/sudoers) == "" ]]; then
54
+ echo "adding vcap to sudoers"
55
+ echo "vcap ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
56
+ fi
57
+
58
+ echo "copying user '$ORIGUSER' authorized_keys to vcap user"
59
+ cp /home/${ORIGUSER}/.ssh/authorized_keys ${bosh_app_dir}/
60
+ cp /home/${ORIGUSER}/.ssh/authorized_keys /home/vcap/.ssh/authorized_keys
61
+ chown vcap:vcap /home/vcap/.ssh/authorized_keys
62
+ echo "copying user '$ORIGUSER' .bashrc to vcap user"
63
+ cp /home/${ORIGUSER}/.bashrc /home/vcap/
64
+ chown vcap:vcap /home/vcap/.bashrc
65
+
66
+ if [[ $(grep "export TMPDIR" /home/vcap/.bashrc) == "" ]]; then
67
+ echo 'adding $TMPDIR to .bashrc'
68
+ echo "export TMPDIR=/var/vcap/store/tmp" >> /home/vcap/.bashrc
69
+ fi
70
+
71
+ if [[ $(grep "export EDITOR" /home/vcap/.bashrc) == "" ]]; then
72
+ echo 'setting $EDITOR to vim as default'
73
+ echo "export EDITOR=vim" >> /home/vcap/.bashrc
74
+ fi
75
+
76
+ if [[ ! -h /home/vcap/.bosh_cache ]]; then
77
+ rm -rf ~vcap/.bosh_cache/
78
+ ln -s /var/vcap/store/bosh_cache ~vcap/.bosh_cache
79
+ fi
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [[ $EUID -ne 0 ]]; then
4
+ echo "ERROR: This script must be run as root" 1>&2
5
+ exit 1
6
+ fi
7
+
8
+ apt-get update
9
+ apt-get install build-essential libsqlite3-dev curl rsync git-core tmux \
10
+ libmysqlclient-dev libxml2-dev libxslt-dev libpq-dev libsqlite3-dev \
11
+ genisoimage mkpasswd \
12
+ debootstrap kpartx qemu-kvm \
13
+ vim -y
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Install BOSH CLI
4
+ #
5
+ # Options:
6
+ # * $UPGRADE - re-install or upgrade gems if already installed
7
+ # * $INSTALL_BOSH_FROM_SOURCE - install from bosh git repo
8
+
9
+ if [[ $EUID -ne 0 ]]; then
10
+ echo "ERROR: This script must be run as root" 1>&2
11
+ exit 1
12
+ fi
13
+
14
+ # Install a gem if $UPGRADE exists or if gem not already installed
15
+ function install_gem() {
16
+ gem_name=$1
17
+ if [[ ("${UPGRADE}X" != "X") || "$(gem list $gem_name | grep $gem_name)X" == "X" ]]; then
18
+ gem install $gem_name --no-ri --no-rdoc
19
+ else
20
+ echo gem $gem_name already installed
21
+ fi
22
+ }
23
+
24
+ if [[ "${INSTALL_BOSH_FROM_SOURCE}X" != "X" ]]; then
25
+ mkdir -p /var/vcap/store/repos
26
+ cd /var/vcap/store/repos
27
+ if [[ -d bosh ]]; then
28
+ cd bosh
29
+ git pull origin master
30
+ else
31
+ git clone https://github.com/cloudfoundry/bosh.git
32
+ fi
33
+
34
+ bosh_dir=/var/vcap/store/repos/bosh
35
+ for project in common cli deployer aws_registry openstack_registry; do
36
+ cd $bosh_dir/$project/
37
+ rm -rf pkg
38
+ bundle install --without=development test
39
+ gem build *.gemspec
40
+ mkdir -p pkg
41
+ mv *.gem pkg/
42
+ gem install pkg/*.gem --no-ri --no-rdoc
43
+ done
44
+
45
+ else
46
+ install_gem bosh_cli
47
+ install_gem bosh_deployer
48
+ fi
49
+
50
+ if [[ ! -d /var/tmp/bosh ]]; then
51
+ echo "Symlinking the expected stemcell creation folder into mounted volume..."
52
+ mkdir -p /var/vcap/store/tmp/bosh
53
+ ln -s /var/vcap/store/tmp/bosh /var/tmp/bosh
54
+ fi
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Install ruby 1.9.3
4
+ #
5
+ # Options:
6
+ # * $RUBY_VERSION - override ruby version to test/install
7
+ # * $UPGRADE - re-install or upgrade ruby if already installed
8
+
9
+ if [[ $EUID -ne 0 ]]; then
10
+ echo "ERROR: This script must be run as root" 1>&2
11
+ exit 1
12
+ fi
13
+
14
+ DISTRIB_CODENAME=lucid
15
+
16
+ if [[ "$(which ruby)" == "" || "${UPGRADE}X" != "X" || ! ("$(ruby -v)" =~ "ruby 1.9.3") ]]; then
17
+ echo "Adding the Unboxed APT repository..."
18
+ echo "deb http://apt.unboxedconsulting.com/ $DISTRIB_CODENAME main" > /etc/apt/sources.list.d/unboxed.list
19
+
20
+ echo -e "\n Retrieving the PGP keys for the repository..."
21
+ wget -O - http://apt.unboxedconsulting.com/release.asc | apt-key add -
22
+
23
+ echo "Resynchronizing the package index files from their sources..."
24
+ apt-get update
25
+
26
+ echo -e "Installing Ruby 1.9.3...\n"
27
+ apt-get -y install ubxd-ruby1.9.3
28
+
29
+ echo -e "Upgrading to latest Rubygems..."
30
+ gem update --system
31
+ else
32
+ echo Ruby 1.9.3 already installed
33
+ fi
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Install bundler, fog, rake
4
+ #
5
+ # Options:
6
+ # * $UPGRADE - re-install or upgrade gems if already installed
7
+
8
+ if [[ $EUID -ne 0 ]]; then
9
+ echo "ERROR: This script must be run as root" 1>&2
10
+ exit 1
11
+ fi
12
+
13
+ # Install a gem if $UPGRADE exists or if gem not already installed
14
+ function install_gem() {
15
+ gem_name=$1
16
+ if [[ ("${UPGRADE}X" != "X") || "$(gem list $gem_name | grep $gem_name)X" == "X" ]]; then
17
+ gem install $gem_name --no-ri --no-rdoc
18
+ else
19
+ echo gem $gem_name already installed
20
+ fi
21
+ }
22
+
23
+ install_gem bundler
24
+ install_gem rake
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Validate that BOSH deployer is ready
4
+
5
+ if [[ $EUID -ne 0 ]]; then
6
+ echo "ERROR: This script must be run as root" 1>&2
7
+ exit 1
8
+ fi
9
+
10
+ echo "Testing for 'bosh micro deploy' command..."
11
+
12
+ bosh_output=$(bosh --no-color help micro)
13
+ if [[ "$(echo $bosh_output | grep 'micro deploy')" == "" ]]; then
14
+ echo "Failed to install 'bosh micro deploy'. Please investigate issue and report root cause so we can fix it."
15
+ echo "Output of 'bosh --no-color help micro':"
16
+ echo $bosh_output
17
+ exit 1
18
+ else
19
+ echo "Successfully installed bosh deployer (bosh micro deploy)"
20
+ exit 0
21
+ fi
@@ -0,0 +1,52 @@
1
+ require "json" # for inline hashes within YAML
2
+
3
+ module Bosh::Bootstrap::Stages
4
+ class SetupNewBosh
5
+ attr_reader :settings
6
+
7
+ def initialize(settings)
8
+ @settings = settings
9
+ end
10
+
11
+ def commands
12
+ @commands ||= Bosh::Bootstrap::Commander::Commands.new do |server|
13
+ server.setup "bosh user", script("setup_bosh_user",
14
+ "BOSH_NAME" => settings.bosh_name,
15
+ "BOSH_HOST" => settings.bosh.ip_address,
16
+ "BOSH_USERNAME" => settings.bosh_username,
17
+ "BOSH_PASSWORD" => settings.bosh_password)
18
+ server.cleanup "permissions", script("cleanup_permissions")
19
+ end
20
+ end
21
+
22
+ private
23
+ def stage_name
24
+ "stage_setup_new_bosh"
25
+ end
26
+
27
+ # Loads local script
28
+ # If +variables+, then injects KEY=VALUE environment
29
+ # variables into bash scripts.
30
+ def script(segment_name, variables={})
31
+ path = File.expand_path("../#{stage_name}/#{segment_name}", __FILE__)
32
+ if File.exist?(path)
33
+ script = File.read(path)
34
+ if variables.keys.size > 0
35
+ # inject variables into script if its bash script
36
+ inline_variables = "#!/usr/bin/env bash\n\n"
37
+ variables.each { |name, value| inline_variables << "#{name}='#{value}'\n" }
38
+ script.gsub!("#!/usr/bin/env bash", inline_variables)
39
+
40
+ # inject variables into script if its ruby script
41
+ inline_variables = "#!/usr/bin/env ruby\n\n"
42
+ variables.each { |name, value| inline_variables << "ENV['#{name}'] = '#{value}'\n" }
43
+ script.gsub!("#!/usr/bin/env ruby", inline_variables)
44
+ end
45
+ script
46
+ else
47
+ Thor::Base.shell.new.say_status "error", "Missing script lib/bosh-bootstrap/stages/#{stage_name}/#{segment_name}", :red
48
+ exit 1
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Cleanup file permissions
4
+
5
+ if [[ $EUID -ne 0 ]]; then
6
+ echo "ERROR: This script must be run as root" 1>&2
7
+ exit 1
8
+ fi
9
+
10
+ chown -R vcap:vcap ~vcap/.bosh*
11
+ if [[ -d ~vcap/.gem ]]; then
12
+ chown -R vcap:vcap ~vcap/.gem
13
+ fi
14
+ chown -R vcap:vcap /var/vcap/store/repos
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Deploys a micro BOSH using "bosh micro deploy"
4
+ #
5
+ # Required:
6
+ # * $BOSH_NAME - name of bosh deployment
7
+ # (thus /var/vcap/store/microboshes/deployments/$BOSH_NAME/micro_bosh.yml exists)
8
+ # * $BOSH_HOST - public IP of the deployed BOSH
9
+ # * $BOSH_USERNAME - user login to be created
10
+ # * $BOSH_PASSWORD - password for user login
11
+
12
+ set -e # exit immediately if a simple command exits with a non-zero status
13
+ set -u # report the usage of uninitialized variables
14
+
15
+ cd /var/vcap/store/microboshes/deployments/
16
+
17
+ if [[ -f $BOSH_NAME/new_bosh_deployed ]]; then
18
+ echo "Initially targeting micro-bosh..."
19
+ bosh -u admin -p admin target $BOSH_HOST
20
+
21
+ echo "Creating initial user $BOSH_USERNAME..."
22
+ bosh login admin admin
23
+ bosh create user $BOSH_USERNAME $BOSH_PASSWORD
24
+
25
+ rm -f $BOSH_NAME/new_bosh_deployed
26
+ fi
27
+
28
+ echo "Login as $BOSH_USERNAME..."
29
+ bosh login $BOSH_USERNAME $BOSH_PASSWORD
@@ -0,0 +1,39 @@
1
+ module Bosh::Bootstrap::Stages
2
+ class StageValidateInceptionVm
3
+ attr_reader :settings
4
+
5
+ def initialize(settings)
6
+ @settings = settings
7
+ end
8
+
9
+ def commands
10
+ @commands ||= Bosh::Bootstrap::Commander::Commands.new do |server|
11
+ server.validate "ubuntu", script("validate_ubuntu"), :user => settings.inception.username
12
+ end
13
+ end
14
+
15
+ private
16
+ def stage_name
17
+ "stage_validate_inception_vm"
18
+ end
19
+
20
+ # Loads local script
21
+ # If +variables+, then injects KEY=VALUE environment
22
+ # variables into bash scripts.
23
+ def script(segment_name, variables={})
24
+ path = File.expand_path("../#{stage_name}/#{segment_name}", __FILE__)
25
+ if File.exist?(path)
26
+ script = File.read(path)
27
+ if variables.keys.size > 0
28
+ inline_variables = "#!/usr/bin/env bash\n\n"
29
+ variables.each { |name, value| inline_variables << "#{name}=#{value}\n" }
30
+ script.gsub!("#!/usr/bin/env bash", inline_variables)
31
+ end
32
+ script
33
+ else
34
+ Thor::Base.shell.new.say_status "error", "Missing script lib/bosh-bootstrap/stages/#{stage_name}/#{segment_name}", :red
35
+ exit 1
36
+ end
37
+ end
38
+ end
39
+ end