Ejemplo n.º 1
0
    def _run_lintian(self):
        """Runs lintian on either the source or binary changes file.

        Returns the filename of the created lintian output file.
        """

        # Determine whether to use the source or binary build for lintian
        if self._build_log:
            build_changes = self._package + "_" + strip_epoch(self._version) + \
                           "_" + self._builder.get_architecture() + ".changes"
            changes_for_lintian = os.path.join(self._buildresult, build_changes)
        else:
            changes_for_lintian = self._changes_file

        # Check lintian
        assert os.path.isfile(changes_for_lintian), "%s does not exist." % \
                                                    (changes_for_lintian)
        cmd = ["lintian", "-IE", "--pedantic", "-q", "--profile", "ubuntu",
               changes_for_lintian]
        lintian_filename = os.path.join(self._workdir,
                                        self._package + "_" +
                                        strip_epoch(self._version) + ".lintian")
        Logger.command(cmd + [">", lintian_filename])
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        report = process.communicate()[0]

        # write lintian report file
        lintian_file = open(lintian_filename, "w")
        lintian_file.writelines(report)
        lintian_file.close()

        return lintian_filename
Ejemplo n.º 2
0
    def update(self, dist):
        cmd = ["schroot", "--list"]
        Logger.command(cmd)
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        chroots, _ = process.communicate()[0].strip().split()
        if process.returncode != 0:
            return process.returncode

        params = {"dist": dist, "arch": self.architecture}
        for chroot in ("%(dist)s-%(arch)s-sbuild-source",
                       "%(dist)s-sbuild-source",
                       "%(dist)s-%(arch)s-source",
                       "%(dist)s-source"):
            chroot = chroot % params
            if chroot in chroots:
                break
        else:
            return 1

        commands = [["sbuild-update"],
                    ["sbuild-distupgrade"],
                    ["sbuild-clean", "-a", "-c"]]
        for cmd in commands:
            # pylint: disable=W0631
            Logger.command(cmd + [chroot])
            ret = subprocess.call(cmd + [chroot])
            # pylint: enable=W0631
            if ret != 0:
                return self._update_failure(ret, dist)
        return 0
Ejemplo n.º 3
0
        def tester(self):
            null = open('/dev/null', 'r')
            process = subprocess.Popen(['./' + script, '--help'],
                                       close_fds=True, stdin=null,
                                       universal_newlines=True,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
            started = time.time()
            out = []

            fds = [process.stdout.fileno(), process.stderr.fileno()]
            for fd in fds:
                fcntl.fcntl(fd, fcntl.F_SETFL,
                            fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)

            while time.time() - started < TIMEOUT:
                for fd in select.select(fds, [], fds, TIMEOUT)[0]:
                    output = os.read(fd, 1024)
                    if not isinstance(output, str):
                        output = output.decode('utf-8')
                    out.append(output)
                if process.poll() is not None:
                    break

            if process.poll() is None:
                os.kill(process.pid, signal.SIGTERM)
                time.sleep(1)
                if process.poll() is None:
                    os.kill(process.pid, signal.SIGKILL)
            null.close()

            self.assertEqual(process.poll(), 0,
                             "%s failed to return usage within %i seconds.\n"
                             "Output:\n%s"
                             % (script, TIMEOUT, ''.join(out)))
Ejemplo n.º 4
0
def rmadison(url, package, suite=None, arch=None):
    "Call rmadison and parse the result"
    cmd = ['rmadison', '-u', url]
    if suite:
        cmd += ['-s', suite]
    if arch:
        cmd += ['-a', arch]
    cmd.append(package)
    process = subprocess.Popen(cmd,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               close_fds=True)
    output, error_output = process.communicate()
    if process.wait() != 0:
        if error_output:
            Logger.error('rmadison failed with: %s', error_output)
        else:
            Logger.error('rmadison failed')
        sys.exit(1)

    # rmadison uses some shorthand
    if suite:
        suite = suite.replace('-proposed-updates', '-p-u')

    # pylint bug: http://www.logilab.org/ticket/46273
    # pylint: disable=E1103
    for line in output.strip().splitlines():
        # pylint: enable=E1103
        pkg, ver, dist, archs = [x.strip() for x in line.split('|')]
        comp = 'main'
        if '/' in dist:
            dist, comp = dist.split('/')
        archs = set(x.strip() for x in archs.split(','))

        # rmadison returns some results outside the requested set.
        # It'll include backports, and when given an unknown suite,
        # it ignores that argument
        #
        # some versions (2.14.1ubuntu0.1) of rmadison return 'sid' when
        # asked about 'unstable'.  Others return 'unstable'.  Accept either.
        if (suite and dist != suite
                and not (suite == 'sid' and dist == 'unstable')):
            continue

        if 'source' in archs:
            yield {
                'source': pkg,
                'version': ver,
                'suite': dist,
                'component': comp,
            }
        archs.discard('source')
        if archs:
            yield {
                'binary': pkg,
                'version': ver,
                'suite': dist,
                'component': comp,
                'architectures': archs,
            }
Ejemplo n.º 5
0
    def download(self):
        """Downloads the patch from Launchpad."""
        Logger.info("Downloading %s." % (self._patch_file))
        patch_f = open(self._patch_file, "w")
        patch_f.write(self._patch.data.open().read())
        patch_f.close()

        cmd = ["diffstat", "-l", "-p0", self._full_path]
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        changed_files = process.communicate()[0]
        self._changed_files = [f for f in changed_files.split("\n") if f != ""]
Ejemplo n.º 6
0
    def generate_debdiff(self, dsc_file):
        """Generates a debdiff between the given .dsc file and this source
           package."""

        assert os.path.isfile(dsc_file), "%s does not exist." % (dsc_file)
        assert os.path.isfile(self._dsc_file), "%s does not exist." % \
                                               (self._dsc_file)
        cmd = ["debdiff", dsc_file, self._dsc_file]
        if not Logger.verbose:
            cmd.insert(1, "-q")
        Logger.command(cmd + [">", self._debdiff_filename])
        process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        debdiff = process.communicate()[0]

        # write debdiff file
        debdiff_file = open(self._debdiff_filename, "w")
        debdiff_file.writelines(debdiff)
        debdiff_file.close()
Ejemplo n.º 7
0
 def __init__(self, name):
     self.name = name
     cmd = ["dpkg-architecture", "-qDEB_BUILD_ARCH_CPU"]
     process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
     self.architecture = process.communicate()[0].strip()
Ejemplo n.º 8
0
def mail_bug(srcpkg, subscribe, status, bugtitle, bugtext, bug_mail_domain,
             keyid, myemailaddr, mailserver_host, mailserver_port,
             mailserver_user, mailserver_pass):
    '''
    Submit the sync request per email.
    '''

    to = 'new@' + bug_mail_domain

    # generate mailbody
    if srcpkg:
        mailbody = ' affects ubuntu/%s\n' % srcpkg
    else:
        mailbody = ' affects ubuntu\n'
    mailbody += '''\
 status %s
 importance wishlist
 subscribe %s
 done

%s''' % (status, subscribe, bugtext)

    # prepare sign command
    gpg_command = None
    for cmd in ('gnome-gpg', 'gpg2', 'gpg'):
        if os.access('/usr/bin/%s' % cmd, os.X_OK):
            gpg_command = [cmd]
            break

    if not gpg_command:
        Logger.error("Cannot locate gpg, please install the 'gnupg' package!")
        sys.exit(1)

    gpg_command.append('--clearsign')
    if keyid:
        gpg_command.extend(('-u', keyid))

    # sign the mail body
    gpg = subprocess.Popen(gpg_command,
                           stdin=subprocess.PIPE,
                           stdout=subprocess.PIPE)
    signed_report = gpg.communicate(
        mailbody.encode('utf-8'))[0].decode('utf-8')
    if gpg.returncode != 0:
        Logger.error("%s failed.", gpg_command[0])
        sys.exit(1)

    # generate email
    mail = u'''\
From: %s
To: %s
Subject: %s
Content-Type: text/plain; charset=UTF-8

%s''' % (myemailaddr, to, bugtitle, signed_report)

    print('The final report is:\n%s' % mail)
    confirmation_prompt()

    # save mail in temporary file
    backup = tempfile.NamedTemporaryFile(
        mode='w',
        delete=False,
        prefix='requestsync-' +
        re.sub(r'[^a-zA-Z0-9_-]', '', bugtitle.replace(' ', '_')))
    with backup:
        backup.write(mail)

    Logger.normal(
        'The e-mail has been saved in %s and will be deleted '
        'after succesful transmission', backup.name)

    # connect to the server
    while True:
        try:
            Logger.normal('Connecting to %s:%s ...', mailserver_host,
                          mailserver_port)
            s = smtplib.SMTP(mailserver_host, mailserver_port)
            break
        except smtplib.SMTPConnectError as s:
            try:
                # py2 path
                # pylint: disable=unsubscriptable-object
                Logger.error('Could not connect to %s:%s: %s (%i)',
                             mailserver_host, mailserver_port, s[1], s[0])
            except TypeError:
                # pylint: disable=no-member
                Logger.error('Could not connect to %s:%s: %s (%i)',
                             mailserver_host, mailserver_port, s.strerror,
                             s.errno)
            if s.smtp_code == 421:
                confirmation_prompt(
                    message='This is a temporary error, press [Enter] '
                    'to retry. Press [Ctrl-C] to abort now.')
        except socket.error as s:
            try:
                # py2 path
                # pylint: disable=unsubscriptable-object
                Logger.error('Could not connect to %s:%s: %s (%i)',
                             mailserver_host, mailserver_port, s[1], s[0])
            except TypeError:
                # pylint: disable=no-member
                Logger.error('Could not connect to %s:%s: %s (%i)',
                             mailserver_host, mailserver_port, s.strerror,
                             s.errno)
            return

    if mailserver_user and mailserver_pass:
        try:
            s.login(mailserver_user, mailserver_pass)
        except smtplib.SMTPAuthenticationError:
            Logger.error('Error authenticating to the server: '
                         'invalid username and password.')
            s.quit()
            return
        except smtplib.SMTPException:
            Logger.error('Unknown SMTP error.')
            s.quit()
            return

    while True:
        try:
            s.sendmail(myemailaddr, to, mail.encode('utf-8'))
            s.quit()
            os.remove(backup.name)
            Logger.normal('Sync request mailed.')
            break
        except smtplib.SMTPRecipientsRefused as smtperror:
            smtp_code, smtp_message = smtperror.recipients[to]
            Logger.error('Error while sending: %i, %s', smtp_code,
                         smtp_message)
            if smtp_code == 450:
                confirmation_prompt(
                    message='This is a temporary error, press [Enter] '
                    'to retry. Press [Ctrl-C] to abort now.')
            else:
                return
        except smtplib.SMTPResponseException as e:
            Logger.error('Error while sending: %i, %s', e.smtp_code,
                         e.smtp_error)
            return
        except smtplib.SMTPServerDisconnected:
            Logger.error('Server disconnected while sending the mail.')
            return