Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal/olm: get installed version from cluster instead of required CLI argument #1634

Merged
merged 12 commits into from
Aug 15, 2019
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/operator-sdk/alpha/olm/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ func NewInstallCmd() *cobra.Command {
},
}

cmd.Flags().StringVar(&mgr.Version, "version", olm.DefaultVersion, "version of OLM resources to install")
mgr.AddToFlagSet(cmd.Flags())
return cmd
}
2 changes: 1 addition & 1 deletion cmd/operator-sdk/alpha/olm/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewStatusCmd() *cobra.Command {
Short: "Get the status of the Operator Lifecycle Manager installation in your cluster",
RunE: func(cmd *cobra.Command, args []string) error {
if err := mgr.Status(); err != nil {
log.Fatalf("Failed to get OLM status for version %q: %s", mgr.Version, err)
log.Fatalf("Failed to get OLM status: %s", err)
}
return nil
},
Expand Down
2 changes: 1 addition & 1 deletion cmd/operator-sdk/alpha/olm/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func NewUninstallCmd() *cobra.Command {
Short: "Uninstall Operator Lifecycle Manager from your cluster",
RunE: func(cmd *cobra.Command, args []string) error {
if err := mgr.Uninstall(); err != nil {
log.Fatalf("Failed to uninstall OLM version %q: %s", mgr.Version, err)
log.Fatalf("Failed to uninstall OLM: %s", err)
}
return nil
},
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
github.com/Masterminds/sprig v0.0.0-20190301161902-9f8fceff796f // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 // indirect
github.com/blang/semver v3.5.1+incompatible
github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect
github.com/coreos/bbolt v1.3.3 // indirect
github.com/coreos/go-semver v0.2.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
Expand Down
31 changes: 15 additions & 16 deletions hack/tests/alpha-olm-subcommands.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,35 @@ set -ex

test_version() {
local version="$1"
# If version is "latest", run without --version flag
local ver_flag="--version=${version}"
if [[ "$version" == "latest" ]]; then
ver_flag=""
fi

# Status should fail with OLM not installed
commandoutput=$(operator-sdk alpha olm status --version=${version} 2>&1 || true)
echo $commandoutput | grep -F "Failed to get OLM status for version \\\"${version}\\\": no existing installation found"
commandoutput=$(operator-sdk alpha olm status 2>&1 || true)
echo $commandoutput | grep -F "Failed to get OLM status: no existing installation found"

# Uninstall should fail with OLM not installed
commandoutput=$(operator-sdk alpha olm uninstall --version=${version} 2>&1 || true)
echo $commandoutput | grep -F "Failed to uninstall OLM version \\\"${version}\\\": no existing installation found"
commandoutput=$(operator-sdk alpha olm uninstall 2>&1 || true)
echo $commandoutput | grep -F "Failed to uninstall OLM: no existing installation found"

# Install should succeed with nothing installed
commandoutput=$(operator-sdk alpha olm install --version=${version} 2>&1)
commandoutput=$(operator-sdk alpha olm install $ver_flag 2>&1)
echo $commandoutput | grep -F "Successfully installed OLM version \\\"${version}\\\""

# Install should fail with OLM Installed
commandoutput=$(operator-sdk alpha olm install --version=${version} 2>&1 || true)
commandoutput=$(operator-sdk alpha olm install $ver_flag 2>&1 || true)
echo $commandoutput | grep -F "Failed to install OLM version \\\"${version}\\\": detected existing OLM resources: OLM must be completely uninstalled before installation"

# Status should succeed with OLM installed
# If version is "latest", also run without --version flag
if [[ "$version" == "latest" ]]; then
commandoutput=$(operator-sdk alpha olm status 2>&1)
echo $commandoutput | grep -F "Successfully got OLM status for version \\\"${version}\\\""
fi

commandoutput=$(operator-sdk alpha olm status --version=${version} 2>&1)
echo $commandoutput | grep -F "Successfully got OLM status for version \\\"${version}\\\""
commandoutput=$(operator-sdk alpha olm status 2>&1)
echo $commandoutput | grep -F "Successfully got OLM status"

# Uninstall should succeed with OLM installed
commandoutput=$(operator-sdk alpha olm uninstall --version=${version} 2>&1)
echo $commandoutput | grep -F "Successfully uninstalled OLM version \\\"${version}\\\""
commandoutput=$(operator-sdk alpha olm uninstall 2>&1)
echo $commandoutput | grep -F "Successfully uninstalled OLM"
}

test_version "latest"
Expand Down
62 changes: 62 additions & 0 deletions internal/olm/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,25 @@ import (
"io"
"io/ioutil"
"net/http"
"strings"
"time"

olmresourceclient "github.com/operator-framework/operator-sdk/internal/olm/client"

"github.com/blang/semver"
olmapiv1alpha1 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/yaml"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
)

const (
Expand Down Expand Up @@ -146,6 +151,63 @@ func (c Client) UninstallVersion(ctx context.Context, version string) error {
return nil
}

func (c Client) GetInstalledVersion(ctx context.Context) (string, error) {
opts := client.InNamespace(olmNamespace)
csvs := &olmapiv1alpha1.ClusterServiceVersionList{}
if err := c.KubeClient.List(ctx, opts, csvs); err != nil {
if apierrors.IsNotFound(err) || meta.IsNoMatchError(err) {
return "", ErrOLMNotInstalled
}
return "", errors.Wrap(err, "failed to get OLM version from CSVs")
}
var pkgServerCSV *olmapiv1alpha1.ClusterServiceVersion
for _, csv := range csvs.Items {
name := csv.GetName()
// Check old and new name possibilities.
if name == pkgServerCSVNewName || strings.HasPrefix(name, pkgServerCSVOldNamePrefix) {
// There is more than one version of OLM installed in the cluster,
// so we can't resolve the version being used.
if pkgServerCSV != nil {
return "", errors.New("failed to get OLM version: more than one OLM version installed")
}
pkgServerCSV = &csv
}
}
if pkgServerCSV == nil {
return "", ErrOLMNotInstalled
}
return getOLMVersionFromPackageServerCSV(pkgServerCSV)
}

const (
// Versions pre-0.11 have a versioned name.
pkgServerCSVOldNamePrefix = "packageserver."
// Versions 0.11+ have a fixed name.
pkgServerCSVNewName = "packageserver"
pkgServerOLMVersionLabel = "olm.version"
)

func getOLMVersionFromPackageServerCSV(csv *olmapiv1alpha1.ClusterServiceVersion) (string, error) {
// Package server CSV's from OLM versions > 0.10.1 have a label containing
// the OLM version.
if labels := csv.GetLabels(); labels != nil {
if ver, ok := labels[pkgServerOLMVersionLabel]; ok {
return ver, nil
}
}
// Fall back to getting OLM version from package server CSV name. Versions
// of OLM <= 0.10.1 are not labelled with pkgServerOLMVersionLabel.
ver := strings.TrimPrefix(csv.GetName(), pkgServerCSVOldNamePrefix)
// OLM releases do not have a "v" prefix but CSV versions do.
ver = strings.TrimPrefix(ver, "v")
// Check if a valid semver. Ignore non-nil errors as they are not related
// to the reason OLM version can't be found.
if _, err := semver.Parse(ver); err == nil {
return ver, nil
}
return "", errors.Errorf("no OLM version found in %s CSV spec", csv.GetName())
}

func (c Client) GetStatus(ctx context.Context, version string) (*olmresourceclient.Status, error) {
resources, err := c.getResources(ctx, version)
if err != nil {
Expand Down
19 changes: 14 additions & 5 deletions internal/olm/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,16 @@ func (m *Manager) Uninstall() error {
ctx, cancel := context.WithTimeout(context.Background(), m.Timeout)
defer cancel()

if err := m.Client.UninstallVersion(ctx, m.Version); err != nil {
version, err := m.Client.GetInstalledVersion(ctx)
if err != nil {
return err
}

if err := m.Client.UninstallVersion(ctx, version); err != nil {
return err
}

log.Infof("Successfully uninstalled OLM version %q", m.Version)
log.Infof("Successfully uninstalled OLM version %q", version)
return nil
}

Expand All @@ -108,18 +113,22 @@ func (m *Manager) Status() error {
ctx, cancel := context.WithTimeout(context.Background(), m.Timeout)
defer cancel()

status, err := m.Client.GetStatus(ctx, m.Version)
version, err := m.Client.GetInstalledVersion(ctx)
if err != nil {
return err
}

status, err := m.Client.GetStatus(ctx, version)
if err != nil {
return err
}

log.Infof("Successfully got OLM status for version %q", m.Version)
log.Infof("Successfully got OLM status for version %s", version)
fmt.Print("\n")
fmt.Println(status)
return nil
}

func (m *Manager) AddToFlagSet(fs *pflag.FlagSet) {
fs.StringVar(&m.Version, "version", DefaultVersion, "version of OLM resources to install, uninstall, or get status about")
fs.DurationVar(&m.Timeout, "timeout", DefaultTimeout, "time to wait for the command to complete before failing")
}