Beispiel #1
0
    def post_docker_sync_hook(self, obj, cloudid):
        jn = obj['name']
        # bid = str(obj['build']['number'])
        jsonUtil = JsonUtil()
        c = jsonUtil.parseJsonString(config.CLOUD_CONFIG)
        j = Jenkins(c[cloudid]['jenkins_url'],
                    username=c[cloudid]['jenkins_name'],
                    password=c[cloudid]['jenkins_token'])

        re = postimagesync()
        try:

            if j.job_exists(jn):
                ss = xmltodict.parse(j.get_job_config(jn))
                jsonpickle.set_preferred_backend('json')

                if isinstance(jsonpickle.decode(ss['project']['description']),
                              callback):
                    desobj = jsonpickle.decode(ss['project']['description'])
                    re.image_name = desobj.image_name
                    re.status = self.getstatus(obj['build']['status'])
                    re.sync_cloud_id = desobj.repo_name
                    re.tag = desobj.tag
                    re.time = datetime.now()
                    re.post_callback_url = desobj.callback_url
                    if re.status != 'error' and config.JENKINS_IMAGEOPTJOB_DELETE == 'true':
                        j.delete_job(jn)

        except Exception as e:
            print e.message
            re = None
        raise gen.Return(re)
 def deleteJobs(self):
     j=Jenkins('http://jenkins-ccp.citrix.com','talluri','vmops.com')
     for i in range(757,918):
        print "deleting job %s"%("report_generator_"+str(i)+"_zone-xen_XenServer.xml")
        try:
           j.delete_job("report_generator_"+str(i)+"_zone-xen_XenServer.xml")
        except Exception,e:
            print e
            pass     
 def deleteJobs(self,jobList):
     j=Jenkins('http://jenkins-ccp.citrix.com','bharatk','BharatK')
     for jobdetail in jobList:
         try:
            print "deleteing job %s"%jobdetail[0]
            j.delete_job(jobdetail[0])
         except Exception,e:
              # try:
              #   j.delete_job(jobdetail[0].replace("Sandbox-simulator_simula","Sandbox-simulator_simul").replace("Sandbox-simulator_simul","Sandbox-simulator_simulator.xml"))
              #    print "deleting job %s"%jobdetail[0].replace("Sandbox-simulator_simula","Sandbox-simulator_simul").replace("Sandbox-simulator_simul","Sandbox-simulator_simulator") 
              # except Exception,e:
              print e
         print "deleting job %s"%jobdetail[0]
         self.resourceMgr.removeJob(jobdetail[0])
         print "deleted job %s"%jobdetail[0]
         print "cleaning up related data"
         os.system("rm -rf %s"%jobdetail[1])
         os.system("rm -rf /automation/jenkins/workspace/%s"%jobdetail[0])
class jenKinsJob:
    def __init__(self):
        self.j = Jenkins("http://jenkins-ccp.citrix.com", "bharatk", "BharatK")
        self.resourceMgr = resourceManager()
        self.logger = logging.getLogger("jenkinsJob")

    def deleteJob(self, jobList):
        print "***********", jobList
        for jobentity in jobList:
            try:
                self.logger.info("deleteing job %s" % jobentity["job_name"])
                self.j.delete_job(jobentity["job_name"])
            except Exception, e:
                # try:
                #   j.delete_job(jobentity[0].replace("Sandbox-simulator_simula","Sandbox-simulator_simul").replace("Sandbox-simulator_simul","Sandbox-simulator_simulator.xml"))
                #    print "deleting job %s"%jobentity[0].replace("Sandbox-simulator_simula","Sandbox-simulator_simul").replace("Sandbox-simulator_simul","Sandbox-simulator_simulator")
                # except Exception,e:
                print e
            self.resourceMgr.removeJob(jobentity["job_name"])
            self.logger.info("cleaning up related data")
            os.system("rm -rf %s" % jobentity["related_data_path"])
            os.system("rm -rf /automation/jenkins/workspace/%s" % jobentity["related_data_path"])
Beispiel #5
0
class JenkinsBot(BotPlugin):
    """Basic Err integration with Jenkins CI"""

    min_err_version = '1.2.1'
    # max_err_version = '4.0.3'

    def get_configuration_template(self):
        return CONFIG_TEMPLATE

    def configure(self, configuration):
        if configuration is not None and configuration != {}:
            config = dict(chain(CONFIG_TEMPLATE.items(),
                                configuration.items()))
        else:
            config = CONFIG_TEMPLATE
        super(JenkinsBot, self).configure(config)
        return

    def check_configuration(self, configuration):
        self.log.debug(configuration)
        for c, v in configuration.items():
            if c == 'URL':
                if not validators.url(v):
                    raise ValidationException('JENKINS_URL is not a well formed URL')
            elif c in ['USERNAME', 'PASSWORD', 'RECEIVE_NOTIFICATION']:
                if len(v) == 0 or not isinstance(v, str):
                    raise ValidationException("{} is a required string config setting".format(c))
            elif c in ['CHATROOMS_NOTIFICATION']:
                if not isinstance(v, tuple):
                    raise ValidationException("{} should be of type tuple".format(c))
        return

    def connect_to_jenkins(self):
        """Connect to a Jenkins instance using configuration."""
        self.log.debug('Connecting to Jenkins ({0})'.format(
            self.config['URL']))
        self.jenkins = Jenkins(url=self.config['URL'],
                               username=self.config['USERNAME'],
                               password=self.config['PASSWORD'])
        return

    def broadcast(self, mess):
        """Shortcut to broadcast a message to all elligible chatrooms."""
        chatrooms = (self.config['CHATROOMS_NOTIFICATION']
                     if self.config['CHATROOMS_NOTIFICATION']
                     else self.bot_config.CHATROOM_PRESENCE)

        for room in chatrooms:
            self.send(self.build_identifier(room), mess)
        return

    @webhook(r'/jenkins/notification')
    def handle_notification(self, incoming_request):
        if not self.config['RECEIVE_NOTIFICATION']:
            return 'Notification handling is disabled.'

        self.log.debug(repr(incoming_request))
        self.broadcast(self.format_notification(incoming_request))
        return

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.connect_to_jenkins()
        return self.format_jobs([job for job in self.jenkins.get_jobs(folder_depth=None)
            if args.lower() in job['fullname'].lower()])

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.connect_to_jenkins()

        jobs = [job for job in self.jenkins.get_jobs()
                if 'anime' in job['color']]
        return self.format_running_jobs(jobs)

    @botcmd(split_args_with=None)
    def jenkins_param(self, mess, args):
        """List Parameters for a given job."""
        if len(args) == 0:
            return 'What Job would you like the parameters for?'

        self.connect_to_jenkins()

        job = self.jenkins.get_job_info(args[0])
        if job['actions'][1] != {}:
            job_param = job['actions'][1]['parameterDefinitions']
        elif job['actions'][0] != {}:
            job_param = job['actions'][0]['parameterDefinitions']
        else:
            job_param = []

        return self.format_params(job_param)

    @botcmd(split_args_with=None)
    def jenkins_build(self, mess, args):
        """Build a Jenkins Job with the given parameters
        Example: !jenkins build test_project FOO:bar
        """
        if len(args) == 0:  # No Job name
            return 'What job would you like to build?'

        self.connect_to_jenkins()
        params = self.build_parameters(args[1:])

        # Is it a parameterized job ?
        job = self.jenkins.get_job_info(args[0])
        if job['actions'][0] == {} and job['actions'][1] == {}:
            self.jenkins.build_job(args[0])
        else:
            self.jenkins.build_job(args[0], params)

        running_job = self.search_job(args[0])
        return 'Your job should begin shortly: {0}'.format(
            self.format_jobs(running_job))

    @botcmd(split_args_with=None)
    def build(self, mess, args):
        """Shortcut for jenkins_build"""
        return self.jenkins_build(mess, args)

    @botcmd
    def jenkins_unqueue(self, msg, args):
        """Cancel a queued job.
        Example !jenkins unqueue foo
        """
        self.connect_to_jenkins()

        try:
            queue = self.jenkins.get_queue_info()

            job = next((job for job in queue if job['task']['name'].lower() == args.lower()), None)

            if job:
                self.jenkins.cancel_queue(job['id'])
                return 'Unqueued job {0}'.format(job['task']['name'])
            else:
                return 'Could not find job {0}, but found the following: {1}'.format(
                    args, ', '.join(job['task']['name'] for job in queue))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

    @botcmd(split_args_with=None)
    def jenkins_createjob(self, mess, args):
        """Create a Jenkins Job.
        Example: !jenkins createjob pipeline foo [email protected]:foo/bar.git
        """
        if len(args) < 2:  # No Job type or name
            return 'Oops, I need a type and a name for your new job.'

        if args[0] not in ('pipeline', 'multibranch'):
            return 'I\'m sorry, I can only create `pipeline` and \
                    `multibranch` jobs.'

        self.connect_to_jenkins()

        try:
            if args[0] == 'pipeline':
                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_PIPELINE.format(repository=args[2]))

            elif args[0] == 'multibranch':
                repository = args[2].rsplit('/', maxsplit=2)[-2:]

                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_MULTIBRANCH.format(
                        repo_owner=repository[0].split(':')[-1],
                        repo_name=repository[1].strip('.git')))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)
        return 'Your job has been created: {0}/job/{1}'.format(
            self.config['URL'], args[1])

    @botcmd(split_args_with=None)
    def jenkins_deletejob(self, mess, args):
        """Delete a Jenkins Job.
        Example: !jenkins deletejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablejob(self, mess, args):
        """Enable a Jenkins Job.
        Example: !jenkins enablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablejob(self, mess, args):
        """Disable a Jenkins Job.
        Example: !jenkins disablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been disabled.'

    @botcmd(split_args_with=None)
    def jenkins_createnode(self, mess, args):
        """Create a Jenkins Node with a JNLP Launcher with optionnal labels.
        Example: !jenkins createnode runner-foo-laptop /home/foo # without labels
        Example: !jenkins createnode runner-bar-laptop /home/bar linux docker # with labels
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need a name and a working dir for your new node.'

        self.connect_to_jenkins()

        try:
            self.jenkins.create_node(
                name=args[0],
                remoteFS=args[1],
                labels=' '.join(args[2:]),
                exclusive=True,
                launcher=LAUNCHER_JNLP)
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been created: {0}/computer/{1}'.format(
            self.config['URL'], args[0])

    @botcmd(split_args_with=None)
    def jenkins_deletenode(self, mess, args):
        """Delete a Jenkins Node.
        Example: !jenkins deletenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablenode(self, mess, args):
        """Enable a Jenkins Node.
        Example: !jenkins enablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablenode(self, mess, args):
        """Disable a Jenkins Node.
        Example: !jenkins disablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been disabled.'

    def search_job(self, search_term):
        self.log.debug('Querying Jenkins for job "{0}"'.format(search_term))
        return [job for job in self.jenkins.get_jobs(folder_depth=None)
                if search_term.lower() == job['fullname'].lower()]

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return 'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join(['%s (%s)\n%s' % (
            job['name'],
            job['lastBuild']['url'],
            job['healthReport'][0]['description'])
                            for job in jobs_info]).strip()

    @staticmethod
    def format_jobs(jobs):
        if len(jobs) == 0:
            return 'No jobs found.'

        max_length = max([len(job['fullname']) for job in jobs])
        return '\n'.join(
            ['%s (%s)' % (job['fullname'].ljust(max_length), job['url'])
             for job in jobs]).strip()

    @staticmethod
    def format_params(job):
        """Format job parameters."""
        if len(job) == 0:
            return 'This job is not parameterized.'
        PARAM_TEMPLATE = Template("""{% for p in params %}Type: {{p.type}}
Description: {{p.description}}
Default Value: {{p.defaultParameterValue.value}}
Parameter Name: {{p.name}}

{% endfor %}""")
        return PARAM_TEMPLATE.render({'params': job})

    @staticmethod
    def format_notification(body):
        body['fullname'] = body.get('fullname', body['name'])
        NOTIFICATION_TEMPLATE = Template("""Build #{{build.number}} \
{{build.status}} for Job {{fullname}} ({{build.full_url}})
{% if build.scm %}Based on {{build.scm.url}}/commit/{{build.scm.commit}} \
({{build.scm.branch}}){% endif %}""")
        return NOTIFICATION_TEMPLATE.render(body)

    @staticmethod
    def build_parameters(params):
        if len(params) > 0:
            return {param.split(':')[0]: param.split(':')[1]
                    for param in params}
        return {'': ''}
    def execOnJenkins(self, env, testSpecifierString, mailto, reRunFailedTests=True, retryCount=1, report=True, execOnOneZone=True,
           postOnPr=False, testMgr=None, avoidZones=None):
        try:
            env['hypervisor'] = ''
            if avoidZones is None:
               avoidZones=[]
            if testMgr is None:
               testMgr = testManager(testSpecifierString, env['virtenvPath'])
            jobModifier = modifyJOb()
            modifiedjob = ''
            j = Jenkins('http://jenkins-ccp.citrix.com', 'bharatk', 'BharatK')
            tests = testMgr.getTests()
            if tests == None:
                raise Exception('found no tests to run')
            while tests is not None:
                os.chdir(env['virtenvPath'])
                self.logger.info('launching jenkins TestExecutor Job')
                cscfg = configGenerator.getSetupConfig(env['config_file'])
                for zone in cscfg.zones:
                    if zone.name in avoidZones:
                       continue
                    for pod in zone.pods:
                        for cluster in pod.clusters:
                            for modifiedjob in jobModifier.addTests(env['build_number'], tests, self.throttle_job_count):
                                file = open('/root/cloud-autodeploy2/newcode/' + modifiedjob, 'r')
                                config = file.read()
                                file.close()
                                bash('rm -f /root/cloud-autodeploy2/newcode/%s' % modifiedjob)
                                if not j.job_exists(modifiedjob):
                                    j.create_job(modifiedjob, config)
                                else:
                                    j.delete_job(modifiedjob)
                                    j.create_job(modifiedjob, config)
                                j.build_job(modifiedjob, {'BASEDIR': env['virtenvPath'],
                                 'MGMT_SVR': env['hostip'],
                                 'buildNumber': env['build_number'],
                                 'zoneName': zone.name,
                                 'hypervisor': cluster.hypervisor.lower(),
                                 'zoneType': zone.networktype,
                                 'configFileName': env['config_file'],
                                 'token': 'bharat'})
                                self.waitForJobComplete(env['virtenvPath'], [zone.name])
                                env['hypervisor'] = '%s,%s' % (env['hypervisor'], cluster.hypervisor.lower())

                            break

                        break

                    if execOnOneZone:
                        break

                tests = testMgr.getTests()

            j.delete_job(modifiedjob)

            reportAnalyserMap=self.getReportAnalysers(cscfg, env, execOnOneZone)  
            if(reRunFailedTests):
               while retryCount > 0:
                     self.logger.info("checking if we need to re run any of the tests")
                     testsToReRun=[]
                     for key in reportAnalyserMap.keys():
                         tests=reportAnalyserMap[key].suitsToRerun
                         if(tests is None):
                            avoidZones.append(key)
                         else:
                            testMgr.addTestsToReRun(tests) 
                     retryCount-=1
                     self.logger.info("zone name:%s The follwoing tests will be re run %s"%(key,tests))
                     if(len(testsToReRun)==0):
                       break
                     else: 
                        self.execOnJenkins(env, testSpecifierString, mailto, reRunFailedTests, retryCount, False, execOnOneZone, postOnPr, testMgr, avoidZones)
               
            if report and postOnPr:
                for key in reportAnalyserMap.keys():
                    self.reportOnPr(reportAnalyserMap[key].generateTextReport2(), env)
            elif report:
                self.reportUsingJenkinsEmailPlugin(cscfg, env)
            return env
        except Exception as e:
            self.logger.exception(e)
Beispiel #7
0
class JenkinsBot(BotPlugin):
    """Basic Err integration with Jenkins CI"""

    min_err_version = '1.2.1'

    # max_err_version = '4.0.3'

    def get_configuration_template(self):
        return CONFIG_TEMPLATE

    def configure(self, configuration):
        if configuration is not None and configuration != {}:
            config = dict(chain(CONFIG_TEMPLATE.items(),
                                configuration.items()))
        else:
            config = CONFIG_TEMPLATE
        super(JenkinsBot, self).configure(config)
        return

    def check_configuration(self, configuration):
        self.log.debug(configuration)
        for c, v in configuration.items():
            if c == 'URL':
                if not validators.url(v):
                    raise ValidationException(
                        'JENKINS_URL is not a well formed URL')
            elif c in ['USERNAME', 'PASSWORD', 'RECEIVE_NOTIFICATION']:
                if len(v) == 0 or not isinstance(v, str):
                    raise ValidationException(
                        "{} is a required string config setting".format(c))
            elif c in ['CHATROOMS_NOTIFICATION']:
                if not isinstance(v, tuple):
                    raise ValidationException(
                        "{} should be of type tuple".format(c))
        return

    def connect_to_jenkins(self):
        """Connect to a Jenkins instance using configuration."""
        self.log.debug('Connecting to Jenkins ({0})'.format(
            self.config['URL']))
        self.jenkins = Jenkins(url=self.config['URL'],
                               username=self.config['USERNAME'],
                               password=self.config['PASSWORD'])
        return

    def broadcast(self, mess):
        """Shortcut to broadcast a message to all elligible chatrooms."""
        chatrooms = (self.config['CHATROOMS_NOTIFICATION']
                     if self.config['CHATROOMS_NOTIFICATION'] else
                     self.bot_config.CHATROOM_PRESENCE)

        for room in chatrooms:
            self.send(self.build_identifier(room), mess)
        return

    @webhook(r'/jenkins/notification')
    def handle_notification(self, incoming_request):
        if not self.config['RECEIVE_NOTIFICATION']:
            return 'Notification handling is disabled.'

        self.log.debug(repr(incoming_request))
        self.broadcast(self.format_notification(incoming_request))
        return

    @botcmd
    def jenkins_list(self, mess, args):
        """List all jobs, optionally filter them using a search term."""
        self.connect_to_jenkins()
        return self.format_jobs([
            job for job in self.jenkins.get_jobs(folder_depth=None)
            if args.lower() in job['fullname'].lower()
        ])

    @botcmd
    def jenkins_running(self, mess, args):
        """List all running jobs."""
        self.connect_to_jenkins()

        jobs = [
            job for job in self.jenkins.get_jobs() if 'anime' in job['color']
        ]
        return self.format_running_jobs(jobs)

    @botcmd(split_args_with=None)
    def jenkins_param(self, mess, args):
        """List Parameters for a given job."""
        if len(args) == 0:
            return 'What Job would you like the parameters for?'

        self.connect_to_jenkins()

        job = self.jenkins.get_job_info(args[0])
        if job['actions'][1] != {}:
            job_param = job['actions'][1]['parameterDefinitions']
        elif job['actions'][0] != {}:
            job_param = job['actions'][0]['parameterDefinitions']
        else:
            job_param = []

        return self.format_params(job_param)

    @botcmd(split_args_with=None)
    def jenkins_build(self, mess, args):
        """Build a Jenkins Job with the given parameters
        Example: !jenkins build test_project FOO:bar
        """
        if len(args) == 0:  # No Job name
            return 'What job would you like to build?'

        self.connect_to_jenkins()
        params = self.build_parameters(args[1:])

        # Is it a parameterized job ?
        job = self.jenkins.get_job_info(args[0])
        if job['actions'][0] == {} and job['actions'][1] == {}:
            self.jenkins.build_job(args[0])
        else:
            self.jenkins.build_job(args[0], params)

        running_job = self.search_job(args[0])
        return 'Your job should begin shortly: {0}'.format(
            self.format_jobs(running_job))

    @botcmd(split_args_with=None)
    def build(self, mess, args):
        """Shortcut for jenkins_build"""
        return self.jenkins_build(mess, args)

    @botcmd
    def jenkins_unqueue(self, msg, args):
        """Cancel a queued job.
        Example !jenkins unqueue foo
        """
        self.connect_to_jenkins()

        try:
            queue = self.jenkins.get_queue_info()

            job = next((job for job in queue
                        if job['task']['name'].lower() == args.lower()), None)

            if job:
                self.jenkins.cancel_queue(job['id'])
                return 'Unqueued job {0}'.format(job['task']['name'])
            else:
                return 'Could not find job {0}, but found the following: {1}'.format(
                    args, ', '.join(job['task']['name'] for job in queue))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

    @botcmd(split_args_with=None)
    def jenkins_createjob(self, mess, args):
        """Create a Jenkins Job.
        Example: !jenkins createjob pipeline foo [email protected]:foo/bar.git
        """
        if len(args) < 2:  # No Job type or name
            return 'Oops, I need a type and a name for your new job.'

        if args[0] not in ('pipeline', 'multibranch'):
            return 'I\'m sorry, I can only create `pipeline` and \
                    `multibranch` jobs.'

        self.connect_to_jenkins()

        try:
            if args[0] == 'pipeline':
                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_PIPELINE.format(repository=args[2]))

            elif args[0] == 'multibranch':
                repository = args[2].rsplit('/', maxsplit=2)[-2:]

                self.jenkins.create_job(
                    args[1],
                    JENKINS_JOB_TEMPLATE_MULTIBRANCH.format(
                        repo_owner=repository[0].split(':')[-1],
                        repo_name=repository[1].strip('.git')))
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)
        return 'Your job has been created: {0}/job/{1}'.format(
            self.config['URL'], args[1])

    @botcmd(split_args_with=None)
    def jenkins_deletejob(self, mess, args):
        """Delete a Jenkins Job.
        Example: !jenkins deletejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablejob(self, mess, args):
        """Enable a Jenkins Job.
        Example: !jenkins enablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablejob(self, mess, args):
        """Disable a Jenkins Job.
        Example: !jenkins disablejob foo
        """
        if len(args) < 1:  # No job name
            return 'Oops, I need the name of the job you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_job(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your job has been disabled.'

    @botcmd(split_args_with=None)
    def jenkins_createnode(self, mess, args):
        """Create a Jenkins Node with a JNLP Launcher with optionnal labels.
        Example: !jenkins createnode runner-foo-laptop /home/foo # without labels
        Example: !jenkins createnode runner-bar-laptop /home/bar linux docker # with labels
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need a name and a working dir for your new node.'

        self.connect_to_jenkins()

        try:
            self.jenkins.create_node(name=args[0],
                                     remoteFS=args[1],
                                     labels=' '.join(args[2:]),
                                     exclusive=True,
                                     launcher=LAUNCHER_JNLP)
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been created: {0}/computer/{1}'.format(
            self.config['URL'], args[0])

    @botcmd(split_args_with=None)
    def jenkins_deletenode(self, mess, args):
        """Delete a Jenkins Node.
        Example: !jenkins deletenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to delete.'

        self.connect_to_jenkins()

        try:
            self.jenkins.delete_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been deleted.'

    @botcmd(split_args_with=None)
    def jenkins_enablenode(self, mess, args):
        """Enable a Jenkins Node.
        Example: !jenkins enablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to enable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.enable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been enabled.'

    @botcmd(split_args_with=None)
    def jenkins_disablenode(self, mess, args):
        """Disable a Jenkins Node.
        Example: !jenkins disablenode runner-foo-laptop
        """
        if len(args) < 1:  # No node name
            return 'Oops, I need the name of the node you want me to disable.'

        self.connect_to_jenkins()

        try:
            self.jenkins.disable_node(args[0])
        except JenkinsException as e:
            return 'Oops, {0}'.format(e)

        return 'Your node has been disabled.'

    def search_job(self, search_term):
        self.log.debug('Querying Jenkins for job "{0}"'.format(search_term))
        return [
            job for job in self.jenkins.get_jobs(folder_depth=None)
            if search_term.lower() == job['fullname'].lower()
        ]

    def format_running_jobs(self, jobs):
        if len(jobs) == 0:
            return 'No running jobs.'

        jobs_info = [self.jenkins.get_job_info(job['name']) for job in jobs]
        return '\n\n'.join([
            '%s (%s)\n%s' % (job['name'], job['lastBuild']['url'],
                             job['healthReport'][0]['description'])
            for job in jobs_info
        ]).strip()

    @staticmethod
    def format_jobs(jobs):
        if len(jobs) == 0:
            return 'No jobs found.'

        max_length = max([len(job['fullname']) for job in jobs])
        return '\n'.join([
            '%s (%s)' % (job['fullname'].ljust(max_length), job['url'])
            for job in jobs
        ]).strip()

    @staticmethod
    def format_params(job):
        """Format job parameters."""
        if len(job) == 0:
            return 'This job is not parameterized.'
        PARAM_TEMPLATE = Template("""{% for p in params %}Type: {{p.type}}
Description: {{p.description}}
Default Value: {{p.defaultParameterValue.value}}
Parameter Name: {{p.name}}

{% endfor %}""")
        return PARAM_TEMPLATE.render({'params': job})

    @staticmethod
    def format_notification(body):
        body['fullname'] = body.get('fullname', body['name'])
        NOTIFICATION_TEMPLATE = Template("""Build #{{build.number}} \
{{build.status}} for Job {{fullname}} ({{build.full_url}})
{% if build.scm %}Based on {{build.scm.url}}/commit/{{build.scm.commit}} \
({{build.scm.branch}}){% endif %}""")
        return NOTIFICATION_TEMPLATE.render(body)

    @staticmethod
    def build_parameters(params):
        if len(params) > 0:
            return {
                param.split(':')[0]: param.split(':')[1]
                for param in params
            }
        return {'': ''}
Beispiel #8
0
class JC:
    def __init__(self):
        self.JCDirectoryLoc = ''
        self.JCBuiltFileLoc = ''
        self.JCServerConfFileLoc = ''
        self.JenkinsServerAddress = 'none'
        self.JenkinsServerPort = 'none'
        self.ServerHandler = None
        self.IpRegex = '''^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 
            25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 
            25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)\.( 
            25[0-5]|2[0-4][0-9]|[0-1]?[0-9][0-9]?)'''

        self.JCSelectedJobCommands = {
            '(enable)': ' - Enable the specified job on Jenkins Server',
            '(disable)': ' - Disable the specified job on Jenkins Server',
            '(build)': ' - Build the specified job on Jenkins Server',
            '(stat [*])': ' - Displays status and general information about the specified job',
            '(?)': ' - Displays list of available commands',
            '(??)': ' - Displays list of available commands verbosely',
            '(quit/exit)': ' - Quit Job configuration mode'

        }

        self.JigGlobalCommands = {
            '(show local jobs [*])': ' - Displays all jobs saved and waiting in your local machine to be created on server',
            '(show server jobs)': ' - Displays all jobs currently on your jenkins server',
            '(show build queue)': ' - Displays all jobs in build queue',
            '(delete local job)': ' - Deletes jobs on your local machine',
            '(delete server job)': ' - Deletes jobs on your jenkins server',
            '(reconfig server job)': ' - Reconfigures an existing job',
            '(select server job)': ' - Selects job and enter job configuration mode',
            '(connect)': ' - Connects to jenkins server',
            '(disconnect)': ' - Disconnects from jenkins server',
            '(create server job)': ' - Creates a new job on server ',
            '(?)': ' - Displays list of available commands',
            '(??)': ' - Displays list of available commands verbosely',
            '(exit / quit)': ' - Quit JC program'

        }

    def initialize(self):

        fh=open("C:\\Users\{0}\JC\controls".format(getuser()))
        for line in fh:
            if line.startswith('server.conf'):
                self.JCServerConfFileLoc=(line.split("=")[1]).strip()
            elif line.startswith('jobdir'):
                self.JCDirectoryLoc=(line.split("=")[1]).strip()
            elif line.startswith('built'):
                self.JCBuiltFileLoc=(line.split("=")[1]).strip()
            elif line.startswith('address'):
                self.JenkinsServerAddress=(line.split("=")[1]).strip()
            elif line.startswith('port'):
                self.JenkinsServerPort=(line.split("=")[1]).strip()
        fh.close()


    def display_introduction(self):
        '''
        Display an introduction message for the program containing the version and status of
        development
        '''

        print("     Welcome to JC 1.4")
        print("JC is a project which creates an interface to manage your Jenkins Server for your projects")
        print("This project is still under development ")

    def display_list_of_global_mode_commands(self, verbos=False, search_key=None):
        '''
        Display list of available commands in global mode

        :param verbos:  display description of command(s) if true
        :param search_key: display all commands starts with the 'key' param . default is None meaning all available commands

        '''

        print("---------------Commands---------------")
        if search_key is None:
            for command, description in self.JigGlobalCommands.items():
                print(command, description if verbos else '')
        else:
            for command, description in self.JigGlobalCommands.items():

                if command.startswith('({0}'.format(search_key)):
                    print(command, description if verbos else '')
        print("---------------------------------------")

    def display_list_of_selected_job_mode_commands(self, verbos=False, search_key=None):

        '''
        Display list of available commands in selected job mode

        :param verbos: display description of command(s) if true
        :param search_key: display all commands starts with the 'key' param . default is None meaning all available commands

        '''

        print("---------------Commands---------------")
        if search_key is None:
            for command, description in self.JCSelectedJobCommands.items():
                print(command, description if verbos else '')
        else:
            for command, description in self.JCSelectedJobCommands.items():
                if command.startswith('({0}'.format(search_key)):
                    print(command, description if verbos else '')
        print("---------------------------------------")

    def show_local_jobs(self, Detail=False):
        '''
        Display list of local jobs
        :param Detail: If True , Displays more detail about local jobs
        :return:
        '''

        # TODO display format
        if len(listdir(self.JCDirectoryLoc)) == 0:
            print("No local job")
        else:
            if Detail:
                print("Status".ljust(8), "CRL".ljust(23), "CRS".ljust(23), "RCFG".ljust(23), "Name")
                print("-----".ljust(8), "--------".ljust(23), "--------".ljust(23), "--------".ljust(23), "-----")

            else:
                print("Status".ljust(8),"Name".ljust(20))
                print("-----".ljust(8), "-----".ljust(33))

            fhandle = open(self.JCBuiltFileLoc)
            for line in fhandle:
                line = line.strip()
                if line.startswith("#"):
                    pass
                else:
                    if Detail:
                        Status=(line.split("@")[0]).ljust(8)
                        CRL = ((line.split("@")[1]).split(".")[0]).ljust(23)
                        CRS = ((line.split("@")[2]).split(".")[0] if line.split("@")[2]!='None' else 'None').ljust(23)
                        RCFG = ((line.split("@")[3]).split(".")[0] if line.split("@")[3]!='None' else 'None').ljust(23)
                        Name= (line.split("@")[4])
                        print(Status,CRL,CRS,RCFG,Name)
                    else:
                        Status = (line.split("@")[0]).ljust(8)
                        Name= (line.split("@")[4])
                        print(Status,Name)

            fhandle.close()



    def connect_to_jenkins_server(self):

        # Because if there is a problem in reading server.conf file
        # both IP address and Port number becomes none
        # so we just check server address to be none or not


        fh=open("C:\\Users\{0}\JC\controls".format(getuser()))
        for line in fh:
            if line.startswith('address'):
                self.JenkinsServerAddress=(line.split("=")[1]).strip()
            elif line.startswith('port'):
                self.JenkinsServerPort=(line.split("=")[1]).strip()
        fh.close()

        if self.JenkinsServerAddress !='none':
            print("Connecting {0}:{1}".format(self.JenkinsServerAddress, self.JenkinsServerPort))
            UserName = input("Username : "******"Password : "******"Connected successfully as {2}".format(self.JenkinsServerAddress, self.JenkinsServerPort, UserName))
            except:
                self.ServerHandler = None
                print("Connection to server Failed")

        else:
            print("-Server configuration parameters are not defined properly")
            print("-Check server.conf for parameters and then use jcr.exe to set them")


    def is_connected(self):
        '''
        Check whether we are connected to server or not
        '''
        return True if self.ServerHandler else False

    def disconnect_from_jenkins_server(self, place=None):
        '''
        Disconnect from the server
        :param place: Defines the place we are disconnecting . Displayed message can be different based on this parameter
        '''
        # TODO Close the TCP PORT

        if self.ServerHandler == None:
            # Disconnect and Stay in the program
            if place is None:
                print("You are already disconnected")
            return
        self.ServerHandler = None
        # Disconnect while exiting the program
        print("You are disconnected successfully")

    def create_server_job(self, JobName):
        '''
        Create a server job based on a config.xml file existing on the local machine
        :param JobName: job's name to be created
        '''

        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        if not path.exists('{0}{1}{2}'.format(self.JCDirectoryLoc, JobName, '.config.xml')):
            print("-Job '{0}' config.xml file does not exist on your local machine".format(JobName))
            print("First create a config.xml file for job {0} by jigjr command".format(JobName))
        else:
            ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
            if JobName in ListServerJobs:
                print("-Job '{0}' already exists on the server".format(JobName))
                AskingResult = self.asking_user_decision("Do you want to recreate job {0}?[y/n] : ".format(JobName))

                if AskingResult:
                    self.ServerHandler.delete_job(JobName)
                    print("-Deleting job '{0}' from server ..".format(JobName))

                    fhandle = open(self.JCDirectoryLoc + JobName + ".config.xml")
                    SelectedJobXml = fhandle.read()
                    fhandle.close()
                    self.ServerHandler.create_job(JobName, SelectedJobXml)
                    print("-Job '{0}' recreated successfully".format(JobName))

                    # Recreate a job is similar to reconfigure that job
                    update_built_file(self.JCBuiltFileLoc, 'update-reconfigure-date', JobName,
                                      reconfig_date=datetime.now())

            else:
                AskingResult = self.asking_user_decision("Sure creating job {0}?[y/n] : ".format(JobName))
                if AskingResult:
                    fhandle = open(self.JCDirectoryLoc + JobName + ".config.xml")
                    SelectedJobXml = fhandle.read()
                    fhandle.close()
                    self.ServerHandler.create_job(JobName, SelectedJobXml)
                    print("-Job '{0}' created successfully".format(JobName))
                    update_built_file(self.JCBuiltFileLoc, 'update-server-create-date', JobName,
                                      server_creation_date=datetime.now())

    def reconfigure_server_job(self, JobName, LocalConfigJobName=None):
        '''
        Reconfigure a server job
        :param JobName: Server job to be configured
        :param LocalConfigJobName:  If None , JobName.config.xml file is searched in local machine , else, LocalConfigJobName.config.xml is searched
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
        if JobName not in ListServerJobs:
            print("-Job '{0}' does not exist on the server".format(JobName))

        else:
            ListLocalJobs = [job.split(".")[0] for job in listdir(self.JCDirectoryLoc)]

            # If the LocalConfigJobName is not specified use the JobName as defualt
            LocalConfigJobName = JobName if LocalConfigJobName is None else LocalConfigJobName

            if LocalConfigJobName not in ListLocalJobs:
                print("-Job {0} config.xml file does not exist in your local machine".format(LocalConfigJobName))

            else:
                print("{0}.config.xml found".format(LocalConfigJobName))
                AskingResult = self.asking_user_decision("Sure reconfiguring job {0}?[y/n] : ".format(JobName))
                if AskingResult:
                    fhandle = open(self.JCDirectoryLoc + LocalConfigJobName + ".config.xml")
                    SelectedJobXml = fhandle.read()
                    fhandle.close()
                    self.ServerHandler.reconfig_job(LocalConfigJobName, SelectedJobXml)
                    print("-Job '{0}' reconfigured successfully".format(LocalConfigJobName))
                    update_built_file(self.JCBuiltFileLoc, 'update-reconfigure-date', LocalConfigJobName,
                                      reconfig_date=datetime.now())

    def show_build_queue(self):
        '''
        Display list of jobs which are currently under building process
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            BuildQueue = self.ServerHandler.get_queue_info()
            if len(BuildQueue) == 0:
                print("No job in build queue")
                return
            else:
                BuildQueueCounter = 1
                for job in BuildQueue:
                    jobInfo = self.ServerHandler.get_job_info(job['task']['name'])
                    print("{0}: {1}\tBuilding No: {2}".format(BuildQueueCounter, job["task"]["name"],
                                                              jobInfo['nextBuildNumber']))
                    BuildQueueCounter += 1

    def show_server_jobs(self):
        '''
        Display list of jobs currently configured on the server
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            if len(self.ServerHandler.get_jobs()) == 0:
                print("No job currently on the server")
            else:
                ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
                # This list is to reduce the latency of display of all jobs
                # First collect information of all jobs then display
                ReadyList = []
                for job in ListServerJobs:
                    JobInfo = self.ServerHandler.get_job_info(job)
                    JobStatus = 'Disabled' if JobInfo['disabled'] else 'Enabled'
                    JobTotalBuilds = "0" if JobInfo['lastBuild'] is None else JobInfo['lastBuild']['number']
                    JobLastBuild = "None" if JobInfo['lastBuild'] is None else datetime.fromtimestamp(
                        self.ServerHandler.get_build_info(job, JobInfo['lastBuild']['number'])['timestamp'] / 1000)
                    ReadyList.append([JobStatus, JobTotalBuilds, JobLastBuild, job])

                print("Status".ljust(8), "Build".ljust(7), "Timestamp".ljust(22), "Name".ljust(20))
                print("-----".ljust(8), "-----".ljust(7), "------".ljust(22), "----".ljust(20))

                for j in ReadyList:
                    print(j[0].ljust(9), str(j[1]).ljust(6),('None' if str(j[2]) == 'None' else str(j[2]).split(".")[0]).ljust(22), j[3].ljust(20))



    def delete_local_job(self, JobName):
        '''
        Delete local jobs
        '''

        LocalJobs = [job.split(".")[0] for job in listdir(self.JCDirectoryLoc)]

        if JobName not in LocalJobs:
            print("-Job '{0}' does not exist in your local machine".format(JobName))
            return
        else:
            AskingResult = self.asking_user_decision("Sure deleting job '{0}'?[y/n] : ".format(JobName))
            if AskingResult:
                remove(self.JCDirectoryLoc + JobName + ".config.xml")
                print("-Job '{0}' removed successfully from your local machine".format(JobName))

                update_built_file(self.JCBuiltFileLoc, 'delete', JobName)

    def delete_server_job(self, JobName):
        '''
        Delete Specified server job
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
            if JobName not in ListServerJobs:
                print("-Job '{0}' does not exist in Jenkins Server".format(JobName))
                return
            else:
                AskingResult = self.asking_user_decision("Sure deleting job '{0}'?[y/n]: ".format(JobName))
                if AskingResult:
                    self.ServerHandler.delete_job(JobName)
                    print("-Job '{0}' removed successfully from server".format(JobName))
                    update_built_file(self.JCBuiltFileLoc, 'update-deploy-status-ND', JobName)

    def disable_server_job(self, JobName):
        '''
        Disable specified server job
        '''

        JobState = self.ServerHandler.get_job_info(JobName)['disabled']
        if JobState:
            print("-Job '{0}' is already disabled".format(JobName))
            return
        self.ServerHandler.disable_job(JobName)
        print("-Job '{0}' successfully disabled".format(JobName))

    def enable_server_job(self, JobName):
        '''
        Enable specified server job
        '''
        JobState = self.ServerHandler.get_job_info(JobName)['disabled']
        if not JobState:
            print("-Job '{0}' is already enabled".format(JobName))
            return
        self.ServerHandler.enable_job(JobName)
        print("-Job '{0}' successfully enabled".format(JobName))

    def build_server_job(self, JobName):
        '''
        Build specified server job
        '''
        JobState = self.ServerHandler.get_job_info(JobName)['disabled']
        if JobState:
            print("-Job '{0}' is disabled and cannot built".format(JobName))
        else:
            self.ServerHandler.build_job(JobName)
            print("-Job '{0}' successfully built".format(JobName))

    def stat_server_job(self, JobName, Detail=False):
        '''
        Display status of the selected job
        :param Detail: If * specified , more detail about job is displayed
        '''

        # Because building a job can take long time we do not display the status
        # until the building process gets done
        BuildQueue = self.ServerHandler.get_queue_info()

        for job in BuildQueue:
            if JobName == job["task"]["name"]:
                print("-Job '{0}' is under building process".format(JobName))
                return

        JobInfo = self.ServerHandler.get_job_info(JobName)
        JobName_Sta = "Name: {0}".format(JobName)
        JobStatus_Sta = "Status: {0}".format('Disabled' if JobInfo['disabled'] else 'Enabled')
        JobTotalBuilds_Sta = "TotalBuilds: {0}".format(
            "0" if JobInfo['lastBuild'] is None else JobInfo['lastBuild']['number'])
        JobLastBuild_Sta = "LastBuild: {0}".format("None" if JobInfo['lastBuild'] is None else datetime.fromtimestamp(
            self.ServerHandler.get_build_info(JobName, JobInfo['lastBuild']['number'])['timestamp'] / 1000))
        JobFirstBuild_Sta = "FirstBuild: {0}".format("None" if JobInfo['lastBuild'] is None else datetime.fromtimestamp(
            self.ServerHandler.get_build_info(JobName, JobInfo['lastBuild']['number'])['timestamp'] / 1000))

        JobLastCompletedBuild_Sta = "LastCompletedBuild: {0}".format(
            "None" if JobInfo['lastCompletedBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastCompletedBuild']['number'])[
                    'timestamp'] / 1000)).split(".")[0])
        JobLastFailedBuild_Sta = "LastFailedBuild: {0}".format(
            "None" if JobInfo['lastFailedBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastFailedBuild']['number'])['timestamp'] / 1000)).split(".")[0])
        JobLastStableBuild_Sta = "LastStableBuild: {0}".format(
            "None" if JobInfo['lastStableBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastStableBuild']['number'])['timestamp'] / 1000)).split(".")[0])
        JobLastSuccessfulBuild_Sta = "LastSuccessfulBuild: {0}".format(
            "None" if JobInfo['lastSuccessfulBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastSuccessfulBuild']['number'])[
                    'timestamp'] / 1000)).split(".")[0])
        JobLastUnstableBuild_Sta = "LastUnstableBuild: {0}".format(
            "None" if JobInfo['lastUnstableBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastUnstableBuild']['number'])['timestamp'] / 1000)).split(".")[0])
        JobLastUnsuccessfulBuild_Sta = "LastUnsuccessfulBuild: {0}".format(
            "None" if JobInfo['lastUnsuccessfulBuild'] is None else str(datetime.fromtimestamp(
                self.ServerHandler.get_build_info(JobName, JobInfo['lastUnsuccessfulBuild']['number'])[
                    'timestamp'] / 1000)).split(".")[0])

        print(JobName_Sta)
        print(JobStatus_Sta)
        print(JobTotalBuilds_Sta)
        print(JobLastBuild_Sta)
        print(JobLastStableBuild_Sta)
        print(JobLastCompletedBuild_Sta)

        if Detail:
            print(JobFirstBuild_Sta)
            print(JobLastFailedBuild_Sta)
            print(JobLastSuccessfulBuild_Sta)
            print(JobLastUnstableBuild_Sta)
            print(JobLastUnsuccessfulBuild_Sta)

    def select_server_job(self, JobName):
        '''
        Select a server job and enter selected job mode
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:

            ListServerJobs = [server_job["name"] for server_job in self.ServerHandler.get_jobs()]
            if JobName not in ListServerJobs:
                print("-Job '{0}'  not exist in Jenkins Server".format(JobName))
                return
            else:
                SelectedJobSession = PromptSession(
                    lexer=PygmentsLexer(SqlLexer), completer=selected_job_command_completer)
                while True:

                    try:
                        UserCommand = SelectedJobSession.prompt("(" + JobName + ')## ')
                        UserCommand = (sub(' +', ' ', UserCommand)).strip()

                        if UserCommand.startswith("??"):
                            keyValue = (UserCommand.split("??")[1].strip())
                            if keyValue == '':
                                jc.display_list_of_selected_job_mode_commands(verbos=True)
                            else:
                                jc.display_list_of_selected_job_mode_commands(search_key=keyValue, verbos=True)

                        elif UserCommand.startswith("?"):
                            keyValue = (UserCommand.split("?")[1].strip())

                            if keyValue == '':
                                jc.display_list_of_selected_job_mode_commands()
                            else:
                                jc.display_list_of_selected_job_mode_commands(search_key=keyValue)


                        elif UserCommand == "quit" or UserCommand == "exit":
                            return

                        elif UserCommand == "enable":
                            self.enable_server_job(JobName)

                        elif UserCommand == "disable":
                            self.disable_server_job(JobName)

                        elif UserCommand == "build":
                            self.build_server_job(JobName)

                        elif UserCommand == 'stat *':
                            self.stat_server_job(JobName, Detail=True)

                        elif UserCommand == 'stat':
                            self.stat_server_job(JobName)

                        elif UserCommand == "":
                            pass
                        else:
                            print("%Invalid Command")

                    except KeyboardInterrupt:
                        break
                    except EOFError:
                        break
                    except:
                        print("There was a problem in program")
                        return

    def get_whoami(self):
        '''
        Display who is connected to server
        '''
        if self.ServerHandler is None:
            print("Your are not connected to server")
            print("First connect by 'connect' command")
            return
        else:
            UserInfo = self.ServerHandler.get_whoami()
            print("Full Name : ", UserInfo["fullName"])
            print("Id : ", UserInfo["id"])

    def asking_user_decision(self, displayMessage):
        '''
        This process is repeated many times in the code asking the user for yes/no answer
        so this process is turned into a function for simplicity

        :param displayMessage:  Message to be displayed for asking user his/her decision
        '''

        while True:
            UserDecision = input(displayMessage)
            if UserDecision.lower() in "y yes ye":
                return True
            elif UserDecision.lower() in "n no":
                return False

    def get_job_directory(self):
        return self.JCDirectoryLoc
Beispiel #9
0
    def execOnJenkins(self,env,testSpecifierString,mailto,execOnOneZone=True):
        try:
              testMgr=testManager(testSpecifierString,env['virtenvPath'])
              jobModifier=modifyJOb()
              modifiedjob=""
              j=Jenkins('http://jenkins-ccp.citrix.com','bharatk','BharatK')
              tests=testMgr.getTests()
              if(tests==None):
                raise Exception("found no tests to run")
              while(not tests is None):
                  #trigger a jenkins job.
                  os.chdir(env['virtenvPath'])
                  self.logger.info("launching jenkins TestExecutor Job")
                  #createing testexecutorjobs for each zone.
                  cscfg=configGenerator.getSetupConfig(env['config_file'])
                  jobIdentifierList=[]
                  for zone in cscfg.zones:
                      for pod in zone.pods:
                         for cluster in pod.clusters:
                             modifiedjob=jobModifier.addTests(env['build_number'],tests)
                             file=open("/root/cloud-autodeploy2/newcode/"+modifiedjob,'r')
                             config=file.read()
                             file.close()
                             bash("rm -f /root/cloud-autodeploy2/newcode/%s"%modifiedjob)
                             if(not j.job_exists(modifiedjob)):
                                  j.create_job(modifiedjob,config)
                             else:
                                  j.reconfig_job(modifiedjob,config)
                             j.build_job(modifiedjob, {'BASEDIR':env['virtenvPath'], 'MGMT_SVR' : env['hostip'],'buildNumber':env['build_number'],'zoneName':zone.name,'hypervisor':cluster.hypervisor.lower(),'zoneType':zone.networktype,'configFileName':env['config_file'],'token':'bharat'})
                             jobIdentifierList.append(zone.name)
                             break
                         break
                      if (execOnOneZone):
                        break
                  self.waitForJobComplete(env['virtenvPath'],jobIdentifierList)
                  tests=testMgr.getTests()  

              j.delete_job(modifiedjob) 
              jobIdentifierList=[]
              bugLoggerData=[]
              time.sleep(30)
              for zone in cscfg.zones:
                 self.logger.info(zone.name)
                 for pod in zone.pods:
                     for cluster in pod.clusters:
                         self.logger.info("creating a jeknins job to generate results and email notfication for hypervisor %s and zone %s"%(cluster.hypervisor, zone.name))
                         modifiedjob=jobModifier.modifyReportGenerator(env['build_number']+"_"+zone.name+"_"+cluster.hypervisor, mailto)
                         jobname=modifiedjob
                         file=open("/root/cloud-autodeploy2/newcode/"+modifiedjob,'r')
                         config=file.read()
                         file.close()
                         j.create_job(modifiedjob,config)
                         j.build_job(modifiedjob, {'buildNumber':env['build_number'],'BuildNo':env['build_number'], 'MGMT_SVR' : env['hostip'], 'BASEDIR':env['virtenvPath'], 'version':env['version'], 'BranchInfo':env['version'],\
                         'GitRepoUrl':env['repo_url'],'GitCommitId':env['commit_id'], 'CIRunStartDateTime':env['startTime'],'CIRunEndDateTime':time.strftime("%c"), 'WikiLinks':'https://cwiki.apache.org/confluence/display/CLOUDSTACK/Infrastructure%2CCI%2CSimulator%2CAutomation+Changes','hypervisor':cluster.hypervisor.lower(), 'HyperVisorInfo':cluster.hypervisor.lower(), 'zoneName':zone.name, 'BuildReport':"http://jenkins-ccp.citrix.com/job/"+jobname+"/1/testReport/",'token':'bharat'})
                         jobIdentifierList.append("report_"+zone.name)
                         jobDetails={"job_name":modifiedjob,"related_data_path":env['virtenvPath']}
                         self.resourceMgr.addJobDetails(jobDetails)
                         bugLoggerData.append({'hypervisor':cluster.hypervisor.lower(), 'branch':env['version'],'logname':cluster.hypervisor.lower()+'__Log_'+env['build_number'], 'type':'BVT'})
                         self.logger.info("bug logger data in zone looop %s"%bugLoggerData)
                         break
                     break
                 if (execOnOneZone):
                    #env['hypervisor':cluster.hypervisor.lower()]
                    break  
              self.logger.info("job identifier list", jobIdentifierList)       
              self.waitForJobComplete(env['virtenvPath'],jobIdentifierList)
              #self.logger.info("deleting the reporter job on jenkins job_name=%s",jobname)
              #j.delete_job(jobname)
              self.logger.info("cleaning up the workspace")
              bash("rm -f /root/cloud-autodeploy2/newcode/%s"%modifiedjob)
              self.logger.info("running bug logger")
              #self.runBugLogger(bugLoggerData)
              #os.system("rm -rf %s"%(self.jenkinsWorkspace+"/"+jobname))
        except Exception, e:
               self.logger.error(e) 
Beispiel #10
0
class jenkinscls(object):
    def __init__(self):
        self.url = config.JENKINS_URL
        self.username = config.JENKINS_NAME
        self.token = config.JENKINS_TOKEN
        self.j = Jenkins(config.JENKINS_URL,
                         username=config.JENKINS_NAME,
                         password=config.JENKINS_TOKEN)

    def getjobnames(self, strval=''):
        rs = {r'...': r'/'}
        s = utils.multiple_replace(str(strval), rs).split('/')
        return s[0], "/".join(s[1:])

    def getlenstr(self, strval, n):
        return str(strval)[0:n]

    def getstatus(self, strval):
        if str(strval) == 'FAILURE':
            return 'error'
        elif str(strval) == 'ABORTED':
            return 'aborted'
        elif str(strval) == 'SUCCESS':
            return 'success'
        else:
            return 'started'

    def edit_userjob_config(self, jn, obj):
        n, r = self.getjobnames(jn)
        try:
            desobj = callback()
            desobj.des = obj['description']
            desobj.callback_url = ""
            desobj.build_id = ''
            desobj.duration = ''
            desobj.namespace = n
            desobj.image_name = obj['image_name']
            desobj.repo_name = r
            desobj.status = ''
            desobj.tag = obj['build_config']['tag_configs']['docker_repo_tag']
            desobj.time = ''

            ss = xmltodict.parse(self.getbasejob_config())
            jsonpickle.set_preferred_backend('json')
            ss['project']['description'] = jsonpickle.encode(desobj)
            ss['project']['properties']['com.tikal.hudson.plugins.notification.HudsonNotificationProperty']['endpoints'] \
                ['com.tikal.hudson.plugins.notification.Endpoint']['url'] = config.JOBHOOKURL

            ss['project']['scm']['userRemoteConfigs']['hudson.plugins.git.UserRemoteConfig'] \
                ['url'] = obj['build_config']['code_repo_clone_url']
            ss['project']['scm']['branches']['hudson.plugins.git.BranchSpec'] \
                ['name'] = '*/' + obj['build_config']['tag_configs']['code_repo_type_value']
            ss['project']['builders']['hudson.tasks.Shell'][
                'command'] = config.JOBCOMMON1
            ss['project']['builders']['com.cloudbees.dockerpublish.DockerBuilder']['registry'] \
                ['url'] = config.REGISTRYURL
            b = str(obj['build_config']['tag_configs']['build_cache_enabled'])
            ss['project']['builders']['com.cloudbees.dockerpublish.DockerBuilder']['noCache'] \
                = ('true' if b == 'false' else 'false')
            ss['project']['builders']['com.cloudbees.dockerpublish.DockerBuilder']['dockerfilePath'] \
                = obj['build_config']['tag_configs']['dockerfile_location']
            ss['project']['builders']['com.cloudbees.dockerpublish.DockerBuilder']['repoTag'] \
                = obj['build_config']['tag_configs']['docker_repo_tag']
            ss['project']['builders']['com.cloudbees.dockerpublish.DockerBuilder']['repoName'] \
                = obj['image_name']

            return xmltodict.unparse(ss)
        except Exception as e:
            print e.message

    def edit_docker_load_job_config(self, obj):

        try:
            # {docker_login} && docker import {httpfilename} {imagename} && docker push {imagename}
            ss = xmltodict.parse(self.getdocker_load_config())
            desobj = callback()
            desobj.des = obj['export_file_url']
            desobj.callback_url = obj['post_callback_url']
            desobj.build_id = obj['build_id']
            desobj.duration = ''
            desobj.namespace = ""
            desobj.repo_name = ""
            desobj.image_name = obj['image_name']
            desobj.status = ''
            desobj.tag = obj['tag']
            desobj.time = ''
            jsonpickle.set_preferred_backend('json')
            ss['project']['description'] = jsonpickle.encode(desobj)
            ss['project']['properties']['com.tikal.hudson.plugins.notification.HudsonNotificationProperty']['endpoints'] \
                ['com.tikal.hudson.plugins.notification.Endpoint']['url'] = config.JOBHOOKURL
            tempstr = str(
                ss['project']['builders']['hudson.tasks.Shell']['command'])
            s = {
                r'{docker_login}':
                config.JOBCOMMON1,
                r'{httpfilename}':
                obj['export_file_url'],
                r'{imagename}':
                config.REGISTRYNAME + '/' + obj['image_name'] + ':' +
                obj['tag']
            }
            ss['project']['builders']['hudson.tasks.Shell'][
                'command'] = utils.multiple_replace(tempstr, s)

            return xmltodict.unparse(ss)
        except Exception as e:
            print e.message

    def edit_docker_sync_job_config(self, obj):

        try:
            # {docker_login} && docker pull {oldimage} && docker tag {oldimage} {newimage} && docker push {newimage}
            ss = xmltodict.parse(self.getdocker_sync_config())
            jsonUtil = JsonUtil()
            c = jsonUtil.parseJsonString(config.CLOUD_CONFIG)
            cid = obj['sync_cloud_id']
            desobj = callback()
            desobj.des = ""
            desobj.callback_url = obj['post_callback_url']
            desobj.build_id = ''
            desobj.duration = ''
            desobj.namespace = ""
            desobj.repo_name = obj['sync_cloud_id']  # 把cloudid 临时存在 这
            desobj.image_name = obj['image_name']
            desobj.status = ''
            desobj.tag = obj['tag']
            desobj.time = ''
            jsonpickle.set_preferred_backend('json')
            ss['project']['description'] = jsonpickle.encode(desobj)
            ss['project']['properties']['com.tikal.hudson.plugins.notification.HudsonNotificationProperty']['endpoints'] \
                ['com.tikal.hudson.plugins.notification.Endpoint']['url'] = config.JOBHOOKURL+'?cloudid='+obj['sync_cloud_id']
            tempstr = str(
                ss['project']['builders']['hudson.tasks.Shell']['command'])
            s = {
                r'{docker_login}':
                c[cid]['login_common'],
                r'{oldimage}':
                config.REGISTRYNAME + '/' + obj['image_name'] + ':' +
                obj['tag'],
                r'{newimage}':
                c[cid]['registry_name'] + '/' + obj['image_name'] + ':' +
                obj['tag']
            }
            ss['project']['builders']['hudson.tasks.Shell'][
                'command'] = utils.multiple_replace(tempstr, s)

            return xmltodict.unparse(ss)
        except Exception as e:
            print e.message

    def updateconfig_buildid(self, jn, imagename, build_id, callback_url):
        try:
            ss = xmltodict.parse(self.j.get_job_config(jn))
            jsonpickle.set_preferred_backend('json')
            desobj = jsonpickle.decode(ss['project']['description'])
            if str(desobj.build_id) == str(build_id):
                return True
            desobj.build_id = build_id
            desobj.callback_url = callback_url
            desobj.image_name = imagename
            ss['project']['description'] = jsonpickle.encode(desobj)

            self.j.reconfig_job(jn, xmltodict.unparse(ss))

            return True
        except Exception as e:
            print e.message
            return False

    @gen.coroutine
    def posthook(self, obj):
        # s = {r'/': r'...'}
        jn = obj['name']
        bid = str(obj['build']['number'])
        # n, r = self.getjobnames(jn)
        re = hook()
        try:
            info = self.j.get_build_info(jn, int(bid))
            if self.j.job_exists(jn):
                ss = xmltodict.parse(self.j.get_job_config(jn))
                jsonpickle.set_preferred_backend('json')

                if isinstance(jsonpickle.decode(ss['project']['description']),
                              callback):
                    desobj = jsonpickle.decode(ss['project']['description'])
                    re.namespace = desobj.namespace
                    re.repo_name = desobj.repo_name
                    re.build_id = str(obj['build']['number'])
                    re.status = self.getstatus(obj['build']['status'])
                    re.duration = info['duration']
                    re.tag = desobj.tag
                    re.time = datetime.now()
                    re.callurl = desobj.callback_url
        except Exception as e:
            print e.message
            re = None
        raise gen.Return(re)

    @gen.coroutine
    def post_docker_load_hook(self, obj):

        jn = obj['name']
        bid = str(obj['build']['number'])

        re = postimage()
        try:
            # info = self.j.get_build_info(jn, int(bid))
            if self.j.job_exists(jn):
                ss = xmltodict.parse(self.j.get_job_config(jn))
                jsonpickle.set_preferred_backend('json')

                if isinstance(jsonpickle.decode(ss['project']['description']),
                              callback):
                    desobj = jsonpickle.decode(ss['project']['description'])
                    re.image_name = desobj.image_name
                    re.status = self.getstatus(obj['build']['status'])
                    re.tag = desobj.tag
                    re.export_file_url = desobj.des
                    re.time = datetime.now()
                    re.build_id = desobj.build_id
                    re.post_callback_url = desobj.callback_url
                    if re.status != 'error' and config.JENKINS_IMAGEOPTJOB_DELETE == 'true':
                        self.j.delete_job(jn)

        except Exception as e:
            print e.message
            re = None
        raise gen.Return(re)

    @gen.coroutine
    def post_docker_sync_hook(self, obj, cloudid):
        jn = obj['name']
        # bid = str(obj['build']['number'])
        jsonUtil = JsonUtil()
        c = jsonUtil.parseJsonString(config.CLOUD_CONFIG)
        j = Jenkins(c[cloudid]['jenkins_url'],
                    username=c[cloudid]['jenkins_name'],
                    password=c[cloudid]['jenkins_token'])

        re = postimagesync()
        try:

            if j.job_exists(jn):
                ss = xmltodict.parse(j.get_job_config(jn))
                jsonpickle.set_preferred_backend('json')

                if isinstance(jsonpickle.decode(ss['project']['description']),
                              callback):
                    desobj = jsonpickle.decode(ss['project']['description'])
                    re.image_name = desobj.image_name
                    re.status = self.getstatus(obj['build']['status'])
                    re.sync_cloud_id = desobj.repo_name
                    re.tag = desobj.tag
                    re.time = datetime.now()
                    re.post_callback_url = desobj.callback_url
                    if re.status != 'error' and config.JENKINS_IMAGEOPTJOB_DELETE == 'true':
                        j.delete_job(jn)

        except Exception as e:
            print e.message
            re = None
        raise gen.Return(re)

    @gen.coroutine
    def createjob(self, jobname, obj):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        try:
            if self.j.job_exists(jn):
                re = createrespo(n, r, '工程已存在', 'error', datetime.now())
            self.j.create_job(jn, self.edit_userjob_config(jn, obj))
            re = createrespo(n, r, '', 'success', datetime.now())
        except Exception as e:
            print e.message
            re = createrespo(n, r, '', 'error', datetime.now())
        raise gen.Return(re)

    @gen.coroutine
    def create_docker_load_job(self, obj):
        # s = {r'/': r'...'}
        # jn = utils.multiple_replace(jobname, s)
        s = utils.randomstr(8)
        jn = '__docker_load_job_' + s
        re = postimage()
        re.created_at = datetime.now()
        re.image_name = obj['image_name']
        re.build_id = str(obj['build_id'])
        re.post_callback_url = obj['post_callback_url']
        re.tag = obj['tag']
        re.status = 'started'
        try:
            if self.j.job_exists(jn):
                jn = jn + utils.randomstr(4)
                x = self.edit_docker_load_job_config(obj)
                self.j.create_job(jn, x)
                yield gen.sleep(0.5)
                self.j.build_job(jn)
            x = self.edit_docker_load_job_config(obj)
            self.j.create_job(jn, x)
            yield gen.sleep(0.5)
            self.j.build_job(jn)

        except Exception as e:
            print e.message
            re.status = 'error'
        raise gen.Return(re)

    @gen.coroutine
    def create_docker_sync_job(self, obj):
        # s = {r'/': r'...'}
        # jn = utils.multiple_replace(jobname, s)
        s = utils.randomstr(8)
        jn = '__docker_sync_job_' + s
        cid = obj['sync_cloud_id']
        jsonUtil = JsonUtil()
        c = jsonUtil.parseJsonString(config.CLOUD_CONFIG)
        j = Jenkins(c[cid]['jenkins_url'],
                    username=c[cid]['jenkins_name'],
                    password=c[cid]['jenkins_token'])
        re = postimagesync()
        re.time = datetime.now()
        re.sync_cloud_id = obj['sync_cloud_id']
        re.image_name = obj['image_name']
        re.post_callback_url = obj['post_callback_url']
        re.tag = obj['tag']
        re.status = 'started'
        try:
            if j.job_exists(jn):
                jn = jn + utils.randomstr(4)
                j.create_job(jn, self.edit_docker_sync_job_config(obj))
                yield gen.sleep(0.5)
                j.build_job(jn)
            j.create_job(jn, self.edit_docker_sync_job_config(obj))
            yield gen.sleep(0.5)
            j.build_job(jn)
        except Exception as e:
            print e.message
            re.status = 'error'
        raise gen.Return(re)

    @gen.coroutine
    def editjob(self, jobname, obj):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        try:
            if self.j.job_exists(jn):
                self.j.reconfig_job(jn, self.edit_userjob_config(jn, obj))
                re = createrespo(n, r, '', 'success', datetime.now())
            else:
                re = createrespo(n, r, 'repo is not find', 'error',
                                 datetime.now())
        except Exception as e:
            print e.message
            re = createrespo(n, r, '', 'error', datetime.now())
        raise gen.Return(re)

    @gen.coroutine
    def getjobinfo(self, jobname):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        re = jobinfo()
        try:
            if self.j.job_exists(jn):
                re.namespace = n
                re.repo_name = r
                re.info = self.j.get_job_info(jn)
        except Exception as e:
            print e.message
            re.namespace = n
            re.repo_name = r
            re.info = ""
        raise gen.Return(re)

    @gen.coroutine
    def deljob(self, jobname):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        try:
            if self.j.job_exists(jn):
                self.j.delete_job(jn)
            re = delrespo(n, r, 'success')

        except Exception as e:
            print e.message
            re = delrespo(n, r, 'error')
        raise gen.Return(re)

    @gen.coroutine
    def stopbuild(self, jobname, build_id):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        try:
            if self.j.job_exists(jn) and self.j.get_build_info(
                    jn, int(build_id)):
                self.j.stop_build(jn, int(build_id))
                re = delbuild(n, r, build_id, 'aborted')
            else:
                re = delbuild(n, r, build_id, 'error')

        except Exception as e:
            print e.message
            re = delbuild(n, r, build_id, 'error')
        raise gen.Return(re)

    @gen.coroutine
    def postbuild(self, jobname, imagename, tag, callback_url):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        try:

            if self.j.job_exists(jn):

                j = self.j.get_job_info(jn)

                build_id = j['nextBuildNumber']

                if self.j.get_queue_info() != []:
                    re = postbuild(n, r, imagename, build_id, tag,
                                   datetime.now(), 'queue')
                elif j['queueItem'] != None:
                    re = postbuild(n, r, imagename, build_id, tag,
                                   datetime.now(), 'queue')
                else:
                    self.updateconfig_buildid(jn, imagename, build_id,
                                              callback_url)
                    self.j.build_job(jn)
                    re = postbuild(n, r, imagename, build_id, tag,
                                   datetime.now(), 'started')
            else:
                re = postbuild(n, r, '', '', datetime.now(), 'error')

        except Exception as e:
            print e.message
            re = postbuild(n, r, '', tag, datetime.now(), 'error')
        raise gen.Return(re)

    @gen.coroutine
    def getbuild(self, jobname, build_id):
        s = {r'/': r'...'}
        jn = utils.multiple_replace(jobname, s)
        n, r = self.getjobnames(jn)
        try:
            b = self.j.get_build_info(jn, int(build_id))
            building = b['building']
            duration = b['duration']
            dt = self.getlenstr(b['timestamp'], 10)
            started_at = utils.timestamp_datetime(int(dt))
            status = self.getstatus(b['result'])
            stdout = self.j.get_build_console_output(jn, int(build_id))
            bd = build_detail(n, r, build_id, building, started_at, duration,
                              status, stdout)
        except Exception as e:
            print e.message
            bd = build_detail(n, r, build_id, '', '', '', 'error', '')
        raise gen.Return(bd)

    def getdocker_sync_config(self):
        s = '''<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="[email protected]">
      <endpoints>
        <com.tikal.hudson.plugins.notification.Endpoint>
          <protocol>HTTP</protocol>
          <format>JSON</format>
          <url>http://10.1.39.60:8080/v1/hook</url>
          <event>completed</event>
          <timeout>30000</timeout>
          <loglines>0</loglines>
        </com.tikal.hudson.plugins.notification.Endpoint>
      </endpoints>
    </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
    <com.synopsys.arc.jenkins.plugins.ownership.jobs.JobOwnerJobProperty plugin="[email protected]"/>
    <hudson.plugins.heavy__job.HeavyJobProperty plugin="[email protected]">
      <weight>1</weight>
    </hudson.plugins.heavy__job.HeavyJobProperty>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>30</daysToKeep>
        <numToKeep>50</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <job-metadata plugin="[email protected]">
      <values class="linked-list">
        <metadata-tree>
          <name>job-info</name>
          <parent class="job-metadata" reference="../../.."/>
          <generated>true</generated>
          <exposedToEnvironment>false</exposedToEnvironment>
          <children class="linked-list">
            <metadata-tree>
              <name>last-saved</name>
              <description></description>
              <parent class="metadata-tree" reference="../../.."/>
              <generated>true</generated>
              <exposedToEnvironment>false</exposedToEnvironment>
              <children class="linked-list">
                <metadata-date>
                  <name>time</name>
                  <description></description>
                  <parent class="metadata-tree" reference="../../.."/>
                  <generated>true</generated>
                  <exposedToEnvironment>false</exposedToEnvironment>
                  <value>
                    <time>1458098001639</time>
                    <timezone>Asia/Shanghai</timezone>
                  </value>
                  <checked>false</checked>
                </metadata-date>
                <metadata-tree>
                  <name>user</name>
                  <parent class="metadata-tree" reference="../../.."/>
                  <generated>true</generated>
                  <exposedToEnvironment>false</exposedToEnvironment>
                  <children class="linked-list">
                    <metadata-string>
                      <name>display-name</name>
                      <description></description>
                      <parent class="metadata-tree" reference="../../.."/>
                      <generated>true</generated>
                      <exposedToEnvironment>false</exposedToEnvironment>
                      <value>admin</value>
                    </metadata-string>
                    <metadata-string>
                      <name>full-name</name>
                      <description></description>
                      <parent class="metadata-tree" reference="../../.."/>
                      <generated>true</generated>
                      <exposedToEnvironment>false</exposedToEnvironment>
                      <value>admin</value>
                    </metadata-string>
                  </children>
                </metadata-tree>
              </children>
            </metadata-tree>
          </children>
        </metadata-tree>
      </values>
    </job-metadata>
  </properties>
  <scm class="hudson.scm.NullSCM"/>
  <scmCheckoutRetryCount>3</scmCheckoutRetryCount>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.tasks.Shell>
      <command>{docker_login} &amp;&amp; docker pull {oldimage} &amp;&amp; docker tag --force=true {oldimage} {newimage} &amp;&amp; docker push {newimage}
</command>
    </hudson.tasks.Shell>
  </builders>
  <publishers/>
  <buildWrappers>
    <hudson.plugins.ansicolor.AnsiColorBuildWrapper plugin="[email protected]">
      <colorMapName>xterm</colorMapName>
    </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
  </buildWrappers>
</project>'''
        return s

    def getdocker_load_config(self):
        s = '''<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="[email protected]">
      <endpoints>
        <com.tikal.hudson.plugins.notification.Endpoint>
          <protocol>HTTP</protocol>
          <format>JSON</format>
          <url>http://10.1.39.60:8080/v1/hook</url>
          <event>completed</event>
          <timeout>30000</timeout>
          <loglines>0</loglines>
        </com.tikal.hudson.plugins.notification.Endpoint>
      </endpoints>
    </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
    <com.synopsys.arc.jenkins.plugins.ownership.jobs.JobOwnerJobProperty plugin="[email protected]"/>
    <hudson.plugins.heavy__job.HeavyJobProperty plugin="[email protected]">
      <weight>1</weight>
    </hudson.plugins.heavy__job.HeavyJobProperty>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>30</daysToKeep>
        <numToKeep>50</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <job-metadata plugin="[email protected]">
      <values class="linked-list">
        <metadata-tree>
          <name>job-info</name>
          <parent class="job-metadata" reference="../../.."/>
          <generated>true</generated>
          <exposedToEnvironment>false</exposedToEnvironment>
          <children class="linked-list">
            <metadata-tree>
              <name>last-saved</name>
              <description></description>
              <parent class="metadata-tree" reference="../../.."/>
              <generated>true</generated>
              <exposedToEnvironment>false</exposedToEnvironment>
              <children class="linked-list">
                <metadata-date>
                  <name>time</name>
                  <description></description>
                  <parent class="metadata-tree" reference="../../.."/>
                  <generated>true</generated>
                  <exposedToEnvironment>false</exposedToEnvironment>
                  <value>
                    <time>1458097635464</time>
                    <timezone>Asia/Shanghai</timezone>
                  </value>
                  <checked>false</checked>
                </metadata-date>
                <metadata-tree>
                  <name>user</name>
                  <parent class="metadata-tree" reference="../../.."/>
                  <generated>true</generated>
                  <exposedToEnvironment>false</exposedToEnvironment>
                  <children class="linked-list">
                    <metadata-string>
                      <name>display-name</name>
                      <description></description>
                      <parent class="metadata-tree" reference="../../.."/>
                      <generated>true</generated>
                      <exposedToEnvironment>false</exposedToEnvironment>
                      <value>admin</value>
                    </metadata-string>
                    <metadata-string>
                      <name>full-name</name>
                      <description></description>
                      <parent class="metadata-tree" reference="../../.."/>
                      <generated>true</generated>
                      <exposedToEnvironment>false</exposedToEnvironment>
                      <value>admin</value>
                    </metadata-string>
                  </children>
                </metadata-tree>
              </children>
            </metadata-tree>
          </children>
        </metadata-tree>
      </values>
    </job-metadata>
  </properties>
  <scm class="hudson.scm.NullSCM"/>
  <scmCheckoutRetryCount>3</scmCheckoutRetryCount>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.tasks.Shell>
      <command>{docker_login} &amp;&amp; docker import {httpfilename} {imagename} &amp;&amp; docker push {imagename}
</command>
    </hudson.tasks.Shell>
  </builders>
  <publishers/>
  <buildWrappers>
    <hudson.plugins.ansicolor.AnsiColorBuildWrapper plugin="[email protected]">
      <colorMapName>xterm</colorMapName>
    </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
  </buildWrappers>
</project>'''
        return s

    def getbasejob_config(self):
        s = '''<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.tikal.hudson.plugins.notification.HudsonNotificationProperty plugin="[email protected]">
      <endpoints>
        <com.tikal.hudson.plugins.notification.Endpoint>
          <protocol>HTTP</protocol>
          <format>JSON</format>
          <url>http://10.1.39.60:8080/v1/hook</url>
          <event>completed</event>
          <timeout>30000</timeout>
          <loglines>0</loglines>
        </com.tikal.hudson.plugins.notification.Endpoint>
      </endpoints>
    </com.tikal.hudson.plugins.notification.HudsonNotificationProperty>
    <com.synopsys.arc.jenkins.plugins.ownership.jobs.JobOwnerJobProperty plugin="[email protected]"/>
    <hudson.plugins.heavy__job.HeavyJobProperty plugin="[email protected]">
      <weight>1</weight>
    </hudson.plugins.heavy__job.HeavyJobProperty>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="hudson.tasks.LogRotator">
        <daysToKeep>30</daysToKeep>
        <numToKeep>50</numToKeep>
        <artifactDaysToKeep>-1</artifactDaysToKeep>
        <artifactNumToKeep>-1</artifactNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <job-metadata plugin="[email protected]">
      <values class="linked-list">
        <metadata-tree>
          <name>job-info</name>
          <parent class="job-metadata" reference="../../.."/>
          <generated>true</generated>
          <exposedToEnvironment>false</exposedToEnvironment>
          <children class="linked-list">
            <metadata-tree>
              <name>last-saved</name>
              <description></description>
              <parent class="metadata-tree" reference="../../.."/>
              <generated>true</generated>
              <exposedToEnvironment>false</exposedToEnvironment>
              <children class="linked-list">
                <metadata-date>
                  <name>time</name>
                  <description></description>
                  <parent class="metadata-tree" reference="../../.."/>
                  <generated>true</generated>
                  <exposedToEnvironment>false</exposedToEnvironment>
                  <value>
                    <time>1457958794480</time>
                    <timezone>Asia/Shanghai</timezone>
                  </value>
                  <checked>false</checked>
                </metadata-date>
                <metadata-tree>
                  <name>user</name>
                  <parent class="metadata-tree" reference="../../.."/>
                  <generated>true</generated>
                  <exposedToEnvironment>false</exposedToEnvironment>
                  <children class="linked-list">
                    <metadata-string>
                      <name>display-name</name>
                      <description></description>
                      <parent class="metadata-tree" reference="../../.."/>
                      <generated>true</generated>
                      <exposedToEnvironment>false</exposedToEnvironment>
                      <value>admin</value>
                    </metadata-string>
                    <metadata-string>
                      <name>full-name</name>
                      <description></description>
                      <parent class="metadata-tree" reference="../../.."/>
                      <generated>true</generated>
                      <exposedToEnvironment>false</exposedToEnvironment>
                      <value>admin</value>
                    </metadata-string>
                  </children>
                </metadata-tree>
              </children>
            </metadata-tree>
          </children>
        </metadata-tree>
      </values>
    </job-metadata>
  </properties>
  <scm class="hudson.plugins.git.GitSCM" plugin="[email protected]">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <url>https://github.com/zhwenh/dockerfile-jdk-tomcat.git</url>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>*/master</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <browser class="hudson.plugins.git.browser.GitLab">
      <url></url>
      <version>7.11</version>
    </browser>
    <submoduleCfg class="list"/>
    <extensions/>
  </scm>
  <scmCheckoutRetryCount>3</scmCheckoutRetryCount>
  <canRoam>true</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers/>
  <concurrentBuild>false</concurrentBuild>
  <builders>
    <hudson.tasks.Shell>
      <command>docker login -u admin -p admin123 -e [email protected] registry.test.com</command>
    </hudson.tasks.Shell>
    <com.cloudbees.dockerpublish.DockerBuilder plugin="[email protected]">
      <server plugin="[email protected]">
        <uri>unix:///var/run/docker.sock</uri>
      </server>
      <registry plugin="[email protected]">
        <url>http://registry.test.com/v2</url>
      </registry>
      <repoName>zhwenh/tomcat</repoName>
      <noCache>false</noCache>
      <forcePull>true</forcePull>
      <dockerfilePath>./Dockerfile</dockerfilePath>
      <skipBuild>false</skipBuild>
      <skipDecorate>false</skipDecorate>
      <repoTag>2.3.1</repoTag>
      <skipPush>false</skipPush>
      <createFingerprint>true</createFingerprint>
      <skipTagLatest>false</skipTagLatest>
      <buildAdditionalArgs></buildAdditionalArgs>
      <forceTag>true</forceTag>
    </com.cloudbees.dockerpublish.DockerBuilder>
  </builders>
  <publishers>
    <hudson.plugins.emailext.ExtendedEmailPublisher plugin="[email protected]">
      <recipientList>$DEFAULT_RECIPIENTS</recipientList>
      <configuredTriggers>
        <hudson.plugins.emailext.plugins.trigger.FailureTrigger>
          <email>
            <recipientList>$DEFAULT_RECIPIENTS</recipientList>
            <subject>$PROJECT_DEFAULT_SUBJECT</subject>
            <body>$PROJECT_DEFAULT_CONTENT</body>
            <recipientProviders>
              <hudson.plugins.emailext.plugins.recipients.DevelopersRecipientProvider/>
            </recipientProviders>
            <attachmentsPattern></attachmentsPattern>
            <attachBuildLog>false</attachBuildLog>
            <compressBuildLog>false</compressBuildLog>
            <replyTo>$PROJECT_DEFAULT_REPLYTO</replyTo>
            <contentType>project</contentType>
          </email>
        </hudson.plugins.emailext.plugins.trigger.FailureTrigger>
        <hudson.plugins.emailext.plugins.trigger.SuccessTrigger>
          <email>
            <recipientList>$DEFAULT_RECIPIENTS</recipientList>
            <subject>$PROJECT_DEFAULT_SUBJECT</subject>
            <body>$PROJECT_DEFAULT_CONTENT</body>
            <recipientProviders>
              <hudson.plugins.emailext.plugins.recipients.DevelopersRecipientProvider/>
            </recipientProviders>
            <attachmentsPattern></attachmentsPattern>
            <attachBuildLog>false</attachBuildLog>
            <compressBuildLog>false</compressBuildLog>
            <replyTo>$PROJECT_DEFAULT_REPLYTO</replyTo>
            <contentType>project</contentType>
          </email>
        </hudson.plugins.emailext.plugins.trigger.SuccessTrigger>
      </configuredTriggers>
      <contentType>default</contentType>
      <defaultSubject>$DEFAULT_SUBJECT</defaultSubject>
      <defaultContent>$DEFAULT_CONTENT</defaultContent>
      <attachmentsPattern></attachmentsPattern>
      <presendScript>$DEFAULT_PRESEND_SCRIPT</presendScript>
      <attachBuildLog>false</attachBuildLog>
      <compressBuildLog>false</compressBuildLog>
      <replyTo></replyTo>
      <saveOutput>false</saveOutput>
      <disabled>false</disabled>
    </hudson.plugins.emailext.ExtendedEmailPublisher>
  </publishers>
  <buildWrappers>
    <hudson.plugins.ansicolor.AnsiColorBuildWrapper plugin="[email protected]">
      <colorMapName>xterm</colorMapName>
    </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
  </buildWrappers>
</project>'''

        return s

    @gen.coroutine
    def createbasejob(self):

        s = self.getbasejob_config()

        try:
            self.j.create_job(config.JENKINS_BASEJOB, s)
        except Exception as e:
            print e.message
            raise gen.Return(False)
        raise gen.Return(True)