add opt-in notifications for beta releases
parent
24a759fb51
commit
29745438da
|
@ -114,6 +114,10 @@ var settings = []Setting{
|
|||
name: config.WantUpdateNotification,
|
||||
set: SetBool,
|
||||
},
|
||||
{
|
||||
name: config.WantBetaUpdateNotification,
|
||||
set: SetBool,
|
||||
},
|
||||
{
|
||||
name: config.ReminderWaitPeriodInHours,
|
||||
set: SetInt,
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[
|
||||
]
|
|
@ -32,7 +32,9 @@ import (
|
|||
const (
|
||||
// WantUpdateNotification is the key for WantUpdateNotification
|
||||
WantUpdateNotification = "WantUpdateNotification"
|
||||
// ReminderWaitPeriodInHours is the key for WantUpdateNotification
|
||||
// WantBetaUpdateNotification is the key for WantBetaUpdateNotification
|
||||
WantBetaUpdateNotification = "WantBetaUpdateNotification"
|
||||
// ReminderWaitPeriodInHours is the key for ReminderWaitPeriodInHours
|
||||
ReminderWaitPeriodInHours = "ReminderWaitPeriodInHours"
|
||||
// WantReportError is the key for WantReportError
|
||||
WantReportError = "WantReportError"
|
||||
|
|
|
@ -19,4 +19,6 @@ package notify
|
|||
const (
|
||||
// GithubMinikubeReleasesURL is the URL of the minikube github releases JSON file
|
||||
GithubMinikubeReleasesURL = "https://storage.googleapis.com/minikube/releases.json"
|
||||
// GithubMinikubeBetaReleasesURL is the URL of the minikube Github beta releases JSON file
|
||||
GithubMinikubeBetaReleasesURL = "https://storage.googleapis.com/minikube/releases-beta.json"
|
||||
)
|
||||
|
|
|
@ -44,6 +44,9 @@ var (
|
|||
|
||||
// MaybePrintUpdateTextFromGithub prints update text if needed, from github
|
||||
func MaybePrintUpdateTextFromGithub() bool {
|
||||
if notified := MaybePrintBetaUpdateText(GithubMinikubeBetaReleasesURL, lastUpdateCheckFilePath); notified {
|
||||
return true
|
||||
}
|
||||
return MaybePrintUpdateText(GithubMinikubeReleasesURL, lastUpdateCheckFilePath)
|
||||
}
|
||||
|
||||
|
@ -74,6 +77,35 @@ func MaybePrintUpdateText(url string, lastUpdatePath string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// MaybePrintBetaUpdateText returns true and prints update text of a new beta version of minikube is available.
|
||||
func MaybePrintBetaUpdateText(url string, lastUpdatePath string) bool {
|
||||
if !shouldCheckURLBetaVersion(lastUpdatePath) {
|
||||
return false
|
||||
}
|
||||
latestVersion, err := getLatestVersionFromURL(url)
|
||||
if err != nil {
|
||||
klog.Warning(err)
|
||||
return false
|
||||
}
|
||||
localVersion, err := version.GetSemverVersion()
|
||||
if err != nil {
|
||||
klog.Warning(err)
|
||||
return false
|
||||
}
|
||||
if localVersion.Compare(latestVersion) >= 0 {
|
||||
return false
|
||||
}
|
||||
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()); err != nil {
|
||||
klog.Errorf("write time failed: %v", err)
|
||||
}
|
||||
url = "https://github.com/kubernetes/minikube/releases/tag/v" + latestVersion.String()
|
||||
out.Styled(style.Celebrate, `minikube {{.version}} is available! Download it: {{.url}}`, out.V{"version": latestVersion, "url": url})
|
||||
out.Styled(style.Tip, "To disable beta notices, run: 'minikube config set WantBetaUpdateNotification false'\n")
|
||||
out.Styled(style.Tip, "To disable update notices in general, run: 'minikube config set WantUpdateNotification false'\n")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func shouldCheckURLVersion(filePath string) bool {
|
||||
if !viper.GetBool(config.WantUpdateNotification) {
|
||||
return false
|
||||
|
@ -82,6 +114,14 @@ func shouldCheckURLVersion(filePath string) bool {
|
|||
return time.Since(lastUpdateTime).Hours() >= viper.GetFloat64(config.ReminderWaitPeriodInHours)
|
||||
}
|
||||
|
||||
func shouldCheckURLBetaVersion(filePath string) bool {
|
||||
if !viper.GetBool(config.WantBetaUpdateNotification) {
|
||||
return false
|
||||
}
|
||||
|
||||
return shouldCheckURLVersion(filePath)
|
||||
}
|
||||
|
||||
// Release represents a release
|
||||
type Release struct {
|
||||
Name string
|
||||
|
|
|
@ -41,7 +41,7 @@ func TestMaybePrintUpdateTextFromGithub(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestShouldCheckURL(t *testing.T) {
|
||||
func TestShouldCheckURLVersion(t *testing.T) {
|
||||
tempDir := tests.MakeTempDir()
|
||||
defer tests.RemoveTempDir(tempDir)
|
||||
|
||||
|
@ -80,6 +80,52 @@ func TestShouldCheckURL(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
func TestShouldCheckURLBetaVersion(t *testing.T) {
|
||||
tempDir := tests.MakeTempDir()
|
||||
defer tests.RemoveTempDir(tempDir)
|
||||
|
||||
lastUpdateCheckFilePath := filepath.Join(tempDir, "last_update_check")
|
||||
|
||||
// test that if users disable update notification in config, the URL version does not get checked
|
||||
viper.Set(config.WantUpdateNotification, true)
|
||||
viper.Set(config.WantBetaUpdateNotification, false)
|
||||
if shouldCheckURLBetaVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLBetaVersion returned true even though config had WantBetaUpdateNotification: false")
|
||||
}
|
||||
|
||||
viper.Set(config.WantUpdateNotification, false)
|
||||
viper.Set(config.WantBetaUpdateNotification, true)
|
||||
if shouldCheckURLBetaVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLBetaVersion returned true even though config had WantUpdateNotification: false")
|
||||
}
|
||||
|
||||
// test that if users want update notification, the URL version does get checked
|
||||
viper.Set(config.WantUpdateNotification, true)
|
||||
if !shouldCheckURLBetaVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLBetaVersion returned false even though there was no last_update_check file")
|
||||
}
|
||||
|
||||
// test that update notifications get triggered if it has been longer than 24 hours
|
||||
viper.Set(config.ReminderWaitPeriodInHours, 24)
|
||||
|
||||
//time.Time{} returns time -> January 1, year 1, 00:00:00.000000000 UTC.
|
||||
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Time{}); err != nil {
|
||||
t.Errorf("write failed: %v", err)
|
||||
}
|
||||
if !shouldCheckURLBetaVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLBetaVersion returned false even though longer than 24 hours since last update")
|
||||
}
|
||||
|
||||
// test that update notifications do not get triggered if it has been less than 24 hours
|
||||
if err := writeTimeToFile(lastUpdateCheckFilePath, time.Now().UTC()); err != nil {
|
||||
t.Errorf("write failed: %v", err)
|
||||
}
|
||||
if shouldCheckURLBetaVersion(lastUpdateCheckFilePath) {
|
||||
t.Fatalf("shouldCheckURLBetaVersion returned true even though less than 24 hours since last update")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
type URLHandlerCorrect struct {
|
||||
releases Releases
|
||||
}
|
||||
|
@ -236,6 +282,106 @@ func TestMaybePrintUpdateText(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestMaybePrintBetaUpdateText(t *testing.T) {
|
||||
tempDir := tests.MakeTempDir()
|
||||
defer tests.RemoveTempDir(tempDir)
|
||||
outputBuffer := tests.NewFakeFile()
|
||||
out.SetOutFile(outputBuffer)
|
||||
|
||||
var tc = []struct {
|
||||
len int
|
||||
wantUpdateNotification bool
|
||||
wantBetaUpdateNotification bool
|
||||
latestVersionFromURL string
|
||||
description string
|
||||
status bool
|
||||
url string
|
||||
lastUpdateCheckFilePath string
|
||||
}{
|
||||
{
|
||||
len: 1,
|
||||
latestVersionFromURL: "0.0.0-dev",
|
||||
wantUpdateNotification: true,
|
||||
wantBetaUpdateNotification: true,
|
||||
description: "latest version lower or equal",
|
||||
},
|
||||
{
|
||||
len: 0,
|
||||
latestVersionFromURL: "100.0.0-dev",
|
||||
wantUpdateNotification: true,
|
||||
wantBetaUpdateNotification: true,
|
||||
description: "latest version greater",
|
||||
status: true,
|
||||
},
|
||||
{
|
||||
len: 1,
|
||||
latestVersionFromURL: "100.0.0-dev",
|
||||
wantUpdateNotification: false,
|
||||
wantBetaUpdateNotification: true,
|
||||
description: "notification unwanted",
|
||||
},
|
||||
{
|
||||
len: 1,
|
||||
latestVersionFromURL: "100.0.0-dev",
|
||||
wantUpdateNotification: true,
|
||||
wantBetaUpdateNotification: false,
|
||||
description: "beta notification unwanted",
|
||||
},
|
||||
{
|
||||
len: 1,
|
||||
latestVersionFromURL: "100.0.0-dev",
|
||||
wantUpdateNotification: true,
|
||||
wantBetaUpdateNotification: true,
|
||||
description: "bad url",
|
||||
url: "this is not valid url",
|
||||
status: false,
|
||||
},
|
||||
{
|
||||
len: 1,
|
||||
latestVersionFromURL: "10.0.0-dev",
|
||||
wantUpdateNotification: true,
|
||||
wantBetaUpdateNotification: true,
|
||||
description: "bad lastUpdateCheckFilePath",
|
||||
lastUpdateCheckFilePath: "/etc/passwd",
|
||||
status: true,
|
||||
},
|
||||
}
|
||||
|
||||
viper.Set(config.ReminderWaitPeriodInHours, 24)
|
||||
for _, test := range tc {
|
||||
t.Run(test.description, func(t *testing.T) {
|
||||
viper.Set(config.WantUpdateNotification, test.wantUpdateNotification)
|
||||
viper.Set(config.WantBetaUpdateNotification, test.wantBetaUpdateNotification)
|
||||
lastUpdateCheckFilePath = filepath.Join(tempDir, "last_update_check")
|
||||
if test.lastUpdateCheckFilePath != "" {
|
||||
lastUpdateCheckFilePath = test.lastUpdateCheckFilePath
|
||||
}
|
||||
latestVersionFromURL := test.latestVersionFromURL
|
||||
handler := &URLHandlerCorrect{
|
||||
releases: []Release{{Name: version.VersionPrefix + latestVersionFromURL}},
|
||||
}
|
||||
server := httptest.NewServer(handler)
|
||||
defer server.Close()
|
||||
if test.url == "" {
|
||||
test.url = server.URL
|
||||
}
|
||||
tmpfile, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot create temp file: %v", err)
|
||||
}
|
||||
defer os.Remove(tmpfile.Name())
|
||||
status := MaybePrintBetaUpdateText(test.url, tmpfile.Name())
|
||||
if test.status != status {
|
||||
t.Fatalf("MaybePrintBetaUpdateText expected to return %v, but got %v", test.status, status)
|
||||
}
|
||||
if len(outputBuffer.String()) == test.len {
|
||||
t.Fatalf("Expected MaybePrintBetaUpdateText to output text as the current version is %s and version %s was served from URL but output was [%s]",
|
||||
version.GetVersion(), latestVersionFromURL, outputBuffer.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDownloadURL(t *testing.T) {
|
||||
const urlBase = "https://github.com/kubernetes/minikube/releases/download/"
|
||||
type args struct {
|
||||
|
|
|
@ -27,6 +27,7 @@ Configurable fields:
|
|||
* kubernetes-version
|
||||
* iso-url
|
||||
* WantUpdateNotification
|
||||
* WantBetaUpdateNotification
|
||||
* ReminderWaitPeriodInHours
|
||||
* WantReportError
|
||||
* WantReportErrorPrompt
|
||||
|
|
Loading…
Reference in New Issue