cilium

Форк
0
/
binarycheck.go 
101 строка · 2.5 Кб
1
// SPDX-License-Identifier: Apache-2.0
2
// Copyright Authors of Cilium
3

4
package main
5

6
import (
7
	"errors"
8
	"fmt"
9
	"os/exec"
10
	"regexp"
11

12
	"github.com/blang/semver/v4"
13
)
14

15
// A binaryCheck checks that a binary called name is installed and optionally at
16
// least version minVersion (inclusive), and less than maxVersion (exclusive)
17
type binaryCheck struct {
18
	name           string
19
	command        string
20
	alternateNames []string
21
	ifNotFound     checkResult
22
	versionArgs    []string
23
	versionRegexp  *regexp.Regexp
24
	minVersion     *semver.Version // inclusive
25
	maxVersion     *semver.Version // exclusive
26
	hint           string
27
}
28

29
func (c *binaryCheck) Name() string {
30
	return c.name
31
}
32

33
func (c *binaryCheck) Run() (checkResult, string) {
34
	var path string
35
	command := c.command
36
	if command == "" {
37
		command = c.name
38
	}
39
	for _, name := range append([]string{command}, c.alternateNames...) {
40
		var err error
41
		path, err = exec.LookPath(name)
42
		switch {
43
		case errors.Is(err, exec.ErrNotFound):
44
			continue
45
		case err != nil:
46
			return checkFailed, err.Error()
47
		}
48
	}
49
	if path == "" {
50
		return c.ifNotFound, fmt.Sprintf("%s not found in $PATH", c.name)
51
	}
52

53
	if c.versionArgs == nil {
54
		return checkOK, fmt.Sprintf("found %s", path)
55
	}
56

57
	output, err := exec.Command(path, c.versionArgs...).CombinedOutput()
58
	if err != nil {
59
		return checkFailed, err.Error()
60
	}
61

62
	version := output
63
	if c.versionRegexp != nil {
64
		match := c.versionRegexp.FindSubmatch(version)
65
		if len(match) != 2 {
66
			return checkFailed, fmt.Sprintf("found %s, could not parse version from %s", path, version)
67
		}
68
		version = match[1]
69
	}
70

71
	if c.minVersion != nil || c.maxVersion != nil {
72
		v, err := semver.ParseTolerant(string(version))
73
		if err != nil {
74
			return checkFailed, err.Error()
75
		}
76

77
		// only compare the major, minor, and patch versions. this is because
78
		// github.com/blang/semver treats any extra text is a pre-release
79
		// version, meaning that, e.g. clang version "10.0.0-4ubuntu1" compares
80
		// less than "10.0.0"
81
		effectiveVersion := semver.Version{
82
			Major: v.Major,
83
			Minor: v.Minor,
84
			Patch: v.Patch,
85
		}
86

87
		if c.minVersion != nil && effectiveVersion.LT(*c.minVersion) {
88
			return checkError, fmt.Sprintf("found %s, version %s, need at least %s", path, version, c.minVersion)
89
		}
90

91
		if c.maxVersion != nil && effectiveVersion.GTE(*c.maxVersion) {
92
			return checkError, fmt.Sprintf("found %s, version %s, need less than %s", path, version, c.maxVersion)
93
		}
94
	}
95

96
	return checkOK, fmt.Sprintf("found %s, version %s", path, version)
97
}
98

99
func (c *binaryCheck) Hint() string {
100
	return c.hint
101
}
102

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.