def addRelease(self, resourceName, releaseName, outputIndent=""):

    # If this is the first release for a requested organism resource, initialize its settings
    if resourceName not in self.userSettings['resources']:
      self.userSettings['resources'][resourceName]               = {}
      self.userSettings['resources'][resourceName]['current']    = ''
      self.userSettings['resources'][resourceName]['isTracking'] = False
      self.userSettings['resources'][resourceName]['releases']   = []

    # Make sure we don't already have this release
    if releaseName in self.userSettings['resources'][resourceName]['releases']:
      self.error.resourceAlreadyAdded(resourceName)
      return False

    # Move into resource's directory
    os.chdir(self.resourcesPath + resourceName)

    # Get URL for release's tarball
    tarballUrl = self.getUrlForRelease(resourceName, releaseName)
    if tarballUrl == '':
      self.error.noReleaseUrlFound(resourceName, releaseName)
      return False

    # Download release tarball
    print(outputIndent + 'Downloading files...  0%', end = '', file = sys.stdout)
    sys.stdout.flush()
    try: filename, headers = urllib.urlretrieve(tarballUrl, reporthook = downloadProgress) 
    except __HOLE__:
      self.error.urlRetrieveFailed(tarballUrl)
      return False
    print('', file=sys.stdout)
  
    # Extract files from tarball
    # N.B. - tarball should be set up so that all of its contents are 
    #        in a parent directory whose name matches its 'releaseName'
    print(outputIndent + 'Unpacking files...', end = '', file = sys.stdout)
    sys.stdout.flush()
    try:
      tar = tarfile.open(filename)
      tar.extractall(self.resourcesPath + resourceName)
      tar.close()
    except tarfile.TarError:
      self.error.extractTarballFailed(filename)
      return False
    print('done.', file = sys.stdout)

    # Delete tarball
    os.remove(filename)

    # Add release to our settings for this resource & return success
    self.userSettings["resources"][resourceName]["releases"].append(releaseName)
    return True

  # Returns a dictionary of all tracked genomes with new 'current' releases
  # { resourceName : newReleaseName }
dataset/ETHPy150Open gkno/gkno_launcher/src/gkno/adminUtils.py/adminUtils.addRelease