bosh-gen 0.9.0 → 0.10.0

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