forked from cloudfoundry/bosh-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file_bundle_collection.go
137 lines (109 loc) · 3.96 KB
/
file_bundle_collection.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
package bundlecollection
import (
"path"
"path/filepath"
"strings"
"os"
"code.cloudfoundry.org/clock"
"github.com/cloudfoundry/bosh-agent/agent/tarpath"
boshcrypto "github.com/cloudfoundry/bosh-utils/crypto"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
"github.com/cloudfoundry/bosh-utils/fileutil"
boshlog "github.com/cloudfoundry/bosh-utils/logger"
boshsys "github.com/cloudfoundry/bosh-utils/system"
)
const fileBundleCollectionLogTag = "FileBundleCollection"
type fileBundleDefinition struct {
name string
version string
}
func newFileBundleDefinition(installPath string) fileBundleDefinition {
cleanInstallPath := cleanPath(installPath) // no trailing slash
// If the path is empty, Base returns ".".
// If the path consists entirely of separators, Base returns a single separator.
name := path.Base(path.Dir(cleanInstallPath))
if name == "." || name == string("/") {
name = ""
}
version := path.Base(cleanInstallPath)
if version == "." || version == string("/") {
version = ""
}
return fileBundleDefinition{name: name, version: version}
}
func (bd fileBundleDefinition) BundleName() string { return bd.name }
func (bd fileBundleDefinition) BundleVersion() string { return bd.version }
type FileBundleCollection struct {
name string
installPath string
enablePath string
fileMode os.FileMode
fs boshsys.FileSystem
timeProvider clock.Clock
compressor fileutil.Compressor
logger boshlog.Logger
}
func NewFileBundleCollection(
installPath, enablePath, name string,
fileMode os.FileMode,
fs boshsys.FileSystem,
timeProvider clock.Clock,
compressor fileutil.Compressor,
logger boshlog.Logger,
) FileBundleCollection {
return FileBundleCollection{
name: cleanPath(name),
installPath: cleanPath(installPath),
enablePath: cleanPath(enablePath),
fileMode: fileMode,
fs: fs,
timeProvider: timeProvider,
compressor: compressor,
logger: logger,
}
}
func (bc FileBundleCollection) Get(definition BundleDefinition) (Bundle, error) {
if len(definition.BundleName()) == 0 {
return nil, bosherr.Error("Missing bundle name")
}
if len(definition.BundleVersion()) == 0 {
return nil, bosherr.Error("Missing bundle version")
}
bundleVersionDigest, err := boshcrypto.DigestAlgorithmSHA1.CreateDigest(strings.NewReader(definition.BundleVersion()))
if err != nil {
return FileBundle{}, err
}
installPath := path.Join(bc.installPath, bc.name, definition.BundleName(), bundleVersionDigest.String())
enablePath := path.Join(bc.enablePath, bc.name, definition.BundleName())
return NewFileBundle(installPath, enablePath, bc.fileMode, bc.fs, bc.timeProvider, bc.compressor, tarpath.NewPrefixDetector(), bc.logger), nil
}
func (bc FileBundleCollection) getDigested(definition BundleDefinition) (Bundle, error) {
if len(definition.BundleName()) == 0 {
return nil, bosherr.Error("Missing bundle name")
}
if len(definition.BundleVersion()) == 0 {
return nil, bosherr.Error("Missing bundle version")
}
installPath := path.Join(bc.installPath, bc.name, definition.BundleName(), definition.BundleVersion())
enablePath := path.Join(bc.enablePath, bc.name, definition.BundleName())
return NewFileBundle(installPath, enablePath, bc.fileMode, bc.fs, bc.timeProvider, bc.compressor, tarpath.NewPrefixDetector(), bc.logger), nil
}
func (bc FileBundleCollection) List() ([]Bundle, error) {
var bundles []Bundle
bundleInstallPaths, err := bc.fs.Glob(path.Join(bc.installPath, bc.name, "*", "*"))
if err != nil {
return bundles, bosherr.WrapError(err, "Globbing bundles")
}
for _, path := range bundleInstallPaths {
bundle, err := bc.getDigested(newFileBundleDefinition(path))
if err != nil {
return bundles, bosherr.WrapError(err, "Getting bundle")
}
bundles = append(bundles, bundle)
}
bc.logger.Debug(fileBundleCollectionLogTag, "Collection contains bundles %v", bundles)
return bundles, nil
}
func cleanPath(name string) string {
return path.Clean(filepath.ToSlash(name))
}