def fetch_version_iter(self, version): """Fetch specified version of the app, with iterator control flow.""" if self.sudo_proxy is not None: for status in self.sudo_proxy.fetch_version_iter(version): yield status return if self.version_finder is None: raise NoVersionFinderError # Guard against malicious input (might be called with root privs) vsdir = self._get_versions_dir() target = join_app_version(self.name, version, self.platform) target = os.path.join(vsdir, target) assert os.path.dirname(target) == vsdir # Get the new version using the VersionFinder loc = self.version_finder.has_version(self, version) if not loc: for status in self.version_finder.fetch_version_iter(self, version): if status["status"] != "ready": yield status else: loc = status["path"] # Adjust permissions to match the current version vdir = join_app_version(self.name, self.version, self.platform) copy_ownership_info(os.path.join(vsdir, vdir), loc) yield {"status": "ready", "path": loc}
def _workdir(self,app,nm,create=True): """Get full path of named working directory, inside the given app.""" updir = app._get_update_dir() workdir = os.path.join(updir,nm) if create: for target in (updir,workdir): try: os.mkdir(target) except OSError, e: if e.errno not in (errno.EEXIST,183): raise else: copy_ownership_info(app.appdir,target)
def install_version(self, version): """Install the specified version of the app. This fetches the specified version if necessary, then makes it available as a version directory inside the app directory. It does not modify any other installed versions. """ if self.sudo_proxy is not None: return self.sudo_proxy.install_version(version) # Extract update then rename into position in main app directory vsdir = self._get_versions_dir() target = join_app_version(self.name, version, self.platform) target = os.path.join(vsdir, target) # Guard against malicious input (might be called with root privs) assert os.path.dirname(target) == vsdir if not os.path.exists(target): self.fetch_version(version) source = self.version_finder.has_version(self, version) # TODO: remove compatability hooks for ESKY_APPDATA_DIR="". # This is our chance to migrate to the new appdata dir layout, # by installing into it. if vsdir == self.appdir and ESKY_APPDATA_DIR: vsdir = os.path.join(self.appdir, ESKY_APPDATA_DIR) try: os.mkdir(vsdir) except EnvironmentError as e: if e.errno not in (errno.EEXIST,): raise else: copy_ownership_info(self.appdir, vsdir) target = os.path.join(vsdir, os.path.basename(target)) self.lock() try: if not os.path.exists(target): really_rename(source, target) trn = esky.fstransact.FSTransaction(self.appdir) try: self._unpack_bootstrap_env(target, trn) except Exception: trn.abort() raise else: trn.commit() finally: self.unlock()
def _workdir(self,app,nm,create=True): """Get full path of named working directory, inside the given app.""" updir = app._get_update_dir() workdir = os.path.join(updir,nm) if create: # the failure of this may raise an error which notifies us to try root access if os.path.exists(workdir) and len(os.listdir(workdir)) == 0: try: os.rmdir(workdir) except OSError: raise for target in (updir,workdir): try: os.mkdir(target) except OSError, e: if e.errno not in (errno.EEXIST,183): raise else: copy_ownership_info(app.appdir,target)
def fetch_version(self, version, callback=None): """Fetch the specified updated version of the app.""" if self.sudo_proxy is not None: for status in self.sudo_proxy.fetch_version_iter(version): if callback is not None: callback(status) return self.version_finder.has_version(self, version) if self.version_finder is None: raise NoVersionFinderError # Guard against malicious input (might be called with root privs) vsdir = self._get_versions_dir() target = join_app_version(self.name, version, self.platform) target = os.path.join(vsdir, target) assert os.path.dirname(target) == vsdir # Get the new version using the VersionFinder loc = self.version_finder.has_version(self, version) if not loc: loc = self.version_finder.fetch_version(self, version, callback) # Adjust permissions to match the current version vdir = join_app_version(self.name, self.version, self.platform) copy_ownership_info(os.path.join(vsdir, vdir), loc) return loc