Esempio n. 1
0
		def END_CMD(command, ok, output, info, stats) :
			#assert f.opened_task
			#assert f.opened_subtask
			#assert f.opened_cmd
			if ok :
				f.content.append( '<span class="command_ok">[OK]</span>' )
			else:
				f.content.append( '<span class="command_failure">[FAILURE]</span>' )
				f.content.append(
					'<div id="output%d" class="output">'
						'<div class="output_header">OUTPUT:</div>'
						'<div class="plain_text">%s</div>'
					'</div>' % (f.id_output, deansi.deansi(output) )
					)
				if output.count('\n') > 10 :
					f.content.append( '<script type="text/javascript">togglesize(\'output%d\');</script>' % f.id_output )
				f.id_output += 1
			if info :
				f.content.append(
					'<div id="info%d" class="info">'
					'<div class="info_header">INFO:</div>\n'
					'<div class="plain_text">%s</div></div>' % ( f.id_info, deansi.deansi(info) ) )
				if info.count('\n') > 10 :
					f.content.append( '<script type="text/javascript">togglesize(\'info%d\');</script>' % f.id_info )
				f.id_info += 1
			if stats :
				f.content.append(  
					'<div class="stats_header">Statistics:</div>'
					'<div class="stats">' +
					'<br />'.join(['<b>%s:</b> %s'%(item) for item in stats.iteritems() ]) +
					'</div>'
					)
			f.content.append( '</div>' )
			f.opened_cmd = False
Esempio n. 2
0
 def _streaming_gen():
     yield '<style>{}</style>'.format(deansi.styleSheet())
     yield FOLLOW_LOG_JS
     yield '<div class="ansi_terminal">'
     buffer = []
     for log in container.logs(stdout=True,
                               stderr=True,
                               stream=True,
                               follow=True):
         char = str(log)
         buffer.append(char)
         if char == '\n':
             yield deansi.deansi(''.join(buffer))
             buffer = []
     if buffer:
         yield deansi.deansi(''.join(buffer))
     yield '</div>'
Esempio n. 3
0
 def END_CMD(command, ok, output, info, stats):
     #assert f.opened_task
     #assert f.opened_subtask
     #assert f.opened_cmd
     if ok:
         f.content.append('<span class="command_ok">[OK]</span>')
     else:
         f.content.append(
             '<span class="command_failure">[FAILURE]</span>')
         f.content.append('<div id="output%d" class="output">'
                          '<div class="output_header">OUTPUT:</div>'
                          '<div class="plain_text">%s</div>'
                          '</div>' %
                          (f.id_output, deansi.deansi(output)))
         if output.count('\n') > 10:
             f.content.append(
                 '<script type="text/javascript">togglesize(\'output%d\');</script>'
                 % f.id_output)
         f.id_output += 1
     if info:
         f.content.append('<div id="info%d" class="info">'
                          '<div class="info_header">INFO:</div>\n'
                          '<div class="plain_text">%s</div></div>' %
                          (f.id_info, deansi.deansi(info)))
         if info.count('\n') > 10:
             f.content.append(
                 '<script type="text/javascript">togglesize(\'info%d\');</script>'
                 % f.id_info)
         f.id_info += 1
     if stats:
         f.content.append('<div class="stats_header">Statistics:</div>'
                          '<div class="stats">' + '<br />'.join([
                              '<b>%s:</b> %s' % (item)
                              for item in stats.iteritems()
                          ]) + '</div>')
     f.content.append('</div>')
     f.opened_cmd = False
Esempio n. 4
0
 def contentBlock(self, kind, content, id):
     id = kind + id
     return ('<div id="{id}" class="{kind}">\n'
             '<div class="{kind}_header">{KIND}:</div>\n'
             '<div class="plain_text">{content}</div>\n'
             '</div>\n'
             '{expander}'.format(
                 id=id,
                 kind=kind,
                 KIND=kind.upper(),
                 content=deansi.deansi(content),
                 expander="" if content.count("\n") <= 10 else
                 "<script type='text/javascript'>"
                 "togglesize('{0}');</script>\n".format(id),
             ))
Esempio n. 5
0
    def get_docker_image(self):
        docker_image_name = self.context.repository.replace('/', '-')
        output = []
        docker_image = self.docker.images(docker_image_name)
        if not docker_image or self.context.rebuild:
            dockerfile = os.path.join(self.context.clone_path, self.spec.dockerfile)
            build_options = {
                'tag': docker_image_name,
                'rm': True,
                'stream': True,
                'decode': True,
                'nocache': self.context.nocache,
            }
            if not os.path.exists(dockerfile):
                logger.warning(
                    'No Dockerfile: %s found for repo: %s, using simple runner image',
                    dockerfile,
                    self.context.repository
                )
                dockerfile_content = 'FROM messense/badwolf-test-runner:python\n'
                fileobj = io.BytesIO(dockerfile_content.encode('utf-8'))
                build_options['fileobj'] = fileobj
            else:
                build_options['dockerfile'] = self.spec.dockerfile

            build_success = False
            logger.info('Building Docker image %s', docker_image_name)
            self.update_build_status('INPROGRESS', 'Building Docker image')
            res = self.docker.build(self.context.clone_path, **build_options)
            for log in res:
                if 'errorDetail' in log:
                    msg = log['errorDetail']['message']
                elif 'error' in log:
                    # Deprecated
                    # https://github.com/docker/docker/blob/master/pkg/jsonmessage/jsonmessage.go#L104
                    msg = log['error']
                else:
                    msg = log['stream']
                if 'Successfully built' in msg:
                    build_success = True

                output.append(deansi.deansi(msg))
                logger.info('`docker build` : %s', msg.strip())
            if not build_success:
                return None, ''.join(output)

        return docker_image_name, ''.join(output)
Esempio n. 6
0
    def run(self):
        start_time = time.time()
        branch = self.context.source['branch']
        context = {
            'context': self.context,
            'build_log_url': self.build_status.url,
            'branch': branch['name'],
            'scripts': self.spec.scripts,
            'ansi_termcolor_style': deansi.styleSheet(),
        }

        self.update_build_status('INPROGRESS', 'Test in progress')
        docker_image_name, build_output = self.get_docker_image()
        context.update({
            'build_logs': Markup(build_output),
            'elapsed_time': int(time.time() - start_time),
        })
        if not docker_image_name:
            self.update_build_status('FAILED',
                                     'Build or get Docker image failed')
            context['exit_code'] = -1
            self.send_notifications(context)
            return

        exit_code, output = self.run_in_container(docker_image_name)
        logger.debug('Docker run output: %s', output)
        if exit_code == 0:
            # Success
            logger.info('Test succeed for repo: %s', self.context.repository)
            self.update_build_status('SUCCESSFUL', '1 of 1 test succeed')
        else:
            # Failed
            logger.info('Test failed for repo: %s, exit code: %s',
                        self.context.repository, exit_code)
            if exit_code == 137:
                self.update_build_status('FAILED', 'build cancelled')
            else:
                self.update_build_status('FAILED', '1 of 1 test failed')

        context.update({
            'logs': Markup(deansi.deansi(output)),
            'exit_code': exit_code,
            'elapsed_time': int(time.time() - start_time),
        })
        self.send_notifications(context)
        return exit_code == 0
	def contentBlock(self, kind, content, id) :
		id = kind+id
		return (
			'<div id="{id}" class="{kind}">\n'
			'<div class="{kind}_header">{KIND}:</div>\n'
			'<div class="plain_text">{content}</div>\n'
			'</div>\n'
			'{expander}'
			.format(
				id = id,
				kind = kind,
				KIND = kind.upper(),
				content = deansi.deansi(content),
				expander = "" if content.count("\n") <= 10 else
					"<script type='text/javascript'>"
						"togglesize('{}');</script>\n".format(id),
				)
			)
def execute(scriptname):
    import os
    scripts = configScripts()
    parameters = ns(request.form.items())
    params_list = []
    output_file = False
    if 'parameters' in scripts[scriptname]:
        for parm_name,parm_data in scripts[scriptname]['parameters'].items():
            if parm_data.get('type', None) ==  'FILE':
                filename=os.path.join(configdb.upload_folder,session[parm_name])
                parameters[parm_name] = filename
            elif parm_data.get('type', None) == 'FILEDOWN':
                session[parm_name]=next(tmpfile())
                filename=os.path.join(configdb.download_folder,session[parm_name])
                parameters[parm_name] = filename
                output_file = parm_name
            if not parameters.get(parm_name, None) and scripts[scriptname]['parameters'][parm_name].get('default',None):
                parameters[parm_name] = scripts[scriptname]['parameters'][parm_name]['default']
    script = scripts[scriptname].script
    if type(script) is not list:
        script = shlex.split(script)
    commandline = [
        piece.format(**parameters)
        for piece in script
        ]
    commandline = [cmd.replace('SOME_SRC',configdb.prefix) for cmd in commandline]
    return_code=0

    try:
        output=subprocess.check_output(commandline,stderr=subprocess.STDOUT)
    except subprocess.CalledProcessError as e:
        output=e.output
        return_code=e.returncode
    try:
        output_decoded=output.decode('utf-8')
    except UnicodeDecodeError:
        output_decoded=output.decode('latin-1')
    return json.dumps(dict(
        script_name=scriptname,
        output_file=output_file,
        return_code=return_code,
        response=deansi.deansi(output_decoded),
        commandline=commandline,
        ))
Esempio n. 9
0
    def get_docker_image(self):
        docker_image_name = self.context.repository.replace('/', '-')
        output = []
        try:
            docker_image = self.docker.images.get(docker_image_name)
        except ImageNotFound:
            docker_image = None
        if not docker_image or self.context.rebuild:
            build_options = {
                'tag': docker_image_name,
                'rm': True,
                'forcerm': True,
                'stream': True,
                'decode': True,
                'nocache': self.context.nocache
            }
            if self.spec.image:
                from_image_name, from_image_tag = self.spec.image.split(':', 2)
                logger.info('Pulling Docker image %s', self.spec.image)
                self.docker.images.pull(from_image_name, tag=from_image_tag)
                logger.info('Pulled Docker image %s', self.spec.image)
                dockerfile_content = 'FROM {}\n'.format(self.spec.image)
                fileobj = io.BytesIO(dockerfile_content.encode('utf-8'))
                build_options['fileobj'] = fileobj
            else:
                dockerfile = os.path.join(self.context.clone_path,
                                          self.spec.dockerfile)
                if os.path.exists(dockerfile):
                    build_options['dockerfile'] = self.spec.dockerfile
                else:
                    logger.warning(
                        'No Dockerfile: %s found for repo: %s, using simple runner image',
                        dockerfile, self.context.repository)
                    dockerfile_content = 'FROM messense/badwolf-test-runner:python\n'
                    fileobj = io.BytesIO(dockerfile_content.encode('utf-8'))
                    build_options['fileobj'] = fileobj

            build_success = False
            logger.info('Building Docker image %s', docker_image_name)
            self.update_build_status('INPROGRESS', 'Building Docker image')

            # Use low level API instead of high level API to get raw output
            res = self.docker.api.build(self.context.clone_path,
                                        **build_options)
            for log in res:
                if 'errorDetail' in log:
                    msg = log['errorDetail']['message']
                elif 'error' in log:
                    # Deprecated
                    # https://github.com/docker/docker/blob/master/pkg/jsonmessage/jsonmessage.go
                    msg = log['error']
                elif 'status' in log:
                    msg = log['status']
                else:
                    msg = log.get('stream')
                if not msg:
                    continue
                if 'Successfully tagged' in msg:
                    build_success = True

                output.append(deansi.deansi(msg))
                logger.info('`docker build` : %s', msg.strip())
            if not build_success:
                return None, ''.join(output)

        return docker_image_name, ''.join(output)
Esempio n. 10
0
def sendMail(
        sender,
        to,
        subject,
        text=None,
        html=None,
        md=None,
        ansi=None,
        cc=[],
        bcc=[],
        replyto=[],
        attachments = [],
        template=None,
        config=None,
        stylesheets = [],
        dump = None,
        verbose=True
        ):

    import smtplib
    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    from email.mime.text import MIMEText
    from email.encoders import encode_base64
    from email.utils import formataddr, parseaddr
    if not config:
        from config import smtp
    else:
        import imp
        smtp=imp.load_source('config',config).smtp

    def formatAddress(address):
        return formataddr(parseaddr(address))
    def formatAddresses(addresses):
        return ', '.join(formatAddress(a) for a in addresses)

    # Headers
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = formatAddress(sender)
    msg['To'] = formatAddresses(to)
    if cc: msg['CC'] = formatAddresses(cc)
    if bcc: msg['BCC'] = formatAddresses(bcc)
    if replyto: msg['Reply-To'] = formatAddresses(replyto)

    recipients = to + (cc if cc else []) + (bcc if bcc else [])

    # Attachments

    for filename in attachments:
        step("Attaching {}...".format(filename))
        part = MIMEBase('application', "octet-stream")
        part.set_payload(open(filename, "rb").read())
        encode_base64(part)
        import os
        part.add_header(
            'Content-Disposition',
            'attachment; filename="{}"'.format(
                os.path.basename(filename.replace('"', ''))))

        msg.attach(part)

    # Content formatting

    style=''
    for stylesheet in stylesheets or []:
        with open(stylesheet) as stylefile:
            style+=stylefile.read()

    if md:
        step("Formating markdown input...")
        import markdown
        text = md # TODO: Format plain text
        html = htmltemplate.format(
            style = style,
            body = markdown.markdown(md, output_format='html')
            )

    if ansi:
        step("Formating ansi input...")
        import deansi
        text = ansi # TODO: Clean ansi sequences
        html = htmltemplate.format(
            style = deansi.styleSheet()+style,
            body = "<div class='ansi_terminal'>"+deansi.deansi(ansi)+"</div>",
            )

    content = MIMEMultipart('alternative')

    if text:
        content.attach(MIMEText(text,'plain','utf8'))

    if html:
        step("Adapting html to mail clients...")
        import premailer
        html = premailer.transform(html)
        content.attach(MIMEText(html,'html','utf8'))

        import sys
        #sys.stdout.write(html)

    msg.attach(content)

    if dump:
        with open(dump,'w') as dumpfile:
            dumpfile.write(msg.as_string())
        success("Email dumped as {}".format(dump))
        return
    return
    # Sending
    step("Connecting to {host}:{port} as {user}...".format(**smtp))
    server = smtplib.SMTP(smtp['host'], smtp['port'])
    server.starttls()
    server.login(smtp['user'], smtp['password'])
    step("\tSending...")
    server.sendmail(sender, recipients, msg.as_string())
    success("\tMail sent")
    server.quit()
Esempio n. 11
0
def sendMail(sender,
             to,
             subject,
             text=None,
             html=None,
             md=None,
             ansi=None,
             cc=[],
             bcc=[],
             replyto=[],
             attachments=[],
             template=None,
             config=None,
             stylesheets=[],
             dump=None,
             verbose=True):

    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    from email.mime.text import MIMEText
    from email.encoders import encode_base64
    from email.utils import formataddr, parseaddr

    def formatAddress(address):
        return formataddr(parseaddr(address))

    def formatAddresses(addresses):
        return ', '.join(formatAddress(a) for a in addresses)

    # Headers
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = formatAddress(sender)
    msg['To'] = formatAddresses(to)
    if cc: msg['CC'] = formatAddresses(cc)
    if bcc: msg['BCC'] = formatAddresses(bcc)
    if replyto: msg['Reply-To'] = formatAddresses(replyto)

    recipients = to + (cc if cc else []) + (bcc if bcc else [])

    # Attachments

    for filename in attachments:
        step("Attaching {}...".format(filename))
        part = MIMEBase('application', "octet-stream")
        part.set_payload(open(filename, "rb").read())
        encode_base64(part)
        import os
        part.add_header(
            'Content-Disposition', 'attachment; filename="{}"'.format(
                os.path.basename(filename.replace('"', ''))))

        msg.attach(part)

    # Content formatting

    style = ''
    for stylesheet in stylesheets or []:
        with open(stylesheet) as stylefile:
            style += stylefile.read()

    if md:
        step("Formating markdown input...")
        import markdown
        text = md  # TODO: Format plain text
        html = htmltemplate.format(style=style,
                                   body=markdown.markdown(
                                       md, output_format='html'))

    if ansi:
        step("Formating ansi input...")
        import deansi
        text = ansi  # TODO: Clean ansi sequences
        html = htmltemplate.format(
            style=deansi.styleSheet() + style,
            body="<div class='ansi_terminal'>" + deansi.deansi(ansi) +
            "</div>",
        )

    content = MIMEMultipart('alternative')

    if text:
        content.attach(MIMEText(text, 'plain', 'utf8'))

    if html:
        step("Adapting html to mail clients...")
        import premailer
        html = premailer.transform(html)
        content.attach(MIMEText(html, 'html', 'utf8'))

        import sys
        #sys.stdout.write(html)

    msg.attach(content)

    if dump:
        with open(dump, 'w') as dumpfile:
            dumpfile.write(msg.as_string())
        success("Email dumped as {}".format(dump))
        return

    # Sending
    sendOverSmtp(config, sender, recipients, msg)