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,133 @@
|
|
|
1
|
+
package provisioner
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
bosherr "bosh/errors"
|
|
7
|
+
boshlog "bosh/logger"
|
|
8
|
+
|
|
9
|
+
bpdep "boshprovisioner/deployment"
|
|
10
|
+
bpeventlog "boshprovisioner/eventlog"
|
|
11
|
+
bptplcomp "boshprovisioner/instance/templatescompiler"
|
|
12
|
+
bppkgscomp "boshprovisioner/packagescompiler"
|
|
13
|
+
bprel "boshprovisioner/release"
|
|
14
|
+
bprelrepo "boshprovisioner/releasesrepo"
|
|
15
|
+
bpvm "boshprovisioner/vm"
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
const releaseCompilerLogTag = "ReleaseCompiler"
|
|
19
|
+
|
|
20
|
+
type ReleaseCompiler struct {
|
|
21
|
+
releasesRepo bprelrepo.ReleasesRepository
|
|
22
|
+
releaseReaderFactory bprel.ReaderFactory
|
|
23
|
+
|
|
24
|
+
packagesCompilerFactory bppkgscomp.ConcretePackagesCompilerFactory
|
|
25
|
+
templatesCompiler bptplcomp.TemplatesCompiler
|
|
26
|
+
|
|
27
|
+
vmProvisioner bpvm.VMProvisioner
|
|
28
|
+
|
|
29
|
+
eventLog bpeventlog.Log
|
|
30
|
+
logger boshlog.Logger
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func NewReleaseCompiler(
|
|
34
|
+
releasesRepo bprelrepo.ReleasesRepository,
|
|
35
|
+
releaseReaderFactory bprel.ReaderFactory,
|
|
36
|
+
packagesCompilerFactory bppkgscomp.ConcretePackagesCompilerFactory,
|
|
37
|
+
templatesCompiler bptplcomp.TemplatesCompiler,
|
|
38
|
+
vmProvisioner bpvm.VMProvisioner,
|
|
39
|
+
eventLog bpeventlog.Log,
|
|
40
|
+
logger boshlog.Logger,
|
|
41
|
+
) ReleaseCompiler {
|
|
42
|
+
return ReleaseCompiler{
|
|
43
|
+
releasesRepo: releasesRepo,
|
|
44
|
+
releaseReaderFactory: releaseReaderFactory,
|
|
45
|
+
|
|
46
|
+
packagesCompilerFactory: packagesCompilerFactory,
|
|
47
|
+
templatesCompiler: templatesCompiler,
|
|
48
|
+
|
|
49
|
+
vmProvisioner: vmProvisioner,
|
|
50
|
+
|
|
51
|
+
eventLog: eventLog,
|
|
52
|
+
logger: logger,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
func (p ReleaseCompiler) Compile(instance bpdep.Instance, releases []bpdep.Release) error {
|
|
57
|
+
vm, err := p.vmProvisioner.Provision(instance)
|
|
58
|
+
if err != nil {
|
|
59
|
+
return bosherr.WrapError(err, "Provisioning agent")
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
err = p.uploadReleases(releases)
|
|
63
|
+
if err != nil {
|
|
64
|
+
return bosherr.WrapError(err, "Uploading releases")
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
pkgsCompiler := p.packagesCompilerFactory.NewCompiler(vm.AgentClient())
|
|
68
|
+
|
|
69
|
+
err = p.compileReleases(pkgsCompiler, releases)
|
|
70
|
+
if err != nil {
|
|
71
|
+
return bosherr.WrapError(err, "Compiling releases")
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return nil
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
func (p ReleaseCompiler) uploadReleases(releases []bpdep.Release) error {
|
|
78
|
+
stage := p.eventLog.BeginStage("Uploading releases", len(releases)+1)
|
|
79
|
+
|
|
80
|
+
for _, depRelease := range releases {
|
|
81
|
+
releaseDesc := fmt.Sprintf("%s/%s", depRelease.Name, depRelease.Version)
|
|
82
|
+
|
|
83
|
+
task := stage.BeginTask(fmt.Sprintf("Release %s", releaseDesc))
|
|
84
|
+
|
|
85
|
+
err := task.End(p.releasesRepo.Pull(depRelease))
|
|
86
|
+
if err != nil {
|
|
87
|
+
return bosherr.WrapError(err, "Pulling release %s", depRelease.Name)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
task := stage.BeginTask("Deleting old releases")
|
|
92
|
+
|
|
93
|
+
err := task.End(p.releasesRepo.KeepOnly(releases))
|
|
94
|
+
if err != nil {
|
|
95
|
+
return bosherr.WrapError(err, "Keeping only releases")
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return nil
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
func (p ReleaseCompiler) compileReleases(pkgsCompiler bppkgscomp.PackagesCompiler, releases []bpdep.Release) error {
|
|
102
|
+
for _, depRelease := range releases {
|
|
103
|
+
err := p.compileRelease(pkgsCompiler, depRelease)
|
|
104
|
+
if err != nil {
|
|
105
|
+
return bosherr.WrapError(err, "Release %s", depRelease.Name)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return nil
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
func (p ReleaseCompiler) compileRelease(pkgsCompiler bppkgscomp.PackagesCompiler, release bpdep.Release) error {
|
|
113
|
+
reader := p.releaseReaderFactory.NewTarReader(release.URL)
|
|
114
|
+
|
|
115
|
+
relRelease, err := reader.Read()
|
|
116
|
+
if err != nil {
|
|
117
|
+
return bosherr.WrapError(err, "Reading release")
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
defer reader.Close()
|
|
121
|
+
|
|
122
|
+
err = pkgsCompiler.Compile(relRelease)
|
|
123
|
+
if err != nil {
|
|
124
|
+
return bosherr.WrapError(err, "Compiling release packages")
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
err = p.templatesCompiler.Precompile(relRelease)
|
|
128
|
+
if err != nil {
|
|
129
|
+
return bosherr.WrapError(err, "Precompiling release job templates")
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return nil
|
|
133
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
package job
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bpreljobman "boshprovisioner/release/job/manifest"
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
type Job struct {
|
|
8
|
+
Manifest bpreljobman.Manifest
|
|
9
|
+
|
|
10
|
+
Name string
|
|
11
|
+
|
|
12
|
+
MonitTemplate Template
|
|
13
|
+
|
|
14
|
+
Templates []Template
|
|
15
|
+
|
|
16
|
+
// Runtime package dependencies for this job
|
|
17
|
+
Packages []Package
|
|
18
|
+
|
|
19
|
+
Properties []Property
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type Template struct {
|
|
23
|
+
SrcPathEnd string
|
|
24
|
+
DstPathEnd string // End of the path on the VM
|
|
25
|
+
|
|
26
|
+
Path string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type Package struct {
|
|
30
|
+
Name string
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
type Property struct {
|
|
34
|
+
Name string
|
|
35
|
+
Description string
|
|
36
|
+
|
|
37
|
+
Default interface{}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// populateFromManifest populates job information interpreted from job manifest.
|
|
41
|
+
func (j *Job) populateFromManifest(manifest bpreljobman.Manifest) {
|
|
42
|
+
j.populateJob(manifest.Job)
|
|
43
|
+
j.populateTemplates(manifest.Job.TemplateNames)
|
|
44
|
+
j.populatePackages(manifest.Job.PackageNames)
|
|
45
|
+
j.populateProperties(manifest.Job.PropertyMappings)
|
|
46
|
+
j.Manifest = manifest
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
func (j *Job) populateJob(manJob bpreljobman.Job) {
|
|
50
|
+
j.Name = manJob.Name
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func (j *Job) populateTemplates(manTemplateNames bpreljobman.TemplateNames) {
|
|
54
|
+
j.MonitTemplate = Template{
|
|
55
|
+
SrcPathEnd: "monit",
|
|
56
|
+
DstPathEnd: "monit",
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for srcPathEnd, dstPathEnd := range manTemplateNames {
|
|
60
|
+
template := Template{
|
|
61
|
+
SrcPathEnd: srcPathEnd,
|
|
62
|
+
DstPathEnd: dstPathEnd,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
j.Templates = append(j.Templates, template)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
func (j *Job) populatePackages(manPackageNames []string) {
|
|
70
|
+
for _, name := range manPackageNames {
|
|
71
|
+
j.Packages = append(j.Packages, Package{Name: name})
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
func (j *Job) populateProperties(manPropMappings bpreljobman.PropertyMappings) {
|
|
76
|
+
for propName, propDef := range manPropMappings {
|
|
77
|
+
property := Property{
|
|
78
|
+
Name: propName,
|
|
79
|
+
Description: propDef.Description,
|
|
80
|
+
|
|
81
|
+
Default: propDef.Default,
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
j.Properties = append(j.Properties, property)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Package manifest represents internal structure of a release job.
|
|
2
|
+
package manifest
|
|
3
|
+
|
|
4
|
+
import (
|
|
5
|
+
bosherr "bosh/errors"
|
|
6
|
+
boshsys "bosh/system"
|
|
7
|
+
"github.com/fraenkel/candiedyaml"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
type Manifest struct {
|
|
11
|
+
Job Job
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type Job struct {
|
|
15
|
+
Name string `yaml:"name"`
|
|
16
|
+
|
|
17
|
+
TemplateNames TemplateNames `yaml:"templates"`
|
|
18
|
+
|
|
19
|
+
PackageNames []string `yaml:"packages"`
|
|
20
|
+
|
|
21
|
+
PropertyMappings PropertyMappings `yaml:"properties"`
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type TemplateNames map[string]string
|
|
25
|
+
|
|
26
|
+
type PropertyMappings map[string]PropertyDefinition
|
|
27
|
+
|
|
28
|
+
type PropertyDefinition struct {
|
|
29
|
+
Description string `yaml:"description"`
|
|
30
|
+
|
|
31
|
+
// Non-raw field is populated by the validator.
|
|
32
|
+
DefaultRaw interface{} `yaml:"default"`
|
|
33
|
+
Default interface{}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
func NewManifestFromPath(path string, fs boshsys.FileSystem) (Manifest, error) {
|
|
37
|
+
bytes, err := fs.ReadFile(path)
|
|
38
|
+
if err != nil {
|
|
39
|
+
return Manifest{}, bosherr.WrapError(err, "Reading manifest %s", path)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return NewManifestFromBytes(bytes)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func NewManifestFromBytes(bytes []byte) (Manifest, error) {
|
|
46
|
+
var manifest Manifest
|
|
47
|
+
var job Job
|
|
48
|
+
|
|
49
|
+
err := candiedyaml.Unmarshal(bytes, &job)
|
|
50
|
+
if err != nil {
|
|
51
|
+
return manifest, bosherr.WrapError(err, "Parsing job")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
manifest.Job = job
|
|
55
|
+
|
|
56
|
+
err = NewSyntaxValidator(&manifest).Validate()
|
|
57
|
+
if err != nil {
|
|
58
|
+
return Manifest{}, bosherr.WrapError(err, "Validating manifest syntactically")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return manifest, nil
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
# Example for job.MF
|
|
66
|
+
name: dummy
|
|
67
|
+
|
|
68
|
+
templates:
|
|
69
|
+
dummy_ctl: bin/dummy_ctl
|
|
70
|
+
|
|
71
|
+
packages:
|
|
72
|
+
- dummy_package
|
|
73
|
+
- dummy_package2
|
|
74
|
+
|
|
75
|
+
properties:
|
|
76
|
+
dummy_value:
|
|
77
|
+
description: Some value for the dummy job
|
|
78
|
+
default: 300
|
|
79
|
+
*/
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
package manifest_test
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
. "github.com/onsi/ginkgo"
|
|
5
|
+
. "github.com/onsi/gomega"
|
|
6
|
+
|
|
7
|
+
. "boshprovisioner/release/job/manifest"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
var _ = Describe("Manifest", func() {
|
|
11
|
+
Describe("NewManifestFromBytes", func() {
|
|
12
|
+
It("returns manifest with property definiton default that have string keys", func() {
|
|
13
|
+
manifestBytes := []byte(`
|
|
14
|
+
properties:
|
|
15
|
+
key:
|
|
16
|
+
default:
|
|
17
|
+
prop:
|
|
18
|
+
nest-prop: instance-val
|
|
19
|
+
props:
|
|
20
|
+
- name: nest-prop
|
|
21
|
+
`)
|
|
22
|
+
|
|
23
|
+
manifest, err := NewManifestFromBytes(manifestBytes)
|
|
24
|
+
Expect(err).ToNot(HaveOccurred())
|
|
25
|
+
|
|
26
|
+
Expect(manifest.Job.PropertyMappings).To(HaveLen(1))
|
|
27
|
+
|
|
28
|
+
for _, propDef := range manifest.Job.PropertyMappings {
|
|
29
|
+
// candiedyaml unmarshals manifest to map[interface{}]interface{}
|
|
30
|
+
// (encoding/json unmarshals manifest to map[string]interface{})
|
|
31
|
+
Expect(propDef.Default).To(Equal(map[string]interface{}{
|
|
32
|
+
"prop": map[string]interface{}{
|
|
33
|
+
"nest-prop": "instance-val",
|
|
34
|
+
},
|
|
35
|
+
"props": []interface{}{
|
|
36
|
+
map[string]interface{}{"name": "nest-prop"},
|
|
37
|
+
},
|
|
38
|
+
}))
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package manifest
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bosherr "bosh/errors"
|
|
5
|
+
|
|
6
|
+
bputil "boshprovisioner/util"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
type SyntaxValidator struct {
|
|
10
|
+
job *Job
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
func NewSyntaxValidator(manifest *Manifest) SyntaxValidator {
|
|
14
|
+
if manifest == nil {
|
|
15
|
+
panic("Expected manifest to not be nil")
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return SyntaxValidator{job: &manifest.Job}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func (v SyntaxValidator) Validate() error {
|
|
22
|
+
for name, propDef := range v.job.PropertyMappings {
|
|
23
|
+
propDef, err := v.validatePropDef(propDef)
|
|
24
|
+
if err != nil {
|
|
25
|
+
return bosherr.WrapError(err, "Property %s", name)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
v.job.PropertyMappings[name] = propDef
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return nil
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func (v SyntaxValidator) validatePropDef(propDef PropertyDefinition) (PropertyDefinition, error) {
|
|
35
|
+
def, err := bputil.NewStringKeyed().ConvertInterface(propDef.DefaultRaw)
|
|
36
|
+
if err != nil {
|
|
37
|
+
return propDef, bosherr.WrapError(err, "Default")
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
propDef.Default = def
|
|
41
|
+
|
|
42
|
+
return propDef, nil
|
|
43
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
package job
|
|
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,133 @@
|
|
|
1
|
+
package job
|
|
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
|
+
bpreljobman "boshprovisioner/release/job/manifest"
|
|
12
|
+
bptar "boshprovisioner/tar"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
const tarReaderLogTag = "TarReader"
|
|
16
|
+
|
|
17
|
+
// TarReader reads .tgz job file and returns a Job.
|
|
18
|
+
// See unpacked job 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() (Job, error) {
|
|
48
|
+
var job Job
|
|
49
|
+
|
|
50
|
+
downloadPath, err := tr.downloader.Download(tr.path)
|
|
51
|
+
if err != nil {
|
|
52
|
+
return job, bosherr.WrapError(err, "Downloading job")
|
|
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 job %v", cleanUpErr)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return job, bosherr.WrapError(err, "Extracting job")
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
tr.extractPath = extractPath
|
|
69
|
+
|
|
70
|
+
manifestPath := filepath.Join(tr.extractPath, "job.MF")
|
|
71
|
+
|
|
72
|
+
manifest, err := bpreljobman.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 job %v", closeErr)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return job, bosherr.WrapError(err, "Building manifest")
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
tr.logger.Debug(tarReaderLogTag, "Done building manifest %#v", manifest)
|
|
84
|
+
|
|
85
|
+
job.populateFromManifest(manifest)
|
|
86
|
+
|
|
87
|
+
tr.populateJobPaths(&job)
|
|
88
|
+
|
|
89
|
+
return job, 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 job %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 job %v", exErr)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if dlErr != nil {
|
|
106
|
+
return dlErr
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return exErr
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// populateJobPaths sets Path for each template and monit in the job.
|
|
113
|
+
func (tr TarReader) populateJobPaths(job *Job) {
|
|
114
|
+
// monit file is outside of templates/ directory
|
|
115
|
+
job.MonitTemplate.Path = filepath.Join(
|
|
116
|
+
tr.extractPath, job.MonitTemplate.SrcPathEnd)
|
|
117
|
+
|
|
118
|
+
for i, template := range job.Templates {
|
|
119
|
+
job.Templates[i].Path = filepath.Join(
|
|
120
|
+
tr.extractPath, "templates", template.SrcPathEnd)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/*
|
|
125
|
+
Example layout of an unpackaged job tar:
|
|
126
|
+
|
|
127
|
+
$ tree ~/Downloads/dummy-job
|
|
128
|
+
~/Downloads/dummy-job
|
|
129
|
+
├── job.MF
|
|
130
|
+
├── monit
|
|
131
|
+
└── templates
|
|
132
|
+
└── dummy_ctl
|
|
133
|
+
*/
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Package manifest represents internal structure of a release.
|
|
2
|
+
package manifest
|
|
3
|
+
|
|
4
|
+
import (
|
|
5
|
+
bosherr "bosh/errors"
|
|
6
|
+
boshsys "bosh/system"
|
|
7
|
+
"github.com/fraenkel/candiedyaml"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
type Manifest struct {
|
|
11
|
+
Release Release
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type Release struct {
|
|
15
|
+
Name string `yaml:"name"`
|
|
16
|
+
Version string `yaml:"version"`
|
|
17
|
+
|
|
18
|
+
Jobs []Job `yaml:"jobs"`
|
|
19
|
+
Packages []Package `yaml:"packages"`
|
|
20
|
+
|
|
21
|
+
CommitHash string `yaml:"commit_hash"`
|
|
22
|
+
UncommittedChanges bool `yaml:"uncommitted_changes"`
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type Job struct {
|
|
26
|
+
Name string `yaml:"name"`
|
|
27
|
+
Version string `yaml:"version"`
|
|
28
|
+
|
|
29
|
+
Fingerprint string `yaml:"fingerprint"`
|
|
30
|
+
SHA1 string `yaml:"sha1"`
|
|
31
|
+
|
|
32
|
+
DependencyNames []DependencyName `yaml:"dependencies"`
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type Package struct {
|
|
36
|
+
Name string `yaml:"name"`
|
|
37
|
+
Version string `yaml:"version"`
|
|
38
|
+
|
|
39
|
+
Fingerprint string `yaml:"fingerprint"`
|
|
40
|
+
SHA1 string `yaml:"sha1"`
|
|
41
|
+
|
|
42
|
+
DependencyNames []DependencyName `yaml:"dependencies"`
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func (p Package) DependencyName() DependencyName {
|
|
46
|
+
return DependencyName(p.Name)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
type DependencyName string
|
|
50
|
+
|
|
51
|
+
func NewManifestFromPath(path string, fs boshsys.FileSystem) (Manifest, error) {
|
|
52
|
+
bytes, err := fs.ReadFile(path)
|
|
53
|
+
if err != nil {
|
|
54
|
+
return Manifest{}, bosherr.WrapError(err, "Reading manifest %s", path)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var release Release
|
|
58
|
+
|
|
59
|
+
err = candiedyaml.Unmarshal(bytes, &release)
|
|
60
|
+
if err != nil {
|
|
61
|
+
return Manifest{}, bosherr.WrapError(err, "Parsing release")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return Manifest{Release: release}, nil
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
# Example for release.MF
|
|
69
|
+
name: bosh
|
|
70
|
+
version: 77
|
|
71
|
+
|
|
72
|
+
commit_hash: bbe5476c
|
|
73
|
+
uncommitted_changes: true
|
|
74
|
+
|
|
75
|
+
packages:
|
|
76
|
+
- name: registry
|
|
77
|
+
version: !binary |-
|
|
78
|
+
ZGQxYmEzMzBiYzQ0YjMxODFiMjYzMzgzYjhlNDI1MmQ3MDUxZGVjYQ==
|
|
79
|
+
sha1: !binary |-
|
|
80
|
+
NmVhYTZjOTYxZWFjN2JkOTk0ZDE2NDRhZDQwNWIzMzk1NDIwZWNhZg==
|
|
81
|
+
fingerprint: !binary |-
|
|
82
|
+
ZGQxYmEzMzBiYzQ0YjMxODFiMjYzMzgzYjhlNDI1MmQ3MDUxZGVjYQ==
|
|
83
|
+
dependencies:
|
|
84
|
+
- libpq
|
|
85
|
+
- mysql
|
|
86
|
+
- ruby
|
|
87
|
+
|
|
88
|
+
jobs:
|
|
89
|
+
- name: powerdns
|
|
90
|
+
version: !binary |-
|
|
91
|
+
MGI4MGIzYzE5OGJmN2FiYzZjODEyNjIwMTNkZTQ5NDM2OWZkMjViNg==
|
|
92
|
+
fingerprint: !binary |-
|
|
93
|
+
MGI4MGIzYzE5OGJmN2FiYzZjODEyNjIwMTNkZTQ5NDM2OWZkMjViNg==
|
|
94
|
+
sha1: !binary |-
|
|
95
|
+
YWI5NzA5YmVhYjViZTBmYjYyYTJkMWYzYzg4ZDA2YzliNGJkZWM2NQ==
|
|
96
|
+
*/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package release
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
bosherr "bosh/errors"
|
|
5
|
+
boshlog "bosh/logger"
|
|
6
|
+
boshsys "bosh/system"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
type ManifestReader struct {
|
|
10
|
+
path string
|
|
11
|
+
fs boshsys.FileSystem
|
|
12
|
+
logger boshlog.Logger
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
func NewManifestReader(
|
|
16
|
+
path string,
|
|
17
|
+
fs boshsys.FileSystem,
|
|
18
|
+
logger boshlog.Logger,
|
|
19
|
+
) ManifestReader {
|
|
20
|
+
return ManifestReader{path: path, fs: fs, logger: logger}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func (r ManifestReader) Read() (Release, error) {
|
|
24
|
+
return Release{}, bosherr.New("Not implemented")
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func (r ManifestReader) Close() error {
|
|
28
|
+
return nil
|
|
29
|
+
}
|