def import_formula(formula_id, git_password): formula = None try: formula = Formula.objects.get(id=formula_id) formula.set_status(Formula.IMPORTING, 'Cloning and importing formula.') repodir = clone_to_temp(formula, git_password) root_dir = formula.get_repo_dir() if os.path.isdir(root_dir): raise FormulaTaskException( formula, 'Formula root path already exists.') formula_title, formula_description, root_path, components = validate_specfile(formula, repodir) # update the formula title and description formula.title = formula_title formula.description = formula_description formula.root_path = root_path formula.save() # validate components for component in components: validate_component(formula, repodir, component) root_dir = formula.get_repo_dir() # move the cloned formula repository to a location known by salt # so we can start using the states in this formula shutil.move(repodir, root_dir) tmpdir = os.path.dirname(repodir) # remove tmpdir now that we're finished if os.path.isdir(tmpdir): shutil.rmtree(tmpdir) formula.set_status(Formula.COMPLETE, 'Import complete. Formula is now ready to be used.') return True except FormulaTaskException: raise except Exception as e: logger.exception(e) raise FormulaTaskException(formula, 'An unhandled exception occurred.')
def update_formula(formula_id, git_password, version, repodir=None, raise_exception=True): repo = None current_commit = None formula = None origin = None try: formula = Formula.objects.get(pk=formula_id) formula.set_status(Formula.IMPORTING, 'Updating formula.') if repodir is None: repodir = formula.get_repo_dir() repo = formula.repo else: repo = git.Repo(repodir) # Ensure that the proper version is active repo.git.checkout(version) current_commit = repo.head.commit origin = repo.remotes.origin.name # Add the username / password for a private repo if formula.private_git_repo: parsed = urlsplit(formula.uri) uri = urlunsplit(( parsed.scheme, '{0}:{1}@{2}'.format(formula.git_username, git_password, parsed.netloc), parsed.path, parsed.query, parsed.fragment )) # add the password to the config repo.git.remote('set-url', origin, uri) result = repo.remotes.origin.pull() if len(result) == 1 and result[0].commit == current_commit: formula.set_status(Formula.COMPLETE, 'There were no changes to the repository.') return True formula_title, formula_description, root_path, components = validate_specfile(formula, repodir) # Validate all the new components for component in components: validate_component(formula, repodir, component) # Everything was validated, update the database formula.title = formula_title formula.description = formula_description formula.root_path = root_path formula.save() formula.set_status(Formula.COMPLETE, 'Import complete. Formula is now ready to be used.') return True except Exception as e: # Roll back the pull if repo is not None and current_commit is not None: repo.git.reset('--hard', current_commit) if isinstance(e, FormulaTaskException): if raise_exception: raise FormulaTaskException( formula, e.message + ' Your formula was not changed.' ) logger.warning(e) if raise_exception: raise FormulaTaskException( formula, 'An unhandled exception occurred. Your formula was not changed' ) finally: if formula and origin and formula.private_git_repo: # remove the password from the config repo.git.remote('set-url', origin, formula.uri) # Remove the logs which also store the password log_dir = os.path.join(repodir, '.git', 'logs') if os.path.isdir(log_dir): shutil.rmtree(log_dir)