mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 01:03:40 +00:00
introduce teleport version, fixes #241
Here's how it works: * It takes the closest tag that is present in the build * Automatically applies this tag * Adds git commit as well * Is 100% go gettable * No external deps, all vendored
This commit is contained in:
parent
9da1e2baf4
commit
19788c25ce
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -30,3 +30,4 @@ _testmain.go
|
|||
flymake*
|
||||
|
||||
QR.png
|
||||
/vendor/github.com/gravitational/version/LICENSE
|
||||
|
|
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
|
@ -97,6 +97,10 @@
|
|||
"ImportPath": "github.com/gravitational/trace",
|
||||
"Rev": "0fd0db9ea941edb81e90278f4eb8f29f5615637e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/gravitational/version",
|
||||
"Rev": "cfc6250a884a833eed6ac0417a6f245f5ac49d7a"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jonboulle/clockwork",
|
||||
"Rev": "ed104f61ea4877bea08af6f759805674861e968d"
|
||||
|
|
8
Makefile
8
Makefile
|
@ -24,8 +24,8 @@ teleport:
|
|||
tsh:
|
||||
go build -o $(OUT)/tsh -i github.com/gravitational/teleport/tool/tsh
|
||||
|
||||
install: remove-temp-files
|
||||
go install github.com/gravitational/teleport/tool/teleport \
|
||||
install: remove-temp-files flags
|
||||
go install -ldflags $(TELEPORT_LINKFLAGS) github.com/gravitational/teleport/tool/teleport \
|
||||
github.com/gravitational/teleport/tool/tctl \
|
||||
github.com/gravitational/teleport/tool/tsh \
|
||||
|
||||
|
@ -50,6 +50,10 @@ test:
|
|||
github.com/gravitational/teleport/tool/teleport... $(FLAGS)
|
||||
go vet ./tool/... ./lib/...
|
||||
|
||||
flags:
|
||||
go install github.com/gravitational/teleport/vendor/github.com/gravitational/version/cmd/linkflags
|
||||
$(eval TELEPORT_LINKFLAGS := "$(shell linkflags -pkg=$(PWD) -verpkg=github.com/gravitational/teleport/vendor/github.com/gravitational/version)")
|
||||
|
||||
|
||||
test-with-etcd: install
|
||||
${ETCD_FLAGS} go test -v -test.parallel=0 $(shell go list ./... | grep -v /vendor/) -cover
|
||||
|
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
|
@ -29,6 +30,7 @@ import (
|
|||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/gravitational/version"
|
||||
"github.com/pborman/uuid"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
@ -143,6 +145,16 @@ func ReadOrMakeHostUUID(dataDir string) (string, error) {
|
|||
return string(bytes), nil
|
||||
}
|
||||
|
||||
// PrintVersion prints human readable version
|
||||
func PrintVersion() {
|
||||
ver := version.Get()
|
||||
if ver.GitCommit != "" {
|
||||
fmt.Printf("%v git:%v\n", ver.Version, ver.GitCommit)
|
||||
} else {
|
||||
fmt.Printf("%v\n", ver.Version)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
// CertTeleportUser specifies teleport user
|
||||
CertTeleportUser = "x-teleport-user"
|
||||
|
|
|
@ -154,5 +154,5 @@ func onConfigDump() {
|
|||
|
||||
// onVersion is the handler for "version"
|
||||
func onVersion() {
|
||||
fmt.Println("'version' command is not implemented")
|
||||
utils.PrintVersion()
|
||||
}
|
||||
|
|
|
@ -284,7 +284,7 @@ func makeClient(cf *CLIConf) (tc *client.TeleportClient, err error) {
|
|||
}
|
||||
|
||||
func onVersion() {
|
||||
fmt.Println("Version!")
|
||||
utils.PrintVersion()
|
||||
}
|
||||
|
||||
func printHeader(t *goterm.Table, cols []string) {
|
||||
|
|
72
vendor/github.com/gravitational/version/README.md
generated
vendored
Normal file
72
vendor/github.com/gravitational/version/README.md
generated
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
# version
|
||||
|
||||
`version` is a Go library for automatic build versioning. It attempts to simplify the mundane task of adding build version information to any Go package.
|
||||
|
||||
### Usage
|
||||
|
||||
Install the command line utility to generate the linker flags necessary for versioning from the cmd/linkflags:
|
||||
|
||||
```shell
|
||||
go install github.com/gravitational/version/cmd/linkflags
|
||||
```
|
||||
|
||||
Add the following configuration to your build script / Makefile
|
||||
(assuming a bash script):
|
||||
|
||||
```bash
|
||||
GO_LDFLAGS=$(linkflags -pkg=path/to/your/package)
|
||||
|
||||
# build with the linker flags:
|
||||
go build -ldflags="${GO_LDFLAGS}"
|
||||
```
|
||||
|
||||
To use, simply import the package and either obtain the version with `Get` or print the JSON-formatted version with `Print`:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/gravitational/version"
|
||||
|
||||
func main() {
|
||||
version.Print()
|
||||
}
|
||||
```
|
||||
|
||||
If you have a custom vendoring solution, you might have this package stored under a different path than the default (`go get`).
|
||||
In this case, you can override the default with a command line option (using [godep] as a vendoring solution):
|
||||
|
||||
```shell
|
||||
MY_PACKAGE=github.com/my/package
|
||||
MY_PACKAGE_PATH=$(pwd)
|
||||
GO_LDFLAGS=$(linkflags -pkg=${MY_PACKAGE_PATH} -verpkg=${MY_PACKAGE}/Godeps/_workspace/src/github.com/gravitational/version)
|
||||
```
|
||||
|
||||
The version part of the version information requires that you properly [tag] your packages:
|
||||
|
||||
```shell
|
||||
$ git tag
|
||||
v1.0.0-alpha.1
|
||||
v1.0.0-beta.1
|
||||
```
|
||||
|
||||
The build versioning scheme is a slight modification of the scheme from the [Kubernetes] project.
|
||||
It consists of three parts:
|
||||
- a version string in [semver] format
|
||||
- git commit ID
|
||||
- git tree state (`clean` or `dirty`)
|
||||
|
||||
```go
|
||||
type Info struct {
|
||||
Version string `json:"version"`
|
||||
GitCommit string `json:"gitCommit"`
|
||||
GitTreeState string `json:"gitTreeState"`
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
[//]: # (Footnots and references)
|
||||
|
||||
[Kubernetes]: <https://github.com/kubernetes/kubernetes>
|
||||
[semver]: <http://semver.org>
|
||||
[godep]: <https://github.com/tools/godep>
|
||||
[tag]: <https://git-scm.com/book/en/v2/Git-Basics-Tagging>
|
29
vendor/github.com/gravitational/version/base.go
generated
vendored
Normal file
29
vendor/github.com/gravitational/version/base.go
generated
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Copyright 2015 Gravitational, Inc.
|
||||
|
||||
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 version
|
||||
|
||||
// Version value defaults
|
||||
var (
|
||||
// Version string, a slightly modified version of `git describe` to be semver-complaint
|
||||
version string = "v0.0.0-master+$Format:%h$"
|
||||
gitCommit string = "$Format:%H$" // sha1 from git, output of $(git rev-parse HEAD)
|
||||
gitTreeState string = "not a git tree" // state of git tree, either "clean" or "dirty"
|
||||
)
|
||||
|
||||
// Init sets an alternative default for the version string.
|
||||
func Init(baseVersion string) {
|
||||
version = baseVersion
|
||||
}
|
213
vendor/github.com/gravitational/version/cmd/linkflags/main.go
generated
vendored
Normal file
213
vendor/github.com/gravitational/version/cmd/linkflags/main.go
generated
vendored
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
Copyright 2015 Gravitational, Inc.
|
||||
|
||||
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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gravitational/version"
|
||||
"github.com/gravitational/version/pkg/tool"
|
||||
)
|
||||
|
||||
// pkg is the path to the package the tool will create linker flags for.
|
||||
var pkg = flag.String("pkg", "", "root package path")
|
||||
|
||||
// versionPackage is the path to this version package.
|
||||
// It is used to access version information attributes during link time.
|
||||
// This flag is useful when the version package is custom-vendored and has a different package path.
|
||||
var versionPackage = flag.String("verpkg", "github.com/gravitational/version", "path to the version package")
|
||||
|
||||
var compatMode = flag.Bool("compat", false, "generate linker flags using go1.4 syntax")
|
||||
|
||||
// semverPattern defines a regexp pattern to modify the results of `git describe` to be semver-complaint.
|
||||
var semverPattern = regexp.MustCompile(`(.+)-([0-9]{1,})-g([0-9a-f]{14})$`)
|
||||
|
||||
// goVersionPattern defines a regexp pattern to parse versions of the `go tool`.
|
||||
var goVersionPattern = regexp.MustCompile(`go([1-9])\.(\d+)(?:.\d+)*`)
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
log.SetFlags(0)
|
||||
flag.Parse()
|
||||
if *pkg == "" {
|
||||
return fmt.Errorf("-pkg required")
|
||||
}
|
||||
|
||||
goVersion, err := goToolVersion()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to determine go tool version: %v\n", err)
|
||||
}
|
||||
|
||||
info, err := getVersionInfo(*pkg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to determine version information: %v\n", err)
|
||||
}
|
||||
|
||||
var linkFlags []string
|
||||
linkFlag := func(key, value string) string {
|
||||
if goVersion <= 14 || *compatMode {
|
||||
return fmt.Sprintf("-X %s.%s %s", *versionPackage, key, value)
|
||||
} else {
|
||||
return fmt.Sprintf("-X %s.%s=%s", *versionPackage, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the values of version-related variables as commands to the go linker.
|
||||
if info.GitCommit != "" {
|
||||
linkFlags = append(linkFlags, linkFlag("gitCommit", info.GitCommit))
|
||||
linkFlags = append(linkFlags, linkFlag("gitTreeState", info.GitTreeState))
|
||||
}
|
||||
if info.Version != "" {
|
||||
linkFlags = append(linkFlags, linkFlag("version", info.Version))
|
||||
}
|
||||
|
||||
fmt.Printf("%s", strings.Join(linkFlags, " "))
|
||||
return nil
|
||||
}
|
||||
|
||||
// getVersionInfo collects the build version information for package pkg.
|
||||
func getVersionInfo(pkg string) (*version.Info, error) {
|
||||
git := newGit(pkg)
|
||||
commitID, err := git.commitID()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to obtain git commit ID: %v\n", err)
|
||||
}
|
||||
treeState, err := git.treeState()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to determine git tree state: %v\n", err)
|
||||
}
|
||||
tag, err := git.tag(commitID)
|
||||
if err != nil {
|
||||
tag = ""
|
||||
}
|
||||
if tag != "" {
|
||||
tag = semverify(tag)
|
||||
if treeState == dirty {
|
||||
tag = tag + "-" + string(treeState)
|
||||
}
|
||||
}
|
||||
return &version.Info{
|
||||
Version: tag,
|
||||
GitCommit: commitID,
|
||||
GitTreeState: string(treeState),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// goToolVersion determines the version of the `go tool`.
|
||||
func goToolVersion() (toolVersion, error) {
|
||||
goTool := &tool.T{Cmd: "go"}
|
||||
out, err := goTool.Exec("version")
|
||||
if err != nil {
|
||||
return toolVersionUnknown, err
|
||||
}
|
||||
build := strings.Split(out, " ")
|
||||
if len(build) > 2 {
|
||||
return parseToolVersion(build[2]), nil
|
||||
}
|
||||
return toolVersionUnknown, nil
|
||||
}
|
||||
|
||||
// parseToolVersion translates a string version of the form 'go1.4.3' to a numeric value 14.
|
||||
func parseToolVersion(version string) toolVersion {
|
||||
match := goVersionPattern.FindStringSubmatch(version)
|
||||
if len(match) > 2 {
|
||||
// After a successful match, match[1] and match[2] are integers
|
||||
major := mustAtoi(match[1])
|
||||
minor := mustAtoi(match[2])
|
||||
return toolVersion(major*10 + minor)
|
||||
}
|
||||
return toolVersionUnknown
|
||||
}
|
||||
|
||||
func newGit(pkg string) *git {
|
||||
args := []string{"--work-tree", pkg, "--git-dir", filepath.Join(pkg, ".git")}
|
||||
return &git{&tool.T{
|
||||
Cmd: "git",
|
||||
Args: args,
|
||||
}}
|
||||
}
|
||||
|
||||
// git represents an instance of the git tool.
|
||||
type git struct {
|
||||
*tool.T
|
||||
}
|
||||
|
||||
// treeState describes the state of the git tree.
|
||||
// `git describe --dirty` only considers changes to existing files.
|
||||
// We track tree state and consider untracked files as they also affect the build.
|
||||
type treeState string
|
||||
|
||||
const (
|
||||
clean treeState = "clean"
|
||||
dirty = "dirty"
|
||||
)
|
||||
|
||||
// toolVersion represents a tool version as an integer.
|
||||
// toolVersion only considers the first two significant version parts and is computed as follows:
|
||||
// majorVersion*10+minorVersion
|
||||
type toolVersion int
|
||||
|
||||
const toolVersionUnknown toolVersion = 0
|
||||
|
||||
func (r *git) commitID() (string, error) {
|
||||
return r.Exec("rev-parse", "HEAD^{commit}")
|
||||
}
|
||||
|
||||
func (r *git) treeState() (treeState, error) {
|
||||
out, err := r.Exec("status", "--porcelain")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(out) == 0 {
|
||||
return clean, nil
|
||||
}
|
||||
return dirty, nil
|
||||
}
|
||||
|
||||
func (r *git) tag(commitID string) (string, error) {
|
||||
return r.Exec("describe", "--tags", "--abbrev=14", commitID+"^{commit}")
|
||||
}
|
||||
|
||||
// semverify transforms the output of `git describe` to be semver-complaint.
|
||||
func semverify(version string) string {
|
||||
var result []byte
|
||||
match := semverPattern.FindStringSubmatchIndex(version)
|
||||
if match != nil {
|
||||
return string(semverPattern.ExpandString(result, "$1.$2+$3", string(version), match))
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
// mustAtoi converts value to an integer.
|
||||
// It panics if the value does not represent a valid integer.
|
||||
func mustAtoi(value string) int {
|
||||
result, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
17
vendor/github.com/gravitational/version/doc.go
generated
vendored
Normal file
17
vendor/github.com/gravitational/version/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
Copyright 2015 Gravitational, Inc.
|
||||
|
||||
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 version supplies version information collected at build time.
|
||||
package version
|
65
vendor/github.com/gravitational/version/pkg/tool/tool.go
generated
vendored
Normal file
65
vendor/github.com/gravitational/version/pkg/tool/tool.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2015 Gravitational, Inc.
|
||||
|
||||
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 tool provides a currying wrapper around os/exec.Command that fixes a set of arguments.
|
||||
package tool
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// T represents an instance of a running tool specified with cmd and
|
||||
// an optional list of fixed initial arguments args.
|
||||
type T struct {
|
||||
Cmd string
|
||||
Args []string
|
||||
}
|
||||
|
||||
// Error is a tool execution error.
|
||||
type Error struct {
|
||||
Tool string
|
||||
Output []byte
|
||||
Err error
|
||||
}
|
||||
|
||||
func (r *Error) Error() string {
|
||||
return fmt.Sprintf("error executing `%s`: %v (%s)", r.Tool, r.Err, r.Output)
|
||||
}
|
||||
|
||||
// exec executes a given command specified with args prepending a set of fixed arguments.
|
||||
// Otherwise behaves exactly as rawExec
|
||||
func (r *T) Exec(args ...string) (string, error) {
|
||||
args = append(r.Args[:], args...)
|
||||
return r.RawExec(args...)
|
||||
}
|
||||
|
||||
// RawExec executes a given command specified with args and returns the output
|
||||
// with whitespace trimmed.
|
||||
func (r *T) RawExec(args ...string) (string, error) {
|
||||
out, err := exec.Command(r.Cmd, args...).CombinedOutput()
|
||||
if err == nil {
|
||||
out = bytes.TrimSpace(out)
|
||||
}
|
||||
if err != nil {
|
||||
err = &Error{
|
||||
Tool: r.Cmd,
|
||||
Output: out,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
return string(out), err
|
||||
}
|
13
vendor/github.com/gravitational/version/test/main.go
generated
vendored
Normal file
13
vendor/github.com/gravitational/version/test/main.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
package main
|
||||
|
||||
import "github.com/gravitational/version"
|
||||
|
||||
func init() {
|
||||
// Reset base version to a custom one in case no tag has been created.
|
||||
// It will be reset with a git tag if there's one.
|
||||
version.Init("v0.0.1")
|
||||
}
|
||||
|
||||
func main() {
|
||||
version.Print()
|
||||
}
|
51
vendor/github.com/gravitational/version/version.go
generated
vendored
Normal file
51
vendor/github.com/gravitational/version/version.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2015 Gravitational, Inc.
|
||||
|
||||
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 version
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Info describes build version with a semver-complaint version string and
|
||||
// git-related commit/tree state details.
|
||||
type Info struct {
|
||||
Version string `json:"version"`
|
||||
GitCommit string `json:"gitCommit"`
|
||||
GitTreeState string `json:"gitTreeState"`
|
||||
}
|
||||
|
||||
// Get returns current build version.
|
||||
func Get() Info {
|
||||
return Info{
|
||||
Version: version,
|
||||
GitCommit: gitCommit,
|
||||
GitTreeState: gitTreeState,
|
||||
}
|
||||
}
|
||||
|
||||
func (r Info) String() string {
|
||||
return r.Version
|
||||
}
|
||||
|
||||
// Print prints build version in default format.
|
||||
func Print() {
|
||||
payload, err := json.Marshal(Get())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("%s", payload)
|
||||
}
|
Loading…
Reference in a new issue