diff --git a/docs/configuration/optional-settings.md b/docs/configuration/optional-settings.md index 82412cdf7..e500bfcad 100644 --- a/docs/configuration/optional-settings.md +++ b/docs/configuration/optional-settings.md @@ -255,6 +255,23 @@ Enable this option to run the webhook backend. See the docs section on the webho --- +## CHECK_UPDATES + +Default: False + +Enable this option to check automatically for updates. + +------ + +## CHECK_UPDATES_URL + +Default: https://github.com/digitalocean/netbox.git + +In case if you're using a fork or a self hosted version you can change the version check url. +Because we use git to check version updates based on tags. + +--- + ## Date and Time Formatting You may define custom formatting for date and times. For detailed instructions on writing format strings, please see [the Django documentation](https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date). diff --git a/netbox/netbox/configuration.example.py b/netbox/netbox/configuration.example.py index d7a9cf2ed..851ae59ae 100644 --- a/netbox/netbox/configuration.example.py +++ b/netbox/netbox/configuration.example.py @@ -158,3 +158,6 @@ TIME_FORMAT = 'g:i a' SHORT_TIME_FORMAT = 'H:i:s' DATETIME_FORMAT = 'N j, Y g:i a' SHORT_DATETIME_FORMAT = 'Y-m-d H:i' + +# Automatically check for updates if enabled. This feature requires a internet connection. +CHECK_UPDATES = False diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index e50e9bd72..6e8ecda1c 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -337,6 +337,10 @@ INTERNAL_IPS = ( '::1', ) +# Automatic update check +CHECK_UPDATES = getattr(configuration, 'CHECK_UPDATES', False) +CHECK_UPDATES_URL = getattr(configuration, 'CHECK_UPDATES_URL', 'https://github.com/digitalocean/netbox.git') +HAS_UPDATES = {'latest_version': '1.0', 'last_updated': None} try: HOSTNAME = socket.gethostname() diff --git a/netbox/templates/_base.html b/netbox/templates/_base.html index f935f078e..d041880f4 100644 --- a/netbox/templates/_base.html +++ b/netbox/templates/_base.html @@ -47,7 +47,7 @@
{{ settings.HOSTNAME }} (v{{ settings.VERSION }})
+{{ settings.HOSTNAME }} (v{{ settings.VERSION }}) {% check_updates %}
{% now 'Y-m-d H:i:s T' %}
diff --git a/netbox/templates/utilities/templatetags/checkUpdates.html b/netbox/templates/utilities/templatetags/checkUpdates.html new file mode 100644 index 000000000..459ec6fb3 --- /dev/null +++ b/netbox/templates/utilities/templatetags/checkUpdates.html @@ -0,0 +1,3 @@ +{% if latest_version %} +New version: {{ latest_version }} +{% endif %} \ No newline at end of file diff --git a/netbox/utilities/templatetags/helpers.py b/netbox/utilities/templatetags/helpers.py index 11fa789ec..0565b73fc 100644 --- a/netbox/utilities/templatetags/helpers.py +++ b/netbox/utilities/templatetags/helpers.py @@ -8,7 +8,7 @@ from markdown import markdown from utilities.forms import unpack_grouped_choices from utilities.utils import foreground_color - +from utilities.version_check import check_newer_version register = template.Library() @@ -208,3 +208,11 @@ def tag(tag, url_name=None): 'tag': tag, 'url_name': url_name, } + + +@register.inclusion_tag('utilities/templatetags/checkUpdates.html') +def check_updates(): + """ + Display if there is a update + """ + return check_newer_version() diff --git a/netbox/utilities/version_check.py b/netbox/utilities/version_check.py new file mode 100644 index 000000000..0a3f8399f --- /dev/null +++ b/netbox/utilities/version_check.py @@ -0,0 +1,54 @@ +import subprocess +import re + +from distutils.version import LooseVersion +from django.conf import settings +from datetime import datetime, timedelta + + +def check_newer_version(): + def _git_get_latest_version(): + version = '1.0' + + try: + ps = subprocess.Popen(('git', 'ls-remote', '--tags', settings.CHECK_UPDATES_URL), stdout=subprocess.PIPE) + output = subprocess.check_output(('tail', '-1'), stdin=ps.stdout) + ps.wait() + except FileNotFoundError: + # Command not found, so git not installed + settings.CHECK_UPDATES = False + return LooseVersion(version) + + output = re.search('refs/tags/v(.*)', output.decode()) + if output is not None: + version = output[1] + + return LooseVersion(version) + + # If check_updates enabled? + if not settings.CHECK_UPDATES: + return {} + + if type(settings.HAS_UPDATES.get('latest_version')) is str: + latest_version = LooseVersion(settings.HAS_UPDATES.get('latest_version')) + else: + latest_version = settings.HAS_UPDATES.get('latest_version') + + # If dev, remove it + cur_version = LooseVersion(settings.VERSION.replace('-dev', '')) + + last_updated = settings.HAS_UPDATES.get('last_updated') + + # Check every 24 hours for updates + if last_updated is None or ((datetime.utcnow() - last_updated) > timedelta(1)): + latest_version = _git_get_latest_version() + settings.HAS_UPDATES = {'latest_version': latest_version, 'last_updated': datetime.utcnow()} + + # Check if this version is older then the newer version + if cur_version >= latest_version: + return {} + + return { + 'url': settings.CHECK_UPDATES_URL.replace('.git', ''), + 'latest_version': latest_version.__str__(), + }