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 +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
|