forked from FDio/govpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutil.go
148 lines (132 loc) · 4.49 KB
/
util.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
// Copyright (c) 2020 Cisco and/or its affiliates.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package vppapi
import (
"errors"
"fmt"
"os"
"os/exec"
"path"
"strings"
"github.com/sirupsen/logrus"
)
const (
VPPVersionEnvVar = "VPP_VERSION"
VPPDirEnvVar = "VPP_DIR"
versionScriptPath = "src/scripts/version"
localBuildRoot = "build-root/install-vpp-native/vpp/share/vpp/api"
)
// ResolveApiDir checks if parameter dir is a path to directory of local VPP
// repository and returns path to directory with VPP API JSON files under
// build-root. It will execute `make json-api-files` in case the folder with
// VPP API JSON files does not exist yet.
func ResolveApiDir(dir string) string {
_, err := os.Stat(path.Join(dir, "build-root"))
if err == nil {
// local VPP build
_, err := os.Stat(path.Join(dir, localBuildRoot))
if err == nil {
return path.Join(dir, localBuildRoot)
} else if errors.Is(err, os.ErrNotExist) {
cmd := exec.Command("make", "json-api-files")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = dir
_, err := cmd.CombinedOutput()
if err != nil {
logrus.Warnf("make json-api-files failed: %v", err)
} else {
return path.Join(dir, localBuildRoot)
}
}
}
return dir
}
// ResolveVPPVersion resolves version of the VPP for target directory.
//
// Version resolved here can be overriden by setting VPP_VERSION env var.
func ResolveVPPVersion(apidir string) string {
// check env variable override
if ver := os.Getenv(VPPVersionEnvVar); ver != "" {
logrus.Infof("VPP version was manually set to %q via %s env var", ver, VPPVersionEnvVar)
return ver
}
// check if inside VPP repo
repoDir, err := findGitRepoRootDir(apidir)
if err != nil {
logrus.Debugf("checking VPP git repo failed: %v", err)
} else {
logrus.Debugf("resolved git repo root directory: %v", repoDir)
version, err := GetVPPVersionRepo(repoDir)
if err != nil {
logrus.Warnf("resolving VPP version from version script failed: %v", err)
} else {
logrus.Infof("resolved VPP version from version script: %v", version)
return version
}
// try to read VPP_VERSION file
data, err := os.ReadFile(path.Join(repoDir, "VPP_VERSION"))
if err == nil {
return strings.TrimSpace(string(data))
}
}
// assuming VPP package is installed
if _, err := exec.LookPath("vpp"); err == nil {
version, err := GetVPPVersionInstalled()
if err != nil {
logrus.Warnf("resolving VPP version from installed package failed: %v", err)
} else {
logrus.Infof("resolved VPP version from installed package: %v", version)
return version
}
}
logrus.Warnf("VPP version could not be resolved, you can set it manually using %s env var", VPPVersionEnvVar)
return ""
}
// GetVPPVersionInstalled retrieves VPP version of installed package using dpkg-query.
func GetVPPVersionInstalled() (string, error) {
cmd := exec.Command("dpkg-query", "-f", "${Version}", "-W", "vpp")
out, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("dpkg-query command failed: %v\noutput: %s", err, out)
}
return strings.TrimSpace(string(out)), nil
}
// GetVPPVersionRepo retrieves VPP version using script in repo directory.
func GetVPPVersionRepo(repoDir string) (string, error) {
scriptPath := path.Join(repoDir, versionScriptPath)
if _, err := os.Stat(scriptPath); err != nil {
return "", err
}
cmd := exec.Command(scriptPath)
cmd.Dir = repoDir
out, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("version script failed: %v\noutput: %s", err, out)
}
return strings.TrimSpace(string(out)), nil
}
func findGitRepoRootDir(dir string) (string, error) {
if conf := os.Getenv(VPPDirEnvVar); conf != "" {
logrus.Infof("VPP directory was manually set to %q via %s env var", conf, VPPDirEnvVar)
return conf, nil
}
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
cmd.Dir = dir
out, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("git command failed: %v\noutput: %s", err, out)
}
return strings.TrimSpace(string(out)), nil
}