bosh-bootstrap 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/.travis.yml +0 -1
- data/ChangeLog.md +23 -4
- data/Gemfile +5 -2
- data/Guardfile +2 -0
- data/README.md +209 -197
- data/TODO.md +55 -0
- data/bosh-bootstrap.gemspec +5 -12
- data/lib/bosh/cli/commands/bootstrap.rb +42 -0
- data/lib/bosh-bootstrap/cli/commands/delete.rb +26 -0
- data/lib/bosh-bootstrap/cli/commands/deploy.rb +89 -0
- data/lib/bosh-bootstrap/cli/commands/ssh.rb +32 -0
- data/lib/bosh-bootstrap/cli/helpers/bundle.rb +12 -0
- data/lib/bosh-bootstrap/cli/helpers/interactions.rb +15 -0
- data/lib/bosh-bootstrap/cli/helpers/settings.rb +61 -0
- data/lib/bosh-bootstrap/cli/helpers.rb +11 -0
- data/lib/bosh-bootstrap/key_pair.rb +21 -0
- data/lib/bosh-bootstrap/microbosh.rb +74 -0
- data/lib/bosh-bootstrap/microbosh_providers/aws.rb +104 -0
- data/lib/bosh-bootstrap/microbosh_providers/base.rb +50 -0
- data/lib/bosh-bootstrap/microbosh_providers/openstack.rb +61 -0
- data/lib/bosh-bootstrap/microbosh_providers/vsphere.rb +78 -0
- data/lib/bosh-bootstrap/microbosh_providers.rb +11 -0
- data/lib/bosh-bootstrap/network.rb +33 -0
- data/lib/bosh-bootstrap/network_providers/aws.rb +28 -0
- data/lib/bosh-bootstrap/network_providers/dummy.rb +10 -0
- data/lib/bosh-bootstrap/network_providers/openstack.rb +28 -0
- data/lib/bosh-bootstrap/network_providers.rb +11 -0
- data/lib/bosh-bootstrap/version.rb +1 -1
- data/lib/bosh-bootstrap.rb +3 -4
- data/spec/assets/microbosh_yml/micro_bosh.aws_ec2.yml +37 -0
- data/spec/assets/microbosh_yml/micro_bosh.aws_vpc.yml +39 -0
- data/spec/assets/microbosh_yml/micro_bosh.openstack.yml +30 -0
- data/spec/assets/microbosh_yml/micro_bosh.vsphere.yml +34 -0
- data/spec/integration/aws/aws_ec2_basic_spec.rb +39 -0
- data/spec/integration/aws/aws_helpers.rb +8 -61
- data/spec/spec_helper.rb +8 -3
- data/spec/support/capture_stdout.rb +18 -0
- data/spec/unit/cli/bootstrap_spec.rb +41 -0
- data/spec/unit/commands/delete_spec.rb +20 -0
- data/spec/unit/commands/deploy_spec.rb +64 -0
- data/spec/unit/commands/ssh_spec.rb +19 -0
- data/spec/unit/key_pair_spec.rb +13 -0
- data/spec/unit/microbosh_providers/aws_spec.rb +68 -0
- data/spec/unit/microbosh_providers/openstack_spec.rb +27 -0
- data/spec/unit/microbosh_providers/vsphere_spec.rb +42 -0
- data/spec/unit/microbosh_spec.rb +27 -0
- data/spec/unit/network_providers/aws_spec.rb +29 -0
- data/spec/unit/network_providers/openstack_spec.rb +29 -0
- data/spec/unit/network_spec.rb +17 -0
- metadata +71 -235
- data/CleanupCi.md +0 -8
- data/bin/bosh-bootstrap +0 -8
- data/docs/README.md +0 -3
- data/docs/devstack-openstack-tutorial.md +0 -215
- data/lib/bosh/providers/README.md +0 -5
- data/lib/bosh/providers/aws.rb +0 -258
- data/lib/bosh/providers/base_provider.rb +0 -48
- data/lib/bosh/providers/openstack.rb +0 -79
- data/lib/bosh/providers.rb +0 -21
- data/lib/bosh-bootstrap/cli.rb +0 -1347
- data/lib/bosh-bootstrap/commander/README.md +0 -47
- data/lib/bosh-bootstrap/commander/command.rb +0 -25
- data/lib/bosh-bootstrap/commander/commands.rb +0 -80
- data/lib/bosh-bootstrap/commander/local_server.rb +0 -68
- data/lib/bosh-bootstrap/commander/remote_script_command.rb +0 -51
- data/lib/bosh-bootstrap/commander/remote_server.rb +0 -137
- data/lib/bosh-bootstrap/commander/upload_command.rb +0 -17
- data/lib/bosh-bootstrap/commander.rb +0 -9
- data/lib/bosh-bootstrap/helpers/fog_setup.rb +0 -50
- data/lib/bosh-bootstrap/helpers/settings.rb +0 -99
- data/lib/bosh-bootstrap/helpers/settings_setter.rb +0 -41
- data/lib/bosh-bootstrap/helpers.rb +0 -3
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_delete/bosh_micro_delete +0 -19
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_delete.rb +0 -90
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/bosh_micro_deploy +0 -79
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy/install_key_pair_for_user +0 -23
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_deploy.rb +0 -146
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_download/download_micro_bosh_stemcell +0 -93
- data/lib/bosh-bootstrap/stages/stage_micro_bosh_download.rb +0 -139
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/configure_git +0 -25
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/create_vcap_user +0 -79
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_base_packages +0 -30
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_bosh +0 -11
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_bosh_plugins +0 -25
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_hub +0 -26
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_ruby +0 -30
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/install_useful_gems +0 -29
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm/validate_bosh_deployer +0 -18
- data/lib/bosh-bootstrap/stages/stage_prepare_inception_vm.rb +0 -69
- data/lib/bosh-bootstrap/stages/stage_salted_password/convert_salted_password +0 -11
- data/lib/bosh-bootstrap/stages/stage_salted_password.rb +0 -51
- data/lib/bosh-bootstrap/stages/stage_setup_new_bosh/setup_bosh_user +0 -29
- data/lib/bosh-bootstrap/stages/stage_setup_new_bosh.rb +0 -51
- data/lib/bosh-bootstrap/stages/stage_validate_inception_vm/validate_ubuntu +0 -6
- data/lib/bosh-bootstrap/stages/stage_validate_inception_vm.rb +0 -39
- data/lib/bosh-bootstrap/stages.rb +0 -10
- data/spec/assets/bosh/public_stemcells/aws_micro.out +0 -7
- data/spec/assets/micro_bosh_yml/micro_bosh.aws_ec2.yml +0 -35
- data/spec/assets/micro_bosh_yml/micro_bosh.aws_vpc.yml +0 -37
- data/spec/integration/aws/aws_basic_spec.rb +0 -39
- data/spec/integration/aws/aws_edge_prebuilt_ami_spec.rb +0 -46
- data/spec/integration/aws/aws_edge_prebuilt_spec.rb +0 -46
- data/spec/integration/aws/aws_edge_spec.rb +0 -45
- data/spec/unit/aws_spec.rb +0 -177
- data/spec/unit/bosh/providers/aws_spec.rb +0 -174
- data/spec/unit/cli_spec.rb +0 -134
- data/spec/unit/cli_ssh_spec.rb +0 -95
- data/spec/unit/cli_upgrade_inception_spec.rb +0 -29
- data/spec/unit/settings_setter_spec.rb +0 -29
- data/vendor/cache/POpen4-0.1.4.gem +0 -0
- data/vendor/cache/Platform-0.4.0.gem +0 -0
- data/vendor/cache/activesupport-3.2.8.gem +0 -0
- data/vendor/cache/awesome_print-1.1.0.gem +0 -0
- data/vendor/cache/aws-s3-0.6.3.gem +0 -0
- data/vendor/cache/blobstore_client-0.4.0.gem +0 -0
- data/vendor/cache/bosh_cli-1.0.3.gem +0 -0
- data/vendor/cache/bosh_common-0.5.4.gem +0 -0
- data/vendor/cache/builder-3.2.0.gem +0 -0
- data/vendor/cache/coderay-1.0.8.gem +0 -0
- data/vendor/cache/diff-lcs-1.1.3.gem +0 -0
- data/vendor/cache/escape-0.0.4.gem +0 -0
- data/vendor/cache/excon-0.20.1.gem +0 -0
- data/vendor/cache/fog-1.8.0.gem +0 -0
- data/vendor/cache/formatador-0.2.4.gem +0 -0
- data/vendor/cache/guard-1.6.2.gem +0 -0
- data/vendor/cache/guard-rspec-2.4.0.gem +0 -0
- data/vendor/cache/highline-1.6.18.gem +0 -0
- data/vendor/cache/httpclient-2.2.4.gem +0 -0
- data/vendor/cache/i18n-0.6.1.gem +0 -0
- data/vendor/cache/json_pure-1.6.8.gem +0 -0
- data/vendor/cache/listen-0.7.2.gem +0 -0
- data/vendor/cache/log4r-1.1.10.gem +0 -0
- data/vendor/cache/lumberjack-1.0.2.gem +0 -0
- data/vendor/cache/method_source-0.8.1.gem +0 -0
- data/vendor/cache/mime-types-1.22.gem +0 -0
- data/vendor/cache/multi_json-1.1.0.gem +0 -0
- data/vendor/cache/net-scp-1.0.4.gem +0 -0
- data/vendor/cache/net-ssh-2.2.2.gem +0 -0
- data/vendor/cache/net-ssh-gateway-1.1.0.gem +0 -0
- data/vendor/cache/netaddr-1.5.0.gem +0 -0
- data/vendor/cache/nokogiri-1.5.9.gem +0 -0
- data/vendor/cache/open4-1.3.0.gem +0 -0
- data/vendor/cache/progressbar-0.9.2.gem +0 -0
- data/vendor/cache/pry-0.9.11.4-java.gem +0 -0
- data/vendor/cache/pry-0.9.11.4.gem +0 -0
- data/vendor/cache/rake-10.0.3.gem +0 -0
- data/vendor/cache/rb-fsevent-0.9.3.gem +0 -0
- data/vendor/cache/redcard-1.0.0.gem +0 -0
- data/vendor/cache/rspec-2.12.0.gem +0 -0
- data/vendor/cache/rspec-core-2.12.2.gem +0 -0
- data/vendor/cache/rspec-expectations-2.12.1.gem +0 -0
- data/vendor/cache/rspec-mocks-2.12.2.gem +0 -0
- data/vendor/cache/ruby-atmos-pure-1.0.5.gem +0 -0
- data/vendor/cache/ruby-hmac-0.4.0.gem +0 -0
- data/vendor/cache/settingslogic-2.0.9.gem +0 -0
- data/vendor/cache/slop-3.4.3.gem +0 -0
- data/vendor/cache/spoon-0.0.1.gem +0 -0
- data/vendor/cache/terminal-table-1.4.5.gem +0 -0
- data/vendor/cache/thor-0.17.0.gem +0 -0
- data/vendor/cache/uuidtools-2.1.3.gem +0 -0
- data/vendor/cache/xml-simple-1.1.2.gem +0 -0
@@ -1,47 +0,0 @@
|
|
1
|
-
# Bosh::Bootstrap::Commander
|
2
|
-
|
3
|
-
The sequence of commands that are run on an Inception VM can be either invoked locally on the Inception VM or from a remote machine. The `Commander` provides a DSL for describing the commands to be run and allows them to be sequentially run against a local or remote server.
|
4
|
-
|
5
|
-
Remote servers are accessed via SSH commands.
|
6
|
-
|
7
|
-
Example commands:
|
8
|
-
``` ruby
|
9
|
-
commands = Bosh::Bootstrap::Commander::Commands.new do |server|
|
10
|
-
server.create "vcap user", <<-BASH
|
11
|
-
#!/usr/bin/env bash
|
12
|
-
|
13
|
-
groupadd vcap
|
14
|
-
useradd vcap -m -g vcap
|
15
|
-
mkdir -p /home/vcap/.ssh
|
16
|
-
chown -R vcap:vcap /home/vcap/.ssh
|
17
|
-
BASH
|
18
|
-
|
19
|
-
server.install "rvm & ruby", <<-BASH
|
20
|
-
#!/usr/bin/env bash
|
21
|
-
|
22
|
-
if [[ -x rvm ]]
|
23
|
-
then
|
24
|
-
rvm get stable
|
25
|
-
else
|
26
|
-
curl -L get.rvm.io | bash -s stable
|
27
|
-
source /etc/profile.d/rvm.sh
|
28
|
-
fi
|
29
|
-
command rvm install 1.9.3 # oh god this takes a long time
|
30
|
-
rvm 1.9.3
|
31
|
-
rvm alias create default 1.9.3
|
32
|
-
BASH
|
33
|
-
end
|
34
|
-
|
35
|
-
@local_machine.run(commands)
|
36
|
-
@server.run(commands)
|
37
|
-
```
|
38
|
-
|
39
|
-
There is a set of predefined command methods which give nicer text output. You can also invoke any method upon `server` and it will be supported as the command name. The name of the method invoked is semantically meaningless; it is a convenience.
|
40
|
-
|
41
|
-
* `assign`
|
42
|
-
* `create`
|
43
|
-
* `download`
|
44
|
-
* `install`
|
45
|
-
* `provision`
|
46
|
-
* `store`
|
47
|
-
* `validate`
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# A single command/script to be run on a local/remote server
|
2
|
-
# For the display, it has an active ("installing") and
|
3
|
-
# past tense ("installed") verb and a noub/description ("packages")
|
4
|
-
module Bosh::Bootstrap::Commander
|
5
|
-
class Command
|
6
|
-
attr_reader :command # verb e.g. "install"
|
7
|
-
attr_reader :description # noun phrase, e.g. "packages"
|
8
|
-
|
9
|
-
attr_reader :full_present_tense # e.g. "installing packages"
|
10
|
-
attr_reader :full_past_tense # e.g. "installed packages"
|
11
|
-
|
12
|
-
def initialize(command, description, full_present_tense=nil, full_past_tense=nil)
|
13
|
-
@command = command
|
14
|
-
@description = description
|
15
|
-
@full_present_tense = full_present_tense || "#{command} #{description}"
|
16
|
-
@full_past_tense = full_past_tense || "#{command} #{description}"
|
17
|
-
end
|
18
|
-
|
19
|
-
# Invoke this command (subclass) to call back upon
|
20
|
-
# +server+ to perform a server helper
|
21
|
-
def perform(server)
|
22
|
-
raise "please implement this method to call back upon `server`"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
module Bosh::Bootstrap::Commander
|
2
|
-
class Commands
|
3
|
-
attr_reader :commands
|
4
|
-
|
5
|
-
def initialize(&block)
|
6
|
-
@commands = []
|
7
|
-
yield self
|
8
|
-
end
|
9
|
-
|
10
|
-
def upload_file(target_path, file_contents)
|
11
|
-
@commands << UploadCommand.new(target_path, file_contents)
|
12
|
-
end
|
13
|
-
|
14
|
-
#
|
15
|
-
# Generic remote script commands with custom phrases
|
16
|
-
#
|
17
|
-
|
18
|
-
def assign(description, script, options={})
|
19
|
-
@commands << RemoteScriptCommand.new(
|
20
|
-
"assign", description, script,
|
21
|
-
"assigning #{description}", "assigned #{description}", options)
|
22
|
-
end
|
23
|
-
|
24
|
-
# Runs a script on target server, and stores the (stripped) STDOUT into
|
25
|
-
# settings.
|
26
|
-
#
|
27
|
-
# Usage:
|
28
|
-
# server.capture_value "salted password", script("convert_salted_password", "PASSWORD" => settings.bosh.password),
|
29
|
-
# :settings => "bosh.salted_password"
|
30
|
-
#
|
31
|
-
# Would store the returned STDOUT into settings[:bosh][:salted_password]
|
32
|
-
def capture_value(description, script, options)
|
33
|
-
@commands << RemoteScriptCommand.new(
|
34
|
-
"capture value", description, script,
|
35
|
-
"captures value of #{description}", "captured value of #{description}", options)
|
36
|
-
end
|
37
|
-
|
38
|
-
def create(description, script, options={})
|
39
|
-
@commands << RemoteScriptCommand.new(
|
40
|
-
"create", description, script,
|
41
|
-
"creating #{description}", "created #{description}", options)
|
42
|
-
end
|
43
|
-
|
44
|
-
def download(description, script, options={})
|
45
|
-
@commands << RemoteScriptCommand.new(
|
46
|
-
"download", description, script,
|
47
|
-
"downloading #{description}", "downloaded #{description}", options)
|
48
|
-
end
|
49
|
-
|
50
|
-
def install(description, script, options={})
|
51
|
-
@commands << RemoteScriptCommand.new(
|
52
|
-
"install", description, script,
|
53
|
-
"installing #{description}", "installed #{description}", options)
|
54
|
-
end
|
55
|
-
|
56
|
-
def provision(description, script, options={})
|
57
|
-
@commands << RemoteScriptCommand.new(
|
58
|
-
"provision", description, script,
|
59
|
-
"provisioning #{description}", "provisioned #{description}", options)
|
60
|
-
end
|
61
|
-
|
62
|
-
def store(description, script, options={})
|
63
|
-
@commands << RemoteScriptCommand.new(
|
64
|
-
"store", description, script,
|
65
|
-
"storing #{description}", "stored #{description}", options)
|
66
|
-
end
|
67
|
-
|
68
|
-
def validate(description, script, options={})
|
69
|
-
@commands << RemoteScriptCommand.new(
|
70
|
-
"validate", description, script,
|
71
|
-
"validating #{description}", "validated #{description}", options)
|
72
|
-
end
|
73
|
-
|
74
|
-
# catch-all for commands with generic active/past tense phrases
|
75
|
-
def method_missing(command, *args, &blk)
|
76
|
-
description, script = args[0..1]
|
77
|
-
@commands << RemoteScriptCommand.new(command.to_s, description, script)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
require "popen4"
|
2
|
-
|
3
|
-
class Bosh::Bootstrap::Commander::LocalServer
|
4
|
-
attr_reader :logfile
|
5
|
-
|
6
|
-
def initialize(logfile=STDERR)
|
7
|
-
@logfile = logfile
|
8
|
-
end
|
9
|
-
|
10
|
-
# Execute the +Command+ objects, in sequential order
|
11
|
-
# upon the local server
|
12
|
-
# +commands+ is a +Commands+ container
|
13
|
-
#
|
14
|
-
# Returns false once any subcommand fails to execute successfully
|
15
|
-
def run(commands)
|
16
|
-
commands.commands.each do |command|
|
17
|
-
puts command.full_present_tense
|
18
|
-
if command.perform(self)
|
19
|
-
Thor::Base.shell.new.say "Successfully #{command.full_past_tense}", :green
|
20
|
-
else
|
21
|
-
Thor::Base.shell.new.say_status "error", "#{command.full_present_tense}", :red
|
22
|
-
return false
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
#
|
28
|
-
# Commands performed on local server
|
29
|
-
# These map to Command subclasses, which then callback to these
|
30
|
-
# local server specific implementations
|
31
|
-
#
|
32
|
-
|
33
|
-
# Run a script
|
34
|
-
def run_script(command, script, options={})
|
35
|
-
command.as_file do |execution_command|
|
36
|
-
`chmod +x #{execution_command}`
|
37
|
-
status = POpen4::popen4(execution_command) do |stdout, stderr, stdin, pid|
|
38
|
-
out = stdout.read
|
39
|
-
logfile.puts out unless out.strip == ""
|
40
|
-
err = stderr.read
|
41
|
-
if err.strip != ""
|
42
|
-
logfile.puts err
|
43
|
-
STDERR.puts err if logfile != STDERR
|
44
|
-
end
|
45
|
-
logfile.flush
|
46
|
-
end
|
47
|
-
status.success?
|
48
|
-
end
|
49
|
-
rescue StandardError => e
|
50
|
-
logfile.puts e.message
|
51
|
-
false
|
52
|
-
end
|
53
|
-
|
54
|
-
# Upload a file (put a file into local filesystem)
|
55
|
-
def upload_file(command, path, contents, upload_as_user=nil)
|
56
|
-
basedir = File.dirname(path)
|
57
|
-
unless File.directory?(basedir)
|
58
|
-
logfile.puts "creating micro-bosh manifest folder: #{basedir}"
|
59
|
-
FileUtils.mkdir_p(basedir)
|
60
|
-
end
|
61
|
-
logfile.puts "creating micro-bosh manifest: #{path}"
|
62
|
-
File.open(path, "w") { |file| file << contents }
|
63
|
-
true
|
64
|
-
rescue StandardError => e
|
65
|
-
logfile.puts e.message
|
66
|
-
false
|
67
|
-
end
|
68
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
# A single command/script to be run on a local/remote server
|
2
|
-
# For the display, it has an active ("installing") and
|
3
|
-
# past tense ("installed") verb and a noub/description ("packages")
|
4
|
-
module Bosh::Bootstrap::Commander
|
5
|
-
class RemoteScriptCommand < Command
|
6
|
-
attr_reader :command # verb e.g. "install"
|
7
|
-
attr_reader :description # noun phrase, e.g. "packages"
|
8
|
-
attr_reader :script
|
9
|
-
|
10
|
-
attr_reader :full_present_tense # e.g. "installing packages"
|
11
|
-
attr_reader :full_past_tense # e.g. "installed packages"
|
12
|
-
|
13
|
-
# Optional:
|
14
|
-
attr_reader :ssh_username # e.g. ubuntu or vcap
|
15
|
-
attr_reader :run_as_root
|
16
|
-
attr_reader :settings # settings manifest (result of script might get stored back)
|
17
|
-
attr_reader :save_output_to_settings_key # e.g. bosh.salted_password
|
18
|
-
|
19
|
-
def initialize(command, description, script, full_present_tense=nil, full_past_tense=nil, options={})
|
20
|
-
super(command, description, full_present_tense, full_past_tense)
|
21
|
-
@script = script
|
22
|
-
@ssh_username = options[:ssh_username]
|
23
|
-
@run_as_root = options[:run_as_root]
|
24
|
-
@settings = options[:settings]
|
25
|
-
@save_output_to_settings_key = options[:save_output_to_settings_key]
|
26
|
-
end
|
27
|
-
|
28
|
-
# Invoke this command to call back upon +server.run_script+
|
29
|
-
def perform(server)
|
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)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Provide a filename that represents this Command
|
36
|
-
def to_filename
|
37
|
-
@to_filename ||= "#{command} #{description}".gsub(/\W+/, '_')
|
38
|
-
end
|
39
|
-
|
40
|
-
# Stores the script on the local filesystem in a temporary directory
|
41
|
-
# Returns path
|
42
|
-
def as_file(&block)
|
43
|
-
tmpdir = ENV['TMPDIR'] || "/tmp"
|
44
|
-
script_path = File.join(tmpdir, to_filename)
|
45
|
-
File.open(script_path, "w") do |f|
|
46
|
-
f << @script
|
47
|
-
end
|
48
|
-
yield script_path
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
require "net/scp"
|
2
|
-
require "tempfile"
|
3
|
-
|
4
|
-
class Bosh::Bootstrap::Commander::RemoteServer
|
5
|
-
|
6
|
-
attr_reader :host
|
7
|
-
attr_reader :private_key_path
|
8
|
-
attr_reader :default_ssh_username
|
9
|
-
attr_reader :logfile
|
10
|
-
|
11
|
-
def initialize(host, private_key_path, logfile=STDERR)
|
12
|
-
@host, @private_key_path, @logfile = host, private_key_path, logfile
|
13
|
-
@default_ssh_username = "vcap" # unless overridden by a Command (before vcap exists)
|
14
|
-
end
|
15
|
-
|
16
|
-
# Execute the +Command+ objects, in sequential order
|
17
|
-
# upon the local server
|
18
|
-
# +commands+ is a +Commands+ container
|
19
|
-
#
|
20
|
-
# Returns false once any subcommand fails to execute successfully
|
21
|
-
def run(commands)
|
22
|
-
commands.commands.each do |command|
|
23
|
-
puts command.full_present_tense
|
24
|
-
if command.perform(self)
|
25
|
-
Thor::Base.shell.new.say "Successfully #{command.full_past_tense}", :green
|
26
|
-
else
|
27
|
-
Thor::Base.shell.new.say_status "error", "#{command.full_present_tense}", :red
|
28
|
-
return false
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
#
|
34
|
-
# Commands performed on remote server
|
35
|
-
# These map to Command subclasses, which then callback to these
|
36
|
-
# remote server specific implementations
|
37
|
-
#
|
38
|
-
|
39
|
-
# Run a script
|
40
|
-
#
|
41
|
-
# Uploads it to the remote server, makes it executable, then executes
|
42
|
-
# Stores the last line of stripped STDOUT/STDERR into a settings field,
|
43
|
-
# if :settings & :save_output_to_settings_key => "x.y.z" provided
|
44
|
-
def run_script(command, script, options={})
|
45
|
-
ssh_username = options[:ssh_username] || default_ssh_username
|
46
|
-
run_as_root = options[:run_as_root]
|
47
|
-
settings = options[:settings]
|
48
|
-
settings_key = options[:save_output_to_settings_key]
|
49
|
-
|
50
|
-
remote_path = remote_tmp_script_path(command)
|
51
|
-
upload_file(command, remote_path, script, ssh_username)
|
52
|
-
output, status = run_remote_script(remote_path, ssh_username, run_as_root)
|
53
|
-
output =~ /^(.*)\Z/
|
54
|
-
last_line = $1
|
55
|
-
# store output into a settings field, if requested
|
56
|
-
# TODO replace this with SettingsSetting#setting(settings_key, last_line.strip)
|
57
|
-
|
58
|
-
puts "Last line of script: #{last_line}"
|
59
|
-
puts "Storing to settings_key #{settings_key}" if settings_key
|
60
|
-
if settings_key
|
61
|
-
settings_key_portions = settings_key.split(".")
|
62
|
-
parent_key_portions, final_key = settings_key_portions[0..-2], settings_key_portions[-1]
|
63
|
-
target_settings_field = settings
|
64
|
-
parent_key_portions.each do |key_portion|
|
65
|
-
target_settings_field[key_portion] ||= {}
|
66
|
-
target_settings_field = target_settings_field[key_portion]
|
67
|
-
end
|
68
|
-
target_settings_field[final_key] = last_line.strip
|
69
|
-
end
|
70
|
-
|
71
|
-
status
|
72
|
-
rescue StandardError => e
|
73
|
-
logfile.puts e.message
|
74
|
-
false
|
75
|
-
end
|
76
|
-
|
77
|
-
# Upload a file (put a file into the remote server's filesystem)
|
78
|
-
def upload_file(command, remote_path, contents, ssh_username=nil)
|
79
|
-
upload_as_user = ssh_username || default_ssh_username
|
80
|
-
run_remote_command("mkdir -p #{File.dirname(remote_path)}", upload_as_user)
|
81
|
-
Tempfile.open("remote_script") do |file|
|
82
|
-
file << contents
|
83
|
-
file.flush
|
84
|
-
logfile.puts "uploading #{remote_path} to Inception VM"
|
85
|
-
Net::SCP.upload!(host, upload_as_user, file.path, remote_path, ssh: { keys: private_keys })
|
86
|
-
end
|
87
|
-
true
|
88
|
-
rescue StandardError => e
|
89
|
-
logfile.puts "ERROR running upload_file(#{command.class}, '#{remote_path}', ...)"
|
90
|
-
logfile.puts e.message
|
91
|
-
logfile.puts e.backtrace
|
92
|
-
false
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
def remote_tmp_script_path(command)
|
97
|
-
"/tmp/remote_script_#{command.to_filename}"
|
98
|
-
end
|
99
|
-
|
100
|
-
# Makes +remote_path+ executable, then runs it
|
101
|
-
# Returns:
|
102
|
-
# * a String of all STDOUT/STDERR; which is also appended to +logfile+
|
103
|
-
# * status (true = success)
|
104
|
-
#
|
105
|
-
# TODO catch exceptions http://learnonthejob.blogspot.com/2010/08/exception-handling-for-netssh.html
|
106
|
-
def run_remote_script(remote_path, ssh_username, run_as_root)
|
107
|
-
sudo = run_as_root ? "sudo " : ""
|
108
|
-
commands = [
|
109
|
-
"chmod +x #{remote_path}",
|
110
|
-
"bash -lc '#{sudo}/usr/bin/env PATH=$PATH #{remote_path}'"
|
111
|
-
]
|
112
|
-
script_output = ""
|
113
|
-
results = Fog::SSH.new(host, ssh_username, keys: private_keys).run(commands) do |stdout, stderr|
|
114
|
-
[stdout, stderr].flatten.each do |data|
|
115
|
-
logfile << data
|
116
|
-
script_output << data
|
117
|
-
end
|
118
|
-
end
|
119
|
-
result = results.last
|
120
|
-
result_success = result.status == 0
|
121
|
-
[script_output, result_success]
|
122
|
-
end
|
123
|
-
|
124
|
-
def run_remote_command(command, username)
|
125
|
-
Net::SSH.start(host, username, keys: private_keys) do |ssh|
|
126
|
-
ssh.exec!("bash -lc '#{command}'") do |channel, stream, data|
|
127
|
-
logfile << data
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
# path to local private key being used
|
133
|
-
def private_keys
|
134
|
-
[private_key_path]
|
135
|
-
end
|
136
|
-
|
137
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# A single command/script to be run on a local/remote server
|
2
|
-
# For the display, it has an active ("installing") and
|
3
|
-
# past tense ("installed") verb and a noub/description ("packages")
|
4
|
-
module Bosh::Bootstrap::Commander
|
5
|
-
class UploadCommand < Command
|
6
|
-
def initialize(target_path, file_contents)
|
7
|
-
super("upload", "file", "uploading file", "uploaded file")
|
8
|
-
@target_path = target_path
|
9
|
-
@file_contents = file_contents
|
10
|
-
end
|
11
|
-
|
12
|
-
# Invoke this command to call back upon +server.upload_file+
|
13
|
-
def perform(server)
|
14
|
-
server.upload_file(self, @target_path, @file_contents)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
module Bosh::Bootstrap::Commander
|
2
|
-
end
|
3
|
-
|
4
|
-
require "bosh-bootstrap/commander/command"
|
5
|
-
require "bosh-bootstrap/commander/remote_script_command"
|
6
|
-
require "bosh-bootstrap/commander/upload_command"
|
7
|
-
require "bosh-bootstrap/commander/commands"
|
8
|
-
require "bosh-bootstrap/commander/local_server"
|
9
|
-
require "bosh-bootstrap/commander/remote_server"
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# Copyright (c) 2012-2013 Stark & Wayne, LLC
|
2
|
-
|
3
|
-
require "fog"
|
4
|
-
module Bosh; module Bootstrap; module Helpers; end; end; end
|
5
|
-
|
6
|
-
# A collection of methods related to getting fog_compute
|
7
|
-
# credentials for creating the inception VM
|
8
|
-
# and to provide to the MicroBOSH for its uses.
|
9
|
-
#
|
10
|
-
# Attempts to look in +settings.fog_path+ to see if there is a .fog file.
|
11
|
-
module Bosh::Bootstrap::Helpers::FogSetup
|
12
|
-
|
13
|
-
# fog connection object to Compute tasks (VMs, IP addresses)
|
14
|
-
def fog_compute
|
15
|
-
@fog_compute ||= begin
|
16
|
-
# Fog::Compute.new requires Hash with keys that are symbols
|
17
|
-
# but Settings converts all keys to strings
|
18
|
-
# So create a version of settings.fog_credentials with symbol keys
|
19
|
-
credentials_with_symbols = settings.fog_credentials.inject({}) do |creds, key_pair|
|
20
|
-
key, value = key_pair
|
21
|
-
creds[key.to_sym] = value
|
22
|
-
creds
|
23
|
-
end
|
24
|
-
Fog::Compute.new(credentials_with_symbols)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def reset_fog_compute
|
29
|
-
@fog_compute = nil
|
30
|
-
@provider = nil # in cli.rb - I don't like this; need one wrapper for all CPI/compute calls
|
31
|
-
# or don't create fog_compute until we know all IaaS details
|
32
|
-
end
|
33
|
-
|
34
|
-
def fog_config
|
35
|
-
@fog_config ||= begin
|
36
|
-
if File.exists?(fog_config_path)
|
37
|
-
say "Found infrastructure API credentials at #{fog_config_path} (override with --fog)"
|
38
|
-
YAML.load_file(fog_config_path)
|
39
|
-
else
|
40
|
-
say "No existing #{fog_config_path} fog configuration file", :yellow
|
41
|
-
{}
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def fog_config_path
|
47
|
-
settings.fog_path
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
# Copyright (c) 2012-2013 Stark & Wayne, LLC
|
2
|
-
|
3
|
-
require "settingslogic"
|
4
|
-
module Bosh; module Bootstrap; module Helpers; end; end; end
|
5
|
-
|
6
|
-
# Helper methods for loading/saving settings
|
7
|
-
module Bosh::Bootstrap::Helpers::Settings
|
8
|
-
|
9
|
-
# Previously selected settings are stored in a YAML manifest
|
10
|
-
# Protects the manifest file with user-only priveleges
|
11
|
-
def settings
|
12
|
-
@settings ||= begin
|
13
|
-
FileUtils.mkdir_p(File.dirname(settings_path))
|
14
|
-
unless File.exists?(settings_path)
|
15
|
-
File.open(settings_path, "w") do |file|
|
16
|
-
file << {}.to_yaml
|
17
|
-
end
|
18
|
-
end
|
19
|
-
FileUtils.chmod 0600, settings_path
|
20
|
-
Settingslogic.new(settings_path)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def save_settings!
|
25
|
-
File.open(settings_path, "w") do |file|
|
26
|
-
raw_settings_yaml = settings.to_yaml.gsub(" !ruby/hash:Settingslogic", "")
|
27
|
-
file << raw_settings_yaml
|
28
|
-
end
|
29
|
-
@settings = nil # force to reload & recreate helper methods
|
30
|
-
end
|
31
|
-
|
32
|
-
# the base directory for holding the manifest settings file
|
33
|
-
# and private keys
|
34
|
-
#
|
35
|
-
# Defaults to ~/.bosh_bootstrap; and can be overridden with either:
|
36
|
-
# * $SETTINGS - to a folder (supported method)
|
37
|
-
# * $MANIFEST - to a folder (unsupported)
|
38
|
-
# * $MANIFEST - to a specific file; but uses its parent dir (unsupported, backwards compatibility)
|
39
|
-
def settings_dir
|
40
|
-
@settings_dir ||= begin
|
41
|
-
settings_dir = ENV["SETTINGS"] if ENV["SETTINGS"]
|
42
|
-
settings_dir ||= ENV["MANIFEST"] if ENV["MANIFEST"]
|
43
|
-
settings_dir = File.dirname(settings_dir) if settings_dir && File.file?(settings_dir)
|
44
|
-
settings_dir ||= "~/.bosh_bootstrap"
|
45
|
-
File.expand_path(settings_dir)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def settings_path
|
50
|
-
File.join(settings_dir, "manifest.yml")
|
51
|
-
end
|
52
|
-
|
53
|
-
def settings_ssh_dir
|
54
|
-
File.join(settings_dir, "ssh")
|
55
|
-
end
|
56
|
-
|
57
|
-
def backup_current_settings_file
|
58
|
-
backup_path = "#{settings_path}.bak"
|
59
|
-
FileUtils.cp_r(settings_path, backup_path)
|
60
|
-
end
|
61
|
-
|
62
|
-
def migrate_old_settings
|
63
|
-
if migrate_old_ssh_keys?
|
64
|
-
say "Upgrading settings manifest file:"
|
65
|
-
backup_current_settings_file
|
66
|
-
end
|
67
|
-
migrate_old_ssh_keys
|
68
|
-
end
|
69
|
-
|
70
|
-
# Do we need to migrate old ssh keys to new settings format?
|
71
|
-
def migrate_old_ssh_keys?
|
72
|
-
settings["local"] && settings["local"]["private_key_path"]
|
73
|
-
end
|
74
|
-
|
75
|
-
# Migrate this old data
|
76
|
-
# local:
|
77
|
-
# public_key_path: /Users/drnic/.ssh/id_rsa.pub
|
78
|
-
# private_key_path: /Users/drnic/.ssh/id_rsa
|
79
|
-
# into new format:
|
80
|
-
# inception:
|
81
|
-
# local_private_key_path: ~/.bosh_bootstrap/ssh/inception (copy of settings.local.private_key_path)
|
82
|
-
# key_pair:
|
83
|
-
# name: <name of provider key_pair used when provisioning inception VM>
|
84
|
-
# private_key: <contents of settings.local.private_key_path file>
|
85
|
-
# public_key: <contents of settings.local.public_key_path file>
|
86
|
-
def migrate_old_ssh_keys
|
87
|
-
if migrate_old_ssh_keys?
|
88
|
-
say "-> migrating to cache private key for inception VM..."
|
89
|
-
inception_vm_private_key_path # to setup the path in settings
|
90
|
-
settings["inception"]["key_pair"] ||= {}
|
91
|
-
settings["inception"]["key_pair"]["name"] = "fog_default"
|
92
|
-
settings["inception"]["key_pair"]["private_key"] = File.read(settings["local"]["private_key_path"]).strip
|
93
|
-
settings["inception"]["key_pair"]["public_key"] = File.read(settings["local"]["public_key_path"]).strip
|
94
|
-
settings.delete("local")
|
95
|
-
save_settings!
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# Copyright (c) 2012-2013 Stark & Wayne, LLC
|
2
|
-
|
3
|
-
require "settingslogic"
|
4
|
-
module Bosh; module Bootstrap; module Helpers; end; end; end
|
5
|
-
|
6
|
-
# Set a nested setting with "key1.key2.key3" notation
|
7
|
-
#
|
8
|
-
# Assumes +settings+ contains the settings
|
9
|
-
module Bosh::Bootstrap::Helpers::SettingsSetter
|
10
|
-
|
11
|
-
# Let's you navigate to a nested setting, do something with it,
|
12
|
-
# and then saves any changes to settings.
|
13
|
-
# Usage:
|
14
|
-
# with_setting "inception" { |s| s["host"] = "1.2.3.4" }
|
15
|
-
# with_setting "a.b.c" { |s| s["value"] = "1.2.3.4" }
|
16
|
-
def with_setting(nested_key, &block)
|
17
|
-
target_settings_field = settings
|
18
|
-
settings_key_portions = nested_key.split(".")
|
19
|
-
parent_key_portions, final_key = settings_key_portions[0..-2], settings_key_portions[-1]
|
20
|
-
parent_key_portions.each do |key_portion|
|
21
|
-
target_settings_field[key_portion] ||= {}
|
22
|
-
target_settings_field = target_settings_field[key_portion]
|
23
|
-
end
|
24
|
-
|
25
|
-
target_settings_field[final_key] ||= {}
|
26
|
-
yield target_settings_field[final_key]
|
27
|
-
save_settings!
|
28
|
-
end
|
29
|
-
|
30
|
-
def setting(nested_key, value)
|
31
|
-
target_settings_field = settings
|
32
|
-
settings_key_portions = nested_key.split(".")
|
33
|
-
parent_key_portions, final_key = settings_key_portions[0..-2], settings_key_portions[-1]
|
34
|
-
parent_key_portions.each do |key_portion|
|
35
|
-
target_settings_field[key_portion] ||= {}
|
36
|
-
target_settings_field = target_settings_field[key_portion]
|
37
|
-
end
|
38
|
-
target_settings_field[final_key] = value
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
#!/usr/bin/env bash
|
2
|
-
|
3
|
-
# Deletes a micro BOSH using "bosh micro delete"
|
4
|
-
#
|
5
|
-
# Required:
|
6
|
-
# * $BOSH_NAME - name of bosh deployment
|
7
|
-
# (thus /var/vcap/store/microboshes/deployments/$BOSH_NAME/micro_bosh.yml exists)
|
8
|
-
|
9
|
-
set -e # exit immediately if a simple command exits with a non-zero status
|
10
|
-
set -u # report the usage of uninitialized variables
|
11
|
-
|
12
|
-
# TODO in preparation for http://reviews.cloudfoundry.org/#/c/11976/
|
13
|
-
export COLUMNS=80 # force a small width for progress bar
|
14
|
-
|
15
|
-
cd /var/vcap/store/microboshes/deployments/
|
16
|
-
bosh -n micro deployment $BOSH_NAME
|
17
|
-
|
18
|
-
echo "Deleting deployment of micro BOSH $BOSH_NAME"
|
19
|
-
bosh -n micro delete
|