vagrant-bosh 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.gitmodules +6 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE +20 -0
  6. data/README.md +73 -0
  7. data/Rakefile +2 -0
  8. data/dev/.gitignore +1 -0
  9. data/dev/Vagrantfile +30 -0
  10. data/dev/example-bosh-manifest.yml +188 -0
  11. data/dev/example-winston-manifest.yml +70 -0
  12. data/go/.gitignore +11 -0
  13. data/go/bin/build +10 -0
  14. data/go/bin/build-linux-amd64 +9 -0
  15. data/go/bin/env +13 -0
  16. data/go/bin/go +5 -0
  17. data/go/bin/golint +19 -0
  18. data/go/bin/test +37 -0
  19. data/go/src/boshprovisioner/agent/client/client_interface.go +73 -0
  20. data/go/src/boshprovisioner/agent/client/fakes/fake_client.go +81 -0
  21. data/go/src/boshprovisioner/agent/client/http_client.go +299 -0
  22. data/go/src/boshprovisioner/agent/client/http_client_envelope.go +107 -0
  23. data/go/src/boshprovisioner/deployment/deployment.go +221 -0
  24. data/go/src/boshprovisioner/deployment/instance.go +54 -0
  25. data/go/src/boshprovisioner/deployment/manifest/deployment.go +80 -0
  26. data/go/src/boshprovisioner/deployment/manifest/ips.go +23 -0
  27. data/go/src/boshprovisioner/deployment/manifest/manifest.go +143 -0
  28. data/go/src/boshprovisioner/deployment/manifest/manifest_suite_test.go +13 -0
  29. data/go/src/boshprovisioner/deployment/manifest/manifest_test.go +86 -0
  30. data/go/src/boshprovisioner/deployment/manifest/syntax_validator.go +186 -0
  31. data/go/src/boshprovisioner/deployment/manifest/watch_time.go +47 -0
  32. data/go/src/boshprovisioner/deployment/manifest_reader.go +46 -0
  33. data/go/src/boshprovisioner/deployment/reader_factory.go +25 -0
  34. data/go/src/boshprovisioner/deployment/semantic_validator.go +111 -0
  35. data/go/src/boshprovisioner/downloader/blobstore_downloader.go +55 -0
  36. data/go/src/boshprovisioner/downloader/default_mux_downloader.go +22 -0
  37. data/go/src/boshprovisioner/downloader/downloader_interface.go +6 -0
  38. data/go/src/boshprovisioner/downloader/http_downloader.go +53 -0
  39. data/go/src/boshprovisioner/downloader/local_fs_downloader.go +48 -0
  40. data/go/src/boshprovisioner/downloader/mux_downloader.go +69 -0
  41. data/go/src/boshprovisioner/eventlog/log.go +72 -0
  42. data/go/src/boshprovisioner/eventlog/stage.go +39 -0
  43. data/go/src/boshprovisioner/eventlog/task.go +58 -0
  44. data/go/src/boshprovisioner/index/file_index.go +289 -0
  45. data/go/src/boshprovisioner/index/file_index_test.go +296 -0
  46. data/go/src/boshprovisioner/index/index_interface.go +18 -0
  47. data/go/src/boshprovisioner/index/index_suite_test.go +13 -0
  48. data/go/src/boshprovisioner/instance/templatescompiler/concrete_templates_compiler.go +273 -0
  49. data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/erb_renderer.go +117 -0
  50. data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/erbrenderer_suite_test.go +13 -0
  51. data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/render_properties.go +77 -0
  52. data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/render_properties_test.go +142 -0
  53. data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/template_evaluation_context.go +85 -0
  54. data/go/src/boshprovisioner/instance/templatescompiler/erbrenderer/template_evaluation_context_rb.go +155 -0
  55. data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/concrete_jobs_repository.go +64 -0
  56. data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/concrete_runtime_packages_repository.go +105 -0
  57. data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/concrete_template_to_job_repository.go +76 -0
  58. data/go/src/boshprovisioner/instance/templatescompiler/jobsrepo/jobs_repository_interface.go +31 -0
  59. data/go/src/boshprovisioner/instance/templatescompiler/rendered_archives_compiler.go +81 -0
  60. data/go/src/boshprovisioner/instance/templatescompiler/templates_compiler_interface.go +20 -0
  61. data/go/src/boshprovisioner/instance/templatescompiler/templatesrepo/ct_repository.go +54 -0
  62. data/go/src/boshprovisioner/instance/templatescompiler/templatesrepo/templates_repository_interface.go +16 -0
  63. data/go/src/boshprovisioner/instance/updater/applier/applier.go +93 -0
  64. data/go/src/boshprovisioner/instance/updater/applier/empty_state.go +66 -0
  65. data/go/src/boshprovisioner/instance/updater/applier/job_state.go +178 -0
  66. data/go/src/boshprovisioner/instance/updater/drainer.go +72 -0
  67. data/go/src/boshprovisioner/instance/updater/preparer.go +39 -0
  68. data/go/src/boshprovisioner/instance/updater/starter.go +36 -0
  69. data/go/src/boshprovisioner/instance/updater/stopper.go +36 -0
  70. data/go/src/boshprovisioner/instance/updater/updater.go +102 -0
  71. data/go/src/boshprovisioner/instance/updater/updater_factory.go +83 -0
  72. data/go/src/boshprovisioner/instance/updater/updater_suite_test.go +13 -0
  73. data/go/src/boshprovisioner/instance/updater/waiter.go +77 -0
  74. data/go/src/boshprovisioner/instance/updater/waiter_test.go +103 -0
  75. data/go/src/boshprovisioner/main/config.go +77 -0
  76. data/go/src/boshprovisioner/main/main.go +183 -0
  77. data/go/src/boshprovisioner/main/repos_factory.go +96 -0
  78. data/go/src/boshprovisioner/packagescompiler/compiledpackagesrepo/compiled_packages_repository_interface.go +17 -0
  79. data/go/src/boshprovisioner/packagescompiler/compiledpackagesrepo/concrete_compiled_packages_repository.go +61 -0
  80. data/go/src/boshprovisioner/packagescompiler/concrete_packages_compiler.go +179 -0
  81. data/go/src/boshprovisioner/packagescompiler/concrete_packages_compiler_factory.go +48 -0
  82. data/go/src/boshprovisioner/packagescompiler/packages_compiler_interface.go +20 -0
  83. data/go/src/boshprovisioner/packagescompiler/packagesrepo/concrete_packages_repository.go +65 -0
  84. data/go/src/boshprovisioner/packagescompiler/packagesrepo/packages_repository_interface.go +16 -0
  85. data/go/src/boshprovisioner/provisioner/blobstore_config.go +65 -0
  86. data/go/src/boshprovisioner/provisioner/blobstore_provisioner.go +38 -0
  87. data/go/src/boshprovisioner/provisioner/deployment_provisioner.go +97 -0
  88. data/go/src/boshprovisioner/provisioner/instance_provisioner.go +48 -0
  89. data/go/src/boshprovisioner/provisioner/release_compiler.go +133 -0
  90. data/go/src/boshprovisioner/release/job/job.go +86 -0
  91. data/go/src/boshprovisioner/release/job/manifest/manifest.go +79 -0
  92. data/go/src/boshprovisioner/release/job/manifest/manifest_suite_test.go +13 -0
  93. data/go/src/boshprovisioner/release/job/manifest/manifest_test.go +42 -0
  94. data/go/src/boshprovisioner/release/job/manifest/syntax_validator.go +43 -0
  95. data/go/src/boshprovisioner/release/job/reader_factory.go +34 -0
  96. data/go/src/boshprovisioner/release/job/tar_reader.go +133 -0
  97. data/go/src/boshprovisioner/release/manifest/manifest.go +96 -0
  98. data/go/src/boshprovisioner/release/manifest_reader.go +29 -0
  99. data/go/src/boshprovisioner/release/reader_factory.go +34 -0
  100. data/go/src/boshprovisioner/release/release.go +144 -0
  101. data/go/src/boshprovisioner/release/release_suite_test.go +13 -0
  102. data/go/src/boshprovisioner/release/release_test.go +129 -0
  103. data/go/src/boshprovisioner/release/tar_reader.go +139 -0
  104. data/go/src/boshprovisioner/releasesrepo/blobstore_releases_repository.go +114 -0
  105. data/go/src/boshprovisioner/releasesrepo/releases_repository_interface.go +15 -0
  106. data/go/src/boshprovisioner/tar/cmd_compressor.go +68 -0
  107. data/go/src/boshprovisioner/tar/cmd_extractor.go +47 -0
  108. data/go/src/boshprovisioner/tar/compressor_interface.go +6 -0
  109. data/go/src/boshprovisioner/tar/extractor_interface.go +6 -0
  110. data/go/src/boshprovisioner/util/string_keyed.go +70 -0
  111. data/go/src/boshprovisioner/vm/agent_provisioner.go +266 -0
  112. data/go/src/boshprovisioner/vm/asset_manager.go +61 -0
  113. data/go/src/boshprovisioner/vm/deps_provisioner.go +92 -0
  114. data/go/src/boshprovisioner/vm/monit_provisioner.go +83 -0
  115. data/go/src/boshprovisioner/vm/runit_provisioner.go +225 -0
  116. data/go/src/boshprovisioner/vm/simple_cmds.go +54 -0
  117. data/go/src/boshprovisioner/vm/vcap_user_provisioner.go +120 -0
  118. data/go/src/boshprovisioner/vm/vm.go +19 -0
  119. data/go/src/boshprovisioner/vm/vm_provisioner.go +57 -0
  120. data/go/src/boshprovisioner/vm/vm_provisioner_factory.go +97 -0
  121. data/lib/vagrant-bosh/asset_uploader.rb +53 -0
  122. data/lib/vagrant-bosh/assets/agent/agent-log +5 -0
  123. data/lib/vagrant-bosh/assets/agent/agent-run +12 -0
  124. data/lib/vagrant-bosh/assets/agent/agent.cert +18 -0
  125. data/lib/vagrant-bosh/assets/agent/agent.json +9 -0
  126. data/lib/vagrant-bosh/assets/agent/agent.key +27 -0
  127. data/lib/vagrant-bosh/assets/agent/bosh-agent +0 -0
  128. data/lib/vagrant-bosh/assets/agent/bosh-agent-rc +18 -0
  129. data/lib/vagrant-bosh/assets/agent/bosh-blobstore-dav +0 -0
  130. data/lib/vagrant-bosh/assets/monit/monit +0 -0
  131. data/lib/vagrant-bosh/assets/monit/monit-log +5 -0
  132. data/lib/vagrant-bosh/assets/monit/monit-run +9 -0
  133. data/lib/vagrant-bosh/assets/monit/monitrc +8 -0
  134. data/lib/vagrant-bosh/assets/provisioner +0 -0
  135. data/lib/vagrant-bosh/bootstrapper.rb +59 -0
  136. data/lib/vagrant-bosh/communicator.rb +50 -0
  137. data/lib/vagrant-bosh/config.rb +15 -0
  138. data/lib/vagrant-bosh/errors.rb +11 -0
  139. data/lib/vagrant-bosh/plugin.rb +25 -0
  140. data/lib/vagrant-bosh/provisioner.rb +46 -0
  141. data/lib/vagrant-bosh/provisioner_tracker.rb +41 -0
  142. data/lib/vagrant-bosh/ui.rb +77 -0
  143. data/lib/vagrant-bosh/version.rb +5 -0
  144. data/lib/vagrant-bosh.rb +15 -0
  145. data/templates/locales/en.yml +15 -0
  146. data/vagrant-bosh.gemspec +20 -0
  147. 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,13 @@
1
+ package manifest_test
2
+
3
+ import (
4
+ . "github.com/onsi/ginkgo"
5
+ . "github.com/onsi/gomega"
6
+
7
+ "testing"
8
+ )
9
+
10
+ func TestManifest(t *testing.T) {
11
+ RegisterFailHandler(Fail)
12
+ RunSpecs(t, "Manifest Suite")
13
+ }
@@ -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
+ }