-
Notifications
You must be signed in to change notification settings - Fork 784
/
packages.go
181 lines (149 loc) · 4.37 KB
/
packages.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package packages
import (
"fmt"
"github.com/jenkins-x/jx-logging/pkg/log"
"github.com/jenkins-x/jx/v2/pkg/util"
"sigs.k8s.io/yaml"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"runtime"
"github.com/pkg/errors"
)
// IBMCloudVersion ibm cloud binary version
const IBMCloudVersion = "0.10.1"
// IamAuthenticatorAwsVersion authenticator binary version to use
const IamAuthenticatorAwsVersion = "1.12.7"
// EksCtlVersion binary version to use
const EksCtlVersion = "0.11.1"
// KubectlVersion binary version to use
const KubectlVersion = "1.16.5"
// Helm2Version binary version to use
const Helm2Version = "2.12.2"
// Helm3Version binary version to use
const Helm3Version = "3.2.0"
// KustomizeVersion binary version to use
const KustomizeVersion = "3.5.1"
// GlooVersion binary version to use
const GlooVersion = "1.3.23"
// GlobalBinaryPathWhitelist binaries that require to be on the path but do not need to exist in JX_HOME/bin
var GlobalBinaryPathWhitelist = []string{
"az",
"gcloud",
"oc",
"brew",
}
func BinaryWithExtension(binary string) string {
if runtime.GOOS == "windows" {
if binary == "gcloud" {
return binary + ".cmd"
}
return binary + ".exe"
}
return binary
}
func LookupForBinary(binary string) (string, error) {
path, err := exec.LookPath(BinaryWithExtension(binary))
if err != nil {
return "", err
}
return path, nil
}
type VersionExtractor interface {
arguments() []string
extractVersion(command string, arguments []string) (string, error)
}
func IsBinaryWithProperVersionInstalled(binary string, expectedVersion string, versionExtractor VersionExtractor) (bool, error) {
if versionExtractor == nil {
installedVersions, err := LoadInstalledPackages()
if err != nil {
return false, err
}
if versionValue, versionExists := installedVersions[binary]; versionExists {
return versionValue == expectedVersion, nil
}
return false, nil
}
binaryPath, err := LookupForBinary(binary)
if err != nil {
return false, errors.Wrap(err, "looking up the binary")
}
if binaryPath != "" {
currentVersion, err := versionExtractor.extractVersion(binaryPath, versionExtractor.arguments())
if err != nil {
return false, errors.Wrap(err, "extracting the version")
}
if currentVersion == expectedVersion {
return true, nil
}
}
return false, nil
}
// Managing installed packages
func LoadInstalledPackages() (map[string]string, error) {
installedPackagesFile, err := InstalledPackagesFile()
if err != nil {
return nil, err
}
binariesVersions := map[string]string{}
if _, err := os.Stat(installedPackagesFile); err == nil {
binariesBytes, err := ioutil.ReadFile(installedPackagesFile)
if err != nil {
return nil, err
}
err = yaml.Unmarshal(binariesBytes, &binariesVersions)
if err != nil {
return nil, err
}
return binariesVersions, nil
}
return map[string]string{}, nil
}
// RememberInstalledPackage writes the version of package into local file system. This allows to identify
// what version of package is currently installed in ~/.jx/bin .
func RememberInstalledPackage(packageName string, version string) error {
if packageName == "" {
return errors.New("package name cannot be empty")
}
if version == "" {
return errors.New("package version cannot be empty")
}
versions, err := LoadInstalledPackages()
if err != nil {
return err
}
versions[packageName] = version
binariesBytes, err := yaml.Marshal(versions)
if err != nil {
return err
}
installedPackagesFile, err := InstalledPackagesFile()
if err != nil {
return err
}
err = ioutil.WriteFile(installedPackagesFile, binariesBytes, 0600)
if err != nil {
return err
}
return nil
}
// InstalledPackagesFile returns absolute path to binaries.yml file used to store version of installed packages.
func InstalledPackagesFile() (string, error) {
configDir, err := util.ConfigDir()
if err != nil {
return "", err
}
return filepath.Join(configDir, "/binaries.yml"), nil
}
// Downloading
// DownloadFile downloads binary content of given URL into local filesystem.
func DownloadFile(clientURL string, fullPath string) error {
log.Logger().Infof("Downloading %s to %s...", util.ColorInfo(clientURL), util.ColorInfo(fullPath))
err := util.DownloadFile(fullPath, clientURL)
if err != nil {
return fmt.Errorf("Unable to download file %s from %s due to: %v", fullPath, clientURL, err)
}
log.Logger().Infof("Downloaded %s", util.ColorInfo(fullPath))
return nil
}