Skip to content

Commit

Permalink
Merge pull request #676 from getredash/feature/version_check
Browse files Browse the repository at this point in the history
Feature: re:dash version check
  • Loading branch information
arikfr committed Nov 30, 2015
2 parents ca8cca0 + 7c4410a commit 740b305
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 4 deletions.
5 changes: 2 additions & 3 deletions rd_ui/app/index.html
Expand Up @@ -125,9 +125,8 @@
<hr/>
<div class="container">
<div class="row">
<div class="col-md-3">
<a href="http://redash.io">re:dash</a> <span ng-bind="version"></span>
</div>
<a href="http://redash.io">re:dash</a> <span ng-bind="version"></span>
<small ng-if="newVersionAvailable" ng-cloak class="ng-cloak"><a href="http://version.redash.io/">(new re:dash version available)</a></small>
<div class="pull-right">
<a href="http://docs.redash.io/">Docs</a>
<a href="http://github.com/getredash/redash">Contribute</a>
Expand Down
2 changes: 2 additions & 0 deletions rd_ui/app/scripts/controllers/controllers.js
Expand Up @@ -152,6 +152,8 @@

var MainCtrl = function ($scope, $location, Dashboard, notifications) {
$scope.version = clientConfig.version;
$scope.newVersionAvailable = clientConfig.newVersionAvailable && currentUser.hasPermission("admin");

if (clientConfig.clientSideMetrics) {
$scope.$on('$locationChangeSuccess', function(event, newLocation, oldLocation) {
// This will be called once per actual page load.
Expand Down
5 changes: 5 additions & 0 deletions rd_ui/app/styles/redash.css
Expand Up @@ -467,3 +467,8 @@ div.table-name {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}

/* Immediately apply ng-cloak, instead of waiting for angular.js to load: */
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
3 changes: 3 additions & 0 deletions redash/__init__.py
Expand Up @@ -38,3 +38,6 @@ def create_redis_connection():
statsd_client = StatsClient(host=settings.STATSD_HOST, port=settings.STATSD_PORT, prefix=settings.STATSD_PREFIX)

import_query_runners(settings.QUERY_RUNNERS)

from redash.version_check import reset_new_version_status
reset_new_version_status()
4 changes: 3 additions & 1 deletion redash/handlers/static.py
Expand Up @@ -4,8 +4,9 @@
from flask import render_template, send_from_directory, current_app
from flask_login import current_user, login_required

from redash import settings, __version__
from redash import settings, __version__, redis_connection
from redash.wsgi import app
from redash.version_check import get_latest_version


@app.route('/admin/<anything>/<whatever>')
Expand Down Expand Up @@ -42,6 +43,7 @@ def index(**kwargs):
'highChartsTurboThreshold': settings.HIGHCHARTS_TURBO_THRESHOLD,
'dateFormat': settings.DATE_FORMAT,
'dateTimeFormat': "{0} HH:mm".format(settings.DATE_FORMAT),
'newVersionAvailable': get_latest_version(),
'version': __version__
}

Expand Down
1 change: 1 addition & 0 deletions redash/settings.py
Expand Up @@ -151,6 +151,7 @@ def all_settings():
# Features:
FEATURE_ALLOW_ALL_TO_EDIT_QUERIES = parse_boolean(os.environ.get("REDASH_FEATURE_ALLOW_ALL_TO_EDIT", "true"))
FEATURE_TABLES_PERMISSIONS = parse_boolean(os.environ.get("REDASH_FEATURE_TABLES_PERMISSIONS", "false"))
VERSION_CHECK = parse_boolean(os.environ.get("REDASH_VERSION_CEHCK", "true"))

# BigQuery
BIGQUERY_HTTP_TIMEOUT = int(os.environ.get("REDASH_BIGQUERY_HTTP_TIMEOUT", "600"))
8 changes: 8 additions & 0 deletions redash/tasks.py
Expand Up @@ -10,6 +10,7 @@
from redash.utils import gen_query_hash
from redash.worker import celery
from redash.query_runner import get_query_runner, InterruptException
from version_check import run_version_check

logger = get_task_logger(__name__)

Expand Down Expand Up @@ -264,9 +265,11 @@ def check_alerts_for_query(self, query_id):

mail.send(message)


def signal_handler(*args):
raise InterruptException


@celery.task(bind=True, base=BaseTask, track_started=True)
def execute_query(self, query, data_source_id, metadata):
signal.signal(signal.SIGINT, signal_handler)
Expand Down Expand Up @@ -321,3 +324,8 @@ def execute_query(self, query, data_source_id, metadata):
@celery.task(base=BaseTask)
def record_event(event):
models.Event.record(event)


@celery.task(base=BaseTask)
def version_check():
run_version_check()
51 changes: 51 additions & 0 deletions redash/version_check.py
@@ -0,0 +1,51 @@
import logging
import requests
import semver

from redash import __version__ as current_version
from redash import redis_connection
from redash.utils import json_dumps

REDIS_KEY = "new_version_available"


def run_version_check():
logging.info("Performing version check.")
logging.info("Current version: %s", current_version)

data = json_dumps({
'current_version': current_version
})
headers = {'content-type': 'application/json'}

try:
response = requests.post('https://version.redash.io/api/report?channel=stable',
data=data, headers=headers, timeout=3.0)
latest_version = response.json()['release']['version']

_compare_and_update(latest_version)
except requests.RequestException:
logging.exception("Failed checking for new version.")
except (ValueError, KeyError):
logging.exception("Failed checking for new version (probably bad/non-JSON response).")


def reset_new_version_status():
latest_version = get_latest_version()
if latest_version:
_compare_and_update(latest_version)


def get_latest_version():
return redis_connection.get(REDIS_KEY)


def _compare_and_update(latest_version):
# TODO: support alpha channel (allow setting which channel to check & parse build number)
is_newer = semver.compare(current_version, latest_version) == -1
logging.info("Latest version: %s (newer: %s)", latest_version, is_newer)

if is_newer:
redis_connection.set(REDIS_KEY, latest_version)
else:
redis_connection.delete(REDIS_KEY)
10 changes: 10 additions & 0 deletions redash/worker.py
@@ -1,5 +1,7 @@
from random import randint
from celery import Celery
from datetime import timedelta
from celery.schedules import crontab
from redash import settings, __version__


Expand All @@ -22,6 +24,14 @@
}
}

if settings.VERSION_CHECK:
celery_schedule['version_check'] = {
'task': 'redash.tasks_version_check',
# We need to schedule the version check to run at a random hour/minute, to spread the requests from all users
# evenly.
'schedule': crontab(minute=randint(0, 59), hour=randint(0, 23))
}

if settings.QUERY_RESULTS_CLEANUP_ENABLED:
celery_schedule['cleanup_query_results'] = {
'task': 'redash.tasks.cleanup_query_results',
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Expand Up @@ -33,3 +33,4 @@ pysaml2==2.4.0
pycrypto==2.6.1
funcy==1.5
raven==5.6.0
semver==2.2.1

0 comments on commit 740b305

Please sign in to comment.