github.com/Mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/version/version.go (about) 1 /* 2 Copyright 2018 Mirantis 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package version 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "fmt" 23 "log" 24 "runtime" 25 26 "github.com/ghodss/yaml" 27 ) 28 29 // Info specifies Virtlet version info 30 type Info struct { 31 // NodeName denotes the name of the node this info belongs too 32 // (empty if not applicable) 33 NodeName string `json:",omitempty"` 34 // Major is the major version number 35 Major string `json:"major"` 36 // Minor is the minor version number 37 Minor string `json:"minor"` 38 // GitVersion is the full version string 39 GitVersion string `json:"gitVersion"` 40 // GitCommit is the git commit id 41 GitCommit string `json:"gitCommit"` 42 // GitTreeState is the git tree state, which can be either "clean" or "dirty" 43 GitTreeState string `json:"gitTreeState"` 44 // BuildDate is the build date, e.g. 2018-04-16T18:48:12Z 45 BuildDate string `json:"buildDate"` 46 // GoVersion is the Go version that was used to build Virtlet 47 GoVersion string `json:"goVersion"` 48 // Compiler is the name of the compiler toolchain that 49 // built the binary (either "gc" or "gccgo") 50 Compiler string `json:"compiler"` 51 // Platform denotes the platform such as "linux" or "darwin" 52 Platform string `json:"platform"` 53 // ImageTag specifies the image tag to use for Virtelt 54 ImageTag string `json:"imageTag"` 55 } 56 57 type formatVersion func(v Info) []byte 58 59 func (v Info) text(indent string) []byte { 60 var b bytes.Buffer 61 fmt.Fprintf(&b, "%sVersion: %s\n", indent, v.GitVersion) 62 fmt.Fprintf(&b, "%sCommit: %s\n", indent, v.GitCommit) 63 fmt.Fprintf(&b, "%sBuild Date: %s\n", indent, v.BuildDate) 64 fmt.Fprintf(&b, "%sGo Version: %s\n", indent, v.GoVersion) 65 fmt.Fprintf(&b, "%sCompiler: %s\n", indent, v.Compiler) 66 fmt.Fprintf(&b, "%sPlatform: %s\n", indent, v.Platform) 67 if v.ImageTag != "" { 68 fmt.Fprintf(&b, "%sImageTag: %s\n", indent, v.ImageTag) 69 } 70 return b.Bytes() 71 } 72 73 var versionFormats = map[string]formatVersion{ 74 "text": func(v Info) []byte { 75 return v.text("") 76 }, 77 "short": func(v Info) []byte { 78 return []byte(v.GitVersion) 79 }, 80 "json": func(v Info) []byte { 81 out, err := json.Marshal(v) 82 if err != nil { 83 log.Panicf("Error marshaling version info to JSON: %#v: %v", v, err) 84 } 85 return out 86 }, 87 "yaml": func(v Info) []byte { 88 out, err := yaml.Marshal(v) 89 if err != nil { 90 log.Panicf("Error marshaling version info to YAML: %#v: %v", v, err) 91 } 92 return out 93 }, 94 } 95 96 // ToBytes returns a text representation of Info using the specified 97 // format which can be one of "text", "short", "json" or "yaml" 98 func (v Info) ToBytes(format string) ([]byte, error) { 99 f := versionFormats[format] 100 if f == nil { 101 return nil, fmt.Errorf("bad version format %q", format) 102 } 103 return f(v), nil 104 } 105 106 // Get returns the codebase version. 107 func Get() Info { 108 return Info{ 109 Major: gitMajor, 110 Minor: gitMinor, 111 GitVersion: gitVersion, 112 GitCommit: gitCommit, 113 GitTreeState: gitTreeState, 114 BuildDate: buildDate, 115 GoVersion: runtime.Version(), 116 Compiler: runtime.Compiler, 117 Platform: runtime.GOOS + "/" + runtime.GOARCH, 118 ImageTag: imageTag, 119 } 120 } 121 122 // ClusterVersionInfo specifies Virtlet version info for the whole 123 // cluster and the client 124 type ClusterVersionInfo struct { 125 // ClientVersion denotes the version of Virtlet command line tool 126 ClientVersion Info `json:"clientVersion"` 127 // NodeVersions specify versions for each node that runs Virtlet 128 NodeVersions []Info `json:"nodeVersions,omitempty"` 129 } 130 131 type formatClusterVersion func(v ClusterVersionInfo) []byte 132 133 var clusterVersionFormats = map[string]formatClusterVersion{ 134 "text": func(v ClusterVersionInfo) []byte { 135 var b bytes.Buffer 136 fmt.Fprintf(&b, "Client:\n%s", v.ClientVersion.text(" ")) 137 for _, nv := range v.NodeVersions { 138 fmt.Fprintf(&b, "Node %s:\n%s", nv.NodeName, nv.text(" ")) 139 } 140 return b.Bytes() 141 }, 142 "short": func(v ClusterVersionInfo) []byte { 143 var b bytes.Buffer 144 fmt.Fprintf(&b, "Client: %s\n", v.ClientVersion.GitVersion) 145 for _, nv := range v.NodeVersions { 146 fmt.Fprintf(&b, "Node %s: %s\n", nv.NodeName, nv.GitVersion) 147 } 148 return b.Bytes() 149 }, 150 "json": func(v ClusterVersionInfo) []byte { 151 out, err := json.Marshal(v) 152 if err != nil { 153 log.Panicf("Error marshaling version info to JSON: %#v: %v", v, err) 154 } 155 return out 156 }, 157 "yaml": func(v ClusterVersionInfo) []byte { 158 out, err := yaml.Marshal(v) 159 if err != nil { 160 log.Panicf("Error marshaling version info to YAML: %#v: %v", v, err) 161 } 162 return out 163 }, 164 } 165 166 // ToBytes returns a text representation of ClusterVersionInfo using 167 // the specified format which can be one of "text", "short", "json" or 168 // "yaml" 169 func (v ClusterVersionInfo) ToBytes(format string) ([]byte, error) { 170 f := clusterVersionFormats[format] 171 if f == nil { 172 return nil, fmt.Errorf("bad version format %q", format) 173 } 174 return f(v), nil 175 } 176 177 // AreNodesConsistent returns true if all the nodes that run Virtlet 178 // run exactly same Virtlet build 179 func (v ClusterVersionInfo) AreNodesConsistent() bool { 180 if len(v.NodeVersions) == 0 { 181 return true 182 } 183 nv := v.NodeVersions[0] 184 nv.NodeName = "" 185 for _, curNV := range v.NodeVersions[1:] { 186 curNV.NodeName = "" 187 if nv != curNV { 188 return false 189 } 190 } 191 return true 192 }