mirror of
https://github.com/weaveworks/scope.git
synced 2026-03-04 18:51:17 +00:00
Report if newer version are availible in /api (#1366)
* Report if newer version are availible in /api * Render version update hint in UI, next to version * Fix lint
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/PuerkitoBio/ghost/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
@@ -132,17 +133,35 @@ func RegisterReportPostHandler(a Adder, router *mux.Router) {
|
||||
}))
|
||||
}
|
||||
|
||||
var newVersion = struct {
|
||||
sync.Mutex
|
||||
*xfer.NewVersionInfo
|
||||
}{}
|
||||
|
||||
// NewVersion is called to expose new version information to /api
|
||||
func NewVersion(version, downloadURL string) {
|
||||
newVersion.Lock()
|
||||
defer newVersion.Unlock()
|
||||
newVersion.NewVersionInfo = &xfer.NewVersionInfo{
|
||||
Version: version,
|
||||
DownloadURL: downloadURL,
|
||||
}
|
||||
}
|
||||
|
||||
func apiHandler(rep Reporter) CtxHandlerFunc {
|
||||
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
report, err := rep.Report(ctx)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
newVersion.Lock()
|
||||
defer newVersion.Unlock()
|
||||
respondWith(w, http.StatusOK, xfer.Details{
|
||||
ID: UniqueID,
|
||||
Version: Version,
|
||||
Hostname: hostname.Get(),
|
||||
Plugins: report.Plugins,
|
||||
ID: UniqueID,
|
||||
Version: Version,
|
||||
Hostname: hostname.Get(),
|
||||
Plugins: report.Plugins,
|
||||
NewVersion: newVersion.NewVersionInfo,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ function getStateFromStores() {
|
||||
updatePaused: AppStore.isUpdatePaused(),
|
||||
updatePausedAt: AppStore.getUpdatePausedAt(),
|
||||
version: AppStore.getVersion(),
|
||||
versionUpdate: AppStore.getVersionUpdate(),
|
||||
plugins: AppStore.getPlugins(),
|
||||
websocketClosed: AppStore.isWebsocketClosed()
|
||||
};
|
||||
@@ -183,7 +184,9 @@ export default class App extends React.Component {
|
||||
activeOptions={this.state.activeTopologyOptions} />
|
||||
</Sidebar>
|
||||
|
||||
<Footer {...this.state} />
|
||||
<Footer hostname={this.state.hostname} plugins={this.state.plugins}
|
||||
updatePaused={this.state.updatePaused} updatePausedAt={this.state.updatePausedAt}
|
||||
version={this.state.version} versionUpdate={this.state.versionUpdate} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { clickDownloadGraph, clickForceRelayout, clickPauseUpdate,
|
||||
import { basePathSlash } from '../utils/web-api-utils';
|
||||
|
||||
export default function Footer(props) {
|
||||
const { hostname, plugins, updatePaused, updatePausedAt, version } = props;
|
||||
const { hostname, plugins, updatePaused, updatePausedAt, version, versionUpdate } = props;
|
||||
const contrastMode = isContrastMode();
|
||||
|
||||
// link url to switch contrast with current UI state
|
||||
@@ -38,10 +38,18 @@ export default function Footer(props) {
|
||||
pauseLabel = 'Paused';
|
||||
}
|
||||
|
||||
const versionUpdateTitle = versionUpdate
|
||||
? `New version available: ${versionUpdate.version}. Click to download`
|
||||
: '';
|
||||
|
||||
return (
|
||||
<div className="footer">
|
||||
|
||||
<div className="footer-status">
|
||||
{versionUpdate && <a className="footer-versionupdate"
|
||||
title={versionUpdateTitle} href={versionUpdate.downloadUrl} target="_blank">
|
||||
Update available: {versionUpdate.version}
|
||||
</a>}
|
||||
<span className="footer-label">Version</span>
|
||||
{version}
|
||||
<span className="footer-label">on</span>
|
||||
|
||||
@@ -46,6 +46,7 @@ let highlightedEdgeIds = makeSet();
|
||||
let highlightedNodeIds = makeSet();
|
||||
let hostname = '...';
|
||||
let version = '...';
|
||||
let versionUpdate = null;
|
||||
let plugins = [];
|
||||
let mouseOverEdgeId = null;
|
||||
let mouseOverNodeId = null;
|
||||
@@ -276,11 +277,14 @@ export class AppStore extends Store {
|
||||
return version;
|
||||
}
|
||||
|
||||
getVersionUpdate() {
|
||||
return versionUpdate;
|
||||
}
|
||||
|
||||
getPlugins() {
|
||||
return plugins;
|
||||
}
|
||||
|
||||
|
||||
isForceRelayout() {
|
||||
return forceRelayout;
|
||||
}
|
||||
@@ -686,6 +690,7 @@ export class AppStore extends Store {
|
||||
hostname = payload.hostname;
|
||||
version = payload.version;
|
||||
plugins = payload.plugins;
|
||||
versionUpdate = payload.newVersion;
|
||||
this.__emitChange();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -188,9 +188,6 @@ h2 {
|
||||
a {
|
||||
color: @text-secondary-color;
|
||||
.btn-opacity;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
font-size: 90%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -203,6 +200,11 @@ h2 {
|
||||
margin: 0 0.25em;
|
||||
}
|
||||
|
||||
&-versionupdate {
|
||||
margin-right: 0.5em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
margin-left: 0.5em;
|
||||
padding: 4px 3px;
|
||||
|
||||
@@ -17,4 +17,13 @@ type Details struct {
|
||||
Version string `json:"version"`
|
||||
Hostname string `json:"hostname"`
|
||||
Plugins PluginSpecs `json:"plugins,omitempty"`
|
||||
|
||||
NewVersion *NewVersionInfo `json:"newVersion,omitempty"`
|
||||
}
|
||||
|
||||
// NewVersionInfo is the struct exposed in /api when there is a new
|
||||
// version of Scope available.
|
||||
type NewVersionInfo struct {
|
||||
Version string `json:"version"`
|
||||
DownloadURL string `json:"downloadUrl"`
|
||||
}
|
||||
|
||||
@@ -184,6 +184,7 @@ func appMain(flags appFlags) {
|
||||
} else if r.Outdated {
|
||||
log.Infof("Scope version %s is available; please update at %s",
|
||||
r.CurrentVersion, r.CurrentDownloadURL)
|
||||
app.NewVersion(r.CurrentVersion, r.CurrentDownloadURL)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user