#! /usr/bin/env python import requests, platform, re, collections, tempfile, os, sys, shutil, math from subprocess import call version_re = "seafile-server-?_?([\d\.]*)" seaf_home = os.environ["SEAF"] or "/opt/seafile" def available(page): (arch, _) = platform.architecture() if arch == "64bit": arch = "x86-64" else: arch = "i386" link = "http(s?):\/\/[^ \"\(\)\<\>]*%s_?%s.tar.gz" % (version_re ,arch) resp = requests.get(page) available = {} for m in re.finditer(link, resp.text): available[m.group(2)] = m.group(0) #{version: link} return collections.OrderedDict(sorted(available.items(), reverse=True)) def version_int(version): parts=version.split('.') rank=len(parts) from math import pow no=0 for p in parts: rank=rank-1 no=no+int(p)*pow(10,rank) return no def list_command(page="https://www.seafile.com/en/download/"): for (version, link) in available(page).items(): print("- %s: %s" % (version, link)) return 0 def current_version_command(): print(current_version()) def installed_versions(): installed = [] for f in os.listdir(seaf_home): m = re.findall(version_re,f) if len(m) > 0: installed.append(m[0]) return installed def current_version(): current = os.path.realpath(os.path.join(seaf_home, "seafile-server-latest")) res = re.findall(version_re,current) if len(res[0]) == 0: return '0' return '.'.join(res) def perform_upgrade_command(version,mysql=False,yes=True): scripts = os.path.join(seaf_home,"seafile-server-%s" % version, "upgrade") current = map(lambda x: int(x), current_version().split(".")) target = map(lambda x: int(x), version.split(".")) if len(current) == 1 and current[0] == 0: #Not installed #print("Running installer.") #if not call(["seafile-server","setup", os.path.join(seaf_home,"seafile-server-%s" % version) ],stdout=sys.stdout, stdin=sys.stdin): # sys.exit(1) crumb = open(seaf_home + "/ahead", 'w') crumb.write(os.path.join(seaf_home,"seafile-server-%s" % version)) crumb.close() sys.exit(126) script_re = "^upgrade_(\d+).(\d+)_(\d+).(\d+)\.sh$" run = [] last = None for s in os.listdir(scripts): m = re.match(script_re, s) if m: comp = map(lambda x: int(x), m.groups()) last = (s, comp) (major, minor, minorsub, rev) = comp if current[0] <= major and minor > current[1]: run.append(s) for script in run: cmd = [] if yes: cmd.append("echo -ne '\n'") cmd.append(script) call(["/bin/sh", "-c", ''.join(cmd)], stdout=sys.stdout, stdin=(None if yes else sys.stdin)) def download(url, version): tmp = tempfile.mkdtemp() filename = "server_%s.tar.gz" % version pks = os.path.join(seaf_home, "pkg") if not os.path.exists(pks): os.mkdir(pks) dest = os.path.join(pks, filename) if os.path.exists(dest): return dest if call(["/bin/sh", "-c", 'curl %s --output %s/%s' % (url, tmp, filename)]) == 0: shutil.move(os.path.join(tmp,filename), dest) call(["/bin/chmod", "-w", dest]) return dest else: print("Download failed") sys.exit(1) return 0 def install_command(url, version): pkg = download(url, version) tmp = tempfile.mkdtemp() if pkg and call(["/bin/sh", "-c", 'cd %s; tar xzvf %s' % (tmp, pkg)]) == 0: for f in os.listdir(tmp): dest = os.path.join(seaf_home, os.path.basename(f)) if len(re.findall(version_re, f)) > 0: if not os.path.exists(dest): shutil.move(os.path.join(tmp,f), dest) else: shutil.rmtree(tmp) print("Found previous installation, resuming setup") current = current_version() target_version = ''.join(re.findall(version_re,dest)) if len(current) == 1: current = current[0] else: current = "0.0.0" print("Upgrading from: %s -> %s" % (current, target_version)) perform_upgrade_command(target_version,mysql=("SEAF_MYSQL" in os.environ and os.environ["SEAF_MYSQL"])) if os.path.exists(tmp) and len(os.listdir(tmp)) != 0: print("Failed to unpack update") os.rmdir(tmp) return 1 os.rmdir(tmp) return 0 #TODO: figure out how to rename main to "" def main_command(version="latest",page="https://www.seafile.com/en/download/"): avail = available(page) install = None if version == "latest": (version,install) = avail.items()[0] else: if version in dict(avail.items()): install = dict(avail.items())[version] if version_int(current_version()) == version_int(version): print("%s(%s) is already installed" % (version,version_int(version))) sys.exit(126) if version in installed_versions(): return perform_upgrade_command(version) if install: print("Installing: %s" % version) sys.exit(install_command(install, version)) else: print("Couldn't determine download for %s" % version) sys.exit(1) if __name__ == '__main__': import scriptine scriptine.run()