예제 #1
0
def install_package_version(request, namespace, number):
    oauth = request.session.get('oauth_response', None)
    if not oauth:
        raise HttpResponse('Unauthorized', status=401)

    version = get_object_or_404(PackageVersion, package__namespace = namespace, number = number)

    # Log the install
    install = PackageInstallation(
        package = version.package, 
        version = version, 
        action = 'install', 
        username = oauth['username'], 
        org_id = oauth['org_id'],
        org_type = oauth['org_type'],
        status = 'Starting',
    )
    install.save()

    request.session['mpinstaller_current_install'] = install.id

    endpoint = build_endpoint_url(oauth)

    # If we have a version number, install via a custom built metadata package using InstalledPackage
    if version.number:
        # Build a zip for the install package
        package_zip = PackageZipBuilder(namespace, number).install_package() 
    else:
        try:
            zip_resp = requests.get(version.zip_url)
            zipfp = TemporaryFile()
            zipfp.write(zip_resp.content)
            zipfile = ZipFile(zipfp, 'r')
            zipfile.close()
            zipfp.seek(0)
            package_zip = base64.b64encode(zipfp.read())
            # FIXME: Implement handling of the subdir field   
        except:
            raise ValueError('Failed to fetch zip from %s' % version.zip_url)

    # Construct the SOAP envelope message
    message = SOAP_DEPLOY % {'package_zip': package_zip}
    message = message.encode('utf-8')
    
    headers = {
        'Content-Type': "text/xml; charset=UTF-8",
        'Content-Length': len(message),
        'SOAPAction': 'deploy',
    }

    response = call_mdapi(request, url=endpoint, headers=headers, data=message)

    id = parseString(response.content).getElementsByTagName('id')[0].firstChild.nodeValue

    # Delete the cached org package versions
    if request.session.get('mpinstaller_org_packages', None) is not None:
        del request.session['mpinstaller_org_packages']

    return HttpResponse(json.dumps({'process_id': id}), content_type='application/json')
예제 #2
0
def uninstall_package(request, namespace):
    package = get_object_or_404(Package, namespace = namespace)

    oauth = request.session.get('oauth_response', None)
    if not oauth:
        sf = SalesforceOAuth2(settings.MPINSTALLER_CLIENT_ID, settings.MPINSTALLER_CLIENT_SECRET, settings.MPINSTALLER_CALLBACK_URL)
        request.session['mpinstaller_package'] = namespace
        request.session['mpinstaller_version'] = 'uninstall'
        return HttpResponseRedirect(sf.authorize_url())

    # Log the install
    install = PackageInstallation(
        package = package, 
        action = 'uninstall', 
        username = oauth['username'], 
        org_id = oauth['org_id'],
        org_type = oauth['org_type'],
        status = 'Starting',
    )
    install.save()

    request.session['mpinstaller_current_install'] = install.id

    endpoint = build_endpoint_url(oauth)

    # Build a zip for the install package
    package_zip = PackageZipBuilder(namespace).uninstall_package() 

    # Construct the SOAP envelope message
    message = SOAP_DEPLOY % {'package_zip': package_zip}
    message = message.encode('utf-8')
    
    headers = {
        'Content-Type': "text/xml; charset=UTF-8",
        'Content-Length': len(message),
        'SOAPAction': 'deploy',
    }

    response = call_mdapi(request, url=endpoint, headers=headers, data=message)

    id = parseString(response.content).getElementsByTagName('id')[0].firstChild.nodeValue

    # Delete the cached org package versions
    if request.session.get('mpinstaller_org_packages', None) is not None:
        del request.session['mpinstaller_org_packages']

    return HttpResponse(json.dumps({'process_id': id}), content_type='application/json')
예제 #3
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)
예제 #4
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
예제 #5
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)