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.
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
+ }