forked from cloudfoundry-attic/bosh-init
/
job_installer.go
152 lines (134 loc) · 3.99 KB
/
job_installer.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package install
import (
"os"
"path"
"path/filepath"
bosherr "github.com/cloudfoundry/bosh-agent/errors"
boshsys "github.com/cloudfoundry/bosh-agent/system"
boshtime "github.com/cloudfoundry/bosh-agent/time"
bmeventlog "github.com/cloudfoundry/bosh-micro-cli/eventlogging"
bmrel "github.com/cloudfoundry/bosh-micro-cli/release"
bmtemcomp "github.com/cloudfoundry/bosh-micro-cli/templatescompiler"
)
type InstalledJob struct {
Name string
Path string
}
type JobInstaller interface {
Install(bmrel.Job) (InstalledJob, error)
}
type jobInstaller struct {
fs boshsys.FileSystem
packageInstaller PackageInstaller
templateExtractor BlobExtractor
templateRepo bmtemcomp.TemplatesRepo
jobsPath string
packagesPath string
eventLogger bmeventlog.EventLogger
timeService boshtime.Service
}
func (i jobInstaller) Install(job bmrel.Job) (InstalledJob, error) {
event := bmeventlog.Event{
Time: i.timeService.Now(),
Stage: "installing CPI jobs",
Total: 1,
State: bmeventlog.Started,
Index: 1,
Task: "cpi",
}
logErr := i.eventLogger.AddEvent(event)
if logErr != nil {
return InstalledJob{}, bosherr.WrapError(logErr, "Logging event: %#v", event)
}
installedJob, err := i.install(job)
if err != nil {
event = bmeventlog.Event{
Time: i.timeService.Now(),
Stage: "installing CPI jobs",
Total: 1,
State: bmeventlog.Failed,
Index: 1,
Task: "cpi",
Message: err.Error(),
}
logErr = i.eventLogger.AddEvent(event)
if logErr != nil {
return InstalledJob{}, bosherr.WrapError(logErr, "Logging event: %#v", event)
}
return InstalledJob{}, err
}
event = bmeventlog.Event{
Time: i.timeService.Now(),
Stage: "installing CPI jobs",
Total: 1,
State: bmeventlog.Finished,
Index: 1,
Task: "cpi",
}
logErr = i.eventLogger.AddEvent(event)
if logErr != nil {
return InstalledJob{}, bosherr.WrapError(logErr, "Logging event: %#v", event)
}
return installedJob, nil
}
func (i jobInstaller) install(job bmrel.Job) (InstalledJob, error) {
jobDir := filepath.Join(i.jobsPath, job.Name)
err := i.fs.MkdirAll(jobDir, os.ModePerm)
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Creating jobs directory `%s'", jobDir)
}
err = i.fs.MkdirAll(i.packagesPath, os.ModePerm)
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Creating packages directory `%s'", i.packagesPath)
}
for _, pkg := range job.Packages {
err = i.packageInstaller.Install(pkg, i.packagesPath)
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Installing package `%s'", pkg.Name)
}
}
template, found, err := i.templateRepo.Find(job)
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Finding template for job `%s'", job.Name)
}
if !found {
return InstalledJob{}, bosherr.New("Could not find template for job `%s'", job.Name)
}
err = i.templateExtractor.Extract(template.BlobID, template.BlobSHA1, jobDir)
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Extracting blob with ID `%s'", template.BlobID)
}
binFiles := path.Join(jobDir, "bin", "*")
files, err := i.fs.Glob(binFiles)
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Globbing %s", binFiles)
}
for _, file := range files {
err = i.fs.Chmod(file, os.FileMode(0755))
if err != nil {
return InstalledJob{}, bosherr.WrapError(err, "Making %s executable", binFiles)
}
}
return InstalledJob{Name: job.Name, Path: jobDir}, nil
}
func NewJobInstaller(
fs boshsys.FileSystem,
packageInstaller PackageInstaller,
blobExtractor BlobExtractor,
templateRepo bmtemcomp.TemplatesRepo,
jobsPath,
packagesPath string,
eventLogger bmeventlog.EventLogger,
timeService boshtime.Service,
) JobInstaller {
return jobInstaller{
fs: fs,
packageInstaller: packageInstaller,
templateExtractor: blobExtractor,
templateRepo: templateRepo,
jobsPath: jobsPath,
packagesPath: packagesPath,
eventLogger: eventLogger,
timeService: timeService,
}
}