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 +10 -0
- data/README.md +105 -0
- data/lib/bosh/gen/cli.rb +7 -1
- data/lib/bosh/gen/generators/job_generator/templates/jobs/%job_name%_simple/templates/bin/%job_name%_ctl.tt +1 -1
- data/lib/bosh/gen/generators/micro_job_generator/templates/jobs/micro/prepare +130 -0
- data/lib/bosh/gen/generators/micro_job_generator.rb +50 -0
- data/lib/bosh/gen/generators/new_release_generator/templates/README.md.tt +48 -2
- data/lib/bosh/gen/generators/new_release_generator.rb +30 -4
- data/lib/bosh/gen/version.rb +1 -1
- metadata +6 -4
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)
|
@@ -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 %>
|
1
|
+
# BOSH Release for <%= name %>
|
2
2
|
|
3
|
-
|
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
|
-
|
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" => "
|
63
|
-
"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
|
}
|
data/lib/bosh/gen/version.rb
CHANGED
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.
|
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-
|
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:
|
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:
|
249
|
+
hash: -108278516028601848
|
248
250
|
requirements: []
|
249
251
|
rubyforge_project:
|
250
252
|
rubygems_version: 1.8.24
|