Skip to content

Commit

Permalink
Merge pull request #44 from gpilab/develop
Browse files Browse the repository at this point in the history
Restore self-updating behavior
  • Loading branch information
borupdaniel authored Feb 6, 2020
2 parents cdee09d + 96f1735 commit ea40766
Showing 1 changed file with 54 additions and 55 deletions.
109 changes: 54 additions & 55 deletions lib/gpi/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,37 +59,13 @@ def __init__(self, in_str, linefeed=True):
else:
raise TypeError("JSONStreamLoads(): input must be of type \'str\'.")

if linefeed:
self._load = self.loadsByLine()
else:
self._load = self.loadsByCharacter()
self._load = self.loadAll()

def objects(self):
def load(self):
return self._load

def loadsByLine(self):
out = []
buf = ''
for l in self._buffer.splitlines():
buf += l.strip().strip('\0')
try:
out.append(json.loads(buf))
buf = ''
except:
pass
return out

def loadsByCharacter(self):
out = []
buf = ''
for l in self._buffer:
buf += l
try:
out.append(json.loads(buf.strip().strip('\0')))
buf = ''
except:
pass
return out
def loadAll(self):
return json.loads(self._buffer)


# use conda to update to the latest package
Expand All @@ -107,8 +83,9 @@ def __init__(self, conda_prefix=ANACONDA_PREFIX, dry_run=False):
super().__init__()
self._dry_run = dry_run
self._conda_prefix = conda_prefix
self._channel = 'gpi'
self._packages = ['gpi', 'gpi-core-nodes', 'gpi-docs']
self._packages = ['gpi', 'gpi_core']
# DDB - No docs for now on c-f, restore later
# self._packages = ['gpi', 'gpi_core', 'gpi-docs']

self._packages_for_installation = []
self._packages_for_update = []
Expand Down Expand Up @@ -152,9 +129,9 @@ def _getStatus(self):
# Check for the latest versions online
for pkg in self._packages:
if self._current_versions[pkg] is None:
self._latest_versions[pkg] = self.updatePkg(pkg, self._channel, dry_run=True, install=True)
self._latest_versions[pkg] = self.updatePkg(pkg, dry_run=True, install=True)
else:
self._latest_versions[pkg] = self.updatePkg(pkg, self._channel, dry_run=True)
self._latest_versions[pkg] = self.updatePkg(pkg, dry_run=True)
pdone += step
self._status_pdone(pdone)

Expand Down Expand Up @@ -184,6 +161,7 @@ def __str__(self):
for pkg in self._packages_for_update:
o = self._current_versions[pkg]
n = self._latest_versions[pkg]
msg += pkg + '<br>'
msg += tab+str(o) + '&nbsp; &#10154; &nbsp;' + str(n) + '<br>'

# installs
Expand All @@ -193,11 +171,12 @@ def __str__(self):
msg += 'The following packages will be installed:<br><br>'
for pkg in self._packages_for_installation:
n = self._latest_versions[pkg]
msg += pkg + '<br>'
msg += tab+str(n) + '<br>'

if self.numberOfUpdates():
msg += '<br><br>GPI will be <b>automatically restarted</b> after updating.' \
+ ' Make sure your networks are saved before proceeding.'
+ ' Please make sure your networks are saved before proceeding.'

if msg == '':
msg = 'GPI is up to date.'
Expand All @@ -208,9 +187,13 @@ def statusMessage(self):
return str(self)

def checkConda(self):
cmd = self._conda_prefix+'/bin/conda --version >/dev/null 2>&1'
cmd_unix = 'conda --version >/dev/null 2>&1'
cmd_win = 'conda --version > NUL'
try:
subprocess.check_output(cmd, shell=True)
if Specs.inWindows():
subprocess.check_output(cmd_win, shell=True)
else:
subprocess.check_output(cmd_unix, shell=True)
except subprocess.CalledProcessError as e:
print('Failed to execute conda, aborting...')
print(e.cmd, e.output)
Expand All @@ -221,14 +204,15 @@ def checkConda(self):
raise

def getInstalledPkgVersion(self, name):
cmd = self._conda_prefix+'/bin/conda list --json'
cmd = 'conda list --json'
try:
output = subprocess.check_output(cmd, shell=True).decode('utf8')
conda = JSONStreamLoads(output).objects()[-1]
conda = JSONStreamLoads(output).load()
for pkg in conda:
m = re.match('('+name+')-([0-9]+\.*[0-9]*\.*[0-9]*)-(.*)', pkg)
pkg_str = json.dumps(pkg)
m = re.search(name+'-([0-9]+\.[0-9]+\.[0-9]+)-[^"]*', pkg_str)
if m:
return pkg
return m[1]
except:
print('Failed to retrieve installed package information on '+name+', skipping...')
print(cmd)
Expand Down Expand Up @@ -269,21 +253,21 @@ def _updateAllPkgs(self):
# Install or update all the packages that have been determined.
for pkg in self._packages_for_installation:
# if there is no package (due to user changes) then install it
self.updatePkg(pkg, self._channel, install=True)
self.updatePkg(pkg, install=True)
pdone += step
self._updateAllPkgs_pdone(pdone)
self.message.emit(message_hdr+pkg)
for pkg in self._packages_for_update:
# if there is a latest version then update
self.updatePkg(pkg, self._channel)
self.updatePkg(pkg)
pdone += step
self._updateAllPkgs_pdone(pdone)
self.message.emit(message_hdr+pkg)

self._updateAllPkgs_pdone(100)
self.message.emit('Package updates complete. Relaunching...')

def updatePkg(self, name, channel, dry_run=False, install=False):
def updatePkg(self, name, dry_run=False, install=False):
# Updates to the latest package and returns the package string.
# -dry_run will just return the latest package string.
# -install will install the package if its not currently installed.
Expand All @@ -292,27 +276,42 @@ def updatePkg(self, name, channel, dry_run=False, install=False):
if install: conda_sub = 'install'
dry_cmd = ''
if dry_run: dry_cmd = '--dry-run --no-deps'
cmd = self._conda_prefix+'/bin/conda '+conda_sub+' -c '+channel+' '+name+' -y --json '+dry_cmd
cmd = 'conda '+conda_sub+' '+name+' -y --json '+dry_cmd

try:
output = subprocess.check_output(cmd, shell=True).decode('utf8')
conda = JSONStreamLoads(output).objects()
conda = conda[-1]

if conda['success']:
if 'message' in conda: # if we're up to date
return
for pkg in conda['actions']['LINK']:
if pkg.startswith(name):
return pkg.split()[0]
if dry_run:
conda = JSONStreamLoads(output).load()

if conda['success']:
if 'message' in conda: # if we're up to date
return
for pkg in conda['actions']['LINK']:
pkg_str = pkg['dist_name']
if pkg_str.startswith(name):
m = re.search('-([0-9]+\.[0-9]+\.[0-9]+)-', pkg_str)
return m[1]
else:
raise RuntimeError('conda returned a failure status.')
else:
raise RuntimeError('conda returned a failure status.')
m = re.search('\"success\": true', output)
if m[0] is not None:
print("Successfully updated ",name)
else:
print("Update unsuccessful, even though a newer package was found.")
print("This is likely due to a dependency problem. Please create an")
print("issue at https://github.com/conda-forge/gpi-feedstock ")
except subprocess.CalledProcessError as e:
print('Failed to update to new package, aborting...')
print('Failed to update to new package. Please try again.')
print('If the problem persists, create an issue at')
print('https://github.com/conda-forge/gpi-feedstock')
print(e.cmd, e.output)
raise
except:
print('Failed to retrieve package update information, aborting...')
print('Failed to retrieve package update information.')
print('This may be due to a network or package manager issue.')
print('If the problem persists, create an issue at')
print('https://github.com/conda-forge/gpi-feedstock')
print(cmd)
raise

Expand Down

0 comments on commit ea40766

Please sign in to comment.