Skip to content

Instantly share code, notes, and snippets.

@soundstorm
Last active July 12, 2017 10:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save soundstorm/1babf3e5adf04105304e322ff819812e to your computer and use it in GitHub Desktop.
Save soundstorm/1babf3e5adf04105304e322ff819812e to your computer and use it in GitHub Desktop.
Rocket.Chat Autoupdater written in Python
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Make sure you have set retry=0 in ProxyPass when on apache
rootdir="/opt/"
#folder in rootdir where Rocket.Chat is installed in
rocketdir="Rocket.Chat"
#MongoDB backup, comment if you don't want to backup your db
mongobackup="mongodump --db rocketchat --archive=/backup/mongodb/Rocket.Chat.db.bak --gzip"
#mongobackup="docker exec rocketchatdocker_mongo mongodump --archive=/dump/rocket.back --gzip"
#release candidates yes/no
prereleases=False
#rocket settings
push=True
#incoming hook url (with token)
rocket_url="https://demo.rocket.chat/hooks/xxx/xxx"
rocket_channel="#rocketchat"
rocket_username=u"Rocket.Chat Updater"
#process start/stop cmds
cmd_stop="systemctl stop rocketchat"
cmd_start="systemctl start rocketchat"
#announcement notification before installing in minutes
wait_pre_install=10
#announcement after restart of Rocket.Chat in seconds
wait_post_install=60
import shutil, sys, json, time, tarfile, os
if sys.version_info[0] == 2:
pyt=2
import urllib, urllib2
else:
pyt=3
import urllib.request, urllib.parse
cur_version = "0.0.0"
try:
f = open(rootdir+".rocketcurversion","r")
cur_version = f.read()
f.close()
except:
print("No current version information cached, updating anyway")
def geturl(url):
if pyt==2:
return urllib2.urlopen(url)
else:
return urllib.request.urlopen(url)
def posturl(url, params):
if pyt==2:
return urllib2.urlopen(url, urllib.urlencode(params, "utf-8"))
else:
return urllib.request.urlopen(urllib.request.Request(url, urllib.parse.urlencode(params, "utf-8")))
def download(url, filename):
if pyt==2:
urllib.urlretrieve(url, filename)
else:
urllib.request.urlretrieve(url, filename)
releases = json.load(geturl('https://api.github.com/repos/RocketChat/Rocket.Chat/releases'))
for release in releases:
if release["prerelease"] > prereleases:
print("Skipping prerelease %s." % release["tag_name"])
continue
#not very robust way, but should work
#if cur_version starts with new version it's likely a rc to main version skip
if release["tag_name"] == cur_version or (release["tag_name"] < cur_version and not cur_version.startswith(release["tag_name"])):
print("Installed version is already the newest.")
break
else:
print("Trying to install version %s." % release["tag_name"])
tarname = rootdir+"rocket.chat."+release["tag_name"]+".tar.gz"
print("Downloading tarball")
try:
download("https://rocket.chat/releases/%s/download" % (release["tag_name"],), tarname)
print("Extracting tar")
tar = tarfile.open(tarname)
release_name = tar.getnames()[0]
tar.extractall(path=rootdir+"tmp")
tar.close()
except:
print("Release is not yet ready")
break
time.sleep(5)
if push:
post = {
"text": u"Rocket.Chat will be updated to %s in %s minutes." % (release["tag_name"], wait_pre_install),
"channel": rocket_channel,
"username": rocket_username,
"icon_emoji": ":warning:"
}
try:
posturl(rocket_url, post)
time.sleep(60 * wait_pre_install)
post = {
"text": u"Rocket.Chat will be updated to %s now." % (release["tag_name"]),
"channel": rocket_channel,
"username": rocket_username,
"icon_emoji": ":no_entry:"
}
posturl(rocket_url, post)
time.sleep(2)
except:
print("Rocket.Chat not online, continuing")
pass
#Stop service
os.system(cmd_stop)
#Remove old backup
try:
shutil.rmtree(rootdir+rocketdir+".bak")
except:
print("No existing backup, can't remove")
print("Moving current installation to %s.bak for Backup." % (rootdir+rocketdir,))
try:
shutil.move(rootdir+rocketdir, rootdir+rocketdir+".bak")
except:
print("No existing version, can't backup.")
try:
print("Backing up database [%s]." % mongobackup)
os.system(mongobackup)
except NameError:
print("MongoDB backup disabled.")
except:
print("Unknown error while executing MongoDB backup routine.")
try:
print("Installing new release into %s." % (rootdir+rocketdir,))
shutil.move(rootdir+"tmp/"+release_name, rootdir+rocketdir)
os.system("cd %s/programs/server && npm install" % (rootdir+rocketdir,))
try:
os.system(cmd_start)
new_version=release["tag_name"]
try:
f = open(rootdir+".rocketcurversion","w")
f.write(new_version)
f.close()
if push:
try:
time.sleep(wait_post_install)
post = {
"text": u"Rocket.Chat was updated to %s.\n%s" % (release["tag_name"], release["body"]),
"channel": rocket_channel,
"username": rocket_username,
"icon_emoji": ":white_check_mark:"
}
posturl(rocket_url, post)
except:
print("Posting to channel failed, maybe not yet online again.")
pass
except:
print("There was an error writing the new version information.")
pass
except:
print("There was an error while restarting Rocket.Chat.")
except IOError:
print("Move failed, reverting to backup")
shutil.move(rootdir+rocketdir+".bak", rootdir+rocketdir)
os.system(cmd_start)
if push:
try:
time.sleep(wait_post_install)
post = {
"text": u"Automatic Rocket.Chat update failed. Can't move directory.",
"channel": rocket_channel,
"username": rocket_username,
"icon_emoji": ":negative_squared_cross_mark:"
}
posturl(rocket_url, post)
except:
print("Error while posting error message.")
pass
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment