forked from cloudfoundry/bosh-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file_bundle.go
114 lines (93 loc) · 2.74 KB
/
file_bundle.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
package bundlecollection
import (
"os"
"path/filepath"
"code.cloudfoundry.org/clock"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshlog "github.com/cloudfoundry/bosh-utils/logger"
boshsys "github.com/cloudfoundry/bosh-utils/system"
)
const (
fileBundleLogTag = "FileBundle"
)
type FileBundle struct {
installPath string
enablePath string
fileMode os.FileMode
fs boshsys.FileSystem
timeProvider clock.Clock
logger boshlog.Logger
}
func NewFileBundle(
installPath, enablePath string,
fileMode os.FileMode,
fs boshsys.FileSystem,
timeProvider clock.Clock,
logger boshlog.Logger,
) FileBundle {
return FileBundle{
installPath: installPath,
enablePath: enablePath,
fileMode: fileMode,
fs: fs,
timeProvider: timeProvider,
logger: logger,
}
}
func (b FileBundle) InstallWithoutContents() (boshsys.FileSystem, string, error) {
b.logger.Debug(fileBundleLogTag, "Installing without contents %v", b)
// MkdirAll MUST be the last possibly-failing operation
// because IsInstalled() relies on installPath presence.
err := b.fs.MkdirAll(b.installPath, b.fileMode)
if err != nil {
return nil, "", bosherr.WrapError(err, "Creating installation directory")
}
err = b.fs.Chown(b.installPath, "root:vcap")
if err != nil {
return nil, "", bosherr.WrapError(err, "Setting ownership on installation directory")
}
return b.fs, b.installPath, nil
}
func (b FileBundle) GetInstallPath() (boshsys.FileSystem, string, error) {
path := b.installPath
if !b.fs.FileExists(path) {
return nil, "", bosherr.Error("install dir does not exist")
}
return b.fs, path, nil
}
func (b FileBundle) IsInstalled() (bool, error) {
return b.fs.FileExists(b.installPath), nil
}
func (b FileBundle) Enable() (boshsys.FileSystem, string, error) {
b.logger.Debug(fileBundleLogTag, "Enabling %v", b)
if !b.fs.FileExists(b.installPath) {
return nil, "", bosherr.Error("bundle must be installed")
}
err := b.fs.MkdirAll(filepath.Dir(b.enablePath), b.fileMode)
if err != nil {
return nil, "", bosherr.WrapError(err, "failed to create enable dir")
}
err = b.fs.Chown(filepath.Dir(b.enablePath), "root:vcap")
if err != nil {
return nil, "", bosherr.WrapError(err, "Setting ownership on source directory")
}
err = b.fs.Symlink(b.installPath, b.enablePath)
if err != nil {
return nil, "", bosherr.WrapError(err, "failed to enable")
}
return b.fs, b.enablePath, nil
}
func (b FileBundle) Disable() error {
b.logger.Debug(fileBundleLogTag, "Disabling %v", b)
target, err := b.fs.ReadAndFollowLink(b.enablePath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return bosherr.WrapError(err, "Reading symlink")
}
if target == b.installPath {
return b.fs.RemoveAll(b.enablePath)
}
return nil
}