Skip to content

Commit 1cb0a2c

Browse files
feat: add version command (#35)
add command to show current binary and addons versions.
1 parent 45d6178 commit 1cb0a2c

File tree

11 files changed

+133
-30
lines changed

11 files changed

+133
-30
lines changed

.github/workflows/pull-request.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,21 @@ jobs:
3737
steps:
3838
- name: Checkout
3939
uses: actions/checkout@v3
40+
- name: Get short commit hash
41+
run: echo "SHORT_SHA=$(git rev-parse --short=7 HEAD)" >> $GITHUB_ENV
4042
- name: Setup Go
4143
uses: actions/setup-go@v4
4244
with:
4345
go-version: "1.21.0"
4446
- name: Build Linux AMD64
4547
run: |
46-
make helmvm-linux-amd64
48+
make helmvm-linux-amd64 VERSION=dev-$SHORT_SHA
4749
- name: Build Darwin AMD64
4850
run: |
4951
make helmvm-darwin-amd64
50-
- name: Build Darwin ARM64
52+
- name: Build Darwin ARM64 VERSION=dev-$SHORT_SHA
5153
run: |
52-
make helmvm-darwin-arm64
54+
make helmvm-darwin-arm64 VERSION=dev-$SHORT_SHA
5355
- name: Build HelmVM Builder Server Image
5456
uses: docker/build-push-action@v4
5557
with:

.github/workflows/release-prod.yaml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,25 @@ jobs:
1313
uses: actions/checkout@v3
1414
with:
1515
fetch-depth: 0
16-
1716
- name: Extract tag name
1817
run: echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
19-
2018
- name: Set up Go
2119
uses: actions/setup-go@v4
2220
with:
2321
go-version: "1.20"
2422
- name: Build linux-amd64
2523
run: |
26-
make helmvm-linux-amd64
24+
make helmvm-linux-amd64 VERSION=$TAG_NAME
2725
tar -C output/bin -czvf helmvm-linux-amd64.tgz helmvm
2826
make clean
2927
- name: Build darwin-amd64
3028
run: |
31-
make helmvm-darwin-amd64
29+
make helmvm-darwin-amd64 VERSION=$TAG_NAME
3230
tar -C output/bin -czvf helmvm-darwin-amd64.tgz helmvm
3331
make clean
3432
- name: Build darwin-arm64
3533
run: |
36-
make helmvm-darwin-arm64
34+
make helmvm-darwin-arm64 VERSION=$TAG_NAME
3735
tar -C output/bin -czvf helmvm-darwin-arm64.tgz helmvm
3836
make clean
3937
- name: Publish release

Makefile

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
BUILDER_NAME=builder
2-
APP_NAME=helmvm
3-
ADMIN_CONSOLE_CHART_VERSION=1.100.1
4-
KUBECTL_VERSION=v1.27.3
5-
K0SCTL_VERSION=v0.15.2
6-
TERRAFORM_VERSION=1.5.4
7-
OPENEBS_VERSION=3.7.0
8-
K0S_VERSION=v1.27.2+k0s.0
9-
LD_FLAGS=-X github.com/replicatedhq/helmvm/pkg/defaults.K0sVersion=$(K0S_VERSION)
1+
VERSION ?= v0.0.0
2+
BUILDER_NAME = builder
3+
APP_NAME = helmvm
4+
ADMIN_CONSOLE_CHART_VERSION = 1.100.1
5+
KUBECTL_VERSION = v1.27.3
6+
K0SCTL_VERSION = v0.15.2
7+
TERRAFORM_VERSION = 1.5.4
8+
OPENEBS_VERSION = 3.7.0
9+
K0S_VERSION = v1.27.2+k0s.0
10+
LD_FLAGS = -X github.com/replicatedhq/helmvm/pkg/defaults.K0sVersion=$(K0S_VERSION) -X main.Version=$(VERSION)
1011

1112
default: helmvm-linux-amd64
1213

cmd/helmvm/install.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ var installCommand = &cli.Command{
374374
ccfg := defaults.PathToConfig("k0sctl.yaml")
375375
kcfg := defaults.PathToConfig("kubeconfig")
376376
os.Setenv("KUBECONFIG", kcfg)
377-
if applier, err := addons.NewApplier(prompt); err != nil {
377+
if applier, err := addons.NewApplier(prompt, true); err != nil {
378378
return fmt.Errorf("unable to create applier: %w", err)
379379
} else if err := applier.Apply(c.Context); err != nil {
380380
return fmt.Errorf("unable to apply addons: %w", err)

cmd/helmvm/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ func main() {
2020
embedCommand,
2121
shellCommand,
2222
nodeCommands,
23+
versionCommand,
2324
},
2425
}
2526
if err := app.Run(os.Args); err != nil {

cmd/helmvm/upgrade.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ var upgradeCommand = &cli.Command{
8181
}
8282
os.Setenv("KUBECONFIG", kcfg)
8383
logrus.Infof("Upgrading addons")
84-
if applier, err := addons.NewApplier(c.Bool("no-prompt")); err != nil {
84+
if applier, err := addons.NewApplier(c.Bool("no-prompt"), true); err != nil {
8585
return fmt.Errorf("unable to create applier: %w", err)
8686
} else if err := applier.Apply(c.Context); err != nil {
8787
return fmt.Errorf("unable to apply addons: %w", err)

cmd/helmvm/version.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/jedib0t/go-pretty/table"
8+
"github.com/urfave/cli/v2"
9+
10+
"github.com/replicatedhq/helmvm/pkg/addons"
11+
"github.com/replicatedhq/helmvm/pkg/defaults"
12+
)
13+
14+
var Version = "v0.0.0"
15+
16+
var versionCommand = &cli.Command{
17+
Name: "version",
18+
Usage: fmt.Sprintf("Shows the %s installer version", defaults.BinaryName()),
19+
Action: func(c *cli.Context) error {
20+
applier, err := addons.NewApplier(true, false)
21+
if err != nil {
22+
return fmt.Errorf("unable to create applier: %w", err)
23+
}
24+
versions, err := applier.Versions()
25+
if err != nil {
26+
return fmt.Errorf("unable to get versions: %w", err)
27+
}
28+
writer := table.NewWriter()
29+
writer.AppendHeader(table.Row{"component", "version"})
30+
writer.AppendRow(table.Row{"Installer", Version})
31+
writer.AppendRow(table.Row{"Kubernetes", defaults.K0sVersion})
32+
for name, version := range versions {
33+
if !strings.HasPrefix(version, "v") {
34+
version = fmt.Sprintf("v%s", version)
35+
}
36+
writer.AppendRow(table.Row{name, version})
37+
}
38+
fmt.Printf("%s\n", writer.Render())
39+
return nil
40+
},
41+
}

pkg/addons/adminconsole/adminconsole.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ func (a *AdminConsole) askPassword() (string, error) {
5858
return pass, nil
5959
}
6060

61+
func (a *AdminConsole) Version() (map[string]string, error) {
62+
latest, err := a.Latest()
63+
if err != nil {
64+
return nil, fmt.Errorf("unable to get latest version: %w", err)
65+
}
66+
return map[string]string{"AdminConsole": latest}, nil
67+
}
68+
6169
func (a *AdminConsole) Apply(ctx context.Context) error {
6270
version, err := a.Latest()
6371
if err != nil {

pkg/addons/applier.go

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/sirupsen/logrus"
13+
"helm.sh/helm/v3/pkg/action"
1314
corev1 "k8s.io/api/core/v1"
1415
"sigs.k8s.io/controller-runtime/pkg/client"
1516
"sigs.k8s.io/controller-runtime/pkg/client/config"
@@ -27,9 +28,21 @@ type Applier struct {
2728
addons map[string]AddOn
2829
}
2930

31+
// DoNotLog is a helper function to disable logging for addons.
32+
func DoNotLog(format string, v ...interface{}) {}
33+
34+
// getLogger creates a logger to be used in an addon.
35+
func getLogger(addon string, verbose bool) action.DebugLog {
36+
if !verbose {
37+
return DoNotLog
38+
}
39+
return logrus.WithField("addon", addon).Infof
40+
}
41+
3042
// AddOn is the interface that all addons must implement.
3143
type AddOn interface {
3244
Apply(ctx context.Context) error
45+
Version() (map[string]string, error)
3346
}
3447

3548
// Apply applies all registered addons to the cluster. Simply calls Apply on
@@ -48,6 +61,21 @@ func (a *Applier) Apply(ctx context.Context) error {
4861
return nil
4962
}
5063

64+
// Version returns a map with the version of each addon that will be applied.
65+
func (a *Applier) Versions() (map[string]string, error) {
66+
versions := map[string]string{}
67+
for name, addon := range a.addons {
68+
version, err := addon.Version()
69+
if err != nil {
70+
return nil, fmt.Errorf("unable to get version (%s): %w", name, err)
71+
}
72+
for k, v := range version {
73+
versions[k] = v
74+
}
75+
}
76+
return versions, nil
77+
}
78+
5179
// waitForKubernetes waits until we manage to make a successful connection to the
5280
// Kubernetes API server.
5381
func (a *Applier) waitForKubernetes(ctx context.Context) error {
@@ -77,7 +105,7 @@ func (a *Applier) waitForKubernetes(ctx context.Context) error {
77105
}
78106

79107
// NewApplier creates a new Applier instance with all addons registered.
80-
func NewApplier(prompt bool) (*Applier, error) {
108+
func NewApplier(prompt, verbose bool) (*Applier, error) {
81109
k8slogger := zap.New(func(o *zap.Options) {
82110
o.DestWriter = io.Discard
83111
})
@@ -90,24 +118,18 @@ func NewApplier(prompt bool) (*Applier, error) {
90118
if err != nil {
91119
return nil, fmt.Errorf("unable to create kubernetes client: %w", err)
92120
}
93-
applier := &Applier{
94-
addons: map[string]AddOn{},
95-
kubeclient: kubecli,
96-
}
97-
logger := logrus.WithField("addon", "openebs")
98-
obs, err := openebs.New("helmvm", logger.Infof)
121+
applier := &Applier{addons: map[string]AddOn{}, kubeclient: kubecli}
122+
obs, err := openebs.New("helmvm", getLogger("openebs", verbose))
99123
if err != nil {
100124
return nil, fmt.Errorf("unable to create admin console addon: %w", err)
101125
}
102126
applier.addons["openebs"] = obs
103-
logger = logrus.WithField("addon", "adminconsole")
104-
aconsole, err := adminconsole.New("helmvm", prompt, kubecli, logger.Infof)
127+
aconsole, err := adminconsole.New("helmvm", prompt, kubecli, getLogger("adminconsole", verbose))
105128
if err != nil {
106129
return nil, fmt.Errorf("unable to create admin console addon: %w", err)
107130
}
108131
applier.addons["adminconsole"] = aconsole
109-
logger = logrus.WithField("addon", "custom")
110-
custom, err := custom.New("helmvm", logger.Infof)
132+
custom, err := custom.New("helmvm", getLogger("custom", verbose))
111133
if err != nil {
112134
return nil, fmt.Errorf("unable to create admin console addon: %w", err)
113135
}

pkg/addons/custom/custom.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,28 @@ type Custom struct {
2424
namespace string
2525
}
2626

27+
func (c *Custom) Version() (map[string]string, error) {
28+
exe, err := os.Executable()
29+
if err != nil {
30+
return nil, fmt.Errorf("unable to get executable path: %w", err)
31+
}
32+
opts, err := hembed.ReadEmbedOptionsFromBinary(exe)
33+
if err != nil {
34+
return nil, fmt.Errorf("unable to read embed options: %w", err)
35+
} else if opts == nil {
36+
return nil, nil
37+
}
38+
infos := make(map[string]string)
39+
for _, raw := range opts.Charts {
40+
chart, err := loader.LoadArchive(raw.ChartReader())
41+
if err != nil {
42+
return nil, fmt.Errorf("unable to load chart archive: %w", err)
43+
}
44+
infos[chart.Name()] = chart.Metadata.Version
45+
}
46+
return infos, nil
47+
}
48+
2749
func (c *Custom) Apply(ctx context.Context) error {
2850
exe, err := os.Executable()
2951
if err != nil {

pkg/addons/openebs/openebs.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ type OpenEBS struct {
4040
namespace string
4141
}
4242

43+
func (o *OpenEBS) Version() (map[string]string, error) {
44+
latest, err := o.latest()
45+
if err != nil {
46+
return nil, fmt.Errorf("unable to get latest version: %w", err)
47+
}
48+
return map[string]string{"OpenEBS": latest}, nil
49+
}
50+
4351
func (o *OpenEBS) Apply(ctx context.Context) error {
4452
version, err := o.latest()
4553
if err != nil {

0 commit comments

Comments
 (0)