2016-10-28 11 views
6

Có cách nào để có danh sách các bản dựng RUNNING trong Jenkins thông qua một hệ thống Groovy Script không? tôi đã cố gắng Looping qua Chấp hành viên bận rộn, nhưng từ một đối tượng thi hành di chúc, tôi không thể có được xây dựng đối tượng:Làm thế nào để có được một danh sách chạy jenkins xây dựng thông qua kịch bản groovy?

def busyExecutors = Jenkins.instance.computers 
           .collect { 
            c -> c.executors.findAll { it.isBusy() } 
           } 
           .flatten() // reminder: transforms list(list(executor)) into list(executor) 

busyExecutors.each { e -> 
    println('=====print out methods of executor object======='); 
    println e.metaClass.methods*.name.sort().unique(); 

} 

Tôi cũng có thể nhắm mục tiêu công việc mà tôi đang quan tâm đến như vậy:

def item = hudson.model.Hudson.instance.getItem("my_job"); 
println item.metaClass.methods*.name.sort().unique(); 

Nhưng sau đó tôi sẽ phải lặp qua 100s (nếu không nhiều hơn) xây dựng và yêu cầu mỗi xây dựng nếu họ đang chạy.

Phải có cách dễ dàng/tốt hơn để nhận danh sách các bản dựng đang chạy.

Có rất nhiều thông tin về làm thế nào để làm những việc khác nhau thông qua hệ thống Groovy Scripts (một số trong đó tôi đã viết), nhưng tôi không thể tìm ra cách để có được một danh sách các hoạt động xây dựng:

How to get currently running job's node name in jenkins using groovy

https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console

https://gist.github.com/dnozay/e7afcf7a7dd8f73a4e05

How to make a Jenkins/Hudson job surveil some others jobs and decide whether to build or not?

+0

Nhận ra tôi có cùng một vấn đề. Ngoài ra một gotcha là looping thông qua thực thi chỉ bao gồm các nô lệ, không phải là chủ. PS, xem ví dụ của tôi dưới đây. Để có được bản dựng cho công việc bạn có thể sử dụng '_getRuns()' –

Trả lời

2

Tôi tìm thấy một cách để làm điều này mà không cần sử dụng API REST hoặc phân tích cú pháp XML:

Jenkins.instance.getItems().each { job-> 
    job.builds.each { build-> 
    if (build.getResult().equals(null)) { 
     // do stuff here... 
    } 
    } 
} 

Lưu ý rằng điều này sẽ không rơi vào thư mục hoặc Multibranch Đường ống hoặc bất cứ điều gì như thế. Bạn sẽ cần phải tự đi sâu vào các thư mục hoặc pha trộn một số cách để làm nó tự động. Ví dụ, đây là một phiên bản làm việc cho một Multibranch Pipeline:

Jenkins.instance.getItemByFullName(multibranchPipelineProjectName).getItems().each { repository-> 
    repository.getItems().each { branch-> 
    branch.builds.each { build-> 
     if (build.getResult().equals(null)) { 
     // do stuff here ... 
     } 
    } 
    } 
} 

Tôi nghĩ rằng có thể là một phương pháp chính xác hơn để sử dụng hơn build.getResult().equals(null) để xác định xem một xây dựng đang chạy hay không, nhưng tôi đang gặp khó khăn khi tìm tài liệu API tốt, vì vậy tôi không chắc chắn. Đây chỉ là phương pháp đầu tiên mà tôi tìm thấy bằng cách sử dụng đối tượng nội tâm mà làm việc.

Một lần nữa do thiếu tài liệu API, tôi không chắc liệu có sự khác biệt đáng kể giữa Jenkins.instance.getItems() mà tôi đã sử dụng ở đây và Jenkins.instance.getAllItems() được sử dụng trong this answer hay không.

Cuối cùng, lưu ý rằng đây là phương pháp tương đối kém hiệu quả. Nó lặp lại trên mọi bản dựng của mỗi công việc, vì vậy nếu bạn lưu một lịch sử lâu dài của các bản dựng (cài đặt mặc định là lưu lịch sử chỉ có 10 bản dựng cho mỗi công việc) hoặc có hàng nghìn công việc, việc này có thể mất một lúc để chạy. Xem How do I Efficiently list **All** currently running jobs on Jenkins using Groovy để biết câu hỏi yêu cầu cách thực hiện tác vụ này hiệu quả hơn.

+0

Điều đó hoạt động! Wow! Cám ơn rất nhiều! Tôi không biết bạn làm theo cách đó! – grayaii

1

Bạn có thể sử dụng API REST để lấy danh sách các bản dựng đang chạy. Sử dụng url sau:

http://myjenkins/jenkins/computer/api/xml?depth=1

Bạn sẽ nhận được câu trả lời tiếp theo, trong đó có yếu tố <executor>. Chỉ bản dựng đang chạy có phần tử <url> bên trong <executor>. Cũng lưu ý rằng chạy xây dựng<idle>false</idle> giá trị:

<computerSet> 
    <busyExecutors>1</busyExecutors> 
    <computer> 
     ... 
     <executor> 
      <idle>true</idle> 
      <likelyStuck>false</likelyStuck> 
      <number>0</number> 
      <progress>-1</progress> 
     </executor> 
     <executor> 
      <currentExecutable> 
       <number>328</number> 
       <!-- This is the url from the current running build --> 
       <url>http://myJenkins/jenkins/job/someJob/328/</url>    
      </currentExecutable> 
      <currentWorkUnit/> 
      <idle>false</idle> 
      <likelyStuck>false</likelyStuck> 
      <number>1</number> 
      <progress>24</progress> 
     </executor> 
     ... 
    </computer> 
<computerSet> 

Do đó sử dụng API REST với một XPath cho url để có được chỉ chạy bản xây dựng (lưu ý rằng &wrapper tham số là tên của phần tử xml gốc để tránh sai sót khi XPath không phù hợp hoặc trả về nhiều hơn một nút):

http://myJenkins/jenkins/computer/api/xml?depth=1&xpath=//url&wrapper=builds 

Bạn sẽ nhận được một cái gì đó như:

<builds> 
    <url> 
http://myJenkins/jenkins/job/someJob/300/ 
    </url> 
    <url> 
http://myJenkins/jenkins/job/another/332/ 
    </url> 
</builds> 

Vì vậy, trong Groovy bạn có thể GET REST API, phân tích Xml trở lại và sau đó áp dụng một regex để mỗi <url> để lấy dữ liệu từ hoạt động xây dựng:

// get the xml from the rest api 
def builds = 'http://myJenkins/jenkins/computer/api/xml?depth=1&xpath=//url&wrapper=builds'.toURL().text 
// parse the xml result 
def xml = new XmlSlurper().parseText(builds) 
// for each url get the job name 
def jobNames = xml.url.collect{ url -> 
    // regex to get the jobName and a build number 
    def group = (url =~ /.*\/job\/([^\/]+)\/(\d+)/) 
    println group[0] // [http://myJenkins/jenkins/job/someJob/300, someJob, 300] 
    def jobName = group[0][1] 
    return jobName 
    // to get the build number 
    // def buildNr = group[0][2] 
} 
println jobNames 
1

Đây không phải là đặc biệt hiệu quả (nhưng MUCH hiệu quả hơn việc sử dụng API). Nó sẽ in ra tất cả các bản đang chạy với một liên kết HTML. Có thể chạy trong bảng điều khiển tập lệnh hoặc thông qua tập lệnh.

def now = new Date() // Get the current time 
// Get a list of all running jobs 
def buildingJobs = Jenkins.instance.getAllItems(Job.class).findAll { 
    it.isBuilding() } 

buildingJobs.each { job-> 
    // Enumerate all runs 
    allRuns = job._getRuns() 
    allRuns.each { item -> 
     // If NOT currently building... check the next build for this job 
     if (!item.isBuilding()) return 

     // Access and calculate time information for this build. 
     def startedAt = new Date(item.getStartTimeInMillis()) 
     def duration_mins = ((now.getTime() - item.getStartTimeInMillis())/60000).intValue() 

     estDurationMins = (item.getEstimatedDuration()/60000).intValue() 
     String jobname = item.getUrl() 
     jobname = jobname.replaceAll('job/', '') // Strip redundant folder info. 

     println "${duration_mins.toString().padLeft(5)}/" + 
      "${estDurationMins.toString().padLeft(4)} - " + 
      "<a href=${baseURL}${item.getUrl()}>${jobname}</a>" 
    } 
} 
+0

Xem https://stackoverflow.com/questions/44988884/how-do-i-efficiently-list-all-currently-running-jobs-on-jenkins -using-groovy cho một câu hỏi tương tự. –

Các vấn đề liên quan