bosh-bootstrap 0.5.0

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