forked from cloudfoundry/bosh-agent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
file_bundle_collection.go
127 lines (100 loc) · 3.52 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
package bundlecollection
import (
"path"
"path/filepath"
"strings"
boshcrypto "github.com/cloudfoundry/bosh-utils/crypto"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshlog "github.com/cloudfoundry/bosh-utils/logger"
boshsys "github.com/cloudfoundry/bosh-utils/system"
"os"
)
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
logger boshlog.Logger
}
func NewFileBundleCollection(
installPath, enablePath, name string,
fileMode os.FileMode,
fs boshsys.FileSystem,
logger boshlog.Logger,
) FileBundleCollection {
return FileBundleCollection{
name: cleanPath(name),
installPath: cleanPath(installPath),
enablePath: cleanPath(enablePath),
fileMode: fileMode,
fs: fs,
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.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.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))
}