forked from cloudfoundry/bosh-cli
/
job_renderer.go
132 lines (111 loc) · 4.03 KB
/
job_renderer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package installation
import (
biinstallmanifest "github.com/cloudfoundry/bosh-cli/installation/manifest"
bireljob "github.com/cloudfoundry/bosh-cli/release/job"
bitemplate "github.com/cloudfoundry/bosh-cli/templatescompiler"
biui "github.com/cloudfoundry/bosh-cli/ui"
boshblob "github.com/cloudfoundry/bosh-utils/blobstore"
boshcrypto "github.com/cloudfoundry/bosh-utils/crypto"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshcmd "github.com/cloudfoundry/bosh-utils/fileutil"
biproperty "github.com/cloudfoundry/bosh-utils/property"
)
type JobRenderer interface {
RenderAndUploadFrom(biinstallmanifest.Manifest, []bireljob.Job, biui.Stage) ([]RenderedJobRef, error)
}
type jobRenderer struct {
jobListRenderer bitemplate.JobListRenderer
compressor boshcmd.Compressor
blobstore boshblob.DigestBlobstore
}
type RenderedJobRef struct {
Name string
Version string
BlobstoreID string
SHA1 string
}
func NewRenderedJobRef(name, version, blobstoreID, sha1 string) RenderedJobRef {
return RenderedJobRef{
Name: name,
Version: version,
BlobstoreID: blobstoreID,
SHA1: sha1,
}
}
func NewJobRenderer(
jobListRenderer bitemplate.JobListRenderer,
compressor boshcmd.Compressor,
blobstore boshblob.DigestBlobstore,
) JobRenderer {
return &jobRenderer{
jobListRenderer: jobListRenderer,
compressor: compressor,
blobstore: blobstore,
}
}
func (b *jobRenderer) RenderAndUploadFrom(installationManifest biinstallmanifest.Manifest, jobs []bireljob.Job, stage biui.Stage) ([]RenderedJobRef, error) {
// installation jobs do not get rendered with global deployment properties, only the cloud_provider properties
globalProperties := biproperty.Map{}
releaseJobProperties := map[string]*biproperty.Map{}
jobProperties := installationManifest.Properties
renderedJobRefs, err := b.renderJobTemplates(jobs, releaseJobProperties, jobProperties, globalProperties, installationManifest.Name, stage)
if err != nil {
return nil, bosherr.WrapError(err, "Rendering job templates for installation")
}
if len(renderedJobRefs) != 1 {
return nil, bosherr.Error("Too many jobs rendered... oops?")
}
return renderedJobRefs, nil
}
// renderJobTemplates renders all the release job templates for multiple release jobs specified
// by a deployment job and randomly uploads them to blobstore
func (b *jobRenderer) renderJobTemplates(
releaseJobs []bireljob.Job,
releaseJobProperties map[string]*biproperty.Map,
jobProperties biproperty.Map,
globalProperties biproperty.Map,
deploymentName string,
stage biui.Stage,
) ([]RenderedJobRef, error) {
renderedJobRefs := make([]RenderedJobRef, 0, len(releaseJobs))
err := stage.Perform("Rendering job templates", func() error {
renderedJobList, err := b.jobListRenderer.Render(releaseJobs, releaseJobProperties, jobProperties, globalProperties, deploymentName, "")
if err != nil {
return err
}
defer renderedJobList.DeleteSilently()
for _, renderedJob := range renderedJobList.All() {
renderedJobRef, err := b.compressAndUpload(renderedJob)
if err != nil {
return err
}
renderedJobRefs = append(renderedJobRefs, renderedJobRef)
}
return nil
})
return renderedJobRefs, err
}
func (b *jobRenderer) compressAndUpload(renderedJob bitemplate.RenderedJob) (RenderedJobRef, error) {
tarballPath, err := b.compressor.CompressFilesInDir(renderedJob.Path())
if err != nil {
return RenderedJobRef{}, bosherr.WrapError(err, "Compressing rendered job templates")
}
defer func() {
_ = b.compressor.CleanUp(tarballPath)
}()
blobID, multiDigest, err := b.blobstore.Create(tarballPath)
if err != nil {
return RenderedJobRef{}, bosherr.WrapError(err, "Creating blob")
}
sha1Digest, err := multiDigest.DigestFor(boshcrypto.DigestAlgorithmSHA1)
if err != nil {
return RenderedJobRef{}, bosherr.WrapError(err, "Looking up SHA1 from blob digest")
}
releaseJob := renderedJob.Job()
return RenderedJobRef{
Name: releaseJob.Name(),
Version: releaseJob.Fingerprint(),
BlobstoreID: blobID,
SHA1: sha1Digest.String(),
}, nil
}