-
Notifications
You must be signed in to change notification settings - Fork 104
/
target_data.go
134 lines (125 loc) · 4.02 KB
/
target_data.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
package platform
import (
"github.com/buildpacks/imgutil"
"github.com/buildpacks/lifecycle/buildpack"
"github.com/buildpacks/lifecycle/internal/fsutil"
"github.com/buildpacks/lifecycle/log"
"github.com/buildpacks/lifecycle/platform/files"
)
// EnvVarsFor fulfills the prophecy set forth in https://github.com/buildpacks/rfcs/blob/b8abe33f2bdc58792acf0bd094dc4ce3c8a54dbb/text/0096-remove-stacks-mixins.md?plain=1#L97
// by returning an array of "VARIABLE=value" strings suitable for inclusion in your environment or complete breakfast.
func EnvVarsFor(tm files.TargetMetadata, logger log.Logger) []string {
// we should always have os & arch,
// if they are not populated try to get target information from the build-time base image
if tm.OS == "" {
GetTargetOSFromFileSystem(&fsutil.Detect{}, &tm, logger)
}
ret := []string{
"CNB_TARGET_OS=" + tm.OS,
"CNB_TARGET_ARCH=" + tm.Arch,
"CNB_TARGET_ARCH_VARIANT=" + tm.ArchVariant,
}
var distName, distVersion string
if tm.Distro != nil {
distName = tm.Distro.Name
distVersion = tm.Distro.Version
}
ret = append(ret, "CNB_TARGET_DISTRO_NAME="+distName)
ret = append(ret, "CNB_TARGET_DISTRO_VERSION="+distVersion)
return ret
}
func GetTargetMetadata(fromImage imgutil.Image) (*files.TargetMetadata, error) {
tm := files.TargetMetadata{}
var err error
tm.OS, err = fromImage.OS()
if err != nil {
return &tm, err
}
tm.Arch, err = fromImage.Architecture()
if err != nil {
return &tm, err
}
tm.ArchVariant, err = fromImage.Variant()
if err != nil {
return &tm, err
}
labels, err := fromImage.Labels()
if err != nil {
return &tm, err
}
distName, distNameExists := labels[OSDistroNameLabel]
distVersion, distVersionExists := labels[OSDistroVersionLabel]
if distNameExists || distVersionExists {
tm.Distro = &files.OSDistro{Name: distName, Version: distVersion}
}
if id, exists := labels[TargetLabel]; exists {
tm.ID = id
}
return &tm, nil
}
// GetTargetOSFromFileSystem populates the target metadata you pass in if the information is available
// returns a boolean indicating whether it populated any data.
func GetTargetOSFromFileSystem(d fsutil.Detector, tm *files.TargetMetadata, logger log.Logger) {
if d.HasSystemdFile() {
contents, err := d.ReadSystemdFile()
if err != nil {
logger.Warnf("Encountered error trying to read /etc/os-release file: %s", err.Error())
return
}
info := d.GetInfo(contents)
if info.Version != "" || info.Name != "" {
tm.OS = "linux"
tm.Distro = &files.OSDistro{Name: info.Name, Version: info.Version}
}
}
}
// TargetSatisfiedForBuild treats empty fields as wildcards and returns true if all populated fields match.
func TargetSatisfiedForBuild(base files.TargetMetadata, module buildpack.TargetMetadata) bool {
if !matches(base.OS, module.OS) {
return false
}
if !matches(base.Arch, module.Arch) {
return false
}
if !matches(base.ArchVariant, module.ArchVariant) {
return false
}
if base.Distro == nil || len(module.Distros) == 0 {
return true
}
foundMatchingDist := false
for _, modDist := range module.Distros {
if matches(base.Distro.Name, modDist.Name) && matches(base.Distro.Version, modDist.Version) {
foundMatchingDist = true
break
}
}
return foundMatchingDist
}
func matches(target1, target2 string) bool {
if target1 == "" || target2 == "" {
return true
}
return target1 == target2
}
// TargetSatisfiedForRebase treats optional fields (ArchVariant and Distribution fields) as wildcards if empty, returns true if all populated fields match
func TargetSatisfiedForRebase(t files.TargetMetadata, appTargetMetadata files.TargetMetadata) bool {
if t.OS != appTargetMetadata.OS || t.Arch != appTargetMetadata.Arch {
return false
}
if !matches(t.ArchVariant, appTargetMetadata.ArchVariant) {
return false
}
if t.Distro != nil {
if appTargetMetadata.Distro == nil {
return false
}
if t.Distro.Name != "" && t.Distro.Name != appTargetMetadata.Distro.Name {
return false
}
if t.Distro.Version != "" && t.Distro.Version != appTargetMetadata.Distro.Version {
return false
}
}
return true
}