bosh-workspace 0.7.0 → 0.8.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 +5 -13
- data/.ruby-version +1 -1
- data/.travis.yml +8 -0
- data/Gemfile +4 -0
- data/Guardfile +2 -2
- data/README.md +78 -39
- data/Rakefile +4 -0
- data/bosh-workspace.gemspec +4 -1
- data/lib/bosh/cli/commands/prepare.rb +74 -0
- data/lib/bosh/cli/commands/{01_make_manifest.rb → project_deployment.rb} +4 -26
- data/lib/bosh/workspace.rb +7 -3
- data/lib/bosh/workspace/helpers/dns_helper.rb +72 -0
- data/lib/bosh/workspace/helpers/project_deployment_helper.rb +8 -3
- data/lib/bosh/workspace/helpers/release_helper.rb +33 -0
- data/lib/bosh/workspace/helpers/spiff_helper.rb +1 -1
- data/lib/bosh/workspace/helpers/stemcell_helper.rb +45 -0
- data/lib/bosh/workspace/manifest_builder.rb +10 -25
- data/lib/bosh/workspace/project_deployment.rb +77 -0
- data/lib/bosh/workspace/release.rb +41 -33
- data/lib/bosh/workspace/stemcell.rb +23 -0
- data/lib/bosh/workspace/stub_file.rb +44 -0
- data/lib/bosh/workspace/version.rb +1 -1
- data/spec/assets/dns/job-properties.yml +22 -0
- data/spec/assets/dns/jobs.yml +18 -0
- data/spec/assets/dns/networks-manual.yml +19 -0
- data/spec/assets/dns/networks-no-manual.yml +18 -0
- data/spec/assets/dns/properties.yml +29 -0
- data/spec/assets/foo-boshrelease-repo.zip +0 -0
- data/spec/commands/prepare_spec.rb +99 -0
- data/spec/commands/{command_make_manifest_spec.rb → project_deployment_spec.rb} +4 -23
- data/spec/helpers/dns_helper_spec.rb +59 -0
- data/spec/helpers/project_deployment_helper_spec.rb +24 -23
- data/spec/helpers/release_helper_spec.rb +76 -0
- data/spec/helpers/spiff_helper_spec.rb +2 -2
- data/spec/helpers/stemcell_helper_spec.rb +89 -0
- data/spec/manifest_builder_spec.rb +24 -45
- data/spec/project_deployment_spec.rb +157 -0
- data/spec/release_spec.rb +39 -18
- data/spec/spec_helper.rb +9 -3
- data/spec/stemcell_spec.rb +28 -0
- data/spec/stub_file_spec.rb +74 -0
- metadata +90 -22
- data/lib/bosh/workspace/deployment_manifest.rb +0 -67
- data/lib/bosh/workspace/release_manager.rb +0 -14
- data/spec/deployment_manifest_spec.rb +0 -93
- data/spec/release_manager_spec.rb +0 -17
@@ -0,0 +1,33 @@
|
|
1
|
+
module Bosh::Workspace
|
2
|
+
module ReleaseHelper
|
3
|
+
include ProjectDeploymentHelper
|
4
|
+
|
5
|
+
def release_uploaded?(name, version)
|
6
|
+
remote_release = director.get_release(name) rescue nil
|
7
|
+
remote_release && remote_release["versions"].include?(version.to_s)
|
8
|
+
end
|
9
|
+
|
10
|
+
def release_upload(manifest_file)
|
11
|
+
release_cmd.upload(manifest_file)
|
12
|
+
end
|
13
|
+
|
14
|
+
def releases_dir
|
15
|
+
@releases_dir ||= begin
|
16
|
+
FileUtils.mkdir_p(File.join(work_dir, ".releases")).first
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def project_deployment_releases
|
21
|
+
@releases ||= begin
|
22
|
+
project_deployment.releases.map { |r| Release.new(r, releases_dir) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def release_cmd
|
29
|
+
@release_cmd ||= Bosh::Cli::Command::Release.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Bosh::Workspace
|
2
|
+
module StemcellHelper
|
3
|
+
include ProjectDeploymentHelper
|
4
|
+
|
5
|
+
def stemcell_download(stemcell_name)
|
6
|
+
Dir.chdir(stemcells_dir) do
|
7
|
+
say "Downloading stemcell '#{stemcell_name}'"
|
8
|
+
nl
|
9
|
+
stemcell_cmd.download_public(stemcell_name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def stemcell_upload(stemcell_file)
|
14
|
+
say "Uploading stemcell '#{File.basename(stemcell_file)}'"
|
15
|
+
nl
|
16
|
+
stemcell_cmd.upload(stemcell_file)
|
17
|
+
end
|
18
|
+
|
19
|
+
def stemcell_uploaded?(name, version)
|
20
|
+
existing = director.list_stemcells.select do |sc|
|
21
|
+
sc['name'] == name && sc['version'] == version.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
!existing.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
def stemcells_dir
|
28
|
+
@stemcells_dir ||= begin
|
29
|
+
FileUtils.mkdir_p(File.join(work_dir, ".stemcells")).first
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def project_deployment_stemcells
|
34
|
+
@stemcells ||= begin
|
35
|
+
project_deployment.stemcells.map { |s| Stemcell.new(s, stemcells_dir) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def stemcell_cmd
|
42
|
+
@stemcell_cmd ||= Bosh::Cli::Command::Stemcell.new
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -1,19 +1,19 @@
|
|
1
|
-
module Bosh::
|
1
|
+
module Bosh::Workspace
|
2
2
|
class ManifestBuilder
|
3
|
-
include Bosh::
|
3
|
+
include Bosh::Workspace::SpiffHelper
|
4
4
|
|
5
|
-
def self.build(
|
6
|
-
manifest_builder = ManifestBuilder.new(
|
5
|
+
def self.build(project_deployment, work_dir)
|
6
|
+
manifest_builder = ManifestBuilder.new(project_deployment, work_dir)
|
7
7
|
manifest_builder.merge_templates
|
8
8
|
end
|
9
9
|
|
10
|
-
def initialize(
|
11
|
-
@
|
10
|
+
def initialize(project_deployment, work_dir)
|
11
|
+
@project_deployment = project_deployment
|
12
12
|
@work_dir = work_dir
|
13
13
|
end
|
14
14
|
|
15
15
|
def merge_templates
|
16
|
-
spiff_merge spiff_template_paths, @
|
16
|
+
spiff_merge spiff_template_paths, @project_deployment.merged_file
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
@@ -24,32 +24,17 @@ module Bosh::Manifests
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def template_paths
|
27
|
-
@
|
27
|
+
@project_deployment.templates.map { |t| template_path(t) }
|
28
28
|
end
|
29
29
|
|
30
30
|
def stub_file_path
|
31
31
|
path = hidden_file_path(:stubs)
|
32
|
-
|
32
|
+
StubFile.create(path, @project_deployment)
|
33
33
|
path
|
34
34
|
end
|
35
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
36
|
def hidden_file_path(type)
|
52
|
-
File.join(hidden_dir_path(type), "#{@
|
37
|
+
File.join(hidden_dir_path(type), "#{@project_deployment.name}.yml")
|
53
38
|
end
|
54
39
|
|
55
40
|
def hidden_dir_path(name)
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "membrane"
|
2
|
+
module Bosh::Workspace
|
3
|
+
class ProjectDeployment
|
4
|
+
include Bosh::Cli::Validation
|
5
|
+
attr_writer :director_uuid
|
6
|
+
attr_reader :file
|
7
|
+
|
8
|
+
RELEASE_SCHEMA = Membrane::SchemaParser.parse do
|
9
|
+
{
|
10
|
+
"name" => String,
|
11
|
+
"version" => enum(Integer, "latest"),
|
12
|
+
"git" => String,
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
STEMCELL_SCHEMA = Membrane::SchemaParser.parse do
|
17
|
+
{
|
18
|
+
"name" => String,
|
19
|
+
"version" => enum(Integer, "latest"),
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
|
24
|
+
|
25
|
+
PROJECT_DEPLOYMENT_SCHEMA = Membrane::SchemaParser.parse do
|
26
|
+
{
|
27
|
+
"name" => String,
|
28
|
+
"director_uuid" => enum(UUID_REGEX, "current"),
|
29
|
+
optional("domain_name") => String,
|
30
|
+
"releases" => [RELEASE_SCHEMA],
|
31
|
+
"stemcells" => [STEMCELL_SCHEMA],
|
32
|
+
"templates" => [String],
|
33
|
+
"meta" => Hash
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def initialize(file)
|
38
|
+
@file = file
|
39
|
+
err("Deployment file does not exist: #{file}") unless File.exist? @file
|
40
|
+
@manifest = Psych.load(File.read(@file))
|
41
|
+
end
|
42
|
+
|
43
|
+
def perform_validation(options = {})
|
44
|
+
PROJECT_DEPLOYMENT_SCHEMA.validate @manifest
|
45
|
+
rescue Membrane::SchemaValidationError => e
|
46
|
+
errors << e.message
|
47
|
+
end
|
48
|
+
|
49
|
+
def director_uuid
|
50
|
+
@director_uuid || @manifest["director_uuid"]
|
51
|
+
end
|
52
|
+
|
53
|
+
def merged_file
|
54
|
+
@merged_file ||= begin
|
55
|
+
path = File.join(file_dirname, "../.deployments", file_basename)
|
56
|
+
FileUtils.mkpath File.dirname(path)
|
57
|
+
File.expand_path path
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
%w[name templates releases stemcells meta domain_name].each do |var|
|
62
|
+
define_method var do
|
63
|
+
@manifest[var]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def file_basename
|
70
|
+
File.basename(@file)
|
71
|
+
end
|
72
|
+
|
73
|
+
def file_dirname
|
74
|
+
File.dirname(@file)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -1,58 +1,66 @@
|
|
1
1
|
require "git"
|
2
|
-
module Bosh::
|
2
|
+
module Bosh::Workspace
|
3
3
|
class Release
|
4
|
+
attr_reader :name, :git_uri, :repo_dir
|
5
|
+
|
4
6
|
def initialize(release, releases_dir)
|
5
7
|
@name = release["name"]
|
6
|
-
@
|
8
|
+
@version_ref = release["version"]
|
7
9
|
@git_uri = release["git"]
|
8
|
-
@
|
10
|
+
@repo_dir = File.join(releases_dir, @name)
|
11
|
+
init_repo
|
9
12
|
end
|
10
13
|
|
11
|
-
def
|
12
|
-
repo.pull
|
13
|
-
repo.checkout(
|
14
|
+
def update_repo
|
15
|
+
@repo.pull
|
16
|
+
@repo.checkout(ref)
|
14
17
|
end
|
15
18
|
|
16
|
-
|
19
|
+
def manifest_file
|
20
|
+
File.join(repo_dir, manifest)
|
21
|
+
end
|
17
22
|
|
18
|
-
def
|
19
|
-
|
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
|
23
|
+
def manifest
|
24
|
+
final_releases[version]
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
|
27
|
+
def name_version
|
28
|
+
"#{name}/#{version}"
|
29
29
|
end
|
30
30
|
|
31
|
-
def
|
32
|
-
if @
|
33
|
-
|
34
|
-
|
35
|
-
version = @version.to_i
|
36
|
-
unless available_versions[version]
|
37
|
-
err("Could not find version: #{@version} for release: #{@name}")
|
38
|
-
end
|
39
|
-
version
|
31
|
+
def version
|
32
|
+
return final_releases.keys.sort.last if @version_ref == "latest"
|
33
|
+
unless final_releases[@version_ref.to_i]
|
34
|
+
err("Could not find version: #{@version_ref} for release: #{@name}")
|
40
35
|
end
|
36
|
+
@version_ref.to_i
|
41
37
|
end
|
42
38
|
|
39
|
+
private
|
40
|
+
|
43
41
|
# transforms releases/foo-1.yml, releases/bar-2.yml to:
|
44
42
|
# { "1" => foo-1.yml, "2" => bar-2.yml }
|
45
|
-
def
|
46
|
-
@
|
47
|
-
Hash[Dir[File.join(repo_dir, "releases", "*.yml")]
|
48
|
-
|
49
|
-
|
50
|
-
|
43
|
+
def final_releases
|
44
|
+
@final_releases ||= begin
|
45
|
+
Hash[Dir[File.join(repo_dir, "releases", "*.yml")]
|
46
|
+
.reject { |f| f[/index.yml/] }
|
47
|
+
.map { |dir| File.join("releases", File.basename(dir)) }
|
48
|
+
.map { |version| [version[/(\d+)/].to_i, version] }]
|
51
49
|
end
|
52
50
|
end
|
53
51
|
|
54
|
-
def
|
55
|
-
|
52
|
+
def ref
|
53
|
+
@repo.log.object(manifest).first
|
54
|
+
end
|
55
|
+
|
56
|
+
def init_repo
|
57
|
+
if File.directory?(repo_dir)
|
58
|
+
@repo ||= Git.open(repo_dir)
|
59
|
+
else
|
60
|
+
releases_dir = File.dirname(repo_dir)
|
61
|
+
FileUtils.mkdir_p(releases_dir)
|
62
|
+
@repo = Git.clone(@git_uri, @name, path: releases_dir)
|
63
|
+
end
|
56
64
|
end
|
57
65
|
end
|
58
66
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Bosh::Workspace
|
2
|
+
class Stemcell
|
3
|
+
attr_reader :name, :version, :file
|
4
|
+
|
5
|
+
def initialize(stemcell, stemcells_dir)
|
6
|
+
@name = stemcell["name"]
|
7
|
+
@version = stemcell["version"]
|
8
|
+
@file = File.join(stemcells_dir, file_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def name_version
|
12
|
+
"#{name}/#{version}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_name
|
16
|
+
name.gsub(/^bosh-/, "bosh-stemcell-#{version}-") + ".tgz"
|
17
|
+
end
|
18
|
+
|
19
|
+
def downloaded?
|
20
|
+
File.exists? file
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Bosh::Workspace
|
2
|
+
class StubFile
|
3
|
+
attr_reader :name, :director_uuid
|
4
|
+
|
5
|
+
def self.create(path, project_deployment)
|
6
|
+
self.new(project_deployment).tap { |stub| stub.write(path) }
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(project_deployment)
|
10
|
+
@name = project_deployment.name
|
11
|
+
@director_uuid = project_deployment.director_uuid
|
12
|
+
@releases = project_deployment.releases
|
13
|
+
@stemcells = project_deployment.stemcells
|
14
|
+
@meta = project_deployment.meta
|
15
|
+
end
|
16
|
+
|
17
|
+
def write(file)
|
18
|
+
IO.write file, content.to_yaml
|
19
|
+
end
|
20
|
+
|
21
|
+
def content
|
22
|
+
{
|
23
|
+
"name" => name,
|
24
|
+
"director_uuid" => director_uuid,
|
25
|
+
"releases" => releases,
|
26
|
+
"meta" => meta
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def releases
|
31
|
+
@releases.map { |r| r.select { |key| %w[name version].include?(key) } }
|
32
|
+
end
|
33
|
+
|
34
|
+
def meta
|
35
|
+
out = case @stemcells.size
|
36
|
+
when 1
|
37
|
+
{ "stemcell" => @stemcells.first }
|
38
|
+
else
|
39
|
+
{ "stemcells" => @stemcells }
|
40
|
+
end
|
41
|
+
out.merge(@meta)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
name: foo
|
2
|
+
|
3
|
+
networks:
|
4
|
+
- name: default
|
5
|
+
type: manual
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
- name: first_job_az1
|
9
|
+
networks:
|
10
|
+
- name: default
|
11
|
+
static_ips:
|
12
|
+
- 10.0.0.50
|
13
|
+
|
14
|
+
- name: second_job_az1
|
15
|
+
networks:
|
16
|
+
- name: default
|
17
|
+
static_ips:
|
18
|
+
- 10.0.0.51
|
19
|
+
properties:
|
20
|
+
job1:
|
21
|
+
foo: bar
|
22
|
+
address: 10.0.0.50
|
@@ -0,0 +1,18 @@
|
|
1
|
+
networks:
|
2
|
+
- name: default
|
3
|
+
type: manual
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
- name: job1
|
7
|
+
networks:
|
8
|
+
- name: default
|
9
|
+
static_ips:
|
10
|
+
- 10.0.0.50
|
11
|
+
- name: job2
|
12
|
+
networks:
|
13
|
+
- name: default
|
14
|
+
static_ips:
|
15
|
+
- 10.0.0.51
|
16
|
+
- name: job3
|
17
|
+
networks:
|
18
|
+
- name: default
|