예제 #1
0
def start_package_installation(request, namespace, version_id):
    """ Kicks off a package installation and redirects to the installation's page """
    version = get_object_or_404(PackageVersion,
                                package__namespace=namespace,
                                id=version_id)
    oauth = request.session.get('oauth', None)

    git_ref = request.GET.get('git_ref', None)
    fork = request.GET.get('fork', None)

    # Redirect back to the package overview page if not connected to an org
    if not oauth or not oauth.get('access_token'):
        redirect = version.get_installer_url(request)
        return HttpResponseRedirect(redirect)

    # Ensure installation is available in connected org, logout and redirect if not
    reason = check_installation_available(request, version)
    if reason:
        return HttpResponseRedirect(
            '/mpinstaller/%s/version/%s/installation-unavailable/%s' %
            (version.package.namespace, version.id, reason))

    # This view should only be used for executing a map already reviewed by the user.
    # If there is no installed list or metadata list in session, that didn't happen for some reason
    installed = request.session.get('org_packages', None)
    if installed is None:
        return HttpResponseRedirect(version.get_installer_url(request))
    metadata = request.session.get('metadata', None)
    if metadata is None:
        return HttpResponseRedirect(version.get_installer_url(request))

    install_map = version_install_map(version, installed, metadata, git_ref,
                                      fork)

    installation_obj = PackageInstallation(
        package=version.package,
        version=version,
        git_ref=git_ref,
        fork=fork,
        org_id=oauth['org_id'],
        org_type=oauth['org_type'],
        instance_url=oauth['instance_url'],
        status='Pending',
        username=oauth['username'],
        install_map=install_map_to_json(install_map),
    )
    installation_obj.save()

    # Temporarily save the needed session variables so background processes can do the work
    session_obj = PackageInstallationSession(
        installation=installation_obj,
        oauth=json.dumps(oauth),
        org_packages=json.dumps(installed),
        metadata=json.dumps(request.session.get('metadata', {})),
    )
    session_obj.save()

    order = 0

    for step in install_map:
        step_obj = PackageInstallationStep(
            installation=installation_obj,
            package=step['version'].package,
            version=step['version'],
            previous_version=step['installed'],
            action=step['action'],
            status='Pending',
            order=order,
        )
        order += 1
        if step_obj.action == 'skip':
            step_obj.status = 'Succeeded'
        step_obj.save()

    # Clear out the org_packages and metadata cached in session
    if 'org_packages' in request.session:
        del request.session['org_packages']
    if 'metadata' in request.session:
        del request.session['metadata']

    return HttpResponseRedirect('/mpinstaller/installation/%s' %
                                installation_obj.id)
예제 #2
0
    def deploy_commit_to_org(self, commit=None, sync=None):
        if not self.sf_oauth:
            if sync:
                sync.log += 'FAILED: No Saleforce Org credentials available to sync with DE org\n'
                sync.status = 'failed'
                sync.save()
            return 

        # If there is currently an installation running, return None
        if self.last_deployment_installation and self.last_deployment_installation.status in ('Pending','In Progress'):
            if sync:
                sync.log += 'FAILED: Another installation is already in progress for this contribution.  Please try again later\n'
                sync.status = 'failed'
                sync.save()
            return

        version = self.package_version
        oauth = self.decode_sf_oauth()

        if commit:
            git_ref = commit
        else:
            git_ref = self.fork_branch

        fork = self.contributor.user.username

        # Get installed packages in org
        api = ApiRetrieveInstalledPackages(oauth)
        if sync:
            sync.log += '--- Getting list of installed packages in org\n'
            sync.save()
        installed = api()
        if sync:
            sync.log += 'DONE'
            sync.save()
      
        if not installed: 
            installed = {}

        # Store the access token from the api call if it changed 
        if api.oauth != oauth:
            self.sf_oauth = json.dumps(api.oauth)

        # With GitHub installations, we don't run conditions since we dynamically construct the install map
        metadata = {}

        # Build the install map
        install_map = version_install_map(version, installed, metadata, git_ref, fork)

        if sync:
            sync.log += '--- Configuring installation steps\n'
            sync.save()

        # Build the Installation object
        installation_obj = PackageInstallation(
            package = version.package,
            version = version,
            git_ref = git_ref,
            fork = fork,
            org_id = oauth['org_id'],
            org_type = oauth['org_type'],
            instance_url = oauth['instance_url'],
            status = 'Pending',
            username = oauth['username'],
            install_map = install_map_to_json(install_map),
        )
        installation_obj.save()

        # Create a PackageInstallationSession so we can reuse the same install method from mpinstaller
        session_obj = PackageInstallationSession(
            installation = installation_obj,
            oauth = json.dumps(oauth),
            org_packages = json.dumps(installed),
            metadata = json.dumps(metadata)
        )
        session_obj.save()

        order = 0

        # Create the PackageInstallationStep objects
        for step in install_map:
            step_obj = PackageInstallationStep(
                installation = installation_obj,
                package = step['version'].package,
                version = step['version'],
                previous_version = step['installed'],
                action = step['action'],
                status = 'Pending',
                order = order,
            )
            order += 1
            if step_obj.action == 'skip':
                step_obj.status = 'Succeeded'
            else:
                if sync:
                    sync.log += '--- * %s: %s\n' % (step_obj.version, step_obj.action)
                    sync.save()
            step_obj.save()

        if sync:
            sync.log += 'DONE\n\n'
            sync.log += '--- Starting installation #%s\n' % installation_obj.id
            sync.log += '--- * NOTE: This can take anywhere from 5-15 minutes to complete\n'
            sync.log += '--- * <a href="/mpinstaller/installation/%s" target="_blank">View installation status in separate tab</a>\n' % installation_obj.id
            sync.save()

        # Run the installer synchronously since we should already be inside a background process
        install_package_version(installation_obj.id)

        if sync:
            sync.log += 'DONE\n\n'
            sync.save()

        # Record the deployment on the Contribution if successful
        self.last_deployment_installation = installation_obj
        self.last_deployment_date = datetime.now()
        if installation_obj.status != 'Failed':
            if commit:
                self.last_deployed_commit = commit
            else:
                branch = self.get_fork_branch()
                self.last_deployed_commit = branch['object']['sha']

        return installation_obj