1
0
mirror of https://github.com/minio/mc.git synced 2025-11-12 01:02:26 +03:00
Files
mc/update-main.go

216 lines
6.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Minio Client (C) 2015 Minio, 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 (
"encoding/json"
"net/http"
"runtime"
"strings"
"time"
"github.com/fatih/color"
"github.com/minio/cli"
"github.com/minio/mc/pkg/console"
"github.com/minio/minio-xl/pkg/probe"
)
// Check for new software updates.
var updateCmd = cli.Command{
Name: "update",
Usage: "Check for new software updates.",
Action: mainUpdate,
CustomHelpTemplate: `Name:
mc {{.Name}} - {{.Usage}}
USAGE:
mc {{.Name}} release
mc {{.Name}} experimental
EXAMPLES:
1. Check for new official releases
$ mc {{.Name}} release
2. Check for new experimental releases
$ mc {{.Name}} experimental
`,
}
// Updates container to hold updates json
type Updates struct {
BuildDate string
Platforms map[string]string
}
// UpdateMessage container to hold update messages
type UpdateMessage struct {
Update bool `json:"update"`
Download string `json:"downloadURL"`
Version string `json:"version"`
}
// String colorized update message
func (u UpdateMessage) String() string {
if u.Update {
var msg string
if runtime.GOOS == "windows" {
msg = "mc.exe cp " + u.Download + " .\\mc.exe"
} else {
msg = "mc cp " + u.Download + " ./mc.new; chmod 755 ./mc.new"
}
msg, err := colorizeUpdateMessage(msg)
fatalIf(err.Trace(msg), "Unable to colorize experimental update notification string "+msg+".")
return msg
}
return console.Colorize("UpdateMessage", "You are already running the most recent version of mc.")
}
// JSON jsonified update message
func (u UpdateMessage) JSON() string {
updateMessageJSONBytes, err := json.Marshal(u)
fatalIf(probe.NewError(err), "Unable to marshal into JSON.")
return string(updateMessageJSONBytes)
}
const (
mcUpdateURL = "https://dl.minio.io:9000/updates/updates.json"
mcExperimentalURL = "https://dl.minio.io:9000/updates/experimental.json"
)
func checkUpdateSyntax(ctx *cli.Context) {
if ctx.Args().First() == "help" || !ctx.Args().Present() {
cli.ShowCommandHelpAndExit(ctx, "update", 1) // last argument is exit code
}
arg := strings.TrimSpace(ctx.Args().First())
if arg != "release" && arg != "experimental" {
fatalIf(errInvalidArgument().Trace(arg), "Unrecognized argument provided.")
}
}
func setUpdatePalette(style string) {
console.SetCustomPalette(map[string]*color.Color{
"UpdateMessage": color.New(color.FgGreen, color.Bold),
})
if style == "light" {
console.SetCustomPalette(map[string]*color.Color{
"UpdateMessage": color.New(color.FgWhite, color.Bold),
})
return
}
/// Add more styles here
if style == "nocolor" {
// All coloring options exhausted, setting nocolor safely
console.SetNoColor()
}
}
// mainUpdate -
func mainUpdate(ctx *cli.Context) {
checkUpdateSyntax(ctx)
setUpdatePalette(ctx.GlobalString("colors"))
arg := strings.TrimSpace(ctx.Args().First())
switch arg {
case "release":
getReleaseUpdate()
case "experimental":
getExperimentalUpdate()
}
}
func getExperimentalUpdate() {
clnt, err := url2Client(mcExperimentalURL)
fatalIf(err.Trace(mcExperimentalURL), "Unable to initalize experimental URL.")
data, _, err := clnt.GetObject(0, 0)
fatalIf(err.Trace(mcExperimentalURL), "Unable to read from experimental URL "+mcExperimentalURL+".")
current, e := time.Parse(http.TimeFormat, mcVersion)
fatalIf(probe.NewError(e), "Unable to parse Version string as time.")
if current.IsZero() {
fatalIf(errDummy().Trace(), "Experimental updates not supported for custom build. Version field is empty. Please download official releases from https://dl.minio.io:9000")
}
var experimentals Updates
decoder := json.NewDecoder(data)
e = decoder.Decode(&experimentals)
fatalIf(probe.NewError(e), "Unable to decode experimental update notification.")
latest, e := time.Parse(http.TimeFormat, experimentals.BuildDate)
fatalIf(probe.NewError(e), "Unable to parse BuildDate.")
if latest.IsZero() {
fatalIf(errDummy().Trace(), "Unable to validate any experimental update available at this time. Please open an issue at https://github.com/minio/mc/issues")
}
mcExperimentalURLParse := clnt.URL()
downloadURL := (mcExperimentalURLParse.Scheme + "://" +
mcExperimentalURLParse.Host +
string(mcExperimentalURLParse.Separator) +
experimentals.Platforms[runtime.GOOS])
updateMessage := UpdateMessage{
Download: downloadURL,
Version: mcVersion,
}
if latest.After(current) {
updateMessage.Update = true
}
Prints("%s\n", updateMessage)
}
func getReleaseUpdate() {
clnt, err := url2Client(mcUpdateURL)
fatalIf(err.Trace(mcUpdateURL), "Unable to initalize update URL.")
data, _, err := clnt.GetObject(0, 0)
fatalIf(err.Trace(mcUpdateURL), "Unable to read from update URL "+mcUpdateURL+".")
current, e := time.Parse(http.TimeFormat, mcVersion)
fatalIf(probe.NewError(e), "Unable to parse Version string as time.")
if current.IsZero() {
fatalIf(errDummy().Trace(), "Updates not supported for custom build. Version field is empty. Please download official releases from https://dl.minio.io:9000")
}
var updates Updates
decoder := json.NewDecoder(data)
e = decoder.Decode(&updates)
fatalIf(probe.NewError(e), "Unable to decode update notification.")
latest, e := time.Parse(http.TimeFormat, updates.BuildDate)
fatalIf(probe.NewError(e), "Unable to parse BuildDate.")
if latest.IsZero() {
fatalIf(errDummy().Trace(), "Unable to validate any update available at this time. Please open an issue at https://github.com/minio/mc/issues")
}
mcUpdateURLParse := clnt.URL()
downloadURL := mcUpdateURLParse.Scheme + "://" + mcUpdateURLParse.Host + string(mcUpdateURLParse.Separator) + updates.Platforms[runtime.GOOS]
updateMessage := UpdateMessage{
Download: downloadURL,
Version: mcVersion,
}
if latest.After(current) {
updateMessage.Update = true
}
Prints("%s\n", updateMessage)
}