vagrant-bosh 0.0.1
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 +7 -0
- data/.gitignore +12 -0
- data/.gitmodules +6 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +73 -0
- data/Rakefile +2 -0
- data/dev/.gitignore +1 -0
- data/dev/Vagrantfile +30 -0
- data/dev/example-bosh-manifest.yml +188 -0
- data/dev/example-winston-manifest.yml +70 -0
- data/go/.gitignore +11 -0
- data/go/bin/build +10 -0
- data/go/bin/build-linux-amd64 +9 -0
- data/go/bin/env +13 -0
- data/go/bin/go +5 -0
- data/go/bin/golint +19 -0
- data/go/bin/test +37 -0
- data/go/src/boshprovisioner/agent/client/client_interface.go +73 -0
- data/go/src/boshprovisioner/agent/client/fakes/fake_client.go +81 -0
- data/go/src/boshprovisioner/agent/client/http_client.go +299 -0
- data/go/src/boshprovisioner/agent/client/http_client_envelope.go +107 -0
- data/go/src/boshprovisioner/deployment/deployment.go +221 -0
- data/go/src/boshprovisioner/deployment/instance.go +54 -0
- data/go/src/boshprovisioner/deployment/manifest/deployment.go +80 -0
- data/go/src/boshprovisioner/deployment/manifest/ips.go +23 -0
- data/go/src/boshprovisioner/deployment/manifest/manifest.go +143 -0
- data/go/src/boshprovisioner/deployment/manifest/manifest_suite_test.go +13 -0
- data/go/src/boshprovisioner/deployment/manifest/manifest_test.go +86 -0
- data/go/src/boshprovisioner/deployment/manifest/syntax_validator.go +186 -0
- data/go/src/boshprovisioner/deployment/manifest/watch_time.go +47 -0
- data/go/src/boshprovisioner/deployment/manifest_reader.go +46 -0
- data/go/src/boshprovisioner/deployment/reader_factory.go +25 -0
- data/go/src/boshprovisioner/deployment/semantic_validator.go +111 -0
- data/go/src/boshprovisioner/downloader/blobstore_downloader.go +55 -0
- data/go/src/boshprovisioner/downloader/default_mux_downloader.go +22 -0
- data/go/src/boshprovisioner/downloader/downloader_interface.go +6 -0
- data/go/src/boshprovisioner/downloader/http_downloader.go +53 -0
- data/go/src/boshprovisioner/downloader/local_fs_downloader.go +48 -0
- data/go/src/boshprovisioner/downloader/mux_downloader.go +69 -0
- data/go/src/boshprovisioner/eventlog/log.go +72 -0
- data/go/src/boshprovisioner/eventlog/stage.go +39 -0
- data/go/src/boshprovisioner/eventlog/task.go +58 -0
- data/go/src/boshprovisioner/index/file_index.go +289 -0
- data/go/src/boshprovisioner/index/file_index_test.go +296 -0
- data/go/src/boshprovisioner/index/index_interface.go +18 -0
- data/go/src/boshprovisioner/index/index_suite_test.go +13 -0
- data/go/src/boshprovisioner/instance/templatescompiler/concrete_templates_compiler.go +273 -0
- data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/erb_renderer.go +117 -0
- data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/erbrenderer_suite_test.go +13 -0
- data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/render_properties.go +77 -0
- data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/render_properties_test.go +142 -0
- data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/template_evaluation_context.go +85 -0
- data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/template_evaluation_context_rb.go +155 -0
- data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/concrete_jobs_repository.go +64 -0
- data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/concrete_runtime_packages_repository.go +105 -0
- data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/concrete_template_to_job_repository.go +76 -0
- data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/jobs_repository_interface.go +31 -0
- data/go/src/boshprovisioner/instance/templatescompiler/rendered_archives_compiler.go +81 -0
- data/go/src/boshprovisioner/instance/templatescompiler/templates_compiler_interface.go +20 -0
- data/go/src/boshprovisioner/instance/templatescompiler/templatesrepo/ct_repository.go +54 -0
- data/go/src/boshprovisioner/instance/templatescompiler/templatesrepo/templates_repository_interface.go +16 -0
- data/go/src/boshprovisioner/instance/updater/applier/applier.go +93 -0
- data/go/src/boshprovisioner/instance/updater/applier/empty_state.go +66 -0
- data/go/src/boshprovisioner/instance/updater/applier/job_state.go +178 -0
- data/go/src/boshprovisioner/instance/updater/drainer.go +72 -0
- data/go/src/boshprovisioner/instance/updater/preparer.go +39 -0
- data/go/src/boshprovisioner/instance/updater/starter.go +36 -0
- data/go/src/boshprovisioner/instance/updater/stopper.go +36 -0
- data/go/src/boshprovisioner/instance/updater/updater.go +102 -0
- data/go/src/boshprovisioner/instance/updater/updater_factory.go +83 -0
- data/go/src/boshprovisioner/instance/updater/updater_suite_test.go +13 -0
- data/go/src/boshprovisioner/instance/updater/waiter.go +77 -0
- data/go/src/boshprovisioner/instance/updater/waiter_test.go +103 -0
- data/go/src/boshprovisioner/main/config.go +77 -0
- data/go/src/boshprovisioner/main/main.go +183 -0
- data/go/src/boshprovisioner/main/repos_factory.go +96 -0
- data/go/src/boshprovisioner/packagescompiler/compiledpackagesrepo/compiled_packages_repository_interface.go +17 -0
- data/go/src/boshprovisioner/packagescompiler/compiledpackagesrepo/concrete_compiled_packages_repository.go +61 -0
- data/go/src/boshprovisioner/packagescompiler/concrete_packages_compiler.go +179 -0
- data/go/src/boshprovisioner/packagescompiler/concrete_packages_compiler_factory.go +48 -0
- data/go/src/boshprovisioner/packagescompiler/packages_compiler_interface.go +20 -0
- data/go/src/boshprovisioner/packagescompiler/packagesrepo/concrete_packages_repository.go +65 -0
- data/go/src/boshprovisioner/packagescompiler/packagesrepo/packages_repository_interface.go +16 -0
- data/go/src/boshprovisioner/provisioner/blobstore_config.go +65 -0
- data/go/src/boshprovisioner/provisioner/blobstore_provisioner.go +38 -0
- data/go/src/boshprovisioner/provisioner/deployment_provisioner.go +97 -0
- data/go/src/boshprovisioner/provisioner/instance_provisioner.go +48 -0
- data/go/src/boshprovisioner/provisioner/release_compiler.go +133 -0
- data/go/src/boshprovisioner/release/job/job.go +86 -0
- data/go/src/boshprovisioner/release/job/manifest/manifest.go +79 -0
- data/go/src/boshprovisioner/release/job/manifest/manifest_suite_test.go +13 -0
- data/go/src/boshprovisioner/release/job/manifest/manifest_test.go +42 -0
- data/go/src/boshprovisioner/release/job/manifest/syntax_validator.go +43 -0
- data/go/src/boshprovisioner/release/job/reader_factory.go +34 -0
- data/go/src/boshprovisioner/release/job/tar_reader.go +133 -0
- data/go/src/boshprovisioner/release/manifest/manifest.go +96 -0
- data/go/src/boshprovisioner/release/manifest_reader.go +29 -0
- data/go/src/boshprovisioner/release/reader_factory.go +34 -0
- data/go/src/boshprovisioner/release/release.go +144 -0
- data/go/src/boshprovisioner/release/release_suite_test.go +13 -0
- data/go/src/boshprovisioner/release/release_test.go +129 -0
- data/go/src/boshprovisioner/release/tar_reader.go +139 -0
- data/go/src/boshprovisioner/releasesrepo/blobstore_releases_repository.go +114 -0
- data/go/src/boshprovisioner/releasesrepo/releases_repository_interface.go +15 -0
- data/go/src/boshprovisioner/tar/cmd_compressor.go +68 -0
- data/go/src/boshprovisioner/tar/cmd_extractor.go +47 -0
- data/go/src/boshprovisioner/tar/compressor_interface.go +6 -0
- data/go/src/boshprovisioner/tar/extractor_interface.go +6 -0
- data/go/src/boshprovisioner/util/string_keyed.go +70 -0
- data/go/src/boshprovisioner/vm/agent_provisioner.go +266 -0
- data/go/src/boshprovisioner/vm/asset_manager.go +61 -0
- data/go/src/boshprovisioner/vm/deps_provisioner.go +92 -0
- data/go/src/boshprovisioner/vm/monit_provisioner.go +83 -0
- data/go/src/boshprovisioner/vm/runit_provisioner.go +225 -0
- data/go/src/boshprovisioner/vm/simple_cmds.go +54 -0
- data/go/src/boshprovisioner/vm/vcap_user_provisioner.go +120 -0
- data/go/src/boshprovisioner/vm/vm.go +19 -0
- data/go/src/boshprovisioner/vm/vm_provisioner.go +57 -0
- data/go/src/boshprovisioner/vm/vm_provisioner_factory.go +97 -0
- data/lib/vagrant-bosh/asset_uploader.rb +53 -0
- data/lib/vagrant-bosh/assets/agent/agent-log +5 -0
- data/lib/vagrant-bosh/assets/agent/agent-run +12 -0
- data/lib/vagrant-bosh/assets/agent/agent.cert +18 -0
- data/lib/vagrant-bosh/assets/agent/agent.json +9 -0
- data/lib/vagrant-bosh/assets/agent/agent.key +27 -0
- data/lib/vagrant-bosh/assets/agent/bosh-agent +0 -0
- data/lib/vagrant-bosh/assets/agent/bosh-agent-rc +18 -0
- data/lib/vagrant-bosh/assets/agent/bosh-blobstore-dav +0 -0
- data/lib/vagrant-bosh/assets/monit/monit +0 -0
- data/lib/vagrant-bosh/assets/monit/monit-log +5 -0
- data/lib/vagrant-bosh/assets/monit/monit-run +9 -0
- data/lib/vagrant-bosh/assets/monit/monitrc +8 -0
- data/lib/vagrant-bosh/assets/provisioner +0 -0
- data/lib/vagrant-bosh/bootstrapper.rb +59 -0
- data/lib/vagrant-bosh/communicator.rb +50 -0
- data/lib/vagrant-bosh/config.rb +15 -0
- data/lib/vagrant-bosh/errors.rb +11 -0
- data/lib/vagrant-bosh/plugin.rb +25 -0
- data/lib/vagrant-bosh/provisioner.rb +46 -0
- data/lib/vagrant-bosh/provisioner_tracker.rb +41 -0
- data/lib/vagrant-bosh/ui.rb +77 -0
- data/lib/vagrant-bosh/version.rb +5 -0
- data/lib/vagrant-bosh.rb +15 -0
- data/templates/locales/en.yml +15 -0
- data/vagrant-bosh.gemspec +20 -0
- metadata +191 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
package release
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
boshlog "bosh/logger"
|
|
5
|
+
boshsys "bosh/system"
|
|
6
|
+
|
|
7
|
+
bpdload "boshprovisioner/downloader"
|
|
8
|
+
bptar "boshprovisioner/tar"
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
type ReaderFactory struct {
|
|
12
|
+
downloader bpdload.Downloader
|
|
13
|
+
extractor bptar.Extractor
|
|
14
|
+
fs boshsys.FileSystem
|
|
15
|
+
logger boshlog.Logger
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
func NewReaderFactory(
|
|
19
|
+
downloader bpdload.Downloader,
|
|
20
|
+
extractor bptar.Extractor,
|
|
21
|
+
fs boshsys.FileSystem,
|
|
22
|
+
logger boshlog.Logger,
|
|
23
|
+
) ReaderFactory {
|
|
24
|
+
return ReaderFactory{
|
|
25
|
+
downloader: downloader,
|
|
26
|
+
extractor: extractor,
|
|
27
|
+
fs: fs,
|
|
28
|
+
logger: logger,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func (rf ReaderFactory) NewTarReader(path string) *TarReader {
|
|
33
|
+
return NewTarReader(path, rf.downloader, rf.extractor, rf.fs, rf.logger)
|
|
34
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
package release
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bprelman "boshprovisioner/release/manifest"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
type Release struct {
|
|
8
|
+
Manifest bprelman.Manifest
|
|
9
|
+
|
|
10
|
+
Name string
|
|
11
|
+
Version string
|
|
12
|
+
|
|
13
|
+
Jobs []Job
|
|
14
|
+
|
|
15
|
+
Packages []*Package
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type Job struct {
|
|
19
|
+
Name string
|
|
20
|
+
Version string
|
|
21
|
+
|
|
22
|
+
Fingerprint string
|
|
23
|
+
SHA1 string
|
|
24
|
+
|
|
25
|
+
TarPath string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type Package struct {
|
|
29
|
+
Name string
|
|
30
|
+
Version string
|
|
31
|
+
|
|
32
|
+
Fingerprint string
|
|
33
|
+
SHA1 string
|
|
34
|
+
|
|
35
|
+
TarPath string
|
|
36
|
+
|
|
37
|
+
// Package dependencies used at compilation of this package
|
|
38
|
+
Dependencies []*Package
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ResolvedPackageDependencies returns list of packages
|
|
42
|
+
// in order such that each package at a higher index
|
|
43
|
+
// only depends on packages at lower indecies.
|
|
44
|
+
func (r Release) ResolvedPackageDependencies() []*Package {
|
|
45
|
+
var resolvedPkgs []*Package
|
|
46
|
+
var pendingPkgs []*Package
|
|
47
|
+
|
|
48
|
+
for _, pkg := range r.Packages {
|
|
49
|
+
pkgRef := pkg
|
|
50
|
+
pendingPkgs = append(pendingPkgs, pkgRef)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
iterations := 0
|
|
54
|
+
|
|
55
|
+
for len(pendingPkgs) > 0 {
|
|
56
|
+
pkg := pendingPkgs[0]
|
|
57
|
+
|
|
58
|
+
depsSatisfied := true
|
|
59
|
+
|
|
60
|
+
for _, depPkg := range pkg.Dependencies {
|
|
61
|
+
depSatisfied := false
|
|
62
|
+
|
|
63
|
+
for _, resPkg := range resolvedPkgs {
|
|
64
|
+
if depPkg.Name == resPkg.Name {
|
|
65
|
+
depSatisfied = true
|
|
66
|
+
break
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if !depSatisfied {
|
|
71
|
+
depsSatisfied = false
|
|
72
|
+
break
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
pendingPkgs = pendingPkgs[1:]
|
|
77
|
+
if depsSatisfied {
|
|
78
|
+
resolvedPkgs = append(resolvedPkgs, pkg)
|
|
79
|
+
} else {
|
|
80
|
+
pendingPkgs = append(pendingPkgs, pkg)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if iterations > 100 {
|
|
84
|
+
panic("Failed to resolve package dependenices witin 100 iterations")
|
|
85
|
+
} else {
|
|
86
|
+
iterations++
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return resolvedPkgs
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// populateFromManifest populates release information
|
|
94
|
+
// interpreted from release manifest.
|
|
95
|
+
func (r *Release) populateFromManifest(manifest bprelman.Manifest) {
|
|
96
|
+
r.populateRelease(manifest.Release)
|
|
97
|
+
r.populatePackages(manifest.Release.Packages)
|
|
98
|
+
r.populateJobs(manifest.Release.Jobs)
|
|
99
|
+
r.Manifest = manifest
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func (r *Release) populateRelease(manRelease bprelman.Release) {
|
|
103
|
+
r.Name = manRelease.Name
|
|
104
|
+
r.Version = manRelease.Version
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
func (r *Release) populatePackages(manPkgs []bprelman.Package) {
|
|
108
|
+
nameToPkg := map[bprelman.DependencyName]*Package{}
|
|
109
|
+
|
|
110
|
+
for _, manPkg := range manPkgs {
|
|
111
|
+
pkg := Package{
|
|
112
|
+
Name: manPkg.Name,
|
|
113
|
+
Version: manPkg.Version,
|
|
114
|
+
|
|
115
|
+
Fingerprint: manPkg.Fingerprint,
|
|
116
|
+
SHA1: manPkg.SHA1,
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
r.Packages = append(r.Packages, &pkg)
|
|
120
|
+
|
|
121
|
+
nameToPkg[bprelman.DependencyName(pkg.Name)] = &pkg
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Connect compile time dependencies for packages
|
|
125
|
+
for i, manPkg := range manPkgs {
|
|
126
|
+
for _, depName := range manPkg.DependencyNames {
|
|
127
|
+
r.Packages[i].Dependencies = append(r.Packages[i].Dependencies, nameToPkg[depName])
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func (r *Release) populateJobs(manJobs []bprelman.Job) {
|
|
133
|
+
for _, manJob := range manJobs {
|
|
134
|
+
job := Job{
|
|
135
|
+
Name: manJob.Name,
|
|
136
|
+
Version: manJob.Version,
|
|
137
|
+
|
|
138
|
+
Fingerprint: manJob.Fingerprint,
|
|
139
|
+
SHA1: manJob.SHA1,
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
r.Jobs = append(r.Jobs, job)
|
|
143
|
+
}
|
|
144
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
package release_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
. "github.com/onsi/ginkgo"
|
|
5
|
+
. "github.com/onsi/gomega"
|
|
6
|
+
|
|
7
|
+
. "boshprovisioner/release"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
var _ = Describe("Release", func() {
|
|
11
|
+
var (
|
|
12
|
+
release Release
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
BeforeEach(func() {
|
|
16
|
+
release = Release{}
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
Describe("ResolvedPackageDependencies", func() {
|
|
20
|
+
It("returns packages in correct order with transitive deps", func() {
|
|
21
|
+
pkg1 := Package{Name: "fake-package-name-1"}
|
|
22
|
+
|
|
23
|
+
pkg2 := Package{
|
|
24
|
+
Name: "fake-package-name-2",
|
|
25
|
+
Dependencies: []*Package{&pkg1},
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
pkg3 := Package{
|
|
29
|
+
Name: "fake-package-name-3",
|
|
30
|
+
Dependencies: []*Package{&pkg2},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
release.Packages = []*Package{&pkg3, &pkg2, &pkg1}
|
|
34
|
+
|
|
35
|
+
pkgs := release.ResolvedPackageDependencies()
|
|
36
|
+
Expect(pkgs).To(Equal([]*Package{&pkg1, &pkg2, &pkg3}))
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
It("returns packages in resolved order with multiple deps", func() {
|
|
40
|
+
pkg1 := Package{Name: "fake-package-name-1"}
|
|
41
|
+
pkg2 := Package{Name: "fake-package-name-2"}
|
|
42
|
+
|
|
43
|
+
pkg3 := Package{
|
|
44
|
+
Name: "fake-package-name-3",
|
|
45
|
+
Dependencies: []*Package{&pkg1, &pkg2},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
release.Packages = []*Package{&pkg3, &pkg2, &pkg1}
|
|
49
|
+
|
|
50
|
+
pkgs := release.ResolvedPackageDependencies()
|
|
51
|
+
Expect(pkgs).To(Equal([]*Package{&pkg2, &pkg1, &pkg3})) // or pkg1, pkg2, pkg3
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
It("compiles BOSH release packages (example)", func() {
|
|
55
|
+
nginx := Package{Name: "nginx"}
|
|
56
|
+
genisoimage := Package{Name: "genisoimage"}
|
|
57
|
+
powerdns := Package{Name: "powerdns"}
|
|
58
|
+
ruby := Package{Name: "ruby"}
|
|
59
|
+
|
|
60
|
+
blobstore := Package{
|
|
61
|
+
Name: "blobstore",
|
|
62
|
+
Dependencies: []*Package{&ruby},
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
mysql := Package{Name: "mysql"}
|
|
66
|
+
|
|
67
|
+
nats := Package{
|
|
68
|
+
Name: "nats",
|
|
69
|
+
Dependencies: []*Package{&ruby},
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
common := Package{Name: "common"}
|
|
73
|
+
redis := Package{Name: "redis"}
|
|
74
|
+
libpq := Package{Name: "libpq"}
|
|
75
|
+
postgres := Package{Name: "postgres"}
|
|
76
|
+
|
|
77
|
+
registry := Package{
|
|
78
|
+
Name: "registry",
|
|
79
|
+
Dependencies: []*Package{&libpq, &mysql, &ruby},
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
director := Package{
|
|
83
|
+
Name: "director",
|
|
84
|
+
Dependencies: []*Package{&libpq, &mysql, &ruby},
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
healthMonitor := Package{
|
|
88
|
+
Name: "health_monitor",
|
|
89
|
+
Dependencies: []*Package{&ruby},
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
release.Packages = []*Package{
|
|
93
|
+
&nginx,
|
|
94
|
+
&genisoimage,
|
|
95
|
+
&powerdns,
|
|
96
|
+
&blobstore, // before ruby
|
|
97
|
+
&ruby,
|
|
98
|
+
&mysql,
|
|
99
|
+
&nats,
|
|
100
|
+
&common,
|
|
101
|
+
&director, // before libpq, postgres; after ruby
|
|
102
|
+
&redis,
|
|
103
|
+
®istry, // before libpq, postgres; after ruby
|
|
104
|
+
&libpq,
|
|
105
|
+
&postgres,
|
|
106
|
+
&healthMonitor, // after ruby, libpq, postgres
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
pkgs := release.ResolvedPackageDependencies()
|
|
110
|
+
|
|
111
|
+
Expect(pkgs).To(Equal([]*Package{
|
|
112
|
+
&nginx,
|
|
113
|
+
&genisoimage,
|
|
114
|
+
&powerdns,
|
|
115
|
+
&ruby,
|
|
116
|
+
&mysql,
|
|
117
|
+
&nats,
|
|
118
|
+
&common,
|
|
119
|
+
&redis,
|
|
120
|
+
&libpq,
|
|
121
|
+
&postgres,
|
|
122
|
+
&healthMonitor, // currently always appended to the end
|
|
123
|
+
&blobstore,
|
|
124
|
+
&director,
|
|
125
|
+
®istry,
|
|
126
|
+
}))
|
|
127
|
+
})
|
|
128
|
+
})
|
|
129
|
+
})
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
package release
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"path/filepath"
|
|
5
|
+
|
|
6
|
+
bosherr "bosh/errors"
|
|
7
|
+
boshlog "bosh/logger"
|
|
8
|
+
boshsys "bosh/system"
|
|
9
|
+
|
|
10
|
+
bpdload "boshprovisioner/downloader"
|
|
11
|
+
bprelman "boshprovisioner/release/manifest"
|
|
12
|
+
bptar "boshprovisioner/tar"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const tarReaderLogTag = "TarReader"
|
|
16
|
+
|
|
17
|
+
// TarReader reads .tgz release file and returns a Release.
|
|
18
|
+
// See unpacked release directory layout at the end of the file.
|
|
19
|
+
type TarReader struct {
|
|
20
|
+
path string
|
|
21
|
+
downloader bpdload.Downloader
|
|
22
|
+
extractor bptar.Extractor
|
|
23
|
+
fs boshsys.FileSystem
|
|
24
|
+
logger boshlog.Logger
|
|
25
|
+
|
|
26
|
+
// location to clean if successfully downloaded/extracted
|
|
27
|
+
downloadPath string
|
|
28
|
+
extractPath string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
func NewTarReader(
|
|
32
|
+
path string,
|
|
33
|
+
downloader bpdload.Downloader,
|
|
34
|
+
extractor bptar.Extractor,
|
|
35
|
+
fs boshsys.FileSystem,
|
|
36
|
+
logger boshlog.Logger,
|
|
37
|
+
) *TarReader {
|
|
38
|
+
return &TarReader{
|
|
39
|
+
path: path,
|
|
40
|
+
downloader: downloader,
|
|
41
|
+
extractor: extractor,
|
|
42
|
+
fs: fs,
|
|
43
|
+
logger: logger,
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
func (tr *TarReader) Read() (Release, error) {
|
|
48
|
+
var release Release
|
|
49
|
+
|
|
50
|
+
downloadPath, err := tr.downloader.Download(tr.path)
|
|
51
|
+
if err != nil {
|
|
52
|
+
return release, bosherr.WrapError(err, "Downloading release")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
tr.downloadPath = downloadPath
|
|
56
|
+
|
|
57
|
+
extractPath, err := tr.extractor.Extract(tr.downloadPath)
|
|
58
|
+
if err != nil {
|
|
59
|
+
cleanUpErr := tr.downloader.CleanUp(tr.downloadPath)
|
|
60
|
+
if cleanUpErr != nil {
|
|
61
|
+
tr.logger.Debug(tarReaderLogTag,
|
|
62
|
+
"Failed to clean up downloaded release %v", cleanUpErr)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return release, bosherr.WrapError(err, "Extracting release")
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
tr.extractPath = extractPath
|
|
69
|
+
|
|
70
|
+
manifestPath := filepath.Join(tr.extractPath, "release.MF")
|
|
71
|
+
|
|
72
|
+
manifest, err := bprelman.NewManifestFromPath(manifestPath, tr.fs)
|
|
73
|
+
if err != nil {
|
|
74
|
+
closeErr := tr.Close()
|
|
75
|
+
if closeErr != nil {
|
|
76
|
+
tr.logger.Debug(tarReaderLogTag,
|
|
77
|
+
"Failed to close release %v", closeErr)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return release, bosherr.WrapError(err, "Building manifest")
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
tr.logger.Debug(tarReaderLogTag, "Done building manifest %#v", manifest)
|
|
84
|
+
|
|
85
|
+
release.populateFromManifest(manifest)
|
|
86
|
+
|
|
87
|
+
tr.populateReleaseTarPaths(&release)
|
|
88
|
+
|
|
89
|
+
return release, nil
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
func (tr TarReader) Close() error {
|
|
93
|
+
dlErr := tr.downloader.CleanUp(tr.downloadPath)
|
|
94
|
+
if dlErr != nil {
|
|
95
|
+
tr.logger.Debug(tarReaderLogTag,
|
|
96
|
+
"Failed to clean up downloaded release %v", dlErr)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
exErr := tr.extractor.CleanUp(tr.extractPath)
|
|
100
|
+
if exErr != nil {
|
|
101
|
+
tr.logger.Debug(tarReaderLogTag,
|
|
102
|
+
"Failed to clean up extracted release %v", exErr)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if dlErr != nil {
|
|
106
|
+
return dlErr
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return exErr
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// populateReleaseTarPaths sets TarPath for each job/package in the release.
|
|
113
|
+
func (tr TarReader) populateReleaseTarPaths(release *Release) {
|
|
114
|
+
for i, job := range release.Jobs {
|
|
115
|
+
fileName := job.Name + ".tgz"
|
|
116
|
+
release.Jobs[i].TarPath = filepath.Join(tr.extractPath, "jobs", fileName)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for _, pkg := range release.Packages {
|
|
120
|
+
fileName := pkg.Name + ".tgz"
|
|
121
|
+
pkg.TarPath = filepath.Join(tr.extractPath, "packages", fileName)
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
Example layout of an unpackaged release tar:
|
|
127
|
+
|
|
128
|
+
$ tree ~/Downloads/dummy-release
|
|
129
|
+
~/Downloads/dummy-release
|
|
130
|
+
├── jobs
|
|
131
|
+
│ ├── dummy.tgz
|
|
132
|
+
│ ├── dummy_with_bad_package.tgz
|
|
133
|
+
│ ├── dummy_with_package.tgz
|
|
134
|
+
│ └── dummy_with_properties.tgz
|
|
135
|
+
├── packages
|
|
136
|
+
│ ├── bad_package.tgz
|
|
137
|
+
│ └── dummy_package.tgz
|
|
138
|
+
└── release.MF
|
|
139
|
+
*/
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
package releasesrepo
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
boshblob "bosh/blobstore"
|
|
5
|
+
bosherr "bosh/errors"
|
|
6
|
+
boshlog "bosh/logger"
|
|
7
|
+
|
|
8
|
+
bpdep "boshprovisioner/deployment"
|
|
9
|
+
bpdload "boshprovisioner/downloader"
|
|
10
|
+
bpindex "boshprovisioner/index"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
type BlobstoreReleasesRepository struct {
|
|
14
|
+
downloader bpdload.Downloader
|
|
15
|
+
blobstore boshblob.Blobstore
|
|
16
|
+
index bpindex.Index
|
|
17
|
+
logger boshlog.Logger
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type blobstoreRecord struct {
|
|
21
|
+
BlobID string
|
|
22
|
+
Fingerprint string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func NewBlobstoreReleasesRepository(
|
|
26
|
+
downloader bpdload.Downloader,
|
|
27
|
+
blobstore boshblob.Blobstore,
|
|
28
|
+
index bpindex.Index,
|
|
29
|
+
logger boshlog.Logger,
|
|
30
|
+
) BlobstoreReleasesRepository {
|
|
31
|
+
return BlobstoreReleasesRepository{
|
|
32
|
+
downloader: downloader,
|
|
33
|
+
blobstore: blobstore,
|
|
34
|
+
index: index,
|
|
35
|
+
logger: logger,
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
func (rr BlobstoreReleasesRepository) Pull(release bpdep.Release) error {
|
|
40
|
+
var record blobstoreRecord
|
|
41
|
+
|
|
42
|
+
err := rr.index.Find(release, &record)
|
|
43
|
+
if err == nil {
|
|
44
|
+
return nil // nothing to do if already exists
|
|
45
|
+
} else if err != bpindex.ErrNotFound {
|
|
46
|
+
return bosherr.WrapError(err, "Finding release in index")
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
path, err := rr.downloader.Download(release.URL)
|
|
50
|
+
if err != nil {
|
|
51
|
+
return bosherr.WrapError(err, "Downloading release")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
defer rr.downloader.CleanUp(path)
|
|
55
|
+
|
|
56
|
+
blobID, fingerprint, err := rr.blobstore.Create(path)
|
|
57
|
+
if err != nil {
|
|
58
|
+
return bosherr.WrapError(err, "Creating release blob")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
record = blobstoreRecord{
|
|
62
|
+
BlobID: blobID,
|
|
63
|
+
Fingerprint: fingerprint,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
err = rr.index.Save(release, record)
|
|
67
|
+
if err != nil {
|
|
68
|
+
// todo delete from blobstore
|
|
69
|
+
|
|
70
|
+
return bosherr.WrapError(err, "Saving release to index")
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return nil
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
func (rr BlobstoreReleasesRepository) KeepOnly(releasesToKeep []bpdep.Release) error {
|
|
77
|
+
var allReleases []bpdep.Release
|
|
78
|
+
|
|
79
|
+
err := rr.index.ListKeys(&allReleases)
|
|
80
|
+
if err != nil {
|
|
81
|
+
return bosherr.WrapError(err, "Listing releases in index")
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for _, foundRelease := range allReleases {
|
|
85
|
+
var keep bool
|
|
86
|
+
|
|
87
|
+
for _, releaseToKeep := range releasesToKeep {
|
|
88
|
+
if foundRelease == releaseToKeep {
|
|
89
|
+
keep = true
|
|
90
|
+
break
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if keep {
|
|
95
|
+
continue
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
var record blobstoreRecord
|
|
99
|
+
|
|
100
|
+
err := rr.index.Find(foundRelease, &record)
|
|
101
|
+
if err != nil {
|
|
102
|
+
return bosherr.WrapError(err, "Finding release to delete")
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// todo delete from blobstore
|
|
106
|
+
|
|
107
|
+
err = rr.index.Remove(foundRelease)
|
|
108
|
+
if err != nil {
|
|
109
|
+
return bosherr.WrapError(err, "Deleting release from index")
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return nil
|
|
114
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package releasesrepo
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bpdep "boshprovisioner/deployment"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
// ReleasesRepository manages collection of releases
|
|
8
|
+
// available to use for provisioning
|
|
9
|
+
type ReleasesRepository interface {
|
|
10
|
+
// Pull downloads/copies/retrieves a release
|
|
11
|
+
Pull(bpdep.Release) error
|
|
12
|
+
|
|
13
|
+
// KeepOnly deletes all releases but the provided ones
|
|
14
|
+
KeepOnly([]bpdep.Release) error
|
|
15
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
package tar
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bosherr "bosh/errors"
|
|
5
|
+
boshlog "bosh/logger"
|
|
6
|
+
boshsys "bosh/system"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
const cmdCompressorLogTag = "CmdCompressor"
|
|
10
|
+
|
|
11
|
+
type CmdCompressor struct {
|
|
12
|
+
runner boshsys.CmdRunner
|
|
13
|
+
fs boshsys.FileSystem
|
|
14
|
+
logger boshlog.Logger
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
func NewCmdCompressor(
|
|
18
|
+
runner boshsys.CmdRunner,
|
|
19
|
+
fs boshsys.FileSystem,
|
|
20
|
+
logger boshlog.Logger,
|
|
21
|
+
) CmdCompressor {
|
|
22
|
+
return CmdCompressor{
|
|
23
|
+
runner: runner,
|
|
24
|
+
fs: fs,
|
|
25
|
+
logger: logger,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func (c CmdCompressor) Compress(path string) (string, error) {
|
|
30
|
+
compressPath, err := c.tmpPath()
|
|
31
|
+
if err != nil {
|
|
32
|
+
return "", err
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
c.logger.Debug(cmdCompressorLogTag, "Compressing %s to %s", path, compressPath)
|
|
36
|
+
|
|
37
|
+
_, _, _, err = c.runner.RunCommand("tar", "-C", path, "-czf", compressPath, ".")
|
|
38
|
+
if err != nil {
|
|
39
|
+
return "", bosherr.WrapError(err, "Running tar")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return compressPath, nil
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func (c CmdCompressor) CleanUp(path string) error {
|
|
46
|
+
return c.fs.RemoveAll(path)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
func (c CmdCompressor) tmpPath() (string, error) {
|
|
50
|
+
file, err := c.fs.TempFile("tar-CmdCompressor")
|
|
51
|
+
if err != nil {
|
|
52
|
+
return "", bosherr.WrapError(err, "Creating extract destination")
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
compressPath := file.Name()
|
|
56
|
+
|
|
57
|
+
err = file.Close()
|
|
58
|
+
if err != nil {
|
|
59
|
+
return "", bosherr.WrapError(err, "Closing temp file")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
err = c.fs.RemoveAll(compressPath)
|
|
63
|
+
if err != nil {
|
|
64
|
+
return "", bosherr.WrapError(err, "Remove temp file")
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return compressPath, nil
|
|
68
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
package tar
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bosherr "bosh/errors"
|
|
5
|
+
boshlog "bosh/logger"
|
|
6
|
+
boshsys "bosh/system"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
const cmdExtractorLogTag = "CmdExtractor"
|
|
10
|
+
|
|
11
|
+
type CmdExtractor struct {
|
|
12
|
+
runner boshsys.CmdRunner
|
|
13
|
+
fs boshsys.FileSystem
|
|
14
|
+
logger boshlog.Logger
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
func NewCmdExtractor(
|
|
18
|
+
runner boshsys.CmdRunner,
|
|
19
|
+
fs boshsys.FileSystem,
|
|
20
|
+
logger boshlog.Logger,
|
|
21
|
+
) CmdExtractor {
|
|
22
|
+
return CmdExtractor{
|
|
23
|
+
runner: runner,
|
|
24
|
+
fs: fs,
|
|
25
|
+
logger: logger,
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
func (e CmdExtractor) Extract(path string) (string, error) {
|
|
30
|
+
extractPath, err := e.fs.TempDir("tar-CmdExtractor")
|
|
31
|
+
if err != nil {
|
|
32
|
+
return "", bosherr.WrapError(err, "Creating extract destination")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
e.logger.Debug(cmdExtractorLogTag, "Extract tar %s to %s", path, extractPath)
|
|
36
|
+
|
|
37
|
+
_, _, _, err = e.runner.RunCommand("tar", "-C", extractPath, "-xzf", path)
|
|
38
|
+
if err != nil {
|
|
39
|
+
return "", bosherr.WrapError(err, "Running tar")
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return extractPath, nil
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func (e CmdExtractor) CleanUp(path string) error {
|
|
46
|
+
return e.fs.RemoveAll(path)
|
|
47
|
+
}
|