bosh-workspace 0.7.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.
- checksums.yaml +15 -0
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/Guardfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +70 -0
- data/Rakefile +1 -0
- data/bosh-workspace.gemspec +31 -0
- data/lib/bosh/cli/commands/01_make_manifest.rb +74 -0
- data/lib/bosh/workspace/deployment_manifest.rb +67 -0
- data/lib/bosh/workspace/helpers/project_deployment_helper.rb +103 -0
- data/lib/bosh/workspace/helpers/spiff_helper.rb +33 -0
- data/lib/bosh/workspace/manifest_builder.rb +68 -0
- data/lib/bosh/workspace/release.rb +58 -0
- data/lib/bosh/workspace/release_manager.rb +14 -0
- data/lib/bosh/workspace/version.rb +5 -0
- data/lib/bosh/workspace.rb +13 -0
- data/spec/assets/bin/spiff +0 -0
- data/spec/assets/empty-manifests-repo/.keep +0 -0
- data/spec/assets/foo-boshrelease-repo.zip +0 -0
- data/spec/assets/manifests-repo/.manifests/foo.yml +1 -0
- data/spec/assets/manifests-repo/deployments/bar.yml +1 -0
- data/spec/assets/manifests-repo/deployments/foo.yml +4 -0
- data/spec/assets/manifests-repo/templates/foo/bar.yml +0 -0
- data/spec/commands/command_make_manifest_spec.rb +107 -0
- data/spec/deployment_manifest_spec.rb +93 -0
- data/spec/helpers/project_deployment_helper_spec.rb +191 -0
- data/spec/helpers/spiff_helper_spec.rb +55 -0
- data/spec/manifest_builder_spec.rb +88 -0
- data/spec/release_manager_spec.rb +17 -0
- data/spec/release_spec.rb +74 -0
- data/spec/spec_helper.rb +84 -0
- metadata +191 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjQwYmNmNWQzMDgxYjhmNTFkOGYxNGJmMTNjOWE1ODZiM2U5ZmJlYg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Y2Y1M2Y2MGZjNmY5MDFhY2NiN2RhYTk3MzliZDA3ZDg5NzFlZWIxMg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGE4ZWQzNjVmY2ZkZDgwOGE3Y2QyNzVlMGUxMGZkMjBkYmE2ZGJlNzFhY2M0
|
10
|
+
YjE2MmY5OThlOWI1MDcxNmJiNTRkNWM0OWM1MWUwMTNlNzYxODcxNjI5OGJh
|
11
|
+
N2M0OGI5OTEwOTM4M2U5ZTkyNTdmMjE3MTAwOTQwNThkYWZmMzk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NGFhZmE1YmMxNzdiZDZhZGFiMjYzNGZiN2UwNmFkZmYyZTZjMzdjMTNlODAz
|
14
|
+
ZjI5NjIyMzQ3NDQzZTRmZTQzNGNmYmM0YWI4MjI2ODBhMzdiNGE1NTc5Yzgy
|
15
|
+
OTk1YWFlODU5ZGYwNTBiNDNjMTJlMDkzODg5Y2I4YTYxMzQyNDY=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
bosh-manifests
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p484
|
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
guard 'rspec', spec_paths: ["spec"] do
|
2
|
+
notification :off
|
3
|
+
watch(%r{^spec/(.+_spec)\.rb$})
|
4
|
+
watch(%r{^lib/bosh/cli/commands/(.+)\.rb$}) { |m| "spec/plugin_spec.rb" }
|
5
|
+
watch(%r{^lib/bosh/cloudfoundry/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
6
|
+
watch('spec/spec_helper.rb') { "spec" }
|
7
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Ruben Koster
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Bosh workspace
|
2
|
+
|
3
|
+
## Design Goals
|
4
|
+
Enabling BOSH operators to share common configuration between different deployments.
|
5
|
+
For example having a `QA` and `production` deployment for which only networking differs.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Before you start make sure ruby, bundler and spiff are available on your system.
|
9
|
+
Instructions for installing spiff can found [here](https://github.com/cloudfoundry-incubator/spiff#installation).
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'bosh-workspace'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install bosh-workspace
|
22
|
+
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
This BOSH plugin improves the deployments work-flow,
|
26
|
+
by extending some of the build in commands bosh commands.
|
27
|
+
|
28
|
+
**Set deployment**
|
29
|
+
Sets the current deployment. Will search in `./deployments`.
|
30
|
+
```
|
31
|
+
bosh deployment cf-warden
|
32
|
+
```
|
33
|
+
|
34
|
+
**Prepare deployment**
|
35
|
+
Resolves upstream templates (via releases).
|
36
|
+
Resolves and uploads releases/stemcells.
|
37
|
+
```
|
38
|
+
bosh prepare deployment
|
39
|
+
```
|
40
|
+
|
41
|
+
**Deploy**
|
42
|
+
Merges the specified templates into one deployment manifests using spiff.
|
43
|
+
And uses this file to initiate a `deploy`.
|
44
|
+
```
|
45
|
+
bosh deploy
|
46
|
+
```
|
47
|
+
|
48
|
+
### Deployment file structure
|
49
|
+
A deployment file has the following structure:
|
50
|
+
|
51
|
+
**name:**
|
52
|
+
The name of your deployment
|
53
|
+
|
54
|
+
**director_uuid:**
|
55
|
+
The director_uuid of the targeted BOSH director
|
56
|
+
|
57
|
+
**releases:**
|
58
|
+
Array of releases used for resolving upstream templates
|
59
|
+
|
60
|
+
**meta:**
|
61
|
+
The meta hash is the last file merged into the final deployment file.
|
62
|
+
It can be used to define properties deployment specific properties.
|
63
|
+
|
64
|
+
## Contributing
|
65
|
+
|
66
|
+
1. Fork it
|
67
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
68
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
69
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
70
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bosh/workspace/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "bosh-workspace"
|
8
|
+
spec.version = Bosh::Manifests::VERSION
|
9
|
+
spec.authors = ["Ruben Koster"]
|
10
|
+
spec.email = ["rkoster@starkandwayne.com"]
|
11
|
+
spec.description = %q{Manage your bosh workspace}
|
12
|
+
spec.summary = %q{Manage your bosh workspace}
|
13
|
+
spec.homepage = "http://starkandwayne.com"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.required_ruby_version = '>= 2.0.0'
|
22
|
+
|
23
|
+
spec.add_runtime_dependency "bosh_cli", ">= 1.1722.0"
|
24
|
+
spec.add_runtime_dependency "git", "~> 1.2.6"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
27
|
+
spec.add_development_dependency "rspec", "~> 2.13.0"
|
28
|
+
spec.add_development_dependency "rspec-fire"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
spec.add_development_dependency "archive-zip", "~> 0.6.0"
|
31
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "bosh/workspace"
|
2
|
+
|
3
|
+
module Bosh::Cli::Command
|
4
|
+
class Manifests < Base
|
5
|
+
include Bosh::Cli::Validation
|
6
|
+
include Bosh::Manifests
|
7
|
+
include ProjectDeploymentHelper
|
8
|
+
|
9
|
+
# Hack to unregister original deployment command
|
10
|
+
Bosh::Cli::Config.instance_eval("@commands.delete('deployment')")
|
11
|
+
|
12
|
+
usage "deployment"
|
13
|
+
desc "Get/set current deployment"
|
14
|
+
def set_current(filename = nil)
|
15
|
+
unless filename.nil?
|
16
|
+
deployment = find_deployment(filename)
|
17
|
+
|
18
|
+
if project_deployment_file?(deployment)
|
19
|
+
self.project_deployment = deployment
|
20
|
+
validate_project_deployment
|
21
|
+
filename = project_deployment.merged_file
|
22
|
+
create_placeholder_deployment unless File.exists?(filename)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
deployment_cmd(options).set_current(filename)
|
27
|
+
end
|
28
|
+
|
29
|
+
usage "prepare deployment"
|
30
|
+
desc "Resolve deployment requirements"
|
31
|
+
def prepare
|
32
|
+
require_project_deployment
|
33
|
+
auth_required
|
34
|
+
|
35
|
+
release_manager.update_release_repos
|
36
|
+
|
37
|
+
# TODO: Implement
|
38
|
+
# current_deployment.stemcells.each do |stemcell|
|
39
|
+
# stemcell.upload unless stemcell.exists?
|
40
|
+
# end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Hack to unregister original deploy command
|
44
|
+
Bosh::Cli::Config.instance_eval("@commands.delete('deploy')")
|
45
|
+
|
46
|
+
usage "deploy"
|
47
|
+
desc "Deploy according to the currently selected deployment manifest"
|
48
|
+
option "--recreate", "recreate all VMs in deployment"
|
49
|
+
def deploy
|
50
|
+
if project_deployment?
|
51
|
+
require_project_deployment
|
52
|
+
build_project_deployment
|
53
|
+
end
|
54
|
+
|
55
|
+
deployment_cmd(options).perform
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def deployment_cmd(options = {})
|
61
|
+
cmd ||= Bosh::Cli::Command::Deployment.new
|
62
|
+
options.each do |key, value|
|
63
|
+
cmd.add_option key.to_sym, value
|
64
|
+
end
|
65
|
+
cmd
|
66
|
+
end
|
67
|
+
|
68
|
+
def release_manager
|
69
|
+
@release_manager ||= begin
|
70
|
+
ReleaseManager.new(project_deployment.releases, work_dir)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Bosh::Manifests
|
2
|
+
class DeploymentManifest
|
3
|
+
include Bosh::Cli::Validation
|
4
|
+
attr_writer :director_uuid
|
5
|
+
attr_reader :file
|
6
|
+
|
7
|
+
def initialize(file)
|
8
|
+
@file = file
|
9
|
+
err("Deployment file does not exist: #{file}") unless File.exist? @file
|
10
|
+
@manifest = Psych.load(File.read(@file))
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform_validation(options = {})
|
14
|
+
if @manifest.is_a?(Hash)
|
15
|
+
unless @manifest.has_key?("name") && @manifest["name"].is_a?(String)
|
16
|
+
errors << "Manifest should contain a name"
|
17
|
+
end
|
18
|
+
|
19
|
+
unless @manifest.has_key?("director_uuid") && @manifest["director_uuid"].is_a?(String)
|
20
|
+
errors << "Manifest should contain a director_uuid"
|
21
|
+
end
|
22
|
+
|
23
|
+
unless @manifest.has_key?("templates") && @manifest["templates"].is_a?(Array)
|
24
|
+
errors << "Manifest should contain templates"
|
25
|
+
end
|
26
|
+
|
27
|
+
unless @manifest.has_key?("releases") && @manifest["releases"].is_a?(Array)
|
28
|
+
errors << "Manifest should contain releases"
|
29
|
+
end
|
30
|
+
|
31
|
+
unless @manifest.has_key?("meta") && @manifest["meta"].is_a?(Hash)
|
32
|
+
errors << "Manifest should contain meta hash"
|
33
|
+
end
|
34
|
+
else
|
35
|
+
errors << "Manifest should be a hash"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def director_uuid
|
40
|
+
@director_uuid || @manifest["director_uuid"]
|
41
|
+
end
|
42
|
+
|
43
|
+
def merged_file
|
44
|
+
@merged_file ||= begin
|
45
|
+
path = File.join(file_dirname, "../.deployments", file_basename)
|
46
|
+
FileUtils.mkpath File.dirname(path)
|
47
|
+
File.expand_path path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
%w[name templates releases meta].each do |var|
|
52
|
+
define_method var do
|
53
|
+
@manifest[var]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def file_basename
|
60
|
+
File.basename(@file)
|
61
|
+
end
|
62
|
+
|
63
|
+
def file_dirname
|
64
|
+
File.dirname(@file)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Bosh::Manifests
|
2
|
+
module ProjectDeploymentHelper
|
3
|
+
|
4
|
+
def project_deployment?
|
5
|
+
File.exists?(project_deployment_file) &&
|
6
|
+
project_deployment_file?(project_deployment_file)
|
7
|
+
end
|
8
|
+
|
9
|
+
def project_deployment
|
10
|
+
@project_deployment ||= DeploymentManifest.new(project_deployment_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
def project_deployment=(deployment)
|
14
|
+
@project_deployment = DeploymentManifest.new(deployment)
|
15
|
+
end
|
16
|
+
|
17
|
+
def project_deployment_file?(deployment)
|
18
|
+
Psych.load(File.read(deployment)).has_key?("templates")
|
19
|
+
end
|
20
|
+
|
21
|
+
def require_project_deployment
|
22
|
+
unless project_deployment?
|
23
|
+
err("Deployment is not a project deployment: #{deployment}")
|
24
|
+
end
|
25
|
+
validate_project_deployment
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_placeholder_deployment
|
29
|
+
resolve_director_uuid
|
30
|
+
|
31
|
+
File.open(project_deployment.merged_file, "w") do |file|
|
32
|
+
file.write(placeholder_deployment_content)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_project_deployment
|
37
|
+
unless project_deployment.valid?
|
38
|
+
say("Validation errors:".make_red)
|
39
|
+
project_deployment.errors.each { |error| say("- #{error}") }
|
40
|
+
err("'#{project_deployment.file}' is not valid".make_red)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_project_deployment
|
45
|
+
resolve_director_uuid
|
46
|
+
|
47
|
+
say("Generating deployment manifest")
|
48
|
+
ManifestBuilder.build(project_deployment, work_dir)
|
49
|
+
end
|
50
|
+
|
51
|
+
def resolve_director_uuid
|
52
|
+
use_targeted_director_uuid if director_uuid_current?
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def use_targeted_director_uuid
|
58
|
+
no_warden_error unless warden_cpi?
|
59
|
+
project_deployment.director_uuid = bosh_uuid
|
60
|
+
end
|
61
|
+
|
62
|
+
def no_warden_error
|
63
|
+
say("Please put 'director_uuid: #{bosh_uuid}' in '#{deployment}'")
|
64
|
+
err("'director_uuid: current' may not be used in production")
|
65
|
+
end
|
66
|
+
|
67
|
+
def director_uuid_current?
|
68
|
+
project_deployment.director_uuid == "current"
|
69
|
+
end
|
70
|
+
|
71
|
+
def warden_cpi?
|
72
|
+
bosh_status["cpi"] == "warden"
|
73
|
+
end
|
74
|
+
|
75
|
+
def project_deployment_file
|
76
|
+
@project_deployment_file ||= begin
|
77
|
+
path = File.join(deployment_dir, "../deployments", deployment_basename)
|
78
|
+
File.expand_path path
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def deployment_dir
|
83
|
+
File.dirname(deployment)
|
84
|
+
end
|
85
|
+
|
86
|
+
def deployment_basename
|
87
|
+
File.basename(deployment)
|
88
|
+
end
|
89
|
+
|
90
|
+
def placeholder_deployment_content
|
91
|
+
{ "director_uuid" => project_deployment.director_uuid }.to_yaml +
|
92
|
+
"# Don't edit; placeholder deployment for: #{project_deployment.file}"
|
93
|
+
end
|
94
|
+
|
95
|
+
def bosh_status
|
96
|
+
@bosh_status ||= director.get_status
|
97
|
+
end
|
98
|
+
|
99
|
+
def bosh_uuid
|
100
|
+
bosh_status["uuid"]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Bosh::Manifests
|
2
|
+
module SpiffHelper
|
3
|
+
include Bosh::Exec
|
4
|
+
|
5
|
+
def spiff_merge(templates, target_file)
|
6
|
+
spiff(:merge, templates) do |output|
|
7
|
+
File.open(target_file, 'w') { |file| file.write(output) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def spiff(verb, params)
|
14
|
+
cmd = ["spiff", verb.to_s] + params + ["2>&1"]
|
15
|
+
sh(cmd.join(" "), :yield => :on_false) do |result|
|
16
|
+
spiff_not_found if result.not_found?
|
17
|
+
spiff_failed(result.command, result.output) if result.failed?
|
18
|
+
yield result.output
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def spiff_not_found
|
23
|
+
say("Can't find spiff in $PATH".make_red)
|
24
|
+
say("Go to spiff.cfapps.io for installation instructions")
|
25
|
+
err("Please make sure spiff is installed")
|
26
|
+
end
|
27
|
+
|
28
|
+
def spiff_failed(command, output)
|
29
|
+
say("Command failed: '#{command}'")
|
30
|
+
err(output)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Bosh::Manifests
|
2
|
+
class ManifestBuilder
|
3
|
+
include Bosh::Manifests::SpiffHelper
|
4
|
+
|
5
|
+
def self.build(manifest, work_dir)
|
6
|
+
manifest_builder = ManifestBuilder.new(manifest, work_dir)
|
7
|
+
manifest_builder.merge_templates
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(manifest, work_dir)
|
11
|
+
@manifest = manifest
|
12
|
+
@work_dir = work_dir
|
13
|
+
end
|
14
|
+
|
15
|
+
def merge_templates
|
16
|
+
spiff_merge spiff_template_paths, @manifest.merged_file
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def spiff_template_paths
|
22
|
+
spiff_templates = template_paths
|
23
|
+
spiff_templates << stub_file_path
|
24
|
+
end
|
25
|
+
|
26
|
+
def template_paths
|
27
|
+
@manifest.templates.map { |t| template_path(t) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def stub_file_path
|
31
|
+
path = hidden_file_path(:stubs)
|
32
|
+
File.open(path, 'w') { |file| file.write(stub_file_content) }
|
33
|
+
path
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub_file_content
|
37
|
+
{
|
38
|
+
"director_uuid" => @manifest.director_uuid,
|
39
|
+
"releases" => filterd_releases,
|
40
|
+
"meta" => @manifest.meta
|
41
|
+
}.to_yaml
|
42
|
+
end
|
43
|
+
|
44
|
+
def filterd_releases
|
45
|
+
allowed_keys = %w[name version]
|
46
|
+
@manifest.releases.map do |release|
|
47
|
+
release.select { |key| allowed_keys.include?(key) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def hidden_file_path(type)
|
52
|
+
File.join(hidden_dir_path(type), "#{@manifest.name}.yml")
|
53
|
+
end
|
54
|
+
|
55
|
+
def hidden_dir_path(name)
|
56
|
+
dir = File.join(@work_dir, ".#{name.to_s}")
|
57
|
+
Dir.mkdir(dir) unless File.exists? dir
|
58
|
+
dir
|
59
|
+
end
|
60
|
+
|
61
|
+
# TODO move to template validator which should have access to @work_dir
|
62
|
+
def template_path(template)
|
63
|
+
path = File.join(@work_dir, "templates", template)
|
64
|
+
err("Template does not exist: #{template}") unless File.exists? path
|
65
|
+
path
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "git"
|
2
|
+
module Bosh::Manifests
|
3
|
+
class Release
|
4
|
+
def initialize(release, releases_dir)
|
5
|
+
@name = release["name"]
|
6
|
+
@version = release["version"]
|
7
|
+
@git_uri = release["git"]
|
8
|
+
@work_dir = File.join(releases_dir)
|
9
|
+
end
|
10
|
+
|
11
|
+
def checkout_current_version
|
12
|
+
repo.pull
|
13
|
+
repo.checkout(current_version_ref)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def repo
|
19
|
+
if File.directory?(repo_dir)
|
20
|
+
@repo ||= Git.open(repo_dir)
|
21
|
+
else
|
22
|
+
FileUtils.mkdir_p(@work_dir)
|
23
|
+
@repo = Git.clone(@git_uri, @name, path: @work_dir)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def current_version_ref
|
28
|
+
repo.log().object("releases/#{available_versions[current_version]}")
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_version
|
32
|
+
if @version == "latest"
|
33
|
+
available_versions.keys.sort.last
|
34
|
+
else
|
35
|
+
version = @version.to_i
|
36
|
+
unless available_versions[version]
|
37
|
+
err("Could not find version: #{@version} for release: #{@name}")
|
38
|
+
end
|
39
|
+
version
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# transforms releases/foo-1.yml, releases/bar-2.yml to:
|
44
|
+
# { "1" => foo-1.yml, "2" => bar-2.yml }
|
45
|
+
def available_versions
|
46
|
+
@available_versions ||= begin
|
47
|
+
Hash[Dir[File.join(repo_dir, "releases", "*.yml")].
|
48
|
+
reject { |f| f[/index.yml/] }.
|
49
|
+
map { |dir| File.basename(dir) }.
|
50
|
+
map { |version| [ version[/(\d+)/].to_i, version ] }]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def repo_dir
|
55
|
+
File.join(@work_dir, @name)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Bosh::Manifests
|
2
|
+
class ReleaseManager
|
3
|
+
def initialize(releases, work_dir)
|
4
|
+
releases_dir = File.join(work_dir, ".releases")
|
5
|
+
@releases = releases.map { |r| Release.new(r, releases_dir) }
|
6
|
+
end
|
7
|
+
|
8
|
+
def update_release_repos
|
9
|
+
@releases.each do |release|
|
10
|
+
release.checkout_current_version
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Bosh; module Manifests; end; end
|
2
|
+
|
3
|
+
require "cli/core_ext"
|
4
|
+
require "cli/validation"
|
5
|
+
|
6
|
+
require "bosh/workspace/helpers/spiff_helper"
|
7
|
+
require "bosh/workspace/helpers/project_deployment_helper"
|
8
|
+
|
9
|
+
require "bosh/workspace/manifest_builder"
|
10
|
+
require "bosh/workspace/release_manager"
|
11
|
+
require "bosh/workspace/release"
|
12
|
+
require "bosh/workspace/deployment_manifest"
|
13
|
+
require "bosh/workspace/version"
|
File without changes
|
File without changes
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
name: foo
|
@@ -0,0 +1 @@
|
|
1
|
+
name: bar
|
File without changes
|