bosh-gen 0.9.0 → 0.10.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.
data/ChangeLog.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## v0.10.0
4
+
5
+ Added:
6
+
7
+ * `micro` - create a "micro" job that packages all/some jobs into a single VM
8
+
9
+ Improved:
10
+
11
+ * `new` - read/write credentials now in private.yml; more useful default README
12
+
3
13
  ## v0.9.0
4
14
 
5
15
  Major news
data/README.md CHANGED
@@ -60,7 +60,112 @@ $ bosh-gen template some-ruby-job config/some-config.ini
60
60
  force jobs/some-ruby-job/spec
61
61
  ```
62
62
 
63
+ ### Micro jobs - all-in-one VM
63
64
 
65
+ If your release includes two or more jobs you might want to offer a "micro" job that includes all/some jobs into a single VM.
66
+
67
+ To achieve this, there is a special `micro` generator.
68
+
69
+ ```
70
+ $ bosh-gen micro
71
+ create jobs/micro
72
+ create jobs/micro/prepare
73
+ chmod jobs/micro/prepare
74
+ create jobs/micro/prepare_spec
75
+ append .gitignore
76
+
77
+ Edit jobs/micro/prepare_spec with ordered list of jobs to include
78
+ in micro job. The order of jobs implicitly specifies the order in
79
+ which they are started.
80
+ ```
81
+
82
+ As above, now edit `prepare_spec` to order/restrict the list of jobs to be included in the micro VM.
83
+
84
+ Now create a new bosh release and a "micro/0.1-dev" job will be included:
85
+
86
+ ```
87
+ $ bosh create release --force
88
+ ...
89
+ Jobs
90
+ +----------+---------+-------+------------------------------------------+
91
+ | Name | Version | Notes | Fingerprint |
92
+ +----------+---------+-------+------------------------------------------+
93
+ ...
94
+ | micro | 0.1-dev | | 6eb2f98644ef7f61a0399c015cbe062987dfd498 |
95
+ +----------+---------+-------+------------------------------------------+
96
+ ```
97
+
98
+ ## Tutorial
99
+
100
+ To see how the various commands work together, let's create a new bosh release for [Cassandra](http://cassandra.apache.org/ "The Apache Cassandra Project").
101
+
102
+ ```
103
+ $ bosh-gen new cassandra --s3
104
+ $ cd cassandra
105
+ $ bosh-gen extract-pkg ../cf-release/packages/dea_jvm7
106
+ create packages/dea_jvm7
107
+ create packages/dea_jvm7/packaging
108
+ create packages/dea_jvm7/spec
109
+ create blobs/java/jre-7u4-linux-i586.tar.gz
110
+ create blobs/java/jre-7u4-linux-x64.tar.gz
111
+ readme Upload blobs with 'bosh upload blobs'
112
+ $ mv packages/dea_jvm7 packages/java7
113
+ ```
114
+
115
+ In `packages/java7/spec`, rename it to `java7`.
116
+
117
+ ```
118
+ $ bosh-gen package cassandra -d java7 -f ~/Downloads/apache-cassandra-1.0.11-bin.tar.gz
119
+ create packages/cassandra/packaging
120
+ create packages/cassandra/pre_packaging
121
+ create blobs/cassandra/apache-cassandra-1.0.11-bin.tar.gz
122
+ create packages/cassandra/spec
123
+ ```
124
+
125
+ Change `packages/cassandra/packaging` to:
126
+
127
+ ```
128
+ tar xfv cassandra/apache-cassandra-1.0.11-bin.tar.gz
129
+ cp -a apache-cassandra-1.0.11/* $BOSH_INSTALL_TARGET
130
+ ```
131
+
132
+ Now create a stub for running cassandra as a job:
133
+
134
+ ```
135
+ $ bosh-gen job cassandra -d java7 cassandra
136
+ create jobs/cassandra
137
+ create jobs/cassandra/monit
138
+ create jobs/cassandra/templates/bin/cassandra_ctl
139
+ create jobs/cassandra/templates/bin/monit_debugger
140
+ create jobs/cassandra/templates/data/properties.sh.erb
141
+ create jobs/cassandra/templates/helpers/ctl_setup.sh
142
+ create jobs/cassandra/templates/helpers/ctl_utils.sh
143
+ create jobs/cassandra/spec
144
+ create examples/cassandra_simple
145
+ create examples/cassandra_simple/default.yml
146
+ ```
147
+
148
+ Look at all that goodness!
149
+
150
+ A quick summary of these files:
151
+
152
+ * The `monit` script uses `bin/monit_debugger` to help you debug any glitches in starting/stopping processes.
153
+ * `ctl_setup.sh` setups up lots of common folders and env vars.
154
+ * `ctl_utils.sh` comes from cf-release's common/utils.sh with some extra helper functions
155
+ * `data/properties.sh.erb` is where you extract any `<%= properties.cassandra... %>` values from the deployment manifest.
156
+ * `bin/cassandra_ctl` no longer needs to be an unreadable ERb template! Use the env variables you create in `data/properties.sh.erb` and normal bash if statements instead of ERb `<% if ... %>` templates.
157
+ * `examples/...` is a folder for documenting example, valid deployment manifest properties for the release.
158
+
159
+ In `bin/cassandra_ctl` you now change "TODO" to `cassandra` and the rest of the tutorial is left to you, dear cassandra lover.
160
+
161
+ Your release is now ready to build, test and deploy:
162
+
163
+ ```
164
+ bosh create release --force
165
+ bosh upload release
166
+ ```
167
+
168
+ When you create a final release, you will first need to setup your AWS credentials in `config/final.yml`
64
169
 
65
170
  ## Contributing
66
171
 
data/lib/bosh/gen/cli.rb CHANGED
@@ -67,7 +67,13 @@ module Bosh
67
67
  require 'bosh/gen/generators/job_generator'
68
68
  Bosh::Gen::Generators::JobGenerator.start([name, dependencies, 'simple'])
69
69
  end
70
-
70
+
71
+ desc "micro", "Create a micro job - a collection of all jobs and packages"
72
+ def micro
73
+ require 'bosh/gen/generators/micro_job_generator'
74
+ Bosh::Gen::Generators::MicroJobGenerator.start([])
75
+ end
76
+
71
77
  desc "template JOB FILE_PATH",
72
78
  "Add a Job template (example FILE_PATH: config/httpd.conf)"
73
79
  def template(job_name, file_path)
@@ -15,7 +15,7 @@ case $1 in
15
15
  pid_guard $PIDFILE $JOB_NAME
16
16
 
17
17
  # TODO: Run some process
18
- exec TODO
18
+ exec TODO \
19
19
  >>$LOG_DIR/$JOB_NAME.stdout.log \
20
20
  2>>$LOG_DIR/$JOB_NAME.stderr.log
21
21
 
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ require 'fileutils'
4
+ require 'yaml'
5
+ require 'erb'
6
+
7
+ TEMPLATES = "templates"
8
+ OVERRIDE = "override"
9
+
10
+ MICRO_JOB_NAME="micro"
11
+
12
+ def job_dir(job)
13
+ File.expand_path("../../#{job}", __FILE__)
14
+ end
15
+
16
+ PREPARE_SPEC = YAML.load_file(File.expand_path("../prepare_spec", __FILE__))
17
+
18
+ # Order of jobs, implicitly specifies the order in which they are started
19
+ jobs = PREPARE_SPEC["jobs"]
20
+
21
+ spec = {
22
+ "name" => MICRO_JOB_NAME,
23
+ "templates" => {
24
+ "post_install" => "bin/post_install"
25
+ },
26
+ "packages" => []
27
+ }
28
+
29
+ monit = []
30
+
31
+ # make sure we start with an empty directory, as it will stop if
32
+ # there are any conflicts when populating the template dir
33
+ FileUtils.rm_rf(TEMPLATES)
34
+ FileUtils.mkdir(TEMPLATES)
35
+
36
+ jobs.each do |job|
37
+ # concatenate monit file
38
+ override = File.join(OVERRIDE, "monit", job)
39
+ if File.exist?(override)
40
+ monit_file = override
41
+ else
42
+ monit_file = "#{job_dir(job)}/monit"
43
+ end
44
+ File.open(monit_file) do |file|
45
+ monit += file.readlines
46
+ monit << "\n"
47
+ end
48
+
49
+ # copy templates from:
50
+ # * templates/<template_name>
51
+ # * templates/<template_dir>/<template_name>
52
+ Dir.glob("#{job_dir(job)}/templates/**/*").each do |file|
53
+ next if File.directory?(file)
54
+
55
+ template_name = File.basename(file)
56
+ template_dir = File.basename(File.dirname(file))
57
+ # check if template file is in a nested dir
58
+ # if 'templates' then its not
59
+ if template_dir == "templates"
60
+ override = File.join(OVERRIDE, job, template_name)
61
+ dest = File.join(TEMPLATES, job)
62
+ else
63
+ override = File.join(OVERRIDE, job, template_dir, template_name)
64
+ dest = File.join(TEMPLATES, job, template_dir)
65
+ end
66
+ FileUtils.mkdir_p(dest) unless File.directory?(dest)
67
+
68
+ if File.exist?(File.join(dest, template_name))
69
+ puts "File conflict for job #{job}: #{template_name}"
70
+ exit 1
71
+ elsif File.exist?(override)
72
+ FileUtils.cp(override, dest)
73
+ else
74
+ FileUtils.cp(file, dest)
75
+ end
76
+ end
77
+
78
+ # build spec
79
+ s = YAML.load_file("#{job_dir(job)}/spec")
80
+ spec["packages"] += s["packages"]
81
+ s["templates"].each do |src, dst|
82
+ spec["templates"]["#{job}/#{src}"] = "#{job}/#{dst}"
83
+ end
84
+ end
85
+
86
+ # write out the concatenated monit file
87
+ File.open("monit", "w") do |file|
88
+ file.puts monit.join
89
+ end
90
+
91
+
92
+ # write out spec file
93
+ spec["packages"] = spec["packages"].uniq
94
+ File.open("spec", "w") do |file|
95
+ file.puts spec.to_yaml
96
+ end
97
+
98
+
99
+
100
+ # generate post_install file with all jobs
101
+ # it creates links from
102
+ # jobs/micro/<job>/bin/foo to jobs/<job>/bin/foo
103
+ # jobs/micro/<job>/config/bar to jobs/<job>/config/bar
104
+ post_install = <<POST_INSTALL
105
+ #!/bin/sh
106
+
107
+ for DIR in /var/vcap/jobs /var/vcap/data/jobs; do
108
+ cd $DIR
109
+ for JOB in <%= jobs.join(" ") %>; do
110
+ mkdir -p ${JOB}/bin ${JOB}/config ${JOB}/data ${JOB}/helpers
111
+ for FILE in <%= MICRO_JOB_NAME %>/$JOB/bin/*; do
112
+ ln -nsf /var/vcap/jobs/$FILE $JOB/bin
113
+ done
114
+ for FILE in <%= MICRO_JOB_NAME %>/$JOB/config/*; do
115
+ ln -nsf /var/vcap/jobs/$FILE $JOB/config
116
+ done
117
+ for FILE in <%= MICRO_JOB_NAME %>/$JOB/data/*; do
118
+ ln -nsf /var/vcap/jobs/$FILE $JOB/data
119
+ done
120
+ for FILE in <%= MICRO_JOB_NAME %>/$JOB/helpers/*; do
121
+ ln -nsf /var/vcap/jobs/$FILE $JOB/helpers
122
+ done
123
+ done
124
+ done
125
+ POST_INSTALL
126
+
127
+ File.open("templates/post_install", "w") do |file|
128
+ template = ERB.new(post_install)
129
+ file.puts template.result
130
+ end
@@ -0,0 +1,50 @@
1
+ require 'yaml'
2
+ require 'thor/group'
3
+
4
+ module Bosh::Gen
5
+ module Generators
6
+ class MicroJobGenerator < Thor::Group
7
+ include Thor::Actions
8
+
9
+ def self.source_root
10
+ File.join(File.dirname(__FILE__), "micro_job_generator", "templates")
11
+ end
12
+
13
+ def check_root_is_release
14
+ unless File.exist?("jobs") && File.exist?("packages")
15
+ raise Thor::Error.new("run inside a BOSH release project")
16
+ end
17
+ end
18
+
19
+ def create_job
20
+ directory "jobs/micro"
21
+ chmod "jobs/micro/prepare", 0755
22
+ end
23
+
24
+ def prepare_spec_defaults_all_jobs
25
+ jobs = Dir[File.expand_path("jobs/*")].map {|job| File.basename(job) } - ['micro']
26
+ spec = { "jobs" => jobs }
27
+ create_file "jobs/micro/prepare_spec", YAML.dump(spec)
28
+ end
29
+
30
+ def gitignore
31
+ append_file ".gitignore", <<-IGNORE.gsub(/^\s{8}/, '')
32
+ jobs/micro*/monit
33
+ jobs/micro*/spec
34
+ jobs/micro*/templates/
35
+ IGNORE
36
+ end
37
+
38
+ def readme
39
+ say ""
40
+ say "Edit "; say "jobs/micro/prepare_spec ", :yellow
41
+ say "with ordered list of jobs to include"
42
+ say "in micro job. The order of jobs implicitly specifies the order in"
43
+ say "which they are started."
44
+ say ""
45
+ say ""
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -1,4 +1,50 @@
1
- # <%= name %> - BOSH Release
1
+ # BOSH Release for <%= name %>
2
2
 
3
- This project is a BOSH release for `<%= name %>`.
3
+ ## Release to your BOSH
4
+
5
+ To create and upload this release to your BOSH:
6
+
7
+ ```
8
+ bosh target BOSH_URL
9
+ git clone git@github.com:<%= `whoami`.strip %>/<%= name %>.git
10
+ cd <%= name %>
11
+ bosh create release
12
+ # blobs are automatically downloaded
13
+ # name it 'cassandra-dev' or something unique to your bosh
14
+ bosh upload release
15
+ ```
16
+
17
+ ### Finalizing a release
18
+
19
+ If you create a final release `bosh create release --final`, you must immediately create a new development release. Yeah, this is a bug I guess.
20
+
21
+ ```
22
+ [outside vagrant]
23
+ bosh create release --final
24
+ bosh create release
25
+
26
+ [inside vagrant as vcap user]
27
+ /vagrant/scripts/update examples/default.yml
28
+ ```
29
+
30
+
31
+ ### Alternate configurations
32
+
33
+ This BOSH release is configurable during deployment with properties.
34
+
35
+ Please maintain example scenarios in the `examples/` folder.
36
+
37
+ To switch between example scenarios, run `sm bosh-solo update examples/FILE.yml` with a different example scenario.
38
+
39
+ ## Uploading to BOSH
40
+
41
+ Once you have a BOSH release that you like, you can upload it to BOSH and deploy it.
42
+
43
+ ```
44
+ bosh upload release
45
+ bosh deployment path/to/manifest.yml
46
+ bosh deploy
47
+ ```
48
+
49
+ Example `properties` for your `manifest.yml` can be taken from the examples in `examples\`
4
50
 
@@ -42,7 +42,34 @@ module Bosh::Gen
42
42
  config_dev = { "dev_name" => name }
43
43
  create_file "config/dev.yml", YAML.dump(config_dev)
44
44
 
45
- config_private = { "blobstore_secret" => 'BLOBSTORE_SECRET' }
45
+ case blobstore_type
46
+ when :local
47
+ config_private = {
48
+ "blobstore" => {
49
+ "simple" => {
50
+ "user" => "USER",
51
+ "password" => "PASSWORD"
52
+ }
53
+ }
54
+ }
55
+ when :s3
56
+ config_private = {
57
+ "blobstore" => {
58
+ "s3" => {
59
+ "access_key_id" => "READWRITE_AWS_ACCESS_KEY",
60
+ "secret_access_key" => "READWRITE_AWS_SECRET_ACCESS_KEY"
61
+ }
62
+ }
63
+ }
64
+ when :atmos
65
+ config_private = {
66
+ "blobstore" => {
67
+ "atmos" => {
68
+ "secret" => "SECRET"
69
+ }
70
+ }
71
+ }
72
+ end
46
73
  create_file "config/private.yml", YAML.dump(config_private)
47
74
 
48
75
  case blobstore_type
@@ -54,13 +81,12 @@ module Bosh::Gen
54
81
  }
55
82
  }
56
83
  when :s3
57
- config_private = { "blobstore_secret" => 'BLOBSTORE_SECRET' }
58
84
  config_final = { "blobstore" => {
59
85
  "provider" => "s3",
60
86
  "options" => {
61
87
  "bucket_name" => "BOSH",
62
- "access_key_id" => "AWS_ACCESS_KEY",
63
- "secret_access_key" => "AWS_SECRET_ACCESS_KEY",
88
+ "access_key_id" => "READONLY_AWS_ACCESS_KEY",
89
+ "secret_access_key" => "READONLY_AWS_SECRET_ACCESS_KEY",
64
90
  "encryption_key" => "PERSONAL_RANDOM_KEY",
65
91
  }
66
92
  }
@@ -1,5 +1,5 @@
1
1
  module Bosh
2
2
  module Gen
3
- VERSION = "0.9.0"
3
+ VERSION = "0.10.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bosh-gen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-11 00:00:00.000000000 Z
12
+ date: 2012-08-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -157,6 +157,8 @@ files:
157
157
  - lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/helpers/ctl_setup.sh
158
158
  - lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/helpers/ctl_utils.sh
159
159
  - lib/bosh/gen/generators/job_template_generator.rb
160
+ - lib/bosh/gen/generators/micro_job_generator.rb
161
+ - lib/bosh/gen/generators/micro_job_generator/templates/jobs/micro/prepare
160
162
  - lib/bosh/gen/generators/new_release_generator.rb
161
163
  - lib/bosh/gen/generators/new_release_generator/templates/README.md.tt
162
164
  - lib/bosh/gen/generators/new_release_generator/templates/Rakefile
@@ -235,7 +237,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
235
237
  version: '0'
236
238
  segments:
237
239
  - 0
238
- hash: 2628842034372834781
240
+ hash: -108278516028601848
239
241
  required_rubygems_version: !ruby/object:Gem::Requirement
240
242
  none: false
241
243
  requirements:
@@ -244,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
244
246
  version: '0'
245
247
  segments:
246
248
  - 0
247
- hash: 2628842034372834781
249
+ hash: -108278516028601848
248
250
  requirements: []
249
251
  rubyforge_project:
250
252
  rubygems_version: 1.8.24