bosh-gen 0.16.2 → 0.17.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 (57) hide show
  1. checksums.yaml +13 -5
  2. data/.rspec +3 -0
  3. data/.travis.yml +16 -0
  4. data/ChangeLog.md +110 -89
  5. data/Gemfile +7 -1
  6. data/Guardfile +4 -8
  7. data/README.md +52 -22
  8. data/Rakefile +10 -0
  9. data/bosh-gen.gemspec +7 -5
  10. data/lib/bosh/gen/cli.rb +20 -28
  11. data/lib/bosh/gen/generators/job_generator.rb +9 -10
  12. data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/bin/%job_name%_ctl.tt +5 -5
  13. data/lib/bosh/gen/generators/new_release_generator.rb +63 -68
  14. data/lib/bosh/gen/generators/new_release_generator/templates/jobs/%project_name_hyphenated%/templates/bin/%job_name%_ctl.tt +5 -5
  15. data/lib/bosh/gen/generators/new_release_generator/templates/jobs/%project_name_hyphenated%/templates/data/properties.sh.erb +6 -0
  16. data/lib/bosh/gen/generators/new_release_generator/templates/templates/infrastructure-aws-ec2.yml.tt +7 -5
  17. data/lib/bosh/gen/generators/new_release_generator/templates/templates/infrastructure-warden.yml.tt +3 -4
  18. data/lib/bosh/gen/generators/new_release_generator/templates/templates/jobs.yml.tt +3 -0
  19. data/lib/bosh/gen/generators/new_release_generator/templates/templates/make_manifest.tt +18 -2
  20. data/lib/bosh/gen/generators/new_release_generator/templates/templates/stub.yml.tt +2 -1
  21. data/lib/bosh/gen/settings.rb +61 -0
  22. data/lib/bosh/gen/version.rb +1 -1
  23. data/spec/fixtures/deployment_manifests/2_jobs_1_ip_8196_disk_with_numeric.yml +64 -0
  24. data/spec/fixtures/releases/s3test-boshrelease/.gitignore +18 -0
  25. data/spec/fixtures/releases/s3test-boshrelease/README.md +51 -0
  26. data/spec/fixtures/releases/s3test-boshrelease/Rakefile +15 -0
  27. data/spec/fixtures/releases/s3test-boshrelease/config/blobs.yml +1 -0
  28. data/spec/fixtures/releases/s3test-boshrelease/config/final.yml +5 -0
  29. data/spec/fixtures/releases/s3test-boshrelease/jobs/.gitkeep +0 -0
  30. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/monit +5 -0
  31. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/spec +13 -0
  32. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/bin/monit_debugger +13 -0
  33. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/bin/s3test_ctl +36 -0
  34. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/config/.gitkeep +0 -0
  35. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/config/s3test.conf.erb +5 -0
  36. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/data/properties.sh.erb +10 -0
  37. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/helpers/ctl_setup.sh +81 -0
  38. data/spec/fixtures/releases/s3test-boshrelease/jobs/s3test/templates/helpers/ctl_utils.sh +156 -0
  39. data/spec/fixtures/releases/s3test-boshrelease/packages/.gitkeep +0 -0
  40. data/spec/fixtures/releases/s3test-boshrelease/src/.gitkeep +0 -0
  41. data/spec/fixtures/releases/s3test-boshrelease/templates/deployment.yml +35 -0
  42. data/spec/fixtures/releases/s3test-boshrelease/templates/infrastructure-aws-ec2.yml +40 -0
  43. data/spec/fixtures/releases/s3test-boshrelease/templates/infrastructure-warden.yml +107 -0
  44. data/spec/fixtures/releases/s3test-boshrelease/templates/jobs.yml +30 -0
  45. data/spec/fixtures/releases/s3test-boshrelease/templates/make_manifest +54 -0
  46. data/spec/fixtures/releases/s3test-boshrelease/templates/stub.yml +13 -0
  47. data/spec/generators/deployment_manifest_generator_spec.rb +19 -14
  48. data/spec/generators/{jobs/webapp_job_generator_spec.rb → job_generator_spec.rb} +8 -13
  49. data/spec/generators/new_release_generator_spec.rb +70 -0
  50. data/spec/models/bosh_config_spec.rb +3 -3
  51. data/spec/models/deployment_manifest_spec.rb +16 -6
  52. data/spec/models/release_detection_spec.rb +6 -6
  53. data/spec/spec_helper.rb +27 -7
  54. data/spec/support/fog.rb +3 -0
  55. data/spec/{generators → support}/generator_spec_helper.rb +47 -6
  56. metadata +105 -36
  57. data/spec/models/extract_spec.rb +0 -10
data/Rakefile CHANGED
@@ -1,3 +1,13 @@
1
1
  #!/usr/bin/env rake
2
2
  require "bundler/gem_tasks"
3
3
 
4
+ require "rspec/core/rake_task"
5
+
6
+
7
+ desc "Run Tests"
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.pattern = "spec/unit/**/*_spec.rb"
10
+ t.rspec_opts = %w(--format progress --color)
11
+ end
12
+
13
+ task :default => :spec
data/bosh-gen.gemspec CHANGED
@@ -14,13 +14,15 @@ Gem::Specification.new do |gem|
14
14
  gem.name = "bosh-gen"
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Bosh::Gen::VERSION
17
-
17
+
18
18
  gem.add_dependency "thor"
19
19
  gem.add_dependency "bosh_cli"
20
20
  gem.add_dependency "bosh_common"
21
-
21
+
22
+ gem.add_dependency "cyoi", "~> 0.10.0"
23
+ gem.add_dependency "fog", "~> 1.11"
24
+ gem.add_dependency "readwritesettings", "~> 3.0"
25
+
22
26
  gem.add_development_dependency "rake"
23
- gem.add_development_dependency "minitest", "~> 2.12"
24
- gem.add_development_dependency "minitest-colorize"
25
- gem.add_development_dependency "guard-minitest"
27
+ gem.add_development_dependency "rspec-fire"
26
28
  end
data/lib/bosh/gen/cli.rb CHANGED
@@ -2,7 +2,7 @@ require "thor"
2
2
 
3
3
  # bosh_cli libraries
4
4
  module Bosh; end
5
- require "cli/config"
5
+ require "cli/config"
6
6
  require "cli/core_ext"
7
7
 
8
8
  require 'bosh/gen/models'
@@ -11,27 +11,19 @@ module Bosh
11
11
  module Gen
12
12
  class Command < Thor
13
13
  include Thor::Actions
14
-
14
+
15
15
  desc "new PATH", "Creates a new BOSH release"
16
- method_option :s3, :alias => ["--aws"], :type => :boolean,
17
- :desc => "Use AWS S3 bucket for blobstore"
18
- method_option :atmos, :type => :boolean,
19
- :desc => "Use EMC ATMOS for blobstore"
20
- method_option :swift, :type => :boolean,
21
- :desc => "Use OpenStack Swift for blobstore"
22
16
  def new(path)
23
- flags = { :aws => options["s3"], :atmos => options["atmos"],
24
- :swift => options["swift"]}
25
17
  require 'bosh/gen/generators/new_release_generator'
26
- Bosh::Gen::Generators::NewReleaseGenerator.start([path, flags])
18
+ Bosh::Gen::Generators::NewReleaseGenerator.start([path])
27
19
  end
28
-
20
+
29
21
  desc "package NAME", "Create a new package"
30
- method_option :apt, :type => :boolean,
22
+ method_option :apt, :type => :boolean,
31
23
  :desc => "Create package using debian/ubuntu apt .debs"
32
- method_option :dependencies, :aliases => ['-d'], :type => :array,
24
+ method_option :dependencies, :aliases => ['-d'], :type => :array,
33
25
  :desc => "List of package dependencies"
34
- method_option :files, :aliases => ['-f'], :type => :array,
26
+ method_option :files, :aliases => ['-f'], :type => :array,
35
27
  :desc => "List of files copy into release"
36
28
  method_option :src, :aliases => ['-s'], :type => :array,
37
29
  :desc => "List of existing sources to use, e.g. --src 'myapp/**/*'"
@@ -48,9 +40,9 @@ module Bosh
48
40
  [name, dependencies, files, sources])
49
41
  end
50
42
  end
51
-
43
+
52
44
  desc "source NAME", "Downloads a source item into the named project"
53
- method_option :blob, :aliases => ['-b'], :type => :boolean,
45
+ method_option :blob, :aliases => ['-b'], :type => :boolean,
54
46
  :desc => "Store file in blobstore"
55
47
  def source(name, uri)
56
48
  flags = { :blob => options[:blob] || false }
@@ -70,9 +62,9 @@ module Bosh
70
62
  Bosh::Gen::Generators::PackageSourceGenerator.start(
71
63
  [name, files, flags])
72
64
  end
73
-
65
+
74
66
  desc "job NAME", "Create a new job"
75
- method_option :dependencies, :aliases => ['-d'], :type => :array,
67
+ method_option :dependencies, :aliases => ['-d'], :type => :array,
76
68
  :desc => "List of package dependencies"
77
69
  def job(name)
78
70
  dependencies = options[:dependencies] || []
@@ -81,7 +73,7 @@ module Bosh
81
73
  end
82
74
 
83
75
  desc "micro [JOB]", "Create a micro job - a collection of all jobs and packages"
84
- method_option :jobs, :aliases => ['-j'], :type => :array,
76
+ method_option :jobs, :aliases => ['-j'], :type => :array,
85
77
  :desc => "Ordered list of jobs to include"
86
78
  def micro(job_name = "micro")
87
79
  specific_jobs = options[:jobs] || []
@@ -89,14 +81,14 @@ module Bosh
89
81
  Bosh::Gen::Generators::MicroJobGenerator.start([job_name, specific_jobs])
90
82
  end
91
83
 
92
- desc "template JOB FILE_PATH",
84
+ desc "template JOB FILE_PATH",
93
85
  "Add a Job template (example FILE_PATH: config/httpd.conf)"
94
86
  def template(job_name, file_path)
95
87
  require 'bosh/gen/generators/job_template_generator'
96
88
  Bosh::Gen::Generators::JobTemplateGenerator.start([job_name, file_path])
97
89
  end
98
-
99
- desc "extract-job SOURCE_PACKAGE_PATH",
90
+
91
+ desc "extract-job SOURCE_PACKAGE_PATH",
100
92
  "Extracts a job from another release and all its " +
101
93
  "dependent packages and source"
102
94
  def extract_job(source_package_path)
@@ -105,7 +97,7 @@ module Bosh
105
97
  Bosh::Gen::Generators::ExtractJobGenerator.start([source_package_path])
106
98
  end
107
99
 
108
- desc "extract-pkg SOURCE_PACKAGE_PATH",
100
+ desc "extract-pkg SOURCE_PACKAGE_PATH",
109
101
  "Extracts a package from another release and all its " +
110
102
  "dependent packages and sources"
111
103
  def extract_pkg(source_package_path)
@@ -114,13 +106,13 @@ module Bosh
114
106
  Bosh::Gen::Generators::ExtractPackageGenerator.start([source_package_path])
115
107
  end
116
108
 
117
- desc "manifest NAME PATH",
109
+ desc "manifest NAME PATH",
118
110
  "Creates a deployment manifest based on the release located at PATH"
119
- method_option :force, :type => :boolean,
111
+ method_option :force, :type => :boolean,
120
112
  :desc => "Force override existing target manifest file"
121
- method_option :addresses, :aliases => ['-a'], :type => :array,
113
+ method_option :addresses, :aliases => ['-a'], :type => :array,
122
114
  :desc => "List of IP addresses available for jobs"
123
- method_option :disk, :aliases => ['-d'], :type => :string,
115
+ method_option :disk, :aliases => ['-d'], :type => :string,
124
116
  :desc => "Attach persistent disks to VMs of specific size, e.g. 8196"
125
117
  method_option :jobs, :type => :array,
126
118
  :desc => "Specific jobs to include in manifest [default: all]"
@@ -9,17 +9,17 @@ module Bosh::Gen
9
9
  argument :job_name
10
10
  argument :dependencies, :type => :array
11
11
  argument :purpose
12
-
12
+
13
13
  def self.source_root
14
14
  File.join(File.dirname(__FILE__), "job_generator", "templates")
15
15
  end
16
-
16
+
17
17
  def check_root_is_release
18
18
  unless File.exist?("jobs") && File.exist?("packages")
19
19
  raise Thor::Error.new("run inside a BOSH release project")
20
20
  end
21
21
  end
22
-
22
+
23
23
  def check_name
24
24
  raise Thor::Error.new("'#{job_name}' is not a valid BOSH id") unless job_name.bosh_valid_id?
25
25
  end
@@ -38,7 +38,7 @@ module Bosh::Gen
38
38
  end
39
39
  end
40
40
  end
41
-
41
+
42
42
  # copy the thor template files into the bosh release to be bosh templates
43
43
  # that's right, templates (.tt) can become templates (.erb)
44
44
  def template_files
@@ -46,7 +46,6 @@ module Bosh::Gen
46
46
  directory "jobs/%job_name%_#{purpose}", "jobs/#{job_name}"
47
47
 
48
48
  # build a hash of { 'bin/webapp_ctl.erb' => 'bin/webapp_ctl', ...} used in spec
49
- # TODO: do I need to flatten it to { 'webapp_ctl' => 'bin/webapp_ctl' }?
50
49
  @template_files = {}
51
50
  FileUtils.chdir(File.join(generator_job_templates_path, "templates")) do
52
51
  `ls */*`.split("\n").each do |template_file|
@@ -60,25 +59,25 @@ module Bosh::Gen
60
59
  end
61
60
  end
62
61
  end
63
-
62
+
64
63
  def job_specification
65
64
  config = { "name" => job_name, "packages" => dependencies, "templates" => @template_files }
66
65
  create_file job_dir("spec"), YAML.dump(config)
67
66
  end
68
-
67
+
69
68
  private
70
69
  def filenames
71
70
  files.map {|f| File.basename(f) }
72
71
  end
73
-
72
+
74
73
  def job_dir(path)
75
74
  File.join("jobs", job_name, path)
76
75
  end
77
-
76
+
78
77
  def valid_purposes
79
78
  %w[simple]
80
79
  end
81
-
80
+
82
81
  # Run a command in git.
83
82
  #
84
83
  # ==== Examples
@@ -14,13 +14,13 @@ case $1 in
14
14
  start)
15
15
  pid_guard $PIDFILE $JOB_NAME
16
16
 
17
- # TODO: Run some process
18
- exec chpst -u vcap:vcap TODO \
17
+ # store pid in $PIDFILE
18
+ echo $$ > $PIDFILE
19
+
20
+ exec chpst -u vcap:vcap <%= job_name %> \
19
21
  >>$LOG_DIR/$JOB_NAME.stdout.log \
20
22
  2>>$LOG_DIR/$JOB_NAME.stderr.log
21
23
 
22
- # store pid in $PIDFILE
23
- echo $! > $PIDFILE
24
24
  ;;
25
25
 
26
26
  stop)
@@ -33,4 +33,4 @@ case $1 in
33
33
  ;;
34
34
 
35
35
  esac
36
- exit 0
36
+ exit 0
@@ -1,32 +1,42 @@
1
- require 'yaml'
2
- require 'thor/group'
1
+ require "yaml"
2
+ require "thor/group"
3
+ require "cyoi/cli/provider"
4
+ require "cyoi/cli/blobstore"
5
+ require "bosh/gen/settings"
3
6
 
4
7
  module Bosh::Gen
5
8
  module Generators
6
9
  class NewReleaseGenerator < Thor::Group
7
10
  include Thor::Actions
11
+ include Bosh::Gen::Settings
8
12
 
9
13
  argument :proposed_app_path
10
- argument :flags, :type => :hash
11
-
14
+
12
15
  def self.source_root
13
16
  File.join(File.dirname(__FILE__), "new_release_generator", "templates")
14
17
  end
15
-
18
+
16
19
  def create_root
17
20
  self.destination_root = File.expand_path(repository_path, destination_root)
18
21
  empty_directory '.'
19
22
  FileUtils.cd(destination_root) unless options[:pretend]
20
23
  end
21
-
24
+
25
+ def select_provider
26
+ self.settings_dir = File.expand_path("config")
27
+ provider = Cyoi::Cli::Provider.new([settings_dir])
28
+ provider.execute!
29
+ reload_settings!
30
+ end
31
+
22
32
  def readme
23
33
  template "README.md.tt", "README.md"
24
34
  end
25
-
35
+
26
36
  def rakefile
27
37
  copy_file "Rakefile"
28
38
  end
29
-
39
+
30
40
  def directories
31
41
  %w[jobs packages src blobs templates].each do |dir|
32
42
  directory dir
@@ -40,15 +50,16 @@ module Bosh::Gen
40
50
  def blobs_yaml
41
51
  create_file "config/blobs.yml", YAML.dump({})
42
52
  end
43
-
44
- # TODO - support other blobstores
45
- def local_blobstore
53
+
54
+ def config_dev_yml
46
55
  config_dev = { "dev_name" => project_name }
47
56
  create_file "config/dev.yml", YAML.dump(config_dev)
57
+ end
48
58
 
59
+ def config_private_yml
49
60
  case blobstore_type
50
61
  when :local
51
- config_private = {
62
+ config_private = {
52
63
  "blobstore" => {
53
64
  "simple" => {
54
65
  "user" => "USER",
@@ -57,41 +68,28 @@ module Bosh::Gen
57
68
  }
58
69
  }
59
70
  when :s3
60
- config_private = {
71
+ config_private = {
61
72
  "blobstore" => {
62
73
  "s3" => {
63
- "access_key_id" => readwrite_aws_access_key,
64
- "secret_access_key" => readwrite_aws_secret_access_key
65
- }
66
- }
67
- }
68
- when :atmos
69
- config_private = {
70
- "blobstore" => {
71
- "atmos" => {
72
- "secret" => "SECRET"
74
+ "access_key_id" => settings.provider.credentials.aws_access_key_id,
75
+ "secret_access_key" => settings.provider.credentials.aws_secret_access_key
73
76
  }
74
77
  }
75
78
  }
79
+ # https://github.com/cloudfoundry/bosh/tree/master/blobstore_client#openstack-object-storage
76
80
  when :swift
77
81
  config_private = {
78
82
  "blobstore" => {
79
83
  "swift" => {
80
- "rackspace" => {
81
- "rackspace_username" => "USERNAME",
82
- "rackspace_api_key" => "API_KEY"
83
- },
84
- "hp" => {
85
- "hp_account_id" => "ACCESS_KEY_ID",
86
- "hp_secret_key" => "SECRET_KEY",
87
- "hp_tenant_id" => "TENANT_ID"
88
- },
84
+ settings.provider.name => settings.provider.credentials.to_hash
89
85
  }
90
86
  }
91
87
  }
92
88
  end
93
89
  create_file "config/private.yml", YAML.dump(config_private)
90
+ end
94
91
 
92
+ def config_final_yml
95
93
  case blobstore_type
96
94
  when :local
97
95
  say_status "warning", "config/final.yml defaulting to local blobstore /tmp/blobstore", :yellow
@@ -104,20 +102,7 @@ module Bosh::Gen
104
102
  config_final = { "blobstore" => {
105
103
  "provider" => "s3",
106
104
  "options" => {
107
- "bucket_name" => repository_name,
108
- "access_key_id" => readonly_aws_access_key,
109
- "secret_access_key" => readonly_aws_secret_access_key,
110
- "encryption_key" => "PERSONAL_RANDOM_KEY",
111
- }
112
- }
113
- }
114
- when :atmos
115
- config_final = { "blobstore" => {
116
- "provider" => "atmos",
117
- "options" => {
118
- "tag" => repository_name,
119
- "url" => "https://blob.cfblob.com",
120
- "uid" => "ATMOS_UID"
105
+ "bucket_name" => repository_name
121
106
  }
122
107
  }
123
108
  }
@@ -126,19 +111,20 @@ module Bosh::Gen
126
111
  "provider" => "swift",
127
112
  "options" => {
128
113
  "container_name" => repository_name,
129
- "swift_provider" => "SWIFT_PROVIDER"
114
+ "swift_provider" => swift_provider
130
115
  }
131
116
  }
132
117
  }
133
118
  end
134
-
119
+
135
120
  create_file "config/final.yml", YAML.dump(config_final)
136
121
  end
137
-
122
+
138
123
  def git_init
139
124
  create_file ".gitignore", <<-IGNORE.gsub(/^\s{8}/, '')
140
125
  config/dev.yml
141
126
  config/private.yml
127
+ config/settings.yml
142
128
  releases/*.tgz
143
129
  dev_releases
144
130
  blobs/*
@@ -157,7 +143,7 @@ module Bosh::Gen
157
143
  my*.yml
158
144
  IGNORE
159
145
  end
160
-
146
+
161
147
  def setup_git
162
148
  git :init
163
149
  git :add => "."
@@ -170,6 +156,17 @@ module Bosh::Gen
170
156
  say "cd #{repository_path}", :yellow
171
157
  end
172
158
 
159
+ def create_blobstore
160
+ say ""
161
+ say "Finally..."
162
+ blobstore = Cyoi::Cli::Blobstore.new([blobstore_name, settings_dir])
163
+ blobstore.execute!
164
+ reload_settings!
165
+ say ""
166
+ end
167
+
168
+
169
+
173
170
  private
174
171
 
175
172
  # converts the base name into having -boshrelease suffix
@@ -177,6 +174,10 @@ module Bosh::Gen
177
174
  @repository_name ||= "#{project_name}-boshrelease"
178
175
  end
179
176
 
177
+ def blobstore_name
178
+ repository_name
179
+ end
180
+
180
181
  def repository_path
181
182
  File.join(File.dirname(proposed_app_path), repository_name)
182
183
  end
@@ -190,30 +191,31 @@ module Bosh::Gen
190
191
  end
191
192
 
192
193
  def project_name_hyphenated
193
- project_name.gsub(/[^A-Za-z]+/, '-')
194
+ project_name.gsub(/[^A-Za-z0-9]+/, '-')
194
195
  end
195
196
 
196
197
  def project_name_underscored
197
- project_name.gsub(/[^A-Za-z]+/, '_')
198
+ project_name.gsub(/[^A-Za-z0-9]+/, '_')
198
199
  end
199
200
 
200
201
  def blobstore_type
201
202
  return :s3 if s3?
202
- return :atmos if atmos?
203
203
  return :swift if swift?
204
204
  return :local
205
205
  end
206
-
206
+
207
207
  def s3?
208
- flags[:aws]
209
- end
210
-
211
- def atmos?
212
- flags[:atmos]
208
+ settings.provider.name == "aws"
213
209
  end
214
210
 
215
211
  def swift?
216
- flags[:swift]
212
+ settings.provider.name == "openstack"
213
+ end
214
+
215
+ # https://github.com/cloudfoundry/bosh/tree/master/blobstore_client#openstack-swift-provider
216
+ # TODO: supported: hp, openstack and rackspace; How to detect this from fog?
217
+ def swift_provider
218
+ "openstack"
217
219
  end
218
220
 
219
221
  # Run a command in git.
@@ -234,14 +236,6 @@ module Bosh::Gen
234
236
  end
235
237
  end
236
238
 
237
- def readonly_aws_access_key
238
- s3_credentials "readonly_access_key", "READONLY_AWS_ACCESS_KEY"
239
- end
240
-
241
- def readonly_aws_secret_access_key
242
- s3_credentials "readonly_secret_access_key", "READONLY_AWS_SECRET_ACCESS_KEY"
243
- end
244
-
245
239
  def readwrite_aws_access_key
246
240
  s3_credentials "readwrite_access_key", "READWRITE_AWS_ACCESS_KEY"
247
241
  end
@@ -261,6 +255,7 @@ module Bosh::Gen
261
255
  end
262
256
  @s3_credentials[key] || default
263
257
  end
258
+
264
259
  end
265
260
  end
266
261
  end