inception 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.chef/knife.rb +4 -0
  2. data/.gitignore +20 -0
  3. data/.kitchen.yml +42 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +23 -0
  6. data/Berksfile +8 -0
  7. data/Berksfile.lock +9 -0
  8. data/Gemfile +18 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +139 -0
  11. data/Rakefile +66 -0
  12. data/TODO.md +26 -0
  13. data/bin/bosh-inception +8 -0
  14. data/config/ssh/kitchen-aws +23 -0
  15. data/cookbooks/bosh_inception/README.md +15 -0
  16. data/cookbooks/bosh_inception/attributes/default.rb +20 -0
  17. data/cookbooks/bosh_inception/files/default/Gemfile.cf +4 -0
  18. data/cookbooks/bosh_inception/files/default/Gemfile.micro +5 -0
  19. data/cookbooks/bosh_inception/metadata.rb +32 -0
  20. data/cookbooks/bosh_inception/recipes/default.rb +15 -0
  21. data/cookbooks/bosh_inception/recipes/install_bosh.rb +37 -0
  22. data/cookbooks/bosh_inception/recipes/install_ruby.rb +10 -0
  23. data/cookbooks/bosh_inception/recipes/mount_store_volume.rb +24 -0
  24. data/cookbooks/bosh_inception/recipes/packages.rb +23 -0
  25. data/cookbooks/bosh_inception/recipes/setup_git.rb +34 -0
  26. data/cookbooks/bosh_inception/recipes/useful_dirs.rb +13 -0
  27. data/inception.gemspec +42 -0
  28. data/lib/bosh/providers.rb +41 -0
  29. data/lib/bosh/providers/README.md +5 -0
  30. data/lib/bosh/providers/cli/aws_provider_cli.rb +58 -0
  31. data/lib/bosh/providers/cli/openstack_provider_cli.rb +47 -0
  32. data/lib/bosh/providers/cli/provider_cli.rb +17 -0
  33. data/lib/bosh/providers/clients/aws_provider_client.rb +168 -0
  34. data/lib/bosh/providers/clients/fog_provider_client.rb +161 -0
  35. data/lib/bosh/providers/clients/openstack_provider_client.rb +65 -0
  36. data/lib/bosh/providers/constants/aws_constants.rb +25 -0
  37. data/lib/bosh/providers/constants/openstack_constants.rb +12 -0
  38. data/lib/inception.rb +9 -0
  39. data/lib/inception/cli.rb +136 -0
  40. data/lib/inception/cli_helpers/display.rb +26 -0
  41. data/lib/inception/cli_helpers/infrastructure.rb +157 -0
  42. data/lib/inception/cli_helpers/interactions.rb +15 -0
  43. data/lib/inception/cli_helpers/prepare_deploy_settings.rb +89 -0
  44. data/lib/inception/cli_helpers/provider.rb +14 -0
  45. data/lib/inception/cli_helpers/settings.rb +47 -0
  46. data/lib/inception/inception_server.rb +305 -0
  47. data/lib/inception/inception_server_cookbook.rb +89 -0
  48. data/lib/inception/next_deploy_actions.rb +20 -0
  49. data/lib/inception/version.rb +3 -0
  50. data/nodes/.gitkeep +0 -0
  51. data/spec/assets/.gitkeep +0 -0
  52. data/spec/assets/gitconfig +5 -0
  53. data/spec/assets/settings/aws-before-server.yml +14 -0
  54. data/spec/assets/settings/aws-created-server.yml +31 -0
  55. data/spec/integration/.gitkeep +0 -0
  56. data/spec/integration/aws/aws_basic_spec.rb +39 -0
  57. data/spec/spec_helper.rb +50 -0
  58. data/spec/support/aws/aws_helpers.rb +73 -0
  59. data/spec/support/settings_helper.rb +20 -0
  60. data/spec/support/stdout_capture.rb +17 -0
  61. data/spec/unit/.gitkeep +0 -0
  62. data/spec/unit/bosh/providers/aws_spec.rb +199 -0
  63. data/spec/unit/cli_delete_spec.rb +39 -0
  64. data/spec/unit/cli_deploy_aws_spec.rb +84 -0
  65. data/spec/unit/cli_ssh_spec.rb +82 -0
  66. data/spec/unit/inception_server_cookbook_spec.rb +61 -0
  67. data/spec/unit/inception_server_spec.rb +58 -0
  68. data/test/integration/default/bats/discover_user.bash +2 -0
  69. data/test/integration/default/bats/install_ruby.bats +8 -0
  70. data/test/integration/default/bats/useful_dirs.bats +8 -0
  71. data/test/integration/default/bats/user.bats +9 -0
  72. data/test/integration/default/bats/verify_bosh.bats +13 -0
  73. data/test/integration/default/bats/verify_git.bats +18 -0
  74. metadata +342 -0
@@ -0,0 +1,20 @@
1
+ # A String or Array of SSH public keys to populate the user"s .ssh/authorized_keys file.
2
+
3
+ default["disk"]["mounted"] = false
4
+ default["disk"]["device"] = "/dev/xvdf"
5
+ default["disk"]["fstype"] = "btrfs"
6
+ default["disk"]["dir"] = "/var/vcap/store"
7
+ default["user"]["username"] = `users | head -n 1`.strip
8
+ default["git"]["name"] = "Nobody"
9
+ default["git"]["email"] = "nobody@in-the-house.com"
10
+ default["rvm"]["default_ruby"] = "ruby-1.9.3"
11
+ default["rvm"]["global_gems"] = [
12
+ { "name" => "bundler" },
13
+ { "name" => "rake" },
14
+ { "name" => "jazor" },
15
+ { "name" => "yaml_command" },
16
+ { "name" => "chef" },
17
+ { "name" => "rubygems-bundler",
18
+ "action" => "remove"
19
+ }
20
+ ]
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ source 'https://s3.amazonaws.com/bosh-jenkins-gems/'
3
+
4
+ gem "bosh-cloudfoundry"
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+ source 'https://s3.amazonaws.com/bosh-jenkins-gems/'
3
+
4
+ gem "bosh_cli", "~> 1.5.0.pre"
5
+ gem "bosh_cli_plugin_micro", "~> 1.5.0.pre"
@@ -0,0 +1,32 @@
1
+ name "bosh_inception"
2
+ version "0.1.0"
3
+ description "Become an inception server to deploy/develop Bosh and bosh releases"
4
+ long_description IO.read(File.expand_path('../README.md', __FILE__))
5
+ maintainer "Dr Nic Williams"
6
+ maintainer_email "drnicwilliams@gmail.com"
7
+
8
+ supports "ubuntu"
9
+
10
+ depends "apt"
11
+ depends "sudo"
12
+ depends "rvm"
13
+ depends "hub"
14
+
15
+ attribute "git",
16
+ display_name: "Git",
17
+ description: "Hash of git config attributes",
18
+ type: "hash",
19
+ required: "recommended"
20
+
21
+ attribute "git/name",
22
+ display_name: "Git user's name",
23
+ description: "Name for git user",
24
+ type: "string",
25
+ required: "recommended"
26
+
27
+ attribute "git/email",
28
+ display_name: "Git user's email",
29
+ description: "Email for git user",
30
+ type: "string",
31
+ required: "recommended"
32
+
@@ -0,0 +1,15 @@
1
+ #
2
+ # Cookbook Name:: bosh_inception
3
+ # Recipe:: default
4
+ #
5
+ # Copyright (c) 2013 Dr Nic Williams, Stark & Wayne, LLC
6
+ #
7
+ # MIT License
8
+ #
9
+
10
+ include_recipe "bosh_inception::mount_store_volume"
11
+ include_recipe "bosh_inception::useful_dirs"
12
+ include_recipe "bosh_inception::packages"
13
+ include_recipe "bosh_inception::setup_git"
14
+ include_recipe "bosh_inception::install_ruby"
15
+ include_recipe "bosh_inception::install_bosh"
@@ -0,0 +1,37 @@
1
+ cookbook_file "/var/vcap/store/microboshes/Gemfile" do
2
+ source "Gemfile.micro"
3
+ owner node.user.username
4
+ group node.user.username
5
+ mode "0644"
6
+ end
7
+
8
+ directory "/var/vcap/store/microboshes" do
9
+ owner node.user.username
10
+ group node.user.username
11
+ mode "0755"
12
+ recursive true
13
+ action :create
14
+ end
15
+
16
+ rvm_shell "install bosh micro" do
17
+ code "bundle install"
18
+ cwd "/var/vcap/store/microboshes"
19
+ # user node.user.username
20
+ # environment ({'HOME' => "/home/#{node.user.username}"})
21
+ action :run
22
+ end
23
+
24
+ cookbook_file "/var/vcap/store/systems/Gemfile" do
25
+ source "Gemfile.cf"
26
+ owner node.user.username
27
+ group node.user.username
28
+ mode "0644"
29
+ end
30
+
31
+ rvm_shell "install bosh cf" do
32
+ code "bundle install"
33
+ cwd "/var/vcap/store/systems"
34
+ # user node.user.username
35
+ # environment ({'HOME' => "/home/#{node.user.username}"})
36
+ action :run
37
+ end
@@ -0,0 +1,10 @@
1
+ #
2
+ # Cookbook Name:: bosh_inception
3
+ # Recipe:: install_ruby
4
+ #
5
+ # Copyright (c) 2013 Dr Nic Williams, Stark & Wayne, LLC
6
+ #
7
+ # MIT License
8
+ #
9
+
10
+ include_recipe "rvm::system"
@@ -0,0 +1,24 @@
1
+ if node.disk.mounted
2
+ package "btrfs-tools" if node.disk.fstype == "btrfs"
3
+
4
+ bash "format /var/vcap/store partition" do
5
+ code "mkfs.#{node.disk.fstype} #{node.disk.device}"
6
+ not_if "cat /proc/mounts | grep /var/vcap/store"
7
+ end
8
+
9
+ directory node.disk.dir do
10
+ owner "root"
11
+ group "root"
12
+ mode "0755"
13
+ recursive true
14
+ action :create
15
+ end
16
+
17
+ mount node.disk.dir do
18
+ device node.disk.device
19
+ options "rw noatime"
20
+ fstype node.disk.fstype
21
+ action [ :enable, :mount ]
22
+ not_if "cat /proc/mounts | grep /var/vcap/store"
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ #
2
+ # Cookbook Name:: bosh_inception
3
+ # Recipe:: packages
4
+ #
5
+ # Copyright (c) 2013 Dr Nic Williams, Stark & Wayne, LLC
6
+ #
7
+ # MIT License
8
+ #
9
+
10
+ include_recipe "apt"
11
+
12
+ %w[
13
+ build-essential libsqlite3-dev curl rsync git-core
14
+ libmysqlclient-dev libxml2-dev libxslt-dev libpq-dev libsqlite3-dev
15
+ runit
16
+ genisoimage
17
+ debootstrap kpartx qemu-kvm
18
+ whois
19
+ tmux mosh
20
+ vim
21
+ ].each do |pkg|
22
+ package pkg
23
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Cookbook Name:: bosh_inception
3
+ # Recipe:: git_config
4
+ #
5
+ # Copyright (c) 2013 Dr Nic Williams, Stark & Wayne, LLC
6
+ #
7
+ # MIT License
8
+ #
9
+
10
+ include_recipe "hub"
11
+
12
+ execute "git config user.name" do
13
+ command "git config --global --replace-all user.name '#{node.git.name}'"
14
+ user node.user.username
15
+ group node.user.username
16
+ action :run
17
+ environment ({'HOME' => "/home/#{node.user.username}"})
18
+ end
19
+
20
+ execute "git config user.email" do
21
+ command "git config --global --replace-all user.email '#{node.git.email}'"
22
+ user node.user.username
23
+ group node.user.username
24
+ action :run
25
+ environment ({'HOME' => "/home/#{node.user.username}"})
26
+ end
27
+
28
+ execute "git config color.ui" do
29
+ command "git config --global color.ui true"
30
+ user node.user.username
31
+ group node.user.username
32
+ action :run
33
+ environment ({'HOME' => "/home/#{node.user.username}"})
34
+ end
@@ -0,0 +1,13 @@
1
+ %w[microboshes microboshes/deployments deployments releases repos stemcells systems tmp bosh_cache].each do |dir|
2
+ directory "/var/vcap/store/#{dir}" do
3
+ owner node.user.username
4
+ group node.user.username
5
+ mode "0755"
6
+ recursive true
7
+ action :create
8
+ end
9
+ end
10
+
11
+ link "/home/#{node.user.username}/.bosh_cache" do
12
+ to "/var/vcap/store/bosh_cache"
13
+ end
@@ -0,0 +1,42 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'inception/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "inception"
8
+ spec.version = Inception::VERSION
9
+ spec.authors = ["Dr Nic Williams"]
10
+ spec.email = ["drnicwilliams@gmail.com"]
11
+ spec.description = %q{Create an inception server for Bosh & general inception of new universes}
12
+ spec.summary = %q{CLI, with chef recipes, for creating and preparing an inception server for deploying/developing a Bosh universe.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "thor"
22
+ spec.add_dependency "highline"
23
+ spec.add_dependency "escape"
24
+ spec.add_dependency "json"
25
+ spec.add_dependency "settingslogic", "~> 2.0.9" # need to_nested_hash method
26
+
27
+ # for bosh/providers
28
+ spec.add_dependency "fog"
29
+
30
+ # for running cookbooks on inception server
31
+ spec.add_dependency "knife-solo", "~> 0.3.0.pre"
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.3"
34
+ spec.add_development_dependency "rake"
35
+
36
+ # gems for the ruby unit & integration tests
37
+ spec.add_development_dependency "rspec"
38
+
39
+ # gems for the cookbook tests
40
+ spec.add_development_dependency "test-kitchen", "~> 1.0.0.alpha.6"
41
+ spec.add_development_dependency "berkshelf"
42
+ end
@@ -0,0 +1,41 @@
1
+ # Copyright (c) 2012-2013 Stark & Wayne, LLC
2
+
3
+ module Bosh; end
4
+
5
+ module Bosh::Providers
6
+ extend self
7
+
8
+ # returns a BOSH provider (CPI) specific object
9
+ # with helpers related to that provider
10
+ # returns nil if +provider_name+ is unknown
11
+ def provider_client(attributes)
12
+ attributes = attributes.is_a?(Hash) ? Settingslogic.new(attributes) : attributes
13
+ case attributes.name.to_sym
14
+ when :aws
15
+ @aws_provider_client ||= begin
16
+ require "bosh/providers/clients/aws_provider_client"
17
+ Bosh::Providers::Clients::AwsProviderClient.new(attributes)
18
+ end
19
+ when :openstack
20
+ @openstack_provider_client ||= begin
21
+ require "bosh/providers/clients/openstack_provider_client"
22
+ Bosh::Providers::Clients::OpenStackProviderClient.new(attributes)
23
+ end
24
+ else
25
+ nil
26
+ end
27
+ end
28
+
29
+ def provider_cli(provider_name, provider_settings)
30
+ case provider_name.to_sym
31
+ when :aws
32
+ require "bosh/providers/cli/aws_provider_cli"
33
+ Bosh::Providers::Cli::AwsProviderCli.new(provider_settings)
34
+ when :openstack
35
+ require "bosh/providers/cli/openstack_provider_cli"
36
+ Bosh::Providers::Cli::OpenStackProviderCli.new(provider_settings)
37
+ else
38
+ nil
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,5 @@
1
+ # Providers
2
+
3
+ Currently these files are kept in sync with bosh-cloudfoundry project.
4
+
5
+ TODO - extract into shared library.
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2012-2013 Stark & Wayne, LLC
2
+
3
+ module Bosh; module Providers; module Cli; end; end; end
4
+
5
+ require "bosh/providers/cli/provider_cli"
6
+ require "bosh/providers/constants/aws_constants"
7
+
8
+ # Interactively prompt user for region & credential information for AWS
9
+ #
10
+ # Primary use within inception is to pass +settings.provider+ hash
11
+ # run #perform to gather credentials, then export the credentials/attributes.
12
+ #
13
+ # settings["provider"] = {}
14
+ # provider = AwsProviderCli.new(settings.provider)
15
+ # provider_client.perform
16
+ # settings.provider = provider_cli.export_attributes
17
+ class Bosh::Providers::Cli::AwsProviderCli < Bosh::Providers::Cli::ProviderCli
18
+
19
+ def perform
20
+ attributes.set("name", "aws") # ensure this property is correct
21
+ choose_region unless attributes.exists?("region")
22
+ setup_credentials unless attributes.exists?("credentials.aws_access_key_id")
23
+ end
24
+
25
+ # helper to export the complete nested attributes as a pure Hash
26
+ def export_attributes
27
+ attributes.to_nested_hash
28
+ end
29
+
30
+ def choose_region
31
+ hl.choose do |menu|
32
+ menu.prompt = "Choose AWS region: "
33
+ default_menu_item = nil
34
+ aws_constants.region_labels.each do |region_info|
35
+ label, code = region_info[:label], region_info[:code]
36
+ menu_item = "#{label} (#{code})"
37
+ if code == aws_constants.default_region_code
38
+ menu_item = "*#{menu_item}"
39
+ default_menu_item = menu_item
40
+ end
41
+ menu.choice(menu_item) do
42
+ attributes["region"] = code
43
+ end
44
+ end
45
+ menu.default = default_menu_item if default_menu_item
46
+ end
47
+ end
48
+
49
+ def setup_credentials
50
+ attributes.set_default("credentials", {})
51
+ attributes.credentials["aws_access_key_id"] = hl.ask("Access key: ")
52
+ attributes.credentials["aws_secret_access_key"] = hl.ask("Secret key: ")
53
+ end
54
+
55
+ def aws_constants
56
+ Bosh::Providers::Constants::AwsConstants
57
+ end
58
+ end
@@ -0,0 +1,47 @@
1
+ # Copyright (c) 2012-2013 Stark & Wayne, LLC
2
+
3
+ module Bosh; module Providers; module Cli; end; end; end
4
+
5
+ require "bosh/providers/cli/provider_cli"
6
+ require "bosh/providers/constants/openstack_constants"
7
+
8
+ # Interactively prompt user for region & credential information for OpenStack
9
+ #
10
+ # Primary use within inception is to pass +settings.provider+ hash
11
+ # run #perform to gather credentials, then export the credentials/attributes.
12
+ #
13
+ # settings["provider"] = {}
14
+ # provider = OpenStackProviderCli.new(settings.provider)
15
+ # provider_client.perform
16
+ # settings.provider = provider_cli.export_attributes
17
+ class Bosh::Providers::Cli::OpenStackProviderCli < Bosh::Providers::Cli::ProviderCli
18
+
19
+ def perform
20
+ attributes.set("name", "openstack") # ensure this property is correct
21
+ choose_region unless attributes.exists?("region")
22
+ setup_credentials unless attributes.exists?("credentials.openstack_api_key")
23
+ end
24
+
25
+ # helper to export the complete nested attributes as a pure Hash
26
+ def export_attributes
27
+ attributes.to_nested_hash
28
+ end
29
+
30
+ def choose_region
31
+ attributes.region = hl.ask("OpenStack Region (optional): ") do |q|
32
+ q.default = openstack_constants.no_region_code
33
+ end
34
+ end
35
+
36
+ def setup_credentials
37
+ attributes.set_default("credentials", {})
38
+ attributes.credentials["openstack_username"] = hl.ask("Username: ")
39
+ attributes.credentials["openstack_api_key"] = hl.ask("Password: ")
40
+ attributes.credentials["openstack_tenant"] = hl.ask("Tenant: ")
41
+ attributes.credentials["openstack_auth_url"] = hl.ask("Authorization Token URL: ")
42
+ end
43
+
44
+ def openstack_constants
45
+ Bosh::Providers::Constants::OpenStackConstants
46
+ end
47
+ end
@@ -0,0 +1,17 @@
1
+ # Copyright (c) 2012-2013 Stark & Wayne, LLC
2
+
3
+ module Bosh; module Providers; module Cli; end; end; end
4
+
5
+ class Bosh::Providers::Cli::ProviderCli
6
+ include Inception::CliHelpers::Interactions
7
+
8
+ attr_reader :provider_client
9
+ attr_reader :attributes
10
+
11
+ def initialize(attributes)
12
+ @provider_client = provider_client
13
+ @attributes = attributes.is_a?(Hash) ? Settingslogic.new(attributes) : attributes
14
+ raise "@attributes must be Settingslogic (or Hash)" unless @attributes.is_a?(Settingslogic)
15
+ end
16
+
17
+ end