diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..71b25de5fede2f693026268b69839c15b95465dd --- /dev/null +++ b/.gitattributes @@ -0,0 +1,39 @@ +# Handle line endings automatically for files detected as text +# and leave all files detected as binary untouched. +* text=auto + +# +# The above will handle all files NOT found below +# +# These files are text and should be normalized (Convert crlf => lf) +*.css text +*.groovy text +*.htm text +*.html text +*.java text +*.js text +*.json text +*.jelly text +*.jellytag text +*.less text +*.properties text +*.rb text +*.sh text +*.txt text +*.xml text + +# These files are binary and should be left untouched +# (binary is a macro for -text -diff) +*.class binary +*.gz binary +*.tgz binary +*.ear binary +*.gif binary +*.hpi binary +*.ico binary +*.jar binary +*.jpg binary +*.jpeg binary +*.png binary +*.war binary +*.zip binary diff --git a/.gitignore b/.gitignore index edb353a62a64f1d0081206585a1e63101d579717..60ba89065c90d09f0cc1ea8935b0bf08b691b0e9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,10 @@ build # vim *~ +*.swp + +# ctags +tags # OS X .DS_Store diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 0000000000000000000000000000000000000000..e93a5b43ee1cd1968d2d971e1486071f4fa1fe0f --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1 @@ +-Xmx800m diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7bd3f7a8f7b30738a6187c17454f431a84f6e45f..7a2d5e0c53ec6c9a1dcaaedf21fada835c68ea8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,3 @@ # Contributing to Jenkins -For information on contributing to Jenkins, check out the https://wiki.jenkins-ci.org/display/JENKINS/contributing and https://wiki.jenkins-ci.org/display/JENKINS/Extend+Jenkins wiki pages over at the official https://wiki.jenkins-ci.org . They will help you get started with contributing to Jenkins. +For information on contributing to Jenkins, check out the https://wiki.jenkins-ci.org/display/JENKINS/Beginners+Guide+to+Contributing and https://wiki.jenkins-ci.org/display/JENKINS/Extend+Jenkins wiki pages over at the official https://wiki.jenkins-ci.org . They will help you get started with contributing to Jenkins. diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000000000000000000000000000000000..5fdd562b8c910c95816fa05d314326b927ef41ee --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,78 @@ +#!/usr/bin/env groovy + +/* + * This Jenkinsfile is intended to run on https://ci.jenkins-ci.org and may fail anywhere else. + * It makes assumptions about plugins being installed, labels mapping to nodes that can build what is needed, etc. + * + * The required labels are "java" and "docker" - "java" would be any node that can run Java builds. It doesn't need + * to have Java installed, but some setups may have nodes that shouldn't have heavier builds running on them, so we + * make this explicit. "docker" would be any node with docker installed. + */ + +// TEST FLAG - to make it easier to turn on/off unit tests for speeding up access to later stuff. +def runTests = true + +// Only keep the 10 most recent builds. +properties([[$class: 'jenkins.model.BuildDiscarderProperty', strategy: [$class: 'LogRotator', + numToKeepStr: '50', + artifactNumToKeepStr: '20']]]) + +node('java') { + timestamps { + // First stage is actually checking out the source. Since we're using Multibranch + // currently, we can use "checkout scm". + stage('Checkout') { + checkout scm + } + + // Now run the actual build. + stage("Build / Test") { + timeout(time: 180, unit: 'MINUTES') { + // See below for what this method does - we're passing an arbitrary environment + // variable to it so that JAVA_OPTS and MAVEN_OPTS are set correctly. + withMavenEnv(["JAVA_OPTS=-Xmx1536m -Xms512m -XX:MaxPermSize=1024m", + "MAVEN_OPTS=-Xmx1536m -Xms512m -XX:MaxPermSize=1024m"]) { + // Actually run Maven! + // The -Dmaven.repo.local=${pwd()}/.repository means that Maven will create a + // .repository directory at the root of the build (which it gets from the + // pwd() Workflow call) and use that for the local Maven repository. + sh "mvn -Pdebug -U clean install ${runTests ? '-Dmaven.test.failure.ignore=true' : '-DskipTests'} -V -B -Dmaven.repo.local=${pwd()}/.repository" + } + } + } + + + // Once we've built, archive the artifacts and the test results. + stage('Archive Artifacts / Test Results') { + archiveArtifacts artifacts: '**/target/*.jar, **/target/*.war, **/target/*.hpi', + fingerprint: true + if (runTests) { + junit healthScaleFactor: 20.0, testResults: '**/target/surefire-reports/*.xml' + } + } + } +} + +// This method sets up the Maven and JDK tools, puts them in the environment along +// with whatever other arbitrary environment variables we passed in, and runs the +// body we passed in within that environment. +void withMavenEnv(List envVars = [], def body) { + // The names here are currently hardcoded for my test environment. This needs + // to be made more flexible. + // Using the "tool" Workflow call automatically installs those tools on the + // node. + String mvntool = tool name: "mvn", type: 'hudson.tasks.Maven$MavenInstallation' + String jdktool = tool name: "jdk8", type: 'hudson.model.JDK' + + // Set JAVA_HOME, MAVEN_HOME and special PATH variables for the tools we're + // using. + List mvnEnv = ["PATH+MVN=${mvntool}/bin", "PATH+JDK=${jdktool}/bin", "JAVA_HOME=${jdktool}", "MAVEN_HOME=${mvntool}"] + + // Add any additional environment variables. + mvnEnv.addAll(envVars) + + // Invoke the body closure we're passed within the environment we've created. + withEnv(mvnEnv) { + body.call() + } +} diff --git a/README.md b/README.md index 4ecfdb2c3738bd3ca3f83b442ecbb8b315e1e29c..501778372da7f1ab5613f35365efdb50a89d5279 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,32 @@ [![][ButlerImage]][website] # About -In a nutshell, Jenkins CI is the leading open-source continuous integration server. Built with Java, it provides over 1000 plugins to support building and testing virtually any project. +In a nutshell, Jenkins is the leading open-source automation server. +Built with Java, it provides over 1000 plugins to support automating virtually anything, +so that humans can actually spend their time doing things machines cannot. + +# What to Use Jenkins for and When to Use It + +Use Jenkins to automate your development workflow so you can focus on work that matters most. Jenkins is commonly used for: + +- Building projects +- Running tests to detect bugs and other issues as soon as they are introduced +- Static code analysis +- Deployment + +Execute repetitive tasks, save time, and optimize your development process with Jenkins. # Downloads Non-source downloads such as WAR files and several Linux packages can be found on our [Mirrors]. # Source -Our latest and greatest source of Jenkins CI can be found on [GitHub]. Fork us! +Our latest and greatest source of Jenkins can be found on [GitHub]. Fork us! # Contributing to Jenkins Follow [contributing](CONTRIBUTING.md) file. # News and Website -All information about Jenkins CI can be found on our [website]. Follow us on Twitter [@jenkinsci]. +All information about Jenkins can be found on our [website]. Follow us on Twitter [@jenkinsci]. # License Jenkins is **licensed** under the **[MIT License]**. The terms of the license are as follows: @@ -40,12 +53,12 @@ Jenkins is **licensed** under the **[MIT License]**. The terms of the license ar OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -[ButlerImage]: http://jenkins-ci.org/sites/default/files/jenkins_logo.png +[ButlerImage]: https://jenkins.io/sites/default/files/jenkins_logo.png [MIT License]: https://github.com/jenkinsci/jenkins/raw/master/LICENSE.txt [Mirrors]: http://mirrors.jenkins-ci.org [GitHub]: https://github.com/jenkinsci/jenkins -[website]: http://jenkins-ci.org -[@jenkinsci]: http://twitter.com/jenkinsci +[website]: https://jenkins.io/ +[@jenkinsci]: https://twitter.com/jenkinsci [Contributing]: https://wiki.jenkins-ci.org/display/JENKINS/contributing [Extend Jenkins]: https://wiki.jenkins-ci.org/display/JENKINS/Extend+Jenkins [wiki]: https://wiki.jenkins-ci.org diff --git a/changelog.html b/changelog.html index aa9b438a9812a3274acf63059bcbba1e87e2efe7..4b8502c6fdd4e2e4a37204a4363054e14c21d332 100644 --- a/changelog.html +++ b/changelog.html @@ -20,30 +20,31 @@ Some tips: Changelog - + - +
Legend: - major RFEmajor enhancement RFEenhancement - major bugmajor bug fix bugbug fix + major RFEmajor enhancement RFEenhancement + major bugmajor bug fix bugbug fix xxxxx
+ @@ -55,2644 +56,3134 @@ Upcoming changes -

What's new in 1.615 (2015/05/25)

+

What's new in 2.36 (2016/12/11)

-

What's new in 1.614 (2015/05/17)

+

What's new in 2.35 (2016/12/04)

-

What's new in 1.613 (2015/05/10)

+

What's new in 2.34 (2016/11/27)

-

What's new in 1.612 (2015/05/03)

+

What's new in 2.33 (2016/11/20)

-

What's new in 1.611 (2015/04/26)

+

What's new in 2.32 (2016/11/16)

+

What's new in 2.31 (2016/11/13)

+ -

What's new in 1.610 (2015/04/19)

+

What's new in 2.30 (2016/11/07)

-

What's new in 1.609 (2015/04/12)

+

What's new in 2.29 (2016/11/06)

+

+ Warning! This release is not recommended for use due to + issue 39555 + and issue 39414. + We are working on the out-of-order release (discussion). +

+ +

What's new in 2.28 (2016/10/30)

-

What's new in 1.608 (2015/04/05)

+

What's new in 2.27 (2016/10/23)

-

What's new in 1.607 (2015/03/30)

+

What's new in 2.26 (2016/10/17)

+ +

What's new in 2.25 (2016/10/09)

+ +

What's new in 2.24 (2016/10/02)

+ +

What's new in 2.23 (2016/09/18)

+ +

What's new in 2.22 (2016/09/11)

+ +

What's new in 2.21 (2016/09/04)

+ +

What's new in 2.20 (2016/08/28)

+ +

What's new in 2.19 (2016/08/21)

+ +

What's new in 2.18 (2016/08/15)

+ +

What's new in 2.17 (2016/08/05)

+

What's new in 2.16 (2016/07/31)

+ +

What's new in 2.15 (2016/07/24)

+ +

What's new in 2.14 (2016/07/17)

+ -

What's new in 1.606 (2015/03/23)

+

What's new in 2.13 (2016/07/10)

-

What's new in 1.605 (2015/03/16)

- -

What's new in 1.604 (2015/03/15)

+

What's new in 2.12 (2016/07/05)

-

What's new in 1.602 (2015/03/08)

+

What's new in 2.11 (2016/06/26)

-

What's new in 1.601 (2015/03/03)

+

What's new in 2.10 (2016/06/19)

-

What's new in 1.600 (2015/02/28)

+

What's new in 2.9 (2016/06/13)

-

What's new in 1.599 (2015/02/16)

+

What's new in 2.8 (2016/06/05)

-

What's new in 1.598 (2015/01/25)

+

What's new in 2.7 (2016/05/29)

+ +

What's new in 2.6 (2016/05/22)

+ +

What's new in 2.5 (2016/05/16)

+

What's new in 2.4 (2016/05/15)

+ -

What's new in 1.597 (2015/01/19)

- +

What's new in 2.3 (2016/05/11)

+ +

What's new in 2.2 (2016/05/08)

+ +

What's new in 2.1 (2016/05/01)

+ + + +

What's new in 2.0 (2016/04/20)

+
+ More detailed information about the new features in Jenkins 2.0 on the overview page. +
+ + +

What's new in 1.656 (2016/04/03)

+ +

What's new in 1.655 (2016/03/27)

+ +

What's new in 1.654 (2016/03/21)

+ +

What's new in 1.653 (2016/03/13)

+ +

What's new in 1.652 (2016/03/06)

+ +

What's new in 1.651 (2016/02/28)

+ +

What's new in 1.650 (2016/02/24)

+ +

What's new in 1.649 (2016/02/21)

+ +

What's new in 1.648 (2016/02/17)

+ +

What's new in 1.647 (2016/02/04)

+ +

What's new in 1.646 (2016/01/25)

+ +

What's new in 1.645 (2016/01/18)

+ -

What's new in 1.596 (2015/01/04)

+

What's new in 1.644 (2016/01/10)

-

What's new in 1.595 (2014/12/21)

+

What's new in 1.643 (2015/12/20)

-

What's new in 1.594 (2014/12/14)

+

What's new in 1.642 (2015/12/13)

-

What's new in 1.593 (2014/12/07)

+

What's new in 1.641 (2015/12/09)

-

What's new in 1.592 (2014/11/30)

+

What's new in 1.640 (2015/12/07)

-

What's new in 1.591 (2014/11/25)

+

What's new in 1.639 (2015/11/29)

-

What's new in 1.590 (2014/11/16)

+

What's new in 1.638 (2015/11/11)

-

What's new in 1.589 (2014/11/09)

+

What's new in 1.637 (2015/11/08)

-

What's new in 1.588 (2014/11/02)

+

What's new in 1.636 (2015/11/01)

-

What's new in 1.587 (2014/10/29)

+

What's new in 1.635 (2015/10/25)

-

What's new in 1.586 (2014/10/26)

+

What's new in 1.634 (2015/10/18)

+

What's new in 1.633 (2015/10/11)

+ -

What's new in 1.585 (2014/10/19)

+

What's new in 1.632 (2015/10/05)

-

What's new in 1.584 (2014/10/12)

+

What's new in 1.631 (2015/09/27)

-

What's new in 1.583 (2014/10/01)

+

What's new in 1.630 (2015/09/20)

-

What's new in 1.582 (2014/09/28)

+

What's new in 1.629 (2015/09/15)

+

What's new in 1.628 (2015/09/06)

+ +

What's new in 1.627 (2015/08/30)

+ +

What's new in 1.626 (2015/08/23)

+ +

What's new in 1.625 (2015/08/17)

+ -

What's new in 1.581 (2014/09/21)

+

What's new in 1.624 (2015/08/09)

+

What's new in 1.623 (2015/08/02)

+

No notable changes in this release.

+

What's new in 1.622 (2015/07/27)

+ +

What's new in 1.621 (2015/07/19)

+ -

What's new in 1.580 (2014/09/14)

+

What's new in 1.620 (2015/07/12)

+

What's new in 1.619 (2015/07/05)

+ -

What's new in 1.579 (2014/09/06)

+

What's new in 1.618 (2015/06/29)

-

What's new in 1.578 (2014/08/31)

+

What's new in 1.617 (2015/06/07)

-

What's new in 1.577 (2014/08/24)

+

What's new in 1.616 (2015/05/31)

+

What's new in 1.615 (2015/05/25)

+ -

What's new in 1.576 (2014/08/18)

- -

What's new in 1.575 (2014/08/10)

+

What's new in 1.614 (2015/05/17)

-

What's new in 1.574 (2014/07/27)

+

What's new in 1.613 (2015/05/10)

-

What's new in 1.573 (2014/07/20)

+

What's new in 1.612 (2015/05/03)

-

What's new in 1.572 (2014/07/13)

+

What's new in 1.611 (2015/04/26)

-

What's new in 1.571 (2014/07/07)

+

What's new in 1.610 (2015/04/19)

-

What's new in 1.570 (2014/06/29)

+

What's new in 1.609 (2015/04/12)

+

What's new in 1.608 (2015/04/05)

+ -

What's new in 1.569 (2014/06/23)

+

What's new in 1.607 (2015/03/30)

-

What's new in 1.568 (2014/06/15)

- +

What's new in 1.606 (2015/03/23)

+ -

What's new in 1.567 (2014/06/09)

+

What's new in 1.605 (2015/03/16)

-

What's new in 1.566 (2014/06/01)

+

What's new in 1.604 (2015/03/15)

-

What's new in 1.565 (2014/05/26)

+

What's new in 1.602 (2015/03/08)

-

What's new in 1.564 (2014/05/19)

+

What's new in 1.601 (2015/03/03)

-

What's new in 1.563 (2014/05/11)

+

What's new in 1.600 (2015/02/28)

-

What's new in 1.562 (2014/05/03)

- -

What's new in 1.561 (2014/04/27)

+

What's new in 1.599 (2015/02/16)

+

What's new in 1.598 (2015/01/25)

+ -

What's new in 1.560 (2014/04/20)

+

What's new in 1.597 (2015/01/19)

-

What's new in 1.559 (2014/04/13)

+

What's new in 1.596 (2015/01/04)

-

What's new in 1.558 (2014/04/06)

+

What's new in 1.595 (2014/12/21)

+

What's new in 1.594 (2014/12/14)

+ +

What's new in 1.593 (2014/12/07)

+ -

What's new in 1.557 (2014/03/31)

+

What's new in 1.592 (2014/11/30)

+

What's new in 1.591 (2014/11/25)

+ +

What's new in 1.590 (2014/11/16)

+ -

What's new in 1.556 (2014/03/23)

+

What's new in 1.589 (2014/11/09)

-

What's new in 1.555 (2014/03/16)

+

What's new in 1.588 (2014/11/02)

-

What's new in 1.554 (2014/03/09)

+

What's new in 1.587 (2014/10/29)

-

What's new in 1.553 (2014/03/02)

+

What's new in 1.586 (2014/10/26)

+

What's new in 1.585 (2014/10/19)

+ -

What's new in 1.552 (2014/02/24)

+

What's new in 1.584 (2014/10/12)

-

What's new in 1.551 (2014/02/14)

+

What's new in 1.583 (2014/10/01)

+

What's new in 1.582 (2014/09/28)

+ -

What's new in 1.550 (2014/02/09)

+

What's new in 1.581 (2014/09/21)

-

What's new in 1.549 (2014/01/25)

+

What's new in 1.580 (2014/09/14)

-

What's new in 1.548 (2014/01/20)

+

What's new in 1.579 (2014/09/06)

-

What's new in 1.547 (2014/01/12)

+

What's new in 1.578 (2014/08/31)

-

What's new in 1.546 (2014/01/06)

+

What's new in 1.577 (2014/08/24)

-

What's new in 1.545 (2013/12/31)

- +

What's new in 1.576 (2014/08/18)

+ +

What's new in 1.575 (2014/08/10)

+ -

What's new in 1.544 (2013/12/15)

+

What's new in 1.574 (2014/07/27)

-

What's new in 1.543 (2013/12/10)

+

What's new in 1.573 (2014/07/20)

-

What's new in 1.542 (2013/12/02)

+

What's new in 1.572 (2014/07/13)

-

What's new in 1.541 (2013/11/24)

- -

What's new in 1.540 (2013/11/17)

+

What's new in 1.571 (2014/07/07)

-

What's new in 1.539 (2013/11/11)

- -

What's new in 1.538 (2013/11/03)

+

What's new in 1.570 (2014/06/29)

-

What's new in 1.537 (2013/10/27)

- -

What's new in 1.536 (2013/10/20)

- -

What's new in 1.535 (2013/10/14)

- -

What's new in 1.534 (2013/10/07)

- -

What's new in 1.533 (2013/09/29)

- -

What's new in 1.532 (2013/09/23)

+

What's new in 1.569 (2014/06/23)

-

What's new in 1.531 (2013/09/16)

- -

What's new in 1.530 (2013/09/09)

+

What's new in 1.568 (2014/06/15)

-

What's new in 1.529 (2013/08/26)

- -

What's new in 1.528 (2013/08/18)

+

What's new in 1.567 (2014/06/09)

-

What's new in 1.527 (2013/08/12)

+

What's new in 1.566 (2014/06/01)

-

What's new in 1.526 (2013/08/05)

+

What's new in 1.565 (2014/05/26)

-

What's new in 1.525 (2013/07/29)

-

Same as 1.524; botched release.

-

What's new in 1.524 (2013/07/23)

+

What's new in 1.564 (2014/05/19)

-

What's new in 1.523 (2013/07/14)

+

What's new in 1.563 (2014/05/11)

-

What's new in 1.522 (2013/07/06)

+

What's new in 1.562 (2014/05/03)

-

What's new in 1.521 (2013/07/02)

+

What's new in 1.561 (2014/04/27)

-

What's new in 1.520 (2013/06/25)

- -

What's new in 1.519 (2013/06/17)

- -

What's new in 1.518 (2013/06/11)

- -

What's new in 1.517 (2013/06/02)

- -

What's new in 1.516 (2013/05/27)

- -

What's new in 1.515 (2013/05/18)

- -

What's new in 1.514 (2013/05/01)

+

What's new in 1.560 (2014/04/20)

-

What's new in 1.513 (2013/04/28)

- -

What's new in 1.512 (2013/04/21)

- -

What's new in 1.511 (2013/04/14)

+

What's new in 1.559 (2014/04/13)

-

What's new in 1.510 (2013/04/06)

- -

What's new in 1.509 (2013/04/02)

+

What's new in 1.558 (2014/04/06)

-

What's new in 1.508 (2013/03/25)

- -

What's new in 1.507 (2013/03/24)

+

What's new in 1.557 (2014/03/31)

-

What's new in 1.506 (2013/03/17)

+

What's new in 1.556 (2014/03/23)

-

What's new in 1.505 (2013/03/10)

+

What's new in 1.555 (2014/03/16)

-

What's new in 1.504 (2013/03/03)

+

What's new in 1.554 (2014/03/09)

-

What's new in 1.503 (2013/02/26)

+

What's new in 1.553 (2014/03/02)

-

What's new in 1.502 (2013/02/16)

+

What's new in 1.552 (2014/02/24)

-

What's new in 1.501 (2013/02/10)

+

What's new in 1.551 (2014/02/14)

-

What's new in 1.500 (2013/01/26)

- +

What's new in 1.550 (2014/02/09)

+ +

What's new in 1.549 (2014/01/25)

+ -

What's new in 1.499 (2013/01/13)

+

What's new in 1.548 (2014/01/20)

-

What's new in 1.498 (2013/01/07)

+

What's new in 1.547 (2014/01/12)

-

What's new in 1.497 (2013/01/06)

+

What's new in 1.546 (2014/01/06)

-Older changelogs can be found in a separate file +Older changelogs can be found in a separate file diff --git a/cli/pom.xml b/cli/pom.xml index 34798c2de996809b5ca08f7f0a3c780115d0fc1a..e70857e1b1036e0e7fdc7fd2d6950c4ed51fe1f2 100644 --- a/cli/pom.xml +++ b/cli/pom.xml @@ -5,7 +5,7 @@ org.jenkins-ci.main pom - 1.616-SNAPSHOT + 2.37-SNAPSHOT cli @@ -24,6 +24,11 @@ powermock-api-mockito test + + org.kohsuke + access-modifier-annotation + 1.7 + commons-codec commons-codec @@ -42,7 +47,7 @@ org.jvnet.localizer localizer - 1.23 + 1.24 org.jenkins-ci @@ -88,10 +93,15 @@ Messages.properties target/generated-sources/localizer + true + + org.codehaus.mojo + findbugs-maven-plugin + diff --git a/cli/src/main/java/hudson/cli/CLI.java b/cli/src/main/java/hudson/cli/CLI.java index de2d2bd7950a3a7a73993dc6581213a3f4ca01ca..c11fcd546a3af0297e9d059fc0f90bf1946c78b2 100644 --- a/cli/src/main/java/hudson/cli/CLI.java +++ b/cli/src/main/java/hudson/cli/CLI.java @@ -25,6 +25,7 @@ package hudson.cli; import hudson.cli.client.Messages; import hudson.remoting.Channel; +import hudson.remoting.NamingThreadFactory; import hudson.remoting.PingThread; import hudson.remoting.Pipe; import hudson.remoting.RemoteInputStream; @@ -80,7 +81,7 @@ import static java.util.logging.Level.*; * * @author Kohsuke Kawaguchi */ -public class CLI { +public class CLI implements AutoCloseable { private final ExecutorService pool; private final Channel channel; private final CliEntryPoint entryPoint; @@ -121,7 +122,7 @@ public class CLI { if(!url.endsWith("/")) url+='/'; ownsPool = exec==null; - pool = exec!=null ? exec : Executors.newCachedThreadPool(); + pool = exec!=null ? exec : Executors.newCachedThreadPool(new NamingThreadFactory(Executors.defaultThreadFactory(), "CLI.pool")); Channel _channel; try { @@ -131,13 +132,7 @@ public class CLI { try { _channel = connectViaHttp(url); } catch (IOException e2) { - try { // Java 7: e.addSuppressed(e2); - Throwable.class.getMethod("addSuppressed", Throwable.class).invoke(e, e2); - } catch (NoSuchMethodException _ignore) { - // Java 6 - } catch (Exception _huh) { - LOGGER.log(Level.SEVERE, null, _huh); - } + e.addSuppressed(e2); throw e; } } diff --git a/cli/src/main/java/hudson/cli/CliPort.java b/cli/src/main/java/hudson/cli/CliPort.java index 1507704d9c0e79dc40c88aa25d8bbe369c159e2a..8faab7de41bee0c88fa90cdaa0cbb8c9599f6a97 100644 --- a/cli/src/main/java/hudson/cli/CliPort.java +++ b/cli/src/main/java/hudson/cli/CliPort.java @@ -11,7 +11,7 @@ import java.security.spec.X509EncodedKeySpec; /** * @author Kohsuke Kawaguchi */ -final class CliPort { +public final class CliPort { /** * The TCP endpoint to talk to. */ @@ -27,7 +27,7 @@ final class CliPort { */ final String identity; - CliPort(InetSocketAddress endpoint, String identity, int version) { + public CliPort(InetSocketAddress endpoint, String identity, int version) { this.endpoint = endpoint; this.identity = identity; this.version = version; diff --git a/cli/src/main/java/hudson/cli/Connection.java b/cli/src/main/java/hudson/cli/Connection.java index 165a6deb7e6af83adf0ccda8cbe86a474414a65e..1c1ada471fdbaaded6f2203ec130a7e69a671a6f 100644 --- a/cli/src/main/java/hudson/cli/Connection.java +++ b/cli/src/main/java/hudson/cli/Connection.java @@ -23,6 +23,8 @@ */ package hudson.cli; +import hudson.remoting.ClassFilter; +import hudson.remoting.ObjectInputStreamEx; import hudson.remoting.SocketChannelStream; import org.apache.commons.codec.binary.Base64; @@ -107,7 +109,8 @@ public class Connection { * Receives an object sent by {@link #writeObject(Object)} */ public T readObject() throws IOException, ClassNotFoundException { - ObjectInputStream ois = new ObjectInputStream(in); + ObjectInputStream ois = new ObjectInputStreamEx(in, + getClass().getClassLoader(), ClassFilter.DEFAULT); return (T)ois.readObject(); } diff --git a/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java b/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java index 941dc4b0ae532f71ddd00c61e09b422a138d689a..abde9bb2022664eda42f5b28d91e9d58fbcfe04f 100644 --- a/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java +++ b/cli/src/main/java/hudson/cli/FullDuplexHttpStream.java @@ -44,7 +44,7 @@ public class FullDuplexHttpStream { private static String basicAuth(String userInfo) { if (userInfo != null) - return "Basic "+new String(new Base64().encodeBase64(userInfo.getBytes())); + return "Basic "+new String(Base64.encodeBase64(userInfo.getBytes())); return null; } diff --git a/cli/src/main/java/hudson/cli/PrivateKeyProvider.java b/cli/src/main/java/hudson/cli/PrivateKeyProvider.java index 834bb7234250d7d7bac2bd424aba5aa670be0fda..5fe402afc69d3cc6b0b1ea21377b7ffe896baa63 100644 --- a/cli/src/main/java/hudson/cli/PrivateKeyProvider.java +++ b/cli/src/main/java/hudson/cli/PrivateKeyProvider.java @@ -127,15 +127,11 @@ public class PrivateKeyProvider { } private static String readPemFile(File f) throws IOException{ - FileInputStream is = new FileInputStream(f); - try { - DataInputStream dis = new DataInputStream(is); + try (FileInputStream is = new FileInputStream(f); + DataInputStream dis = new DataInputStream(is)) { byte[] bytes = new byte[(int) f.length()]; dis.readFully(bytes); - dis.close(); return new String(bytes); - } finally { - is.close(); } } diff --git a/cli/src/main/resources/hudson/cli/client/Messages_bg.properties b/cli/src/main/resources/hudson/cli/client/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..187d7208d6bea45ac5ed62fbac8dac35cc469937 --- /dev/null +++ b/cli/src/main/resources/hudson/cli/client/Messages_bg.properties @@ -0,0 +1,44 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +CLI.Usage=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434 \u043d\u0430 Jenkins\n\ + \u0423\u043f\u043e\u0442\u0440\u0435\u0431\u0430: java -jar jenkins-cli.jar [-s \u0410\u0414\u0420\u0415\u0421] \u041a\u041e\u041c\u0410\u041d\u0414\u0410 [\u041e\u041f\u0426\u0418\u042f\u2026] \u0410\u0420\u0413\u0423\u041c\u0415\u041d\u0422\u2026\n\ + \u041e\u043f\u0446\u0438\u0438:\n\ + -s \u0410\u0414\u0420\u0415\u0421 : \u0430\u0434\u0440\u0435\u0441\u044a\u0442 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430 (\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e \u0441\u0435 \u0432\u0437\u0438\u043c\u0430 \u043e\u0442 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0430\u0442\u0430 \u043d\u0430\n\ + \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u201eJENKINS_URL\u201c)\n\ + -i \u041a\u041b\u042e\u0427 : \u0447\u0430\u0441\u0442\u0435\u043d \u043a\u043b\u044e\u0447 \u0437\u0430 SSH \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f\n\ + -p \u0425\u041e\u0421\u0422:\u041f\u041e\u0420\u0422 : \u0445\u043e\u0441\u0442 \u0438 \u043f\u043e\u0440\u0442 \u0437\u0430 \u0441\u044a\u0440\u0432\u044a\u0440-\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u043f\u043e HTTP \u0437\u0430 \u0442\u0443\u043d\u0435\u043b \u043f\u043e HTTPS.\n\ + \u0417\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f: http://jenkins-ci.org/https-proxy-tunnel\n\ + -noCertificateCheck : \u0431\u0435\u0437 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u0437\u0430 HTTPS (\u0412\u041d\u0418\u041c\u0410\u041d\u0418\u0415!)\n\ + -noKeyAuth : \u0431\u0435\u0437 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0441 \u0447\u0430\u0441\u0442\u0435\u043d \u043a\u043b\u044e\u0447 \u0437\u0430 SSH, \u043e\u043f\u0446\u0438\u044f\u0442\u0430 \u0435\n\ + \u043d\u0435\u0441\u044a\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430 \u0441 \u043e\u043f\u0446\u0438\u044f\u0442\u0430 \u201e-i\u201c\n\n\ + \u041d\u0430\u043b\u0438\u0447\u043d\u0438\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0438 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430. \u0417\u0430 \u0438\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0441\u043f\u0438\u0441\u044a\u043a\u0430\n\ + \u0438\u043c \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201ehelp\u201c.\n +CLI.NoURL=\ + \u0410\u0434\u0440\u0435\u0441\u044a\u0442 \u043d\u0435 \u0435 \u0437\u0430\u0434\u0430\u0434\u0435\u043d \u043d\u0438\u0442\u043e \u0447\u0440\u0435\u0437 \u043e\u043f\u0446\u0438\u044f\u0442\u0430 \u201e-s\u201c, \u043d\u0438\u0442\u043e \u0447\u0440\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0430\u0442\u0430 \u043d\u0430\ + \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u201eJENKINS_URL\u201c. +CLI.VersionMismatch=\ + \u0412\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430\u0442. \u0422\u0430\u0437\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u0430 \u0437\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0435\u043d \u0440\u0435\u0434 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0438 \u0441 \u0442\u043e\u0437\u0438 \u0441\u044a\u0440\u0432\u044a\u0440\ + Jenkins. +CLI.NoSuchFileExists=\ + \u0422\u0430\u043a\u044a\u0432 \u0444\u0430\u0439\u043b \u043d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430: {0} diff --git a/cli/src/main/resources/hudson/cli/client/Messages_de.properties b/cli/src/main/resources/hudson/cli/client/Messages_de.properties index aa7972afa42fbb6dd99737ad46b7f3e32c7e6217..55769d64ded51906132d5ff94ef67e36aa9c66d1 100644 --- a/cli/src/main/resources/hudson/cli/client/Messages_de.properties +++ b/cli/src/main/resources/hudson/cli/client/Messages_de.properties @@ -3,11 +3,12 @@ CLI.Usage=Jenkins Kommandozeilenschnittstelle (Jenkins CLI)\n\ Verwendung: java -jar jenkins-cli.jar [-s URL] command [opts...] args...\n\ Optionen:\n\ -s URL : URL des Hudson-Servers (Wert der Umgebungsvariable JENKINS_URL ist der Vorgabewert)\n\ - -i KEY : Datei mit privatem SSH-Schlssel zur Authentisierung\n\ - -p HOST\:PORT : HTTP-Proxy-Host und -Port fr HTTPS-Proxy-Tunnel. Siehe http://jenkins-ci.org/https-proxy-tunnel\n\ - -noCertificateCheck : berspringt die Zertifikatsprfung bei HTTPS. Bitte mit Vorsicht einsetzen.\n\ + -i KEY : Datei mit privatem SSH-Schl\u00fcssel zur Authentisierung\n\ + -p HOST\:PORT : HTTP-Proxy-Host und -Port f\u00fcr HTTPS-Proxy-Tunnel. Siehe http://jenkins-ci.org/https-proxy-tunnel\n\ + -noCertificateCheck : \u00dcberspringt die Zertifikatspr\u00fcfung bei HTTPS. Bitte mit Vorsicht einsetzen.\n\ + -noKeyAuth : \u00dcberspringt die Authentifizierung mit einem privaten SSH-Schl\u00fcssel. Nicht kombinierbar mit -i\n\ \n\ - Die verfgbaren Kommandos hngen vom kontaktierten Server ab. Verwenden Sie das Kommando help, um eine Liste aller verfgbaren Kommandos anzuzeigen. + Die verf\u00fcgbaren Kommandos h\u00e4ngen vom kontaktierten Server ab. Verwenden Sie das Kommando help, um eine Liste aller verf\u00fcgbaren Kommandos anzuzeigen. CLI.NoURL=Weder die Option -s noch eine Umgebungsvariable JENKINS_URL wurde spezifiziert. CLI.NoSuchFileExists=Diese Datei existiert nicht {0} CLI.VersionMismatch=Versionskonflikt: Diese Version von Jenkins CLI ist nicht mit dem kontaktierten Jenkins-Server kompatibel. diff --git a/cli/src/test/java/hudson/cli/ConnectionTest.java b/cli/src/test/java/hudson/cli/ConnectionTest.java index 8cfac14fb4bc07eac67bca5370967bc47de94c84..f4cb0e8b1d595516130553bbe6568f8255324327 100644 --- a/cli/src/test/java/hudson/cli/ConnectionTest.java +++ b/cli/src/test/java/hudson/cli/ConnectionTest.java @@ -1,9 +1,11 @@ package hudson.cli; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; import hudson.remoting.FastPipedInputStream; import hudson.remoting.FastPipedOutputStream; +import org.codehaus.groovy.runtime.Security218; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -71,4 +73,15 @@ public class ConnectionTest { throw new Error("thread is still alive"); } } + + @Test + public void testSecurity218() throws Exception { + c1.writeObject(new Security218()); + try { + c2.readObject(); + fail(); + } catch (SecurityException e) { + assertTrue(e.getMessage().contains(Security218.class.getName())); + } + } } diff --git a/cli/src/test/java/org/codehaus/groovy/runtime/Security218.java b/cli/src/test/java/org/codehaus/groovy/runtime/Security218.java new file mode 100644 index 0000000000000000000000000000000000000000..cc3dfeef041c6ac07b91f80d3dc98a5f1530e4c7 --- /dev/null +++ b/cli/src/test/java/org/codehaus/groovy/runtime/Security218.java @@ -0,0 +1,11 @@ +package org.codehaus.groovy.runtime; + +import java.io.Serializable; + +/** + * Test payload in a prohibited package name. + * + * @author Kohsuke Kawaguchi + */ +public class Security218 implements Serializable { +} diff --git a/core/pom.xml b/core/pom.xml index 66c11616d78a3c6a14fd49157f98b916b2bcb073..36489c62c89057b432fb8e39b8c48043234b4ef4 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -29,7 +29,7 @@ THE SOFTWARE. org.jenkins-ci.main pom - 1.616-SNAPSHOT + 2.37-SNAPSHOT jenkins-core @@ -39,9 +39,11 @@ THE SOFTWARE. true - 1.237 + 1.248 2.5.6.SEC03 - 1.8.9 + 2.4.7 + + true @@ -147,7 +149,7 @@ THE SOFTWARE. org.kohsuke windows-package-checker - 1.0 + 1.2 org.kohsuke.stapler @@ -195,12 +197,12 @@ THE SOFTWARE. org.jenkins-ci annotation-indexer - 1.7 + 1.11 org.jenkins-ci bytecode-compatibility-transformer - 1.5 + 1.8 org.jenkins-ci @@ -210,7 +212,7 @@ THE SOFTWARE. org.jvnet.localizer localizer - 1.23 + 1.24 antlr @@ -243,8 +245,8 @@ THE SOFTWARE. javax.servlet - servlet-api - 2.4 + javax.servlet-api + 3.1.0 provided @@ -276,6 +278,11 @@ THE SOFTWARE. commons-beanutils 1.8.3 + + org.apache.commons + commons-compress + 1.10 + javax.mail mail @@ -403,16 +410,16 @@ THE SOFTWARE. groovy-all ${groovy.version} - + jline jline - 0.9.94 + 2.12 compile org.fusesource.jansi jansi - 1.9 + 1.11 commons-codec @@ -558,9 +579,9 @@ THE SOFTWARE. - findbugs + com.google.code.findbugs annotations - 1.0.0 + 3.0.0 provided @@ -618,7 +639,7 @@ THE SOFTWARE. - + org.jenkins-ci.tools maven-hpi-plugin @@ -626,6 +647,7 @@ THE SOFTWARE. generate-taglib-interface + record-core-location @@ -675,6 +697,7 @@ THE SOFTWARE. Messages.properties target/generated-sources/localizer + true @@ -784,6 +807,10 @@ THE SOFTWARE. + + org.codehaus.mojo + findbugs-maven-plugin + @@ -859,21 +886,12 @@ THE SOFTWARE. + findbugs - - - - org.codehaus.mojo - findbugs-maven-plugin - 2.5.2 - - Max - High - src/findbugs-filter.xml - - - - + + + true + diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.properties similarity index 92% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.properties index d303a63fc3e91e9b1a55c3b395f71c8d94c79e48..fffef47e59cd5c72bb4ac44cd9f2d6bc2ca5cee4 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.properties @@ -21,7 +21,8 @@ # THE SOFTWARE. NewVersionAvailable=New version of Jenkins ({0}) is available for download \ - (changelog). + (changelog). UpgradeComplete=Upgrade to Jenkins {0} is complete, awaiting restart. UpgradeCompleteRestartNotSupported=Upgrade to Jenkins {0} is complete, awaiting restart. -UpgradeProgress=Upgrade to Jenkins {0} is in progress or failed. +UpgradeProgress=Upgrade to Jenkins {0} is in progress. +UpgradeFailed=Upgrade to Jenkins {0} failed: {1}. diff --git a/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_bg.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..95e74685ada811e8f8b8e5855fbc99b66847d304 --- /dev/null +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_bg.properties @@ -0,0 +1,32 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +NewVersionAvailable=\ + \u041d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Jenkins ({0}) \u0435 \u043d\u0430\u043b\u0438\u0447\u043d\u0430 \u0437\u0430 \u0438\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435\ + (\u0441\u043f\u0438\u0441\u044a\u043a \u0441 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435). +UpgradeComplete=\ + \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043a\u044a\u043c \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f Jenkins {0} \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0438. \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435. +UpgradeCompleteRestartNotSupported=\ +\u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043a\u044a\u043c \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f Jenkins {0} \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0438. \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435. +UpgradeProgress=\u0418\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u0441\u0435 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043a\u044a\u043c Jenkins {0}. +UpgradeFailed=\u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043a\u044a\u043c Jenkins {0}: {1}. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_cs.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_cs.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_cs.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_cs.properties index 0627dbf1e4e6eb9c5e980357fc146aaa4cd3e8b6..691b46b7f011fea7b7006332205079333c537c84 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_cs.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_cs.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Nov\u00E1 verze Jenkins-u ({0}) je k dispozici ke sta\u017Een\u00ED (changelog). +NewVersionAvailable=Nov\u00E1 verze Jenkins-u ({0}) je k dispozici ke sta\u017Een\u00ED (changelog). Or\ Upgrade\ Automatically=Nebo Upgradovat Automaticky UpgradeComplete=Upgrade na Jenkinse {0} je hotov, \u010Dek\u00E1 na restart. UpgradeCompleteRestartNotSupported=Upgrade na Jenkinse {0} je hotov, \u010Dek\u00E1 na restart. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_da.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_da.properties similarity index 96% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_da.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_da.properties index 37285e900f14f4efd15dd43e9fb13957cdb3bdb5..8b5776e534c4c7b1976cc64e6cf05be51b585d9f 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_da.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_da.properties @@ -25,4 +25,4 @@ UpgradeCompleteRestartNotSupported=Opdatering til Jenkins {0} er fuldf\u00f8rt, UpgradeProgress=Opdatering til Jenkins {0} er i gang eller er fejlet. Or\ Upgrade\ Automatically=Eller opdater automatisk NewVersionAvailable=En ny version af Jenkins ({0}) er tilg\u00e6ngelig til hentning \ - (changelog). + (changelog). diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_de.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_de.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_de.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_de.properties index 5eb9dc40793c4bff153407d10ba9b3ffa0cee571..344e4571183a7eaa3becaab2ef851cd3ac008099 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_de.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_de.properties @@ -23,5 +23,5 @@ UpgradeComplete=Aktualisierung auf Jenkins {0} abgeschlossen. Neustart von Jenkins erforderlich. UpgradeCompleteRestartNotSupported=Aktualisierung auf Jenkins {0} abgeschlossen. Neustart von Jenkins erforderlich. UpgradeProgress=Aktualisierung auf Jenkins {0} in Arbeit oder fehlgeschlagen. -NewVersionAvailable=Eine neue Version von Jenkins ({0}) kann hier heruntergeladen werden (Was ist neu?). +NewVersionAvailable=Eine neue Version von Jenkins ({0}) kann hier heruntergeladen werden (Was ist neu?). Or\ Upgrade\ Automatically=Automatisch aktualisieren diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_es.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_es.properties similarity index 66% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_es.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_es.properties index f3bd1ba6f4c69fac5de1ded01f4d7c998d39935a..6016d4d17c127ce0247010aad57455532ffcd8e4 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_es.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_es.properties @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Hay una nueva versin de Jenkins disponible ({0}). descargar (listado de cambios). -Or\ Upgrade\ Automatically=O actualizar automticamente -UpgradeComplete=La actualizacin a Jenkins {0} se ha completado, esperando para reiniciar. -UpgradeCompleteRestartNotSupported=La actualizacin a Jenkins {0} se ha completado, esperando para reiniciar. -UpgradeProgress=La actualizacin a Jenkins {0} est en ejecucin o ha fallado. +NewVersionAvailable=Hay una nueva versi\u00f3n de Jenkins disponible ({0}). descargar (listado de cambios). +Or\ Upgrade\ Automatically=O actualizar autom\u00e1ticamente +UpgradeComplete=La actualizaci\u00f3n a Jenkins {0} se ha completado, esperando para reiniciar. +UpgradeCompleteRestartNotSupported=La actualizaci\u00f3n a Jenkins {0} se ha completado, esperando para reiniciar. +UpgradeProgress=La actualizaci\u00f3n a Jenkins {0} est\u00e1 en ejecuci\u00f3n o ha fallado. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_et.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_et.properties similarity index 52% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_et.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_et.properties index 7cd8b01f2a7a4eaeeed6bc01da9c269b27517f8c..1df6054b1428d863d5b65a19a2da234fa6cf08b3 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_et.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_et.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -NewVersionAvailable=Jenkinsi uus versioon ({0}) on saadaval allalaadimiseks (muudatuste nimekiri). +NewVersionAvailable=Jenkinsi uus versioon ({0}) on saadaval allalaadimiseks (muudatuste nimekiri). diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fi.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fi.properties similarity index 58% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fi.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fi.properties index 4822e11895de090d17bbdec6b2ddb85d1a22e01c..8243a6f68555eec617915e558122db1d0033ae49 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fi.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fi.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -NewVersionAvailable=Uusi Jenkinsin versio ({0}) on saatavana (muutosloki). +NewVersionAvailable=Uusi Jenkinsin versio ({0}) on saatavana (muutosloki). diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fr.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fr.properties similarity index 94% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fr.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fr.properties index f00987657878298f54bcca2660ce3e1e701f066e..0dbdae69d7d8df9097c1df2db7ded0102902c8ae 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fr.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_fr.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Une nouvelle version de Jenkins ({0}) est disponible (changelog). +NewVersionAvailable=Une nouvelle version de Jenkins ({0}) est disponible (changelog). Or\ Upgrade\ Automatically=Ou mettre \u00E0 jour automatiquement UpgradeProgress=Mise \u00E0 jour vers Jenkins {0} est en cours ou en \u00E9chec. UpgradeComplete=La mise \u00E0 jour de Jenkins en {0} est termin\u00E9e, en attente de red\u00E9marrage. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_hu.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_hu.properties similarity index 90% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_hu.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_hu.properties index c28160d6590d5656ff448260dac92953c8e19d35..19587285cae841957f0c83b526dcf3cf6750c815 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_hu.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_hu.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=A Jenkins \u00FAj verzi\u00F3ja ({0}) el\u00E9rhet\u0151 let\u00F6lt\u00E9sre (v\u00E1ltoz\u00E1sok). +NewVersionAvailable=A Jenkins \u00FAj verzi\u00F3ja ({0}) el\u00E9rhet\u0151 let\u00F6lt\u00E9sre (v\u00E1ltoz\u00E1sok). Or\ Upgrade\ Automatically=Vagy friss\u00EDtsen automatikusan diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_id.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_id.properties similarity index 64% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_id.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_id.properties index aa157c3f69813a8b798ed70b83f1ceefc2d71a68..c28903b2ddf3ae2e9e532bb7006518699b72bf77 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_id.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_id.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -NewVersionAvailable=Versi baru Jenkins ({0}) tersedia untuk diunduh (catatan perubahan). +NewVersionAvailable=Versi baru Jenkins ({0}) tersedia untuk diunduh (catatan perubahan). Or\ Upgrade\ Automatically=Atau Perbarui Secara Otomatis diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_it.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_it.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_it.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_it.properties index f6538f878eacab3b00e9c5fc5a997ba9dfc5fb8f..7378e405c76f9e21a930a2e698b8baf8f024a484 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_it.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_it.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=C''\u00E8 una nuova versione di Jenkins ({0}) disponibile per il download (changelog). +NewVersionAvailable=C''\u00E8 una nuova versione di Jenkins ({0}) disponibile per il download (changelog). Or\ Upgrade\ Automatically=Oppure aggiorna automaticamente UpgradeComplete=Aggiornamento a Jenkins {0} completato, in attesa di riavvio. UpgradeCompleteRestartNotSupported=Aggiornamento a Jenkins {0} completato, in attesa di riavvio. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ja.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ja.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ja.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ja.properties index 91ea7ae49a31a5ef876403f6d732286efb4764ce..5738b71b7682a2f7f0039aac4f593df8a9dce103 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ja.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ja.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Jenkins\u306E\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3({0})\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3067\u304D\u307E\u3059 (\u5909\u66F4\u5C65\u6B74)\u3002 +NewVersionAvailable=Jenkins\u306E\u65B0\u3057\u3044\u30D0\u30FC\u30B8\u30E7\u30F3({0})\u3092\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3067\u304D\u307E\u3059 (\u5909\u66F4\u5C65\u6B74)\u3002 Or\ Upgrade\ Automatically=\u81EA\u52D5\u3067\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9 UpgradeComplete=Jenkins {0} \u3078\u306E\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u306F\u5B8C\u4E86\u3057\u307E\u3057\u305F\u3002\u518D\u8D77\u52D5\u5F85\u3061\u3067\u3059\u3002 UpgradeProgress=Jenkins {0}\u3078\u306E\u30A2\u30C3\u30D7\u30B0\u30EC\u30FC\u30C9\u306F\u5B9F\u884C\u4E2D\u304B\u3001\u5931\u6557\u3057\u307E\u3057\u305F\u3002 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ko.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ko.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ko.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ko.properties index 3e54bb7c1204196e3c8ee28c652046b67ca14ef8..f5f6a772762aa34cd55aa6893fae4bc67c0aa073 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ko.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ko.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Jenkins \uC2E0\uADDC\uBC84\uC804({0})\uC744 \uC5EC\uAE30\uC11C \uBC1B\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.(\uBCC0\uACBD\uC0AC\uD56D). +NewVersionAvailable=Jenkins \uC2E0\uADDC\uBC84\uC804({0})\uC744 \uC5EC\uAE30\uC11C \uBC1B\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.(\uBCC0\uACBD\uC0AC\uD56D). Or\ Upgrade\ Automatically=\uB610\uB294 \uC790\uB3D9 \uC5C5\uADF8\uB808\uC774\uB4DC diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lt.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lt.properties similarity index 62% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lt.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lt.properties index b9995fe88bebe7f6236de20f5278c8d81b2155ed..2a16d979f6579860244892c408238e5e5ea6de66 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lt.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lt.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -NewVersionAvailable=Galima parsisi\u0173sti nauj\u0105 ({0}) Jenkins versij\u0105. (pakeitimai). +NewVersionAvailable=Galima parsisi\u0173sti nauj\u0105 ({0}) Jenkins versij\u0105. (pakeitimai). Or\ Upgrade\ Automatically=Parsi\u0173sti automati\u0161kai diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lv.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lv.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lv.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lv.properties index cf14b56b6fe54478da5e1bb04fa84d46c2dce5f2..9193a28385403d2933853f0dec5069a038406fa6 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lv.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_lv.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Jauna Jenkins ({0}) versija ir pieejama lejupl\u0101dei (izmai\u0146as). +NewVersionAvailable=Jauna Jenkins ({0}) versija ir pieejama lejupl\u0101dei (izmai\u0146as). Or\ Upgrade\ Automatically=Vai atjaunin\u0101t autom\u0101tiski UpgradeComplete=Atjaunin\u0101s\u0101na uz Jenkins {0} ir pabeigta; gaidu p\u0101rstart\u0113\u0161anos. UpgradeCompleteRestartNotSupported=Atjaunin\u0101s\u0101na uz Jenkins {0} ir pabeigta; gaidu p\u0101rstart\u0113\u0161anos. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nb_NO.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nb_NO.properties similarity index 92% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nb_NO.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nb_NO.properties index d86c6788e0fa80a045bf9ba845f7ef3f4eb3bd8a..b15161b4421813795e09b62fb4c26d00a4c7a858 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nb_NO.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nb_NO.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=En ny versjon av Jenkins ({0}) er n\u00E5 tilgjengelig (Endringer). +NewVersionAvailable=En ny versjon av Jenkins ({0}) er n\u00E5 tilgjengelig (Endringer). diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nl.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nl.properties similarity index 93% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nl.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nl.properties index d3a0df68e52fa4e22955eb330fb708d7451e20d1..9c291b0fddb44854da763828b29e37eaad0e1534 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nl.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_nl.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Er is een nieuwere versie van Jenkins ({0}) beschikbaar. downloaden (changelog). +NewVersionAvailable=Er is een nieuwere versie van Jenkins ({0}) beschikbaar. downloaden (changelog). Or\ Upgrade\ Automatically=Of werk automatisch bij UpgradeComplete=Upgrade naar Jenkins {0} is volledig; aan het wachten op herstart. UpgradeCompleteRestartNotSupported=Upgrade naar Jenkins {0} is volledig; aan het wachten op herstart. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pl.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pl.properties similarity index 54% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pl.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pl.properties index d22c58b0cc96b9f86675e87f7ea2d4889663bb21..6f5ff479b3092c96f38a93a2f6fb46a126fead29 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pl.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pl.properties @@ -1,5 +1,6 @@ # This file is under the MIT License by authors -NewVersionAvailable=Nowa wersja Jenkinsa ({0}) jest dost\u0119pna do pobrania (changelog). +NewVersionAvailable=Nowa wersja Jenkinsa ({0}) jest dost\u0119pna do pobrania (historia zmian). Or\ Upgrade\ Automatically=Albo uaktualnij automatycznie +UpgradeCompleteRestartNotSupported=Aktualizacja Jenkinsa do wersji {0} zako\u0144czy\u0142a si\u0119 pomy\u015Blnie, oczekiwanie na ponowne uruchomienie. UpgradeProgress=Aktualizacja Jenkinsa do wersji {0} trwa lub nie powiod\u0142a si\u0119. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties similarity index 96% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties index 96e622fc3bed40133241ed18a2860e57d3d21a29..216eee44d9e947331dd3e7cf1737cb1c88f56f8f 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_BR.properties @@ -27,5 +27,5 @@ UpgradeCompleteRestartNotSupported=Atualiza\u00e7\u00e3o do Jenkins {0} completa UpgradeProgress=Atualiza\u00e7\u00e3o para Jenkins {0} est\u00e1 em andamento ou falhou. Or\ Upgrade\ Automatically=Ou fazer a atualiza\u00e7\u00e3o automaticamente. # New version of Jenkins ({0}) is available for download \ -# (changelog). +# (changelog). NewVersionAvailable=Nova vers\u00e3o do Jenkins ({0}) est\u00e1 dispon\u00edvel em download diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_PT.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_PT.properties similarity index 55% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_PT.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_PT.properties index ad3dcdcaef7c7ca02225f7327bf19b7e9ec9dda3..dd2d81456d153cad42b32e5d27a0ceea7bea71c2 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_PT.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_pt_PT.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -NewVersionAvailable=Uma nova vers\u00E3o do Jenkins ({0}) est\u00E1 dispon\u00EDvel para download (registo de altera\u00E7\u00F5es). +NewVersionAvailable=Uma nova vers\u00E3o do Jenkins ({0}) est\u00E1 dispon\u00EDvel para download (registo de altera\u00E7\u00F5es). Or\ Upgrade\ Automatically=Ou atualizar automaticamente diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ru.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ru.properties similarity index 92% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ru.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ru.properties index c3cd495635173c5de7b5114ded24a6597be99498..97659c57c7def17ad08d3af7af2b9eba4e7b8fee 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ru.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_ru.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=\u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F Jenkins ({0}) \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 (\u0441\u043F\u0438\u0441\u043E\u043A \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439). +NewVersionAvailable=\u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F Jenkins ({0}) \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0434\u043B\u044F \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 (\u0441\u043F\u0438\u0441\u043E\u043A \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439). Or\ Upgrade\ Automatically=\u0418\u043B\u0438 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 UpgradeComplete=\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0434\u043E Jenkins {0} \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043E, \u043E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438. UpgradeCompleteRestartNotSupported=\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0434\u043E Jenkins {0} \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043E, \u043E\u0436\u0438\u0434\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sk.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sk.properties similarity index 92% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sk.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sk.properties index bca3d05fab39593ad4e321072d0956ee6988a40b..96543df586253a9821c3057b38d334cc733e9b25 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sk.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sk.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=Nov\u00E1 verzia Jenkins ({0}) je dostupn\u00E1 na stiahnutie (zoznam zmien). +NewVersionAvailable=Nov\u00E1 verzia Jenkins ({0}) je dostupn\u00E1 na stiahnutie (zoznam zmien). diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sl.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sl.properties similarity index 61% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sl.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sl.properties index b69224ebd301faa0d6441f52535fc50fa973d86b..649104bcf5a3aa6702a824ed73c0c5195550f13c 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sl.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sl.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -NewVersionAvailable=Nova razli\u010Dica Jenkins-a ({0}) je na voljo za prenos (seznam sprememb). +NewVersionAvailable=Nova razli\u010Dica Jenkins-a ({0}) je na voljo za prenos (seznam sprememb). Or\ Upgrade\ Automatically=ali posodobi samodejno diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sv_SE.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sv_SE.properties similarity index 100% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sv_SE.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sv_SE.properties diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_uk.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_uk.properties similarity index 92% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_uk.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_uk.properties index 3379d203678e3487f91fc8dc55a126b05c23e206..625195c3513bf5a71162d33e25b76066a09f3b84 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_uk.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_uk.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -NewVersionAvailable=\u041D\u043E\u0432\u0430 \u0432\u0435\u0440\u0441\u0456\u044F \u0414\u0436\u0435\u043D\u043A\u0456\u043D\u0441 ({0}) \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0434\u043B\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F (\u0437\u043C\u0456\u043D\u0438). +NewVersionAvailable=\u041D\u043E\u0432\u0430 \u0432\u0435\u0440\u0441\u0456\u044F \u0414\u0436\u0435\u043D\u043A\u0456\u043D\u0441 ({0}) \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0434\u043B\u044F \u0437\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0435\u043D\u043D\u044F (\u0437\u043C\u0456\u043D\u0438). Or\ Upgrade\ Automatically=\u0410\u0431\u043E \u043E\u043D\u043E\u0432\u0456\u0442\u044C \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043D\u043E diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_CN.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_CN.properties similarity index 77% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_CN.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_CN.properties index 1ddf921908269e57c7370c85b7252ea5dbde5b47..0ef79b530b974daaaed8ae9bc346ed86fb71a2bc 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_CN.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_CN.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors -NewVersionAvailable=Jenkins\u65B0\u7248\u672C ({0})\u53EF\u70B9\u51FB download (\u53D8\u66F4\u8BF4\u660E)\u4E0B\u8F7D\u3002 +NewVersionAvailable=Jenkins\u65B0\u7248\u672C ({0})\u53EF\u70B9\u51FB download (\u53D8\u66F4\u8BF4\u660E)\u4E0B\u8F7D\u3002 Or\ Upgrade\ Automatically=\u6216 \u81EA\u52A8\u5347\u7EA7\u7248\u672C UpgradeComplete=Jenkins {0} \u7248\u672C\u5347\u7EA7\u5DF2\u5B8C\u6210,\u7B49\u5F85\u91CD\u542F\u4E2D. UpgradeCompleteRestartNotSupported=Jenkins {0} \u7248\u672C\u5347\u7EA7\u5DF2\u5B8C\u6210,\u7B49\u5F85\u91CD\u542F\u4E2D. diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties similarity index 92% rename from core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties rename to core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties index 0423c94c73d6319e64f59b6cebf2c0adb64629f0..76967e8ea16086a1772118b76e503a32fe985ef6 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties +++ b/core/src/filter/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_zh_TW.properties @@ -24,5 +24,5 @@ UpgradeComplete=Jenkins {0} \u5347\u7248\u5b8c\u6210\uff0c\u7b49\u5019\u91cd\u65b0\u555f\u52d5\u3002 UpgradeCompleteRestartNotSupported=Jenkins {0} \u5347\u7248\u5b8c\u6210\uff0c\u7b49\u5019\u91cd\u65b0\u555f\u52d5\u3002 UpgradeProgress=Jenkins {0} \u5347\u7d1a\u4f5c\u696d\u6b63\u5728\u9032\u884c\u4e2d\u6216\u662f\u5df2\u7d93\u5931\u6557\u3002 -NewVersionAvailable=\u65b0\u7248\u7684 Jenkins ({0}) \u5df2\u7d93\u53ef\u4ee5\u4e0b\u8f09 (\u6539\u7248\u8a18\u9304)\u3002 +NewVersionAvailable=\u65b0\u7248\u7684 Jenkins ({0}) \u5df2\u7d93\u53ef\u4ee5\u4e0b\u8f09 (\u6539\u7248\u8a18\u9304)\u3002 Or\ Upgrade\ Automatically=\u6216\u662f\u81ea\u52d5\u5347\u7248 diff --git a/core/src/main/java/hudson/AbortException.java b/core/src/main/java/hudson/AbortException.java index 41a10739eb16075a27a26a6704923fa45432d131..b68276e8eec12409624d20932aa3c7c58f30391c 100644 --- a/core/src/main/java/hudson/AbortException.java +++ b/core/src/main/java/hudson/AbortException.java @@ -32,7 +32,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -public final class AbortException extends IOException { +public class AbortException extends IOException { public AbortException() { } diff --git a/core/src/main/java/hudson/AboutJenkins.java b/core/src/main/java/hudson/AboutJenkins.java index 42332f9a920c5db3aeba241ac6df58824aeaacb9..34fc120e57272e4983e4d51b6f393e7306e579f5 100644 --- a/core/src/main/java/hudson/AboutJenkins.java +++ b/core/src/main/java/hudson/AboutJenkins.java @@ -2,6 +2,8 @@ package hudson; import hudson.model.ManagementLink; import java.net.URL; + +import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -10,7 +12,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("about") public class AboutJenkins extends ManagementLink { @Override public String getIconFileName() { diff --git a/core/src/main/java/hudson/BulkChange.java b/core/src/main/java/hudson/BulkChange.java index db48db3de78cacd7f96ffde7305d1bc9ae787aa0..3c7da451f6384a6f516e7e2aa45851b5ea77f846 100644 --- a/core/src/main/java/hudson/BulkChange.java +++ b/core/src/main/java/hudson/BulkChange.java @@ -25,6 +25,7 @@ package hudson; import hudson.model.Saveable; +import java.io.Closeable; import java.io.IOException; /** @@ -35,28 +36,13 @@ import java.io.IOException; * The usage of {@link BulkChange} needs to follow a specific closure-like pattern, namely: * *

- * BulkChange bc = new BulkChange(someObject);
- * try {
+ * try (BulkChange bc = new BulkChange(someObject)) {
  *    ... make changes to 'someObject'
- * } finally {
  *    bc.commit();
  * }
  * 
* *

- * ... or if you'd like to avoid saving when something bad happens: - * - *

- * BulkChange bc = new BulkChange(someObject);
- * try {
- *    ... make changes to 'someObject'
- *    bc.commit();
- * } finally {
- *    bc.abort();
- * }
- * 
- * - *

* Use of this method is optional. If {@link BulkChange} is not used, individual mutator * will perform the save operation, and things will just run somewhat slower. * @@ -82,7 +68,7 @@ import java.io.IOException; * @author Kohsuke Kawaguchi * @since 1.249 */ -public class BulkChange { +public class BulkChange implements Closeable { private final Saveable saveable; public final Exception allocator; private final BulkChange parent; @@ -112,6 +98,14 @@ public class BulkChange { saveable.save(); } + /** + * Alias for {@link #abort()} to make {@link BulkChange} auto-closeable. + */ + @Override + public void close() { + abort(); + } + /** * Exits the scope of {@link BulkChange} without saving the changes. * diff --git a/core/src/main/java/hudson/ClassicPluginStrategy.java b/core/src/main/java/hudson/ClassicPluginStrategy.java index 727bdd7fbd7e580006ac0ccc9099dafa4912354e..792e02a0b73abb959f141bfd1f227d87a25996c0 100644 --- a/core/src/main/java/hudson/ClassicPluginStrategy.java +++ b/core/src/main/java/hudson/ClassicPluginStrategy.java @@ -23,6 +23,7 @@ */ package hudson; +import jenkins.util.SystemProperties; import com.google.common.collect.Lists; import hudson.Plugin.DummyImpl; import hudson.PluginWrapper.Dependency; @@ -56,8 +57,6 @@ import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -74,6 +73,10 @@ import java.util.jar.Manifest; import java.util.logging.Level; import java.util.logging.Logger; import org.jenkinsci.bytecode.Transformer; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import javax.annotation.Nonnull; import static org.apache.commons.io.FilenameUtils.getBaseName; @@ -104,11 +107,8 @@ public class ClassicPluginStrategy implements PluginStrategy { if (isLinked(archive)) { manifest = loadLinkedManifest(archive); } else { - JarFile jf = new JarFile(archive, false); - try { + try (JarFile jf = new JarFile(archive, false)) { manifest = jf.getManifest(); - } finally { - jf.close(); } } return PluginWrapper.computeShortName(manifest, archive.getName()); @@ -162,7 +162,8 @@ public class ClassicPluginStrategy implements PluginStrategy { if (archive.isDirectory()) {// already expanded expandDir = archive; } else { - expandDir = new File(archive.getParentFile(), getBaseName(archive.getName())); + File f = pluginManager.getWorkDir(); + expandDir = new File(f == null ? archive.getParentFile() : f, getBaseName(archive.getName())); explode(archive, expandDir); } @@ -172,11 +173,8 @@ public class ClassicPluginStrategy implements PluginStrategy { "Plugin installation failed. No manifest at " + manifestFile); } - FileInputStream fin = new FileInputStream(manifestFile); - try { + try (FileInputStream fin = new FileInputStream(manifestFile)) { manifest = new Manifest(fin); - } finally { - fin.close(); } } @@ -200,21 +198,8 @@ public class ClassicPluginStrategy implements PluginStrategy { if (libs != null) paths.addAll(Arrays.asList(libs)); - try { - Class pathJDK7 = Class.forName("java.nio.file.Path"); - Object toPath = File.class.getMethod("toPath").invoke(expandDir); - URI uri = (URI) pathJDK7.getMethod("toUri").invoke(toPath); + baseResourceURL = expandDir.toPath().toUri().toURL(); - baseResourceURL = uri.toURL(); - } catch (NoSuchMethodException e) { - throw new Error(e); - } catch (ClassNotFoundException e) { - baseResourceURL = expandDir.toURI().toURL(); - } catch (InvocationTargetException e) { - throw new Error(e); - } catch (IllegalAccessException e) { - throw new Error(e); - } } File disableFile = new File(archive.getPath() + ".disabled"); if (disableFile.exists()) { @@ -235,8 +220,8 @@ public class ClassicPluginStrategy implements PluginStrategy { } } } - for (DetachedPlugin detached : DETACHED_LIST) - detached.fix(atts,optionalDependencies); + + fix(atts,optionalDependencies); // Register global classpath mask. This is useful for hiding JavaEE APIs that you might see from the container, // such as database plugin for JPA support. The Mask-Classes attribute is insufficient because those classes @@ -254,6 +239,41 @@ public class ClassicPluginStrategy implements PluginStrategy { createClassLoader(paths, dependencyLoader, atts), disableFile, dependencies, optionalDependencies); } + private static void fix(Attributes atts, List optionalDependencies) { + String pluginName = atts.getValue("Short-Name"); + + String jenkinsVersion = atts.getValue("Jenkins-Version"); + if (jenkinsVersion==null) + jenkinsVersion = atts.getValue("Hudson-Version"); + + optionalDependencies.addAll(getImpliedDependencies(pluginName, jenkinsVersion)); + } + + /** + * Returns all the plugin dependencies that are implicit based on a particular Jenkins version + * @since 2.0 + */ + @Nonnull + public static List getImpliedDependencies(String pluginName, String jenkinsVersion) { + List out = new ArrayList<>(); + for (DetachedPlugin detached : DETACHED_LIST) { + // don't fix the dependency for itself, or else we'll have a cycle + if (detached.shortName.equals(pluginName)) { + continue; + } + if (BREAK_CYCLES.contains(pluginName + '/' + detached.shortName)) { + LOGGER.log(Level.FINE, "skipping implicit dependency {0} → {1}", new Object[] {pluginName, detached.shortName}); + continue; + } + // some earlier versions of maven-hpi-plugin apparently puts "null" as a literal in Hudson-Version. watch out for them. + if (jenkinsVersion == null || jenkinsVersion.equals("null") || new VersionNumber(jenkinsVersion).compareTo(detached.splitWhen) <= 0) { + out.add(new PluginWrapper.Dependency(detached.shortName + ':' + detached.requiredVersion)); + LOGGER.log(Level.FINE, "adding implicit dependency {0} → {1} because of {2}", new Object[] {pluginName, detached.shortName, jenkinsVersion}); + } + } + return out; + } + @Deprecated protected ClassLoader createClassLoader(List paths, ClassLoader parent) throws IOException { return createClassLoader( paths, parent, null ); @@ -279,10 +299,66 @@ public class ClassicPluginStrategy implements PluginStrategy { return classLoader; } + /** + * Get the list of all plugins that have ever been {@link DetachedPlugin detached} from Jenkins core. + * @return A {@link List} of {@link DetachedPlugin}s. + */ + @Restricted(NoExternalUse.class) + public static @Nonnull List getDetachedPlugins() { + return DETACHED_LIST; + } + + /** + * Get the list of plugins that have been detached since a specific Jenkins release version. + * @param since The Jenkins version. + * @return A {@link List} of {@link DetachedPlugin}s. + */ + @Restricted(NoExternalUse.class) + public static @Nonnull List getDetachedPlugins(@Nonnull VersionNumber since) { + List detachedPlugins = new ArrayList<>(); + + for (DetachedPlugin detachedPlugin : DETACHED_LIST) { + if (!detachedPlugin.getSplitWhen().isOlderThan(since)) { + detachedPlugins.add(detachedPlugin); + } + } + + return detachedPlugins; + } + + /** + * Is the named plugin a plugin that was detached from Jenkins at some point in the past. + * @param pluginId The plugin ID. + * @return {@code true} if the plugin is a plugin that was detached from Jenkins at some + * point in the past, otherwise {@code false}. + */ + @Restricted(NoExternalUse.class) + public static boolean isDetachedPlugin(@Nonnull String pluginId) { + for (DetachedPlugin detachedPlugin : DETACHED_LIST) { + if (detachedPlugin.getShortName().equals(pluginId)) { + return true; + } + } + + return false; + } + /** * Information about plugins that were originally in the core. + *

+ * A detached plugin is one that has any of the following characteristics: + *

*/ - private static final class DetachedPlugin { + @Restricted(NoExternalUse.class) + public static final class DetachedPlugin { private final String shortName; /** * Plugins built for this Jenkins version (and earlier) will automatically be assumed to have @@ -292,57 +368,67 @@ public class ClassicPluginStrategy implements PluginStrategy { * be "1.123.*" (because 1.124 will be the first version that doesn't include the removed code.) */ private final VersionNumber splitWhen; - private final String requireVersion; + private final String requiredVersion; - private DetachedPlugin(String shortName, String splitWhen, String requireVersion) { + private DetachedPlugin(String shortName, String splitWhen, String requiredVersion) { this.shortName = shortName; this.splitWhen = new VersionNumber(splitWhen); - this.requireVersion = requireVersion; + this.requiredVersion = requiredVersion; } - private void fix(Attributes atts, List optionalDependencies) { - // don't fix the dependency for yourself, or else we'll have a cycle - String yourName = atts.getValue("Short-Name"); - if (shortName.equals(yourName)) return; - if (BREAK_CYCLES.contains(yourName + '/' + shortName)) { - LOGGER.log(Level.FINE, "skipping implicit dependency {0} → {1}", new Object[] {yourName, shortName}); - return; - } + /** + * Get the short name of the plugin. + * @return The short name of the plugin. + */ + public String getShortName() { + return shortName; + } - // some earlier versions of maven-hpi-plugin apparently puts "null" as a literal in Hudson-Version. watch out for them. - String jenkinsVersion = atts.getValue("Jenkins-Version"); - if (jenkinsVersion==null) - jenkinsVersion = atts.getValue("Hudson-Version"); - if (jenkinsVersion == null || jenkinsVersion.equals("null") || new VersionNumber(jenkinsVersion).compareTo(splitWhen) <= 0) { - optionalDependencies.add(new PluginWrapper.Dependency(shortName + ':' + requireVersion)); - LOGGER.log(Level.FINE, "adding implicit dependency {0} → {1} because of {2}", new Object[] {yourName, shortName, jenkinsVersion}); - } + /** + * Get the Jenkins version from which the plugin was detached. + * @return The Jenkins version from which the plugin was detached. + */ + public VersionNumber getSplitWhen() { + return splitWhen; + } + + /** + * Gets the minimum required version for the current version of Jenkins. + * + * @return the minimum required version for the current version of Jenkins. + * @sice 2.16 + */ + public VersionNumber getRequiredVersion() { + return new VersionNumber(requiredVersion); } } - private static final List DETACHED_LIST = Arrays.asList( - new DetachedPlugin("maven-plugin","1.296","1.296"), - new DetachedPlugin("subversion","1.310","1.0"), - new DetachedPlugin("cvs","1.340","0.1"), - new DetachedPlugin("ant","1.430.*","1.0"), - new DetachedPlugin("javadoc","1.430.*","1.0"), - new DetachedPlugin("external-monitor-job","1.467.*","1.0"), - new DetachedPlugin("ldap","1.467.*","1.0"), - new DetachedPlugin("pam-auth","1.467.*","1.0"), - new DetachedPlugin("mailer","1.493.*","1.2"), - new DetachedPlugin("matrix-auth","1.535.*","1.0.2"), - new DetachedPlugin("windows-slaves","1.547.*","1.0"), - new DetachedPlugin("antisamy-markup-formatter","1.553.*","1.0"), - new DetachedPlugin("matrix-project","1.561.*","1.0"), - new DetachedPlugin("junit","1.577.*","1.0") - ); + private static final List DETACHED_LIST = Collections.unmodifiableList(Arrays.asList( + new DetachedPlugin("maven-plugin", "1.296", "1.296"), + new DetachedPlugin("subversion", "1.310", "1.0"), + new DetachedPlugin("cvs", "1.340", "0.1"), + new DetachedPlugin("ant", "1.430.*", "1.0"), + new DetachedPlugin("javadoc", "1.430.*", "1.0"), + new DetachedPlugin("external-monitor-job", "1.467.*", "1.0"), + new DetachedPlugin("ldap", "1.467.*", "1.0"), + new DetachedPlugin("pam-auth", "1.467.*", "1.0"), + new DetachedPlugin("mailer", "1.493.*", "1.2"), + new DetachedPlugin("matrix-auth", "1.535.*", "1.0.2"), + new DetachedPlugin("windows-slaves", "1.547.*", "1.0"), + new DetachedPlugin("antisamy-markup-formatter", "1.553.*", "1.0"), + new DetachedPlugin("matrix-project", "1.561.*", "1.0"), + new DetachedPlugin("junit", "1.577.*", "1.0"), + new DetachedPlugin("bouncycastle-api", "2.16.*", "2.16.0") + )); /** Implicit dependencies that are known to be unnecessary and which must be cut out to prevent a dependency cycle among bundled plugins. */ private static final Set BREAK_CYCLES = new HashSet(Arrays.asList( "script-security/matrix-auth", "script-security/windows-slaves", "script-security/antisamy-markup-formatter", - "script-security/matrix-project" + "script-security/matrix-project", + "credentials/matrix-auth", + "credentials/windows-slaves" )); /** @@ -418,13 +504,9 @@ public class ClassicPluginStrategy implements PluginStrategy { throw new IOException(className+" doesn't extend from hudson.Plugin"); } wrapper.setPlugin((Plugin) o); - } catch (LinkageError e) { + } catch (LinkageError | ClassNotFoundException e) { throw new IOException("Unable to load " + className + " from " + wrapper.getShortName(),e); - } catch (ClassNotFoundException e) { - throw new IOException("Unable to load " + className + " from " + wrapper.getShortName(),e); - } catch (IllegalAccessException e) { - throw new IOException("Unable to create instance of " + className + " from " + wrapper.getShortName(),e); - } catch (InstantiationException e) { + } catch (IllegalAccessException | InstantiationException e) { throw new IOException("Unable to create instance of " + className + " from " + wrapper.getShortName(),e); } } @@ -558,14 +640,13 @@ public class ClassicPluginStrategy implements PluginStrategy { final long dirTime = archive.lastModified(); // this ZipOutputStream is reused and not created for each directory - final ZipOutputStream wrappedZOut = new ZipOutputStream(new NullOutputStream()) { + try (ZipOutputStream wrappedZOut = new ZipOutputStream(new NullOutputStream()) { @Override public void putNextEntry(ZipEntry ze) throws IOException { ze.setTime(dirTime+1999); // roundup super.putNextEntry(ze); } - }; - try { + }) { Zip z = new Zip() { /** * Forces the fixed timestamp for directories to make sure @@ -584,8 +665,6 @@ public class ClassicPluginStrategy implements PluginStrategy { z.setDestFile(classesJar); z.add(mapper); z.execute(); - } finally { - wrappedZOut.close(); } } @@ -753,9 +832,7 @@ public class ClassicPluginStrategy implements PluginStrategy { Field $pathComponents = AntClassLoader.class.getDeclaredField("pathComponents"); $pathComponents.setAccessible(true); pathComponents = (Vector)$pathComponents.get(this); - } catch (NoSuchFieldException e) { - throw new Error(e); - } catch (IllegalAccessException e) { + } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } } @@ -795,12 +872,12 @@ public class ClassicPluginStrategy implements PluginStrategy { @Override protected Class defineClassFromData(File container, byte[] classData, String classname) throws IOException { if (!DISABLE_TRANSFORMER) - classData = pluginManager.getCompatibilityTransformer().transform(classname, classData); + classData = pluginManager.getCompatibilityTransformer().transform(classname, classData, this); return super.defineClassFromData(container, classData, classname); } } - public static boolean useAntClassLoader = Boolean.getBoolean(ClassicPluginStrategy.class.getName()+".useAntClassLoader"); + public static boolean useAntClassLoader = SystemProperties.getBoolean(ClassicPluginStrategy.class.getName()+".useAntClassLoader"); private static final Logger LOGGER = Logger.getLogger(ClassicPluginStrategy.class.getName()); - public static boolean DISABLE_TRANSFORMER = Boolean.getBoolean(ClassicPluginStrategy.class.getName()+".noBytecodeTransformer"); + public static boolean DISABLE_TRANSFORMER = SystemProperties.getBoolean(ClassicPluginStrategy.class.getName()+".noBytecodeTransformer"); } diff --git a/core/src/main/java/hudson/DNSMultiCast.java b/core/src/main/java/hudson/DNSMultiCast.java index 8d029b6ae3f4ba42ca5aa253cdea8ea9ee294b80..aa71b2e23b2be38ba799c7d3f3742e9442a5c550 100644 --- a/core/src/main/java/hudson/DNSMultiCast.java +++ b/core/src/main/java/hudson/DNSMultiCast.java @@ -1,5 +1,6 @@ package hudson; +import jenkins.util.SystemProperties; import jenkins.model.Jenkins; import jenkins.model.Jenkins.MasterComputer; @@ -66,7 +67,8 @@ public class DNSMultiCast implements Closeable { jmdns.registerService(ServiceInfo.create("_http._tcp.local.","Jenkins", jenkins_port,0,0,props)); } catch (IOException e) { - LOGGER.log(Level.WARNING,"Failed to advertise the service to DNS multi-cast",e); + LOGGER.log(Level.INFO, "Cannot advertise service to DNS multi-cast, skipping: {0}", e); + LOGGER.log(Level.FINE, null, e); } return null; } @@ -86,5 +88,5 @@ public class DNSMultiCast implements Closeable { private static final Logger LOGGER = Logger.getLogger(DNSMultiCast.class.getName()); - public static boolean disabled = Boolean.getBoolean(DNSMultiCast.class.getName()+".disabled"); + public static boolean disabled = SystemProperties.getBoolean(DNSMultiCast.class.getName()+".disabled"); } diff --git a/core/src/main/java/hudson/DependencyRunner.java b/core/src/main/java/hudson/DependencyRunner.java index bd4282f8c209bc8012d02ceb2ff16b913725c41b..acf035676910ad3ac77f6e4b3164ed7358fc0f39 100644 --- a/core/src/main/java/hudson/DependencyRunner.java +++ b/core/src/main/java/hudson/DependencyRunner.java @@ -35,7 +35,6 @@ import java.util.Set; import java.util.Collection; import java.util.logging.Logger; -import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; diff --git a/core/src/main/java/hudson/DescriptorExtensionList.java b/core/src/main/java/hudson/DescriptorExtensionList.java index 513c557d44c7c11bcbd0c62c891d83f03997adeb..16d96ae441b0ff5a7cc4a3e59e8398db0cc595a4 100644 --- a/core/src/main/java/hudson/DescriptorExtensionList.java +++ b/core/src/main/java/hudson/DescriptorExtensionList.java @@ -39,6 +39,7 @@ import hudson.tasks.Publisher; import java.util.Collection; import java.util.List; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; @@ -182,6 +183,11 @@ public class DescriptorExtensionList, D extends Descrip */ @Override protected List> load() { + if (jenkins == null) { + // Should never happen on the real instance + LOGGER.log(Level.WARNING, "Cannot load extension components, because Jenkins instance has not been assigned yet"); + return Collections.emptyList(); + } return _load(jenkins.getExtensionList(Descriptor.class).getComponents()); } diff --git a/core/src/main/java/hudson/EnvVars.java b/core/src/main/java/hudson/EnvVars.java index c0047b557836d7865e14c4f9ee7919d04dd39c4b..5cdc672bf4cd8caf70f40d045c8e10a7bb4bb49c 100644 --- a/core/src/main/java/hudson/EnvVars.java +++ b/core/src/main/java/hudson/EnvVars.java @@ -63,7 +63,7 @@ import java.util.logging.Logger; * *

* In Jenkins, often we need to build up "environment variable overrides" - * on master, then to execute the process on slaves. This causes a problem + * on master, then to execute the process on agents. This causes a problem * when working with variables like PATH. So to make this work, * we introduce a special convention PATH+FOO — all entries * that starts with PATH+ are merged and prepended to the inherited @@ -134,7 +134,7 @@ public class EnvVars extends TreeMap { String v = get(realKey); if(v==null) v=value; else { - // we might be handling environment variables for a slave that can have different path separator + // we might be handling environment variables for a agent that can have different path separator // than the master, so the following is an attempt to get it right. // it's still more error prone that I'd like. char ch = platform==null ? File.pathSeparatorChar : platform.pathSeparator; @@ -421,8 +421,8 @@ public class EnvVars extends TreeMap { * variables only when you access this from the master. * *

- * If you access this field from slaves, then this is the environment - * variable of the slave agent. + * If you access this field from agents, then this is the environment + * variable of the agent agent. */ public static final Map masterEnvVars = initMaster(); diff --git a/core/src/main/java/hudson/Extension.java b/core/src/main/java/hudson/Extension.java index 5ad913ef6ad39a1e8f2c35168c0863e48ec31221..1ca863d2f4f5cbdf46c66ede57c9e59920e5781b 100644 --- a/core/src/main/java/hudson/Extension.java +++ b/core/src/main/java/hudson/Extension.java @@ -74,7 +74,8 @@ public @interface Extension { /** * Used for sorting extensions. * - * Extensions will be sorted in the descending order of the ordinal. + * Extensions will be sorted in the descending order of the ordinal. In other words, + * the extensions with the highest numbers will be chosen first. * This is a rather poor approach to the problem, so its use is generally discouraged. * * @since 1.306 diff --git a/core/src/main/java/hudson/ExtensionFinder.java b/core/src/main/java/hudson/ExtensionFinder.java index 4f0719da59ac5254c5d1bc6cae1a53a6544a90dc..6208f6cec8322a0145f2fc4436519000d07e0ce6 100644 --- a/core/src/main/java/hudson/ExtensionFinder.java +++ b/core/src/main/java/hudson/ExtensionFinder.java @@ -175,7 +175,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { * from here. * *

- * See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459208 for how to force a class initialization. + * See https://bugs.openjdk.java.net/browse/JDK-4993813 for how to force a class initialization. * Also see http://kohsuke.org/2010/09/01/deadlock-that-you-cant-avoid/ for how class initialization * can results in a dead lock. */ @@ -245,7 +245,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { */ private List> sezpozIndex; - private final Map annotations = new HashMap(); + private final Map annotations = new HashMap<>(); private final Sezpoz moduleFinder = new Sezpoz(); /** @@ -261,7 +261,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { sezpozIndex = loadSezpozIndices(Jenkins.getInstance().getPluginManager().uberClassLoader); - List modules = new ArrayList(); + List modules = new ArrayList<>(); modules.add(new AbstractModule() { @Override protected void configure() { @@ -282,7 +282,6 @@ public abstract class ExtensionFinder implements ExtensionPoint { LOGGER.log(Level.SEVERE, "Failed to create Guice container from all the plugins",e); // failing to load all bindings are disastrous, so recover by creating minimum that works // by just including the core - // TODO this recovery is pretty much useless; startup crashes anyway container = Guice.createInjector(new SezpozModule(loadSezpozIndices(Jenkins.class.getClassLoader()))); } @@ -325,7 +324,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { l.addAll(delta); sezpozIndex = l; - List modules = new ArrayList(); + List modules = new ArrayList<>(); modules.add(new SezpozModule(delta)); for (ExtensionComponent ec : moduleFinder.refresh().find(Module.class)) { modules.add(ec.getInstance()); @@ -338,7 +337,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { return new ExtensionComponentSet() { @Override public Collection> find(Class type) { - List> result = new ArrayList>(); + List> result = new ArrayList<>(); _find(type, result, child); return result; } @@ -352,14 +351,11 @@ public abstract class ExtensionFinder implements ExtensionPoint { private Object instantiate(IndexItem item) { try { return item.instance(); - } catch (LinkageError e) { + } catch (LinkageError | Exception e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING, "Failed to load "+item.className(), e); - } catch (Exception e) { - LOGGER.log(isOptional(item.annotation()) ? Level.FINE : Level.WARNING, - "Failed to load "+item.className(), e); } return null; } @@ -376,7 +372,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { public Collection> find(Class type, Hudson jenkins) { // the find method contract requires us to traverse all known components - List> result = new ArrayList>(); + List> result = new ArrayList<>(); for (Injector i=container; i!=null; i=i.getParent()) { _find(type, result, i); } @@ -390,7 +386,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { Object o = e.getValue().getProvider().get(); if (o!=null) { GuiceExtensionAnnotation gea = a!=null ? extensionAnnotations.get(a.annotationType()) : null; - result.add(new ExtensionComponent(type.cast(o),gea!=null?gea.getOrdinal(a):0)); + result.add(new ExtensionComponent<>(type.cast(o), gea != null ? gea.getOrdinal(a) : 0)); } } } @@ -426,10 +422,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { public T get() { try { return base.get(); - } catch (Exception e) { - error(key, e); - return null; - } catch (LinkageError e) { + } catch (Exception | LinkageError e) { error(key, e); return null; } @@ -438,13 +431,13 @@ public abstract class ExtensionFinder implements ExtensionPoint { if (verbose) { LOGGER.log(Level.WARNING, "Failed to instantiate " + key + "; skipping this component", x); } else { - LOGGER.log(Level.WARNING, "Failed to instantiate optional component {0}; skipping", key.getTypeLiteral()); + LOGGER.log(Level.INFO, "Failed to instantiate optional component {0}; skipping", key.getTypeLiteral()); LOGGER.log(Level.FINE, key.toString(), x); } } }; } - }; + } private static final Logger LOGGER = Logger.getLogger(GuiceFinder.class.getName()); @@ -482,7 +475,11 @@ public abstract class ExtensionFinder implements ExtensionPoint { m.invoke(ecl, c); c.getConstructors(); c.getMethods(); - c.getFields(); + for (Field f : c.getFields()) { + if (f.getAnnotation(javax.inject.Inject.class) != null || f.getAnnotation(com.google.inject.Inject.class) != null) { + resolve(f.getType()); + } + } LOGGER.log(Level.FINER, "{0} looks OK", c); while (c != Object.class) { c.getGenericSuperclass(); @@ -496,10 +493,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { @SuppressWarnings({"unchecked", "ChainOfInstanceofChecks"}) @Override protected void configure() { - int id=0; - for (final IndexItem item : index) { - id++; boolean optional = isOptional(item.annotation()); try { AnnotatedElement e = item.element(); @@ -524,8 +518,8 @@ public abstract class ExtensionFinder implements ExtensionPoint { resolve(extType); - // use arbitrary id to make unique key, because Guice wants that. - Key key = Key.get(extType, Names.named(String.valueOf(id))); + // make unique key, because Guice wants that. + Key key = Key.get(extType, Names.named(item.className() + "." + item.memberName())); annotations.put(key,a); bind(key).toProvider(new Provider() { public Object get() { @@ -533,14 +527,11 @@ public abstract class ExtensionFinder implements ExtensionPoint { } }).in(scope); } - } catch (LinkageError e) { + } catch (Exception|LinkageError e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError LOGGER.log(optional ? Level.FINE : Level.WARNING, "Failed to load "+item.className(), e); - } catch (Exception e) { - LOGGER.log(optional ? Level.FINE : Level.WARNING, - "Failed to load "+item.className(), e); } } } @@ -622,7 +613,7 @@ public abstract class ExtensionFinder implements ExtensionPoint { * Finds all the matching {@link IndexItem}s that match the given type and instantiate them. */ private Collection> _find(Class type, List> indices) { - List> result = new ArrayList>(); + List> result = new ArrayList<>(); for (IndexItem item : indices) { try { @@ -642,14 +633,12 @@ public abstract class ExtensionFinder implements ExtensionPoint { if(type.isAssignableFrom(extType)) { Object instance = item.instance(); if(instance!=null) - result.add(new ExtensionComponent(type.cast(instance),item.annotation())); + result.add(new ExtensionComponent<>(type.cast(instance),item.annotation())); } - } catch (LinkageError e) { + } catch (LinkageError|Exception e) { // sometimes the instantiation fails in an indirect classloading failure, // which results in a LinkageError LOGGER.log(logLevel(item), "Failed to load "+item.className(), e); - } catch (Exception e) { - LOGGER.log(logLevel(item), "Failed to load "+item.className(), e); } } @@ -676,12 +665,9 @@ public abstract class ExtensionFinder implements ExtensionPoint { extType = ((Method)e).getReturnType(); } else throw new AssertionError(); - // according to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6459208 - // this appears to be the only way to force a class initialization + // according to JDK-4993813 this is the only way to force class initialization Class.forName(extType.getName(),true,extType.getClassLoader()); - } catch (Exception e) { - LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e); - } catch (LinkageError e) { + } catch (Exception | LinkageError e) { LOGGER.log(logLevel(item), "Failed to scout "+item.className(), e); } } diff --git a/core/src/main/java/hudson/ExtensionList.java b/core/src/main/java/hudson/ExtensionList.java index 46447fbcdabaffddfb0716b0cbbb94a73569f073..f2fcab81d403e63588322b73ceacae33dce66617 100644 --- a/core/src/main/java/hudson/ExtensionList.java +++ b/core/src/main/java/hudson/ExtensionList.java @@ -46,6 +46,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import jenkins.util.io.OnMaster; /** * Retains the known extension instances for the given type 'T'. @@ -68,7 +69,7 @@ import javax.annotation.Nonnull; * @see jenkins.model.Jenkins#getExtensionList(Class) * @see jenkins.model.Jenkins#getDescriptorList(Class) */ -public class ExtensionList extends AbstractList { +public class ExtensionList extends AbstractList implements OnMaster { /** * @deprecated as of 1.417 * Use {@link #jenkins} @@ -203,6 +204,21 @@ public class ExtensionList extends AbstractList { } } + @Override + public boolean removeAll(Collection c) { + boolean removed = false; + try { + for (Object o : c) { + removed |= removeSync(o); + } + return removed; + } finally { + if (extensions != null && removed) { + fireOnChangeListeners(); + } + } + } + private synchronized boolean removeSync(Object o) { boolean removed = removeComponent(legacyInstances, o); if(extensions!=null) { @@ -390,14 +406,14 @@ public class ExtensionList extends AbstractList { /** * Gets the extension list for a given type. * Normally calls {@link Jenkins#getExtensionList(Class)} but falls back to an empty list - * in case {@link Jenkins#getInstance} is null. + * in case {@link Jenkins#getInstanceOrNull()} is null. * Thus it is useful to call from {@code all()} methods which need to behave gracefully during startup or shutdown. * @param type the extension point type * @return some list * @since 1.572 */ public static @Nonnull ExtensionList lookup(Class type) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); return j == null ? create((Jenkins) null, type) : j.getExtensionList(type); } diff --git a/core/src/main/java/hudson/ExtensionListListener.java b/core/src/main/java/hudson/ExtensionListListener.java index 26950b985a5d95be8fac6a881ce7076ad3c06da3..f5c8528add3995535060b3d39bd9bea75d447124 100644 --- a/core/src/main/java/hudson/ExtensionListListener.java +++ b/core/src/main/java/hudson/ExtensionListListener.java @@ -27,7 +27,7 @@ package hudson; * {@link ExtensionList} listener. * * @author tom.fennelly@gmail.com - * @since TODO + * @since 1.614 */ public abstract class ExtensionListListener { diff --git a/core/src/main/java/hudson/ExtensionListView.java b/core/src/main/java/hudson/ExtensionListView.java index 95ea80068c636ffc393785fb27f53ce7e4517961..59b81ffd95869297d20ea67694b923652235812d 100644 --- a/core/src/main/java/hudson/ExtensionListView.java +++ b/core/src/main/java/hudson/ExtensionListView.java @@ -24,7 +24,6 @@ package hudson; import jenkins.model.Jenkins; -import hudson.tasks.UserNameResolver; import hudson.util.CopyOnWriteList; import java.util.AbstractList; diff --git a/core/src/main/java/hudson/ExtensionPoint.java b/core/src/main/java/hudson/ExtensionPoint.java index f49a5a096cc7ba2b6671b3ec8a0dd5b23746f3a2..e544ed7576ad411694e868a149dbf2ee1a6971b2 100644 --- a/core/src/main/java/hudson/ExtensionPoint.java +++ b/core/src/main/java/hudson/ExtensionPoint.java @@ -29,6 +29,7 @@ import static java.lang.annotation.ElementType.TYPE; import java.lang.annotation.Retention; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Target; +import jenkins.util.io.OnMaster; /** * Marker interface that designates extensible components diff --git a/core/src/main/java/hudson/FilePath.java b/core/src/main/java/hudson/FilePath.java index d2778ba37e36fd7d86db8913f21228698c6d94d6..ece13ca3447e274b876860ca0ac2473902eba5dd 100644 --- a/core/src/main/java/hudson/FilePath.java +++ b/core/src/main/java/hudson/FilePath.java @@ -25,6 +25,8 @@ */ package hudson; +import jenkins.util.SystemProperties; +import com.google.common.annotations.VisibleForTesting; import com.jcraft.jzlib.GZIPInputStream; import com.jcraft.jzlib.GZIPOutputStream; import hudson.Launcher.LocalLauncher; @@ -33,7 +35,6 @@ import hudson.model.AbstractProject; import hudson.model.Computer; import hudson.model.Item; import hudson.model.TaskListener; -import hudson.org.apache.tools.tar.TarInputStream; import hudson.os.PosixAPI; import hudson.os.PosixException; import hudson.remoting.Callable; @@ -70,9 +71,10 @@ import org.apache.commons.io.input.CountingInputStream; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.FileSet; -import org.apache.tools.tar.TarEntry; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Stapler; import javax.annotation.CheckForNull; @@ -92,8 +94,8 @@ import java.io.OutputStreamWriter; import java.io.RandomAccessFile; import java.io.Serializable; import java.io.Writer; -import java.lang.reflect.Field; import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLConnection; @@ -120,6 +122,8 @@ import static hudson.Util.*; import javax.annotation.Nonnull; import javax.annotation.Nullable; import jenkins.security.MasterToSlaveCallable; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.jenkinsci.remoting.RoleChecker; import org.jenkinsci.remoting.RoleSensitive; @@ -128,7 +132,7 @@ import org.jenkinsci.remoting.RoleSensitive; * *

* Unlike {@link File}, which always implies a file path on the current computer, - * {@link FilePath} represents a file path on a specific slave or the master. + * {@link FilePath} represents a file path on a specific agent or the master. * * Despite that, {@link FilePath} can be used much like {@link File}. It exposes * a bunch of operations (and we should add more operations as long as they are @@ -175,7 +179,7 @@ import org.jenkinsci.remoting.RoleSensitive; * * *

- * When {@link FileCallable} is transfered to a remote node, it will be done so + * When {@link FileCallable} is transferred to a remote node, it will be done so * by using the same Java serialization scheme that the remoting module uses. * See {@link Channel} for more about this. * @@ -189,22 +193,27 @@ import org.jenkinsci.remoting.RoleSensitive; * @see VirtualFile */ public final class FilePath implements Serializable { + /** + * Maximum http redirects we will follow. This defaults to the same number as Firefox/Chrome tolerates. + */ + private static final int MAX_REDIRECTS = 20; + /** * When this {@link FilePath} represents the remote path, * this field is always non-null on master (the field represents - * the channel to the remote slave.) When transferred to a slave via remoting, + * the channel to the remote agent.) When transferred to a agent via remoting, * this field reverts back to null, since it's transient. * * When this {@link FilePath} represents a path on the master, - * this field is null on master. When transferred to a slave via remoting, + * this field is null on master. When transferred to a agent via remoting, * this field becomes non-null, representing the {@link Channel} * back to the master. * - * This is used to determine whether we are running on the master or the slave. + * This is used to determine whether we are running on the master or the agent. */ private transient VirtualChannel channel; - // since the platform of the slave might be different, can't use java.io.File + // since the platform of the agent might be different, can't use java.io.File private final String remote; /** @@ -260,7 +269,7 @@ public final class FilePath implements Serializable { return base.remote+'/'+rel.replace('\\','/'); } else { // need this replace, see Slave.getWorkspaceFor and AbstractItem.getFullName, nested jobs on Windows - // slaves will always have a rel containing at least one '/' character. JENKINS-13649 + // agents will always have a rel containing at least one '/' character. JENKINS-13649 return base.remote+'\\'+rel.replace('/','\\'); } } @@ -380,11 +389,8 @@ public final class FilePath implements Serializable { } public void zip(FilePath dst) throws IOException, InterruptedException { - OutputStream os = dst.write(); - try { + try (OutputStream os = dst.write()) { zip(os); - } finally { - os.close(); } } @@ -546,7 +552,7 @@ public final class FilePath implements Serializable { * @see #unzip(FilePath) */ public void unzipFrom(InputStream _in) throws IOException, InterruptedException { - final InputStream in = new RemoteInputStream(_in); + final InputStream in = new RemoteInputStream(_in, Flag.GREEDY); act(new SecureFileCallable() { public Void invoke(File dir, VirtualChannel channel) throws IOException { unzip(dir, in); @@ -585,11 +591,8 @@ public final class FilePath implements Serializable { if (p != null) { mkdirs(p); } - InputStream input = zip.getInputStream(e); - try { + try (InputStream input = zip.getInputStream(e)) { IOUtils.copy(input, writing(f)); - } finally { - input.close(); } try { FilePath target = new FilePath(f); @@ -715,7 +718,7 @@ public final class FilePath implements Serializable { */ public void untarFrom(InputStream _in, final TarCompression compression) throws IOException, InterruptedException { try { - final InputStream in = new RemoteInputStream(_in); + final InputStream in = new RemoteInputStream(_in, Flag.GREEDY); act(new SecureFileCallable() { public Void invoke(File dir, VirtualChannel channel) throws IOException { readFromTar("input stream",dir, compression.extract(in)); @@ -756,6 +759,10 @@ public final class FilePath implements Serializable { * @since 1.299 */ public boolean installIfNecessaryFrom(@Nonnull URL archive, @CheckForNull TaskListener listener, @Nonnull String message) throws IOException, InterruptedException { + return installIfNecessaryFrom(archive, listener, message, MAX_REDIRECTS); + } + + private boolean installIfNecessaryFrom(@Nonnull URL archive, @CheckForNull TaskListener listener, @Nonnull String message, int maxRedirects) throws InterruptedException, IOException { try { FilePath timestamp = this.child(".timestamp"); long lastModified = timestamp.lastModified(); @@ -778,14 +785,28 @@ public final class FilePath implements Serializable { } } - if (lastModified != 0 && con instanceof HttpURLConnection) { + if (con instanceof HttpURLConnection) { HttpURLConnection httpCon = (HttpURLConnection) con; int responseCode = httpCon.getResponseCode(); - if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) { - return false; - } else if (responseCode != HttpURLConnection.HTTP_OK) { - listener.getLogger().println("Skipping installation of " + archive + " to " + remote + " due to server error: " + responseCode + " " + httpCon.getResponseMessage()); - return false; + if (responseCode == HttpURLConnection.HTTP_MOVED_PERM + || responseCode == HttpURLConnection.HTTP_MOVED_TEMP) { + // follows redirect + if (maxRedirects > 0) { + String location = httpCon.getHeaderField("Location"); + listener.getLogger().println("Following redirect " + archive.toExternalForm() + " -> " + location); + return installIfNecessaryFrom(getUrlFactory().newURL(location), listener, message, maxRedirects - 1); + } else { + listener.getLogger().println("Skipping installation of " + archive + " to " + remote + " due to too many redirects."); + return false; + } + } + if (lastModified != 0) { + if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) { + return false; + } else if (responseCode != HttpURLConnection.HTTP_OK) { + listener.getLogger().println("Skipping installation of " + archive + " to " + remote + " due to server error: " + responseCode + " " + httpCon.getResponseMessage()); + return false; + } } } @@ -803,14 +824,14 @@ public final class FilePath implements Serializable { listener.getLogger().println(message); if (isRemote()) { - // First try to download from the slave machine. + // First try to download from the agent machine. try { act(new Unpack(archive)); timestamp.touch(sourceTimestamp); return true; } catch (IOException x) { if (listener != null) { - x.printStackTrace(listener.error("Failed to download " + archive + " from slave; will retry from master")); + x.printStackTrace(listener.error("Failed to download " + archive + " from agent; will retry from master")); } } } @@ -841,8 +862,7 @@ public final class FilePath implements Serializable { this.archive = archive; } @Override public Void invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { - InputStream in = archive.openStream(); - try { + try (InputStream in = archive.openStream()) { CountingInputStream cis = new CountingInputStream(in); try { if (archive.toExternalForm().endsWith(".zip")) { @@ -853,8 +873,6 @@ public final class FilePath implements Serializable { } catch (IOException x) { throw new IOException(String.format("Failed to unpack %s (%d bytes read)", archive, cis.getByteCount()), x); } - } finally { - in.close(); } return null; } @@ -867,11 +885,8 @@ public final class FilePath implements Serializable { * @since 1.293 */ public void copyFrom(URL url) throws IOException, InterruptedException { - InputStream in = url.openStream(); - try { + try (InputStream in = url.openStream()) { copyFrom(in); - } finally { - in.close(); } } @@ -881,11 +896,8 @@ public final class FilePath implements Serializable { * @since 1.293 */ public void copyFrom(InputStream in) throws IOException, InterruptedException { - OutputStream os = write(); - try { + try (OutputStream os = write()) { org.apache.commons.io.IOUtils.copy(in, os); - } finally { - os.close(); } } @@ -911,16 +923,9 @@ public final class FilePath implements Serializable { throw new IOException(e); } } else { - InputStream i = file.getInputStream(); - OutputStream o = write(); - try { + try (InputStream i = file.getInputStream(); + OutputStream o = write()) { org.apache.commons.io.IOUtils.copy(i,o); - } finally { - try { - o.close(); - } finally { - i.close(); - } } } } @@ -1134,7 +1139,7 @@ public final class FilePath implements Serializable { * @since 1.571 */ public @CheckForNull Computer toComputer() { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { for (Computer c : j.getComputers()) { if (getChannel()==c.getChannel()) { @@ -1369,11 +1374,8 @@ public final class FilePath implements Serializable { throw new IOException("Failed to create a temporary directory in "+dir,e); } - Writer w = new FileWriter(writing(f)); - try { + try (Writer w = new FileWriter(writing(f))) { w.write(contents); - } finally { - w.close(); } return f.getAbsolutePath(); @@ -1850,11 +1852,8 @@ public final class FilePath implements Serializable { * Reads this file into a string, by using the current system encoding. */ public String readToString() throws IOException, InterruptedException { - InputStream in = read(); - try { + try (InputStream in = read()) { return org.apache.commons.io.IOUtils.toString(in); - } finally { - in.close(); } } @@ -1904,11 +1903,8 @@ public final class FilePath implements Serializable { public Void invoke(File f, VirtualChannel channel) throws IOException { mkdirs(f.getParentFile()); FileOutputStream fos = new FileOutputStream(writing(f)); - Writer w = encoding != null ? new OutputStreamWriter(fos, encoding) : new OutputStreamWriter(fos); - try { + try (Writer w = encoding != null ? new OutputStreamWriter(fos, encoding) : new OutputStreamWriter(fos)) { w.write(content); - } finally { - w.close(); } return null; } @@ -1981,11 +1977,8 @@ public final class FilePath implements Serializable { */ public void copyTo(FilePath target) throws IOException, InterruptedException { try { - OutputStream out = target.write(); - try { + try (OutputStream out = target.write()) { copyTo(out); - } finally { - out.close(); } } catch (IOException e) { throw new IOException("Failed to copy "+this+" to "+target,e); @@ -2171,11 +2164,9 @@ public final class FilePath implements Serializable { Future future = target.actAsync(new SecureFileCallable() { private static final long serialVersionUID = 1L; public Void invoke(File f, VirtualChannel channel) throws IOException { - try { - readFromTar(remote + '/' + description, f,TarCompression.GZIP.extract(pipe.getIn())); + try (InputStream in = pipe.getIn()) { + readFromTar(remote + '/' + description, f,TarCompression.GZIP.extract(in)); return null; - } finally { - pipe.getIn().close(); } } }); @@ -2199,10 +2190,8 @@ public final class FilePath implements Serializable { Future future = actAsync(new SecureFileCallable() { private static final long serialVersionUID = 1L; public Integer invoke(File f, VirtualChannel channel) throws IOException { - try { - return writeToTar(f, scanner, TarCompression.GZIP.compress(pipe.getOut())); - } finally { - pipe.getOut().close(); + try (OutputStream out = pipe.getOut()) { + return writeToTar(f, scanner, TarCompression.GZIP.compress(out)); } } }); @@ -2268,42 +2257,39 @@ public final class FilePath implements Serializable { /** * Reads from a tar stream and stores obtained files to the base dir. + * Supports large files > 10 GB since 1.627 when this was migrated to use commons-compress. */ private void readFromTar(String name, File baseDir, InputStream in) throws IOException { - TarInputStream t = new TarInputStream(in); - try { - TarEntry te; - while ((te = t.getNextEntry()) != null) { - File f = new File(baseDir,te.getName()); - if(te.isDirectory()) { + + // TarInputStream t = new TarInputStream(in); + try (TarArchiveInputStream t = new TarArchiveInputStream(in)) { + TarArchiveEntry te; + while ((te = t.getNextTarEntry()) != null) { + File f = new File(baseDir, te.getName()); + if (te.isDirectory()) { mkdirs(f); } else { File parent = f.getParentFile(); if (parent != null) mkdirs(parent); writing(f); - byte linkFlag = (Byte) LINKFLAG_FIELD.get(te); - if (linkFlag==TarEntry.LF_SYMLINK) { + if (te.isSymbolicLink()) { new FilePath(f).symlinkTo(te.getLinkName(), TaskListener.NULL); } else { - IOUtils.copy(t,f); + IOUtils.copy(t, f); f.setLastModified(te.getModTime().getTime()); - int mode = te.getMode()&0777; - if(mode!=0 && !Functions.isWindows()) // be defensive - _chmod(f,mode); + int mode = te.getMode() & 0777; + if (mode != 0 && !Functions.isWindows()) // be defensive + _chmod(f, mode); } } } - } catch(IOException e) { - throw new IOException("Failed to extract "+name,e); + } catch (IOException e) { + throw new IOException("Failed to extract " + name, e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // process this later - throw new IOException("Failed to extract "+name,e); - } catch (IllegalAccessException e) { - throw new IOException("Failed to extract "+name,e); - } finally { - t.close(); + throw new IOException("Failed to extract " + name, e); } } @@ -2345,10 +2331,17 @@ public final class FilePath implements Serializable { } /** - * Default bound for {@link #validateAntFileMask(String, int)}. + * Same as {@link #validateFileMask(String, int, boolean)} with caseSensitive set to true + */ + public String validateAntFileMask(final String fileMasks, final int bound) throws IOException, InterruptedException { + return validateAntFileMask(fileMasks, bound, true); + } + + /** + * Default bound for {@link #validateAntFileMask(String, int, boolean)}. * @since 1.592 */ - public static int VALIDATE_ANT_FILE_MASK_BOUND = Integer.getInteger(FilePath.class.getName() + ".VALIDATE_ANT_FILE_MASK_BOUND", 10000); + public static int VALIDATE_ANT_FILE_MASK_BOUND = SystemProperties.getInteger(FilePath.class.getName() + ".VALIDATE_ANT_FILE_MASK_BOUND", 10000); /** * Like {@link #validateAntFileMask(String)} but performing only a bounded number of operations. @@ -2363,7 +2356,7 @@ public final class FilePath implements Serializable { * @throws InterruptedException not only in case of a channel failure, but also if too many operations were performed without finding any matches * @since 1.484 */ - public String validateAntFileMask(final String fileMasks, final int bound) throws IOException, InterruptedException { + public String validateAntFileMask(final String fileMasks, final int bound, final boolean caseSensitive) throws IOException, InterruptedException { return act(new MasterToSlaveFileCallable() { private static final long serialVersionUID = 1; public String invoke(File dir, VirtualChannel channel) throws IOException, InterruptedException { @@ -2374,15 +2367,21 @@ public final class FilePath implements Serializable { while(tokens.hasMoreTokens()) { final String fileMask = tokens.nextToken().trim(); - if(hasMatch(dir,fileMask)) + if(hasMatch(dir,fileMask,caseSensitive)) continue; // no error on this portion + + // JENKINS-5253 - if we can get some match in case insensitive mode + // and user requested case sensitive match, notify the user + if (caseSensitive && hasMatch(dir, fileMask, false)) { + return Messages.FilePath_validateAntFileMask_matchWithCaseInsensitive(fileMask); + } // in 1.172 we introduced an incompatible change to stop using ' ' as the separator // so see if we can match by using ' ' as the separator if(fileMask.contains(" ")) { boolean matched = true; for (String token : Util.tokenize(fileMask)) - matched &= hasMatch(dir,token); + matched &= hasMatch(dir,token,caseSensitive); if(matched) return Messages.FilePath_validateAntFileMask_whitespaceSeprator(); } @@ -2398,7 +2397,7 @@ public final class FilePath implements Serializable { if(idx==-1) break; f=f.substring(idx+1); - if(hasMatch(dir,f)) + if(hasMatch(dir,f,caseSensitive)) return Messages.FilePath_validateAntFileMask_doesntMatchAndSuggest(fileMask,f); } } @@ -2406,6 +2405,7 @@ public final class FilePath implements Serializable { {// check the (2) above next as this is more expensive. // Try prepending "**/" to see if that results in a match FileSet fs = Util.createFileSet(reading(dir),"**/"+fileMask); + fs.setCaseSensitive(caseSensitive); DirectoryScanner ds = fs.getDirectoryScanner(new Project()); if(ds.getIncludedFilesCount()!=0) { // try shorter name first so that the suggestion results in least amount of changes @@ -2425,7 +2425,7 @@ public final class FilePath implements Serializable { prefix+=f.substring(0,idx)+'/'; f=f.substring(idx+1); - if(hasMatch(dir,prefix+fileMask)) + if(hasMatch(dir,prefix+fileMask,caseSensitive)) return Messages.FilePath_validateAntFileMask_doesntMatchAndSuggest(fileMask, prefix+fileMask); } } @@ -2437,7 +2437,7 @@ public final class FilePath implements Serializable { String pattern = fileMask; while(true) { - if(hasMatch(dir,pattern)) { + if(hasMatch(dir,pattern,caseSensitive)) { // found a match if(previous==null) return Messages.FilePath_validateAntFileMask_portionMatchAndSuggest(fileMask,pattern); @@ -2463,7 +2463,7 @@ public final class FilePath implements Serializable { return null; // no error } - private boolean hasMatch(File dir, String pattern) throws InterruptedException { + private boolean hasMatch(File dir, String pattern, boolean bCaseSensitive) throws InterruptedException { class Cancel extends RuntimeException {} DirectoryScanner ds = bound == Integer.MAX_VALUE ? new DirectoryScanner() : new DirectoryScanner() { int ticks; @@ -2481,6 +2481,7 @@ public final class FilePath implements Serializable { }; ds.setBasedir(reading(dir)); ds.setIncludes(new String[] {pattern}); + ds.setCaseSensitive(bCaseSensitive); try { ds.scan(); } catch (Cancel c) { @@ -2506,19 +2507,58 @@ public final class FilePath implements Serializable { }); } + private static final UrlFactory DEFAULT_URL_FACTORY = new UrlFactory(); + + @Restricted(NoExternalUse.class) + static class UrlFactory { + public URL newURL(String location) throws MalformedURLException { + return new URL(location); + } + } + + private UrlFactory urlFactory; + + @VisibleForTesting + @Restricted(NoExternalUse.class) + void setUrlFactory(UrlFactory urlFactory) { + this.urlFactory = urlFactory; + } + + private UrlFactory getUrlFactory() { + if (urlFactory != null) { + return urlFactory; + } else { + return DEFAULT_URL_FACTORY; + } + } + /** - * Shortcut for {@link #validateFileMask(String)} in case the left-hand side can be null. + * Short for {@code validateFileMask(path, value, true)} */ public static FormValidation validateFileMask(@CheckForNull FilePath path, String value) throws IOException { + return FilePath.validateFileMask(path, value, true); + } + + /** + * Shortcut for {@link #validateFileMask(String,true,boolean)} as the left-hand side can be null. + */ + public static FormValidation validateFileMask(@CheckForNull FilePath path, String value, boolean caseSensitive) throws IOException { if(path==null) return FormValidation.ok(); - return path.validateFileMask(value); + return path.validateFileMask(value, true, caseSensitive); } /** - * Short for {@code validateFileMask(value,true)} + * Short for {@code validateFileMask(value, true, true)} */ public FormValidation validateFileMask(String value) throws IOException { - return validateFileMask(value,true); + return validateFileMask(value, true, true); + } + + /** + * Short for {@code validateFileMask(value, errorIfNotExist, true)} + */ + public FormValidation validateFileMask(String value, boolean errorIfNotExist) throws IOException { + return validateFileMask(value, errorIfNotExist, true); } /** @@ -2527,7 +2567,7 @@ public final class FilePath implements Serializable { * or admin permission if no such ancestor is found. * @since 1.294 */ - public FormValidation validateFileMask(String value, boolean errorIfNotExist) throws IOException { + public FormValidation validateFileMask(String value, boolean errorIfNotExist, boolean caseSensitive) throws IOException { checkPermissionForValidate(); value = fixEmpty(value); @@ -2538,7 +2578,7 @@ public final class FilePath implements Serializable { if(!exists()) // no workspace. can't check return FormValidation.ok(); - String msg = validateAntFileMask(value, VALIDATE_ANT_FILE_MASK_BOUND); + String msg = validateAntFileMask(value, VALIDATE_ANT_FILE_MASK_BOUND, caseSensitive); if(errorIfNotExist) return FormValidation.error(msg); else return FormValidation.warning(msg); } catch (InterruptedException e) { @@ -2725,20 +2765,6 @@ public final class FilePath implements Serializable { } }; - private static final Field LINKFLAG_FIELD = getTarEntryLinkFlagField(); - - private static Field getTarEntryLinkFlagField() { - try { - Field f = TarEntry.class.getDeclaredField("linkFlag"); - f.setAccessible(true); - return f; - } catch (SecurityException e) { - throw new AssertionError(e); - } catch (NoSuchFieldException e) { - throw new AssertionError(e); - } - } - /** * Gets the {@link FilePath} representation of the "~" directory * (User's home directory in the Unix sense) of the given channel. diff --git a/core/src/main/java/hudson/FileSystemProvisioner.java b/core/src/main/java/hudson/FileSystemProvisioner.java index 15932a1dcabf932bb493a7c4feea1a52f8a865c9..8b9967e2bb63694dec3e5361c63a5cd5e08a204f 100644 --- a/core/src/main/java/hudson/FileSystemProvisioner.java +++ b/core/src/main/java/hudson/FileSystemProvisioner.java @@ -34,6 +34,7 @@ import hudson.util.io.ArchiverFactory; import jenkins.model.Jenkins; import hudson.model.listeners.RunListener; import hudson.scm.SCM; +import org.jenkinsci.Symbol; import java.io.BufferedOutputStream; import java.io.File; @@ -51,7 +52,7 @@ import java.io.OutputStream; * STILL A WORK IN PROGRESS. SUBJECT TO CHANGE! DO NOT EXTEND. * * TODO: is this per {@link Computer}? Per {@link Job}? - * -> probably per slave. + * -> probably per agent. * *

Design Problems

*
    @@ -71,7 +72,7 @@ import java.io.OutputStream; * one more configuration option. It's especially tricky because * during the configuration we don't know the OS type. * - * OTOH special slave type like the ones for network.com grid can + * OTOH special agent type like the ones for network.com grid can * hide this. *
* @@ -80,8 +81,8 @@ import java.io.OutputStream; * * To recap, * - * - when a slave connects, we auto-detect the file system provisioner. - * (for example, ZFS FSP would check the slave root user prop + * - when an agent connects, we auto-detect the file system provisioner. + * (for example, ZFS FSP would check the agent root user prop * and/or attempt to "pfexec zfs create" and take over.) * * - the user may configure jobs for snapshot collection, along with @@ -214,11 +215,8 @@ public abstract class FileSystemProvisioner implements ExtensionPoint, Describab */ public WorkspaceSnapshot snapshot(AbstractBuild build, FilePath ws, String glob, TaskListener listener) throws IOException, InterruptedException { File wss = new File(build.getRootDir(),"workspace.tgz"); - OutputStream os = new BufferedOutputStream(new FileOutputStream(wss)); - try { - ws.archive(ArchiverFactory.TARGZ,os,glob); - } finally { - os.close(); + try (OutputStream os = new BufferedOutputStream(new FileOutputStream(wss))) { + ws.archive(ArchiverFactory.TARGZ, os, glob); } return new WorkspaceSnapshotImpl(); } @@ -235,10 +233,10 @@ public abstract class FileSystemProvisioner implements ExtensionPoint, Describab } } - @Extension + @Extension @Symbol("standard") public static final class DescriptorImpl extends FileSystemProvisionerDescriptor { public boolean discard(FilePath ws, TaskListener listener) throws IOException, InterruptedException { - // the default provisioner doens't do anything special, + // the default provisioner does not do anything special, // so allow other types to manage it return false; } diff --git a/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java b/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java index 2cb0506fa9da19b11cea287563d6a6c4343e7b9c..ce0371ceec0ecf79d7c4d06061e5a558358dfa6f 100644 --- a/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java +++ b/core/src/main/java/hudson/FileSystemProvisionerDescriptor.java @@ -38,9 +38,9 @@ public abstract class FileSystemProvisionerDescriptor extends Descriptor - * Because users may modify the file system behind Hudson, and slaves may come and go when - * configuration changes hapen, in general case Hudson is unable to keep track of which jobs - * have workspaces in which slaves. + * Because users may modify the file system behind Hudson, and agents may come and go when + * configuration changes happen, in general case Hudson is unable to keep track of which jobs + * have workspaces in which agents. * *

* So instead we rey on a garbage collection mechanism, to look at workspaces left in the file system diff --git a/core/src/main/java/hudson/Functions.java b/core/src/main/java/hudson/Functions.java index a285476b7a1d9875e172099c5ed5b0b57ac615a1..565d4dc50227c01c20a933cb552fee7d01e12477 100644 --- a/core/src/main/java/hudson/Functions.java +++ b/core/src/main/java/hudson/Functions.java @@ -25,6 +25,8 @@ */ package hudson; +import hudson.model.Slave; +import jenkins.util.SystemProperties; import hudson.cli.CLICommand; import hudson.console.ConsoleAnnotationDescriptor; import hudson.console.ConsoleAnnotatorFactory; @@ -74,7 +76,10 @@ import hudson.tasks.Publisher; import hudson.tasks.UserAvatarResolver; import hudson.util.Area; import hudson.util.FormValidation.CheckMethod; +import hudson.util.HudsonIsLoading; +import hudson.util.HudsonIsRestarting; import hudson.util.Iterators; +import hudson.util.jna.GNUCLibrary; import hudson.util.Secret; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; @@ -82,6 +87,7 @@ import hudson.widgets.RenderOnDemandClosure; import java.io.File; import java.io.IOException; +import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.lang.management.LockInfo; @@ -126,7 +132,6 @@ import javax.servlet.http.HttpServletResponse; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; -import jenkins.model.GlobalConfigurationCategory.Unclassified; import jenkins.model.Jenkins; import jenkins.model.ModelObjectWithChildren; import jenkins.model.ModelObjectWithContextMenu; @@ -149,14 +154,15 @@ import org.kohsuke.stapler.jelly.InternationalizedStringExpression.RawHtmlArgume import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import hudson.model.PasswordParameterDefinition; import hudson.util.RunList; -import java.io.PrintWriter; import java.util.concurrent.atomic.AtomicLong; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import org.apache.commons.io.IOUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.accmod.restrictions.DoNotUse; /** * Utility functions used in views. @@ -208,20 +214,28 @@ public class Functions { /** * During Jenkins start-up, before {@link InitMilestone#PLUGINS_STARTED} the extensions lists will be empty - * and they are not guaranteed to be fully populated until after {@link InitMilestone#EXTENSIONS_AUGMENTED}. + * and they are not guaranteed to be fully populated until after {@link InitMilestone#EXTENSIONS_AUGMENTED}, + * similarly, during termination after {@link Jenkins#isTerminating()} is set, it is no longer safe to access + * the extensions lists. * If you attempt to access the extensions list from a UI thread while the extensions are being loaded you will * hit a big honking great monitor lock that will block until the effective extension list has been determined * (as if a plugin fails to start, all of the failed plugin's extensions and any dependent plugins' extensions * will have to be evicted from the list of extensions. In practical terms this only affects the * "Jenkins is loading" screen, but as that screen uses the generic layouts we provide this utility method * so that the generic layouts can avoid iterating extension lists while Jenkins is starting up. + * If you attempt to access the extensions list from a UI thread while Jenkins is being shut down, the extensions + * themselves may no longer be in a valid state and could attempt to revive themselves and block termination. + * In actual terms the termination only affects those views required to render {@link HudsonIsRestarting}'s + * {@code index.jelly} which is the same set as the {@link HudsonIsLoading} pages so it makes sense to + * use both checks here. * * @return {@code true} if the extensions lists have been populated. * @since 1.607 */ public static boolean isExtensionsAvailable() { - final Jenkins jenkins = Jenkins.getInstance(); - return jenkins != null && jenkins.getInitLevel().compareTo(InitMilestone.EXTENSIONS_AUGMENTED) >= 0; + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + return jenkins != null && jenkins.getInitLevel().compareTo(InitMilestone.EXTENSIONS_AUGMENTED) >= 0 + && !jenkins.isTerminating(); } public static void initPageVariables(JellyContext context) { @@ -461,6 +475,15 @@ public class Functions { public static boolean isWindows() { return File.pathSeparatorChar==';'; } + + public static boolean isGlibcSupported() { + try { + GNUCLibrary.LIBC.getpid(); + return true; + } catch(Throwable t) { + return false; + } + } public static List getLogRecords() { return Jenkins.logRecords; @@ -553,7 +576,7 @@ public class Functions { /** * Set to true if you need to use the debug version of YUI. */ - public static boolean DEBUG_YUI = Boolean.getBoolean("debug.YUI"); + public static boolean DEBUG_YUI = SystemProperties.getBoolean("debug.YUI"); /** * Creates a sub map by using the given range (both ends inclusive). @@ -608,7 +631,7 @@ public class Functions { response.addCookie(c); } if (refresh) { - response.addHeader("Refresh", System.getProperty("hudson.Functions.autoRefreshSeconds", "10")); + response.addHeader("Refresh", SystemProperties.getString("hudson.Functions.autoRefreshSeconds", "10")); } } @@ -830,7 +853,7 @@ public class Functions { */ public static String getFooterURL() { if(footerURL == null) { - footerURL = System.getProperty("hudson.footerURL"); + footerURL = SystemProperties.getString("hudson.footerURL"); if(StringUtils.isBlank(footerURL)) { footerURL = "http://jenkins-ci.org/"; } @@ -843,6 +866,10 @@ public class Functions { return JobPropertyDescriptor.getPropertyDescriptors(clazz); } + public static List getJobPropertyDescriptors(Job job) { + return DescriptorVisibilityFilter.apply(job, JobPropertyDescriptor.getPropertyDescriptors(job.getClass())); + } + public static List> getBuildWrapperDescriptors(AbstractProject project) { return BuildWrappers.getFor(project); } @@ -867,10 +894,24 @@ public class Functions { return SCM._for(project); } + /** + * @since 2.12 + * @deprecated replaced by {@link Slave.SlaveDescriptor#computerLauncherDescriptors(Slave)} + */ + @Deprecated + @Restricted(DoNotUse.class) + @RestrictedSince("2.12") public static List> getComputerLauncherDescriptors() { return Jenkins.getInstance().>getDescriptorList(ComputerLauncher.class); } + /** + * @since 2.12 + * @deprecated replaced by {@link Slave.SlaveDescriptor#retentionStrategyDescriptors(Slave)} + */ + @Deprecated + @Restricted(DoNotUse.class) + @RestrictedSince("2.12") public static List>> getRetentionStrategyDescriptors() { return RetentionStrategy.all(); } @@ -891,6 +932,13 @@ public class Functions { return MyViewsTabBar.all(); } + /** + * @deprecated replaced by {@link Slave.SlaveDescriptor#nodePropertyDescriptors(Slave)} + * @since 2.12 + */ + @Deprecated + @Restricted(DoNotUse.class) + @RestrictedSince("2.12") public static List getNodePropertyDescriptors(Class clazz) { List result = new ArrayList(); Collection list = (Collection) Jenkins.getInstance().getDescriptorList(NodeProperty.class); @@ -943,12 +991,8 @@ public class Functions { Descriptor d = c.getInstance(); if (d.getGlobalConfigPage()==null) continue; - if (d instanceof GlobalConfiguration) { - if (predicate.apply(((GlobalConfiguration)d).getCategory())) - r.add(new Tag(c.ordinal(), d)); - } else { - if (predicate.apply(GlobalConfigurationCategory.get(Unclassified.class))) - r.add(new Tag(0, d)); + if (predicate.apply(d.getCategory())) { + r.add(new Tag(c.ordinal(), d)); } } Collections.sort(r); @@ -1387,7 +1431,7 @@ public class Functions { /** * If the value exists, return that value. Otherwise return the default value. *

- * Starting 1.294, JEXL supports the elvis operator "x?:y" that supercedes this. + * Starting 1.294, JEXL supports the elvis operator "x?:y" that supersedes this. * * @since 1.150 */ @@ -1399,10 +1443,15 @@ public class Functions { * Prints a stack trace from an exception into a readable form. * Unlike {@link Throwable#printStackTrace(PrintWriter)}, this implementation follows the suggestion of JDK-6507809 * to produce a linear trace even when {@link Throwable#getCause} is used. - * @param t any throwable - * @return generally a multiline string ending in a (platform-specific) newline + * @param t Input {@link Throwable} + * @return If {@code t} is not null, generally a multiline string ending in a (platform-specific) newline; + * otherwise, the method returns a default + * "No exception details" string. */ - public static @Nonnull String printThrowable(@Nonnull Throwable t) { + public static @Nonnull String printThrowable(@CheckForNull Throwable t) { + if (t == null) { + return Messages.Functions_NoExceptionDetails(); + } StringBuilder s = new StringBuilder(); doPrintStackTrace(s, t, null); return s.toString(); @@ -1544,10 +1593,12 @@ public class Functions { /** * Computes the hyperlink to actions, to handle the situation when the {@link Action#getUrlName()} * returns absolute URL. + * + * @return null in case the action should not be presented to the user. */ - public static String getActionUrl(String itUrl,Action action) { + public static @CheckForNull String getActionUrl(String itUrl,Action action) { String urlName = action.getUrlName(); - if(urlName==null) return null; // to avoid NPE and fail to render the whole page + if(urlName==null) return null; // Should not be displayed try { if (new URI(urlName).isAbsolute()) { return urlName; @@ -1584,15 +1635,11 @@ public class Functions { return projectName; } - public String getSystemProperty(String key) { - return System.getProperty(key); - } - /** * Obtains the host name of the Hudson server that clients can use to talk back to. *

* This is primarily used in slave-agent.jnlp.jelly to specify the destination - * that the slaves talk to. + * that the agents talk to. */ public String getServerName() { // Try to infer this from the configured root URL. @@ -1666,7 +1713,7 @@ public class Functions { */ public static List getPageDecorators() { // this method may be called to render start up errors, at which point Hudson doesn't exist yet. see HUDSON-3608 - if(Jenkins.getInstance()==null) return Collections.emptyList(); + if(Jenkins.getInstanceOrNull()==null) return Collections.emptyList(); return PageDecorator.all(); } @@ -1688,13 +1735,13 @@ public class Functions { } public static String getCrumb(StaplerRequest req) { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; return issuer != null ? issuer.getCrumb(req) : ""; } public static String getCrumbRequestField() { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); CrumbIssuer issuer = h != null ? h.getCrumbIssuer() : null; return issuer != null ? issuer.getDescriptor().getCrumbRequestField() : ""; } @@ -1759,8 +1806,17 @@ public class Functions { */ public String getPasswordValue(Object o) { if (o==null) return null; - if (o instanceof Secret) return ((Secret)o).getEncryptedValue(); - if (getIsUnitTest()) { + if (o instanceof Secret) { + StaplerRequest req = Stapler.getCurrentRequest(); + if (req != null) { + Item item = req.findAncestorObject(Item.class); + if (item != null && !item.hasPermission(Item.CONFIGURE)) { + return "********"; + } + } + return ((Secret) o).getEncryptedValue(); + } + if (getIsUnitTest() && !o.equals(PasswordParameterDefinition.DEFAULT_VALUE)) { throw new SecurityException("attempted to render plaintext ‘" + o + "’ in password field; use a getter of type Secret instead"); } return o.toString(); @@ -1789,7 +1845,7 @@ public class Functions { * the permission can't be configured in the security screen). Got it?

*/ public static boolean isArtifactsPermissionEnabled() { - return Boolean.getBoolean("hudson.security.ArtifactsPermission"); + return SystemProperties.getBoolean("hudson.security.ArtifactsPermission"); } /** @@ -1804,7 +1860,7 @@ public class Functions { * control on the "Wipe Out Workspace" action.

*/ public static boolean isWipeOutPermissionEnabled() { - return Boolean.getBoolean("hudson.security.WipeOutPermission"); + return SystemProperties.getBoolean("hudson.security.WipeOutPermission"); } public static String createRenderOnDemandProxy(JellyContext context, String attributesToCapture) { @@ -1924,7 +1980,7 @@ public class Functions { * discovery of Jenkins. */ public static void advertiseHeaders(HttpServletResponse rsp) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j!=null) { rsp.setHeader("X-Hudson","1.395"); rsp.setHeader("X-Jenkins", Jenkins.VERSION); @@ -1932,7 +1988,7 @@ public class Functions { TcpSlaveAgentListener tal = j.tcpSlaveAgentListener; if (tal !=null) { - int p = TcpSlaveAgentListener.CLI_PORT !=null ? TcpSlaveAgentListener.CLI_PORT : tal.getPort(); + int p = tal.getAdvertisedPort(); rsp.setIntHeader("X-Hudson-CLI-Port", p); rsp.setIntHeader("X-Jenkins-CLI-Port", p); rsp.setIntHeader("X-Jenkins-CLI2-Port", p); diff --git a/core/src/main/java/hudson/Launcher.java b/core/src/main/java/hudson/Launcher.java index 974fc2cba7734ae877a4c75844104c784275c4be..4e8d0b58ab4494e056e2b12ad15684a9aad76ec1 100644 --- a/core/src/main/java/hudson/Launcher.java +++ b/core/src/main/java/hudson/Launcher.java @@ -29,7 +29,6 @@ import hudson.util.QuotedStringTokenizer; import jenkins.model.Jenkins; import hudson.model.TaskListener; import hudson.model.Node; -import hudson.remoting.Callable; import hudson.remoting.Channel; import hudson.remoting.Pipe; import hudson.remoting.RemoteInputStream; @@ -43,6 +42,8 @@ import org.apache.commons.io.input.NullInputStream; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import javax.annotation.CheckForNull; +import javax.annotation.concurrent.GuardedBy; import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; @@ -58,6 +59,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import static org.apache.commons.io.output.NullOutputStream.NULL_OUTPUT_STREAM; +import hudson.Proc.ProcWithJenkins23271Patch; /** * Starts a process. @@ -131,7 +133,7 @@ public abstract class Launcher { * @deprecated since 2008-11-16. * See the javadoc for why this is inherently unreliable. If you are trying to * figure out the current {@link Computer} from within a build, use - * {@link Computer#currentComputer()} + * {@link FilePath#toComputer()} or {@link Computer#currentComputer()}. */ @Deprecated public Computer getComputer() { @@ -298,7 +300,7 @@ public abstract class Launcher { * *

* In adition to what the current process - * is inherited (if this is going to be launched from a slave agent, that + * is inherited (if this is going to be launched from a agent agent, that * becomes the "current" process), these variables will be also set. */ public ProcStarter envs(Map overrides) { @@ -384,9 +386,37 @@ public abstract class Launcher { /** * Starts the process and waits for its completion. + * @return Return code of the invoked process + * @throws IOException Operation error (e.g. remote call failure) + * @throws InterruptedException The process has been interrupted */ public int join() throws IOException, InterruptedException { - return start().join(); + // The logging around procHolderForJoin prevents the preliminary object deallocation we saw in JENKINS-23271 + final Proc procHolderForJoin = start(); + LOGGER.log(Level.FINER, "Started the process {0}", procHolderForJoin); + + if (procHolderForJoin instanceof ProcWithJenkins23271Patch) { + return procHolderForJoin.join(); + } else { + // Fallback to the internal handling logic + if (!(procHolderForJoin instanceof LocalProc)) { + // We consider that the process may be at risk of JENKINS-23271 + LOGGER.log(Level.FINE, "Process {0} of type {1} is neither {2} nor instance of {3}. " + + "If this process operates with Jenkins agents via remote invocation, you may get into JENKINS-23271", + new Object[] {procHolderForJoin, procHolderForJoin.getClass(), LocalProc.class, ProcWithJenkins23271Patch.class}); + } + try { + final int returnCode = procHolderForJoin.join(); + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.log(Level.FINER, "Process {0} has finished with the return code {1}", new Object[]{procHolderForJoin, returnCode}); + } + return returnCode; + } finally { + if (procHolderForJoin.isAlive()) { // Should never happen but this forces Proc to not be removed and early GC by escape analysis + LOGGER.log(Level.WARNING, "Process {0} has not finished after the join() method completion", procHolderForJoin); + } + } + } } /** @@ -612,7 +642,7 @@ public abstract class Launcher { * from the current process * @param envVars * Environment variable overrides. In addition to what the current process - * is inherited (if this is going to be launched from a slave agent, that + * is inherited (if this is going to be launched from an agent, that * becomes the "current" process), these variables will be also set. */ public abstract Channel launchChannel(String[] cmd, OutputStream out, FilePath workDir, Map envVars) throws IOException, InterruptedException; @@ -973,7 +1003,7 @@ public abstract class Launcher { private static final long serialVersionUID = 1L; } - public static final class ProcImpl extends Proc { + public static final class ProcImpl extends Proc implements ProcWithJenkins23271Patch { private final RemoteProcess process; private final IOTriplet io; @@ -984,12 +1014,28 @@ public abstract class Launcher { @Override public void kill() throws IOException, InterruptedException { - process.kill(); + try { + process.kill(); + } finally { + if (this.isAlive()) { // Should never happen but this forces Proc to not be removed and early GC by escape analysis + LOGGER.log(Level.WARNING, "Process {0} has not really finished after the kill() method execution", this); + } + } } @Override public int join() throws IOException, InterruptedException { - return process.join(); + try { + final int returnCode = process.join(); + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.log(Level.FINER, "Process {0} has finished with the return code {1}", new Object[]{this, returnCode}); + } + return returnCode; + } finally { + if (this.isAlive()) { // Should never happen but this forces Proc to not be removed and early GC by escape analysis + LOGGER.log(Level.WARNING, "Process {0} has not really finished after the join() method completion", this); + } + } } @Override diff --git a/core/src/main/java/hudson/LauncherDecorator.java b/core/src/main/java/hudson/LauncherDecorator.java index 3bd5f7d0212b56bb87be7ebe56d1e5bda08c96c7..86f69fe496a2e3f6cfabe3cb8ddbe15bcc3fe0f0 100644 --- a/core/src/main/java/hudson/LauncherDecorator.java +++ b/core/src/main/java/hudson/LauncherDecorator.java @@ -1,6 +1,5 @@ package hudson; -import jenkins.model.Jenkins; import hudson.model.Node; import hudson.model.Executor; import hudson.tasks.BuildWrapper; diff --git a/core/src/main/java/hudson/LocalPluginManager.java b/core/src/main/java/hudson/LocalPluginManager.java index 4cfbf6ad93343a04c666e5277cb8c999ecd3b309..25e48c053d0bf2dc7ef897dd6db8f0261e979ce3 100644 --- a/core/src/main/java/hudson/LocalPluginManager.java +++ b/core/src/main/java/hudson/LocalPluginManager.java @@ -24,31 +24,46 @@ package hudson; +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.NonNull; +import jenkins.util.SystemProperties; import jenkins.model.Jenkins; import javax.servlet.ServletContext; import java.io.File; -import java.io.IOException; -import java.net.URL; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; -import java.util.Set; -import java.util.logging.Level; import java.util.logging.Logger; /** - * {@link PluginManager} + * Default implementation of {@link PluginManager}. * * @author Kohsuke Kawaguchi */ public class LocalPluginManager extends PluginManager { - public LocalPluginManager(Jenkins jenkins) { - super(jenkins.servletContext, new File(jenkins.getRootDir(),"plugins")); + /** + * Creates a new LocalPluginManager + * @param context Servlet context. Provided for compatibility as {@code Jenkins.getInstance().servletContext} should be used. + * @param rootDir Jenkins home directory. + */ + public LocalPluginManager(@CheckForNull ServletContext context, @NonNull File rootDir) { + super(context, new File(rootDir,"plugins")); + } + + /** + * Creates a new LocalPluginManager + * @param jenkins Jenkins instance that will use the plugin manager. + */ + public LocalPluginManager(@NonNull Jenkins jenkins) { + this(jenkins.servletContext, jenkins.getRootDir()); } - public LocalPluginManager(File rootDir) { - super(null, new File(rootDir,"plugins")); + /** + * Creates a new LocalPluginManager + * @param rootDir Jenkins home directory. + */ + public LocalPluginManager(@NonNull File rootDir) { + this(null, rootDir); } /** @@ -60,32 +75,15 @@ public class LocalPluginManager extends PluginManager { @Override protected Collection loadBundledPlugins() { // this is used in tests, when we want to override the default bundled plugins with .jpl (or .hpl) versions - if (System.getProperty("hudson.bundled.plugins") != null) { + if (SystemProperties.getString("hudson.bundled.plugins") != null) { return Collections.emptySet(); } - Set names = new HashSet(); - - ServletContext context = Jenkins.getInstance().servletContext; - - for( String path : Util.fixNull((Set)context.getResourcePaths("/WEB-INF/plugins"))) { - String fileName = path.substring(path.lastIndexOf('/')+1); - if(fileName.length()==0) { - // see http://www.nabble.com/404-Not-Found-error-when-clicking-on-help-td24508544.html - // I suspect some containers are returning directory names. - continue; - } - try { - names.add(fileName); - - URL url = context.getResource(path); - copyBundledPlugin(url, fileName); - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failed to extract the bundled plugin "+fileName,e); - } + try { + return loadPluginsFromWar("/WEB-INF/plugins"); + } finally { + loadDetachedPlugins(); } - - return names; } private static final Logger LOGGER = Logger.getLogger(LocalPluginManager.class.getName()); diff --git a/core/src/main/java/hudson/Main.java b/core/src/main/java/hudson/Main.java index cf8a168ba115549ba3e6be45cbdf70423198311d..8e8ec46dd40adffefc2a88e11256d8b36b46a8db 100644 --- a/core/src/main/java/hudson/Main.java +++ b/core/src/main/java/hudson/Main.java @@ -23,6 +23,7 @@ */ package hudson; +import jenkins.util.SystemProperties; import hudson.util.DualOutputStream; import hudson.util.EncodingStream; import com.thoughtworks.xstream.core.util.Base64Encoder; @@ -218,10 +219,10 @@ public class Main { /** * Set to true if we are running inside "mvn hpi:run" or "mvn hudson-dev:run" */ - public static boolean isDevelopmentMode = Boolean.getBoolean(Main.class.getName()+".development"); + public static boolean isDevelopmentMode = SystemProperties.getBoolean(Main.class.getName()+".development"); /** * Time out for socket connection to Hudson. */ - public static final int TIMEOUT = Integer.getInteger(Main.class.getName()+".timeout",15000); + public static final int TIMEOUT = SystemProperties.getInteger(Main.class.getName()+".timeout",15000); } diff --git a/core/src/main/java/hudson/Plugin.java b/core/src/main/java/hudson/Plugin.java index 4808f208eddb3bd8fc27690c4b054eb4263ac399..75af4fda013ef329000e81e1bed297d63dc6ab6a 100644 --- a/core/src/main/java/hudson/Plugin.java +++ b/core/src/main/java/hudson/Plugin.java @@ -40,15 +40,18 @@ import java.io.File; import net.sf.json.JSONObject; import com.thoughtworks.xstream.XStream; +import hudson.init.Initializer; +import hudson.init.Terminator; import java.net.URI; import java.net.URISyntaxException; +import jenkins.model.GlobalConfiguration; import org.kohsuke.stapler.HttpResponses; /** * Base class of Hudson plugin. * *

- * A plugin may derive from this class, or it may directly define extension + * A plugin may {@linkplain #Plugin derive from this class}, or it may directly define extension * points annotated with {@link hudson.Extension}. For a list of extension * points, see * https://wiki.jenkins-ci.org/display/JENKINS/Extension+points. @@ -78,6 +81,22 @@ import org.kohsuke.stapler.HttpResponses; */ public abstract class Plugin implements Saveable { + /** + * You do not need to create custom subtypes: + *

    + *
  • {@code config.jelly}, {@link #configure(StaplerRequest, JSONObject)}, {@link #load}, and {@link #save} + * can be replaced by {@link GlobalConfiguration} + *
  • {@link #start} and {@link #postInitialize} can be replaced by {@link Initializer} (or {@link ItemListener#onLoaded}) + *
  • {@link #stop} can be replaced by {@link Terminator} + *
  • {@link #setServletContext} can be replaced by {@link Jenkins#servletContext} + *
+ * Note that every plugin gets a {@link DummyImpl} by default, + * which will still route the URL space, serve {@link #getWrapper}, and so on. + * @deprecated Use more modern APIs rather than subclassing. + */ + @Deprecated + protected Plugin() {} + /** * Set by the {@link PluginManager}, before the {@link #start()} method is called. * This points to the {@link PluginWrapper} that wraps diff --git a/core/src/main/java/hudson/PluginManager.java b/core/src/main/java/hudson/PluginManager.java index 443716eed5867ffbfa0ac0c44d5987bf95731b8d..c0f08883e7e35920f1f2b93fd53764d044c32017 100644 --- a/core/src/main/java/hudson/PluginManager.java +++ b/core/src/main/java/hudson/PluginManager.java @@ -23,6 +23,10 @@ */ package hudson; +import edu.umd.cs.findbugs.annotations.NonNull; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.security.ACLContext; +import jenkins.util.SystemProperties; import hudson.PluginWrapper.Dependency; import hudson.init.InitMilestone; import hudson.init.InitStrategy; @@ -36,41 +40,53 @@ import hudson.model.Failure; import hudson.model.ItemGroupMixIn; import hudson.model.UpdateCenter; import hudson.model.UpdateSite; +import hudson.model.UpdateCenter.DownloadJob; +import hudson.model.UpdateCenter.InstallationJob; +import hudson.security.ACL; import hudson.security.Permission; import hudson.security.PermissionScope; import hudson.util.CyclicGraphDetector; import hudson.util.CyclicGraphDetector.CycleDetectedException; -import hudson.util.IOUtils; import hudson.util.PersistedList; import hudson.util.Service; import hudson.util.VersionNumber; import hudson.util.XStream2; import jenkins.ClassLoaderReflectionToolkit; import jenkins.InitReactorRunner; +import jenkins.MissingDependencyException; import jenkins.RestartRequiredException; import jenkins.YesNoMaybe; +import jenkins.install.InstallState; +import jenkins.install.InstallUtil; import jenkins.model.Jenkins; import jenkins.util.io.OnMaster; import jenkins.util.xml.RestrictiveEntityResolver; import net.sf.json.JSONArray; import net.sf.json.JSONObject; + +import org.acegisecurity.Authentication; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.LogFactory; +import org.jenkinsci.Symbol; import org.jenkinsci.bytecode.Transformer; import org.jvnet.hudson.reactor.Executable; import org.jvnet.hudson.reactor.Reactor; import org.jvnet.hudson.reactor.ReactorException; import org.jvnet.hudson.reactor.TaskBuilder; import org.jvnet.hudson.reactor.TaskGraphBuilder; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerOverridable; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; @@ -78,16 +94,20 @@ import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; import java.io.Closeable; import java.io.File; +import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; @@ -97,11 +117,14 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -118,6 +141,14 @@ import org.xml.sax.helpers.DefaultHandler; import static hudson.init.InitMilestone.*; import hudson.model.DownloadService; import hudson.util.FormValidation; +import java.io.ByteArrayInputStream; +import java.net.JarURLConnection; +import java.net.URLConnection; +import java.util.jar.JarEntry; + +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.SEVERE; import static java.util.logging.Level.WARNING; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -125,10 +156,101 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Manages {@link PluginWrapper}s. * + *

+ * Setting default Plugin Managers. The default plugin manager in {@code Jenkins} can be replaced by defining a + * System Property (hudson.PluginManager.className). See {@link #createDefault(Jenkins)}. + * This className should be available on early startup, so it cannot come only from a library + * (e.g. Jenkins module or Extra library dependency in the WAR file project). + * Plugins cannot be used for such purpose. + * In order to be correctly instantiated, the class definition must have at least one constructor with the same + * signature as the following ones: + *

    + *
  1. {@link LocalPluginManager#LocalPluginManager(Jenkins)}
  2. + *
  3. {@link LocalPluginManager#LocalPluginManager(ServletContext, File)}
  4. + *
  5. {@link LocalPluginManager#LocalPluginManager(File)}
  6. + *
+ * Constructors are searched in the order provided above and only the first found suitable constructor is + * tried to build an instance. In the last two cases the {@link File} argument refers to the Jenkins home directory. + * * @author Kohsuke Kawaguchi */ @ExportedBean -public abstract class PluginManager extends AbstractModelObject implements OnMaster { +public abstract class PluginManager extends AbstractModelObject implements OnMaster, StaplerOverridable { + /** Custom plugin manager system property or context param. */ + public static final String CUSTOM_PLUGIN_MANAGER = PluginManager.class.getName() + ".className"; + + /** Accepted constructors for custom plugin manager, in the order they are tried. */ + private enum PMConstructor { + JENKINS { + @Override + @NonNull PluginManager doCreate(@NonNull Class klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException { + return klass.getConstructor(Jenkins.class).newInstance(jenkins); + } + }, + SC_FILE { + @Override + @NonNull PluginManager doCreate(@NonNull Class klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException { + return klass.getConstructor(ServletContext.class, File.class).newInstance(jenkins.servletContext, jenkins.getRootDir()); + } + }, + FILE { + @Override + @NonNull PluginManager doCreate(@NonNull Class klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException { + return klass.getConstructor(File.class).newInstance(jenkins.getRootDir()); + } + }; + + final @CheckForNull PluginManager create(@NonNull Class klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException { + try { + return doCreate(klass, jenkins); + } catch(NoSuchMethodException e) { + // Constructor not found. Will try the remaining ones. + return null; + } + } + + abstract @NonNull PluginManager doCreate(@NonNull Class klass, + @NonNull Jenkins jenkins) throws ReflectiveOperationException; + } + + /** + * Creates the {@link PluginManager} to use if no one is provided to a {@link Jenkins} object. + * This method will be called after creation of {@link Jenkins} object, but before it is fully initialized. + * @param jenkins Jenkins Instance. + * @return Plugin manager to use. If no custom class is configured or in case of any error, the default + * {@link LocalPluginManager} is returned. + */ + public static @NonNull PluginManager createDefault(@NonNull Jenkins jenkins) { + String pmClassName = SystemProperties.getString(CUSTOM_PLUGIN_MANAGER); + if (!StringUtils.isBlank(pmClassName)) { + LOGGER.log(FINE, String.format("Use of custom plugin manager [%s] requested.", pmClassName)); + try { + final Class klass = Class.forName(pmClassName).asSubclass(PluginManager.class); + // Iteration is in declaration order + for (PMConstructor c : PMConstructor.values()) { + PluginManager pm = c.create(klass, jenkins); + if (pm != null) { + return pm; + } + } + LOGGER.log(WARNING, String.format("Provided custom plugin manager [%s] does not provide any of the suitable constructors. Using default.", pmClassName)); + } catch(NullPointerException e) { + // Class.forName and Class.getConstructor are supposed to never return null though a broken ClassLoader + // could break the contract. Just in case we introduce this specific catch to avoid polluting the logs with NPEs. + LOGGER.log(WARNING, String.format("Unable to instantiate custom plugin manager [%s]. Using default.", pmClassName)); + } catch(ClassCastException e) { + LOGGER.log(WARNING, String.format("Provided class [%s] does not extend PluginManager. Using default.", pmClassName)); + } catch(Exception e) { + LOGGER.log(WARNING, String.format("Unable to instantiate custom plugin manager [%s]. Using default.", pmClassName), e); + } + } + return new LocalPluginManager(jenkins); + } + /** * All discovered plugins. */ @@ -146,6 +268,13 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas */ public final File rootDir; + /** + * If non-null, the base directory for all exploded .hpi/.jpi plugins. Controlled by the system property / servlet + * context parameter {@literal hudson.PluginManager.workDir}. + */ + @CheckForNull + private final File workDir; + /** * @deprecated as of 1.355 * {@link PluginManager} can now live longer than {@link jenkins.model.Jenkins} instance, so @@ -185,17 +314,14 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas */ private final PluginStrategy strategy; - /** - * Manifest of the plugin binaries that are bundled with core. - */ - private final Map bundledPluginManifests = new HashMap(); - public PluginManager(ServletContext context, File rootDir) { this.context = context; this.rootDir = rootDir; if(!rootDir.exists()) rootDir.mkdirs(); + String workDir = SystemProperties.getString(PluginManager.class.getName()+".workDir"); + this.workDir = StringUtils.isBlank(workDir) ? null : new File(workDir); strategy = createPluginStrategy(); @@ -212,9 +338,29 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas } public Api getApi() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); return new Api(this); } + /** + * If non-null, the base directory for all exploded .hpi/.jpi plugins. + * @return the base directory for all exploded .hpi/.jpi plugins or {@code null} to leave this up to the strategy. + */ + @CheckForNull + public File getWorkDir() { + return workDir; + } + + /** + * Find all registered overrides (intended to allow overriding/adding views) + * @return List of extensions + * @since 1.627 + */ + @Override + public Collection getOverrides() { + return PluginManagerStaplerOverride.all(); + } + /** * Called immediately after the construction. * This is a separate method so that code executed from here will see a valid value in @@ -324,7 +470,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas if(p.isActive()) activePlugins.add(p); } - } catch (CycleDetectedException e) { + } catch (CycleDetectedException e) { // TODO this should be impossible, since we override reactOnCycle to not throw the exception stop(); // disable all plugins since classloading from them can lead to StackOverflow throw e; // let Hudson fail } @@ -353,22 +499,28 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas // lists up initialization tasks about loading plugins. return TaskBuilder.union(initializerFinder, // this scans @Initializer in the core once - builder,new TaskGraphBuilder() {{ - requires(PLUGINS_LISTED).attains(PLUGINS_PREPARED).add("Loading plugins",new Executable() { + builder, new TaskGraphBuilder() {{ + requires(PLUGINS_LISTED).attains(PLUGINS_PREPARED).add("Loading plugins", new Executable() { /** * Once the plugins are listed, schedule their initialization. */ public void run(Reactor session) throws Exception { - Jenkins.getInstance().lookup.set(PluginInstanceStore.class,new PluginInstanceStore()); + Jenkins.getInstance().lookup.set(PluginInstanceStore.class, new PluginInstanceStore()); TaskGraphBuilder g = new TaskGraphBuilder(); // schedule execution of loading plugins for (final PluginWrapper p : activePlugins.toArray(new PluginWrapper[activePlugins.size()])) { - g.followedBy().notFatal().attains(PLUGINS_PREPARED).add("Loading plugin " + p.getShortName(), new Executable() { + g.followedBy().notFatal().attains(PLUGINS_PREPARED).add(String.format("Loading plugin %s v%s (%s)", p.getLongName(), p.getVersion(), p.getShortName()), new Executable() { public void run(Reactor session) throws Exception { try { p.resolvePluginDependencies(); strategy.load(p); + } catch (MissingDependencyException e) { + failedPlugins.add(new FailedPlugin(p.getShortName(), e)); + activePlugins.remove(p); + plugins.remove(p); + LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { p.getShortName(), e.getMessage() }); + return; } catch (IOException e) { failedPlugins.add(new FailedPlugin(p.getShortName(), e)); activePlugins.remove(p); @@ -409,9 +561,234 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas session.addAll(g.discoverTasks(session)); } }); + + // All plugins are loaded. Now we can figure out who depends on who. + requires(PLUGINS_PREPARED).attains(COMPLETED).add("Resolving Dependant Plugins Graph", new Executable() { + @Override + public void run(Reactor reactor) throws Exception { + resolveDependantPlugins(); + } + }); }}); } + protected @Nonnull Set loadPluginsFromWar(@Nonnull String fromPath) { + return loadPluginsFromWar(fromPath, null); + } + + //TODO: Consider refactoring in order to avoid DMI_COLLECTION_OF_URLS + @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", justification = "Plugin loading happens only once on Jenkins startup") + protected @Nonnull Set loadPluginsFromWar(@Nonnull String fromPath, @CheckForNull FilenameFilter filter) { + Set names = new HashSet(); + + ServletContext context = Jenkins.getActiveInstance().servletContext; + Set plugins = Util.fixNull((Set) context.getResourcePaths(fromPath)); + Set copiedPlugins = new HashSet<>(); + Set dependencies = new HashSet<>(); + + for( String pluginPath : plugins) { + String fileName = pluginPath.substring(pluginPath.lastIndexOf('/')+1); + if(fileName.length()==0) { + // see http://www.nabble.com/404-Not-Found-error-when-clicking-on-help-td24508544.html + // I suspect some containers are returning directory names. + continue; + } + try { + URL url = context.getResource(pluginPath); + if (filter != null && url != null) { + if (!filter.accept(new File(url.getFile()).getParentFile(), fileName)) { + continue; + } + } + + names.add(fileName); + copyBundledPlugin(url, fileName); + copiedPlugins.add(url); + try { + addDependencies(url, fromPath, dependencies); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to resolve dependencies for the bundled plugin " + fileName, e); + } + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to extract the bundled plugin "+fileName,e); + } + } + + // Copy dependencies. These are not detached plugins, but are required by them. + for (URL dependency : dependencies) { + if (copiedPlugins.contains(dependency)) { + // Ignore. Already copied. + continue; + } + + String fileName = new File(dependency.getFile()).getName(); + try { + names.add(fileName); + copyBundledPlugin(dependency, fileName); + copiedPlugins.add(dependency); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to extract the bundled dependency plugin " + fileName, e); + } + } + + return names; + } + + //TODO: Consider refactoring in order to avoid DMI_COLLECTION_OF_URLS + @SuppressFBWarnings(value = "DMI_COLLECTION_OF_URLS", justification = "Plugin loading happens only once on Jenkins startup") + protected static void addDependencies(URL hpiResUrl, String fromPath, Set dependencySet) throws URISyntaxException, MalformedURLException { + if (dependencySet.contains(hpiResUrl)) { + return; + } + + Manifest manifest = parsePluginManifest(hpiResUrl); + String dependencySpec = manifest.getMainAttributes().getValue("Plugin-Dependencies"); + if (dependencySpec != null) { + String[] dependencyTokens = dependencySpec.split(","); + ServletContext context = Jenkins.getActiveInstance().servletContext; + + for (String dependencyToken : dependencyTokens) { + if (dependencyToken.endsWith(";resolution:=optional")) { + // ignore optional dependencies + continue; + } + + String artifactId = dependencyToken.split(":")[0]; + URL dependencyURL = context.getResource(fromPath + "/" + artifactId + ".hpi"); + + if (dependencyURL == null) { + // Maybe bundling has changed .jpi files + dependencyURL = context.getResource(fromPath + "/" + artifactId + ".jpi"); + } + + if (dependencyURL != null) { + // And transitive deps... + addDependencies(dependencyURL, fromPath, dependencySet); + // And then add the current plugin + dependencySet.add(dependencyURL); + } + } + } + } + + /** + * Load detached plugins and their dependencies. + *

+ * Only loads plugins that: + *

    + *
  • Have been detached since the last running version.
  • + *
  • Are already installed and need to be upgraded. This can be the case if this Jenkins install has been running since before plugins were "unbundled".
  • + *
  • Are dependencies of one of the above e.g. script-security is not one of the detached plugins but it must be loaded if matrix-project is loaded.
  • + *
+ */ + protected void loadDetachedPlugins() { + InstallState installState = Jenkins.getActiveInstance().getInstallState(); + if (InstallState.UPGRADE.equals(installState)) { + VersionNumber lastExecVersion = new VersionNumber(InstallUtil.getLastExecVersion()); + + LOGGER.log(INFO, "Upgrading Jenkins. The last running version was {0}. This Jenkins is version {1}.", + new Object[] {lastExecVersion, Jenkins.VERSION}); + + final List detachedPlugins = ClassicPluginStrategy.getDetachedPlugins(lastExecVersion); + + Set loadedDetached = loadPluginsFromWar("/WEB-INF/detached-plugins", new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + name = normalisePluginName(name); + + // If this was a plugin that was detached some time in the past i.e. not just one of the + // plugins that was bundled "for fun". + if (ClassicPluginStrategy.isDetachedPlugin(name)) { + // If it's already installed and the installed version is older + // than the bundled version, then we upgrade. The bundled version is the min required version + // for "this" version of Jenkins, so we must upgrade. + VersionNumber installedVersion = getPluginVersion(rootDir, name); + VersionNumber bundledVersion = getPluginVersion(dir, name); + if (installedVersion != null && bundledVersion != null && installedVersion.isOlderThan(bundledVersion)) { + return true; + } + } + + // If it's a plugin that was detached since the last running version. + for (ClassicPluginStrategy.DetachedPlugin detachedPlugin : detachedPlugins) { + if (detachedPlugin.getShortName().equals(name)) { + return true; + } + } + + // Otherwise skip this and do not install. + return false; + } + }); + + LOGGER.log(INFO, "Upgraded Jenkins from version {0} to version {1}. Loaded detached plugins (and dependencies): {2}", + new Object[] {lastExecVersion, Jenkins.VERSION, loadedDetached}); + + InstallUtil.saveLastExecVersion(); + } else { + final Set forceUpgrade = new HashSet<>(); + for (ClassicPluginStrategy.DetachedPlugin p : ClassicPluginStrategy.getDetachedPlugins()) { + VersionNumber installedVersion = getPluginVersion(rootDir, p.getShortName()); + VersionNumber requiredVersion = p.getRequiredVersion(); + if (installedVersion != null && installedVersion.isOlderThan(requiredVersion)) { + LOGGER.log(Level.WARNING, + "Detached plugin {0} found at version {1}, required minimum version is {2}", + new Object[]{p.getShortName(), installedVersion, requiredVersion}); + forceUpgrade.add(p); + } + } + if (!forceUpgrade.isEmpty()) { + Set loadedDetached = loadPluginsFromWar("/WEB-INF/detached-plugins", new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + name = normalisePluginName(name); + for (ClassicPluginStrategy.DetachedPlugin detachedPlugin : forceUpgrade) { + if (detachedPlugin.getShortName().equals(name)) { + return true; + } + } + return false; + } + }); + LOGGER.log(INFO, "Upgraded detached plugins (and dependencies): {0}", + new Object[]{loadedDetached}); + } + } + } + + private String normalisePluginName(@Nonnull String name) { + // Normalise the name by stripping off the file extension (if present)... + return name.replace(".jpi", "").replace(".hpi", ""); + } + + private @CheckForNull VersionNumber getPluginVersion(@Nonnull File dir, @Nonnull String pluginId) { + VersionNumber version = getPluginVersion(new File(dir, pluginId + ".jpi")); + if (version == null) { + version = getPluginVersion(new File(dir, pluginId + ".hpi")); + } + return version; + } + + private @CheckForNull VersionNumber getPluginVersion(@Nonnull File pluginFile) { + if (!pluginFile.exists()) { + return null; + } + try { + return getPluginVersion(pluginFile.toURI().toURL()); + } catch (MalformedURLException e) { + return null; + } + } + + private @CheckForNull VersionNumber getPluginVersion(@Nonnull URL pluginURL) { + Manifest manifest = parsePluginManifest(pluginURL); + if (manifest == null) { + return null; + } + String versionSpec = manifest.getMainAttributes().getValue("Plugin-Version"); + return new VersionNumber(versionSpec); + } + /* * contains operation that considers xxx.hpi and xxx.jpi as equal * this is necessary since the bundled plugins are still called *.hpi @@ -424,14 +801,23 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas /** * Returns the manifest of a bundled but not-extracted plugin. */ + @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public @CheckForNull Manifest getBundledPluginManifest(String shortName) { - return bundledPluginManifests.get(shortName); + return null; } /** * TODO: revisit where/how to expose this. This is an experiment. */ public void dynamicLoad(File arc) throws IOException, InterruptedException, RestartRequiredException { + dynamicLoad(arc, false); + } + + /** + * Try the dynamicLoad, removeExisting to attempt to dynamic load disabled plugins + */ + @Restricted(NoExternalUse.class) + public void dynamicLoad(File arc, boolean removeExisting) throws IOException, InterruptedException, RestartRequiredException { LOGGER.info("Attempting to dynamic load "+arc); PluginWrapper p = null; String sn; @@ -442,9 +828,21 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas p = strategy.createPluginWrapper(arc); sn = p.getShortName(); } - if (getPlugin(sn)!=null) - throw new RestartRequiredException(Messages._PluginManager_PluginIsAlreadyInstalled_RestartRequired(sn)); - + PluginWrapper pw = getPlugin(sn); + if (pw!=null) { + if (removeExisting) { // try to load disabled plugins + for (Iterator i = plugins.iterator(); i.hasNext();) { + pw = i.next(); + if(sn.equals(pw.getShortName())) { + i.remove(); + pw = null; + break; + } + } + } else { + throw new RestartRequiredException(Messages._PluginManager_PluginIsAlreadyInstalled_RestartRequired(sn)); + } + } if (p == null) { p = strategy.createPluginWrapper(arc); } @@ -455,7 +853,8 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas // so existing plugins can't be depending on this newly deployed one. plugins.add(p); - activePlugins.add(p); + if (p.isActive()) + activePlugins.add(p); synchronized (((UberClassLoader) uberClassLoader).loaded) { ((UberClassLoader) uberClassLoader).loaded.clear(); } @@ -509,9 +908,33 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas } } + // Redo who depends on who. + resolveDependantPlugins(); + LOGGER.info("Plugin " + p.getShortName()+":"+p.getVersion() + " dynamically installed"); } + @Restricted(NoExternalUse.class) + public synchronized void resolveDependantPlugins() { + for (PluginWrapper plugin : plugins) { + Set dependants = new HashSet<>(); + for (PluginWrapper possibleDependant : plugins) { + // The plugin could have just been deleted. If so, it doesn't + // count as a dependant. + if (possibleDependant.isDeleted()) { + continue; + } + List dependencies = possibleDependant.getDependencies(); + for (Dependency dependency : dependencies) { + if (dependency.shortName.equals(plugin.getShortName())) { + dependants.add(possibleDependant.getShortName()); + } + } + } + plugin.setDependants(dependants); + } + } + /** * If the war file has any "/WEB-INF/plugins/[*.jpi | *.hpi]", extract them into the plugin directory. * @@ -529,53 +952,123 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas protected void copyBundledPlugin(URL src, String fileName) throws IOException { fileName = fileName.replace(".hpi",".jpi"); // normalize fileNames to have the correct suffix String legacyName = fileName.replace(".jpi",".hpi"); - long lastModified = src.openConnection().getLastModified(); + long lastModified = getModificationDate(src); File file = new File(rootDir, fileName); - File pinFile = new File(rootDir, fileName+".pinned"); // normalization first, if the old file exists. rename(new File(rootDir,legacyName),file); - rename(new File(rootDir,legacyName+".pinned"),pinFile); // update file if: // - no file exists today - // - bundled version and current version differs (by timestamp), and the file isn't pinned. - if (!file.exists() || (file.lastModified() != lastModified && !pinFile.exists())) { + // - bundled version and current version differs (by timestamp). + if (!file.exists() || file.lastModified() != lastModified) { FileUtils.copyURLToFile(src, file); - file.setLastModified(src.openConnection().getLastModified()); + file.setLastModified(getModificationDate(src)); // lastModified is set for two reasons: // - to avoid unpacking as much as possible, but still do it on both upgrade and downgrade // - to make sure the value is not changed after each restart, so we can avoid // unpacking the plugin itself in ClassicPluginStrategy.explode } - if (pinFile.exists()) - parsePinnedBundledPluginManifest(src); + + // Plugin pinning has been deprecated. + // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ } - /** - * When a pin file prevented a bundled plugin from getting extracted, check if the one we currently have - * is older than we bundled. - */ - private void parsePinnedBundledPluginManifest(URL bundledJpi) { + /*package*/ static @CheckForNull Manifest parsePluginManifest(URL bundledJpi) { try { URLClassLoader cl = new URLClassLoader(new URL[]{bundledJpi}); InputStream in=null; try { URL res = cl.findResource(PluginWrapper.MANIFEST_FILENAME); if (res!=null) { - in = res.openStream(); + in = getBundledJpiManifestStream(res); Manifest manifest = new Manifest(in); - String shortName = PluginWrapper.computeShortName(manifest, FilenameUtils.getName(bundledJpi.getPath())); - bundledPluginManifests.put(shortName, manifest); + return manifest; } } finally { - IOUtils.closeQuietly(in); + Util.closeAndLogFailures(in, LOGGER, PluginWrapper.MANIFEST_FILENAME, bundledJpi.toString()); if (cl instanceof Closeable) ((Closeable)cl).close(); } } catch (IOException e) { LOGGER.log(WARNING, "Failed to parse manifest of "+bundledJpi, e); } + return null; + } + + /** + * Retrieves input stream for the Manifest url. + * The method intelligently handles the case of {@link JarURLConnection} pointing to files within JAR. + * @param url Url of the manifest file + * @return Input stream, which allows to retrieve manifest. This stream must be closed outside + * @throws IOException Operation error + */ + @Nonnull + /*package*/ static InputStream getBundledJpiManifestStream(@Nonnull URL url) throws IOException { + URLConnection uc = url.openConnection(); + InputStream in = null; + // Magic, which allows to avoid using stream generated for JarURLConnection. + // It prevents getting into JENKINS-37332 due to the file desciptor leak + if (uc instanceof JarURLConnection) { + final JarURLConnection jarURLConnection = (JarURLConnection) uc; + final String entryName = jarURLConnection.getEntryName(); + + try(final JarFile jarFile = jarURLConnection.getJarFile()) { + final JarEntry entry = (entryName != null && jarFile != null) ? jarFile.getJarEntry(entryName) : null; + if (entry != null && jarFile != null) { + try(InputStream i = jarFile.getInputStream(entry)) { + byte[] manifestBytes = IOUtils.toByteArray(i); + in = new ByteArrayInputStream(manifestBytes); + } + } else { + LOGGER.log(Level.WARNING, "Failed to locate the JAR file for {0}" + + "The default URLConnection stream access will be used, file descriptor may be leaked.", + url); + } + } + } + + // If input stream is undefined, use the default implementation + if (in == null) { + in = url.openStream(); + } + + return in; + } + + /** + * Retrieves modification date of the specified file. + * The method intelligently handles the case of {@link JarURLConnection} pointing to files within JAR. + * @param url Url of the file + * @return Modification date + * @throws IOException Operation error + */ + @Nonnull + /*package*/ static long getModificationDate(@Nonnull URL url) throws IOException { + URLConnection uc = url.openConnection(); + + // It prevents file desciptor leak if the URL references a file within JAR + // See JENKINS-37332 for more info + // The code idea is taken from https://github.com/jknack/handlebars.java/pull/394 + if (uc instanceof JarURLConnection) { + final JarURLConnection connection = (JarURLConnection) uc; + final URL jarURL = connection.getJarFileURL(); + if (jarURL.getProtocol().equals("file")) { + uc = null; + String file = jarURL.getFile(); + return new File(file).lastModified(); + } else { + // We access the data without file protocol + if (connection.getEntryName() != null) { + LOGGER.log(WARNING, "Accessing modification date of {0} file, which is an entry in JAR file. " + + "The access protocol is not file:, falling back to the default logic (risk of file descriptor leak).", + url); + } + } + } + + // Fallbak to the default implementation + return uc.getLastModified(); } /** @@ -596,7 +1089,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas * Creates a hudson.PluginStrategy, looking at the corresponding system property. */ protected PluginStrategy createPluginStrategy() { - String strategyName = System.getProperty(PluginStrategy.class.getName()); + String strategyName = SystemProperties.getString(PluginStrategy.class.getName()); if (strategyName != null) { try { Class klazz = getClass().getClassLoader().loadClass(strategyName); @@ -744,6 +1237,57 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas LogFactory.release(uberClassLoader); } + /** + * Get the list of all plugins - available and installed. + * @return The list of all plugins - available and installed. + */ + @Restricted(DoNotUse.class) // WebOnly + public HttpResponse doPlugins() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + JSONArray response = new JSONArray(); + Map allPlugins = new HashMap<>(); + for (PluginWrapper plugin : plugins) { + JSONObject pluginInfo = new JSONObject(); + pluginInfo.put("installed", true); + pluginInfo.put("name", plugin.getShortName()); + pluginInfo.put("title", plugin.getDisplayName()); + pluginInfo.put("active", plugin.isActive()); + pluginInfo.put("enabled", plugin.isEnabled()); + pluginInfo.put("bundled", plugin.isBundled); + pluginInfo.put("deleted", plugin.isDeleted()); + pluginInfo.put("downgradable", plugin.isDowngradable()); + pluginInfo.put("website", plugin.getUrl()); + List dependencies = plugin.getDependencies(); + if (dependencies != null && !dependencies.isEmpty()) { + Map dependencyMap = new HashMap<>(); + for (Dependency dependency : dependencies) { + dependencyMap.put(dependency.shortName, dependency.version); + } + pluginInfo.put("dependencies", dependencyMap); + } else { + pluginInfo.put("dependencies", Collections.emptyMap()); + } + response.add(pluginInfo); + } + for (UpdateSite site : Jenkins.getActiveInstance().getUpdateCenter().getSiteList()) { + for (UpdateSite.Plugin plugin: site.getAvailables()) { + JSONObject pluginInfo = allPlugins.get(plugin.name); + if(pluginInfo == null) { + pluginInfo = new JSONObject(); + pluginInfo.put("installed", false); + } + pluginInfo.put("name", plugin.name); + pluginInfo.put("title", plugin.getDisplayName()); + pluginInfo.put("excerpt", plugin.excerpt); + pluginInfo.put("site", site.getId()); + pluginInfo.put("dependencies", plugin.dependencies); + pluginInfo.put("website", plugin.wiki); + response.add(pluginInfo); + } + } + return hudson.util.HttpResponses.okJSON(response); + } + public HttpResponse doUpdateSources(StaplerRequest req) throws IOException { Jenkins.getInstance().checkPermission(CONFIGURE_UPDATECENTER); @@ -762,54 +1306,213 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas return new HttpRedirect("./sites"); } + + /** + * Called to progress status beyond installing plugins, e.g. if + * there were failures that prevented installation from naturally proceeding + */ + @RequirePOST + @Restricted(DoNotUse.class) // WebOnly + public void doInstallPluginsDone() { + Jenkins j = Jenkins.getInstance(); + j.checkPermission(Jenkins.ADMINISTER); + InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING); + } /** * Performs the installation of the plugins. */ public void doInstall(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { - boolean dynamicLoad = req.getParameter("dynamicLoad")!=null; + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + Set plugins = new LinkedHashSet<>(); Enumeration en = req.getParameterNames(); while (en.hasMoreElements()) { String n = en.nextElement(); if(n.startsWith("plugin.")) { n = n.substring(7); - // JENKINS-22080 plugin names can contain '.' as could (according to rumour) update sites - int index = n.indexOf('.'); - UpdateSite.Plugin p = null; + plugins.add(n); + } + } + + boolean dynamicLoad = req.getParameter("dynamicLoad")!=null; + install(plugins, dynamicLoad); + + rsp.sendRedirect("../updateCenter/"); + } + + /** + * Installs a list of plugins from a JSON POST. + * @param req The request object. + * @return A JSON response that includes a "correlationId" in the "data" element. + * That "correlationId" can then be used in calls to + * {@link UpdateCenter#doInstallStatus(org.kohsuke.stapler.StaplerRequest)}. + * @throws IOException Error reading JSON payload fro request. + */ + @RequirePOST + @Restricted(DoNotUse.class) // WebOnly + public HttpResponse doInstallPlugins(StaplerRequest req) throws IOException { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + String payload = IOUtils.toString(req.getInputStream(), req.getCharacterEncoding()); + JSONObject request = JSONObject.fromObject(payload); + JSONArray pluginListJSON = request.getJSONArray("plugins"); + List plugins = new ArrayList<>(); + + for (int i = 0; i < pluginListJSON.size(); i++) { + plugins.add(pluginListJSON.getString(i)); + } + + UUID correlationId = UUID.randomUUID(); + try { + boolean dynamicLoad = request.getBoolean("dynamicLoad"); + install(plugins, dynamicLoad, correlationId); + + JSONObject responseData = new JSONObject(); + responseData.put("correlationId", correlationId.toString()); + + return hudson.util.HttpResponses.okJSON(responseData); + } catch (Exception e) { + return hudson.util.HttpResponses.errorJSON(e.getMessage()); + } + } + + /** + * Performs the installation of the plugins. + * @param plugins The collection of plugins to install. + * @param dynamicLoad If true, the plugin will be dynamically loaded into this Jenkins. If false, + * the plugin will only take effect after the reboot. + * See {@link UpdateCenter#isRestartRequiredForCompletion()} + * @return The install job list. + * @since 2.0 + */ + @Restricted(NoExternalUse.class) + public List> install(@Nonnull Collection plugins, boolean dynamicLoad) { + return install(plugins, dynamicLoad, null); + } + + private List> install(@Nonnull Collection plugins, boolean dynamicLoad, @CheckForNull UUID correlationId) { + List> installJobs = new ArrayList<>(); + + for (String n : plugins) { + // JENKINS-22080 plugin names can contain '.' as could (according to rumour) update sites + int index = n.indexOf('.'); + UpdateSite.Plugin p = null; + + if (index == -1) { + p = getPlugin(n, UpdateCenter.ID_DEFAULT); + } else { while (index != -1) { if (index + 1 >= n.length()) { break; } String pluginName = n.substring(0, index); String siteName = n.substring(index + 1); - UpdateSite updateSite = Jenkins.getInstance().getUpdateCenter().getById(siteName); - if (updateSite == null) { - throw new Failure("No such update center: " + siteName); - } else { - UpdateSite.Plugin plugin = updateSite.getPlugin(pluginName); - if (plugin != null) { - if (p != null) { - throw new Failure("Ambiguous plugin: " + n); - } - p = plugin; + UpdateSite.Plugin plugin = getPlugin(pluginName, siteName); + // There could be cases like: + // 'plugin.ambiguous.updatesite' where both + // 'plugin' @ 'ambigiuous.updatesite' and 'plugin.ambiguous' @ 'updatesite' resolve to valid plugins + if (plugin != null) { + if (p != null) { + throw new Failure("Ambiguous plugin: " + n); } + p = plugin; } index = n.indexOf('.', index + 1); } - if (p == null) { - throw new Failure("No such plugin: " + n); - } - p.deploy(dynamicLoad); } + + if (p == null) { + throw new Failure("No such plugin: " + n); + } + Future jobFuture = p.deploy(dynamicLoad, correlationId); + installJobs.add(jobFuture); } - rsp.sendRedirect("../updateCenter/"); + + trackInitialPluginInstall(installJobs); + + return installJobs; + } + + private void trackInitialPluginInstall(@Nonnull final List> installJobs) { + final Jenkins jenkins = Jenkins.getInstance(); + final UpdateCenter updateCenter = jenkins.getUpdateCenter(); + final Authentication currentAuth = Jenkins.getAuthentication(); + + if (!Jenkins.getInstance().getInstallState().isSetupComplete()) { + jenkins.setInstallState(InstallState.INITIAL_PLUGINS_INSTALLING); + updateCenter.persistInstallStatus(); + new Thread() { + @Override + public void run() { + boolean failures = false; + INSTALLING: while (true) { + try { + updateCenter.persistInstallStatus(); + Thread.sleep(500); + failures = false; + for (Future jobFuture : installJobs) { + if(!jobFuture.isDone() && !jobFuture.isCancelled()) { + continue INSTALLING; + } + UpdateCenter.UpdateCenterJob job = jobFuture.get(); + if(job instanceof InstallationJob && ((InstallationJob)job).status instanceof DownloadJob.Failure) { + failures = true; + } + } + } catch (Exception e) { + LOGGER.log(WARNING, "Unexpected error while waiting for initial plugin set to install.", e); + } + break; + } + updateCenter.persistInstallStatus(); + if(!failures) { + try (ACLContext _ = ACL.as(currentAuth)) { + InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_PLUGINS_INSTALLING); + } + } + } + }.start(); + } + + // Fire a one-off thread to wait for the plugins to be deployed and then + // refresh the dependant plugins list. + new Thread() { + @Override + public void run() { + INSTALLING: while (true) { + for (Future deployJob : installJobs) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + LOGGER.log(SEVERE, "Unexpected error while waiting for some plugins to install. Plugin Manager state may be invalid. Please restart Jenkins ASAP.", e); + } + if (!deployJob.isCancelled() && !deployJob.isDone()) { + // One of the plugins is not installing/canceled, so + // go back to sleep and try again in a while. + continue INSTALLING; + } + } + // All the plugins are installed. It's now safe to refresh. + resolveDependantPlugins(); + break; + } + } + }.start(); + } + private UpdateSite.Plugin getPlugin(String pluginName, String siteName) { + UpdateSite updateSite = Jenkins.getInstance().getUpdateCenter().getById(siteName); + if (updateSite == null) { + throw new Failure("No such update center: " + siteName); + } + return updateSite.getPlugin(pluginName); + } /** * Bare-minimum configuration mechanism to change the update center. */ + @RequirePOST public HttpResponse doSiteConfigure(@QueryParameter String site) throws IOException { Jenkins hudson = Jenkins.getInstance(); hudson.checkPermission(CONFIGURE_UPDATECENTER); @@ -825,6 +1528,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas } + @RequirePOST public HttpResponse doProxyConfigure(StaplerRequest req) throws IOException, ServletException { Jenkins jenkins = Jenkins.getInstance(); jenkins.checkPermission(CONFIGURE_UPDATECENTER); @@ -843,6 +1547,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas /** * Uploads a plugin. */ + @RequirePOST public HttpResponse doUploadPlugin(StaplerRequest req) throws IOException, ServletException { try { Jenkins.getInstance().checkPermission(UPLOAD_PLUGINS); @@ -870,12 +1575,33 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas pluginUploaded = true; + JSONArray dependencies = new JSONArray(); + try { + Manifest m = new JarFile(t).getManifest(); + String deps = m.getMainAttributes().getValue("Plugin-Dependencies"); + + if (StringUtils.isNotBlank(deps)) { + // now we get to parse it! + String[] plugins = deps.split(","); + for (String p : plugins) { + // should have name:version[;resolution:=optional] + String[] attrs = p.split("[:;]"); + dependencies.add(new JSONObject() + .element("name", attrs[0]) + .element("version", attrs[1]) + .element("optional", p.contains("resolution:=optional"))); + } + } + } catch(IOException e) { + LOGGER.log(WARNING, "Unable to setup dependency list for plugin upload", e); + } + // Now create a dummy plugin that we can dynamically load (the InstallationJob will force a restart if one is needed): JSONObject cfg = new JSONObject(). element("name", baseName). element("version", "0"). // unused but mandatory element("url", t.toURI().toString()). - element("dependencies", new JSONArray()); + element("dependencies", dependencies); new UpdateSite(UpdateCenter.ID_UPLOAD, null).new Plugin(UpdateCenter.ID_UPLOAD, cfg).deploy(true); return new HttpRedirect("../updateCenter"); } catch (IOException e) { @@ -887,20 +1613,25 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas @Restricted(NoExternalUse.class) @RequirePOST public HttpResponse doCheckUpdatesServer() throws IOException { - for (UpdateSite site : Jenkins.getInstance().getUpdateCenter().getSites()) { - FormValidation v = site.updateDirectlyNow(DownloadService.signatureCheck); - if (v.kind != FormValidation.Kind.OK) { - // TODO crude but enough for now - return v; + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + try { + for (UpdateSite site : Jenkins.getInstance().getUpdateCenter().getSites()) { + FormValidation v = site.updateDirectlyNow(DownloadService.signatureCheck); + if (v.kind != FormValidation.Kind.OK) { + // TODO crude but enough for now + return v; + } } - } - for (DownloadService.Downloadable d : DownloadService.Downloadable.all()) { - FormValidation v = d.updateNow(); - if (v.kind != FormValidation.Kind.OK) { - return v; + for (DownloadService.Downloadable d : DownloadService.Downloadable.all()) { + FormValidation v = d.updateNow(); + if (v.kind != FormValidation.Kind.OK) { + return v; + } } + return HttpResponses.forwardToPreviousPage(); + } catch(RuntimeException ex) { + throw new IOException("Unhandled exception during updates server check", ex); } - return HttpResponses.forwardToPreviousPage(); } protected String identifyPluginShortName(File t) { @@ -1184,7 +1915,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas private static final Logger LOGGER = Logger.getLogger(PluginManager.class.getName()); - public static boolean FAST_LOOKUP = !Boolean.getBoolean(PluginManager.class.getName()+".noFastLookup"); + public static boolean FAST_LOOKUP = !SystemProperties.getBoolean(PluginManager.class.getName()+".noFastLookup"); public static final Permission UPLOAD_PLUGINS = new Permission(Jenkins.PERMISSIONS, "UploadPlugins", Messages._PluginManager_UploadPluginsPermission_Description(),Jenkins.ADMINISTER,PermissionScope.JENKINS); public static final Permission CONFIGURE_UPDATECENTER = new Permission(Jenkins.PERMISSIONS, "ConfigureUpdateCenter", Messages._PluginManager_ConfigureUpdateCenterPermission_Description(),Jenkins.ADMINISTER,PermissionScope.JENKINS); @@ -1216,19 +1947,24 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas /** * {@link AdministrativeMonitor} that checks if there are any plugins with cycle dependencies. */ - @Extension + @Extension @Symbol("pluginCycleDependencies") public static final class PluginCycleDependenciesMonitor extends AdministrativeMonitor { + @Override + public String getDisplayName() { + return Messages.PluginManager_PluginCycleDependenciesMonitor_DisplayName(); + } + private transient volatile boolean isActive = false; - private transient volatile List pluginsWithCycle; + private transient volatile List pluginsWithCycle; public boolean isActivated() { if(pluginsWithCycle == null){ - pluginsWithCycle = new ArrayList(); + pluginsWithCycle = new ArrayList<>(); for (PluginWrapper p : Jenkins.getInstance().getPluginManager().getPlugins()) { if(p.hasCycleDependency()){ - pluginsWithCycle.add(p.getShortName()); + pluginsWithCycle.add(p); isActive = true; } } @@ -1236,7 +1972,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas return isActive; } - public List getPluginsWithCycle() { + public List getPluginsWithCycle() { return pluginsWithCycle; } } @@ -1245,7 +1981,7 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas * {@link AdministrativeMonitor} that informs the administrator about a required plugin update. * @since 1.491 */ - @Extension + @Extension @Symbol("pluginUpdate") public static final class PluginUpdateMonitor extends AdministrativeMonitor { private Map pluginsToBeUpdated = new HashMap(); @@ -1278,6 +2014,11 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas return !pluginsToBeUpdated.isEmpty(); } + @Override + public String getDisplayName() { + return Messages.PluginManager_PluginUpdateMonitor_DisplayName(); + } + /** * adds a message about a plugin to the manage screen * @param pluginName the plugins name diff --git a/core/src/main/java/hudson/PluginManagerStaplerOverride.java b/core/src/main/java/hudson/PluginManagerStaplerOverride.java new file mode 100644 index 0000000000000000000000000000000000000000..3103ba181835d9ba31bab32fb6581f9aee82b9a9 --- /dev/null +++ b/core/src/main/java/hudson/PluginManagerStaplerOverride.java @@ -0,0 +1,26 @@ +package hudson; + + +import javax.annotation.Nonnull; + +/** + * Extension point for selectively overriding parts of the {@link PluginManager} views + * Anything extending this and registered with an @Extension can replace existing views and define new views. + * + * It is also possible to add/modify API calls coming via Stapler, but this requires caution. + * + * In both cases, this is simply done by defining a resource or method that matches the existing one + * + * @author Sam Van Oort + * @since 1.627 + */ +public abstract class PluginManagerStaplerOverride implements ExtensionPoint { + + /** + * Return all implementations of this extension point + * @return All implementations of this extension point + */ + public static @Nonnull ExtensionList all() { + return ExtensionList.lookup(PluginManagerStaplerOverride.class); + } +} diff --git a/core/src/main/java/hudson/PluginWrapper.java b/core/src/main/java/hudson/PluginWrapper.java index aa683e630f7af7ca0306d86ad3474c2269584f1b..5932f0777e84ffb801743192145a6c26afe77168 100644 --- a/core/src/main/java/hudson/PluginWrapper.java +++ b/core/src/main/java/hudson/PluginWrapper.java @@ -24,7 +24,9 @@ */ package hudson; +import com.google.common.collect.ImmutableSet; import hudson.PluginManager.PluginInstanceStore; +import hudson.model.AdministrativeMonitor; import hudson.model.Api; import hudson.model.ModelObject; import jenkins.YesNoMaybe; @@ -32,38 +34,50 @@ import jenkins.model.Jenkins; import hudson.model.UpdateCenter; import hudson.model.UpdateSite; import hudson.util.VersionNumber; +import org.jvnet.localizer.ResourceBundleHolder; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.interceptor.RequirePOST; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.LogFactory; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import java.io.Closeable; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.logging.Level; import java.util.logging.Logger; + import static java.util.logging.Level.WARNING; import static org.apache.commons.io.FilenameUtils.getBaseName; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.logging.LogFactory; -import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.HttpResponses; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.kohsuke.stapler.interceptor.RequirePOST; - -import java.util.Enumeration; -import java.util.jar.JarFile; -import java.util.logging.Level; -import javax.annotation.CheckForNull; /** * Represents a Jenkins plug-in and associated control information * for Jenkins to control {@link Plugin}. * *

- * A plug-in is packaged into a jar file whose extension is ".jpi" (or ".hpi" for backward compatability), + * A plug-in is packaged into a jar file whose extension is ".jpi" (or ".hpi" for backward compatibility), * A plugin needs to have a special manifest entry to identify what it is. * *

@@ -82,6 +96,12 @@ import javax.annotation.CheckForNull; */ @ExportedBean public class PluginWrapper implements Comparable, ModelObject { + /** + * A plugin won't be loaded unless his declared dependencies are present and match the required minimal version. + * This can be set to false to disable the version check (legacy behaviour) + */ + private static final boolean ENABLE_PLUGIN_DEPENDENCIES_VERSION_CHECK = Boolean.parseBoolean(System.getProperty(PluginWrapper.class.getName()+"." + "dependenciesVersionCheck.enabled", "true")); + /** * {@link PluginManager} to which this belongs to. */ @@ -112,15 +132,6 @@ public class PluginWrapper implements Comparable, ModelObject { */ private final File disableFile; - /** - * Used to control the unpacking of the bundled plugin. - * If a pin file exists, Jenkins assumes that the user wants to pin down a particular version - * of a plugin, and will not try to overwrite it. Otherwise, it'll be overwritten - * by a bundled copy, to ensure consistency across upgrade/downgrade. - * @since 1.325 - */ - private final File pinFile; - /** * A .jpi file, an exploded plugin directory, or a .jpl file. */ @@ -145,11 +156,65 @@ public class PluginWrapper implements Comparable, ModelObject { private final List dependencies; private final List optionalDependencies; + public List getDependencyErrors() { + return Collections.unmodifiableList(dependencyErrors); + } + + private final transient List dependencyErrors = new ArrayList<>(); + /** * Is this plugin bundled in jenkins.war? */ /*package*/ boolean isBundled; + /** + * List of plugins that depend on this plugin. + */ + private Set dependants = Collections.emptySet(); + + /** + * The core can depend on a plugin if it is bundled. Sometimes it's the only thing that + * depends on the plugin e.g. UI support library bundle plugin. + */ + private static Set CORE_ONLY_DEPENDANT = ImmutableSet.copyOf(Arrays.asList("jenkins-core")); + + /** + * Set the list of components that depend on this plugin. + * @param dependants The list of components that depend on this plugin. + */ + public void setDependants(@Nonnull Set dependants) { + this.dependants = dependants; + } + + /** + * Get the list of components that depend on this plugin. + * @return The list of components that depend on this plugin. + */ + public @Nonnull Set getDependants() { + if (isBundled && dependants.isEmpty()) { + return CORE_ONLY_DEPENDANT; + } else { + return dependants; + } + } + + /** + * Does this plugin have anything that depends on it. + * @return {@code true} if something (Jenkins core, or another plugin) depends on this + * plugin, otherwise {@code false}. + */ + public boolean hasDependants() { + return (isBundled || !dependants.isEmpty()); + } + + /** + * Does this plugin depend on any other plugins. + * @return {@code true} if this plugin depends on other plugins, otherwise {@code false}. + */ + public boolean hasDependencies() { + return (dependencies != null && !dependencies.isEmpty()); + } + @ExportedBean public static final class Dependency { @Exported @@ -164,10 +229,10 @@ public class PluginWrapper implements Comparable, ModelObject { if(idx==-1) throw new IllegalArgumentException("Illegal dependency specifier "+s); this.shortName = s.substring(0,idx); - this.version = s.substring(idx+1); - + String version = s.substring(idx+1); + boolean isOptional = false; - String[] osgiProperties = s.split(";"); + String[] osgiProperties = version.split("[;]"); for (int i = 1; i < osgiProperties.length; i++) { String osgiProperty = osgiProperties[i].trim(); if (osgiProperty.equalsIgnoreCase("resolution:=optional")) { @@ -175,11 +240,16 @@ public class PluginWrapper implements Comparable, ModelObject { } } this.optional = isOptional; + if (isOptional) { + this.version = osgiProperties[0]; + } else { + this.version = version; + } } @Override public String toString() { - return shortName + " (" + version + ")"; + return shortName + " (" + version + ")" + (optional ? " optional" : ""); } } @@ -206,7 +276,6 @@ public class PluginWrapper implements Comparable, ModelObject { this.baseResourceURL = baseResourceURL; this.classLoader = classLoader; this.disableFile = disableFile; - this.pinFile = new File(archive.getPath() + ".pinned"); this.active = !disableFile.exists(); this.dependencies = dependencies; this.optionalDependencies = optionalDependencies; @@ -218,6 +287,7 @@ public class PluginWrapper implements Comparable, ModelObject { } public Api getApi() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); return new Api(this); } @@ -344,6 +414,21 @@ public class PluginWrapper implements Comparable, ModelObject { return "???"; } + /** + * Returns the required Jenkins core version of this plugin. + * @return the required Jenkins core version of this plugin. + * @since 2.16 + */ + @Exported + public @CheckForNull String getRequiredCoreVersion() { + String v = manifest.getMainAttributes().getValue("Jenkins-Version"); + if (v!= null) return v; + + v = manifest.getMainAttributes().getValue("Hudson-Version"); + if (v!= null) return v; + return null; + } + /** * Returns the version number of this plugin */ @@ -397,6 +482,10 @@ public class PluginWrapper implements Comparable, ModelObject { * Enables this plugin next time Jenkins runs. */ public void enable() throws IOException { + if (!disableFile.exists()) { + LOGGER.log(Level.FINEST, "Plugin {0} has been already enabled. Skipping the enable() operation", getShortName()); + return; + } if(!disableFile.delete()) throw new IOException("Failed to delete "+disableFile); } @@ -470,20 +559,71 @@ public class PluginWrapper implements Comparable, ModelObject { * thrown if one or several mandatory dependencies doesn't exists. */ /*package*/ void resolvePluginDependencies() throws IOException { - List missingDependencies = new ArrayList(); + if (ENABLE_PLUGIN_DEPENDENCIES_VERSION_CHECK) { + String requiredCoreVersion = getRequiredCoreVersion(); + if (requiredCoreVersion == null) { + LOGGER.warning(shortName + " doesn't declare required core version."); + } else { + VersionNumber actualVersion = Jenkins.getVersion(); + if (actualVersion.isOlderThan(new VersionNumber(requiredCoreVersion))) { + dependencyErrors.add(Messages.PluginWrapper_obsoleteCore(Jenkins.getVersion().toString(), requiredCoreVersion)); + } + } + } // make sure dependencies exist for (Dependency d : dependencies) { - if (parent.getPlugin(d.shortName) == null) - missingDependencies.add(d.toString()); - } - if (!missingDependencies.isEmpty()) - throw new IOException("Dependency "+Util.join(missingDependencies, ", ")+" doesn't exist"); + PluginWrapper dependency = parent.getPlugin(d.shortName); + if (dependency == null) { + PluginWrapper failedDependency = NOTICE.getPlugin(d.shortName); + if (failedDependency != null) { + dependencyErrors.add(Messages.PluginWrapper_failed_to_load_dependency(failedDependency.getLongName(), failedDependency.getVersion())); + break; + } else { + dependencyErrors.add(Messages.PluginWrapper_missing(d.shortName, d.version)); + } + } else { + if (dependency.isActive()) { + if (isDependencyObsolete(d, dependency)) { + dependencyErrors.add(Messages.PluginWrapper_obsolete(dependency.getLongName(), dependency.getVersion(), d.version)); + } + } else { + if (isDependencyObsolete(d, dependency)) { + dependencyErrors.add(Messages.PluginWrapper_disabledAndObsolete(dependency.getLongName(), dependency.getVersion(), d.version)); + } else { + dependencyErrors.add(Messages.PluginWrapper_disabled(dependency.getLongName())); + } + } + } + } // add the optional dependencies that exists for (Dependency d : optionalDependencies) { - if (parent.getPlugin(d.shortName) != null) - dependencies.add(d); + PluginWrapper dependency = parent.getPlugin(d.shortName); + if (dependency != null && dependency.isActive()) { + if (isDependencyObsolete(d, dependency)) { + dependencyErrors.add(Messages.PluginWrapper_obsolete(dependency.getLongName(), dependency.getVersion(), d.version)); + } else { + dependencies.add(d); + } + } } + if (!dependencyErrors.isEmpty()) { + NOTICE.addPlugin(this); + StringBuilder messageBuilder = new StringBuilder(); + messageBuilder.append(Messages.PluginWrapper_failed_to_load_plugin(getLongName(), getVersion())).append(System.lineSeparator()); + for (Iterator iterator = dependencyErrors.iterator(); iterator.hasNext(); ) { + String dependencyError = iterator.next(); + messageBuilder.append(" - ").append(dependencyError); + if (iterator.hasNext()) { + messageBuilder.append(System.lineSeparator()); + } + } + throw new IOException(messageBuilder.toString()); + } + } + + private boolean isDependencyObsolete(Dependency d, PluginWrapper dependency) { + return ENABLE_PLUGIN_DEPENDENCIES_VERSION_CHECK && dependency.getVersionNumber().isOlderThan(new VersionNumber(d.version)); } /** @@ -522,8 +662,9 @@ public class PluginWrapper implements Comparable, ModelObject { } @Exported + @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public boolean isPinned() { - return pinFile.exists(); + return false; } /** @@ -567,11 +708,8 @@ public class PluginWrapper implements Comparable, ModelObject { File backup = getBackupFile(); if (backup.exists()) { try { - JarFile backupPlugin = new JarFile(backup); - try { + try (JarFile backupPlugin = new JarFile(backup)) { return backupPlugin.getManifest().getMainAttributes().getValue("Plugin-Version"); - } finally { - backupPlugin.close(); } } catch (IOException e) { LOGGER.log(WARNING, "Failed to get backup version from " + backup, e); @@ -585,16 +723,54 @@ public class PluginWrapper implements Comparable, ModelObject { /** * Checks if this plugin is pinned and that's forcing us to use an older version than the bundled one. */ + @Deprecated // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ public boolean isPinningForcingOldVersion() { - if (!isPinned()) return false; + return false; + } + + @Extension + public final static PluginWrapperAdministrativeMonitor NOTICE = new PluginWrapperAdministrativeMonitor(); + + /** + * Administrative Monitor for failed plugins + */ + public static final class PluginWrapperAdministrativeMonitor extends AdministrativeMonitor { + private final Map plugins = new HashMap<>(); + + void addPlugin(PluginWrapper plugin) { + plugins.put(plugin.shortName, plugin); + } + + public boolean isActivated() { + return !plugins.isEmpty(); + } - Manifest bundled = Jenkins.getInstance().pluginManager.getBundledPluginManifest(getShortName()); - if (bundled==null) return false; + @Override + public String getDisplayName() { + return Messages.PluginWrapper_PluginWrapperAdministrativeMonitor_DisplayName(); + } - VersionNumber you = new VersionNumber(getVersionOf(bundled)); - VersionNumber me = getVersionNumber(); + public Collection getPlugins() { + return plugins.values(); + } - return me.isOlderThan(you); + public PluginWrapper getPlugin(String shortName) { + return plugins.get(shortName); + } + + /** + * Depending on whether the user said "dismiss" or "correct", send him to the right place. + */ + public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + if(req.hasParameter("correct")) { + rsp.sendRedirect(req.getContextPath()+"/pluginManager"); + + } + } + + public static PluginWrapperAdministrativeMonitor get() { + return AdministrativeMonitor.all().get(PluginWrapperAdministrativeMonitor.class); + } } // @@ -617,23 +793,33 @@ public class PluginWrapper implements Comparable, ModelObject { } @RequirePOST + @Deprecated public HttpResponse doPin() throws IOException { Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); - new FileOutputStream(pinFile).close(); + // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ + LOGGER.log(WARNING, "Call to pin plugin has been ignored. Plugin name: " + shortName); return HttpResponses.ok(); } @RequirePOST + @Deprecated public HttpResponse doUnpin() throws IOException { Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); - pinFile.delete(); + // See https://groups.google.com/d/msg/jenkinsci-dev/kRobm-cxFw8/6V66uhibAwAJ + LOGGER.log(WARNING, "Call to unpin plugin has been ignored. Plugin name: " + shortName); return HttpResponses.ok(); } @RequirePOST public HttpResponse doDoUninstall() throws IOException { - Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + Jenkins jenkins = Jenkins.getActiveInstance(); + + jenkins.checkPermission(Jenkins.ADMINISTER); archive.delete(); + + // Redo who depends on who. + jenkins.getPluginManager().resolveDependantPlugins(); + return HttpResponses.redirectViaContextPath("/pluginManager/installed"); // send back to plugin manager } diff --git a/core/src/main/java/hudson/Proc.java b/core/src/main/java/hudson/Proc.java index 598fbca374efd2694ab661b9364bec81141cbd76..abe104462a8de0d04034c7132c4dbdd6e6614bbc 100644 --- a/core/src/main/java/hudson/Proc.java +++ b/core/src/main/java/hudson/Proc.java @@ -49,6 +49,8 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * External process wrapper. @@ -156,11 +158,7 @@ public abstract class Proc { unit.toString().toLowerCase(Locale.ENGLISH)); kill(); } - } catch (InterruptedException x) { - x.printStackTrace(listener.error("Failed to join a process")); - } catch (IOException x) { - x.printStackTrace(listener.error("Failed to join a process")); - } catch (RuntimeException x) { + } catch (InterruptedException | IOException | RuntimeException x) { x.printStackTrace(listener.error("Failed to join a process")); } } @@ -241,6 +239,9 @@ public abstract class Proc { this.out = out; this.cookie = EnvVars.createCookie(); procBuilder.environment().putAll(cookie); + if (procBuilder.directory() != null && !procBuilder.directory().exists()) { + throw new IOException(String.format("Process working directory '%s' doesn't exist!", procBuilder.directory().getAbsolutePath())); + } this.proc = procBuilder.start(); InputStream procInputStream = proc.getInputStream(); @@ -432,7 +433,7 @@ public abstract class Proc { * @deprecated as of 1.399. Replaced by {@link Launcher.RemoteLauncher.ProcImpl} */ @Deprecated - public static final class RemoteProc extends Proc { + public static final class RemoteProc extends Proc implements ProcWithJenkins23271Patch { private final Future process; public RemoteProc(Future process) { @@ -441,7 +442,14 @@ public abstract class Proc { @Override public void kill() throws IOException, InterruptedException { - process.cancel(true); + try { + process.cancel(true); + } finally { + if (this.isAlive()) { // Should never happen but this forces Proc to not be removed and early GC by escape analysis + // TODO: Report exceptions if they happen? + LOGGER.log(Level.WARNING, "Process {0} has not really finished after the kill() method execution", this); + } + } } @Override @@ -449,8 +457,8 @@ public abstract class Proc { try { return process.get(); } catch (InterruptedException e) { - // aborting. kill the process - process.cancel(true); + LOGGER.log(Level.FINE, String.format("Join operation has been interrupted for the process %s. Killing the process", this), e); + kill(); throw e; } catch (ExecutionException e) { if(e.getCause() instanceof IOException) @@ -458,6 +466,10 @@ public abstract class Proc { throw new IOException("Failed to join the process",e); } catch (CancellationException x) { return -1; + } finally { + if (this.isAlive()) { // Should never happen but this forces Proc to not be removed and early GC by escape analysis + LOGGER.log(Level.WARNING, "Process {0} has not really finished after the join() method completion", this); + } } } @@ -487,4 +499,15 @@ public abstract class Proc { * Debug switch to have the thread display the process it's waiting for. */ public static boolean SHOW_PID = false; + + /** + * An instance of {@link Proc}, which has an internal workaround for JENKINS-23271. + * It presumes that the instance of the object is guaranteed to be used after the {@link Proc#join()} call. + * See JENKINS-23271> + * @author Oleg Nenashev + */ + @Restricted(NoExternalUse.class) + public interface ProcWithJenkins23271Patch { + // Empty marker interface + } } diff --git a/core/src/main/java/hudson/ProxyConfiguration.java b/core/src/main/java/hudson/ProxyConfiguration.java index 9b5199092502586e20b2609e271a6f02f8184063..f7ce804f5e8e0c0ca3fbdbc39baf1da83035cc35 100644 --- a/core/src/main/java/hudson/ProxyConfiguration.java +++ b/core/src/main/java/hudson/ProxyConfiguration.java @@ -40,6 +40,7 @@ import java.io.Serializable; import java.net.Authenticator; import java.net.HttpURLConnection; import java.net.InetSocketAddress; +import java.net.MalformedURLException; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.URL; @@ -47,12 +48,17 @@ import java.net.URLConnection; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; +import javax.annotation.CheckForNull; import jenkins.model.Jenkins; +import jenkins.util.JenkinsJVM; +import jenkins.util.SystemProperties; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.NTCredentials; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; +import org.jenkinsci.Symbol; import org.jvnet.robust_http_client.RetryableHttpStream; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -72,6 +78,12 @@ import org.kohsuke.stapler.QueryParameter; * @see jenkins.model.Jenkins#proxy */ public final class ProxyConfiguration extends AbstractDescribableImpl implements Saveable, Serializable { + /** + * Holds a default TCP connect timeout set on all connections returned from this class, + * note this is value is in milliseconds, it's passed directly to {@link URLConnection#setConnectTimeout(int)} + */ + private static final int DEFAULT_CONNECT_TIMEOUT_MILLIS = SystemProperties.getInteger("hudson.ProxyConfiguration.DEFAULT_CONNECT_TIMEOUT_MILLIS", 20 * 1000); + public final String name; public final int port; @@ -215,34 +227,39 @@ public final class ProxyConfiguration extends AbstractDescribableImpl 0) { + con.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT_MILLIS); + } + + if (JenkinsJVM.isJenkinsJVM()) { // this code may run on a slave + decorate(con); } - - for (URLConnectionDecorator d : URLConnectionDecorator.all()) - d.decorate(con); return con; } - + public static InputStream getInputStream(URL url) throws IOException { - Jenkins h = Jenkins.getInstance(); // this code might run on slaves - final ProxyConfiguration p = (h != null) ? h.proxy : null; + final ProxyConfiguration p = get(); if (p == null) return new RetryableHttpStream(url); @@ -264,6 +281,27 @@ public final class ProxyConfiguration extends AbstractDescribableImpl { @Override public String getDisplayName() { @@ -304,17 +342,24 @@ public final class ProxyConfiguration extends AbstractDescribableImpl 0 ? DEFAULT_CONNECT_TIMEOUT_MILLIS : new Integer(30 * 1000)); HttpClient client = new HttpClient(); - if (Util.fixEmptyAndTrim(name) != null) { + if (Util.fixEmptyAndTrim(name) != null && !isNoProxyHost(host, noProxyHost)) { client.getHostConfiguration().setProxy(name, port); - Credentials credentials = - new UsernamePasswordCredentials(userName, Secret.fromString(password).getPlainText()); + Credentials credentials = createCredentials(userName, password); AuthScope scope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT); client.getState().setProxyCredentials(scope, credentials); } @@ -333,5 +378,26 @@ public final class ProxyConfiguration extends AbstractDescribableImpl= 0){ + final String domain = userName.substring(0, userName.indexOf('\\')); + final String user = userName.substring(userName.indexOf('\\') + 1); + return new NTCredentials(user, Secret.fromString(password).getPlainText(), domain, ""); + } else { + return new UsernamePasswordCredentials(userName, Secret.fromString(password).getPlainText()); + } + } } } diff --git a/core/src/main/java/hudson/TcpSlaveAgentListener.java b/core/src/main/java/hudson/TcpSlaveAgentListener.java index 46d99076aea2dff78d7c99f467f7222a7091c894..6bee598966fd5cde1a0346041f28cc4d236cfa54 100644 --- a/core/src/main/java/hudson/TcpSlaveAgentListener.java +++ b/core/src/main/java/hudson/TcpSlaveAgentListener.java @@ -23,7 +23,22 @@ */ package hudson; +import java.io.ByteArrayInputStream; +import java.io.SequenceInputStream; +import java.io.Writer; +import java.nio.charset.Charset; +import java.security.interfaces.RSAPublicKey; +import javax.annotation.Nullable; +import jenkins.model.Jenkins; +import jenkins.model.identity.InstanceIdentityProvider; +import jenkins.util.SystemProperties; import hudson.slaves.OfflineCause; +import java.io.DataOutputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.net.SocketAddress; +import java.util.Arrays; import jenkins.AgentProtocol; import java.io.BufferedWriter; @@ -37,13 +52,18 @@ import java.net.Socket; import java.nio.channels.ServerSocketChannel; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.Charsets; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.NullOutputStream; +import org.apache.commons.lang.StringUtils; /** - * Listens to incoming TCP connections from JNLP slave agents and CLI. + * Listens to incoming TCP connections from JNLP agents and CLI. * *

* Aside from the HTTP endpoint, Jenkins runs {@link TcpSlaveAgentListener} that listens on a TCP socket. - * Historically this was used for inbound connection from slave agents (hence the name), but over time + * Historically this was used for inbound connection from agents (hence the name), but over time * it was extended and made generic, so that multiple protocols of different purposes can co-exist on the * same socket. * @@ -66,7 +86,7 @@ public final class TcpSlaveAgentListener extends Thread { * Use 0 to choose a random port. */ public TcpSlaveAgentListener(int port) throws IOException { - super("TCP slave agent listener port="+port); + super("TCP agent listener port="+port); try { serverSocket = ServerSocketChannel.open(); serverSocket.socket().bind(new InetSocketAddress(port)); @@ -75,7 +95,7 @@ public final class TcpSlaveAgentListener extends Thread { } this.configuredPort = port; - LOGGER.log(Level.FINE, "JNLP slave agent listener started on TCP port {0}", getPort()); + LOGGER.log(Level.FINE, "JNLP agent listener started on TCP port {0}", getPort()); start(); } @@ -87,11 +107,41 @@ public final class TcpSlaveAgentListener extends Thread { return serverSocket.socket().getLocalPort(); } + /** + * Gets the TCP port number in which we are advertising. + * @since 1.656 + */ + public int getAdvertisedPort() { + return CLI_PORT != null ? CLI_PORT : getPort(); + } + + /** + * Gets the Base64 encoded public key that forms part of this instance's identity keypair. + * @return the Base64 encoded public key + * @since 2.16 + */ + @Nullable + public String getIdentityPublicKey() { + RSAPublicKey key = InstanceIdentityProvider.RSA.getPublicKey(); + return key == null ? null : new String(Base64.encodeBase64(key.getEncoded()), Charset.forName("UTF-8")); + } + + /** + * Returns a comma separated list of the enabled {@link AgentProtocol#getName()} implementations so that + * clients can avoid creating additional work for the server attempting to connect with unsupported protocols. + * + * @return a comma separated list of the enabled {@link AgentProtocol#getName()} implementations + * @since 2.16 + */ + public String getAgentProtocolNames() { + return StringUtils.join(Jenkins.getInstance().getAgentProtocols(), ", "); + } + @Override public void run() { try { // the loop eventually terminates when the socket is closed. - while (true) { + while (!shuttingDown) { Socket s = serverSocket.accept().socket(); // this prevents a connection from silently terminated by the router in between or the other peer @@ -105,7 +155,7 @@ public final class TcpSlaveAgentListener extends Thread { } } catch (IOException e) { if(!shuttingDown) { - LOGGER.log(Level.SEVERE,"Failed to accept JNLP slave agent connections",e); + LOGGER.log(Level.SEVERE,"Failed to accept JNLP agent connections",e); } } } @@ -115,6 +165,17 @@ public final class TcpSlaveAgentListener extends Thread { */ public void shutdown() { shuttingDown = true; + try { + SocketAddress localAddress = serverSocket.getLocalAddress(); + if (localAddress instanceof InetSocketAddress) { + InetSocketAddress address = (InetSocketAddress) localAddress; + Socket client = new Socket(address.getHostName(), address.getPort()); + client.setSoTimeout(1000); // waking the acceptor loop should be quick + new PingAgentProtocol().connect(client); + } + } catch (IOException e) { + LOGGER.log(Level.FINE, "Failed to send Ping to wake acceptor loop", e); + } try { serverSocket.close(); } catch (IOException e) { @@ -134,27 +195,43 @@ public final class TcpSlaveAgentListener extends Thread { synchronized(getClass()) { id = iotaGen++; } - setName("TCP slave agent connection handler #"+id+" with "+s.getRemoteSocketAddress()); + setName("TCP agent connection handler #"+id+" with "+s.getRemoteSocketAddress()); } @Override public void run() { try { - LOGGER.info("Accepted connection #"+id+" from "+s.getRemoteSocketAddress()); + LOGGER.log(Level.INFO, "Accepted connection #{0} from {1}", new Object[]{id,s.getRemoteSocketAddress()}); DataInputStream in = new DataInputStream(s.getInputStream()); PrintWriter out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8")), true); // DEPRECATED: newer protocol shouldn't use PrintWriter but should use DataOutputStream - String s = in.readUTF(); + // peek the first few bytes to determine what to do with this client + byte[] head = new byte[10]; + in.readFully(head); + + String header = new String(head, Charsets.US_ASCII); + if (header.startsWith("GET ")) { + // this looks like an HTTP client + respondHello(header,s); + return; + } + + // otherwise assume this is AgentProtocol and start from the beginning + String s = new DataInputStream(new SequenceInputStream(new ByteArrayInputStream(head),in)).readUTF(); if(s.startsWith("Protocol:")) { String protocol = s.substring(9); AgentProtocol p = AgentProtocol.of(protocol); - if (p!=null) - p.handle(this.s); - else + if (p!=null) { + if (Jenkins.getInstance().getAgentProtocols().contains(protocol)) { + p.handle(this.s); + } else { + error(out, "Disabled protocol:" + s); + } + } else error(out, "Unknown protocol:" + s); } else { error(out, "Unrecognized protocol: "+s); @@ -176,6 +253,42 @@ public final class TcpSlaveAgentListener extends Thread { } } + /** + * Respond to HTTP request with simple diagnostics. + * Primarily used to test the low-level connectivity. + */ + private void respondHello(String header, Socket s) throws IOException { + try { + Writer o = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); + + if (header.startsWith("GET / ")) { + o.write("HTTP/1.0 200 OK\r\n"); + o.write("Content-Type: text/plain;charset=UTF-8\r\n"); + o.write("\r\n"); + o.write("Jenkins-Agent-Protocols: " + getAgentProtocolNames()+"\r\n"); + o.write("Jenkins-Version: " + Jenkins.VERSION + "\r\n"); + o.write("Jenkins-Session: " + Jenkins.SESSION_HASH + "\r\n"); + o.write("Client: " + s.getInetAddress().getHostAddress() + "\r\n"); + o.write("Server: " + s.getLocalAddress().getHostAddress() + "\r\n"); + o.flush(); + s.shutdownOutput(); + } else { + o.write("HTTP/1.0 404 Not Found\r\n"); + o.write("Content-Type: text/plain;charset=UTF-8\r\n"); + o.write("\r\n"); + o.write("Not Found\r\n"); + o.flush(); + s.shutdownOutput(); + } + + InputStream i = s.getInputStream(); + IOUtils.copy(i, new NullOutputStream()); + s.shutdownInput(); + } finally { + s.close(); + } + } + private void error(PrintWriter out, String msg) throws IOException { out.println(msg); LOGGER.log(Level.WARNING,"Connection #"+id+" is aborted: "+msg); @@ -183,6 +296,95 @@ public final class TcpSlaveAgentListener extends Thread { } } + /** + * This extension provides a Ping protocol that allows people to verify that the TcpSlaveAgentListener is alive. + * We also use this to wake the acceptor thread on termination. + * + * @since 1.653 + */ + @Extension + public static class PingAgentProtocol extends AgentProtocol { + + private final byte[] ping; + + public PingAgentProtocol() { + try { + ping = "Ping\n".getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException("JLS mandates support for UTF-8 charset", e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isRequired() { + return true; + } + + @Override + public String getName() { + return "Ping"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return Messages.TcpSlaveAgentListener_PingAgentProtocol_displayName(); + } + + @Override + public void handle(Socket socket) throws IOException, InterruptedException { + try { + OutputStream stream = socket.getOutputStream(); + try { + LOGGER.log(Level.FINE, "Received ping request from {0}", socket.getRemoteSocketAddress()); + stream.write(ping); + stream.flush(); + LOGGER.log(Level.FINE, "Sent ping response to {0}", socket.getRemoteSocketAddress()); + } finally { + stream.close(); + } + } finally { + socket.close(); + } + } + + public boolean connect(Socket socket) throws IOException { + try { + DataOutputStream out = null; + InputStream in = null; + try { + LOGGER.log(Level.FINE, "Requesting ping from {0}", socket.getRemoteSocketAddress()); + out = new DataOutputStream(socket.getOutputStream()); + out.writeUTF("Protocol:Ping"); + in = socket.getInputStream(); + byte[] response = new byte[ping.length]; + int responseLength = in.read(response); + if (responseLength == ping.length && Arrays.equals(response, ping)) { + LOGGER.log(Level.FINE, "Received ping response from {0}", socket.getRemoteSocketAddress()); + return true; + } else { + LOGGER.log(Level.FINE, "Expected ping response from {0} of {1} got {2}", new Object[]{ + socket.getRemoteSocketAddress(), + new String(ping, "UTF-8"), + new String(response, 0, responseLength, "UTF-8") + }); + return false; + } + } finally { + IOUtils.closeQuietly(out); + IOUtils.closeQuietly(in); + } + } finally { + socket.close(); + } + } + } + /** * Connection terminated because we are reconnected from the current peer. */ @@ -203,7 +405,7 @@ public final class TcpSlaveAgentListener extends Thread { * * TODO: think about how to expose this (including whether this needs to be exposed at all.) */ - public static String CLI_HOST_NAME = System.getProperty(TcpSlaveAgentListener.class.getName()+".hostName"); + public static String CLI_HOST_NAME = SystemProperties.getString(TcpSlaveAgentListener.class.getName()+".hostName"); /** * Port number that we advertise the CLI client to connect to. @@ -215,7 +417,7 @@ public final class TcpSlaveAgentListener extends Thread { * * @since 1.611 */ - public static Integer CLI_PORT = Integer.getInteger(TcpSlaveAgentListener.class.getName()+".port"); + public static Integer CLI_PORT = SystemProperties.getInteger(TcpSlaveAgentListener.class.getName()+".port"); } /* @@ -250,4 +452,4 @@ the application gets it from the dynamic JNLP. Just write it so that it can't do anything useful without going through a protected path or doing something to present credentials that could only have come from a valid user. -*/ \ No newline at end of file +*/ diff --git a/core/src/main/java/hudson/UDPBroadcastFragment.java b/core/src/main/java/hudson/UDPBroadcastFragment.java index 9e7039f739566cba48c4ad53001d67447cb75730..069320298d1bdc4652a715832b21c3b341b81ce8 100644 --- a/core/src/main/java/hudson/UDPBroadcastFragment.java +++ b/core/src/main/java/hudson/UDPBroadcastFragment.java @@ -23,7 +23,6 @@ */ package hudson; -import jenkins.model.Jenkins; import java.net.SocketAddress; diff --git a/core/src/main/java/hudson/UDPBroadcastThread.java b/core/src/main/java/hudson/UDPBroadcastThread.java index ebc6eb9e1b9a518c7dab3d95782154f2f587cab6..03bdbc3bba5258a6efc0726cac002552a37dd417 100644 --- a/core/src/main/java/hudson/UDPBroadcastThread.java +++ b/core/src/main/java/hudson/UDPBroadcastThread.java @@ -23,17 +23,18 @@ */ package hudson; -import edu.umd.cs.findbugs.annotations.SuppressWarnings; +import jenkins.util.SystemProperties; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.Hudson; import jenkins.model.Jenkins; import hudson.util.OneShotEvent; import java.io.IOException; -import java.net.BindException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.SocketAddress; +import java.net.SocketException; import java.net.UnknownHostException; import java.nio.channels.ClosedByInterruptException; import java.util.logging.Level; @@ -70,7 +71,7 @@ public class UDPBroadcastThread extends Thread { mcs = new MulticastSocket(PORT); } - @SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") + @SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") @Override public void run() { try { @@ -103,10 +104,13 @@ public class UDPBroadcastThread extends Thread { } } catch (ClosedByInterruptException e) { // shut down - } catch (BindException e) { - // if we failed to listen to UDP, just silently abandon it, as a stack trace + } catch (SocketException e) { + if (shutdown) { // forcibly closed + return; + } // if we failed to listen to UDP, just silently abandon it, as a stack trace // makes people unnecessarily concerned, for a feature that currently does no good. - LOGGER.log(Level.WARNING, "Failed to listen to UDP port "+PORT,e); + LOGGER.log(Level.INFO, "Cannot listen to UDP port {0}, skipping: {1}", new Object[] {PORT, e}); + LOGGER.log(Level.FINE, null, e); } catch (IOException e) { if (shutdown) return; // forcibly closed LOGGER.log(Level.WARNING, "UDP handling problem",e); @@ -125,7 +129,7 @@ public class UDPBroadcastThread extends Thread { interrupt(); } - public static final int PORT = Integer.getInteger("hudson.udp",33848); + public static final int PORT = SystemProperties.getInteger("hudson.udp",33848); private static final Logger LOGGER = Logger.getLogger(UDPBroadcastThread.class.getName()); diff --git a/core/src/main/java/hudson/URLConnectionDecorator.java b/core/src/main/java/hudson/URLConnectionDecorator.java index d6aad07b7081e76a3a2ab81b317ff1a22b2489f0..f3794f4e33ea03467ea36486b0d4b32067104856 100644 --- a/core/src/main/java/hudson/URLConnectionDecorator.java +++ b/core/src/main/java/hudson/URLConnectionDecorator.java @@ -23,7 +23,6 @@ */ package hudson; -import jenkins.model.Jenkins; import java.io.IOException; import java.net.URL; diff --git a/core/src/main/java/hudson/Util.java b/core/src/main/java/hudson/Util.java index 24d2ffd268e7a5d76ba2af7a818c21bc8f3db687..4b56102bd5eee745307ed6ab1c27e2009873d112 100644 --- a/core/src/main/java/hudson/Util.java +++ b/core/src/main/java/hudson/Util.java @@ -23,16 +23,18 @@ */ package hudson; -import com.sun.jna.Memory; +import jenkins.util.SystemProperties; import com.sun.jna.Native; -import com.sun.jna.NativeLong; -import edu.umd.cs.findbugs.annotations.SuppressWarnings; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Proc.LocalProc; import hudson.model.TaskListener; import hudson.os.PosixAPI; import hudson.util.QuotedStringTokenizer; import hudson.util.VariableResolver; import hudson.util.jna.WinIOException; + import org.apache.commons.io.IOUtils; import org.apache.commons.lang.time.FastDateFormat; import org.apache.tools.ant.BuildException; @@ -40,14 +42,19 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Chmod; import org.apache.tools.ant.taskdefs.Copy; import org.apache.tools.ant.types.FileSet; + +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + import jnr.posix.FileStat; import jnr.posix.POSIX; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; + import java.io.*; -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.net.InetAddress; import java.net.URI; import java.net.URISyntaxException; @@ -57,6 +64,11 @@ import java.nio.CharBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.FileSystemException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.NumberFormat; @@ -70,12 +82,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import hudson.util.jna.Kernel32Utils; - import static hudson.util.jna.GNUCLibrary.LIBC; + import java.security.DigestInputStream; + import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; + import org.apache.commons.codec.digest.DigestUtils; /** @@ -184,14 +198,11 @@ public class Util { StringBuilder str = new StringBuilder((int)logfile.length()); - BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(logfile),charset)); - try { + try (BufferedReader r = new BufferedReader(new InputStreamReader(new FileInputStream(logfile), charset))) { char[] buf = new char[1024]; int len; - while((len=r.read(buf,0,buf.length))>0) - str.append(buf,0,len); - } finally { - r.close(); + while ((len = r.read(buf, 0, buf.length)) > 0) + str.append(buf, 0, len); } return str.toString(); @@ -200,24 +211,54 @@ public class Util { /** * Deletes the contents of the given directory (but not the directory itself) * recursively. + * It does not take no for an answer - if necessary, it will have multiple + * attempts at deleting things. * * @throws IOException * if the operation fails. */ public static void deleteContentsRecursive(@Nonnull File file) throws IOException { - File[] files = file.listFiles(); - if(files==null) - return; // the directory didn't exist in the first place - for (File child : files) - deleteRecursive(child); + for( int numberOfAttempts=1 ; ; numberOfAttempts++ ) { + try { + tryOnceDeleteContentsRecursive(file); + break; // success + } catch (IOException ex) { + boolean threadWasInterrupted = pauseBetweenDeletes(numberOfAttempts); + if( numberOfAttempts>= DELETION_MAX || threadWasInterrupted) + throw new IOException(deleteFailExceptionMessage(file, numberOfAttempts, threadWasInterrupted), ex); + } + } } /** * Deletes this file (and does not take no for an answer). + * If necessary, it will have multiple attempts at deleting things. + * * @param f a file to delete * @throws IOException if it exists but could not be successfully deleted */ public static void deleteFile(@Nonnull File f) throws IOException { + for( int numberOfAttempts=1 ; ; numberOfAttempts++ ) { + try { + tryOnceDeleteFile(f); + break; // success + } catch (IOException ex) { + boolean threadWasInterrupted = pauseBetweenDeletes(numberOfAttempts); + if( numberOfAttempts>= DELETION_MAX || threadWasInterrupted) + throw new IOException(deleteFailExceptionMessage(f, numberOfAttempts, threadWasInterrupted), ex); + } + } + } + + /** + * Deletes this file, working around most problems which might make + * this difficult. + * + * @param f + * What to delete. If a directory, it'll need to be empty. + * @throws IOException if it exists but could not be successfully deleted + */ + private static void tryOnceDeleteFile(File f) throws IOException { if (!f.delete()) { if(!f.exists()) // we are trying to delete a file that no longer exists, so this is not an error @@ -243,19 +284,9 @@ public class Util { if(!f.delete() && f.exists()) { // trouble-shooting. - try { - Class.forName("java.nio.file.Files").getMethod("delete", Class.forName("java.nio.file.Path")).invoke(null, File.class.getMethod("toPath").invoke(f)); - } catch (InvocationTargetException x) { - Throwable x2 = x.getCause(); - if (x2 instanceof IOException) { - // may have a specific exception message - throw (IOException) x2; - } - // else suppress - } catch (Throwable x) { - // linkage errors, etc.; suppress - } - // see http://www.nabble.com/Sometimes-can%27t-delete-files-from-hudson.scm.SubversionSCM%24CheckOutTask.invoke%28%29-tt17333292.html + Files.deleteIfExists(f.toPath()); + + // see https://java.net/projects/hudson/lists/users/archive/2008-05/message/357 // I suspect other processes putting files in this directory File[] files = f.listFiles(); if(files!=null && files.length>0) @@ -296,19 +327,146 @@ public class Util { } + /** + * Deletes the given directory (including its contents) recursively. + * It does not take no for an answer - if necessary, it will have multiple + * attempts at deleting things. + * + * @throws IOException + * if the operation fails. + */ public static void deleteRecursive(@Nonnull File dir) throws IOException { + for( int numberOfAttempts=1 ; ; numberOfAttempts++ ) { + try { + tryOnceDeleteRecursive(dir); + break; // success + } catch (IOException ex) { + boolean threadWasInterrupted = pauseBetweenDeletes(numberOfAttempts); + if( numberOfAttempts>= DELETION_MAX || threadWasInterrupted) + throw new IOException(deleteFailExceptionMessage(dir, numberOfAttempts, threadWasInterrupted), ex); + } + } + } + + /** + * Deletes a file or folder, throwing the first exception encountered, but + * having a go at deleting everything. i.e. it does not stop on the + * first exception, but tries (to delete) everything once. + * + * @param dir + * What to delete. If a directory, the contents will be deleted + * too. + * @throws The first exception encountered. + */ + private static void tryOnceDeleteRecursive(File dir) throws IOException { if(!isSymlink(dir)) - deleteContentsRecursive(dir); + tryOnceDeleteContentsRecursive(dir); + tryOnceDeleteFile(dir); + } + + /** + * Deletes a folder's contents, throwing the first exception encountered, + * but having a go at deleting everything. i.e. it does not stop + * on the first exception, but tries (to delete) everything once. + * + * @param directory + * The directory whose contents will be deleted. + * @throws The first exception encountered. + */ + private static void tryOnceDeleteContentsRecursive(File directory) throws IOException { + File[] directoryContents = directory.listFiles(); + if(directoryContents==null) + return; // the directory didn't exist in the first place + IOException firstCaught = null; + for (File child : directoryContents) { + try { + tryOnceDeleteRecursive(child); + } catch (IOException justCaught) { + if( firstCaught==null) { + firstCaught = justCaught; + } + } + } + if( firstCaught!=null ) + throw firstCaught; + } + + /** + * Pauses between delete attempts, and says if it's ok to try again. + * This does not wait if the wait time is zero or if we have tried + * too many times already. + *

+ * See {@link #WAIT_BETWEEN_DELETION_RETRIES} for details of + * the pause duration.
+ * See {@link #GC_AFTER_FAILED_DELETE} for when {@link System#gc()} is called. + * + * @return false if it is ok to continue trying to delete things, true if + * we were interrupted (and should stop now). + */ + @SuppressFBWarnings(value = "DM_GC", justification = "Garbage collection happens only when " + + "GC_AFTER_FAILED_DELETE is true. It's an experimental feature in Jenkins.") + private static boolean pauseBetweenDeletes(int numberOfAttemptsSoFar) { + long delayInMs; + if( numberOfAttemptsSoFar>=DELETION_MAX ) return false; + /* If the Jenkins process had the file open earlier, and it has not + * closed it then Windows won't let us delete it until the Java object + * with the open stream is Garbage Collected, which can result in builds + * failing due to "file in use" on Windows despite working perfectly + * well on other OSs. */ + if (GC_AFTER_FAILED_DELETE) { + System.gc(); + } + if (WAIT_BETWEEN_DELETION_RETRIES>=0) { + delayInMs = WAIT_BETWEEN_DELETION_RETRIES; + } else { + delayInMs = -numberOfAttemptsSoFar*WAIT_BETWEEN_DELETION_RETRIES; + } + if (delayInMs<=0) + return Thread.interrupted(); try { - deleteFile(dir); - } catch (IOException e) { - // if some of the child directories are big, it might take long enough to delete that - // it allows others to create new files, causing problemsl ike JENKINS-10113 - // so give it one more attempt before we give up. - if(!isSymlink(dir)) - deleteContentsRecursive(dir); - deleteFile(dir); + Thread.sleep(delayInMs); + return false; + } catch (InterruptedException e) { + return true; + } + } + + /** + * Creates a "couldn't delete file" message that explains how hard we tried. + * See {@link #DELETION_MAX}, {@link #WAIT_BETWEEN_DELETION_RETRIES} + * and {@link #GC_AFTER_FAILED_DELETE} for more details. + */ + private static String deleteFailExceptionMessage(File whatWeWereTryingToRemove, int retryCount, boolean wasInterrupted) { + StringBuilder sb = new StringBuilder(); + sb.append("Unable to delete '"); + sb.append(whatWeWereTryingToRemove); + sb.append("'. Tried "); + sb.append(retryCount); + sb.append(" time"); + if( retryCount!=1 ) sb.append('s'); + if( DELETION_MAX>1 ) { + sb.append(" (of a maximum of "); + sb.append(DELETION_MAX); + sb.append(')'); + if( GC_AFTER_FAILED_DELETE ) + sb.append(" garbage-collecting"); + if( WAIT_BETWEEN_DELETION_RETRIES!=0 && GC_AFTER_FAILED_DELETE ) + sb.append(" and"); + if( WAIT_BETWEEN_DELETION_RETRIES!=0 ) { + sb.append(" waiting "); + sb.append(getTimeSpanString(Math.abs(WAIT_BETWEEN_DELETION_RETRIES))); + if( WAIT_BETWEEN_DELETION_RETRIES<0 ) { + sb.append("-"); + sb.append(getTimeSpanString(Math.abs(WAIT_BETWEEN_DELETION_RETRIES)*DELETION_MAX)); + } + } + if( WAIT_BETWEEN_DELETION_RETRIES!=0 || GC_AFTER_FAILED_DELETE) + sb.append(" between attempts"); } + if( wasInterrupted ) + sb.append(". The delete operation was interrupted before it completed successfully"); + sb.append('.'); + return sb.toString(); } /* @@ -331,19 +489,30 @@ public class Util { */ //Taken from http://svn.apache.org/viewvc/maven/shared/trunk/file-management/src/main/java/org/apache/maven/shared/model/fileset/util/FileSetManager.java?view=markup public static boolean isSymlink(@Nonnull File file) throws IOException { - Boolean r = isSymlinkJava7(file); - if (r != null) { - return r; - } + /* + * Windows Directory Junctions are effectively the same as Linux symlinks to directories. + * Unfortunately, the Java 7 NIO2 API function isSymbolicLink does not treat them as such. + * It thinks of them as normal directories. To use the NIO2 API & treat it like a symlink, + * you have to go through BasicFileAttributes and do the following check: + * isSymbolicLink() || isOther() + * The isOther() call will include Windows reparse points, of which a directory junction is. + * + * Since we already have a function that detects Windows junctions or symlinks and treats them + * both as symlinks, let's use that function and always call it before calling down to the + * NIO2 API. + * + */ if (Functions.isWindows()) { try { return Kernel32Utils.isJunctionOrSymlink(file); - } catch (UnsupportedOperationException e) { - // fall through - } catch (LinkageError e) { + } catch (UnsupportedOperationException | LinkageError e) { // fall through } } + Boolean r = isSymlinkJava7(file); + if (r != null) { + return r; + } String name = file.getName(); if (name.equals(".") || name.equals("..")) return false; @@ -358,13 +527,11 @@ public class Util { return !fileInCanonicalParent.getCanonicalFile().equals( fileInCanonicalParent.getAbsoluteFile() ); } - @SuppressWarnings("NP_BOOLEAN_RETURN_NULL") + @SuppressFBWarnings("NP_BOOLEAN_RETURN_NULL") private static Boolean isSymlinkJava7(@Nonnull File file) throws IOException { try { - Object path = File.class.getMethod("toPath").invoke(file); - return (Boolean) Class.forName("java.nio.file.Files").getMethod("isSymbolicLink", Class.forName("java.nio.file.Path")).invoke(null, path); - } catch (NoSuchMethodException x) { - return null; // fine, Java 6 + Path path = file.toPath(); + return Files.isSymbolicLink(path); } catch (Exception x) { throw (IOException) new IOException(x.toString()).initCause(x); } @@ -598,12 +765,9 @@ public class Util { MessageDigest md5 = MessageDigest.getInstance("MD5"); byte[] buffer = new byte[1024]; - DigestInputStream in =new DigestInputStream(source,md5); - try { - while(in.read(buffer)>=0) + try (DigestInputStream in = new DigestInputStream(source, md5)) { + while (in.read(buffer) >= 0) ; // simply discard the input - } finally { - in.close(); } return toHexString(md5.digest()); } catch (NoSuchAlgorithmException e) { @@ -636,11 +800,8 @@ public class Util { */ @Nonnull public static String getDigestOf(@Nonnull File file) throws IOException { - InputStream is = new FileInputStream(file); - try { + try (InputStream is = new FileInputStream(file)) { return getDigestOf(new BufferedInputStream(is)); - } finally { - is.close(); } } @@ -1212,48 +1373,36 @@ public class Util { private static boolean createSymlinkJava7(@Nonnull File baseDir, @Nonnull String targetPath, @Nonnull String symlinkPath) throws IOException { try { - Object path = File.class.getMethod("toPath").invoke(new File(baseDir, symlinkPath)); - Object target = Class.forName("java.nio.file.Paths").getMethod("get", String.class, String[].class).invoke(null, targetPath, new String[0]); - Class filesC = Class.forName("java.nio.file.Files"); - Class pathC = Class.forName("java.nio.file.Path"); - Class fileAlreadyExistsExceptionC = Class.forName("java.nio.file.FileAlreadyExistsException"); + Path path = new File(baseDir, symlinkPath).toPath(); + Path target = Paths.get(targetPath, new String[0]); - Object noAttrs = Array.newInstance(Class.forName("java.nio.file.attribute.FileAttribute"), 0); final int maxNumberOfTries = 4; final int timeInMillis = 100; for (int tryNumber = 1; tryNumber <= maxNumberOfTries; tryNumber++) { - filesC.getMethod("deleteIfExists", pathC).invoke(null, path); + Files.deleteIfExists(path); try { - filesC.getMethod("createSymbolicLink", pathC, pathC, noAttrs.getClass()).invoke(null, path, target, noAttrs); + Files.createSymbolicLink(path, target); break; - } - catch (Exception x) { - if (fileAlreadyExistsExceptionC.isInstance(x)) { - if(tryNumber < maxNumberOfTries) { - TimeUnit.MILLISECONDS.sleep(timeInMillis); //trying to defeat likely ongoing race condition - continue; - } - LOGGER.warning("symlink FileAlreadyExistsException thrown "+maxNumberOfTries+" times => cannot createSymbolicLink"); + } catch (FileAlreadyExistsException fileAlreadyExistsException) { + if (tryNumber < maxNumberOfTries) { + TimeUnit.MILLISECONDS.sleep(timeInMillis); //trying to defeat likely ongoing race condition + continue; } - throw x; + LOGGER.warning("symlink FileAlreadyExistsException thrown " + maxNumberOfTries + " times => cannot createSymbolicLink"); + throw fileAlreadyExistsException; } } return true; - } catch (NoSuchMethodException x) { - return false; // fine, Java 6 - } catch (InvocationTargetException x) { - Throwable x2 = x.getCause(); - if (x2 instanceof UnsupportedOperationException) { + } catch (UnsupportedOperationException e) { return true; // no symlinks on this platform - } - if (Functions.isWindows() && String.valueOf(x2).contains("java.nio.file.FileSystemException")) { + } catch (FileSystemException e) { + if (Functions.isWindows()) { warnWindowsSymlink(); return true; } - if (x2 instanceof IOException) { - throw (IOException) x2; - } - throw (IOException) new IOException(x.toString()).initCause(x); + return false; + } catch (IOException x) { + throw x; } catch (Exception x) { throw (IOException) new IOException(x.toString()).initCause(x); } @@ -1304,62 +1453,19 @@ public class Util { */ @CheckForNull public static String resolveSymlink(@Nonnull File link) throws InterruptedException, IOException { - try { // Java 7 - Object path = File.class.getMethod("toPath").invoke(link); - return Class.forName("java.nio.file.Files").getMethod("readSymbolicLink", Class.forName("java.nio.file.Path")).invoke(null, path).toString(); - } catch (NoSuchMethodException x) { - // fine, Java 6; fall through - } catch (InvocationTargetException x) { - Throwable x2 = x.getCause(); - if (x2 instanceof UnsupportedOperationException) { - return null; // no symlinks on this platform - } - try { - if (Class.forName("java.nio.file.NotLinkException").isInstance(x2)) { - return null; - } - } catch (ClassNotFoundException x3) { - assert false : x3; // should be Java 7+ here - } - if (x2.getClass().getName().equals("java.nio.file.FileSystemException")) { - // Thrown ("Incorrect function.") on JDK 7u21 in Windows 2012 when called on a non-symlink, rather than NotLinkException, contrary to documentation. Maybe only when not on NTFS? - return null; - } - if (x2 instanceof IOException) { - throw (IOException) x2; - } - throw (IOException) new IOException(x.toString()).initCause(x); + try { + Path path = link.toPath(); + return Files.readSymbolicLink(path).toString(); + } catch (UnsupportedOperationException | FileSystemException x) { + // no symlinks on this platform (windows?), + // or not a link (// Thrown ("Incorrect function.") on JDK 7u21 in Windows 2012 when called on a non-symlink, + // rather than NotLinkException, contrary to documentation. Maybe only when not on NTFS?) ? + return null; + } catch (IOException x) { + throw x; } catch (Exception x) { throw (IOException) new IOException(x.toString()).initCause(x); } - - if(Functions.isWindows()) return null; - - String filename = link.getAbsolutePath(); - try { - for (int sz=512; sz < 65536; sz*=2) { - Memory m = new Memory(sz); - int r = LIBC.readlink(filename,m,new NativeLong(sz)); - if (r<0) { - int err = Native.getLastError(); - if (err==22/*EINVAL --- but is this really portable?*/) - return null; // this means it's not a symlink - throw new IOException("Failed to readlink "+link+" error="+ err+" "+ LIBC.strerror(err)); - } - if (r==sz) - continue; // buffer too small - - byte[] buf = new byte[r]; - m.read(0,buf,0,r); - return new String(buf); - } - // something is wrong. It can't be this long! - throw new IOException("Symlink too long: "+link); - } catch (LinkageError e) { - // if JNA is unavailable, fall back. - // we still prefer to try JNA first as PosixAPI supports even smaller platforms. - return PosixAPI.jnr().readlink(filename); - } } /** @@ -1415,16 +1521,36 @@ public class Util { } /** - * Checks if the public method defined on the base type with the given arguments - * are overridden in the given derived type. + * Checks if the method defined on the base type with the given arguments + * is overridden in the given derived type. */ public static boolean isOverridden(@Nonnull Class base, @Nonnull Class derived, @Nonnull String methodName, @Nonnull Class... types) { + return !getMethod(base, methodName, types).equals(getMethod(derived, methodName, types)); + } + + private static Method getMethod(@Nonnull Class clazz, @Nonnull String methodName, @Nonnull Class... types) { + Method res = null; try { - return !base.getMethod(methodName, types).equals( - derived.getMethod(methodName,types)); + res = clazz.getDeclaredMethod(methodName, types); + // private, static or final methods can not be overridden + if (res != null && (Modifier.isPrivate(res.getModifiers()) || Modifier.isFinal(res.getModifiers()) + || Modifier.isStatic(res.getModifiers()))) { + res = null; + } } catch (NoSuchMethodException e) { + // Method not found in clazz, let's search in superclasses + Class superclass = clazz.getSuperclass(); + if (superclass != null) { + res = getMethod(superclass, methodName, types); + } + } catch (SecurityException e) { throw new AssertionError(e); } + if (res == null) { + throw new IllegalArgumentException( + String.format("Method %s not found in %s (or it is private, final or static)", methodName, clazz.getName())); + } + return res; } /** @@ -1456,7 +1582,12 @@ public class Util { * The same algorithm can be seen in {@link URI}, but * implementing this by ourselves allow it to be more lenient about * escaping of URI. + * + * @deprecated Use {@code isAbsoluteOrSchemeRelativeUri} instead if your goal is to prevent open redirects */ + @Deprecated + @RestrictedSince("1.651.2 / 2.TODO") + @Restricted(NoExternalUse.class) public static boolean isAbsoluteUri(@Nonnull String uri) { int idx = uri.indexOf(':'); if (idx<0) return false; // no ':'. can't be absolute @@ -1465,6 +1596,14 @@ public class Util { return idx<_indexOf(uri, '#') && idx<_indexOf(uri,'?') && idx<_indexOf(uri,'/'); } + /** + * Return true iff the parameter does not denote an absolute URI and not a scheme-relative URI. + * @since 2.3 / 1.651.2 + */ + public static boolean isSafeToRedirectTo(@Nonnull String uri) { + return !isAbsoluteUri(uri) && !uri.startsWith("//"); + } + /** * Works like {@link String#indexOf(int)} but 'not found' is returned as s.length(), not -1. * This enables more straight-forward comparison. @@ -1485,6 +1624,28 @@ public class Util { p.load(new StringReader(properties)); return p; } + + /** + * Closes the item and logs error to the log in the case of error. + * Logging will be performed on the {@code WARNING} level. + * @param toClose Item to close. Nothing will happen if it is {@code null} + * @param logger Logger, which receives the error + * @param closeableName Name of the closeable item + * @param closeableOwner String representation of the closeable holder + * @since 2.19, but TODO update once un-restricted + */ + @Restricted(NoExternalUse.class) + public static void closeAndLogFailures(@CheckForNull Closeable toClose, @Nonnull Logger logger, + @Nonnull String closeableName, @Nonnull String closeableOwner) { + if (toClose == null) { + return; + } + try { + toClose.close(); + } catch(IOException ex) { + logger.log(Level.WARNING, String.format("Failed to close %s of %s", closeableName, closeableOwner), ex); + } + } public static final FastDateFormat XS_DATETIME_FORMATTER = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss'Z'",new SimpleTimeZone(0,"GMT")); @@ -1497,7 +1658,60 @@ public class Util { /** * On Unix environment that cannot run "ln", set this to true. */ - public static boolean NO_SYMLINK = Boolean.getBoolean(Util.class.getName()+".noSymLink"); + public static boolean NO_SYMLINK = SystemProperties.getBoolean(Util.class.getName()+".noSymLink"); + + public static boolean SYMLINK_ESCAPEHATCH = SystemProperties.getBoolean(Util.class.getName()+".symlinkEscapeHatch"); + + /** + * The number of times we will attempt to delete files/directory trees + * before giving up and throwing an exception.
+ * Specifying a value less than 1 is invalid and will be treated as if + * a value of 1 (i.e. one attempt, no retries) was specified. + *

+ * e.g. if some of the child directories are big, it might take long enough + * to delete that it allows others to create new files in the directory we + * are trying to empty, causing problems like JENKINS-10113. + * Or, if we're on Windows, then deletes can fail for transient reasons + * regardless of external activity; see JENKINS-15331. + * Whatever the reason, this allows us to do multiple attempts before we + * give up, thus improving build reliability. + */ + @Restricted(value = NoExternalUse.class) + static int DELETION_MAX = Math.max(1, SystemProperties.getInteger(Util.class.getName() + ".maxFileDeletionRetries", 3).intValue()); - public static boolean SYMLINK_ESCAPEHATCH = Boolean.getBoolean(Util.class.getName()+".symlinkEscapeHatch"); + /** + * The time (in milliseconds) that we will wait between attempts to + * delete files when retrying.
+ * This has no effect unless {@link #DELETION_MAX} is non-zero. + *

+ * If zero, we will not delay between attempts.
+ * If negative, we will wait an (linearly) increasing multiple of this value + * between attempts. + */ + @Restricted(value = NoExternalUse.class) + static int WAIT_BETWEEN_DELETION_RETRIES = SystemProperties.getInteger(Util.class.getName() + ".deletionRetryWait", 100).intValue(); + + /** + * If this flag is set to true then we will request a garbage collection + * after a deletion failure before we next retry the delete.
+ * It defaults to false and is ignored unless + * {@link #DELETION_MAX} is greater than 1. + *

+ * Setting this flag to true may resolve some problems on Windows, + * and also for directory trees residing on an NFS share, but it can + * have a negative impact on performance and may have no effect at all (GC + * behavior is JVM-specific). + *

+ * Warning: This should only ever be used if you find that your builds are + * failing because Jenkins is unable to delete files, that this failure is + * because Jenkins itself has those files locked "open", and even then it + * should only be used on slaves with relatively few executors (because the + * garbage collection can impact the performance of all job executors on + * that slave).
+ * i.e. Setting this flag is a act of last resort - it is not + * recommended, and should not be used on the main Jenkins server + * unless you can tolerate the performance impact. + */ + @Restricted(value = NoExternalUse.class) + static boolean GC_AFTER_FAILED_DELETE = SystemProperties.getBoolean(Util.class.getName() + ".performGCOnFailedDelete"); } diff --git a/core/src/main/java/hudson/WebAppMain.java b/core/src/main/java/hudson/WebAppMain.java index 11d438d5ab0496010403ef6e046d9684c8ca0a66..947363b78e652041dc9a8ea9f3791c5a0847b0ac 100644 --- a/core/src/main/java/hudson/WebAppMain.java +++ b/core/src/main/java/hudson/WebAppMain.java @@ -23,10 +23,13 @@ */ package hudson; +import hudson.security.ACLContext; +import jenkins.util.SystemProperties; import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider; import com.thoughtworks.xstream.core.JVM; import com.trilead.ssh2.util.IOUtils; import hudson.model.Hudson; +import hudson.security.ACL; import hudson.util.BootFailure; import jenkins.model.Jenkins; import hudson.util.HudsonIsLoading; @@ -40,6 +43,7 @@ import hudson.util.IncompatibleAntVersionDetected; import hudson.util.HudsonFailedToLoad; import hudson.util.ChartUtil; import hudson.util.AWTProblem; +import jenkins.util.JenkinsJVM; import org.jvnet.localizer.LocaleProvider; import org.kohsuke.stapler.jelly.JellyFacet; import org.apache.tools.ant.types.FileSet; @@ -56,7 +60,6 @@ import javax.xml.transform.TransformerFactoryConfigurationError; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.Date; @@ -74,7 +77,11 @@ import static java.util.logging.Level.*; * @author Kohsuke Kawaguchi */ public class WebAppMain implements ServletContextListener { - private final RingBufferLogHandler handler = new RingBufferLogHandler() { + + // use RingBufferLogHandler class name to configure for backward compatibility + private static final int DEFAULT_RING_BUFFER_SIZE = SystemProperties.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256); + + private final RingBufferLogHandler handler = new RingBufferLogHandler(DEFAULT_RING_BUFFER_SIZE) { @Override public synchronized void publish(LogRecord record) { if (record.getLevel().intValue() >= Level.INFO.intValue()) { super.publish(record); @@ -89,6 +96,7 @@ public class WebAppMain implements ServletContextListener { * Creates the sole instance of {@link jenkins.model.Jenkins} and register it to the {@link ServletContext}. */ public void contextInitialized(ServletContextEvent event) { + JenkinsJVMAccess._setJenkinsJVM(true); final ServletContext context = event.getServletContext(); File home=null; try { @@ -117,8 +125,6 @@ public class WebAppMain implements ServletContextListener { installLogger(); - markCookieAsHttpOnly(context); - final FileAndDescription describedHomeDir = getHomeDir(event); home = describedHomeDir.file.getAbsoluteFile(); home.mkdirs(); @@ -223,6 +229,11 @@ public class WebAppMain implements ServletContextListener { boolean success = false; try { Jenkins instance = new Hudson(_home, context); + + // one last check to make sure everything is in order before we go live + if (Thread.interrupted()) + throw new InterruptedException(); + context.setAttribute(APP, instance); BootFailure.getBootFailureFile(_home).delete(); @@ -236,7 +247,7 @@ public class WebAppMain implements ServletContextListener { } catch (Exception e) { new HudsonFailedToLoad(e).publish(context,_home); } finally { - Jenkins instance = Jenkins.getInstance(); + Jenkins instance = Jenkins.getInstanceOrNull(); if(!success && instance!=null) instance.cleanUp(); } @@ -244,38 +255,10 @@ public class WebAppMain implements ServletContextListener { }; initThread.start(); } catch (BootFailure e) { - e.publish(context,home); - } catch (Error e) { + e.publish(context, home); + } catch (Error | RuntimeException e) { LOGGER.log(SEVERE, "Failed to initialize Jenkins",e); throw e; - } catch (RuntimeException e) { - LOGGER.log(SEVERE, "Failed to initialize Jenkins",e); - throw e; - } - } - - /** - * Set the session cookie as HTTP only. - * - * @see discussion of this topic in OWASP - */ - private void markCookieAsHttpOnly(ServletContext context) { - try { - Method m; - try { - m = context.getClass().getMethod("getSessionCookieConfig"); - } catch (NoSuchMethodException x) { // 3.0+ - LOGGER.log(Level.FINE, "Failed to set secure cookie flag", x); - return; - } - Object sessionCookieConfig = m.invoke(context); - - // not exposing session cookie to JavaScript to mitigate damage caused by XSS - Class scc = Class.forName("javax.servlet.SessionCookieConfig"); - Method setHttpOnly = scc.getMethod("setHttpOnly",boolean.class); - setHttpOnly.invoke(sessionCookieConfig,true); - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to set HTTP-only cookie flag", e); } } @@ -308,7 +291,7 @@ public class WebAppMain implements ServletContextListener { /** * Installs log handler to monitor all Hudson logs. */ - @edu.umd.cs.findbugs.annotations.SuppressWarnings("LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE") + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE") private void installLogger() { Jenkins.logRecords = handler.getView(); Logger.getLogger("").addHandler(handler); @@ -357,9 +340,9 @@ public class WebAppMain implements ServletContextListener { // next the system property for (String name : HOME_NAMES) { - String sysProp = System.getProperty(name); + String sysProp = SystemProperties.getString(name); if(sysProp!=null) - return new FileAndDescription(new File(sysProp.trim()),"System.getProperty(\""+name+"\")"); + return new FileAndDescription(new File(sysProp.trim()),"SystemProperties.getProperty(\""+name+"\")"); } // look at the env var next @@ -391,21 +374,32 @@ public class WebAppMain implements ServletContextListener { } public void contextDestroyed(ServletContextEvent event) { - terminated = true; - Jenkins instance = Jenkins.getInstance(); - if(instance!=null) - instance.cleanUp(); - Thread t = initThread; - if (t!=null) - t.interrupt(); - - // Logger is in the system classloader, so if we don't do this - // the whole web app will never be undepoyed. - Logger.getLogger("").removeHandler(handler); + try (ACLContext old = ACL.as(ACL.SYSTEM)) { + terminated = true; + Jenkins instance = Jenkins.getInstanceOrNull(); + if (instance != null) + instance.cleanUp(); + Thread t = initThread; + if (t != null && t.isAlive()) { + LOGGER.log(Level.INFO, "Shutting down a Jenkins instance that was still starting up", new Throwable("reason")); + t.interrupt(); + } + + // Logger is in the system classloader, so if we don't do this + // the whole web app will never be undepoyed. + Logger.getLogger("").removeHandler(handler); + } finally { + JenkinsJVMAccess._setJenkinsJVM(false); + } } private static final Logger LOGGER = Logger.getLogger(WebAppMain.class.getName()); + private static final class JenkinsJVMAccess extends JenkinsJVM { + private static void _setJenkinsJVM(boolean jenkinsJVM) { + JenkinsJVM.setJenkinsJVM(jenkinsJVM); + } + } private static final String[] HOME_NAMES = {"JENKINS_HOME","HUDSON_HOME"}; } diff --git a/core/src/main/java/hudson/XmlFile.java b/core/src/main/java/hudson/XmlFile.java index 00eae060e9f378a4631ab505bc3e9daedb39fad2..9f438eededb82797f92ae944386c8486be187b8b 100644 --- a/core/src/main/java/hudson/XmlFile.java +++ b/core/src/main/java/hudson/XmlFile.java @@ -28,7 +28,7 @@ import com.thoughtworks.xstream.XStreamException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.StreamException; -import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.io.xml.Xpp3Driver; import hudson.diagnosis.OldDataMonitor; import hudson.model.Descriptor; import hudson.util.AtomicFileWriter; @@ -51,6 +51,7 @@ import java.io.InputStreamReader; import java.io.Reader; import java.io.Writer; import java.io.StringWriter; +import java.io.UnsupportedEncodingException; import java.util.logging.Level; import java.util.logging.Logger; @@ -137,15 +138,10 @@ public final class XmlFile { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Reading "+file); } - InputStream in = new BufferedInputStream(new FileInputStream(file)); - try { + try (InputStream in = new BufferedInputStream(new FileInputStream(file))) { return xs.fromXML(in); - } catch (XStreamException e) { - throw new IOException("Unable to read "+file,e); - } catch(Error e) {// mostly reflection errors + } catch (XStreamException | Error e) { throw new IOException("Unable to read "+file,e); - } finally { - in.close(); } } @@ -157,16 +153,12 @@ public final class XmlFile { * if the XML representation is completely new. */ public Object unmarshal( Object o ) throws IOException { - InputStream in = new BufferedInputStream(new FileInputStream(file)); - try { + + try (InputStream in = new BufferedInputStream(new FileInputStream(file))) { // TODO: expose XStream the driver from XStream return xs.unmarshal(DEFAULT_DRIVER.createReader(in), o); - } catch (XStreamException e) { - throw new IOException("Unable to read "+file,e); - } catch(Error e) {// mostly reflection errors + } catch (XStreamException | Error e) { throw new IOException("Unable to read "+file,e); - } finally { - in.close(); } } @@ -205,9 +197,19 @@ public final class XmlFile { * Opens a {@link Reader} that loads XML. * This method uses {@link #sniffEncoding() the right encoding}, * not just the system default encoding. + * @throws IOException Encoding issues + * @return Reader for the file. should be close externally once read. */ public Reader readRaw() throws IOException { - return new InputStreamReader(new FileInputStream(file),sniffEncoding()); + FileInputStream fileInputStream = new FileInputStream(file); + try { + return new InputStreamReader(fileInputStream, sniffEncoding()); + } catch(IOException ex) { + // Exception may happen if we fail to find encoding or if this encoding is unsupported. + // In such case we close the underlying stream and rethrow. + Util.closeAndLogFailures(fileInputStream, LOGGER, "FileInputStream", file.toString()); + throw ex; + } } /** @@ -224,11 +226,8 @@ public final class XmlFile { * Writer will not be closed by the implementation. */ public void writeRawTo(Writer w) throws IOException { - Reader r = readRaw(); - try { - Util.copyStream(r,w); - } finally { - r.close(); + try (Reader r = readRaw()) { + Util.copyStream(r, w); } } @@ -247,10 +246,10 @@ public final class XmlFile { this.encoding = encoding; } } - InputSource input = new InputSource(file.toURI().toASCIIString()); - input.setByteStream(new FileInputStream(file)); - try { + try (InputStream in = new FileInputStream(file)) { + InputSource input = new InputSource(file.toURI().toASCIIString()); + input.setByteStream(in); JAXP.newSAXParser().parse(input,new DefaultHandler() { private Locator loc; @Override @@ -292,9 +291,6 @@ public final class XmlFile { throw new IOException("Failed to detect encoding of "+file,e); } catch (ParserConfigurationException e) { throw new AssertionError(e); // impossible - } finally { - // some JAXP implementations appear to leak the file handle if we just call parse(File,DefaultHandler) - input.getByteStream().close(); } } @@ -307,7 +303,7 @@ public final class XmlFile { private static final SAXParserFactory JAXP = SAXParserFactory.newInstance(); - private static final XppDriver DEFAULT_DRIVER = new XppDriver(); + private static final Xpp3Driver DEFAULT_DRIVER = new Xpp3Driver(); static { JAXP.setNamespaceAware(true); diff --git a/core/src/main/java/hudson/cli/AddJobToViewCommand.java b/core/src/main/java/hudson/cli/AddJobToViewCommand.java index cea483785a304ea5651758c4f078e8b8d2cb18b3..792ff4feaa4cacdce65ddafceaf8c61cf0701ba6 100644 --- a/core/src/main/java/hudson/cli/AddJobToViewCommand.java +++ b/core/src/main/java/hudson/cli/AddJobToViewCommand.java @@ -31,7 +31,6 @@ import hudson.model.DirectlyModifiableView; import hudson.model.View; import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.CmdLineException; /** * @author ogondza @@ -55,9 +54,8 @@ public class AddJobToViewCommand extends CLICommand { protected int run() throws Exception { view.checkPermission(View.CONFIGURE); - if (!(view instanceof DirectlyModifiableView)) throw new CmdLineException( - null, "'" + view.getDisplayName() + "' view can not be modified directly" - ); + if (!(view instanceof DirectlyModifiableView)) throw new IllegalStateException( + "'" + view.getDisplayName() + "' view can not be modified directly"); for (TopLevelItem job: jobs) { ((DirectlyModifiableView) view).add(job); diff --git a/core/src/main/java/hudson/cli/BuildCommand.java b/core/src/main/java/hudson/cli/BuildCommand.java index 39df01901ad1fe0a916afd00b704bed6cbf7c17f..dbe330ec23270b0f3ea26975a0063fe00cf0a1bc 100644 --- a/core/src/main/java/hudson/cli/BuildCommand.java +++ b/core/src/main/java/hudson/cli/BuildCommand.java @@ -25,24 +25,28 @@ package hudson.cli; import hudson.Util; import hudson.console.ModelHyperlinkNote; -import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Cause.UserIdCause; +import hudson.model.CauseAction; +import hudson.model.Job; +import hudson.model.Run; import hudson.model.ParametersAction; import hudson.model.ParameterValue; import hudson.model.ParametersDefinitionProperty; import hudson.model.ParameterDefinition; import hudson.Extension; import hudson.AbortException; +import hudson.model.Queue; import hudson.model.Item; -import hudson.model.Result; import hudson.model.TaskListener; import hudson.model.User; import hudson.model.queue.QueueTaskFuture; -import hudson.scm.PollingResult.Change; import hudson.util.EditDistance; import hudson.util.StreamTaskListener; + +import jenkins.scm.SCMDecisionHandler; import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.Option; import java.util.Map; @@ -52,9 +56,10 @@ import java.util.ArrayList; import java.util.Map.Entry; import java.io.FileNotFoundException; import java.io.PrintStream; -import javax.annotation.Nonnull; import jenkins.model.Jenkins; +import jenkins.model.ParameterizedJobMixIn; +import jenkins.triggers.SCMTriggerItem; /** * Builds a job, and optionally waits until its completion. @@ -69,7 +74,7 @@ public class BuildCommand extends CLICommand { } @Argument(metaVar="JOB",usage="Name of the job to build",required=true) - public AbstractProject job; + public Job job; @Option(name="-f", usage="Follow the build progress. Like -s only interrupts are not passed through to the build.") public boolean follow = false; @@ -92,7 +97,7 @@ public class BuildCommand extends CLICommand { @Option(name="-r") @Deprecated public int retryCnt = 10; - protected static final String BUILD_SCHEDULING_REFUSED = "Build scheduling Refused by an extension, hence not in Queue"; + protected static final String BUILD_SCHEDULING_REFUSED = "Build scheduling Refused by an extension, hence not in Queue."; protected int run() throws Exception { job.checkPermission(Item.BUILD); @@ -101,7 +106,7 @@ public class BuildCommand extends CLICommand { if (!parameters.isEmpty()) { ParametersDefinitionProperty pdp = job.getProperty(ParametersDefinitionProperty.class); if (pdp==null) - throw new AbortException(job.getFullDisplayName()+" is not parameterized but the -p option was specified"); + throw new IllegalStateException(job.getFullDisplayName()+" is not parameterized but the -p option was specified."); //TODO: switch to type annotations after the migration to Java 1.8 List values = new ArrayList(); @@ -110,12 +115,14 @@ public class BuildCommand extends CLICommand { String name = e.getKey(); ParameterDefinition pd = pdp.getParameterDefinition(name); if (pd==null) { - throw new AbortException(String.format("\'%s\' is not a valid parameter. Did you mean %s?", - name, EditDistance.findNearest(name, pdp.getParameterDefinitionNames()))); + String nearest = EditDistance.findNearest(name, pdp.getParameterDefinitionNames()); + throw new CmdLineException(null, nearest == null ? + String.format("'%s' is not a valid parameter.", name) : + String.format("'%s' is not a valid parameter. Did you mean %s?", name, nearest)); } ParameterValue val = pd.createValue(this, Util.fixNull(e.getValue())); if (val == null) { - throw new AbortException(String.format("Cannot resolve the value for the parameter \'%s\'.",name)); + throw new CmdLineException(null, String.format("Cannot resolve the value for the parameter '%s'.",name)); } values.add(val); } @@ -128,7 +135,7 @@ public class BuildCommand extends CLICommand { // not passed in use default ParameterValue defaultValue = pd.getDefaultParameterValue(); if (defaultValue == null) { - throw new AbortException(String.format("No default value for the parameter \'%s\'.",pd.getName())); + throw new CmdLineException(null, String.format("No default value for the parameter '%s'.",pd.getName())); } values.add(defaultValue); } @@ -137,30 +144,35 @@ public class BuildCommand extends CLICommand { } if (checkSCM) { - if (job.poll(new StreamTaskListener(stdout, getClientCharset())).change == Change.NONE) { + SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job); + if (item == null) + throw new AbortException(job.getFullDisplayName()+" has no SCM trigger, but checkSCM was specified"); + // pre-emtively check for a polling veto + if (SCMDecisionHandler.firstShouldPollVeto(job) != null) { return 0; } + if (!item.poll(new StreamTaskListener(stdout, getClientCharset())).hasChanges()) + return 0; } if (!job.isBuildable()) { String msg = Messages.BuildCommand_CLICause_CannotBuildUnknownReasons(job.getFullDisplayName()); - if (job.isDisabled()) { + if (job instanceof AbstractProject && ((AbstractProject)job).isDisabled()) { msg = Messages.BuildCommand_CLICause_CannotBuildDisabled(job.getFullDisplayName()); } else if (job.isHoldOffBuildUntilSave()){ msg = Messages.BuildCommand_CLICause_CannotBuildConfigNotSaved(job.getFullDisplayName()); } - stderr.println(msg); - return -1; + throw new IllegalStateException(msg); } - QueueTaskFuture f = job.scheduleBuild2(0, new CLICause(Jenkins.getAuthentication().getName()), a); + Queue.Item item = ParameterizedJobMixIn.scheduleBuild2(job, 0, new CauseAction(new CLICause(Jenkins.getAuthentication().getName())), a); + QueueTaskFuture> f = item != null ? (QueueTaskFuture)item.getFuture() : null; if (wait || sync || follow) { if (f == null) { - stderr.println(BUILD_SCHEDULING_REFUSED); - return -1; + throw new IllegalStateException(BUILD_SCHEDULING_REFUSED); } - AbstractBuild b = f.waitForStart(); // wait for the start + Run b = f.waitForStart(); // wait for the start stdout.println("Started "+b.getFullDisplayName()); stdout.flush(); @@ -179,7 +191,9 @@ public class BuildCommand extends CLICommand { } catch (FileNotFoundException e) { if ( i == retryCnt ) { - throw e; + Exception myException = new AbortException(); + myException.initCause(e); + throw myException; } i++; Thread.sleep(retryInterval); @@ -195,7 +209,9 @@ public class BuildCommand extends CLICommand { } else { // if the CLI is aborted, try to abort the build as well f.cancel(true); - throw e; + Exception myException = new AbortException(); + myException.initCause(e); + throw myException; } } } @@ -216,9 +232,9 @@ public class BuildCommand extends CLICommand { "With the -f option, this command changes the exit code based on\n" + "the outcome of the build (exit code 0 indicates a success)\n" + "however, unlike -s, interrupting the command will not interrupt\n" + - "the job (exit code 125 indicates the command was interrupted)\n" + + "the job (exit code 125 indicates the command was interrupted).\n" + "With the -c option, a build will only run if there has been\n" + - "an SCM change" + "an SCM change." ); } diff --git a/core/src/main/java/hudson/cli/CLIAction.java b/core/src/main/java/hudson/cli/CLIAction.java index 3253fc2840074f4674e69d3f45456716f0692fcd..0053c278bc3ab5333f81f55470c3f9592244e774 100644 --- a/core/src/main/java/hudson/cli/CLIAction.java +++ b/core/src/main/java/hudson/cli/CLIAction.java @@ -34,6 +34,7 @@ import javax.servlet.http.HttpServletResponse; import hudson.model.UnprotectedRootAction; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponses.HttpResponseException; @@ -51,7 +52,7 @@ import hudson.remoting.Channel; * * @author ogondza */ -@Extension +@Extension @Symbol("cli") @Restricted(NoExternalUse.class) public class CLIAction implements UnprotectedRootAction, StaplerProxy { @@ -62,23 +63,22 @@ public class CLIAction implements UnprotectedRootAction, StaplerProxy { } public String getDisplayName() { - return "Jenkins CLI"; } public String getUrlName() { - return "cli"; + return jenkins.CLI.DISABLED ? null : "cli"; } public void doCommand(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getActiveInstance(); jenkins.checkPermission(Jenkins.READ); // Strip trailing slash final String commandName = req.getRestOfPath().substring(1); CLICommand command = CLICommand.clone(commandName); if (command == null) { - rsp.sendError(HttpServletResponse.SC_NOT_FOUND, "No such command " + commandName); + rsp.sendError(HttpServletResponse.SC_NOT_FOUND, "No such command"); return; } @@ -112,7 +112,7 @@ public class CLIAction implements UnprotectedRootAction, StaplerProxy { FullDuplexHttpChannel server; if(req.getHeader("Side").equals("download")) { - duplexChannels.put(uuid,server=new FullDuplexHttpChannel(uuid, !Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) { + duplexChannels.put(uuid,server=new FullDuplexHttpChannel(uuid, !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER)) { @Override protected void main(Channel channel) throws IOException, InterruptedException { // capture the identity given by the transport, since this can be useful for SecurityRealm.createCliAuthenticator() diff --git a/core/src/main/java/hudson/cli/CLICommand.java b/core/src/main/java/hudson/cli/CLICommand.java index 2c68b0f6ff7ae094250e8dc89c14c81a8fad3280..2ebd3291defe6061178dbf47746b8351c2d89358 100644 --- a/core/src/main/java/hudson/cli/CLICommand.java +++ b/core/src/main/java/hudson/cli/CLICommand.java @@ -29,6 +29,7 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.cli.declarative.CLIMethod; import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; +import jenkins.util.SystemProperties; import hudson.cli.declarative.OptionHandlerExtension; import jenkins.model.Jenkins; import hudson.remoting.Callable; @@ -37,6 +38,7 @@ import hudson.remoting.ChannelProperty; import hudson.security.CliAuthenticator; import hudson.security.SecurityRealm; import jenkins.security.MasterToSlaveCallable; +import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.acegisecurity.BadCredentialsException; import org.acegisecurity.context.SecurityContext; @@ -122,6 +124,13 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { */ public transient PrintStream stdout,stderr; + /** + * Shared text, which is reported back to CLI if an error happens in commands + * taking lists of parameters. + * @since 2.26 + */ + static final String CLI_LISTPARAM_SUMMARY_ERROR_TEXT = "Error occurred while performing this command, see previous stderr output."; + /** * Connected to stdin of the CLI agent. * @@ -194,7 +203,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { * to an empty method. * You would however then have to consider {@link CliAuthenticator} and {@link #getTransportAuthentication}, * so this is not really recommended. - * + * * @param args * Arguments to the sub command. For example, if the CLI is invoked like "java -jar cli.jar foo bar zot", * then "foo" is the sub-command and the argument list is ["bar","zot"]. @@ -208,7 +217,23 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { * @param stderr * Connected to the stderr of the CLI client. * @return - * Exit code from the command. + * Exit code from the CLI command execution + * + *

+ * Jenkins standard exit codes from CLI: + * 0 means everything went well. + * 1 means further unspecified exception is thrown while performing the command. + * 2 means CmdLineException is thrown while performing the command. + * 3 means IllegalArgumentException is thrown while performing the command. + * 4 mean IllegalStateException is thrown while performing the command. + * 5 means AbortException is thrown while performing the command. + * 6 means AccessDeniedException is thrown while performing the command. + * 7 means BadCredentialsException is thrown while performing the command. + * 8-15 are reserved for future usage + * 16+ mean a custom CLI exit error code (meaning defined by the CLI command itself) + * + *

+ * Note: For details - see JENKINS-32273 */ public int main(List args, Locale locale, InputStream stdin, PrintStream stdout, PrintStream stderr) { this.stdin = new BufferedInputStream(stdin); @@ -219,42 +244,65 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { CmdLineParser p = getCmdLineParser(); // add options from the authenticator - SecurityContext sc = SecurityContextHolder.getContext(); - Authentication old = sc.getAuthentication(); + SecurityContext sc = null; + Authentication old = null; + try { + sc = SecurityContextHolder.getContext(); + old = sc.getAuthentication(); - CliAuthenticator authenticator = Jenkins.getInstance().getSecurityRealm().createCliAuthenticator(this); - sc.setAuthentication(getTransportAuthentication()); - new ClassParser().parse(authenticator,p); + CliAuthenticator authenticator = Jenkins.getActiveInstance().getSecurityRealm().createCliAuthenticator(this); + sc.setAuthentication(getTransportAuthentication()); + new ClassParser().parse(authenticator,p); - try { p.parseArgument(args.toArray(new String[args.size()])); Authentication auth = authenticator.authenticate(); if (auth==Jenkins.ANONYMOUS) auth = loadStoredAuthentication(); sc.setAuthentication(auth); // run the CLI with the right credential if (!(this instanceof LoginCommand || this instanceof HelpCommand)) - Jenkins.getInstance().checkPermission(Jenkins.READ); + Jenkins.getActiveInstance().checkPermission(Jenkins.READ); return run(); } catch (CmdLineException e) { - stderr.println(e.getMessage()); + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); printUsage(stderr, p); - return -1; + return 2; + } catch (IllegalStateException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 4; + } catch (IllegalArgumentException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 3; } catch (AbortException e) { // signals an error without stack trace - stderr.println(e.getMessage()); - return -1; + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 5; + } catch (AccessDeniedException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 6; } catch (BadCredentialsException e) { // to the caller, we can't reveal whether the user didn't exist or the password didn't match. // do that to the server log instead String id = UUID.randomUUID().toString(); - LOGGER.log(Level.INFO, "CLI login attempt failed: "+id, e); - stderr.println("Bad Credentials. Search the server log for "+id+" for more details."); - return -1; - } catch (Exception e) { + LOGGER.log(Level.INFO, "CLI login attempt failed: " + id, e); + stderr.println(""); + stderr.println("ERROR: Bad Credentials. Search the server log for " + id + " for more details."); + return 7; + } catch (Throwable e) { + final String errorMsg = String.format("Unexpected exception occurred while performing %s command.", + getName()); + stderr.println(""); + stderr.println("ERROR: " + errorMsg); + LOGGER.log(Level.WARNING, errorMsg, e); e.printStackTrace(stderr); - return -1; + return 1; } finally { - sc.setAuthentication(old); // restore + if(sc != null) + sc.setAuthentication(old); // restore } } @@ -343,13 +391,22 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { * To execute CLI method from outside, use {@link #main(List, Locale, InputStream, PrintStream, PrintStream)} * * @return - * 0 to indicate a success, otherwise an error code. - * @throws AbortException - * If the processing should be aborted. Hudson will report the error message - * without stack trace, and then exits this command. + * 0 to indicate a success, otherwise a custom error code. + * Error codes 1-15 shouldn;t be used in {@link #run()} as a custom error code. * @throws Exception - * All the other exceptions cause the stack trace to be dumped, and then - * the command exits with an error code. + * If a further unspecified exception is thrown; means: Unknown and/or unexpected issue occurred + * @throws CmdLineException + * If a wrong parameter specified, input value can't be decoded etc. + * @throws IllegalArgumentException + * If the execution can't continue due to wrong input parameter (job doesn't exist etc.) + * @throws IllegalStateException + * If the execution can't continue due to an incorect state of Jenkins, job, build etc. + * @throws AbortException + * If the execution can't continue due to an other (rare, but foreseeable) issue + * @throws AccessDeniedException + * If the caller doesn't have sufficent rights for requested action + * @throws BadCredentialsException + * If bad credentials were provided to CLI */ protected abstract int run() throws Exception; @@ -418,7 +475,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { } public String call() throws IOException { - return System.getProperty(name); + return SystemProperties.getString(name); } private static final long serialVersionUID = 1L; @@ -474,9 +531,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { protected CLICommand createClone() { try { return getClass().newInstance(); - } catch (IllegalAccessException e) { - throw new AssertionError(e); - } catch (InstantiationException e) { + } catch (IllegalAccessException | InstantiationException e) { throw new AssertionError(e); } } @@ -486,7 +541,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { */ protected void registerOptionHandlers() { try { - for (Class c : Index.list(OptionHandlerExtension.class, Jenkins.getInstance().pluginManager.uberClassLoader,Class.class)) { + for (Class c : Index.list(OptionHandlerExtension.class, Jenkins.getActiveInstance().pluginManager.uberClassLoader,Class.class)) { Type t = Types.getBaseClass(c, OptionHandler.class); CmdLineParser.registerHandler(Types.erasure(Types.getTypeArgument(t,0)), c); } @@ -538,7 +593,7 @@ public abstract class CLICommand implements ExtensionPoint, Cloneable { static { // register option handlers that are defined ClassLoaders cls = new ClassLoaders(); - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getActiveInstance(); if (j!=null) {// only when running on the master cls.put(j.getPluginManager().uberClassLoader); diff --git a/core/src/main/java/hudson/cli/CancelQuietDownCommand.java b/core/src/main/java/hudson/cli/CancelQuietDownCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..24b2ec301851fea81867b277c953d45ca1785097 --- /dev/null +++ b/core/src/main/java/hudson/cli/CancelQuietDownCommand.java @@ -0,0 +1,53 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package hudson.cli; + +import hudson.Extension; +import jenkins.model.Jenkins; + +import java.util.logging.Logger; + +/** + * Cancel previous quiet down Jenkins - preparation for a restart + * + * @author pjanouse + * @since 2.14 + */ +@Extension +public class CancelQuietDownCommand extends CLICommand { + + private static final Logger LOGGER = Logger.getLogger(CancelQuietDownCommand.class.getName()); + + @Override + public String getShortDescription() { + return Messages.CancelQuietDownCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + Jenkins.getActiveInstance().doCancelQuietDown(); + return 0; + } +} diff --git a/test/src/main/java/jenkins/model/WorkspaceWriter.java b/core/src/main/java/hudson/cli/ClearQueueCommand.java similarity index 62% rename from test/src/main/java/jenkins/model/WorkspaceWriter.java rename to core/src/main/java/hudson/cli/ClearQueueCommand.java index 5738f9ed8e53d7a3374f084e4e08b616433d7757..8e76a477aa12af83cf315b4c35a0e7253401a223 100644 --- a/test/src/main/java/jenkins/model/WorkspaceWriter.java +++ b/core/src/main/java/hudson/cli/ClearQueueCommand.java @@ -21,36 +21,35 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package jenkins.model; -import hudson.Launcher; -import hudson.model.BuildListener; -import hudson.model.AbstractBuild; +package hudson.cli; -import java.io.IOException; +import hudson.Extension; +import jenkins.model.Jenkins; +import org.acegisecurity.AccessDeniedException; -import org.jvnet.hudson.test.TestBuilder; +import java.util.logging.Logger; /** - * Write text into file in workspace. + * Clears the build queue * - * @author ogondza + * @author pjanouse + * @since 1.654 */ -public class WorkspaceWriter extends TestBuilder { +@Extension +public class ClearQueueCommand extends CLICommand { - private final String path; - private final String content; + private static final Logger LOGGER = Logger.getLogger(ClearQueueCommand.class.getName()); - public WorkspaceWriter(String path, String content) { - this.path = path; - this.content = content; + @Override + public String getShortDescription() { + return Messages.ClearQueueCommand_ShortDescription(); } @Override - public boolean perform( - AbstractBuild build, Launcher launcher, BuildListener listener - ) throws InterruptedException, IOException { - build.getWorkspace().child(path).write(content, "UTF-8"); - return true; + protected int run() throws Exception { + Jenkins.getActiveInstance().getQueue().clear(); + return 0; } + } diff --git a/test/src/main/java/org/jvnet/hudson/test/UnstableBuilder.java b/core/src/main/java/hudson/cli/CliCrumbExclusion.java similarity index 55% rename from test/src/main/java/org/jvnet/hudson/test/UnstableBuilder.java rename to core/src/main/java/hudson/cli/CliCrumbExclusion.java index 0bf6d0a1c9726943ddabfe6c3d6c32b404754a71..ac49349ccfcc91207325bd3933b75c2c8593ed77 100644 --- a/test/src/main/java/org/jvnet/hudson/test/UnstableBuilder.java +++ b/core/src/main/java/hudson/cli/CliCrumbExclusion.java @@ -1,18 +1,18 @@ /* * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * + * Copyright (c) 2016 CloudBees, Inc. + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,32 +21,32 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; +package hudson.cli; import hudson.Extension; -import hudson.model.Descriptor; -import hudson.model.Result; -import hudson.tasks.Builder; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; +import hudson.security.csrf.CrumbExclusion; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; /** - * Mock {@link Builder} that always cause a build to fail. - * - * @author Kohsuke Kawaguchi + * Makes CLI HTTP fallback work with CSRF protection enabled (JENKINS-18114). */ -public class UnstableBuilder extends MockBuilder { - public UnstableBuilder() { - super(Result.UNSTABLE); - } - - @Extension - public static final class DescriptorImpl extends Descriptor { - public String getDisplayName() { - return "Make build unstable"; - } - public UnstableBuilder newInstance(StaplerRequest req, JSONObject data) { - return new UnstableBuilder(); +@Extension +@Restricted(DoNotUse.class) +public class CliCrumbExclusion extends CrumbExclusion { + @Override + public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + String pathInfo = request.getPathInfo(); + if (pathInfo != null && "/cli".equals(pathInfo)) { + chain.doFilter(request, response); + return true; } + return false; } } diff --git a/core/src/main/java/hudson/cli/CliManagerImpl.java b/core/src/main/java/hudson/cli/CliManagerImpl.java index 7ff5247e854c4ae9a2cbfdb64298b6b0af7cdf65..577cf3ce132fe373b6f95e80c95ff2415e75e366 100644 --- a/core/src/main/java/hudson/cli/CliManagerImpl.java +++ b/core/src/main/java/hudson/cli/CliManagerImpl.java @@ -50,10 +50,11 @@ public class CliManagerImpl implements CliEntryPoint, Serializable { private Authentication transportAuth; + //TODO: Migrate the code to Callable decorator /** * Runs callable from this CLI client with the transport authentication credential. */ - private final CallableFilter authenticationFilter = new CallableFilter() { + private transient final CallableFilter authenticationFilter = new CallableFilter() { public V call(Callable callable) throws Exception { SecurityContext context = SecurityContextHolder.getContext(); Authentication old = context.getAuthentication(); diff --git a/core/src/main/java/hudson/cli/CliProtocol.java b/core/src/main/java/hudson/cli/CliProtocol.java index eecb4c5faf9da881203b3668cbfd9fe23f330182..d663957fe9debe8998bb698ece5067fa40b410bd 100644 --- a/core/src/main/java/hudson/cli/CliProtocol.java +++ b/core/src/main/java/hudson/cli/CliProtocol.java @@ -1,6 +1,7 @@ package hudson.cli; import hudson.Extension; +import hudson.Util; import hudson.model.Computer; import hudson.remoting.Channel; import hudson.remoting.Channel.Mode; @@ -8,6 +9,7 @@ import hudson.remoting.ChannelBuilder; import jenkins.AgentProtocol; import jenkins.model.Jenkins; import jenkins.slaves.NioChannelSelector; +import org.jenkinsci.Symbol; import org.jenkinsci.remoting.nio.NioChannelHub; import javax.inject.Inject; @@ -25,14 +27,30 @@ import java.net.Socket; * @author Kohsuke Kawaguchi * @since 1.467 */ -@Extension +@Extension @Symbol("cli") public class CliProtocol extends AgentProtocol { @Inject NioChannelSelector nio; + /** + * {@inheritDoc} + */ + @Override + public boolean isOptIn() { + return OPT_IN; + } + @Override public String getName() { - return "CLI-connect"; + return jenkins.CLI.DISABLED ? null : "CLI-connect"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return "Jenkins CLI Protocol/1"; } @Override @@ -77,11 +95,21 @@ public class CliProtocol extends AgentProtocol { Channel channel = cb .withMode(Mode.BINARY) .withRestricted(true) - .withBaseLoader(Jenkins.getInstance().pluginManager.uberClassLoader) + .withBaseLoader(Jenkins.getActiveInstance().pluginManager.uberClassLoader) .build(new BufferedInputStream(c.in), new BufferedOutputStream(c.out)); channel.setProperty(CliEntryPoint.class.getName(),new CliManagerImpl(channel)); channel.join(); } } + + /** + * A/B test turning off this protocol by default. + */ + private static final boolean OPT_IN; + + static { + byte hash = Util.fromHexString(Jenkins.getInstance().getLegacyInstanceId())[0]; + OPT_IN = (hash % 10) == 0; + } } diff --git a/core/src/main/java/hudson/cli/CliProtocol2.java b/core/src/main/java/hudson/cli/CliProtocol2.java index 0f2757df786b7dc72c0e8d4e59528aa79df4e6ad..bb14599dbfea037d7d07517d828ffb9aa7f968b9 100644 --- a/core/src/main/java/hudson/cli/CliProtocol2.java +++ b/core/src/main/java/hudson/cli/CliProtocol2.java @@ -2,6 +2,7 @@ package hudson.cli; import hudson.Extension; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.jenkinsci.remoting.nio.NioChannelHub; import javax.crypto.SecretKey; @@ -20,11 +21,27 @@ import java.security.Signature; * @author Kohsuke Kawaguchi * @since 1.467 */ -@Extension +@Extension @Symbol("cli2") public class CliProtocol2 extends CliProtocol { @Override public String getName() { - return "CLI2-connect"; + return jenkins.CLI.DISABLED ? null : "CLI2-connect"; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isOptIn() { + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return "Jenkins CLI Protocol/2"; } @Override @@ -60,7 +77,7 @@ public class CliProtocol2 extends CliProtocol { try { // HACK: TODO: move the transport support into modules - Class cls = Jenkins.getInstance().pluginManager.uberClassLoader.loadClass("org.jenkinsci.main.modules.instance_identity.InstanceIdentity"); + Class cls = Jenkins.getActiveInstance().pluginManager.uberClassLoader.loadClass("org.jenkinsci.main.modules.instance_identity.InstanceIdentity"); Object iid = cls.getDeclaredMethod("get").invoke(null); PrivateKey instanceId = (PrivateKey)cls.getDeclaredMethod("getPrivate").invoke(iid); @@ -69,13 +86,7 @@ public class CliProtocol2 extends CliProtocol { signer.initSign(instanceId); signer.update(secret); c.writeByteArray(signer.sign()); - } catch (ClassNotFoundException e) { - throw new Error(e); - } catch (IllegalAccessException e) { - throw new Error(e); - } catch (InvocationTargetException e) { - throw new Error(e); - } catch (NoSuchMethodException e) { + } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { throw new Error(e); } diff --git a/core/src/main/java/hudson/cli/CliTransportAuthenticator.java b/core/src/main/java/hudson/cli/CliTransportAuthenticator.java index 0db90cce10c8a57cb7bb9b56b4d63060cf625afd..f561a50eddf21c362f130fdf1c445f8003ceaa62 100644 --- a/core/src/main/java/hudson/cli/CliTransportAuthenticator.java +++ b/core/src/main/java/hudson/cli/CliTransportAuthenticator.java @@ -4,7 +4,6 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.remoting.Channel; import hudson.security.SecurityRealm; -import jenkins.model.Jenkins; /** * Perform {@link SecurityRealm} independent authentication. diff --git a/core/src/main/java/hudson/cli/ClientAuthenticationCache.java b/core/src/main/java/hudson/cli/ClientAuthenticationCache.java index b00b816d37d6e0391a307584480dfeccb6da0983..fb754417861c61c3e17b3c45ae66572d4f25b1c9 100644 --- a/core/src/main/java/hudson/cli/ClientAuthenticationCache.java +++ b/core/src/main/java/hudson/cli/ClientAuthenticationCache.java @@ -51,11 +51,8 @@ public class ClientAuthenticationCache implements Serializable { } }); if (store.exists()) { - InputStream istream = store.read(); - try { + try (InputStream istream = store.read()) { props.load(istream); - } finally { - istream.close(); } } } @@ -66,15 +63,13 @@ public class ClientAuthenticationCache implements Serializable { * @return {@link jenkins.model.Jenkins#ANONYMOUS} if no such credential is found, or if the stored credential is invalid. */ public Authentication get() { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); Secret userName = Secret.decrypt(props.getProperty(getPropertyKey())); if (userName==null) return Jenkins.ANONYMOUS; // failed to decrypt try { UserDetails u = h.getSecurityRealm().loadUserByUsername(userName.getPlainText()); return new UsernamePasswordAuthenticationToken(u.getUsername(), "", u.getAuthorities()); - } catch (AuthenticationException e) { - return Jenkins.ANONYMOUS; - } catch (DataAccessException e) { + } catch (AuthenticationException | DataAccessException e) { return Jenkins.ANONYMOUS; } } @@ -83,7 +78,7 @@ public class ClientAuthenticationCache implements Serializable { * Computes the key that identifies this Hudson among other Hudsons that the user has a credential for. */ private String getPropertyKey() { - String url = Jenkins.getInstance().getRootUrl(); + String url = Jenkins.getActiveInstance().getRootUrl(); if (url!=null) return url; return Secret.fromString("key").toString(); } @@ -92,7 +87,7 @@ public class ClientAuthenticationCache implements Serializable { * Persists the specified authentication. */ public void set(Authentication a) throws IOException, InterruptedException { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); // make sure that this security realm is capable of retrieving the authentication by name, // as it's not required. @@ -111,11 +106,8 @@ public class ClientAuthenticationCache implements Serializable { } private void save() throws IOException, InterruptedException { - OutputStream os = store.write(); - try { - props.store(os,"Credential store"); - } finally { - os.close(); + try (OutputStream os = store.write()) { + props.store(os, "Credential store"); } // try to protect this file from other users, if we can. store.chmod(0600); diff --git a/core/src/main/java/hudson/cli/CloneableCLICommand.java b/core/src/main/java/hudson/cli/CloneableCLICommand.java index 7fb3b96dd35a3841c491e4138f2cfc61c79c798c..f6a4c60b02c12a17b77481735f1d3b421adfe800 100644 --- a/core/src/main/java/hudson/cli/CloneableCLICommand.java +++ b/core/src/main/java/hudson/cli/CloneableCLICommand.java @@ -26,7 +26,7 @@ package hudson.cli; /** * {@link Cloneable} {@link CLICommand}. * - * Uses {@link #clone()} instead of "new" to create a copy for exection. + * Uses {@link #clone()} instead of "new" to create a copy for execution. * * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/cli/CommandDuringBuild.java b/core/src/main/java/hudson/cli/CommandDuringBuild.java index dfa65f487ae5de60b985039fb204575a8d3b18c0..67e7d64717f6377d1522c561e8d676bb53c707a1 100644 --- a/core/src/main/java/hudson/cli/CommandDuringBuild.java +++ b/core/src/main/java/hudson/cli/CommandDuringBuild.java @@ -27,7 +27,6 @@ package hudson.cli; import jenkins.model.Jenkins; import hudson.model.Job; import hudson.model.Run; -import hudson.remoting.Callable; import jenkins.security.MasterToSlaveCallable; import org.kohsuke.args4j.CmdLineException; @@ -46,7 +45,7 @@ public abstract class CommandDuringBuild extends CLICommand { protected Run getCurrentlyBuilding() throws CmdLineException { Run r = optCurrentlyBuilding(); if (r==null) - throw new CmdLineException("This CLI command works only when invoked from inside a build"); + throw new IllegalStateException("This CLI command works only when invoked from inside a build"); return r; } @@ -56,29 +55,30 @@ public abstract class CommandDuringBuild extends CLICommand { protected Run optCurrentlyBuilding() throws CmdLineException { try { CLICommand c = CLICommand.getCurrent(); - if (c==null) throw new IllegalStateException("Not executing a CLI command"); + if (c==null) + throw new IllegalStateException("Not executing a CLI command"); String[] envs = c.checkChannel().call(new GetCharacteristicEnvironmentVariables()); if (envs[0]==null || envs[1]==null) return null; - Job j = Jenkins.getInstance().getItemByFullName(envs[0],Job.class); - if (j==null) throw new CmdLineException("No such job: "+envs[0]); + Job j = Jenkins.getActiveInstance().getItemByFullName(envs[0],Job.class); + if (j==null) + throw new IllegalArgumentException("No such job: "+envs[0]); try { Run r = j.getBuildByNumber(Integer.parseInt(envs[1])); - if (r==null) throw new CmdLineException("No such build #"+envs[1]+" in "+envs[0]); + if (r==null) + throw new IllegalArgumentException("No such build #"+envs[1]+" in "+envs[0]); if (!r.isBuilding()) { - throw new CmdLineException(r + " is not currently being built"); + throw new IllegalStateException(r + " is not currently being built"); } return r; } catch (NumberFormatException e) { - throw new CmdLineException("Invalid build number: "+envs[1]); + throw new IllegalArgumentException("Invalid build number: "+envs[1]); } - } catch (IOException e) { - throw new CmdLineException("Failed to identify the build being executed",e); - } catch (InterruptedException e) { - throw new CmdLineException("Failed to identify the build being executed",e); + } catch (IOException | InterruptedException e) { + throw new IllegalArgumentException("Failed to identify the build being executed",e); } } diff --git a/core/src/main/java/hudson/cli/ConnectNodeCommand.java b/core/src/main/java/hudson/cli/ConnectNodeCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..ae20f5e60848507503cca9f3ff0d3a21cb9c53a5 --- /dev/null +++ b/core/src/main/java/hudson/cli/ConnectNodeCommand.java @@ -0,0 +1,104 @@ +/* + * The MIT License + * + * Copyright (c) 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.Computer; +import hudson.model.ComputerSet; +import hudson.util.EditDistance; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; + +import java.util.HashSet; +import java.util.List; +import java.util.logging.Logger; + +/** + * Reconnect to a node or nodes. + * @author pjanouse + * @since 2.6 + */ +@Extension +public class ConnectNodeCommand extends CLICommand { + + @Argument(metaVar="NAME", usage="Slave name, or empty string for master; comma-separated list is supported", required=true, multiValued=true) + private List nodes; + + @Option(name="-f", usage="Cancel any currently pending connect operation and retry from scratch") + public boolean force = false; + + private static final Logger LOGGER = Logger.getLogger(ConnectNodeCommand.class.getName()); + + @Override + public String getShortDescription() { + return Messages.ConnectNodeCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getActiveInstance(); + + final HashSet hs = new HashSet(); + hs.addAll(nodes); + + List names = null; + + for (String node_s : hs) { + Computer computer = null; + + try { + computer = jenkins.getComputer(node_s); + + if(computer == null) { + if(names == null) { + names = ComputerSet.getComputerNames(); + } + String adv = EditDistance.findNearest(node_s, names); + throw new IllegalArgumentException(adv == null ? + hudson.model.Messages.Computer_NoSuchSlaveExistsWithoutAdvice(node_s) : + hudson.model.Messages.Computer_NoSuchSlaveExists(node_s, adv)); + } + + computer.cliConnect(force); + } catch (Exception e) { + if (hs.size() == 1) { + throw e; + } + + final String errorMsg = String.format(node_s + ": " + e.getMessage()); + stderr.println(errorMsg); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/ConsoleCommand.java b/core/src/main/java/hudson/cli/ConsoleCommand.java index 5da97b0947b11846a0f282c7b9d0ca9685eba955..f4c3f719b5fdb98d3548a7c572136a4458d6e849 100644 --- a/core/src/main/java/hudson/cli/ConsoleCommand.java +++ b/core/src/main/java/hudson/cli/ConsoleCommand.java @@ -50,17 +50,20 @@ public class ConsoleCommand extends CLICommand { int n = Integer.parseInt(build); run = job.getBuildByNumber(n); if (run==null) - throw new CmdLineException("No such build #"+n); + throw new IllegalArgumentException("No such build #"+n); } catch (NumberFormatException e) { // maybe a permalink? Permalink p = job.getPermalinks().get(build); if (p!=null) { run = (AbstractBuild)p.resolve(job); if (run==null) - throw new CmdLineException("Permalink "+build+" produced no build"); + throw new IllegalStateException("Permalink "+build+" produced no build"); } else { Permalink nearest = job.getPermalinks().findNearest(build); - throw new CmdLineException(String.format("Not sure what you meant by \"%s\". Did you mean \"%s\"?", build, nearest.getId())); + throw new IllegalArgumentException(nearest == null ? + String.format("Not sure what you meant by \"%s\".", build) : + String.format("Not sure what you meant by \"%s\". Did you mean \"%s\"?", + build, nearest.getId())); } } @@ -75,12 +78,9 @@ public class ConsoleCommand extends CLICommand { pos = logText.writeLogTo(pos, w); } while (!logText.isComplete()); } else { - InputStream logInputStream = run.getLogInputStream(); - try { - IOUtils.skip(logInputStream,pos); - org.apache.commons.io.IOUtils.copy(new InputStreamReader(logInputStream,run.getCharset()),w); - } finally { - logInputStream.close(); + try (InputStream logInputStream = run.getLogInputStream()) { + IOUtils.skip(logInputStream, pos); + IOUtils.copy(new InputStreamReader(logInputStream, run.getCharset()), w); } } } finally { diff --git a/core/src/main/java/hudson/cli/CopyJobCommand.java b/core/src/main/java/hudson/cli/CopyJobCommand.java index 7d83fa99a076ec00c7228c6e4b58b7f562d111ff..3eb8049c1f723ee81963a34550eaa01db554a1af 100644 --- a/core/src/main/java/hudson/cli/CopyJobCommand.java +++ b/core/src/main/java/hudson/cli/CopyJobCommand.java @@ -50,11 +50,10 @@ public class CopyJobCommand extends CLICommand { public String dst; protected int run() throws Exception { - Jenkins jenkins = Jenkins.getInstance(); + Jenkins jenkins = Jenkins.getActiveInstance(); if (jenkins.getItemByFullName(dst)!=null) { - stderr.println("Job '"+dst+"' already exists"); - return -1; + throw new IllegalStateException("Job '"+dst+"' already exists"); } ModifiableTopLevelItemGroup ig = jenkins; @@ -69,7 +68,7 @@ public class CopyJobCommand extends CLICommand { if (item instanceof ModifiableTopLevelItemGroup) { ig = (ModifiableTopLevelItemGroup) item; } else { - throw new IllegalArgumentException("Can't create job from CLI in " + group); + throw new IllegalStateException("Can't create job from CLI in " + group); } dst = dst.substring(i + 1); } diff --git a/core/src/main/java/hudson/cli/CreateJobCommand.java b/core/src/main/java/hudson/cli/CreateJobCommand.java index 1e1b807c5ee257880a094a74c8d8bde7dc3db83d..0f0108c361b67c490db7c0d911f79bc07cbfb267 100644 --- a/core/src/main/java/hudson/cli/CreateJobCommand.java +++ b/core/src/main/java/hudson/cli/CreateJobCommand.java @@ -45,11 +45,10 @@ public class CreateJobCommand extends CLICommand { public String name; protected int run() throws Exception { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); if (h.getItemByFullName(name)!=null) { - stderr.println("Job '"+name+"' already exists"); - return -1; + throw new IllegalStateException("Job '"+name+"' already exists"); } ModifiableTopLevelItemGroup ig = h; @@ -64,7 +63,7 @@ public class CreateJobCommand extends CLICommand { if (item instanceof ModifiableTopLevelItemGroup) { ig = (ModifiableTopLevelItemGroup) item; } else { - throw new IllegalArgumentException("Can't create job from CLI in " + group); + throw new IllegalStateException("Can't create job from CLI in " + group); } name = name.substring(i + 1); } diff --git a/core/src/main/java/hudson/cli/CreateNodeCommand.java b/core/src/main/java/hudson/cli/CreateNodeCommand.java index b7ccac632fe260a0b8bc55ee10743a975e72a9bf..6a7f6dee7698cf6f5f4dddeb2167dd5df003a51f 100644 --- a/core/src/main/java/hudson/cli/CreateNodeCommand.java +++ b/core/src/main/java/hudson/cli/CreateNodeCommand.java @@ -53,7 +53,7 @@ public class CreateNodeCommand extends CLICommand { @Override protected int run() throws Exception { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getActiveInstance(); jenkins.checkPermission(Computer.CREATE); final Node newNode = (Node) Jenkins.XSTREAM2.fromXML(stdin); @@ -70,10 +70,7 @@ public class CreateNodeCommand extends CLICommand { } if (jenkins.getNode(newNode.getNodeName()) != null) { - - throw new CmdLineException( - null, "Node '" + newNode.getNodeName() + "' already exists" - ); + throw new IllegalStateException("Node '" + newNode.getNodeName() + "' already exists"); } jenkins.addNode(newNode); diff --git a/core/src/main/java/hudson/cli/CreateViewCommand.java b/core/src/main/java/hudson/cli/CreateViewCommand.java index 73fd374b854195f0d96de49f582f61c364509b32..d22a0b424f68a2e2926bd1b19cfa094735ea6b4a 100644 --- a/core/src/main/java/hudson/cli/CreateViewCommand.java +++ b/core/src/main/java/hudson/cli/CreateViewCommand.java @@ -49,7 +49,7 @@ public class CreateViewCommand extends CLICommand { @Override protected int run() throws Exception { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getActiveInstance(); jenkins.checkPermission(View.CREATE); View newView; @@ -57,16 +57,12 @@ public class CreateViewCommand extends CLICommand { newView = View.createViewFromXML(viewName, stdin); } catch (Failure ex) { - - stderr.format("Invalid view name: %s\n", ex.getMessage()); - return -1; + throw new IllegalArgumentException("Invalid view name: " + ex.getMessage()); } final String newName = newView.getViewName(); if (jenkins.getView(newName) != null) { - - stderr.format("View '%s' already exists\n", newName); - return -1; + throw new IllegalStateException("View '" + newName + "' already exists"); } jenkins.addView(newView); diff --git a/core/src/main/java/hudson/cli/DeleteBuildsCommand.java b/core/src/main/java/hudson/cli/DeleteBuildsCommand.java index 7a20cea783eb72d49ca0758bf29ea9fa2fd8d664..cfe21e072e7eb8592ea673fa7046d9a885398770 100644 --- a/core/src/main/java/hudson/cli/DeleteBuildsCommand.java +++ b/core/src/main/java/hudson/cli/DeleteBuildsCommand.java @@ -29,6 +29,7 @@ import hudson.model.Run; import java.io.IOException; import java.io.PrintStream; +import java.util.HashSet; import java.util.List; /** @@ -54,10 +55,16 @@ public class DeleteBuildsCommand extends AbstractBuildRangeCommand { protected int act(List> builds) throws IOException { job.checkPermission(Run.DELETE); - for (AbstractBuild build : builds) - build.delete(); + final HashSet hsBuilds = new HashSet(); - stdout.println("Deleted "+builds.size()+" builds"); + for (AbstractBuild build : builds) { + if (!hsBuilds.contains(build.number)) { + build.delete(); + hsBuilds.add(build.number); + } + } + + stdout.println("Deleted "+hsBuilds.size()+" builds"); return 0; } diff --git a/core/src/main/java/hudson/cli/DeleteJobCommand.java b/core/src/main/java/hudson/cli/DeleteJobCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..199296f87fc48d09a14d289ef4c36cea8f05901f --- /dev/null +++ b/core/src/main/java/hudson/cli/DeleteJobCommand.java @@ -0,0 +1,91 @@ +/* + * The MIT License + * + * Copyright (c) 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.AbstractItem; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; + +import java.util.List; +import java.util.HashSet; +import java.util.logging.Logger; + +/** + * CLI command, which deletes a job or multiple jobs. + * @author pjanouse + * @since 1.618 + */ +@Extension +public class DeleteJobCommand extends CLICommand { + + @Argument(usage="Name of the job(s) to delete", required=true, multiValued=true) + private List jobs; + + @Override + public String getShortDescription() { + + return Messages.DeleteJobCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getActiveInstance(); + + final HashSet hs = new HashSet(); + hs.addAll(jobs); + + for (String job_s: hs) { + AbstractItem job = null; + + try { + job = (AbstractItem) jenkins.getItemByFullName(job_s); + + if(job == null) { + throw new IllegalArgumentException("No such job '" + job_s + "'"); + } + + job.checkPermission(AbstractItem.DELETE); + job.delete(); + } catch (Exception e) { + if(hs.size() == 1) { + throw e; + } + + final String errorMsg = String.format(job_s + ": " + e.getMessage()); + stderr.println(errorMsg); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/DeleteNodeCommand.java b/core/src/main/java/hudson/cli/DeleteNodeCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..03001fccc3a10886fb164632952e426d31862ba7 --- /dev/null +++ b/core/src/main/java/hudson/cli/DeleteNodeCommand.java @@ -0,0 +1,90 @@ +/* + * The MIT License + * + * Copyright (c) 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.Node; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; + +import java.util.HashSet; +import java.util.List; +import java.util.logging.Logger; + +/** + * CLI command, which deletes Jenkins nodes. + * @author pjanouse + * @since 1.618 + */ +@Extension +public class DeleteNodeCommand extends CLICommand { + + @Argument(usage="Names of nodes to delete", required=true, multiValued=true) + private List nodes; + + @Override + public String getShortDescription() { + + return Messages.DeleteNodeCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getActiveInstance(); + + final HashSet hs = new HashSet(); + hs.addAll(nodes); + + for (String node_s : hs) { + Node node = null; + + try { + node = jenkins.getNode(node_s); + + if (node == null) { + throw new IllegalArgumentException("No such node '" + node_s + "'"); + } + + node.toComputer().doDoDelete(); + } catch (Exception e) { + if(hs.size() == 1) { + throw e; + } + + final String errorMsg = String.format(node_s + ": " + e.getMessage()); + stderr.println(errorMsg); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/DeleteViewCommand.java b/core/src/main/java/hudson/cli/DeleteViewCommand.java index 73414701139bab47cc931edb63df4b12e4e7b4c7..894978e683fcac696a634fcad383c199e5dec840 100644 --- a/core/src/main/java/hudson/cli/DeleteViewCommand.java +++ b/core/src/main/java/hudson/cli/DeleteViewCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2013 Red Hat, Inc. + * Copyright (c) 2013-5 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,21 +23,27 @@ */ package hudson.cli; +import hudson.AbortException; import hudson.Extension; +import hudson.cli.handlers.ViewOptionHandler; import hudson.model.ViewGroup; import hudson.model.View; import org.kohsuke.args4j.Argument; +import java.util.HashSet; +import java.util.List; +import java.util.logging.Logger; + /** - * @author ogondza + * @author ogondza, pjanouse * @since 1.538 */ @Extension public class DeleteViewCommand extends CLICommand { - @Argument(usage="Name of the view to delete", required=true) - private View view; + @Argument(usage="View names to delete", required=true, multiValued=true) + private List views; @Override public String getShortDescription() { @@ -48,20 +54,49 @@ public class DeleteViewCommand extends CLICommand { @Override protected int run() throws Exception { - view.checkPermission(View.DELETE); + boolean errorOccurred = false; - final ViewGroup group = view.getOwner(); - if (!group.canDelete(view)) { + // Remove duplicates + final HashSet hs = new HashSet(); + hs.addAll(views); - stderr.format("%s does not allow to delete '%s' view\n", - group.getDisplayName(), - view.getViewName() - ); - return -1; - } + ViewOptionHandler voh = new ViewOptionHandler(null, null, null); + + for(String view_s : hs) { + View view = null; + + try { + view = voh.getView(view_s); + + if (view == null) { + throw new IllegalArgumentException("View name is empty"); + } - group.deleteView(view);; + view.checkPermission(View.DELETE); + ViewGroup group = view.getOwner(); + if (!group.canDelete(view)) { + throw new IllegalStateException(String.format("%s does not allow to delete '%s' view", + group.getDisplayName(), + view.getViewName())); + } + + group.deleteView(view); + } catch (Exception e) { + if(hs.size() == 1) { + throw e; + } + + final String errorMsg = String.format(view_s + ": " + e.getMessage()); + stderr.println(errorMsg); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } return 0; } } diff --git a/core/src/main/java/hudson/cli/DisconnectNodeCommand.java b/core/src/main/java/hudson/cli/DisconnectNodeCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..65c95106eb5f8653007b8d62bf8aa5c8c5e987e0 --- /dev/null +++ b/core/src/main/java/hudson/cli/DisconnectNodeCommand.java @@ -0,0 +1,102 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.Computer; +import hudson.model.ComputerSet; +import hudson.util.EditDistance; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; + +import java.util.HashSet; +import java.util.List; +import java.util.logging.Logger; + +/** + * CLI Command, which disconnects nodes. + * @author pjanouse + * @since 2.4 + */ +@Extension +public class DisconnectNodeCommand extends CLICommand { + @Argument(metaVar = "NAME", usage = "Slave name, or empty string for master; comma-separated list is supported", required = true, multiValued = true) + private List nodes; + + @Option(name = "-m", usage = "Record the reason about why you are disconnecting this node") + public String cause; + + private static final Logger LOGGER = Logger.getLogger(DisconnectNodeCommand.class.getName()); + + @Override + public String getShortDescription() { + return Messages.DisconnectNodeCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getActiveInstance(); + + final HashSet hs = new HashSet(); + hs.addAll(nodes); + + List names = null; + + for (String node_s : hs) { + Computer computer = null; + + try { + computer = jenkins.getComputer(node_s); + + if (computer == null) { + if (names == null) { + names = ComputerSet.getComputerNames(); + } + String adv = EditDistance.findNearest(node_s, names); + throw new IllegalArgumentException(adv == null ? + hudson.model.Messages.Computer_NoSuchSlaveExistsWithoutAdvice(node_s) : + hudson.model.Messages.Computer_NoSuchSlaveExists(node_s, adv)); + } + + computer.cliDisconnect(cause); + } catch (Exception e) { + if (hs.size() == 1) { + throw e; + } + + stderr.println(String.format(node_s + ": " + e.getMessage())); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} \ No newline at end of file diff --git a/core/src/main/java/hudson/cli/GetJobCommand.java b/core/src/main/java/hudson/cli/GetJobCommand.java index efc1e90836927f593b6016c53615634d20d67978..051e75f6c0836a668a2bb7c9b0cf87d0f3f5d0a3 100644 --- a/core/src/main/java/hudson/cli/GetJobCommand.java +++ b/core/src/main/java/hudson/cli/GetJobCommand.java @@ -25,8 +25,6 @@ package hudson.cli; import hudson.Extension; import hudson.model.AbstractItem; -import hudson.model.Item; -import hudson.util.IOUtils; import org.kohsuke.args4j.Argument; /** @@ -43,10 +41,7 @@ public class GetJobCommand extends CLICommand { } protected int run() throws Exception { - job.checkPermission(Item.EXTENDED_READ); - IOUtils.copy( - job.getConfigFile().getFile(), - stdout); + job.writeConfigDotXml(stdout); return 0; } } diff --git a/core/src/main/java/hudson/cli/GroovyCommand.java b/core/src/main/java/hudson/cli/GroovyCommand.java index 7866e2f7228d6fde0ea480631c52676da97702fc..144c2dfe0cfe9d846e73c54cc77b4ab350af95b2 100644 --- a/core/src/main/java/hudson/cli/GroovyCommand.java +++ b/core/src/main/java/hudson/cli/GroovyCommand.java @@ -30,23 +30,15 @@ import hudson.model.AbstractProject; import jenkins.model.Jenkins; import hudson.model.Item; import hudson.model.Run; -import hudson.remoting.Callable; -import hudson.AbortException; import hudson.Extension; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.apache.commons.io.IOUtils; -import org.apache.commons.io.FileUtils; import java.io.IOException; -import java.io.Serializable; -import java.io.File; -import java.io.InputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import java.net.URL; -import java.net.MalformedURLException; /** * Executes the specified groovy script. @@ -71,7 +63,7 @@ public class GroovyCommand extends CLICommand { protected int run() throws Exception { // this allows the caller to manipulate the JVM state, so require the execute script privilege. - Jenkins.getInstance().checkPermission(Jenkins.RUN_SCRIPTS); + Jenkins.getActiveInstance().checkPermission(Jenkins.RUN_SCRIPTS); Binding binding = new Binding(); binding.setProperty("out",new PrintWriter(stdout,true)); @@ -81,7 +73,7 @@ public class GroovyCommand extends CLICommand { binding.setProperty("channel",channel); String j = getClientEnvironmentVariable("JOB_NAME"); if (j!=null) { - Item job = Jenkins.getInstance().getItemByFullName(j); + Item job = Jenkins.getActiveInstance().getItemByFullName(j); binding.setProperty("currentJob", job); String b = getClientEnvironmentVariable("BUILD_NUMBER"); if (b!=null && job instanceof AbstractProject) { @@ -90,7 +82,7 @@ public class GroovyCommand extends CLICommand { } } - GroovyShell groovy = new GroovyShell(Jenkins.getInstance().getPluginManager().uberClassLoader, binding); + GroovyShell groovy = new GroovyShell(Jenkins.getActiveInstance().getPluginManager().uberClassLoader, binding); groovy.run(loadScript(),"RemoteClass",remaining.toArray(new String[remaining.size()])); return 0; } diff --git a/core/src/main/java/hudson/cli/GroovyshCommand.java b/core/src/main/java/hudson/cli/GroovyshCommand.java index 48babcb90dbc98a2ca04941813357fec51505427..31f998d0aa5be777ef55f2d4c1bfbf3aab4fe459 100644 --- a/core/src/main/java/hudson/cli/GroovyshCommand.java +++ b/core/src/main/java/hudson/cli/GroovyshCommand.java @@ -41,7 +41,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import jline.UnsupportedTerminal; -import jline.Terminal; +import jline.TerminalFactory; import org.kohsuke.args4j.Argument; /** @@ -61,14 +61,22 @@ public class GroovyshCommand extends CLICommand { @Override protected int run() { // this allows the caller to manipulate the JVM state, so require the admin privilege. - Jenkins.getInstance().checkPermission(Jenkins.RUN_SCRIPTS); + Jenkins.getActiveInstance().checkPermission(Jenkins.RUN_SCRIPTS); // this being remote means no jline capability is available System.setProperty("jline.terminal", UnsupportedTerminal.class.getName()); - Terminal.resetTerminal(); + TerminalFactory.reset(); + + StringBuilder commandLine = new StringBuilder(); + for (String arg : args) { + if (commandLine.length() > 0) { + commandLine.append(" "); + } + commandLine.append(arg); + } Groovysh shell = createShell(stdin, stdout, stderr); - return shell.run(args.toArray(new String[args.size()])); + return shell.run(commandLine.toString()); } @SuppressWarnings({"unchecked","rawtypes"}) @@ -78,17 +86,17 @@ public class GroovyshCommand extends CLICommand { Binding binding = new Binding(); // redirect "println" to the CLI binding.setProperty("out", new PrintWriter(stdout,true)); - binding.setProperty("hudson", Jenkins.getInstance()); // backward compatibility - binding.setProperty("jenkins", Jenkins.getInstance()); + binding.setProperty("hudson", Jenkins.getActiveInstance()); // backward compatibility + binding.setProperty("jenkins", Jenkins.getActiveInstance()); IO io = new IO(new BufferedInputStream(stdin),stdout,stderr); - final ClassLoader cl = Jenkins.getInstance().pluginManager.uberClassLoader; + final ClassLoader cl = Jenkins.getActiveInstance().pluginManager.uberClassLoader; Closure registrar = new Closure(null, null) { private static final long serialVersionUID = 1L; @SuppressWarnings("unused") - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS",justification="Closure invokes this via reflection") + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value="UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS",justification="Closure invokes this via reflection") public Object doCall(Object[] args) { assert(args.length == 1); assert(args[0] instanceof Shell); @@ -101,7 +109,7 @@ public class GroovyshCommand extends CLICommand { } }; Groovysh shell = new Groovysh(cl, binding, io, registrar); - shell.getImports().add("import hudson.model.*"); + shell.getImports().add("hudson.model.*"); // defaultErrorHook doesn't re-throw IOException, so ShellRunner in // Groovysh will keep looping forever if we don't terminate when the @@ -111,7 +119,7 @@ public class GroovyshCommand extends CLICommand { private static final long serialVersionUID = 1L; @SuppressWarnings("unused") - @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS",justification="Closure invokes this via reflection") + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value="UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS",justification="Closure invokes this via reflection") public Object doCall(Object[] args) throws ChannelClosedException { if (args.length == 1 && args[0] instanceof ChannelClosedException) { throw (ChannelClosedException)args[0]; diff --git a/core/src/main/java/hudson/cli/HelpCommand.java b/core/src/main/java/hudson/cli/HelpCommand.java index bebb39dfcd9ce8aff1f1fb1a42c685e9ce941899..295e6e0e8e966f9e724d4eda231dff37b1e0952f 100644 --- a/core/src/main/java/hudson/cli/HelpCommand.java +++ b/core/src/main/java/hudson/cli/HelpCommand.java @@ -23,12 +23,14 @@ */ package hudson.cli; +import hudson.AbortException; import hudson.Extension; import jenkins.model.Jenkins; import java.util.Map; import java.util.TreeMap; +import org.acegisecurity.AccessDeniedException; import org.kohsuke.args4j.Argument; /** @@ -48,11 +50,10 @@ public class HelpCommand extends CLICommand { } @Override - protected int run() { - if (!Jenkins.getInstance().hasPermission(Jenkins.READ)) { - stderr.println("You must authenticate to access this Jenkins.\n" + protected int run() throws Exception { + if (!Jenkins.getActiveInstance().hasPermission(Jenkins.READ)) { + throw new AccessDeniedException("You must authenticate to access this Jenkins.\n" + "Use --username/--password/--password-file parameters or login command."); - return -1; } if (command != null) @@ -76,12 +77,11 @@ public class HelpCommand extends CLICommand { return 0; } - private int showCommandDetails() { + private int showCommandDetails() throws Exception { CLICommand command = CLICommand.clone(this.command); if (command == null) { - stderr.format("No such command %s. Awailable commands are: ", this.command); showAllCommands(); - return -1; + throw new AbortException(String.format("No such command %s. Available commands are above. ", this.command)); } command.printUsage(stderr, command.getCmdLineParser()); diff --git a/core/src/main/java/hudson/cli/InstallPluginCommand.java b/core/src/main/java/hudson/cli/InstallPluginCommand.java index 1fd23d81acba7de5c3a4050e4925c96b797934b9..21484e05bfe4333e77483f907903506ae7a05217 100644 --- a/core/src/main/java/hudson/cli/InstallPluginCommand.java +++ b/core/src/main/java/hudson/cli/InstallPluginCommand.java @@ -23,6 +23,7 @@ */ package hudson.cli; +import hudson.AbortException; import hudson.Extension; import hudson.FilePath; import hudson.PluginManager; @@ -57,20 +58,20 @@ public class InstallPluginCommand extends CLICommand { @Argument(metaVar="SOURCE",required=true,usage="If this points to a local file, that file will be installed. " + "If this is an URL, Jenkins downloads the URL and installs that as a plugin." + "Otherwise the name is assumed to be the short name of the plugin in the existing update center (like \"findbugs\")," + - "and the plugin will be installed from the update center") + "and the plugin will be installed from the update center.") public List sources = new ArrayList(); - @Option(name="-name",usage="If specified, the plugin will be installed as this short name (whereas normally the name is inferred from the source name automatically.)") + @Option(name="-name",usage="If specified, the plugin will be installed as this short name (whereas normally the name is inferred from the source name automatically).") public String name; - @Option(name="-restart",usage="Restart Jenkins upon successful installation") + @Option(name="-restart",usage="Restart Jenkins upon successful installation.") public boolean restart; @Option(name="-deploy",usage="Deploy plugins right away without postponing them until the reboot.") public boolean dynamicLoad; protected int run() throws Exception { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); h.checkPermission(PluginManager.UPLOAD_PLUGINS); PluginManager pm = h.getPluginManager(); @@ -113,8 +114,11 @@ public class InstallPluginCommand extends CLICommand { if (p!=null) { stdout.println(Messages.InstallPluginCommand_InstallingFromUpdateCenter(source)); Throwable e = p.deploy(dynamicLoad).get().getError(); - if (e!=null) - throw new IOException("Failed to install plugin "+source,e); + if (e!=null) { + AbortException myException = new AbortException("Failed to install plugin " + source); + myException.initCause(e); + throw myException; + } continue; } @@ -137,7 +141,7 @@ public class InstallPluginCommand extends CLICommand { } } - return 1; + throw new AbortException("Error occurred, see previous output."); } if (restart) @@ -150,6 +154,6 @@ public class InstallPluginCommand extends CLICommand { } private File getTargetFile() { - return new File(Jenkins.getInstance().getPluginManager().rootDir,name+".jpi"); + return new File(Jenkins.getActiveInstance().getPluginManager().rootDir,name+".jpi"); } } diff --git a/core/src/main/java/hudson/cli/InstallToolCommand.java b/core/src/main/java/hudson/cli/InstallToolCommand.java index 7e0c37ac281beccff8a57a7db2c63dfaa5c6ab24..c387241f5a9066aadba2166f9faa4c23f6f8efd5 100644 --- a/core/src/main/java/hudson/cli/InstallToolCommand.java +++ b/core/src/main/java/hudson/cli/InstallToolCommand.java @@ -62,18 +62,18 @@ public class InstallToolCommand extends CLICommand { } protected int run() throws Exception { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); h.checkPermission(Jenkins.READ); // where is this build running? BuildIDs id = checkChannel().call(new BuildIDs()); if (!id.isComplete()) - throw new AbortException("This command can be only invoked from a build executing inside Hudson"); + throw new IllegalStateException("This command can be only invoked from a build executing inside Hudson"); - AbstractProject p = Jenkins.getInstance().getItemByFullName(id.job, AbstractProject.class); + AbstractProject p = h.getItemByFullName(id.job, AbstractProject.class); if (p==null) - throw new AbortException("No such job found: "+id.job); + throw new IllegalStateException("No such job found: "+id.job); p.checkPermission(Item.CONFIGURE); List toolTypes = new ArrayList(); @@ -101,9 +101,9 @@ public class InstallToolCommand extends CLICommand { private int error(List candidates, String given, String noun) throws AbortException { if (given ==null) - throw new AbortException("No tool "+ noun +" was specified. Valid values are "+candidates.toString()); + throw new IllegalArgumentException("No tool "+ noun +" was specified. Valid values are "+candidates.toString()); else - throw new AbortException("Unrecognized tool "+noun+". Perhaps you meant '"+ EditDistance.findNearest(given,candidates)+"'?"); + throw new IllegalArgumentException("Unrecognized tool "+noun+". Perhaps you meant '"+ EditDistance.findNearest(given,candidates)+"'?"); } /** @@ -113,15 +113,15 @@ public class InstallToolCommand extends CLICommand { Run b = p.getBuildByNumber(Integer.parseInt(id.number)); if (b==null) - throw new AbortException("No such build: "+id.number); + throw new IllegalStateException("No such build: "+id.number); Executor exec = b.getExecutor(); if (exec==null) - throw new AbortException(b.getFullDisplayName()+" is not building"); + throw new IllegalStateException(b.getFullDisplayName()+" is not building"); Node node = exec.getOwner().getNode(); if (node == null) { - throw new AbortException("The node " + exec.getOwner().getDisplayName() + " has been deleted"); + throw new IllegalStateException("The node " + exec.getOwner().getDisplayName() + " has been deleted"); } t = t.translate(node, EnvVars.getRemote(checkChannel()), new StreamTaskListener(stderr)); diff --git a/core/src/main/java/hudson/cli/ListJobsCommand.java b/core/src/main/java/hudson/cli/ListJobsCommand.java index 97ea8d29671f992d942a72639dc604c99f654d2e..45b9661e283768f21de570287777570bf4a294d6 100644 --- a/core/src/main/java/hudson/cli/ListJobsCommand.java +++ b/core/src/main/java/hudson/cli/ListJobsCommand.java @@ -50,7 +50,7 @@ public class ListJobsCommand extends CLICommand { public String name; protected int run() throws Exception { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); final Collection jobs; // If name is given retrieve jobs for the given view. @@ -70,8 +70,7 @@ public class ListJobsCommand extends CLICommand { } // No view and no item group with the given name found. else { - stderr.println("No view or item group with the given name found"); - return -1; + throw new IllegalArgumentException("No view or item group with the given name '" + name + "' found."); } } } diff --git a/core/src/main/java/hudson/cli/ListPluginsCommand.java b/core/src/main/java/hudson/cli/ListPluginsCommand.java index f21ea7e70152271f30f03398363472de2b1f0bf4..99c926cdaf1ef8c648ff1a339b6fdf61314497f2 100644 --- a/core/src/main/java/hudson/cli/ListPluginsCommand.java +++ b/core/src/main/java/hudson/cli/ListPluginsCommand.java @@ -47,7 +47,7 @@ public class ListPluginsCommand extends CLICommand { public String name; protected int run() { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getActiveInstance(); PluginManager pluginManager = h.getPluginManager(); if (this.name != null) { @@ -57,7 +57,7 @@ public class ListPluginsCommand extends CLICommand { printPlugin(plugin, plugin.getShortName().length(), plugin.getDisplayName().length()); } else { - stderr.println(String.format("No plugin with the name '%s' found", this.name)); + throw new IllegalArgumentException("No plugin with the name '" + name + "' found"); } } else { diff --git a/core/src/main/java/hudson/cli/OfflineNodeCommand.java b/core/src/main/java/hudson/cli/OfflineNodeCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..e003a633b28ce80895a5257e74973918c7ee9a2b --- /dev/null +++ b/core/src/main/java/hudson/cli/OfflineNodeCommand.java @@ -0,0 +1,96 @@ +/* + * The MIT License + * + * Copyright 2016 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.Computer; +import hudson.model.ComputerSet; +import hudson.util.EditDistance; +import jenkins.model.Jenkins; + +import org.kohsuke.args4j.Argument; +import org.kohsuke.args4j.Option; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +/** + * CLI Command, which puts the Jenkins node offline. + * @author pjanouse + * @since 2.15 + */ +@Extension +public class OfflineNodeCommand extends CLICommand { + + @Argument(metaVar = "NAME", usage = "Agent name, or empty string for master", required = true, multiValued = true) + private List nodes; + + @Option(name = "-m", usage = "Record the reason about why you are disconnecting this node") + public String cause; + + @Override + public String getShortDescription() { + return Messages.OfflineNodeCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getInstance(); + final HashSet hs = new HashSet(nodes); + List names = null; + + for (String node_s : hs) { + try { + Computer computer = jenkins.getComputer(node_s); + if (computer == null) { + if (names == null) { + names = ComputerSet.getComputerNames(); + } + String adv = EditDistance.findNearest(node_s, names); + throw new IllegalArgumentException(adv == null ? + hudson.model.Messages.Computer_NoSuchSlaveExistsWithoutAdvice(node_s) : + hudson.model.Messages.Computer_NoSuchSlaveExists(node_s, adv)); + } + computer.cliOffline(cause); + } catch (Exception e) { + if (hs.size() == 1) { + throw e; + } + + stderr.println(node_s + ": " + e.getMessage()); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/OnlineNodeCommand.java b/core/src/main/java/hudson/cli/OnlineNodeCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..5cb190fcd8ccf6bdb2c7f4e3e4c7e55888ad6505 --- /dev/null +++ b/core/src/main/java/hudson/cli/OnlineNodeCommand.java @@ -0,0 +1,94 @@ +/* + * The MIT License + * + * Copyright 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.Computer; +import hudson.model.ComputerSet; +import hudson.util.EditDistance; +import jenkins.model.Jenkins; + +import org.kohsuke.args4j.Argument; + +import java.util.HashSet; +import java.util.List; + +/** + * CLI Command, which moves the node to the online state. + * @author pjanouse + * @since 1.642 + */ +@Extension +public class OnlineNodeCommand extends CLICommand { + + @Argument(metaVar = "NAME", usage = "Agent name, or empty string for master", required = true, multiValued = true) + private List nodes; + + @Override + public String getShortDescription() { + return Messages.OnlineNodeCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getActiveInstance(); + final HashSet hs = new HashSet(nodes); + List names = null; + + for (String node_s : hs) { + Computer computer = null; + + try { + computer = jenkins.getComputer(node_s); + if (computer == null) { + if (names == null) { + names = ComputerSet.getComputerNames(); + } + String adv = EditDistance.findNearest(node_s, names); + throw new IllegalArgumentException(adv == null ? + hudson.model.Messages.Computer_NoSuchSlaveExistsWithoutAdvice(node_s) : + hudson.model.Messages.Computer_NoSuchSlaveExists(node_s, adv)); + } + computer.cliOnline(); + } catch (Exception e) { + if (hs.size() == 1) { + throw e; + } + + final String errorMsg = node_s + ": " + e.getMessage(); + stderr.println(errorMsg); + errorOccurred = true; + continue; + } + } + + if (errorOccurred){ + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} diff --git a/test/src/main/java/org/jvnet/hudson/test/TestNotifier.java b/core/src/main/java/hudson/cli/QuietDownCommand.java similarity index 55% rename from test/src/main/java/org/jvnet/hudson/test/TestNotifier.java rename to core/src/main/java/hudson/cli/QuietDownCommand.java index 7e138ee2a696c17e01535c8d934537cf7cd42146..4d84055c8de21667dac56c35ef6397cb253e7574 100644 --- a/test/src/main/java/org/jvnet/hudson/test/TestNotifier.java +++ b/core/src/main/java/hudson/cli/QuietDownCommand.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2016 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,37 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Notifier; -import hudson.tasks.Publisher; -import hudson.model.AbstractProject; +package hudson.cli; + +import hudson.Extension; +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Option; + +import java.util.logging.Logger; /** - * Partial {@link Notifier} implementation to facilitate notifier implementation for testing. + * Quiet down Jenkins - preparation for a restart + * + * @author pjanouse + * @since 2.14 */ -public abstract class TestNotifier extends Notifier { +@Extension +public class QuietDownCommand extends CLICommand { + + private static final Logger LOGGER = Logger.getLogger(QuietDownCommand.class.getName()); + + @Option(name="-block",usage="Block until the system really quiets down and no builds are running") + public boolean block = false; + + @Option(name="-timeout",usage="If non-zero, only block up to the specified number of milliseconds") + public int timeout = 0; @Override - public BuildStepDescriptor getDescriptor() { - return new BuildStepDescriptor() { - @Override - public boolean isApplicable(Class jobType) { - return true; - } - - @Override - public String getDisplayName() { - return "Bogus"; - } - }; + public String getShortDescription() { + return Messages.QuietDownCommand_ShortDescription(); } - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; + @Override + protected int run() throws Exception { + Jenkins.getActiveInstance().doQuietDown(block, timeout); + return 0; } - - private Object writeReplace() { return new Object(); } } diff --git a/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..25199ec5bed80421701fdbb9bb94537563b754a8 --- /dev/null +++ b/core/src/main/java/hudson/cli/ReloadConfigurationCommand.java @@ -0,0 +1,50 @@ +/* + * The MIT License + * + * Copyright (c) 2016 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package hudson.cli; + +import hudson.Extension; +import jenkins.model.Jenkins; + +/** + * Reload everything from the file system. + * + * @author pjanouse + * @since 2.4 + */ +@Extension +public class ReloadConfigurationCommand extends CLICommand { + + @Override + public String getShortDescription() { + return Messages.ReloadConfigurationCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + Jenkins.getActiveInstance().doReload(); + return 0; + } + +} diff --git a/core/src/main/java/hudson/cli/ReloadJobCommand.java b/core/src/main/java/hudson/cli/ReloadJobCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..17b0379f731bee1c311c435789cfb9a2bb08e94d --- /dev/null +++ b/core/src/main/java/hudson/cli/ReloadJobCommand.java @@ -0,0 +1,108 @@ +/* + * The MIT License + * + * Copyright (c) 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.AbortException; +import hudson.Extension; +import hudson.model.AbstractItem; +import hudson.model.AbstractProject; +import hudson.model.Item; + +import jenkins.model.Jenkins; +import org.kohsuke.args4j.Argument; + +import java.util.HashSet; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Reloads job from the disk. + * @author pjanouse + * @since 1.633 + */ +@Extension +public class ReloadJobCommand extends CLICommand { + + @Argument(usage="Name of the job(s) to reload", required=true, multiValued=true) + private List jobs; + + private static final Logger LOGGER = Logger.getLogger(ReloadJobCommand.class.getName()); + + @Override + public String getShortDescription() { + + return Messages.ReloadJobCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + + boolean errorOccurred = false; + final Jenkins jenkins = Jenkins.getActiveInstance(); + + final HashSet hs = new HashSet(); + hs.addAll(jobs); + + for (String job_s: hs) { + AbstractItem job = null; + + try { + // TODO: JENKINS-30786 + Item item = jenkins.getItemByFullName(job_s); + if (item instanceof AbstractItem) { + job = (AbstractItem) item; + } else if (item != null) { + LOGGER.log(Level.WARNING, "Unsupported item type: {0}", item.getClass().getName()); + } + + if(job == null) { + // TODO: JENKINS-30785 + AbstractProject project = AbstractProject.findNearest(job_s); + throw new IllegalArgumentException(project == null ? + "No such job \u2018" + job_s + "\u2019 exists." : + String.format("No such job \u2018%s\u2019 exists. Perhaps you meant \u2018%s\u2019?", + job_s, project.getFullName())); + } + + job.checkPermission(AbstractItem.CONFIGURE); + job.doReload(); + } catch (Exception e) { + if(hs.size() == 1) { + throw e; + } + + final String errorMsg = String.format(job_s + ": " + e.getMessage()); + stderr.println(errorMsg); + errorOccurred = true; + continue; + } + } + + if (errorOccurred) { + throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT); + } + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java b/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java index 8c317d908f97bccfe39c14f8434a2167e1814249..786f33d21e1ee5fc1cb0d68cec7bcb8605816d40 100644 --- a/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java +++ b/core/src/main/java/hudson/cli/RemoveJobFromViewCommand.java @@ -55,9 +55,8 @@ public class RemoveJobFromViewCommand extends CLICommand { protected int run() throws Exception { view.checkPermission(View.CONFIGURE); - if (!(view instanceof DirectlyModifiableView)) throw new CmdLineException( - null, "'" + view.getDisplayName() + "' view can not be modified directly" - ); + if (!(view instanceof DirectlyModifiableView)) + throw new IllegalStateException("'" + view.getDisplayName() + "' view can not be modified directly"); for (TopLevelItem job: jobs) { ((DirectlyModifiableView) view).remove(job); diff --git a/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java b/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java index 0aeedb4a37303b7875d1b5178181d79eccabc96c..1863e5a22ef86cd71f5f892fc231ccd18cfc0d5e 100644 --- a/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java +++ b/core/src/main/java/hudson/cli/SetBuildDescriptionCommand.java @@ -3,9 +3,7 @@ package hudson.cli; import hudson.Extension; import hudson.model.AbstractProject; import hudson.model.Run; -import hudson.remoting.Callable; -import java.io.IOException; import java.io.Serializable; import org.apache.commons.io.IOUtils; @@ -30,6 +28,9 @@ public class SetBuildDescriptionCommand extends CLICommand implements Serializab protected int run() throws Exception { Run run = job.getBuildByNumber(number); + if (run == null) + throw new IllegalArgumentException("No such build #"+number); + run.checkPermission(Run.UPDATE); if ("=".equals(description)) { diff --git a/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java b/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java index 08b08b7d7166b510e545d598cfddbad85c299ad7..f52dc58a57f7785257d19a75617f8fc33f3c1122 100644 --- a/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java +++ b/core/src/main/java/hudson/cli/SetBuildDisplayNameCommand.java @@ -30,8 +30,7 @@ public class SetBuildDisplayNameCommand extends CLICommand implements Serializab protected int run() throws Exception { Run run = job.getBuildByNumber(number); if (run == null) { - stderr.format("Build #%d does not exist\n", number); - return -1; + throw new IllegalArgumentException("Build #" + number + " does not exist"); } run.checkPermission(Run.UPDATE); diff --git a/core/src/main/java/hudson/cli/SetBuildResultCommand.java b/core/src/main/java/hudson/cli/SetBuildResultCommand.java index 7666d590a5f7147f33b08f7b15b4a08235e3800a..82756472c7b3ac09f7b6276e472512d4ad8df314 100644 --- a/core/src/main/java/hudson/cli/SetBuildResultCommand.java +++ b/core/src/main/java/hudson/cli/SetBuildResultCommand.java @@ -25,7 +25,6 @@ package hudson.cli; import hudson.Extension; -import hudson.model.Item; import hudson.model.Result; import hudson.model.Run; import org.kohsuke.args4j.Argument; diff --git a/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java b/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..319e4424a9e44b8b95d1b00b19403f0a805dc994 --- /dev/null +++ b/core/src/main/java/hudson/cli/WaitNodeOfflineCommand.java @@ -0,0 +1,51 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.Extension; +import hudson.model.Node; +import org.kohsuke.args4j.Argument; + +/** + * CLI command, which waits till the node switches to the offline state. + * @author pjanouse + * @since 2.16 + */ +@Extension +public class WaitNodeOfflineCommand extends CLICommand { + + @Argument(metaVar="NODE", usage="Name of the node", required=true) + public Node node; + + @Override + public String getShortDescription() { + return Messages.WaitNodeOfflineCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + node.toComputer().waitUntilOffline(); + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java b/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..2e9713ad6f4cd4e6034ca11f8e1ae9748d1315cf --- /dev/null +++ b/core/src/main/java/hudson/cli/WaitNodeOnlineCommand.java @@ -0,0 +1,51 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.cli; + +import hudson.Extension; +import hudson.model.Node; +import org.kohsuke.args4j.Argument; + +/** + * CLI command, which waits till the node switches to the online state. + * @author pjanouse + * @since 2.16 + */ +@Extension +public class WaitNodeOnlineCommand extends CLICommand { + + @Argument(metaVar="NODE", usage="Name of the node", required=true) + public Node node; + + @Override + public String getShortDescription() { + return Messages.WaitNodeOnlineCommand_ShortDescription(); + } + + @Override + protected int run() throws Exception { + node.toComputer().waitUntilOnline(); + return 0; + } +} diff --git a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java index fe7ed1f690b8fa4aa486a2cc0ae9cd689fa91ac4..e063bb08cdd2996b08e0fa24e519ca051c093ca2 100644 --- a/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java +++ b/core/src/main/java/hudson/cli/declarative/CLIRegisterer.java @@ -23,6 +23,7 @@ */ package hudson.cli.declarative; +import hudson.AbortException; import hudson.Extension; import hudson.ExtensionComponent; import hudson.ExtensionFinder; @@ -33,9 +34,10 @@ import hudson.model.Hudson; import jenkins.ExtensionComponentSet; import jenkins.ExtensionRefreshException; import jenkins.model.Jenkins; -import hudson.remoting.Channel; import hudson.security.CliAuthenticator; +import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; +import org.acegisecurity.BadCredentialsException; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.jvnet.hudson.annotation_indexer.Index; @@ -57,6 +59,9 @@ import java.util.List; import java.util.Locale; import java.util.Stack; import static java.util.logging.Level.SEVERE; + +import java.util.UUID; +import java.util.logging.Level; import java.util.logging.Logger; /** @@ -152,6 +157,40 @@ public class CLIRegisterer extends ExtensionFinder { return parser; } + /** + * Envelope an annotated CLI command + * + * @param args + * Arguments to the sub command. For example, if the CLI is invoked like "java -jar cli.jar foo bar zot", + * then "foo" is the sub-command and the argument list is ["bar","zot"]. + * @param locale + * Locale of the client (which can be different from that of the server.) Good behaving command implementation + * would use this locale for formatting messages. + * @param stdin + * Connected to the stdin of the CLI client. + * @param stdout + * Connected to the stdout of the CLI client. + * @param stderr + * Connected to the stderr of the CLI client. + * @return + * Exit code from the CLI command execution + * + *

+ * Jenkins standard exit codes from CLI: + * 0 means everything went well. + * 1 means further unspecified exception is thrown while performing the command. + * 2 means CmdLineException is thrown while performing the command. + * 3 means IllegalArgumentException is thrown while performing the command. + * 4 mean IllegalStateException is thrown while performing the command. + * 5 means AbortException is thrown while performing the command. + * 6 means AccessDeniedException is thrown while performing the command. + * 7 means BadCredentialsException is thrown while performing the command. + * 8-15 are reserved for future usage + * 16+ mean a custom CLI exit error code (meaning defined by the CLI command itself) + * + *

+ * Note: For details - see JENKINS-32273 + */ @Override public int main(List args, Locale locale, InputStream stdin, PrintStream stdout, PrintStream stderr) { this.stdout = stdout; @@ -167,13 +206,13 @@ public class CLIRegisterer extends ExtensionFinder { try { // authentication CliAuthenticator authenticator = Jenkins.getInstance().getSecurityRealm().createCliAuthenticator(this); - new ClassParser().parse(authenticator,parser); + new ClassParser().parse(authenticator, parser); // fill up all the binders parser.parseArgument(args); Authentication auth = authenticator.authenticate(); - if (auth== Jenkins.ANONYMOUS) + if (auth == Jenkins.ANONYMOUS) auth = loadStoredAuthentication(); sc.setAuthentication(auth); // run the CLI with the right credential hudson.checkPermission(Jenkins.READ); @@ -196,10 +235,40 @@ public class CLIRegisterer extends ExtensionFinder { sc.setAuthentication(old); // restore } } catch (CmdLineException e) { - stderr.println(e.getMessage()); - printUsage(stderr,parser); - return 1; - } catch (Exception e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + printUsage(stderr, parser); + return 2; + } catch (IllegalStateException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 4; + } catch (IllegalArgumentException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 3; + } catch (AbortException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 5; + } catch (AccessDeniedException e) { + stderr.println(""); + stderr.println("ERROR: " + e.getMessage()); + return 6; + } catch (BadCredentialsException e) { + // to the caller, we can't reveal whether the user didn't exist or the password didn't match. + // do that to the server log instead + String id = UUID.randomUUID().toString(); + LOGGER.log(Level.INFO, "CLI login attempt failed: " + id, e); + stderr.println(""); + stderr.println("ERROR: Bad Credentials. Search the server log for " + id + " for more details."); + return 7; + } catch (Throwable e) { + final String errorMsg = String.format("Unexpected exception occurred while performing %s command.", + getName()); + stderr.println(""); + stderr.println("ERROR: " + errorMsg); + LOGGER.log(Level.WARNING, errorMsg, e); e.printStackTrace(stderr); return 1; } @@ -214,7 +283,7 @@ public class CLIRegisterer extends ExtensionFinder { } } } catch (IOException e) { - LOGGER.log(SEVERE, "Failed to discvoer @CLIMethod",e); + LOGGER.log(SEVERE, "Failed to discover @CLIMethod",e); } return r; diff --git a/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java b/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java index e27bb32dc8709b8972c64cd7db80b24b0c61634f..6cd1d86eba57141695824a9ec52c22a8cad074f7 100644 --- a/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/GenericItemOptionHandler.java @@ -27,6 +27,7 @@ package hudson.cli.handlers; import hudson.model.Item; import hudson.model.Items; import hudson.security.ACL; +import hudson.security.ACLContext; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; @@ -61,21 +62,19 @@ public abstract class GenericItemOptionHandler extends OptionHan T s = j.getItemByFullName(src, type()); if (s == null) { final Authentication who = Jenkins.getAuthentication(); - ACL.impersonate(ACL.SYSTEM, new Runnable() { - @Override public void run() { - Item actual = j.getItemByFullName(src); - if (actual == null) { - LOGGER.log(Level.FINE, "really no item exists named {0}", src); - } else { - LOGGER.log(Level.WARNING, "running as {0} could not find {1} of {2}", new Object[] {who.getPrincipal(), actual, type()}); - } + try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + Item actual = j.getItemByFullName(src); + if (actual == null) { + LOGGER.log(Level.FINE, "really no item exists named {0}", src); + } else { + LOGGER.log(Level.WARNING, "running as {0} could not find {1} of {2}", new Object[] {who.getPrincipal(), actual, type()}); } - }); + } T nearest = Items.findNearest(type(), src, j); if (nearest != null) { - throw new CmdLineException(owner, "No such job '" + src + "'; perhaps you meant '" + nearest.getFullName() + "'?"); + throw new IllegalArgumentException("No such job '" + src + "'; perhaps you meant '" + nearest.getFullName() + "'?"); } else { - throw new CmdLineException(owner, "No such job '" + src + "'"); + throw new IllegalArgumentException("No such job '" + src + "'"); } } setter.addValue(s); diff --git a/test/src/main/java/org/jvnet/hudson/test/junit/FailedTest.java b/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java similarity index 64% rename from test/src/main/java/org/jvnet/hudson/test/junit/FailedTest.java rename to core/src/main/java/hudson/cli/handlers/JobOptionHandler.java index 364364ef8da606999f250326dfd0ccdea50dcd07..c0326fbacc9ae2a3a9003cd8cd4ef2d94b7873d4 100644 --- a/test/src/main/java/org/jvnet/hudson/test/junit/FailedTest.java +++ b/core/src/main/java/hudson/cli/handlers/JobOptionHandler.java @@ -21,34 +21,33 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test.junit; +package hudson.cli.handlers; -import junit.framework.TestCase; +import hudson.model.Job; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.Setter; +import org.kohsuke.MetaInfServices; +import org.kohsuke.args4j.spi.OptionHandler; /** - * {@link TestCase} implementation that has already failed. - * Used to represent a problem happened during a test suite construction. + * Refer to {@link Job} by its name. * * @author Kohsuke Kawaguchi */ -public class FailedTest extends TestCase { - /** - * The failure. If null, the test will succeed, despite the class name. - */ - private final Throwable problem; - - public FailedTest(String name, Throwable problem) { - super(name); - this.problem = problem; +@MetaInfServices(OptionHandler.class) +@SuppressWarnings("rawtypes") +public class JobOptionHandler extends GenericItemOptionHandler { + public JobOptionHandler(CmdLineParser parser, OptionDef option, Setter setter) { + super(parser, option, setter); } - public FailedTest(Class name, Throwable problem) { - this(name.getName(),problem); + @Override protected Class type() { + return Job.class; } @Override - protected void runTest() throws Throwable { - if (problem!=null) - throw problem; + public String getDefaultMetaVariable() { + return "JOB"; } } diff --git a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java index 516f1e6ed411c19f3741cbec69cda42a602c9bc6..90905d5348968191b2d75e61ceeb01b3ca670b5f 100644 --- a/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/NodeOptionHandler.java @@ -54,7 +54,7 @@ public class NodeOptionHandler extends OptionHandler { String nodeName = params.getParameter(0); final Node node = Jenkins.getInstance().getNode(nodeName); - if (node == null) throw new CmdLineException(owner, "No such node '" + nodeName + "'"); + if (node == null) throw new IllegalArgumentException("No such node '" + nodeName + "'"); setter.addValue(node); return 1; diff --git a/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java b/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java index 387621ae56b570e70731cbf7f6a6f6a98e755d41..f578a8620b014b74aea50ba3d401f2521251c826 100644 --- a/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java +++ b/core/src/main/java/hudson/cli/handlers/ViewOptionHandler.java @@ -30,6 +30,7 @@ import java.util.StringTokenizer; import jenkins.model.Jenkins; +import org.acegisecurity.AccessDeniedException; import org.kohsuke.MetaInfServices; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; @@ -38,6 +39,8 @@ import org.kohsuke.args4j.spi.OptionHandler; import org.kohsuke.args4j.spi.Parameters; import org.kohsuke.args4j.spi.Setter; +import javax.annotation.CheckForNull; + /** * Refers to {@link View} by its name. * @@ -73,10 +76,26 @@ public class ViewOptionHandler extends OptionHandler { return 1; } - private View getView(String name) throws CmdLineException { - + /** + * + * Gets a view by its name + * Note: Personal user's views aren't supported now. + * + * @param name A view name + * @return The {@link View} instance. Null if name is empty string + * @throws IllegalArgumentException + * If the view isn't found + * @throws IllegalStateException + * If cannot get active Jenkins instance or view can't contain a views + * @throws AccessDeniedException + * If user doens't have a READ permission for the view + * @since 1.618 + */ + @CheckForNull + public View getView(final String name) { + + ViewGroup group = Jenkins.getActiveInstance(); View view = null; - ViewGroup group = Jenkins.getInstance(); final StringTokenizer tok = new StringTokenizer(name, "/"); while(tok.hasMoreTokens()) { @@ -84,19 +103,17 @@ public class ViewOptionHandler extends OptionHandler { String viewName = tok.nextToken(); view = group.getView(viewName); - if (view == null) throw new CmdLineException(owner, String.format( - "No view named %s inside view %s", - viewName, group.getDisplayName() - )); + if (view == null) + throw new IllegalArgumentException(String.format( + "No view named %s inside view %s", + viewName, group.getDisplayName() + )); view.checkPermission(View.READ); - if (view instanceof ViewGroup) { group = (ViewGroup) view; } else if (tok.hasMoreTokens()) { - throw new CmdLineException( - owner, view.getViewName() + " view can not contain views" - ); + throw new IllegalStateException(view.getViewName() + " view can not contain views"); } } diff --git a/core/src/main/java/hudson/cli/util/ScriptLoader.java b/core/src/main/java/hudson/cli/util/ScriptLoader.java index e2252efbd5f78f9670bd272e6fa130180e78b3ce..8484c1e95926e09ecb20876dda6d5a3bdf0962c9 100644 --- a/core/src/main/java/hudson/cli/util/ScriptLoader.java +++ b/core/src/main/java/hudson/cli/util/ScriptLoader.java @@ -35,11 +35,8 @@ public class ScriptLoader extends MasterToSlaveCallable { } catch (MalformedURLException e) { throw new AbortException("Unable to find a script "+script); } - InputStream s = url.openStream(); - try { + try (InputStream s = url.openStream()) { return IOUtils.toString(s); - } finally { - s.close(); } } } diff --git a/core/src/main/java/hudson/console/AnnotatedLargeText.java b/core/src/main/java/hudson/console/AnnotatedLargeText.java index 89e307bf22df8a46ad4e97dc0acc09bda283eedf..4e8c40658af523124c83815290ea0efaa8d2f43d 100644 --- a/core/src/main/java/hudson/console/AnnotatedLargeText.java +++ b/core/src/main/java/hudson/console/AnnotatedLargeText.java @@ -147,7 +147,7 @@ public class AnnotatedLargeText extends LargeText { /** * Strips annotations using a {@link PlainTextConsoleOutputStream}. - * @inheritDoc + * {@inheritDoc} */ @Override public long writeLogTo(long start, OutputStream out) throws IOException { @@ -156,7 +156,6 @@ public class AnnotatedLargeText extends LargeText { /** * Calls {@link LargeText#writeLogTo(long, OutputStream)} without stripping annotations as {@link #writeLogTo(long, OutputStream)} would. - * @inheritDoc * @since 1.577 */ public long writeRawLogTo(long start, OutputStream out) throws IOException { diff --git a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java index b4e260b6af257a5f16fb62611253ce7c0ce7ec31..d5ac5081364fe5f7220d2435f65940aa2b436c2e 100644 --- a/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java +++ b/core/src/main/java/hudson/console/ConsoleAnnotationDescriptor.java @@ -55,7 +55,10 @@ public abstract class ConsoleAnnotationDescriptor extends Descriptor + * Even though this method is not marked 'abstract', this is the method that must be overridden + * by extensions. + */ + public OutputStream decorateLogger(Run build, OutputStream logger) throws IOException, InterruptedException { + // this implementation is backward compatibility thunk in case subtypes only override the + // old signature (AbstractBuild,OutputStream) + + if (build instanceof AbstractBuild) { + // maybe the plugin implements the old signature. + return decorateLogger((AbstractBuild) build, logger); + } else { + // this ConsoleLogFilter can only decorate AbstractBuild, so just pass through + return logger; + } + } + + /** + * Called to decorate logger for master/agent communication. + * + * @param computer + * Agent computer for which the logger is getting decorated. Useful to do + * contextual decoration. + * @since 1.632 + */ + public OutputStream decorateLogger(@Nonnull Computer computer, OutputStream logger) throws IOException, InterruptedException { + return logger; // by default no-op + } /** * All the registered {@link ConsoleLogFilter}s. diff --git a/core/src/main/java/hudson/console/ConsoleNote.java b/core/src/main/java/hudson/console/ConsoleNote.java index c27fec63643527d8b9f775f6e1c6b6a739a47f62..7ef15fee9347c57de400627578a232a5abd512c5 100644 --- a/core/src/main/java/hudson/console/ConsoleNote.java +++ b/core/src/main/java/hudson/console/ConsoleNote.java @@ -170,11 +170,8 @@ public abstract class ConsoleNote implements Serializable, Describable implements Serializable, Describable { return "http://stacktrace.jenkins-ci.org/search?query="+className; } - @Extension + @Extension @Symbol("stackTrace") public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/console/HyperlinkNote.java b/core/src/main/java/hudson/console/HyperlinkNote.java index 7e32acddc0b7bebcc574851e6d512f8a3e128b3b..79fbbffc70ec1284d530da6b7eeec284e4b195d7 100644 --- a/core/src/main/java/hudson/console/HyperlinkNote.java +++ b/core/src/main/java/hudson/console/HyperlinkNote.java @@ -26,6 +26,7 @@ package hudson.console; import hudson.Extension; import hudson.MarkupText; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; @@ -83,7 +84,7 @@ public class HyperlinkNote extends ConsoleNote { } } - @Extension + @Extension @Symbol("hyperlink") public static class DescriptorImpl extends ConsoleAnnotationDescriptor { public String getDisplayName() { return "Hyperlinks"; diff --git a/core/src/main/java/hudson/console/ModelHyperlinkNote.java b/core/src/main/java/hudson/console/ModelHyperlinkNote.java index 5e415b58bbd100ed361e1d9a20782460fe7f9c38..784934708d62dc95389f0877fd571601d865e61c 100644 --- a/core/src/main/java/hudson/console/ModelHyperlinkNote.java +++ b/core/src/main/java/hudson/console/ModelHyperlinkNote.java @@ -3,10 +3,12 @@ package hudson.console; import hudson.Extension; import hudson.model.*; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.Nonnull; /** * {@link HyperlinkNote} that links to a {@linkplain ModelObject model object}, @@ -25,7 +27,7 @@ public class ModelHyperlinkNote extends HyperlinkNote { return " class='model-link'"; } - public static String encodeTo(User u) { + public static String encodeTo(@Nonnull User u) { return encodeTo(u,u.getDisplayName()); } @@ -64,7 +66,7 @@ public class ModelHyperlinkNote extends HyperlinkNote { } } - @Extension + @Extension @Symbol("hyperlinkToModels") public static class DescriptorImpl extends HyperlinkNote.DescriptorImpl { public String getDisplayName() { return "Hyperlinks to models"; diff --git a/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java b/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java index f1afa2fad5ad91447f5588d35edaede9defcab40..ee02d177d48c4fbd7d0aadc9e422b02aa3d02421 100644 --- a/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java +++ b/core/src/main/java/hudson/console/PlainTextConsoleOutputStream.java @@ -89,5 +89,5 @@ public class PlainTextConsoleOutputStream extends LineTransformationOutputStream } - private static final Logger LOGGER = Logger.getLogger(ConsoleAnnotationOutputStream.class.getName()); + private static final Logger LOGGER = Logger.getLogger(PlainTextConsoleOutputStream.class.getName()); } diff --git a/core/src/main/java/hudson/console/UrlAnnotator.java b/core/src/main/java/hudson/console/UrlAnnotator.java index 6adc511be96856429899371820470c1a60937853..95b7b8f4f0d9f8e4de2a0195b951cab16b9b3c58 100644 --- a/core/src/main/java/hudson/console/UrlAnnotator.java +++ b/core/src/main/java/hudson/console/UrlAnnotator.java @@ -3,6 +3,7 @@ package hudson.console; import hudson.Extension; import hudson.MarkupText; import hudson.MarkupText.SubText; +import org.jenkinsci.Symbol; import java.util.regex.Pattern; @@ -11,7 +12,7 @@ import java.util.regex.Pattern; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("url") public class UrlAnnotator extends ConsoleAnnotatorFactory { @Override public ConsoleAnnotator newInstance(Object context) { diff --git a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java index 5cf0c81ee412aca2174c44a2e878daa73ed6f4f4..4e16de8c99777110775a14af93c1af97a65d3f63 100644 --- a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java +++ b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageChecker.java @@ -26,6 +26,7 @@ package hudson.diagnosis; import hudson.Extension; import jenkins.model.Jenkins; import hudson.model.PeriodicWork; +import org.jenkinsci.Symbol; import java.util.logging.Logger; @@ -35,7 +36,7 @@ import java.util.logging.Logger; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("diskUsageCheck") public class HudsonHomeDiskUsageChecker extends PeriodicWork { public long getRecurrencePeriod() { return HOUR; diff --git a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java index bb4e8e50401e9292932cf948995d4bb21029ebcb..20cd973989e3d386bef902beace1f97334e9069c 100644 --- a/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java +++ b/core/src/main/java/hudson/diagnosis/HudsonHomeDiskUsageMonitor.java @@ -24,11 +24,11 @@ package hudson.diagnosis; import hudson.model.AdministrativeMonitor; -import jenkins.model.Jenkins; import hudson.model.AbstractModelObject; import hudson.Extension; import hudson.ExtensionPoint; import hudson.ExtensionList; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; @@ -41,7 +41,7 @@ import java.util.List; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("diskUsageCheck") public final class HudsonHomeDiskUsageMonitor extends AdministrativeMonitor { /** * Value updated by {@link HudsonHomeDiskUsageChecker}. diff --git a/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java b/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java index 947970f0877b44ced9ee6532890c7d235f44a654..23ad5140b8280a5c3388916e806a770efffe4d23 100644 --- a/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java +++ b/core/src/main/java/hudson/diagnosis/MemoryUsageMonitor.java @@ -39,6 +39,7 @@ import java.util.List; import java.util.ArrayList; import java.io.IOException; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.QueryParameter; /** @@ -46,7 +47,7 @@ import org.kohsuke.stapler.QueryParameter; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("memoryUsage") public final class MemoryUsageMonitor extends PeriodicWork { /** * A memory group is conceptually a set of memory pools. diff --git a/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java b/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java index 3182ddc9542fc8b260e0c4322d49d1438c0dc90b..8b3778262ef5650e2aa00f03e63f2fcb07c589c5 100644 --- a/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java +++ b/core/src/main/java/hudson/diagnosis/NullIdDescriptorMonitor.java @@ -29,6 +29,7 @@ import hudson.init.Initializer; import hudson.model.AdministrativeMonitor; import hudson.model.Descriptor; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import java.text.MessageFormat; import java.util.ArrayList; @@ -46,9 +47,14 @@ import static hudson.init.InitMilestone.EXTENSIONS_AUGMENTED; * @author Kohsuke Kawaguchi * @since 1.402 */ -@Extension +@Extension @Symbol("nullId") public class NullIdDescriptorMonitor extends AdministrativeMonitor { + @Override + public String getDisplayName() { + return Messages.NullIdDescriptorMonitor_DisplayName(); + } + private final List problems = new ArrayList(); @Override @@ -60,11 +66,9 @@ public class NullIdDescriptorMonitor extends AdministrativeMonitor { return Collections.unmodifiableList(problems); } - private void verify() { + @Initializer(after=EXTENSIONS_AUGMENTED) + public void verify() { Jenkins h = Jenkins.getInstance(); - if (h == null) { - return; - } for (Descriptor d : h.getExtensionList(Descriptor.class)) { PluginWrapper p = h.getPluginManager().whichPlugin(d.getClass()); String id; @@ -84,10 +88,5 @@ public class NullIdDescriptorMonitor extends AdministrativeMonitor { } } - @Initializer(after=EXTENSIONS_AUGMENTED) - public static void verifyId() { - AdministrativeMonitor.all().get(NullIdDescriptorMonitor.class).verify(); - } - private static final Logger LOGGER = Logger.getLogger(NullIdDescriptorMonitor.class.getName()); } diff --git a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java index 29a2187b93546fd61b3b1a793aabae4f1ecbef1c..90324b67ca9196e6e7b259ab34f90e7b8d649f24 100644 --- a/core/src/main/java/hudson/diagnosis/OldDataMonitor.java +++ b/core/src/main/java/hudson/diagnosis/OldDataMonitor.java @@ -36,6 +36,7 @@ import hudson.model.Saveable; import hudson.model.listeners.ItemListener; import hudson.model.listeners.RunListener; import hudson.model.listeners.SaveableListener; +import hudson.security.ACL; import hudson.util.RobustReflectionConverter; import hudson.util.VersionNumber; import java.io.IOException; @@ -46,10 +47,17 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.CheckForNull; import jenkins.model.Jenkins; +import org.acegisecurity.context.SecurityContext; +import org.acegisecurity.context.SecurityContextHolder; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; @@ -63,11 +71,11 @@ import org.kohsuke.stapler.interceptor.RequirePOST; * * @author Alan.Harder@Sun.Com */ -@Extension +@Extension @Symbol("oldData") public class OldDataMonitor extends AdministrativeMonitor { private static final Logger LOGGER = Logger.getLogger(OldDataMonitor.class.getName()); - private HashMap data = new HashMap(); + private ConcurrentMap data = new ConcurrentHashMap(); static OldDataMonitor get(Jenkins j) { return (OldDataMonitor) j.getAdministrativeMonitor("OldData"); @@ -87,12 +95,8 @@ public class OldDataMonitor extends AdministrativeMonitor { } public Map getData() { - Map _data; - synchronized (this) { - _data = new HashMap(this.data); - } Map r = new HashMap(); - for (Map.Entry entry : _data.entrySet()) { + for (Map.Entry entry : this.data.entrySet()) { Saveable s = entry.getKey().get(); if (s != null) { r.put(s, entry.getValue()); @@ -102,12 +106,18 @@ public class OldDataMonitor extends AdministrativeMonitor { } private static void remove(Saveable obj, boolean isDelete) { - OldDataMonitor odm = get(Jenkins.getInstance()); - synchronized (odm) { + Jenkins j = Jenkins.getInstance(); + OldDataMonitor odm = get(j); + SecurityContext oldContext = ACL.impersonate(ACL.SYSTEM); + try { odm.data.remove(referTo(obj)); - if (isDelete && obj instanceof Job) - for (Run r : ((Job)obj).getBuilds()) + if (isDelete && obj instanceof Job) { + for (Run r : ((Job) obj).getBuilds()) { odm.data.remove(referTo(r)); + } + } + } finally { + SecurityContextHolder.setContext(oldContext); } } @@ -146,15 +156,18 @@ public class OldDataMonitor extends AdministrativeMonitor { */ public static void report(Saveable obj, String version) { OldDataMonitor odm = get(Jenkins.getInstance()); - synchronized (odm) { - try { - SaveableReference ref = referTo(obj); + try { + SaveableReference ref = referTo(obj); + while (true) { VersionRange vr = odm.data.get(ref); - if (vr != null) vr.add(version); - else odm.data.put(ref, new VersionRange(version, null)); - } catch (IllegalArgumentException ex) { - LOGGER.log(Level.WARNING, "Bad parameter given to OldDataMonitor", ex); + if (vr != null && odm.data.replace(ref, vr, new VersionRange(vr, version, null))) { + break; + } else if (odm.data.putIfAbsent(ref, new VersionRange(null, version, null)) == null) { + break; + } } + } catch (IllegalArgumentException ex) { + LOGGER.log(Level.WARNING, "Bad parameter given to OldDataMonitor", ex); } } @@ -192,8 +205,8 @@ public class OldDataMonitor extends AdministrativeMonitor { } } if (buf.length() == 0) return; - Jenkins j = Jenkins.getInstance(); - if (j == null) { + Jenkins j = Jenkins.getInstanceOrNull(); + if (j == null) { // Need this path, at least for unit tests, but also in case of very broken startup // Startup failed, something is very broken, so report what we can. for (Throwable t : errors) { LOGGER.log(Level.WARNING, "could not read " + obj + " (and Jenkins did not start up)", t); @@ -201,32 +214,49 @@ public class OldDataMonitor extends AdministrativeMonitor { return; } OldDataMonitor odm = get(j); - synchronized (odm) { - SaveableReference ref = referTo(obj); + SaveableReference ref = referTo(obj); + while (true) { VersionRange vr = odm.data.get(ref); - if (vr != null) vr.extra = buf.toString(); - else odm.data.put(ref, new VersionRange(null, buf.toString())); + if (vr != null && odm.data.replace(ref, vr, new VersionRange(vr, null, buf.toString()))) { + break; + } else if (odm.data.putIfAbsent(ref, new VersionRange(null, null, buf.toString())) == null) { + break; + } } } public static class VersionRange { private static VersionNumber currentVersion = Jenkins.getVersion(); - VersionNumber min, max; - boolean single = true; - public String extra; - - public VersionRange(String version, String extra) { - min = max = version != null ? new VersionNumber(version) : null; - this.extra = extra; - } - - public void add(String version) { - VersionNumber ver = new VersionNumber(version); - if (min==null) { min = max = ver; } - else { - if (ver.isOlderThan(min)) { min = ver; single = false; } - if (ver.isNewerThan(max)) { max = ver; single = false; } + final VersionNumber min; + final VersionNumber max; + final boolean single; + final public String extra; + + public VersionRange(VersionRange previous, String version, String extra) { + if (previous == null) { + min = max = version != null ? new VersionNumber(version) : null; + this.single = true; + this.extra = extra; + } else if (version == null) { + min = previous.min; + max = previous.max; + single = previous.single; + this.extra = extra; + } else { + VersionNumber ver = new VersionNumber(version); + if (previous.min == null || ver.isOlderThan(previous.min)) { + this.min = ver; + } else { + this.min = previous.min; + } + if (previous.max == null || ver.isNewerThan(previous.max)) { + this.max = ver; + } else { + this.max = previous.max; + } + this.single = this.max.isNewerThan(this.min); + this.extra = extra; } } @@ -245,15 +275,20 @@ public class OldDataMonitor extends AdministrativeMonitor { || (currentVersion.digit(0) == min.digit(0) && currentVersion.digit(1) - min.digit(1) >= threshold)); } + } /** * Sorted list of unique max-versions in the data set. For select list in jelly. */ - public synchronized Iterator getVersionList() { + @Restricted(NoExternalUse.class) + public Iterator getVersionList() { TreeSet set = new TreeSet(); - for (VersionRange vr : data.values()) - if (vr.max!=null) set.add(vr.max); + for (VersionRange vr : data.values()) { + if (vr.max != null) { + set.add(vr.max); + } + } return set.iterator(); } @@ -279,7 +314,7 @@ public class OldDataMonitor extends AdministrativeMonitor { final String thruVerParam = req.getParameter("thruVer"); final VersionNumber thruVer = thruVerParam.equals("all") ? null : new VersionNumber(thruVerParam); - saveAndRemoveEntries( new Predicate>() { + saveAndRemoveEntries(new Predicate>() { @Override public boolean apply(Map.Entry entry) { VersionNumber version = entry.getValue().max; @@ -318,13 +353,8 @@ public class OldDataMonitor extends AdministrativeMonitor { * does occur: just means the user will be prompted to discard less than they should have been (and * would see the warning again after next restart). */ - Map localCopy = null; - synchronized (this) { - localCopy = new HashMap(data); - } - List removed = new ArrayList(); - for (Map.Entry entry : localCopy.entrySet()) { + for (Map.Entry entry : data.entrySet()) { if (matchingPredicate.apply(entry)) { Saveable s = entry.getKey().get(); if (s != null) { @@ -338,9 +368,7 @@ public class OldDataMonitor extends AdministrativeMonitor { } } - synchronized (this) { - data.keySet().removeAll(removed); - } + data.keySet().removeAll(removed); } public HttpResponse doIndex(StaplerResponse rsp) throws IOException { @@ -403,7 +431,7 @@ public class OldDataMonitor extends AdministrativeMonitor { } } - @Extension + @Extension @Symbol("oldData") public static class ManagementLinkImpl extends ManagementLink { @Override public String getIconFileName() { diff --git a/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java b/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java index 94412637bfcd20a22c138bafd6853c8086b11606..f3b55cb6a1236e4de51228dad30152aa86e59560 100644 --- a/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java +++ b/core/src/main/java/hudson/diagnosis/ReverseProxySetupMonitor.java @@ -26,6 +26,7 @@ package hudson.diagnosis; import hudson.Extension; import hudson.Util; import hudson.model.AdministrativeMonitor; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; @@ -48,7 +49,7 @@ import org.kohsuke.stapler.Stapler; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("reverseProxy") public class ReverseProxySetupMonitor extends AdministrativeMonitor { private static final Logger LOGGER = Logger.getLogger(ReverseProxySetupMonitor.class.getName()); @@ -62,7 +63,6 @@ public class ReverseProxySetupMonitor extends AdministrativeMonitor { public HttpResponse doTest() { String referer = Stapler.getCurrentRequest().getReferer(); Jenkins j = Jenkins.getInstance(); - assert j != null; // May need to send an absolute URL, since handling of HttpRedirect with a relative URL does not currently honor X-Forwarded-Proto/Port at all. String redirect = j.getRootUrl() + "administrativeMonitor/" + id + "/testForReverseProxySetup/" + (referer != null ? Util.rawEncode(referer) : "NO-REFERER") + "/"; LOGGER.log(Level.FINE, "coming from {0} and redirecting to {1}", new Object[] {referer, redirect}); @@ -71,7 +71,6 @@ public class ReverseProxySetupMonitor extends AdministrativeMonitor { public void getTestForReverseProxySetup(String rest) { Jenkins j = Jenkins.getInstance(); - assert j != null; String inferred = j.getRootUrlFromRequest() + "manage"; // TODO this could also verify that j.getRootUrl() has been properly configured, and send a different message if not if (rest.startsWith(inferred)) { // not using equals due to JENKINS-24014 @@ -94,5 +93,10 @@ public class ReverseProxySetupMonitor extends AdministrativeMonitor { return new HttpRedirect("https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+setup+is+broken"); } } + + @Override + public String getDisplayName() { + return Messages.ReverseProxySetupMonitor_DisplayName(); + } } diff --git a/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java b/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java index 80ea45c9e6be5ac67888db85d0b71d4ad791840f..d94aa68ed2928562e048e7fd601645f93ac8eeb3 100644 --- a/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java +++ b/core/src/main/java/hudson/diagnosis/TooManyJobsButNoView.java @@ -26,6 +26,7 @@ package hudson.diagnosis; import hudson.model.AdministrativeMonitor; import jenkins.model.Jenkins; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -39,8 +40,14 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("tooManyJobsButNoView") public class TooManyJobsButNoView extends AdministrativeMonitor { + + @Override + public String getDisplayName() { + return Messages.TooManyJobsButNoView_DisplayName(); + } + public boolean isActivated() { Jenkins h = Jenkins.getInstance(); return h.getViews().size()==1 && h.getItemMap().size()> THRESHOLD; diff --git a/core/src/main/java/hudson/init/InitMilestone.java b/core/src/main/java/hudson/init/InitMilestone.java index 0f5c51dba59c55360529aecb7560d925d94a2298..3d5412e0bffca0ffc4c4b44d7c4d1d1f895320e7 100644 --- a/core/src/main/java/hudson/init/InitMilestone.java +++ b/core/src/main/java/hudson/init/InitMilestone.java @@ -36,7 +36,16 @@ import org.jvnet.hudson.reactor.TaskGraphBuilder; * (in addition to defining their own milestones by implementing {@link Milestone}. * *

- * These milestones are achieve in this order. + * These milestones are achieve in this order: + *

    + *
  1. STARTED + *
  2. PLUGINS_LISTED + *
  3. PLUGINS_PREPARED + *
  4. PLUGINS_STARTED + *
  5. EXTENSIONS_AUGMENTED + *
  6. JOB_LOADED + *
  7. COMPLETED + *
* * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/init/InitStrategy.java b/core/src/main/java/hudson/init/InitStrategy.java index 7b8497405d4ef6014b6b01076a770f5538e9c63d..0d1e037e6a6bc5cf939ea2da9bc42d5f058e5147 100644 --- a/core/src/main/java/hudson/init/InitStrategy.java +++ b/core/src/main/java/hudson/init/InitStrategy.java @@ -10,11 +10,11 @@ import java.util.Collection; import java.util.List; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.logging.Level; import java.util.logging.Logger; import hudson.PluginManager; +import jenkins.util.SystemProperties; import hudson.util.DirScanner; import hudson.util.FileVisitor; import hudson.util.Service; @@ -50,15 +50,6 @@ public class InitStrategy { // for example, while doing "mvn jpi:run" or "mvn hpi:run" on a plugin that's bundled with Jenkins, we want to the // *.jpl file to override the bundled jpi/hpi file. getBundledPluginsFromProperty(r); - Iterator it = r.iterator(); - while (it.hasNext()) { - File f = it.next(); - if (new File(pm.rootDir, f.getName().replace(".hpi", ".jpi") + ".pinned").isFile()) { - // Cf. PluginManager.copyBundledPlugin, which is not called in this case. - LOGGER.log(Level.INFO, "ignoring {0} since this plugin is pinned", f); - it.remove(); - } - } // similarly, we prefer *.jpi over *.hpi listPluginFiles(pm, ".jpl", r); // linked plugin. for debugging. @@ -84,7 +75,7 @@ public class InitStrategy { * TODO: maven-hpi-plugin should inject its own InitStrategy instead of having this in the core. */ protected void getBundledPluginsFromProperty(final List r) { - String hplProperty = System.getProperty("hudson.bundled.plugins"); + String hplProperty = SystemProperties.getString("hudson.bundled.plugins"); if (hplProperty != null) { for (String hplLocation : hplProperty.split(",")) { File hpl = new File(hplLocation.trim()); diff --git a/core/src/main/java/hudson/init/Initializer.java b/core/src/main/java/hudson/init/Initializer.java index d693314b7cc8a2ec076718cb6352627bf98bfeb8..d41f45da52edba6cc1637d7c33f0bfb4eee50c29 100644 --- a/core/src/main/java/hudson/init/Initializer.java +++ b/core/src/main/java/hudson/init/Initializer.java @@ -23,6 +23,7 @@ */ package hudson.init; +import hudson.Extension; import org.jvnet.hudson.annotation_indexer.Indexed; import org.jvnet.hudson.reactor.Task; @@ -36,7 +37,7 @@ import static hudson.init.InitMilestone.STARTED; import static hudson.init.InitMilestone.COMPLETED; /** - * Placed on static methods to indicate that this method is to be run during the Jenkins start up to perform + * Placed on methods to indicate that this method is to be run during the Jenkins start up to perform * some sort of initialization tasks. * *

Example

@@ -46,6 +47,11 @@ import static hudson.init.InitMilestone.COMPLETED; .... } * + * + *

+ * The method in question can be either {@code static} or an instance method. When used with instance + * methods, those methods have to be on a class annotated with {@link Extension} and marked as + * {@link #after()} {@link InitMilestone#PLUGINS_PREPARED}. * * @author Kohsuke Kawaguchi */ diff --git a/core/src/main/java/hudson/init/TaskMethodFinder.java b/core/src/main/java/hudson/init/TaskMethodFinder.java index 9ced2cb1abed9431fa5914e9f5eaa375a16b7a23..0e09bfe267821a22fc01f26296477880a4d046eb 100644 --- a/core/src/main/java/hudson/init/TaskMethodFinder.java +++ b/core/src/main/java/hudson/init/TaskMethodFinder.java @@ -56,9 +56,6 @@ abstract class TaskMethodFinder extends TaskBuilder { for (Method e : Index.list(type, cl, Method.class)) { if (filter(e)) continue; // already reported once - if (!Modifier.isStatic(e.getModifiers())) - throw new IOException(e+" is not a static method"); - T i = e.getAnnotation(type); if (i==null) continue; // stale index @@ -103,7 +100,10 @@ abstract class TaskMethodFinder extends TaskBuilder { Object[] args = new Object[pt.length]; for (int i=0; i extends TaskBuilder { * Determines the parameter injection of the initialization method. */ private Object lookUp(Class type) { - if (type==Jenkins.class || type==Hudson.class) - return Jenkins.getInstance(); Jenkins j = Jenkins.getInstance(); - if (j!=null) { - Injector i = j.getInjector(); - if (i!=null) - return i.getInstance(type); - } + assert j != null : "This method is only invoked after the Jenkins singleton instance has been set"; + if (type==Jenkins.class || type==Hudson.class) + return j; + Injector i = j.getInjector(); + if (i!=null) + return i.getInstance(type); throw new IllegalArgumentException("Unable to inject "+type); } @@ -150,7 +149,7 @@ abstract class TaskMethodFinder extends TaskBuilder { } /** - * Static method that runs the initialization, that this task wraps. + * Method that runs the initialization, that this task wraps. */ public Method getMethod() { return e; diff --git a/core/src/main/java/hudson/init/Terminator.java b/core/src/main/java/hudson/init/Terminator.java index 72a2c9025b6f4e1e1d2417bcb0f9e998c57aedb8..3e1155babdcfee7954b507a33d93d81fd4a24be9 100644 --- a/core/src/main/java/hudson/init/Terminator.java +++ b/core/src/main/java/hudson/init/Terminator.java @@ -1,7 +1,6 @@ package hudson.init; import org.jvnet.hudson.annotation_indexer.Indexed; -import org.jvnet.hudson.reactor.Task; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @@ -12,6 +11,8 @@ import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** + * Like {@link Initializer} but used during the shut down. + * * @author Kohsuke Kawaguchi */ @Indexed diff --git a/core/src/main/java/hudson/init/impl/GroovyInitScript.java b/core/src/main/java/hudson/init/impl/GroovyInitScript.java index 621d52ce635f59c8d09bc4f198a3a24e4b90b88f..20cd1a481c006f82f2f69557f5a7fc1bcf72ccb0 100644 --- a/core/src/main/java/hudson/init/impl/GroovyInitScript.java +++ b/core/src/main/java/hudson/init/impl/GroovyInitScript.java @@ -27,7 +27,6 @@ import hudson.init.Initializer; import jenkins.model.Jenkins; import jenkins.util.groovy.GroovyHookScript; -import java.io.IOException; import static hudson.init.InitMilestone.*; @@ -39,6 +38,6 @@ import static hudson.init.InitMilestone.*; public class GroovyInitScript { @Initializer(after=JOB_LOADED) public static void init(Jenkins j) { - new GroovyHookScript("init").run(); + new GroovyHookScript("init", j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader).run(); } } diff --git a/core/src/main/java/hudson/init/impl/InitialUserContent.java b/core/src/main/java/hudson/init/impl/InitialUserContent.java index 85a7d7bb7e3c2cc33fa687bde259b97613a4add5..0407dd8bb64eaa7ca7ba087ce4022c45ed5904e1 100644 --- a/core/src/main/java/hudson/init/impl/InitialUserContent.java +++ b/core/src/main/java/hudson/init/impl/InitialUserContent.java @@ -42,7 +42,7 @@ public class InitialUserContent { File userContentDir = new File(h.getRootDir(), "userContent"); if(!userContentDir.exists()) { userContentDir.mkdirs(); - FileUtils.writeStringToFile(new File(userContentDir,"readme.txt"), Messages.Hudson_USER_CONTENT_README()); + FileUtils.writeStringToFile(new File(userContentDir,"readme.txt"), Messages.Hudson_USER_CONTENT_README() + "\n"); } } } diff --git a/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java b/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java index e39edb8f7cd1232800fc65ff2e9f61996de65fc8..7a37561571fc2a8c419d748c72886c647453650b 100644 --- a/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java +++ b/core/src/main/java/hudson/init/impl/InstallUncaughtExceptionHandler.java @@ -11,6 +11,9 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.kohsuke.stapler.Stapler; /** @@ -26,16 +29,40 @@ public class InstallUncaughtExceptionHandler { try { WebApp.get(j.servletContext).getSomeStapler() .invoke(req,rsp, Jenkins.getInstance(), "/oops"); - } catch (ServletException x) { - if (!Stapler.isSocketException(x)) { - throw x; - } - } catch (IOException x) { + } catch (ServletException | IOException x) { if (!Stapler.isSocketException(x)) { throw x; } } } }); + try { + Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler()); + DefaultUncaughtExceptionHandler.LOGGER.log(Level.FINE, "Successfully installed a global UncaughtExceptionHandler."); + } + catch (SecurityException ex) { + DefaultUncaughtExceptionHandler.LOGGER.log(Level.SEVERE, + "Failed to set the default UncaughtExceptionHandler. " + + "If any threads die due to unhandled coding errors then there will be no logging of this information. " + + "The lack of this diagnostic information will make it harder to track down issues which will reduce the supportability of Jenkins. " + + "It is highly recomended that you consult the documentation that comes with you servlet container on how to allow the " + + "`setDefaultUncaughtExceptionHandler` permission and enable it.", ex); + } + } + + /** An UncaughtExceptionHandler that just logs the exception */ + private static class DefaultUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { + + private static final Logger LOGGER = Logger.getLogger(InstallUncaughtExceptionHandler.class.getName()); + + @Override + public void uncaughtException(Thread t, Throwable ex) { + // if this was an OutOfMemoryError then all bets about logging are off - but in the absence of anything else... + LOGGER.log(Level.SEVERE, + "A thread (" + t.getName() + '/' + t.getId() + + ") died unexpectedly due to an uncaught exception, this may leave your Jenkins in a bad way and is usually indicative of a bug in the code.", + ex); + } + } } diff --git a/core/src/main/java/hudson/lifecycle/Lifecycle.java b/core/src/main/java/hudson/lifecycle/Lifecycle.java index d314742f85fe9ad9d3ac23e16eb8064e4f526e04..34915da0de1beab1dbd7c085506d8bb51aab2644 100644 --- a/core/src/main/java/hudson/lifecycle/Lifecycle.java +++ b/core/src/main/java/hudson/lifecycle/Lifecycle.java @@ -25,6 +25,7 @@ package hudson.lifecycle; import hudson.ExtensionPoint; import hudson.Functions; +import jenkins.util.SystemProperties; import hudson.Util; import jenkins.model.Jenkins; @@ -57,7 +58,7 @@ public abstract class Lifecycle implements ExtensionPoint { public synchronized static Lifecycle get() { if(INSTANCE==null) { Lifecycle instance; - String p = System.getProperty("hudson.lifecycle"); + String p = SystemProperties.getString("hudson.lifecycle"); if(p!=null) { try { ClassLoader cl = Jenkins.getInstance().getPluginManager().uberClassLoader; @@ -119,7 +120,7 @@ public abstract class Lifecycle implements ExtensionPoint { * to a newer version. */ public File getHudsonWar() { - String war = System.getProperty("executable-war"); + String war = SystemProperties.getString("executable-war"); if(war!=null && new File(war).exists()) return new File(war); return null; diff --git a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java index 9da1505229ae2d57905c708c63b66e4c8c600953..ca90fb83d42798b3a5e2da4b5b0db9f38669db13 100644 --- a/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/SolarisSMFLifecycle.java @@ -38,7 +38,7 @@ public class SolarisSMFLifecycle extends Lifecycle { */ @Override public void restart() throws IOException, InterruptedException { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); // guard against repeated concurrent calls to restart if (h != null) h.cleanUp(); System.exit(0); diff --git a/core/src/main/java/hudson/lifecycle/UnixLifecycle.java b/core/src/main/java/hudson/lifecycle/UnixLifecycle.java index 6a558594532ca65ad95372afecb3cd692c3ea835..5d545a4fe4f528ca7934d90394fd65873c3e58c9 100644 --- a/core/src/main/java/hudson/lifecycle/UnixLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/UnixLifecycle.java @@ -24,7 +24,6 @@ package hudson.lifecycle; import com.sun.akuma.JavaVMArguments; -import com.sun.akuma.Daemon; import com.sun.jna.Native; import com.sun.jna.StringArray; @@ -66,7 +65,7 @@ public class UnixLifecycle extends Lifecycle { @Override public void restart() throws IOException, InterruptedException { - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); // guard against repeated concurrent calls to restart if (h != null) h.cleanUp(); diff --git a/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java b/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java index 4401b43649858f649980b7866dada16175e8cdca..978b3c79659546fcefff70c05a21aeb366a0b53c 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java +++ b/core/src/main/java/hudson/lifecycle/WindowsInstallerLink.java @@ -34,6 +34,7 @@ import hudson.util.jna.Shell32; import jenkins.model.Jenkins; import hudson.AbortException; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.util.StreamTaskListener; import hudson.util.jna.DotNet; import org.apache.commons.io.IOUtils; @@ -257,14 +258,14 @@ public class WindowsInstallerLink extends ManagementLink { // this system property is set by the launcher when we run "java -jar jenkins.war" // and this is how we know where is jenkins.war. - String war = System.getProperty("executable-war"); + String war = SystemProperties.getString("executable-war"); if(war!=null && new File(war).exists()) { WindowsInstallerLink link = new WindowsInstallerLink(new File(war)); // in certain situations where we know the user is just trying Jenkins (like when Jenkins is launched // from JNLP), also put this link on the navigation bar to increase // visibility - if(System.getProperty(WindowsInstallerLink.class.getName()+".prominent")!=null) + if(SystemProperties.getString(WindowsInstallerLink.class.getName()+".prominent")!=null) Jenkins.getInstance().getActions().add(link); return link; diff --git a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java index 11f364e953ba25fce29da0a4499aa567731cb219..4a7e8d2fa9d6987013502dca90ecced7e7d1b575 100644 --- a/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java +++ b/core/src/main/java/hudson/lifecycle/WindowsServiceLifecycle.java @@ -110,11 +110,8 @@ public class WindowsServiceLifecycle extends Lifecycle { File rootDir = Jenkins.getInstance().getRootDir(); File copyFiles = new File(rootDir,baseName+".copies"); - FileWriter w = new FileWriter(copyFiles, true); - try { - w.write(by.getAbsolutePath()+'>'+getHudsonWar().getAbsolutePath()+'\n'); - } finally { - w.close(); + try (FileWriter w = new FileWriter(copyFiles, true)) { + w.write(by.getAbsolutePath() + '>' + getHudsonWar().getAbsolutePath() + '\n'); } } diff --git a/core/src/main/java/hudson/logging/LogRecorder.java b/core/src/main/java/hudson/logging/LogRecorder.java index 81c9486e3fa8fd0f6ce3d4b9c4ec111faaf5e06b..af6fb378ce559dded833f04755128f11faa5a372 100644 --- a/core/src/main/java/hudson/logging/LogRecorder.java +++ b/core/src/main/java/hudson/logging/LogRecorder.java @@ -33,7 +33,6 @@ import hudson.model.*; import hudson.util.HttpResponses; import jenkins.model.Jenkins; import hudson.model.listeners.SaveableListener; -import hudson.remoting.Callable; import hudson.remoting.Channel; import hudson.remoting.VirtualChannel; import hudson.slaves.ComputerListener; @@ -209,7 +208,7 @@ public class LogRecorder extends AbstractModelObject implements Saveable { } private static final class SetLevel extends MasterToSlaveCallable { - /** known loggers (kept per slave), to avoid GC */ + /** known loggers (kept per agent), to avoid GC */ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private static final Set loggers = new HashSet(); private final String name; private final Level level; @@ -364,7 +363,7 @@ public class LogRecorder extends AbstractModelObject implements Saveable { } /** - * Gets a view of log records per slave matching this recorder. + * Gets a view of log records per agent matching this recorder. * @return a map (sorted by display name) from computer to (nonempty) list of log records * @since 1.519 */ diff --git a/core/src/main/java/hudson/logging/LogRecorderManager.java b/core/src/main/java/hudson/logging/LogRecorderManager.java index d16ece6c2babdcfdf0fd9f95ddf25ce1098c0b06..698718634b2c12bbdcffc6f26339ec86e15b425b 100644 --- a/core/src/main/java/hudson/logging/LogRecorderManager.java +++ b/core/src/main/java/hudson/logging/LogRecorderManager.java @@ -40,6 +40,7 @@ import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpRedirect; +import org.kohsuke.stapler.interceptor.RequirePOST; import javax.servlet.ServletException; import java.io.File; @@ -106,6 +107,7 @@ public class LogRecorderManager extends AbstractModelObject implements ModelObje /** * Creates a new log recorder. */ + @RequirePOST public HttpResponse doNewLogRecorder(@QueryParameter String name) { Jenkins.checkGoodName(name); @@ -127,7 +129,7 @@ public class LogRecorderManager extends AbstractModelObject implements ModelObje /** * Configure the logging level. */ - @edu.umd.cs.findbugs.annotations.SuppressWarnings("LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE") + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE") public HttpResponse doConfigLogger(@QueryParameter String name, @QueryParameter String level) { Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); Level lv; diff --git a/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java b/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java index f106b5de2c6f00520a0656420c780143f0cb0f33..f97e5e94c4e22c2cf0ee794858c49b5bf74289d8 100644 --- a/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java +++ b/core/src/main/java/hudson/markup/EscapedMarkupFormatter.java @@ -29,10 +29,12 @@ import hudson.markup.MarkupFormatter; import hudson.markup.MarkupFormatterDescriptor; import java.io.IOException; import java.io.Writer; + +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** - * @link MarkupFormatter} that treats the input as the escaped html. + * {@link MarkupFormatter} that treats the input as the escaped html. * * @author Seiji Sogabe * @since 1.553 @@ -48,7 +50,7 @@ public class EscapedMarkupFormatter extends MarkupFormatter { output.write(Util.escape(markup)); } - @Extension + @Extension @Symbol("plainText") public static class DescriptorImpl extends MarkupFormatterDescriptor { @Override diff --git a/core/src/main/java/hudson/model/AbstractBuild.java b/core/src/main/java/hudson/model/AbstractBuild.java index aa1f9626e635940a9a4e54033b8b3b6bbee9249a..b723b9b5196176351913d2ad244d3f64bc02cf12 100644 --- a/core/src/main/java/hudson/model/AbstractBuild.java +++ b/core/src/main/java/hudson/model/AbstractBuild.java @@ -30,8 +30,7 @@ import hudson.EnvVars; import hudson.FilePath; import hudson.Functions; import hudson.Launcher; -import hudson.console.AnnotatedLargeText; -import hudson.console.ExpandableDetailsNote; +import jenkins.util.SystemProperties; import hudson.console.ModelHyperlinkNote; import hudson.model.Fingerprint.BuildPtr; import hudson.model.Fingerprint.RangeSet; @@ -70,7 +69,6 @@ import javax.servlet.ServletException; import java.io.File; import java.io.IOException; import java.io.InterruptedIOException; -import java.io.StringWriter; import java.lang.ref.WeakReference; import java.util.AbstractSet; import java.util.ArrayList; @@ -109,10 +107,10 @@ public abstract class AbstractBuild

,R extends Abs /** * Set if we want the blame information to flow from upstream to downstream build. */ - private static final boolean upstreamCulprits = Boolean.getBoolean("hudson.upstreamCulprits"); + private static final boolean upstreamCulprits = SystemProperties.getBoolean("hudson.upstreamCulprits"); /** - * Name of the slave this project was built on. + * Name of the agent this project was built on. * Null or "" if built by the master. (null happens when we read old record that didn't have this information.) */ private String builtOn; @@ -130,7 +128,6 @@ public abstract class AbstractBuild

,R extends Abs /** * SCM used for this build. - * Maybe null, for historical reason, in which case CVS is assumed. */ private ChangeLogParser scm; @@ -208,7 +205,7 @@ public abstract class AbstractBuild

,R extends Abs * Returns a {@link Slave} on which this build was done. * * @return - * null, for example if the slave that this build run no longer exists. + * null, for example if the agent that this build run no longer exists. */ public @CheckForNull Node getBuiltOn() { if (builtOn==null || builtOn.equals("")) @@ -218,7 +215,7 @@ public abstract class AbstractBuild

,R extends Abs } /** - * Returns the name of the slave it was built on; null or "" if built by the master. + * Returns the name of the agent it was built on; null or "" if built by the master. * (null happens when we read old record that didn't have this information.) */ @Exported(name="builtOn") @@ -279,7 +276,7 @@ public abstract class AbstractBuild

,R extends Abs * {@link AbstractBuildExecution#decideWorkspace(Node,WorkspaceList)}. * * @return - * null if the workspace is on a slave that's not connected. Note that once the build is completed, + * null if the workspace is on an agent that's not connected. Note that once the build is completed, * the workspace may be used to build something else, so the value returned from this method may * no longer show a workspace as it was used for this build. * @since 1.319 @@ -600,9 +597,6 @@ public abstract class AbstractBuild

,R extends Abs AbstractProject project = build.getProject(); for (int retryCount=project.getScmCheckoutRetryCount(); ; retryCount--) { - // for historical reasons, null in the scm field means CVS, so we need to explicitly set this to something - // in case check out fails and leaves a broken changelog.xml behind. - // see http://www.nabble.com/CVSChangeLogSet.parse-yields-SAXParseExceptions-when-parsing-bad-*AccuRev*-changelog.xml-files-td22213663.html build.scm = NullChangeLogParser.INSTANCE; try { @@ -742,13 +736,19 @@ public abstract class AbstractBuild

,R extends Abs } private void reportError(BuildStep bs, Throwable e, BuildListener listener, boolean phase) { - final String publisher = ((Publisher) bs).getDescriptor().getDisplayName(); + final String buildStep; + + if (bs instanceof Describable) { + buildStep = ((Describable) bs).getDescriptor().getDisplayName(); + } else { + buildStep = bs.getClass().getName(); + } if (e instanceof AbortException) { - LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {AbstractBuild.this, publisher}); - listener.error("Publisher '" + publisher + "' failed: " + e.getMessage()); + LOGGER.log(Level.FINE, "{0} : {1} failed", new Object[] {AbstractBuild.this, buildStep}); + listener.error("Step ‘" + buildStep + "’ failed: " + e.getMessage()); } else { - String msg = "Publisher '" + publisher + "' aborted due to exception: "; + String msg = "Step ‘" + buildStep + "’ aborted due to exception: "; e.printStackTrace(listener.error(msg)); LOGGER.log(WARNING, msg, e); } @@ -805,7 +805,7 @@ public abstract class AbstractBuild

,R extends Abs private void reportBrokenChannel(BuildListener listener) throws IOException { final Node node = getCurrentNode(); - listener.hyperlink("/" + node.toComputer().getUrl() + "log", "Slave went offline during the build"); + listener.hyperlink("/" + node.toComputer().getUrl() + "log", "Agent went offline during the build"); listener.getLogger().println(); final OfflineCause offlineCause = node.toComputer().getOfflineCause(); if (offlineCause != null) { @@ -867,20 +867,7 @@ public abstract class AbstractBuild

,R extends Abs public ChangeLogSet getChangeSet() { synchronized (changeSetLock) { if (scm==null) { - // for historical reason, null means CVS. - try { - Class c = Jenkins.getInstance().getPluginManager().uberClassLoader.loadClass("hudson.scm.CVSChangeLogParser"); - scm = (ChangeLogParser)c.newInstance(); - } catch (ClassNotFoundException e) { - // if CVS isn't available, fall back to something non-null. - scm = NullChangeLogParser.INSTANCE; - } catch (InstantiationException e) { - scm = NullChangeLogParser.INSTANCE; - throw (Error)new InstantiationError().initCause(e); - } catch (IllegalAccessException e) { - scm = NullChangeLogParser.INSTANCE; - throw (Error)new IllegalAccessError().initCause(e); - } + scm = NullChangeLogParser.INSTANCE; } } diff --git a/core/src/main/java/hudson/model/AbstractDescribableImpl.java b/core/src/main/java/hudson/model/AbstractDescribableImpl.java index 5961a80834a13feb490f3d29fd3976860913dcda..07ed386a930885d755b29f9b68c1d184d1bc7a18 100644 --- a/core/src/main/java/hudson/model/AbstractDescribableImpl.java +++ b/core/src/main/java/hudson/model/AbstractDescribableImpl.java @@ -37,6 +37,7 @@ public abstract class AbstractDescribableImpl{@inheritDoc} */ + @Override public Descriptor getDescriptor() { return Jenkins.getInstance().getDescriptorOrDie(getClass()); } diff --git a/core/src/main/java/hudson/model/AbstractItem.java b/core/src/main/java/hudson/model/AbstractItem.java index 179b3ec92f3e53d18408369f6c4c14dbde7c1bfc..eb71ce20ae74ba07c6fc84e29ffd80a506f24722 100644 --- a/core/src/main/java/hudson/model/AbstractItem.java +++ b/core/src/main/java/hudson/model/AbstractItem.java @@ -30,7 +30,6 @@ import hudson.XmlFile; import hudson.Util; import hudson.Functions; import hudson.BulkChange; -import hudson.cli.declarative.CLIMethod; import hudson.cli.declarative.CLIResolver; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; @@ -41,6 +40,7 @@ import hudson.util.AlternativeUiTextProvider; import hudson.util.AlternativeUiTextProvider.Message; import hudson.util.AtomicFileWriter; import hudson.util.IOUtils; +import hudson.util.Secret; import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; import jenkins.security.NotReallyRoleSensitiveCallable; @@ -55,11 +55,14 @@ import org.kohsuke.stapler.export.ExportedBean; import java.io.File; import java.io.IOException; +import java.io.OutputStream; import java.util.Collection; import java.util.List; import java.util.ListIterator; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.annotation.Nonnull; import org.kohsuke.stapler.StaplerRequest; @@ -72,12 +75,16 @@ import org.kohsuke.stapler.interceptor.RequirePOST; import org.xml.sax.SAXException; import javax.servlet.ServletException; +import javax.servlet.ServletOutputStream; import javax.xml.transform.Source; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import org.apache.commons.io.FileUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.Ancestor; /** @@ -164,7 +171,7 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet } public void setDisplayName(String displayName) throws IOException { - this.displayName = Util.fixEmpty(displayName); + this.displayName = Util.fixEmptyAndTrim(displayName); save(); } @@ -347,12 +354,14 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet */ public abstract Collection getAllJobs(); + @Exported public final String getFullName() { String n = getParent().getFullName(); if(n.length()==0) return getName(); else return n+'/'+getName(); } + @Exported public final String getFullDisplayName() { String n = getParent().getFullDisplayName(); if(n.length()==0) return getDisplayName(); @@ -538,7 +547,6 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet * since it predates {@code }. {@code /delete} goes to a Jelly page * which should now be unused by core but is left in case plugins are still using it. */ - @CLIMethod(name="delete-job") @RequirePOST public void doDoDelete( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, InterruptedException { delete(); @@ -602,9 +610,8 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet throws IOException { if (req.getMethod().equals("GET")) { // read - checkPermission(EXTENDED_READ); rsp.setContentType("application/xml"); - IOUtils.copy(getConfigFile().getFile(),rsp.getOutputStream()); + writeConfigDotXml(rsp.getOutputStream()); return; } if (req.getMethod().equals("POST")) { @@ -617,6 +624,33 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet rsp.sendError(SC_BAD_REQUEST); } + static final Pattern SECRET_PATTERN = Pattern.compile(">(" + Secret.ENCRYPTED_VALUE_PATTERN + ")<"); + /** + * Writes {@code config.xml} to the specified output stream. + * The user must have at least {@link #EXTENDED_READ}. + * If he lacks {@link #CONFIGURE}, then any {@link Secret}s detected will be masked out. + */ + @Restricted(NoExternalUse.class) + public void writeConfigDotXml(OutputStream os) throws IOException { + checkPermission(EXTENDED_READ); + XmlFile configFile = getConfigFile(); + if (hasPermission(CONFIGURE)) { + IOUtils.copy(configFile.getFile(), os); + } else { + String encoding = configFile.sniffEncoding(); + String xml = FileUtils.readFileToString(configFile.getFile(), encoding); + Matcher matcher = SECRET_PATTERN.matcher(xml); + StringBuffer cleanXml = new StringBuffer(); + while (matcher.find()) { + if (Secret.decrypt(matcher.group(1)) != null) { + matcher.appendReplacement(cleanXml, ">********<"); + } + } + matcher.appendTail(cleanXml); + org.apache.commons.io.IOUtils.write(cleanXml.toString(), os, encoding); + } + } + /** * @deprecated as of 1.473 * Use {@link #updateByXml(Source)} @@ -641,9 +675,7 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet try { XMLUtils.safeTransform(source, new StreamResult(out)); out.close(); - } catch (TransformerException e) { - throw new IOException("Failed to persist config.xml", e); - } catch (SAXException e) { + } catch (TransformerException | SAXException e) { throw new IOException("Failed to persist config.xml", e); } @@ -681,7 +713,6 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet * * @since 1.556 */ - @CLIMethod(name="reload-job") @RequirePOST public void doReload() throws IOException { checkPermission(CONFIGURE); @@ -701,8 +732,8 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet } - /* (non-Javadoc) - * @see hudson.model.AbstractModelObject#getSearchName() + /** + * {@inheritDoc} */ @Override public String getSearchName() { @@ -724,8 +755,11 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet @Argument(required=true,metaVar="NAME",usage="Job name") String name) throws CmdLineException { // TODO can this (and its pseudo-override in AbstractProject) share code with GenericItemOptionHandler, used for explicit CLICommand’s rather than CLIMethod’s? AbstractItem item = Jenkins.getInstance().getItemByFullName(name, AbstractItem.class); - if (item==null) - throw new CmdLineException(null,Messages.AbstractItem_NoSuchJobExists(name,AbstractProject.findNearest(name).getFullName())); + if (item==null) { + AbstractProject project = AbstractProject.findNearest(name); + throw new CmdLineException(null, project == null ? Messages.AbstractItem_NoSuchJobExistsWithoutSuggestion(name) + : Messages.AbstractItem_NoSuchJobExists(name, project.getFullName())); + } return item; } diff --git a/core/src/main/java/hudson/model/AbstractProject.java b/core/src/main/java/hudson/model/AbstractProject.java index 5fd056b711bb20970a673578e7509ce2572ff817..2c2fe31c765bb0ccc6b6965106a7fc53f87bc494 100644 --- a/core/src/main/java/hudson/model/AbstractProject.java +++ b/core/src/main/java/hudson/model/AbstractProject.java @@ -55,7 +55,6 @@ import hudson.model.queue.CauseOfBlockage; import hudson.model.queue.QueueTaskFuture; import hudson.model.queue.SubTask; import hudson.model.queue.SubTaskContributor; -import hudson.node_monitors.DiskSpaceMonitor; import hudson.scm.ChangeLogSet; import hudson.scm.ChangeLogSet.Entry; import hudson.scm.NullSCM; @@ -106,6 +105,7 @@ import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.servlet.ServletException; +import jenkins.model.BlockedBecauseOfBuildInProgress; import jenkins.model.Jenkins; import jenkins.model.JenkinsLocationConfiguration; import jenkins.model.ParameterizedJobMixIn; @@ -114,6 +114,7 @@ import jenkins.model.lazy.LazyBuildMixIn; import jenkins.scm.DefaultSCMCheckoutStrategyImpl; import jenkins.scm.SCMCheckoutStrategy; import jenkins.scm.SCMCheckoutStrategyDescriptor; +import jenkins.scm.SCMDecisionHandler; import jenkins.util.TimeDuration; import net.sf.json.JSONObject; import org.acegisecurity.Authentication; @@ -266,8 +267,10 @@ public abstract class AbstractProject

,R extends A buildMixIn = createBuildMixIn(); builds = buildMixIn.getRunMap(); - if(Jenkins.getInstance()!=null && !Jenkins.getInstance().getNodes().isEmpty()) { - // if a new job is configured with Hudson that already has slave nodes + final Jenkins j = Jenkins.getInstance(); + final List nodes = j != null ? j.getNodes() : null; + if(nodes!=null && !nodes.isEmpty()) { + // if a new job is configured with Hudson that already has agent nodes // make it roamable by default canRoam = true; } @@ -355,7 +358,7 @@ public abstract class AbstractProject

,R extends A jdkTool = jdkTool.forNode(node, listener); } jdkTool.buildEnvVars(env); - } else if (jdk != null && !jdk.equals(JDK.DEFAULT_NAME)) { + } else if (!JDK.isDefaultName(jdk)) { listener.getLogger().println("No JDK named ‘" + jdk + "’ found"); } @@ -406,7 +409,7 @@ public abstract class AbstractProject

,R extends A /** * Set of labels relevant to this job. * - * This method is used to determine what slaves are relevant to jobs, for example by {@link View}s. + * This method is used to determine what agents are relevant to jobs, for example by {@link View}s. * It does not affect the scheduling. This information is informational and the best-effort basis. * * @since 1.456 @@ -469,6 +472,7 @@ public abstract class AbstractProject

,R extends A * @since 1.401 */ public String getBuildNowText() { + // For compatibility, still use the deprecated replacer if specified. return AlternativeUiTextProvider.get(BUILD_NOW_TEXT, this, getParameterizedJobMixIn().getBuildNowText()); } @@ -498,7 +502,7 @@ public abstract class AbstractProject

,R extends A * Gets the directory where the module is checked out. * * @return - * null if the workspace is on a slave that's not connected. + * null if the workspace is on an agent that's not connected. * @deprecated as of 1.319 * To support concurrent builds of the same project, this method is moved to {@link AbstractBuild}. * For backward compatibility, this method returns the right {@link AbstractBuild#getWorkspace()} if called @@ -1086,6 +1090,7 @@ public abstract class AbstractProject

,R extends A * or if the blockBuildWhenUpstreamBuilding option is true and an upstream * project is building, but derived classes can also check other conditions. */ + @Override public boolean isBuildBlocked() { return getCauseOfBlockage()!=null; } @@ -1096,23 +1101,12 @@ public abstract class AbstractProject

,R extends A } /** - * Blocked because the previous build is already in progress. + * @deprecated use {@link BlockedBecauseOfBuildInProgress} instead. */ - public static class BecauseOfBuildInProgress extends CauseOfBlockage { - private final AbstractBuild build; - - public BecauseOfBuildInProgress(AbstractBuild build) { - this.build = build; - } - - @Override - public String getShortDescription() { - Executor e = build.getExecutor(); - String eta = ""; - if (e != null) - eta = Messages.AbstractProject_ETA(e.getEstimatedRemainingTime()); - int lbn = build.getNumber(); - return Messages.AbstractProject_BuildInProgress(lbn, eta); + @Deprecated + public static class BecauseOfBuildInProgress extends BlockedBecauseOfBuildInProgress { + public BecauseOfBuildInProgress(@Nonnull AbstractBuild build) { + super(build); } } @@ -1148,10 +1142,20 @@ public abstract class AbstractProject

,R extends A } } + @Override public CauseOfBlockage getCauseOfBlockage() { // Block builds until they are done with post-production - if (isLogUpdated() && !isConcurrentBuild()) - return new BecauseOfBuildInProgress(getLastBuild()); + if (isLogUpdated() && !isConcurrentBuild()) { + final R lastBuild = getLastBuild(); + if (lastBuild != null) { + return new BlockedBecauseOfBuildInProgress(lastBuild); + } else { + // The build has been likely deleted after the isLogUpdated() call. + // Another cause may be an API implemetation glitсh in the implementation for AbstractProject. + // Anyway, we should let the code go then. + LOGGER.log(Level.FINE, "The last build has been deleted during the non-concurrent cause creation. The build is not blocked anymore"); + } + } if (blockBuildWhenDownstreamBuilding()) { AbstractProject bup = getBuildingDownstream(); if (bup!=null) @@ -1269,13 +1273,7 @@ public abstract class AbstractProject

,R extends A return true; // no SCM FilePath workspace = build.getWorkspace(); - try { - workspace.mkdirs(); - } catch (IOException e) { - // Can't create workspace dir - Is slave disk full ? - new DiskSpaceMonitor().markNodeOfflineIfDiskspaceIsTooLow(build.getBuiltOn().toComputer()); - throw e; - } + workspace.mkdirs(); boolean r = scm.checkout(build, launcher, workspace, listener, changelogFile); if (r) { @@ -1333,6 +1331,11 @@ public abstract class AbstractProject

,R extends A listener.getLogger().println(Messages.AbstractProject_Disabled()); return NO_CHANGES; } + SCMDecisionHandler veto = SCMDecisionHandler.firstShouldPollVeto(this); + if (veto != null) { + listener.getLogger().println(Messages.AbstractProject_PollingVetoed(veto)); + return NO_CHANGES; + } R lb = getLastBuild(); if (lb==null) { @@ -1406,7 +1409,7 @@ public abstract class AbstractProject

,R extends A // At this point we start thinking about triggering a build just to get a workspace, // because otherwise there's no way we can detect changes. // However, first there are some conditions in which we do not want to do so. - // give time for slaves to come online if we are right after reconnection (JENKINS-8408) + // give time for agents to come online if we are right after reconnection (JENKINS-8408) long running = Jenkins.getInstance().getInjector().getInstance(Uptime.class).getUptime(); long remaining = TimeUnit2.MINUTES.toMillis(10)-running; if (remaining>0 && /* this logic breaks tests of polling */!Functions.getIsUnitTest()) { @@ -1415,7 +1418,7 @@ public abstract class AbstractProject

,R extends A return NO_CHANGES; } - // Do not trigger build, if no suitable slave is online + // Do not trigger build, if no suitable agent is online if (workspaceOfflineReason.equals(WorkspaceOfflineReason.all_suitable_nodes_are_offline)) { // No suitable executor is online listener.getLogger().print(Messages.AbstractProject_AwaitingWorkspaceToComeOnline(running/1000)); @@ -1426,7 +1429,7 @@ public abstract class AbstractProject

,R extends A Label label = getAssignedLabel(); if (label != null && label.isSelfLabel()) { // if the build is fixed on a node, then attempting a build will do us - // no good. We should just wait for the slave to come back. + // no good. We should just wait for the agent to come back. listener.getLogger().print(Messages.AbstractProject_NoWorkspace()); listener.getLogger().println( " (" + workspaceOfflineReason.name() + ")"); return NO_CHANGES; @@ -1471,7 +1474,8 @@ public abstract class AbstractProject

,R extends A Launcher launcher = ws.createLauncher(listener).decorateByEnv(getEnvironment(node,listener)); WorkspaceList.Lease lease = l.acquire(ws, !concurrentBuild); try { - listener.getLogger().println("Polling SCM changes on " + node.getSelfLabel().getName()); + String nodeName = node != null ? node.getSelfLabel().getName() : "[node_unavailable]"; + listener.getLogger().println("Polling SCM changes on " + nodeName); LOGGER.fine("Polling SCM changes of " + getName()); if (pollingBaseline==null) // see NOTE-NO-BASELINE above calcPollingBaseline(lb,launcher,listener); @@ -1933,6 +1937,7 @@ public abstract class AbstractProject

,R extends A /** * Wipes out the workspace. */ + @RequirePOST public HttpResponse doDoWipeOutWorkspace() throws IOException, ServletException, InterruptedException { checkPermission(Functions.isWipeOutPermissionEnabled() ? WIPEOUT : BUILD); R b = getSomeBuildWithWorkspace(); @@ -2087,9 +2092,6 @@ public abstract class AbstractProject

,R extends A Messages.AbstractProject_AssignedLabelString_InvalidBooleanExpression(e.getMessage())); } Jenkins j = Jenkins.getInstance(); - if (j == null) { - return FormValidation.ok(); // ? - } Label l = j.getLabel(value); if (l.isEmpty()) { for (LabelAtom a : l.listAtoms()) { @@ -2110,8 +2112,8 @@ public abstract class AbstractProject

,R extends A } } return FormValidation.okWithMarkup(Messages.AbstractProject_LabelLink( - j.getRootUrl(), l.getUrl(), l.getNodes().size() + l.getClouds().size() - )); + j.getRootUrl(), Util.escape(l.getName()), l.getUrl(), l.getNodes().size(), l.getClouds().size()) + ); } public FormValidation doCheckCustomWorkspace(@QueryParameter String customWorkspace){ @@ -2236,8 +2238,9 @@ public abstract class AbstractProject

,R extends A public static final Permission ABORT = CANCEL; /** - * Replaceable "Build Now" text. + * @deprecated Use {@link ParameterizedJobMixIn#BUILD_NOW_TEXT}. */ + @Deprecated public static final Message BUILD_NOW_TEXT = new Message(); /** @@ -2247,8 +2250,11 @@ public abstract class AbstractProject

,R extends A public static AbstractProject resolveForCLI( @Argument(required=true,metaVar="NAME",usage="Job name") String name) throws CmdLineException { AbstractProject item = Jenkins.getInstance().getItemByFullName(name, AbstractProject.class); - if (item==null) - throw new CmdLineException(null,Messages.AbstractItem_NoSuchJobExists(name,AbstractProject.findNearest(name).getFullName())); + if (item==null) { + AbstractProject project = AbstractProject.findNearest(name); + throw new CmdLineException(null, project == null ? Messages.AbstractItem_NoSuchJobExistsWithoutSuggestion(name) + : Messages.AbstractItem_NoSuchJobExists(name, project.getFullName())); + } return item; } diff --git a/core/src/main/java/hudson/model/Action.java b/core/src/main/java/hudson/model/Action.java index f73bd34032f670fe3b90db60797184fcd96b0e3a..9e48742986de696c08afd2167701da1723d8a701 100644 --- a/core/src/main/java/hudson/model/Action.java +++ b/core/src/main/java/hudson/model/Action.java @@ -25,6 +25,8 @@ package hudson.model; import hudson.Functions; +import javax.annotation.CheckForNull; + /** * Object that contributes additional information, behaviors, and UIs to {@link ModelObject} * (more specifically {@link Actionable} objects, which most interesting {@link ModelObject}s are.) @@ -66,6 +68,11 @@ import hudson.Functions; * (for example with {@link Build}) via XStream. In some other cases, * {@link Action}s are transient and not persisted (such as * when it's used with {@link Job}). + *

+ * The {@link Actionable#replaceAction(Action)}, {@link Actionable#addOrReplaceAction(Action)}, and + * {@link Actionable#removeAction(Action)} methods use {@link Action#equals(Object)} to determine whether to update + * or replace or remove an {@link Action}. As such, {@link Action} subclasses that provide a deep + * {@link #equals(Object)} will assist in reducing the need for unnecessary persistence. * * @author Kohsuke Kawaguchi */ @@ -90,15 +97,17 @@ public interface Action extends ModelObject { * @see Functions#isAnonymous() * @see Functions#getIconFilePath(Action) */ - String getIconFileName(); + @CheckForNull String getIconFileName(); /** * Gets the string to be displayed. * * The convention is to capitalize the first letter of each word, - * such as "Test Result". + * such as "Test Result". + * + * @return Can be null in case the action is hidden. */ - String getDisplayName(); + @CheckForNull String getDisplayName(); /** * Gets the URL path name. @@ -124,5 +133,5 @@ public interface Action extends ModelObject { * (when you do that, be sure to also return null from {@link #getIconFileName()}. * @see Functions#getActionUrl(String, Action) */ - String getUrlName(); + @CheckForNull String getUrlName(); } diff --git a/core/src/main/java/hudson/model/Actionable.java b/core/src/main/java/hudson/model/Actionable.java index 8285544821df9d98c258ea6ed0311128a2516587..84e52ea3c48b802d62515744c17120c8cad5e036 100644 --- a/core/src/main/java/hudson/model/Actionable.java +++ b/core/src/main/java/hudson/model/Actionable.java @@ -23,7 +23,7 @@ */ package hudson.model; -import hudson.ExtensionList; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.Util; import java.util.ArrayList; import java.util.Collection; @@ -32,7 +32,8 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; - +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import jenkins.model.ModelObjectWithContextMenu; import jenkins.model.TransientActionFactory; import org.kohsuke.stapler.StaplerRequest; @@ -65,23 +66,21 @@ public abstract class Actionable extends AbstractModelObject implements ModelObj * This method by default returns only persistent actions * (though some subclasses override it to return an extended unmodifiable list). * - * @return - * may be empty but never null. + * @return a possibly empty list * @deprecated Normally outside code should not call this method any more. * Use {@link #getAllActions}, or {@link #addAction}, or {@link #replaceAction}. * May still be called for compatibility reasons from subclasses predating {@link TransientActionFactory}. */ @Deprecated - public List getActions() { - if(actions == null) { - synchronized (this) { - if(actions == null) { - actions = new CopyOnWriteArrayList(); - } - } - } - return actions; - } + @Nonnull + public List getActions() { + synchronized (this) { + if(actions == null) { + actions = new CopyOnWriteArrayList(); + } + return actions; + } + } /** * Gets all actions, transient or persistent. @@ -90,61 +89,223 @@ public abstract class Actionable extends AbstractModelObject implements ModelObj * @since 1.548 */ @Exported(name="actions") + @Nonnull public final List getAllActions() { - List _actions = new ArrayList(getActions()); - for (TransientActionFactory taf : ExtensionList.lookup(TransientActionFactory.class)) { - if (taf.type().isInstance(this)) { - try { - _actions.addAll(createFor(taf)); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Could not load actions from " + taf + " for " + this, e); + List _actions = getActions(); + boolean adding = false; + for (TransientActionFactory taf : TransientActionFactory.factoriesFor(getClass(), Action.class)) { + Collection additions = createFor(taf); + if (!additions.isEmpty()) { + if (!adding) { // need to make a copy + adding = true; + _actions = new ArrayList<>(_actions); } + _actions.addAll(additions); } } return Collections.unmodifiableList(_actions); } + private Collection createFor(TransientActionFactory taf) { - return taf.createFor(taf.type().cast(this)); + try { + Collection result = taf.createFor(taf.type().cast(this)); + for (Action a : result) { + if (!taf.actionType().isInstance(a)) { + LOGGER.log(Level.WARNING, "Actions from {0} for {1} included {2} not assignable to {3}", new Object[] {taf, this, a, taf.actionType()}); + return Collections.emptySet(); + } + } + return result; + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Could not load actions from " + taf + " for " + this, e); + return Collections.emptySet(); + } } /** * Gets all actions of a specified type that contributed to this object. * * @param type The type of action to return. - * @return - * may be empty but never null. + * @return an unmodifiable, possible empty list * @see #getAction(Class) */ + @Nonnull public List getActions(Class type) { - return Util.filter(getAllActions(), type); + List _actions = Util.filter(getActions(), type); + for (TransientActionFactory taf : TransientActionFactory.factoriesFor(getClass(), type)) { + _actions.addAll(Util.filter(createFor(taf), type)); + } + return Collections.unmodifiableList(_actions); } /** * Adds a new action. - * - * The default implementation calls {@code getActions().add(a)}. + * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. + * Note: this method will always modify the actions */ - public void addAction(Action a) { - if(a==null) throw new IllegalArgumentException(); + @SuppressWarnings({"ConstantConditions","deprecation"}) + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + public void addAction(@Nonnull Action a) { + if(a==null) { + throw new IllegalArgumentException("Action must be non-null"); + } getActions().add(a); } /** - * Add an action, replacing any existing action of the (exact) same class. + * Add an action, replacing any existing actions of the (exact) same class. + * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. + * Note: this method does not affect transient actions contributed by a {@link TransientActionFactory}. + * Note: this method cannot provide concurrency control due to the backing storage being a + * {@link CopyOnWriteArrayList} so concurrent calls to any of the mutation methods may produce surprising results + * though technically consistent from the concurrency contract of {@link CopyOnWriteArrayList} (we would need + * some form of transactions or a different backing type). + * * @param a an action to add/replace * @since 1.548 + * @see #addOrReplaceAction(Action) if you want to know whether the backing {@link #actions} was modified, for + * example in cases where the caller would need to persist the {@link Actionable} in order to persist the change + * and there is a desire to elide unneccessary persistence of unmodified objects. */ - public void replaceAction(Action a) { + @SuppressWarnings({"ConstantConditions", "deprecation"}) + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + public void replaceAction(@Nonnull Action a) { + addOrReplaceAction(a); + } + + /** + * Add an action, replacing any existing actions of the (exact) same class. + * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. + * Note: this method does not affect transient actions contributed by a {@link TransientActionFactory} + * Note: this method cannot provide concurrency control due to the backing storage being a + * {@link CopyOnWriteArrayList} so concurrent calls to any of the mutation methods may produce surprising results + * though technically consistent from the concurrency contract of {@link CopyOnWriteArrayList} (we would need + * some form of transactions or a different backing type). + * + * @param a an action to add/replace + * @return {@code true} if this actions changed as a result of the call + * @since 2.29 + */ + @SuppressWarnings({"ConstantConditions", "deprecation"}) + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + public boolean addOrReplaceAction(@Nonnull Action a) { + if (a == null) { + throw new IllegalArgumentException("Action must be non-null"); + } // CopyOnWriteArrayList does not support Iterator.remove, so need to do it this way: List old = new ArrayList(1); List current = getActions(); + boolean found = false; for (Action a2 : current) { - if (a2.getClass() == a.getClass()) { + if (!found && a.equals(a2)) { + found = true; + } else if (a2.getClass() == a.getClass()) { old.add(a2); } } current.removeAll(old); - addAction(a); + if (!found) { + addAction(a); + } + return !found || !old.isEmpty(); + } + + /** + * Remove an action. + * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. + * Note: this method does not affect transient actions contributed by a {@link TransientActionFactory} + * Note: this method cannot provide concurrency control due to the backing storage being a + * {@link CopyOnWriteArrayList} so concurrent calls to any of the mutation methods may produce surprising results + * though technically consistent from the concurrency contract of {@link CopyOnWriteArrayList} (we would need + * some form of transactions or a different backing type). + * + * @param a an action to remove (if {@code null} then this will be a no-op) + * @return {@code true} if this actions changed as a result of the call + * @since 2.29 + */ + @SuppressWarnings("deprecation") + public boolean removeAction(@Nullable Action a) { + if (a == null) { + return false; + } + // CopyOnWriteArrayList does not support Iterator.remove, so need to do it this way: + return getActions().removeAll(Collections.singleton(a)); + } + + /** + * Removes any actions of the specified type. + * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. + * Note: this method does not affect transient actions contributed by a {@link TransientActionFactory} + * Note: this method cannot provide concurrency control due to the backing storage being a + * {@link CopyOnWriteArrayList} so concurrent calls to any of the mutation methods may produce surprising results + * though technically consistent from the concurrency contract of {@link CopyOnWriteArrayList} (we would need + * some form of transactions or a different backing type). + * + * @param clazz the type of actions to remove + * @return {@code true} if this actions changed as a result of the call + * @since 2.29 + */ + @SuppressWarnings({"ConstantConditions","deprecation"}) + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + public boolean removeActions(@Nonnull Class clazz) { + if (clazz == null) { + throw new IllegalArgumentException("Action type must be non-null"); + } + // CopyOnWriteArrayList does not support Iterator.remove, so need to do it this way: + List old = new ArrayList(); + List current = getActions(); + for (Action a : current) { + if (clazz.isInstance(a)) { + old.add(a); + } + } + return current.removeAll(old); + } + + /** + * Replaces any actions of the specified type by the supplied action. + * Note: calls to {@link #getAllActions()} that happen before calls to this method may not see the update. + * Note: this method does not affect transient actions contributed by a {@link TransientActionFactory} + * Note: this method cannot provide concurrency control due to the backing storage being a + * {@link CopyOnWriteArrayList} so concurrent calls to any of the mutation methods may produce surprising results + * though technically consistent from the concurrency contract of {@link CopyOnWriteArrayList} (we would need + * some form of transactions or a different backing type). + * + * @param clazz the type of actions to replace (note that the action you are replacing this with need not extend + * this class) + * @param a the action to replace with + * @return {@code true} if this actions changed as a result of the call + * @since 2.29 + */ + @SuppressWarnings({"ConstantConditions", "deprecation"}) + @SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE") + public boolean replaceActions(@Nonnull Class clazz, @Nonnull Action a) { + if (clazz == null) { + throw new IllegalArgumentException("Action type must be non-null"); + } + if (a == null) { + throw new IllegalArgumentException("Action must be non-null"); + } + // CopyOnWriteArrayList does not support Iterator.remove, so need to do it this way: + List old = new ArrayList(); + List current = getActions(); + boolean found = false; + for (Action a1 : current) { + if (!found) { + if (a.equals(a1)) { + found = true; + } else if (clazz.isInstance(a1)) { + old.add(a1); + } + } else if (clazz.isInstance(a1) && !a.equals(a1)) { + old.add(a1); + } + } + current.removeAll(old); + if (!found) { + addAction(a); + } + return !(old.isEmpty() && found); } /** @deprecated No clear purpose, since subclasses may have overridden {@link #getActions}, and does not consider {@link TransientActionFactory}. */ @@ -162,9 +323,20 @@ public abstract class Actionable extends AbstractModelObject implements ModelObj * @see #getActions(Class) */ public T getAction(Class type) { - for (Action a : getAllActions()) - if (type.isInstance(a)) + // Shortcut: if the persisted list has one, return it. + for (Action a : getActions()) { + if (type.isInstance(a)) { return type.cast(a); + } + } + // Otherwise check transient factories. + for (TransientActionFactory taf : TransientActionFactory.factoriesFor(getClass(), type)) { + for (Action a : createFor(taf)) { + if (type.isInstance(a)) { + return type.cast(a); + } + } + } return null; } diff --git a/core/src/main/java/hudson/model/AdministrativeMonitor.java b/core/src/main/java/hudson/model/AdministrativeMonitor.java index a8e555409214ac44570ffbd1384d8c53b887630d..0bdc8a97bc18b9cab09dbca8e559273e67cf2ae4 100644 --- a/core/src/main/java/hudson/model/AdministrativeMonitor.java +++ b/core/src/main/java/hudson/model/AdministrativeMonitor.java @@ -28,7 +28,6 @@ import hudson.ExtensionList; import hudson.Extension; import hudson.ExtensionPoint.LegacyInstancesAreScopedToHudson; import hudson.triggers.SCMTrigger; -import hudson.triggers.TimerTrigger; import java.util.Set; import java.io.IOException; diff --git a/core/src/main/java/hudson/model/AllView.java b/core/src/main/java/hudson/model/AllView.java index 6cf8f2448d7c10734a06b54dbba4f3cf407ec92b..939c5fd2ebd8a0bbf474a0135e79ed029f558fab 100644 --- a/core/src/main/java/hudson/model/AllView.java +++ b/core/src/main/java/hudson/model/AllView.java @@ -23,8 +23,16 @@ */ package hudson.model; +import java.util.List; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import jenkins.util.SystemProperties; +import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -43,6 +51,21 @@ import org.kohsuke.stapler.interceptor.RequirePOST; * @since 1.269 */ public class AllView extends View { + + /** + * The name of the default {@link AllView}. An {@link AllView} with this name will get a localized display name. + * Other {@link AllView} instances will be assumed to have been created by the user and thus will use the + * name the user created them with. + * + * @since 2.37 + */ + public static final String DEFAULT_VIEW_NAME = "all"; + + /** + * Our logger. + */ + private static final Logger LOGGER = Logger.getLogger(AllView.class.getName()); + @DataBoundConstructor public AllView(String name) { super(name); @@ -63,6 +86,11 @@ public class AllView extends View { return true; } + @Override + public String getDisplayName() { + return DEFAULT_VIEW_NAME.equals(name) ? Messages.Hudson_ViewName() : name; + } + @RequirePOST @Override public Item doCreateItem(StaplerRequest req, StaplerResponse rsp) @@ -88,13 +116,73 @@ public class AllView extends View { // noop } - @Extension + /** + * Corrects the name of the {@link AllView} if and only if the {@link AllView} is the primary view and + * its name is one of the localized forms of {@link Messages#_Hudson_ViewName()} and the user has not opted out of + * fixing the view name by setting the system property {@code hudson.mode.AllView.JENKINS-38606} to {@code false}. + * Use this method to round-trip the primary view name, e.g. + * {@code primaryView = applyJenkins38606Fixup(views, primaryView)} + *

+ * NOTE: we can only fix the localized name of an {@link AllView} if it is the primary view as otherwise urls + * would change, whereas the primary view is special and does not normally get accessed by the + * {@code /view/_name_} url. (Also note that there are some cases where the primary view will get accessed by + * its {@code /view/_name_} url which will then fall back to the primary view) + * + * @param views the list of views. + * @param primaryView the current primary view name. + * @return the primary view name - this will be the same as the provided primary view name unless a JENKINS-38606 + * matching name is detected, in which case this will be the new name of the primary view. + * @since 2.37 + */ + @Nonnull + public static String migrateLegacyPrimaryAllViewLocalizedName(@Nonnull List views, + @Nonnull String primaryView) { + if (DEFAULT_VIEW_NAME.equals(primaryView)) { + // modern name, we are safe + return primaryView; + } + if (SystemProperties.getBoolean(AllView.class.getName()+".JENKINS-38606", true)) { + AllView allView = null; + for (View v : views) { + if (DEFAULT_VIEW_NAME.equals(v.getViewName())) { + // name conflict, we cannot rename the all view anyway + return primaryView; + } + if (StringUtils.equals(v.getViewName(), primaryView)) { + if (v instanceof AllView) { + allView = (AllView) v; + } else { + // none of our business fixing as we can only safely fix the primary view + return primaryView; + } + } + } + if (allView != null) { + // the primary view is an AllView but using a non-default name + for (Locale l : Locale.getAvailableLocales()) { + if (primaryView.equals(Messages._Hudson_ViewName().toString(l))) { + // bingo JENKINS-38606 detected + LOGGER.log(Level.INFO, + "JENKINS-38606 detected for AllView in {0}; renaming view from {1} to {2}", + new Object[]{allView.owner.getUrl(), DEFAULT_VIEW_NAME}); + allView.name = DEFAULT_VIEW_NAME; + return DEFAULT_VIEW_NAME; + } + } + } + } + return primaryView; + } + + @Extension @Symbol("all") public static final class DescriptorImpl extends ViewDescriptor { @Override - public boolean isInstantiable() { - for (View v : Stapler.getCurrentRequest().findAncestorObject(ViewGroup.class).getViews()) - if(v instanceof AllView) + public boolean isApplicableIn(ViewGroup owner) { + for (View v : owner.getViews()) { + if (v instanceof AllView) { return false; + } + } return true; } diff --git a/core/src/main/java/hudson/model/AperiodicWork.java b/core/src/main/java/hudson/model/AperiodicWork.java index 56b0804da1ec2f949193a67c93d99e23db88ea70..fbd4f2c4f7a3da987d57e4f61168d453647ff667 100644 --- a/core/src/main/java/hudson/model/AperiodicWork.java +++ b/core/src/main/java/hudson/model/AperiodicWork.java @@ -27,11 +27,9 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.init.Initializer; import hudson.triggers.SafeTimerTask; -import jenkins.model.Jenkins; import jenkins.util.Timer; import java.util.Random; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; diff --git a/core/src/main/java/hudson/model/Api.java b/core/src/main/java/hudson/model/Api.java index 258f48ffea95f243d6d47b2f831e356d51286f9f..6878a4284a1d884c957e1c7aefa8307272f4f504 100644 --- a/core/src/main/java/hudson/model/Api.java +++ b/core/src/main/java/hudson/model/Api.java @@ -169,8 +169,7 @@ public class Api extends AbstractModelObject { } // switch to gzipped output - OutputStream o = rsp.getCompressedOutputStream(req); - try { + try (OutputStream o = rsp.getCompressedOutputStream(req)) { if (isSimpleOutput(result)) { // simple output allowed rsp.setContentType("text/plain;charset=UTF-8"); @@ -182,8 +181,6 @@ public class Api extends AbstractModelObject { // otherwise XML rsp.setContentType("application/xml;charset=UTF-8"); new XMLWriter(o).write(result); - } finally { - o.close(); } } diff --git a/core/src/main/java/hudson/model/AsyncAperiodicWork.java b/core/src/main/java/hudson/model/AsyncAperiodicWork.java index f46dd33b61d835eec945fec60f76975809d9c3de..069a4bb05f2f2818e14232fd6b07746efd051bba 100644 --- a/core/src/main/java/hudson/model/AsyncAperiodicWork.java +++ b/core/src/main/java/hudson/model/AsyncAperiodicWork.java @@ -25,14 +25,13 @@ package hudson.model; import hudson.security.ACL; import hudson.util.StreamTaskListener; - import java.io.File; import java.io.IOException; +import java.util.Date; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; - import jenkins.model.Jenkins; -import org.acegisecurity.context.SecurityContext; -import org.acegisecurity.context.SecurityContextHolder; +import jenkins.util.SystemProperties; /** * {@link AperiodicWork} that takes a long time to run. Similar to {@link AsyncPeriodicWork}, see {@link AsyncPeriodicWork} for @@ -42,8 +41,48 @@ import org.acegisecurity.context.SecurityContextHolder; * @since 1.410 */ public abstract class AsyncAperiodicWork extends AperiodicWork { - - /** + /** + * The default number of minutes after which to try and rotate the log file used by {@link #createListener()}. + * This value is controlled by the system property {@code hudson.model.AsyncAperiodicWork.logRotateMinutes}. + * Each individual AsyncAperiodicWork can also have a per-extension override using the system property + * based on their fully qualified class name with {@code .logRotateMinutes} appended. + * + * @since 1.651 + */ + private static final long LOG_ROTATE_MINUTES = SystemProperties.getLong(AsyncAperiodicWork.class.getName() + + ".logRotateMinutes", TimeUnit.DAYS.toMinutes(1)); + /** + * The default file size after which to try and rotate the log file used by {@link #createListener()}. + * A value of {@code -1L} disables rotation based on file size. + * This value is controlled by the system property {@code hudson.model.AsyncAperiodicWork.logRotateSize}. + * Each individual AsyncAperiodicWork can also have a per-extension override using the system property + * based on their fully qualified class name with {@code .logRotateSize} appended. + * + * @since 1.651 + */ + private static final long LOG_ROTATE_SIZE = SystemProperties.getLong(AsyncAperiodicWork.class.getName() + ".logRotateSize", + -1L); + /** + * The number of milliseconds (since startup or previous rotation) after which to try and rotate the log file. + * + * @since 1.651 + */ + private final long logRotateMillis; + /** + * {@code -1L} disabled file size based log rotation, otherwise when starting an {@link #execute(TaskListener)}, + * if the log file size is above this number of bytes then the log file will be rotated beforehand. + * + * @since 1.651 + */ + private final long logRotateSize; + /** + * The last time the log files were rotated. On start-up this will be {@link Long#MIN_VALUE} to ensure that the + * logs are always rotated every time Jenkins starts up to make it easier to correlate events with the main log. + * + * @since 1.651 + */ + private long lastRotateMillis = Long.MIN_VALUE; + /** * Name of the work. */ public final String name; @@ -52,6 +91,9 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { protected AsyncAperiodicWork(String name) { this.name = name; + this.logRotateMillis = TimeUnit.MINUTES.toMillis( + SystemProperties.getLong(getClass().getName()+".logRotateMinutes", LOG_ROTATE_MINUTES)); + this.logRotateSize = SystemProperties.getLong(getClass().getName() +".logRotateSize", LOG_ROTATE_SIZE); } /** @@ -61,16 +103,18 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { public final void doAperiodicRun() { try { if(thread!=null && thread.isAlive()) { - logger.log(Level.INFO, name+" thread is still running. Execution aborted."); + logger.log(getSlowLoggingLevel(), "{0} thread is still running. Execution aborted.", name); return; } thread = new Thread(new Runnable() { public void run() { - logger.log(Level.INFO, "Started "+name); + logger.log(getNormalLoggingLevel(), "Started {0}", name); long startTime = System.currentTimeMillis(); + long stopTime; StreamTaskListener l = createListener(); try { + l.getLogger().printf("Started at %tc%n", new Date(startTime)); ACL.impersonate(ACL.SYSTEM); execute(l); @@ -79,11 +123,16 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { } catch (InterruptedException e) { e.printStackTrace(l.fatalError("aborted")); } finally { - l.closeQuietly(); + stopTime = System.currentTimeMillis(); + try { + l.getLogger().printf("Finished at %tc. %dms%n", new Date(stopTime), stopTime - startTime); + } finally { + l.closeQuietly(); + } } - logger.log(Level.INFO, "Finished "+name+". "+ - (System.currentTimeMillis()-startTime)+" ms"); + logger.log(getNormalLoggingLevel(), "Finished {0}. {1,number} ms", + new Object[]{name, stopTime - startTime}); } },name+" thread"); thread.start(); @@ -93,8 +142,54 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { } protected StreamTaskListener createListener() { + File f = getLogFile(); + if (!f.getParentFile().isDirectory()) { + if (!f.getParentFile().mkdirs()) { + logger.log(getErrorLoggingLevel(), "Could not create directory {0}", f.getParentFile()); + } + } + if (f.isFile()) { + if ((lastRotateMillis + logRotateMillis < System.currentTimeMillis()) + || (logRotateSize > 0 && f.length() > logRotateSize)) { + lastRotateMillis = System.currentTimeMillis(); + File prev = null; + for (int i = 5; i >= 0; i--) { + File curr = i == 0 ? f : new File(f.getParentFile(), f.getName() + "." + i); + if (curr.isFile()) { + if (prev != null && !prev.exists()) { + if (!curr.renameTo(prev)) { + logger.log(getErrorLoggingLevel(), "Could not rotate log files {0} to {1}", + new Object[]{curr, prev}); + } + } else { + if (!curr.delete()) { + logger.log(getErrorLoggingLevel(), "Could not delete log file {0} to enable rotation", + curr); + } + } + } + prev = curr; + } + } + } else { + lastRotateMillis = System.currentTimeMillis(); + // migrate old log files the first time we start-up + File oldFile = new File(Jenkins.getActiveInstance().getRootDir(), f.getName()); + if (oldFile.isFile()) { + File newFile = new File(f.getParentFile(), f.getName() + ".1"); + if (!newFile.isFile()) { + // if there has never been rotation then this is the first time + if (oldFile.renameTo(newFile)) { + logger.log(getNormalLoggingLevel(), "Moved {0} to {1}", new Object[]{oldFile, newFile}); + } else { + logger.log(getErrorLoggingLevel(), "Could not move {0} to {1}", + new Object[]{oldFile, newFile}); + } + } + } + } try { - return new StreamTaskListener(getLogFile()); + return new StreamTaskListener(f, true, null); } catch (IOException e) { throw new Error(e); } @@ -104,7 +199,37 @@ public abstract class AsyncAperiodicWork extends AperiodicWork { * Determines the log file that records the result of this task. */ protected File getLogFile() { - return new File(Jenkins.getInstance().getRootDir(),name+".log"); + return new File(Jenkins.getActiveInstance().getRootDir(),"logs/tasks/"+name+".log"); + } + + /** + * Returns the logging level at which normal messages are displayed. + * + * @return The logging level. + * @since 1.651 + */ + protected Level getNormalLoggingLevel() { + return Level.INFO; + } + + /** + * Returns the logging level at which previous task still executing messages is displayed. + * + * @return The logging level. + * @since 1.651 + */ + protected Level getSlowLoggingLevel() { + return getNormalLoggingLevel(); + } + + /** + * Returns the logging level at which error messages are displayed. + * + * @return The logging level. + * @since 1.651 + */ + protected Level getErrorLoggingLevel() { + return Level.SEVERE; } /** diff --git a/core/src/main/java/hudson/model/AsyncPeriodicWork.java b/core/src/main/java/hudson/model/AsyncPeriodicWork.java index 9444887b5b1c262818920df69006021e291e5559..d88413f4127646d21972ec59884f4eac07541392 100644 --- a/core/src/main/java/hudson/model/AsyncPeriodicWork.java +++ b/core/src/main/java/hudson/model/AsyncPeriodicWork.java @@ -2,12 +2,14 @@ package hudson.model; import hudson.security.ACL; import hudson.util.StreamTaskListener; -import jenkins.model.Jenkins; - import java.io.File; import java.io.IOException; +import java.util.Date; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.LogRecord; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; /** * {@link PeriodicWork} that takes a long time to run. @@ -20,6 +22,46 @@ import java.util.logging.LogRecord; * @author Kohsuke Kawaguchi */ public abstract class AsyncPeriodicWork extends PeriodicWork { + /** + * The default number of minutes after which to try and rotate the log file used by {@link #createListener()}. + * This value is controlled by the system property {@code hudson.model.AsyncPeriodicWork.logRotateMinutes}. + * Each individual AsyncPeriodicWork can also have a per-extension override using the system property + * based on their fully qualified class name with {@code .logRotateMinutes} appended. + * + * @since 1.651 + */ + private static final long LOG_ROTATE_MINUTES = SystemProperties.getLong(AsyncPeriodicWork.class.getName() + ".logRotateMinutes", + TimeUnit.DAYS.toMinutes(1)); + /** + * The default file size after which to try and rotate the log file used by {@link #createListener()}. + * A value of {@code -1L} disables rotation based on file size. + * This value is controlled by the system property {@code hudson.model.AsyncPeriodicWork.logRotateSize}. + * Each individual AsyncPeriodicWork can also have a per-extension override using the system property + * based on their fully qualified class name with {@code .logRotateSize} appended. + * + * @since 1.651 + */ + private static final long LOG_ROTATE_SIZE = SystemProperties.getLong(AsyncPeriodicWork.class.getName() + ".logRotateSize", -1L); + /** + * The number of milliseconds (since startup or previous rotation) after which to try and rotate the log file. + * + * @since 1.651 + */ + private final long logRotateMillis; + /** + * {@code -1L} disabled file size based log rotation, otherwise when starting an {@link #execute(TaskListener)}, + * if the log file size is above this number of bytes then the log file will be rotated beforehand. + * + * @since 1.651 + */ + private final long logRotateSize; + /** + * The last time the log files were rotated. On start-up this will be {@link Long#MIN_VALUE} to ensure that the + * logs are always rotated every time Jenkins starts up to make it easier to correlate events with the main log. + * + * @since 1.651 + */ + private long lastRotateMillis = Long.MIN_VALUE; /** * Human readable name of the work. */ @@ -29,6 +71,9 @@ public abstract class AsyncPeriodicWork extends PeriodicWork { protected AsyncPeriodicWork(String name) { this.name = name; + this.logRotateMillis = TimeUnit.MINUTES.toMillis( + SystemProperties.getLong(getClass().getName() + ".logRotateMinutes", LOG_ROTATE_MINUTES)); + this.logRotateSize = SystemProperties.getLong(getClass().getName() + ".logRotateSize", LOG_ROTATE_SIZE); } /** @@ -45,9 +90,11 @@ public abstract class AsyncPeriodicWork extends PeriodicWork { public void run() { logger.log(getNormalLoggingLevel(), "Started {0}", name); long startTime = System.currentTimeMillis(); + long stopTime; StreamTaskListener l = createListener(); try { + l.getLogger().printf("Started at %tc%n", new Date(startTime)); ACL.impersonate(ACL.SYSTEM); execute(l); @@ -56,11 +103,16 @@ public abstract class AsyncPeriodicWork extends PeriodicWork { } catch (InterruptedException e) { e.printStackTrace(l.fatalError("aborted")); } finally { - l.closeQuietly(); + stopTime = System.currentTimeMillis(); + try { + l.getLogger().printf("Finished at %tc. %dms%n", new Date(stopTime), stopTime - startTime); + } finally { + l.closeQuietly(); + } } logger.log(getNormalLoggingLevel(), "Finished {0}. {1,number} ms", - new Object[]{name, (System.currentTimeMillis()-startTime)}); + new Object[]{name, stopTime - startTime}); } },name+" thread"); thread.start(); @@ -73,8 +125,54 @@ public abstract class AsyncPeriodicWork extends PeriodicWork { } protected StreamTaskListener createListener() { + File f = getLogFile(); + if (!f.getParentFile().isDirectory()) { + if (!f.getParentFile().mkdirs()) { + logger.log(getErrorLoggingLevel(), "Could not create directory {0}", f.getParentFile()); + } + } + if (f.isFile()) { + if ((lastRotateMillis + logRotateMillis < System.currentTimeMillis()) + || (logRotateSize > 0 && f.length() > logRotateSize)) { + lastRotateMillis = System.currentTimeMillis(); + File prev = null; + for (int i = 5; i >= 0; i--) { + File curr = i == 0 ? f : new File(f.getParentFile(), f.getName() + "." + i); + if (curr.isFile()) { + if (prev != null && !prev.exists()) { + if (!curr.renameTo(prev)) { + logger.log(getErrorLoggingLevel(), "Could not rotate log files {0} to {1}", + new Object[]{curr, prev}); + } + } else { + if (!curr.delete()) { + logger.log(getErrorLoggingLevel(), "Could not delete log file {0} to enable rotation", + curr); + } + } + } + prev = curr; + } + } + } else { + lastRotateMillis = System.currentTimeMillis(); + // migrate old log files the first time we start-up + File oldFile = new File(Jenkins.getActiveInstance().getRootDir(), f.getName()); + if (oldFile.isFile()) { + File newFile = new File(f.getParentFile(), f.getName() + ".1"); + if (!newFile.isFile()) { + // if there has never been rotation then this is the first time + if (oldFile.renameTo(newFile)) { + logger.log(getNormalLoggingLevel(), "Moved {0} to {1}", new Object[]{oldFile, newFile}); + } else { + logger.log(getErrorLoggingLevel(), "Could not move {0} to {1}", + new Object[]{oldFile, newFile}); + } + } + } + } try { - return new StreamTaskListener(getLogFile()); + return new StreamTaskListener(f, true, null); } catch (IOException e) { throw new Error(e); } @@ -84,7 +182,7 @@ public abstract class AsyncPeriodicWork extends PeriodicWork { * Determines the log file that records the result of this task. */ protected File getLogFile() { - return new File(Jenkins.getInstance().getRootDir(),name+".log"); + return new File(Jenkins.getActiveInstance().getRootDir(),"logs/tasks/"+name+".log"); } /** diff --git a/core/src/main/java/hudson/model/BooleanParameterDefinition.java b/core/src/main/java/hudson/model/BooleanParameterDefinition.java index 9fca7351ad90766f2de69dbee9eaac18081d12cd..15cb4ec80aee93663f490f5f86f1eb974698bce1 100644 --- a/core/src/main/java/hudson/model/BooleanParameterDefinition.java +++ b/core/src/main/java/hudson/model/BooleanParameterDefinition.java @@ -23,6 +23,7 @@ */ package hudson.model; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; import net.sf.json.JSONObject; @@ -72,7 +73,9 @@ public class BooleanParameterDefinition extends SimpleParameterDefinition { return new BooleanParameterValue(getName(), defaultValue, getDescription()); } - @Extension + // unlike all the other ParameterDescriptors, using 'booleanParam' as the primary + // to avoid picking the Java reserved word "boolean" as the primary identifier + @Extension @Symbol({"booleanParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/BuildStepListener.java b/core/src/main/java/hudson/model/BuildStepListener.java index a37cb8f67abfa6f37622d042ff09038207f4a6dd..e0ee3efe29ce12313b1ff81abfbc11c51d7d0905 100644 --- a/core/src/main/java/hudson/model/BuildStepListener.java +++ b/core/src/main/java/hudson/model/BuildStepListener.java @@ -3,7 +3,6 @@ package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.tasks.BuildStep; -import jenkins.model.Jenkins; /** * Receives events that happen as a build executes {@link BuildStep}s. diff --git a/core/src/main/java/hudson/model/BuildTimelineWidget.java b/core/src/main/java/hudson/model/BuildTimelineWidget.java index 9b8bc849b860100e957e392b5aa4e094ef8d3716..31810b5f5e939e8409eb12422b150b3bffb2d91b 100644 --- a/core/src/main/java/hudson/model/BuildTimelineWidget.java +++ b/core/src/main/java/hudson/model/BuildTimelineWidget.java @@ -62,8 +62,8 @@ public class BuildTimelineWidget { TimelineEventList result = new TimelineEventList(); for (Run r : builds.byTimestamp(min,max)) { Event e = new Event(); - e.start = r.getTime(); - e.end = new Date(r.timestamp+r.getDuration()); + e.start = new Date(r.getStartTimeInMillis()); + e.end = new Date(r.getStartTimeInMillis()+r.getDuration()); e.title = r.getFullDisplayName(); // what to put in the description? // e.description = "Longish description of event "+r.getFullDisplayName(); diff --git a/core/src/main/java/hudson/model/BuildVariableContributor.java b/core/src/main/java/hudson/model/BuildVariableContributor.java index 15baad759088c83ce5deb3cde44e56e7b4103e68..83046baa5440d2c5f7c489db65c040ce54da5009 100644 --- a/core/src/main/java/hudson/model/BuildVariableContributor.java +++ b/core/src/main/java/hudson/model/BuildVariableContributor.java @@ -27,7 +27,6 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.tasks.Builder; import hudson.tasks.Publisher; -import jenkins.model.Jenkins; import java.util.Map; diff --git a/core/src/main/java/hudson/model/Cause.java b/core/src/main/java/hudson/model/Cause.java index 2ee6ba7982730ee1a563224c80e75cf8a6c1270b..bca7831012f8ec499187c35bdbd52b134e64b1bb 100644 --- a/core/src/main/java/hudson/model/Cause.java +++ b/core/src/main/java/hudson/model/Cause.java @@ -37,6 +37,7 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext; import hudson.Util; import java.io.IOException; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; @@ -212,12 +213,10 @@ public abstract class Cause { final UpstreamCause o = (UpstreamCause) rhs; - if (upstreamBuild != o.upstreamBuild) return false; - if (!upstreamCauses.equals(o.upstreamCauses)) return false; - if (upstreamUrl == null ? o.upstreamUrl != null : !upstreamUrl.equals(o.upstreamUrl)) return false; - if (upstreamProject == null ? o.upstreamProject != null : !upstreamProject.equals(o.upstreamProject)) return false; - - return true; + return Objects.equals(upstreamBuild, o.upstreamBuild) && + Objects.equals(upstreamCauses, o.upstreamCauses) && + Objects.equals(upstreamUrl, o.upstreamUrl) && + Objects.equals(upstreamProject, o.upstreamProject); } /** @@ -225,12 +224,7 @@ public abstract class Cause { */ @Override public int hashCode() { - - int hashCode = 17; - hashCode = hashCode * 31 + upstreamCauses.hashCode(); - hashCode = hashCode * 31 + upstreamBuild; - hashCode = hashCode * 31 + (upstreamUrl == null ? 0 : upstreamUrl.hashCode ()); - return hashCode * 31 + (upstreamProject == null ? 0 : upstreamProject.hashCode ()); + return Objects.hash(upstreamCauses, upstreamBuild, upstreamUrl, upstreamProject); } private @Nonnull Cause trim(@Nonnull Cause c, int depth, Set traversed) { @@ -430,13 +424,12 @@ public abstract class Cause { @Override public boolean equals(Object o) { - return o instanceof UserIdCause && Arrays.equals(new Object[]{userId}, - new Object[]{((UserIdCause) o).userId}); + return o instanceof UserIdCause && Objects.equals(userId, ((UserIdCause) o).userId); } @Override public int hashCode() { - return 295 + (this.userId != null ? this.userId.hashCode() : 0); + return Objects.hash(userId); } } @@ -473,16 +466,12 @@ public abstract class Cause { @Override public boolean equals(Object o) { - return o instanceof RemoteCause && Arrays.equals(new Object[] {addr, note}, - new Object[] {((RemoteCause)o).addr, ((RemoteCause)o).note}); + return o instanceof RemoteCause && Objects.equals(addr, ((RemoteCause) o).addr) && Objects.equals(note, ((RemoteCause) o).note); } @Override public int hashCode() { - int hash = 5; - hash = 83 * hash + (this.addr != null ? this.addr.hashCode() : 0); - hash = 83 * hash + (this.note != null ? this.note.hashCode() : 0); - return hash; + return Objects.hash(addr, note); } } } diff --git a/core/src/main/java/hudson/model/CauseAction.java b/core/src/main/java/hudson/model/CauseAction.java index 252c91c722cbba7ad0dc081bfadbf74c666862de..b065715db852731b41653b85f987e2a57847f12b 100644 --- a/core/src/main/java/hudson/model/CauseAction.java +++ b/core/src/main/java/hudson/model/CauseAction.java @@ -34,6 +34,7 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -47,35 +48,62 @@ public class CauseAction implements FoldableAction, RunAction2 { @Deprecated // there can be multiple causes, so this is deprecated private transient Cause cause; - - private List causes = new ArrayList(); + + /** @deprecated JENKINS-33467 inefficient */ + @Deprecated + private transient List causes; + + private Map causeBag = new LinkedHashMap<>(); public CauseAction(Cause c) { - this.causes.add(c); + this.causeBag.put(c, 1); } + private void addCause(Cause c) { + synchronized (causeBag) { + Integer cnt = causeBag.get(c); + causeBag.put(c, cnt == null ? 1 : cnt + 1); + } + } + private void addCauses(Collection causes) { + for (Cause cause : causes) { + addCause(cause); + } + } + public CauseAction(Cause... c) { this(Arrays.asList(c)); } public CauseAction(Collection causes) { - this.causes.addAll(causes); + addCauses(causes); } public CauseAction(CauseAction ca) { - this.causes.addAll(ca.causes); + addCauses(ca.getCauses()); } - + + /** + * Lists all causes of this build. + * Note that the current implementation does not preserve insertion order of duplicates. + * @return an immutable list; + * to create an action with multiple causes use either of the constructors that support this; + * to append causes retroactively to a build you must create a new {@link CauseAction} and replace the old + */ @Exported(visibility=2) public List getCauses() { - return causes; + List r = new ArrayList<>(); + for (Map.Entry entry : causeBag.entrySet()) { + r.addAll(Collections.nCopies(entry.getValue(), entry.getKey())); + } + return Collections.unmodifiableList(r); } /** * Finds the cause of the specific type. */ public T findCause(Class type) { - for (Cause c : causes) + for (Cause c : causeBag.keySet()) if (type.isInstance(c)) return type.cast(c); return null; @@ -99,14 +127,7 @@ public class CauseAction implements FoldableAction, RunAction2 { * @return Map of Cause to number of occurrences of that Cause */ public Map getCauseCounts() { - Map result = new LinkedHashMap(); - for (Cause c : causes) { - if (c != null) { - Integer i = result.get(c); - result.put(c, i == null ? 1 : i.intValue() + 1); - } - } - return result; + return Collections.unmodifiableMap(causeBag); } /** @@ -115,12 +136,14 @@ public class CauseAction implements FoldableAction, RunAction2 { */ @Deprecated public String getShortDescription() { - if(causes.isEmpty()) return "N/A"; - return causes.get(0).getShortDescription(); + if (causeBag.isEmpty()) { + return "N/A"; + } + return causeBag.keySet().iterator().next().getShortDescription(); } @Override public void onLoad(Run owner) { - for (Cause c : causes) { + for (Cause c : causeBag.keySet()) { if (c != null) { c.onLoad(owner); } @@ -131,7 +154,7 @@ public class CauseAction implements FoldableAction, RunAction2 { * When hooked up to build, notify {@link Cause}s. */ @Override public void onAttached(Run owner) { - for (Cause c : causes) { + for (Cause c : causeBag.keySet()) { if (c != null) { c.onAddedTo(owner); } @@ -141,7 +164,7 @@ public class CauseAction implements FoldableAction, RunAction2 { public void foldIntoExisting(hudson.model.Queue.Item item, Task owner, List otherActions) { CauseAction existing = item.getAction(CauseAction.class); if (existing!=null) { - existing.causes.addAll(this.causes); + existing.addCauses(getCauses()); return; } // no CauseAction found, so add a copy of this one @@ -153,9 +176,19 @@ public class CauseAction implements FoldableAction, RunAction2 { @Override protected void callback(CauseAction ca, UnmarshallingContext context) { // if we are being read in from an older version if (ca.cause != null) { - if (ca.causes == null) ca.causes = new ArrayList(); - ca.causes.add(ca.cause); + if (ca.causeBag == null) { + ca.causeBag = new LinkedHashMap<>(); + } + ca.addCause(ca.cause); OldDataMonitor.report(context, "1.288"); + ca.cause = null; + } else if (ca.causes != null) { + if (ca.causeBag == null) { + ca.causeBag = new LinkedHashMap<>(); + } + ca.addCauses(ca.causes); + OldDataMonitor.report(context, "1.653"); + ca.causes = null; } } } diff --git a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java index c13137d62a7b2f833497b302cb66960d74c17936..964d05a214281871518eda61469d219787fb2bd1 100644 --- a/core/src/main/java/hudson/model/ChoiceParameterDefinition.java +++ b/core/src/main/java/hudson/model/ChoiceParameterDefinition.java @@ -1,6 +1,7 @@ package hudson.model; import hudson.util.FormValidation; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; @@ -17,20 +18,24 @@ import java.util.Arrays; * @author huybrechts */ public class ChoiceParameterDefinition extends SimpleParameterDefinition { - public static final String CHOICES_DELIMETER = "\\r?\\n"; + public static final String CHOICES_DELIMITER = "\\r?\\n"; + + @Deprecated + public static final String CHOICES_DELIMETER = CHOICES_DELIMITER; + private final List choices; private final String defaultValue; public static boolean areValidChoices(String choices) { String strippedChoices = choices.trim(); - return !StringUtils.isEmpty(strippedChoices) && strippedChoices.split(CHOICES_DELIMETER).length > 0; + return !StringUtils.isEmpty(strippedChoices) && strippedChoices.split(CHOICES_DELIMITER).length > 0; } @DataBoundConstructor public ChoiceParameterDefinition(String name, String choices, String description) { super(name, description); - this.choices = Arrays.asList(choices.split(CHOICES_DELIMETER)); + this.choices = Arrays.asList(choices.split(CHOICES_DELIMITER)); defaultValue = null; } @@ -87,7 +92,7 @@ public class ChoiceParameterDefinition extends SimpleParameterDefinition { return checkValue(new StringParameterValue(getName(), value, getDescription())); } - @Extension + @Extension @Symbol({"choice","choiceParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/Computer.java b/core/src/main/java/hudson/model/Computer.java index 1f9f94a72159c052463ceb39283010c1ac4e2c6f..f372a5413c066749e02be0274394386708498a19 100644 --- a/core/src/main/java/hudson/model/Computer.java +++ b/core/src/main/java/hudson/model/Computer.java @@ -2,7 +2,8 @@ * The MIT License * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, - * Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts, CloudBees, Inc. + * Red Hat, Inc., Seiji Sogabe, Stephen Connolly, Thomas J. Black, Tom Huybrechts, + * CloudBees, Inc., Christopher Simons * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,10 +25,10 @@ */ package hudson.model; -import edu.umd.cs.findbugs.annotations.OverrideMustInvoke; -import edu.umd.cs.findbugs.annotations.When; import hudson.EnvVars; +import hudson.Extension; import hudson.Launcher.ProcStarter; +import jenkins.util.SystemProperties; import hudson.Util; import hudson.cli.declarative.CLIMethod; import hudson.cli.declarative.CLIResolver; @@ -62,10 +63,13 @@ import hudson.util.RunList; import hudson.util.Futures; import hudson.util.NamingThreadFactory; import jenkins.model.Jenkins; -import jenkins.model.queue.AsynchronousExecution; import jenkins.util.ContextResettingExecutorService; import jenkins.security.MasterToSlaveCallable; + +import org.jenkins.ui.icon.Icon; +import org.jenkins.ui.icon.IconSet; import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; @@ -82,8 +86,10 @@ import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.args4j.Option; import org.kohsuke.stapler.interceptor.RequirePOST; +import javax.annotation.OverridingMethodsMustInvokeSuper; import javax.annotation.concurrent.GuardedBy; import javax.servlet.ServletException; + import java.io.File; import java.io.FilenameFilter; import java.io.IOException; @@ -105,6 +111,7 @@ import java.net.NetworkInterface; import java.net.Inet4Address; import java.util.regex.Matcher; import java.util.regex.Pattern; + import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -261,13 +268,6 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces return Collections.unmodifiableList(result); } - @SuppressWarnings("deprecation") - @Override - public void addAction(Action a) { - if(a==null) throw new IllegalArgumentException(); - super.getActions().add(a); - } - /** * This is where the log from the remote agent goes. * The method also creates a log directory if required. @@ -278,7 +278,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } /** - * Directory where rotated slave logs are stored. + * Directory where rotated agent logs are stored. * * The method also creates a log directory if required. * @@ -287,7 +287,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces protected @Nonnull File getLogDir() { File dir = new File(Jenkins.getInstance().getRootDir(),"logs/slaves/"+nodeName); if (!dir.exists() && !dir.mkdirs()) { - LOGGER.severe("Failed to create slave log directory " + dir.getAbsolutePath()); + LOGGER.severe("Failed to create agent log directory " + dir.getAbsolutePath()); } return dir; } @@ -300,7 +300,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } /** - * Gets the string representation of the slave log. + * Gets the string representation of the agent log. */ public String getLog() throws IOException { return Util.loadFile(getLogFile()); @@ -377,12 +377,12 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces public abstract Charset getDefaultCharset(); /** - * Gets the logs recorded by this slave. + * Gets the logs recorded by this agent. */ public abstract List getLogRecords() throws IOException, InterruptedException; /** - * If {@link #getChannel()}==null, attempts to relaunch the slave agent. + * If {@link #getChannel()}==null, attempts to relaunch the agent. */ public abstract void doLaunchSlaveAgent( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException; @@ -415,7 +415,6 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * make much sense because as soon as {@link Computer} is connected it can be disconnected by some other threads.) */ public final Future connect(boolean forceReconnect) { - this.cachedEnvironment = null; connectTime = System.currentTimeMillis(); return _connect(forceReconnect); } @@ -442,10 +441,13 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces protected abstract Future _connect(boolean forceReconnect); /** - * CLI command to reconnect this node. + * @deprecated Implementation of CLI command "connect-node" moved to {@link hudson.cli.ConnectNodeCommand}. + * + * @param force + * If true cancel any currently pending connect operation and retry from scratch */ - @CLIMethod(name="connect-node") - public void cliConnect(@Option(name="-f",usage="Cancel any currently pending connect operation and retry from scratch") boolean force) throws ExecutionException, InterruptedException { + @Deprecated + public void cliConnect(boolean force) throws ExecutionException, InterruptedException { checkPermission(CONNECT); connect(force).get(); } @@ -501,27 +503,36 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } /** - * CLI command to disconnects this node. + * @deprecated Implementation of CLI command "disconnect-node" moved to {@link hudson.cli.DisconnectNodeCommand}. + * + * @param cause + * Record the note about why you are disconnecting this node */ - @CLIMethod(name="disconnect-node") - public void cliDisconnect(@Option(name="-m",usage="Record the note about why you are disconnecting this node") String cause) throws ExecutionException, InterruptedException { + @Deprecated + public void cliDisconnect(String cause) throws ExecutionException, InterruptedException { checkPermission(DISCONNECT); disconnect(new ByCLI(cause)).get(); } /** - * CLI command to mark the node offline. + * @deprecated Implementation of CLI command "offline-node" moved to {@link hudson.cli.OfflineNodeCommand}. + * + * @param cause + * Record the note about why you are disconnecting this node */ - @CLIMethod(name="offline-node") - public void cliOffline(@Option(name="-m",usage="Record the note about why you are disconnecting this node") String cause) throws ExecutionException, InterruptedException { + @Deprecated + public void cliOffline(String cause) throws ExecutionException, InterruptedException { checkPermission(DISCONNECT); setTemporarilyOffline(true, new ByCLI(cause)); } - @CLIMethod(name="online-node") + /** + * @deprecated Implementation of CLI command "online-node" moved to {@link hudson.cli.OnlineNodeCommand}. + */ + @Deprecated public void cliOnline() throws ExecutionException, InterruptedException { checkPermission(CONNECT); - setTemporarilyOffline(false,null); + setTemporarilyOffline(false, null); } /** @@ -544,6 +555,15 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces return nodeName != null ? nodeName : ""; } + /** + * True if this computer is a Unix machine (as opposed to Windows machine). + * + * @since 1.624 + * @return + * null if the computer is disconnected and therefore we don't know whether it is Unix or not. + */ + public abstract @CheckForNull Boolean isUnix(); + /** * Returns the {@link Node} that this computer represents. * @@ -551,8 +571,9 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * null if the configuration has changed and the node is removed, yet the corresponding {@link Computer} * is not yet gone. */ - public @CheckForNull Node getNode() { - Jenkins j = Jenkins.getInstance(); + @CheckForNull + public Node getNode() { + Jenkins j = Jenkins.getInstanceOrNull(); // TODO confirm safe to assume non-null and use getInstance() if (j == null) { return null; } @@ -574,6 +595,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces /** * {@inheritDoc} */ + @Override public void taskAccepted(Executor executor, Queue.Task task) { // dummy implementation } @@ -581,6 +603,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces /** * {@inheritDoc} */ + @Override public void taskCompleted(Executor executor, Queue.Task task, long durationMS) { // dummy implementation } @@ -588,6 +611,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces /** * {@inheritDoc} */ + @Override public void taskCompletedWithProblems(Executor executor, Queue.Task task, long durationMS, Throwable problems) { // dummy implementation } @@ -602,8 +626,8 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } /** - * This method is called to determine whether manual launching of the slave is allowed at this point in time. - * @return {@code true} if manual launching of the slave is allowed at this point in time. + * This method is called to determine whether manual launching of the agent is allowed at this point in time. + * @return {@code true} if manual launching of the agent is allowed at this point in time. */ @Exported public boolean isManualLaunchAllowed() { @@ -631,8 +655,8 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * Returns true if this computer can be launched by Hudson proactively and automatically. * *

- * For example, JNLP slaves return {@code false} from this, because the launch process - * needs to be initiated from the slave side. + * For example, JNLP agents return {@code false} from this, because the launch process + * needs to be initiated from the agent side. */ @Exported public boolean isLaunchSupported() { @@ -645,7 +669,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces *

* In contrast, {@link #isOffline()} represents the actual online/offline * state. For example, this method may return false while {@link #isOffline()} - * returns true if the slave agent failed to launch. + * returns true if the agent failed to launch. * * @deprecated * You should almost always want {@link #isOffline()}. @@ -682,7 +706,6 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces if (node != null) { node.setTemporaryOfflineCause(offlineCause); } - Jenkins.getInstance().getQueue().scheduleMaintenance(); synchronized (statusChangeLock) { statusChangeLock.notifyAll(); } @@ -692,6 +715,13 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } } + /** + * Returns the icon for this computer. + * + * It is both the recommended and default implementation to serve different icons based on {@link #isOffline} + * + * @see #getIconClassName() + */ @Exported public String getIcon() { if(isOffline()) @@ -700,6 +730,17 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces return "computer.png"; } + /** + * Returns the class name that will be used to lookup the icon. + * + * This class name will be added as a class tag to the html img tags where the icon should + * show up followed by a size specifier given by {@link Icon#toNormalizedIconSizeClass(String)} + * The conversion of class tag to src tag is registered through {@link IconSet#addIcon(Icon)} + * + * It is both the recommended and default implementation to serve different icons based on {@link #isOffline} + * + * @see #getIcon() + */ @Exported public String getIconClassName() { if(isOffline()) @@ -813,7 +854,20 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces protected void onRemoved(){ } - private synchronized void setNumExecutors(int n) { + /** + * Calling path, *means protected by Queue.withLock + * + * Computer.doConfigSubmit -> Computer.replaceBy ->Jenkins.setNodes* ->Computer.setNode + * AbstractCIBase.updateComputerList->Computer.inflictMortalWound* + * AbstractCIBase.updateComputerList->AbstractCIBase.updateComputer* ->Computer.setNode + * AbstractCIBase.updateComputerList->AbstractCIBase.killComputer->Computer.kill + * Computer.constructor->Computer.setNode + * Computer.kill is called after numExecutors set to zero(Computer.inflictMortalWound) so not need the Queue.lock + * + * @param number of executors + */ + @GuardedBy("hudson.model.Queue.lock") + private void setNumExecutors(int n) { this.numExecutors = n; final int diff = executors.size()-n; @@ -988,29 +1042,31 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces /** * Called by {@link Executor} to kill excessive executors from this computer. */ - /*package*/ void removeExecutor(final Executor e) { - Queue.withLock(new Runnable() { + protected void removeExecutor(final Executor e) { + final Runnable task = new Runnable() { @Override public void run() { synchronized (Computer.this) { executors.remove(e); addNewExecutorIfNecessary(); - if (!isAlive()) // TODO except from interrupt/doYank this is called while the executor still isActive(), so how could !this.isAlive()? - { - AbstractCIBase ciBase = Jenkins.getInstance(); - ciBase.removeComputer(Computer.this); + if (!isAlive()) { + AbstractCIBase ciBase = Jenkins.getInstanceOrNull(); + if (ciBase != null) { // TODO confirm safe to assume non-null and use getInstance() + ciBase.removeComputer(Computer.this); + } } } } - }); + }; + if (!Queue.tryWithLock(task)) { + // JENKINS-28840 if we couldn't get the lock push the operation to a separate thread to avoid deadlocks + threadPoolForRemoting.submit(Queue.wrapWithLock(task)); + } } /** * Returns true if any of the executors are {@linkplain Executor#isActive active}. * - * Note that if an executor dies, we'll leave it in {@link #executors} until - * the administrator yanks it out, so that we can see why it died. - * * @since 1.509 */ protected boolean isAlive() { @@ -1025,9 +1081,14 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * Called from {@link Jenkins#cleanUp}. */ public void interrupt() { - for (Executor e : executors) { - e.interruptForShutdown(); - } + Queue.withLock(new Runnable() { + @Override + public void run() { + for (Executor e : executors) { + e.interruptForShutdown(); + } + } + }); } public String getSearchUrl() { @@ -1117,7 +1178,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } /** - * Gets the thread dump of the slave JVM. + * Gets the thread dump of the agent JVM. * @return * key is the thread name, and the value is the pre-formatted dump. */ @@ -1136,14 +1197,14 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * This method tries to compute the name of the host that's reachable by all the other nodes. * *

- * Since it's possible that the slave is not reachable from the master (it may be behind a firewall, + * Since it's possible that the agent is not reachable from the master (it may be behind a firewall, * connecting to master via JNLP), this method may return null. * * It's surprisingly tricky for a machine to know a name that other systems can get to, * especially between things like DNS search suffix, the hosts file, and YP. * *

- * So the technique here is to compute possible interfaces and names on the slave, + * So the technique here is to compute possible interfaces and names on the agent, * then try to ping them from the master, and pick the one that worked. * *

@@ -1152,7 +1213,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces * @since 1.300 * @return * null if the host name cannot be computed (for example because this computer is offline, - * because the slave is behind the firewall, etc.) + * because the agent is behind the firewall, etc.) */ public String getHostName() throws IOException, InterruptedException { if(hostNameCached) @@ -1247,7 +1308,7 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces private static class GetFallbackName extends MasterToSlaveCallable { public String call() throws IOException { - return System.getProperty("host.name"); + return SystemProperties.getString("host.name"); } private static final long serialVersionUID = 1L; } @@ -1309,19 +1370,19 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces checkPermission(Jenkins.ADMINISTER); rsp.setContentType("text/plain"); - PrintWriter w = new PrintWriter(rsp.getCompressedWriter(req)); - VirtualChannel vc = getChannel(); - if (vc instanceof Channel) { - w.println("Master to slave"); - ((Channel)vc).dumpExportTable(w); - w.flush(); // flush here once so that even if the dump from the slave fails, the client gets some useful info - - w.println("\n\n\nSlave to master"); - w.print(vc.call(new DumpExportTableTask())); - } else { - w.println(Messages.Computer_BadChannel()); + try (PrintWriter w = new PrintWriter(rsp.getCompressedWriter(req))) { + VirtualChannel vc = getChannel(); + if (vc instanceof Channel) { + w.println("Master to slave"); + ((Channel) vc).dumpExportTable(w); + w.flush(); // flush here once so that even if the dump from the agent fails, the client gets some useful info + + w.println("\n\n\nSlave to master"); + w.print(vc.call(new DumpExportTableTask())); + } else { + w.println(Messages.Computer_BadChannel()); + } } - w.close(); } private static final class DumpExportTableTask extends MasterToSlaveCallable { @@ -1360,17 +1421,23 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces public void doConfigSubmit( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException, FormException { checkPermission(CONFIGURE); - String name = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name")); - Jenkins.checkGoodName(name); + String proposedName = Util.fixEmptyAndTrim(req.getSubmittedForm().getString("name")); + Jenkins.checkGoodName(proposedName); Node node = getNode(); if (node == null) { throw new ServletException("No such node " + nodeName); } + + if ((!proposedName.equals(nodeName)) + && Jenkins.getActiveInstance().getNode(proposedName) != null) { + throw new FormException(Messages.ComputerSet_SlaveAlreadyExists(proposedName), "name"); + } + Node result = node.reconfigure(req, req.getSubmittedForm()); - replaceBy(result); + Jenkins.getInstance().getNodesObject().replaceNode(this.getNode(), result); - // take the user back to the slave top page. + // take the user back to the agent top page. rsp.sendRedirect2("../" + result.getNodeName() + '/'); } @@ -1402,26 +1469,6 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces rsp.sendError(SC_BAD_REQUEST); } - /** - * Replaces the current {@link Node} by another one. - */ - private void replaceBy(Node newNode) throws ServletException, IOException { - final Jenkins app = Jenkins.getInstance(); - - // replace the old Node object by the new one - synchronized (app) { - List nodes = new ArrayList(app.getNodes()); - Node node = getNode(); - int i = (node != null) ? nodes.indexOf(node) : -1; - if(i<0) { - throw new IOException("This slave appears to be removed while you were editing the configuration"); - } - - nodes.set(i, newNode); - app.setNodes(nodes); - } - } - /** * Updates Job by its XML definition. * @@ -1430,13 +1477,12 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces public void updateByXml(final InputStream source) throws IOException, ServletException { checkPermission(CONFIGURE); Node result = (Node)Jenkins.XSTREAM2.fromXML(source); - replaceBy(result); + Jenkins.getInstance().getNodesObject().replaceNode(this.getNode(), result); } /** - * Really deletes the slave. + * Really deletes the agent. */ - @CLIMethod(name="delete-node") @RequirePOST public HttpResponse doDoDelete() throws IOException { checkPermission(DELETE); @@ -1453,7 +1499,6 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces /** * Blocks until the node becomes online/offline. */ - @CLIMethod(name="wait-node-online") public void waitUntilOnline() throws InterruptedException { synchronized (statusChangeLock) { while (!isOnline()) @@ -1461,7 +1506,6 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } } - @CLIMethod(name="wait-node-offline") public void waitUntilOffline() throws InterruptedException { synchronized (statusChangeLock) { while (!isOffline()) @@ -1488,14 +1532,14 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces } /** - * Returns {@code true} if the computer is accepting tasks. Needed to allow slaves programmatic suspension of task + * Returns {@code true} if the computer is accepting tasks. Needed to allow agents programmatic suspension of task * scheduling that does not overlap with being offline. * * @return {@code true} if the computer is accepting tasks * @see hudson.slaves.RetentionStrategy#isAcceptingTasks(Computer) * @see hudson.model.Node#isAcceptingTasks() */ - @OverrideMustInvoke(When.ANYTIME) + @OverridingMethodsMustInvokeSuper public boolean isAcceptingTasks() { final Node node = getNode(); return getRetentionStrategy().isAcceptingTasks(this) && (node == null || node.isAcceptingTasks()); @@ -1506,15 +1550,15 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces */ @CLIResolver public static Computer resolveForCLI( - @Argument(required=true,metaVar="NAME",usage="Slave name, or empty string for master") String name) throws CmdLineException { + @Argument(required=true,metaVar="NAME",usage="Agent name, or empty string for master") String name) throws CmdLineException { Jenkins h = Jenkins.getInstance(); Computer item = h.getComputer(name); if (item==null) { - List names = new ArrayList(); - for (Computer c : h.getComputers()) - if (c.getName().length()>0) - names.add(c.getName()); - throw new CmdLineException(null,Messages.Computer_NoSuchSlaveExists(name,EditDistance.findNearest(name,names))); + List names = ComputerSet.getComputerNames(); + String adv = EditDistance.findNearest(name, names); + throw new IllegalArgumentException(adv == null ? + hudson.model.Messages.Computer_NoSuchSlaveExistsWithoutAdvice(name) : + hudson.model.Messages.Computer_NoSuchSlaveExists(name, adv)); } return item; } @@ -1546,8 +1590,8 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces if (m.matches()) { File newLocation = new File(dir, "logs/slaves/" + m.group(1) + "/slave.log" + Util.fixNull(m.group(2))); newLocation.getParentFile().mkdirs(); - boolean relocationSuccessfull=f.renameTo(newLocation); - if (relocationSuccessfull) { // The operation will fail if mkdir fails + boolean relocationSuccessful=f.renameTo(newLocation); + if (relocationSuccessful) { // The operation will fail if mkdir fails LOGGER.log(Level.INFO, "Relocated log file {0} to {1}",new Object[] {f.getPath(),newLocation.getPath()}); } else { LOGGER.log(Level.WARNING, "Cannot relocate log file {0} to {1}",new Object[] {f.getPath(),newLocation.getPath()}); @@ -1624,6 +1668,15 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces return true; } + @Extension(ordinal = Double.MAX_VALUE) + @Restricted(DoNotUse.class) + public static class InternalComputerListener extends ComputerListener { + @Override + public void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException { + c.cachedEnvironment = null; + } + } + @Override public int hashCode() { return executor.hashCode(); @@ -1658,9 +1711,9 @@ public /*transient*/ abstract class Computer extends Actionable implements Acces /** * @since 1.532 */ - public static final Permission EXTENDED_READ = new Permission(PERMISSIONS,"ExtendedRead", Messages._Computer_ExtendedReadPermission_Description(), CONFIGURE, Boolean.getBoolean("hudson.security.ExtendedReadPermission"), new PermissionScope[]{PermissionScope.COMPUTER}); + public static final Permission EXTENDED_READ = new Permission(PERMISSIONS,"ExtendedRead", Messages._Computer_ExtendedReadPermission_Description(), CONFIGURE, SystemProperties.getBoolean("hudson.security.ExtendedReadPermission"), new PermissionScope[]{PermissionScope.COMPUTER}); public static final Permission DELETE = new Permission(PERMISSIONS,"Delete", Messages._Computer_DeletePermission_Description(), Permission.DELETE, PermissionScope.COMPUTER); - public static final Permission CREATE = new Permission(PERMISSIONS,"Create", Messages._Computer_CreatePermission_Description(), Permission.CREATE, PermissionScope.COMPUTER); + public static final Permission CREATE = new Permission(PERMISSIONS,"Create", Messages._Computer_CreatePermission_Description(), Permission.CREATE, PermissionScope.JENKINS); public static final Permission DISCONNECT = new Permission(PERMISSIONS,"Disconnect", Messages._Computer_DisconnectPermission_Description(), Jenkins.ADMINISTER, PermissionScope.COMPUTER); public static final Permission CONNECT = new Permission(PERMISSIONS,"Connect", Messages._Computer_ConnectPermission_Description(), DISCONNECT, PermissionScope.COMPUTER); public static final Permission BUILD = new Permission(PERMISSIONS, "Build", Messages._Computer_BuildPermission_Description(), Permission.WRITE, PermissionScope.COMPUTER); diff --git a/core/src/main/java/hudson/model/ComputerPanelBox.java b/core/src/main/java/hudson/model/ComputerPanelBox.java index f7def3d04f2321cd73a179015d06508c1c593aff..94ee1aaa3ca938aa8412999f65cbae7c2cbf7337 100644 --- a/core/src/main/java/hudson/model/ComputerPanelBox.java +++ b/core/src/main/java/hudson/model/ComputerPanelBox.java @@ -4,7 +4,6 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import java.util.ArrayList; import java.util.List; -import jenkins.model.Jenkins; /** * Adds box rendered in the computer side panel. diff --git a/core/src/main/java/hudson/model/ComputerPinger.java b/core/src/main/java/hudson/model/ComputerPinger.java index d924ab63b4fea091b3eeccd7033044f0addb2016..ecf81abceb7a430c81e1bfa61dccd8ce413652cd 100644 --- a/core/src/main/java/hudson/model/ComputerPinger.java +++ b/core/src/main/java/hudson/model/ComputerPinger.java @@ -3,7 +3,6 @@ package hudson.model; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import java.io.IOException; import java.net.InetAddress; diff --git a/core/src/main/java/hudson/model/ComputerSet.java b/core/src/main/java/hudson/model/ComputerSet.java index 40b71fb24e08aee66d62f5417eed7606315cec1f..b907420b5876a4ce5d34f930e228c7ea89585fab 100644 --- a/core/src/main/java/hudson/model/ComputerSet.java +++ b/core/src/main/java/hudson/model/ComputerSet.java @@ -49,6 +49,7 @@ import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; +import javax.annotation.Nonnull; import javax.servlet.ServletException; import java.io.File; import java.io.IOException; @@ -137,7 +138,7 @@ public final class ComputerSet extends AbstractModelObject implements Describabl } /** - * Gets all the slave names. + * Gets all the agent names. */ public List get_slaveNames() { return new AbstractList() { @@ -229,7 +230,7 @@ public final class ComputerSet extends AbstractModelObject implements Describabl } /** - * First check point in creating a new slave. + * First check point in creating a new agent. */ public synchronized void doCreateItem( StaplerRequest req, StaplerResponse rsp, @QueryParameter String name, @QueryParameter String mode, @@ -278,7 +279,7 @@ public final class ComputerSet extends AbstractModelObject implements Describabl } /** - * Really creates a new slave. + * Really creates a new agent. */ public synchronized void doDoCreateItem( StaplerRequest req, StaplerResponse rsp, @QueryParameter String name, @@ -295,12 +296,12 @@ public final class ComputerSet extends AbstractModelObject implements Describabl Node result = NodeDescriptor.all().find(type).newInstance(req, formData); app.addNode(result); - // take the user back to the slave list top page + // take the user back to the agent list top page rsp.sendRedirect2("."); } /** - * Makes sure that the given name is good as a slave name. + * Makes sure that the given name is good as an agent name. * @return trimmed name if valid; throws ParseException if not */ public String checkName(String name) throws Failure { @@ -318,7 +319,7 @@ public final class ComputerSet extends AbstractModelObject implements Describabl } /** - * Makes sure that the given name is good as a slave name. + * Makes sure that the given name is good as an agent name. */ public FormValidation doCheckName(@QueryParameter String value) throws IOException, ServletException { Jenkins.getInstance().checkPermission(Computer.CREATE); @@ -380,11 +381,6 @@ public final class ComputerSet extends AbstractModelObject implements Describabl @Extension public static class DescriptorImpl extends Descriptor { - @Override - public String getDisplayName() { - return ""; - } - /** * Auto-completion for the "copy from" field in the new job page. */ @@ -415,6 +411,21 @@ public final class ComputerSet extends AbstractModelObject implements Describabl }, 10, TimeUnit.SECONDS); } + /** + * @return The list of strings of computer names (excluding master) + * @since 2.14 + */ + @Nonnull + public static List getComputerNames() { + final ArrayList names = new ArrayList(); + for (Computer c : Jenkins.getInstance().getComputers()) { + if (!c.getName().isEmpty()) { + names.add(c.getName()); + } + } + return names; + } + private static final Logger LOGGER = Logger.getLogger(ComputerSet.class.getName()); static { @@ -457,10 +468,8 @@ public final class ComputerSet extends AbstractModelObject implements Describabl NodeMonitor nm = d.clazz.newInstance(); nm.setIgnored(ignored); return nm; - } catch (InstantiationException e) { - LOGGER.log(Level.SEVERE, "Failed to instanciate "+d.clazz,e); - } catch (IllegalAccessException e) { - LOGGER.log(Level.SEVERE, "Failed to instanciate "+d.clazz,e); + } catch (InstantiationException | IllegalAccessException e) { + LOGGER.log(Level.SEVERE, "Failed to instantiate "+d.clazz,e); } return null; } diff --git a/core/src/main/java/hudson/model/Descriptor.java b/core/src/main/java/hudson/model/Descriptor.java index 4c5693b933865d2472883bfc735c196f8ec1ccf4..5271a3b8550f0d689ebc68af809a301f6fc142e2 100644 --- a/core/src/main/java/hudson/model/Descriptor.java +++ b/core/src/main/java/hudson/model/Descriptor.java @@ -36,7 +36,10 @@ import hudson.util.FormValidation.CheckMethod; import hudson.util.ReflectionUtils; import hudson.util.ReflectionUtils.Parameter; import hudson.views.ListViewColumn; +import jenkins.model.GlobalConfiguration; +import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; +import jenkins.util.io.OnMaster; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.kohsuke.stapler.*; @@ -72,6 +75,7 @@ import java.lang.reflect.Type; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.beans.Introspector; +import java.util.IdentityHashMap; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; @@ -122,7 +126,7 @@ import javax.annotation.Nonnull; * @author Kohsuke Kawaguchi * @see Describable */ -public abstract class Descriptor> implements Saveable { +public abstract class Descriptor> implements Saveable, OnMaster { /** * The class being described by this descriptor. */ @@ -293,8 +297,15 @@ public abstract class Descriptor> implements Saveable { /** * Human readable name of this kind of configurable object. + * Should be overridden for most descriptors, if the display name is visible somehow. + * As a fallback it uses {@link Class#getSimpleName} on {@link #clazz}, so for example {@code MyThing} from {@code some.pkg.MyThing.DescriptorImpl}. + * Historically some implementations returned null as a way of hiding the descriptor from the UI, + * but this is generally managed by an explicit method such as {@code isEnabled} or {@code isApplicable}. */ - public abstract String getDisplayName(); + @Nonnull + public String getDisplayName() { + return clazz.getSimpleName(); + } /** * Uniquely identifies this {@link Descriptor} among all the other {@link Descriptor}s. @@ -552,7 +563,7 @@ public abstract class Descriptor> implements Saveable { * Signals a problem in the submitted form. * @since 1.145 */ - public T newInstance(StaplerRequest req, JSONObject formData) throws FormException { + public T newInstance(@CheckForNull StaplerRequest req, @Nonnull JSONObject formData) throws FormException { try { Method m = getClass().getMethod("newInstance", StaplerRequest.class); @@ -567,19 +578,106 @@ public abstract class Descriptor> implements Saveable { } // new behavior as of 1.206 - return verifyNewInstance(req.bindJSON(clazz,formData)); + BindInterceptor oldInterceptor = req.getBindInterceptor(); + try { + NewInstanceBindInterceptor interceptor; + if (oldInterceptor instanceof NewInstanceBindInterceptor) { + interceptor = (NewInstanceBindInterceptor) oldInterceptor; + } else { + interceptor = new NewInstanceBindInterceptor(oldInterceptor); + req.setBindInterceptor(interceptor); + } + interceptor.processed.put(formData, true); + return verifyNewInstance(req.bindJSON(clazz, formData)); + } finally { + req.setBindInterceptor(oldInterceptor); + } } } catch (NoSuchMethodException e) { throw new AssertionError(e); // impossible - } catch (InstantiationException e) { - throw new Error("Failed to instantiate "+clazz+" from "+formData,e); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException | RuntimeException e) { throw new Error("Failed to instantiate "+clazz+" from "+formData,e); - } catch (RuntimeException e) { - throw new RuntimeException("Failed to instantiate "+clazz+" from "+formData,e); } } + /** + * Ensures that calls to {@link StaplerRequest#bindJSON(Class, JSONObject)} from {@link #newInstance(StaplerRequest, JSONObject)} recurse properly. + * {@code doConfigSubmit}-like methods will wind up calling {@code newInstance} directly + * or via {@link #newInstancesFromHeteroList(StaplerRequest, Object, Collection)}, + * which consult any custom {@code newInstance} overrides for top-level {@link Describable} objects. + * But for nested describable objects Stapler would know nothing about {@code newInstance} without this trick. + */ + @SuppressWarnings({"unchecked", "rawtypes"}) + private static class NewInstanceBindInterceptor extends BindInterceptor { + + private final BindInterceptor oldInterceptor; + private final Map processed = new IdentityHashMap<>(); + + NewInstanceBindInterceptor(BindInterceptor oldInterceptor) { + LOGGER.log(Level.FINER, "new interceptor delegating to {0}", oldInterceptor); + this.oldInterceptor = oldInterceptor; + } + + private boolean isApplicable(Class type, JSONObject json) { + if (Modifier.isAbstract(type.getModifiers())) { + LOGGER.log(Level.FINER, "ignoring abstract {0} {1}", new Object[] {type.getName(), json}); + return false; + } + if (!Describable.class.isAssignableFrom(type)) { + LOGGER.log(Level.FINER, "ignoring non-Describable {0} {1}", new Object[] {type.getName(), json}); + return false; + } + if (Boolean.TRUE.equals(processed.put(json, true))) { + LOGGER.log(Level.FINER, "already processed {0} {1}", new Object[] {type.getName(), json}); + return false; + } + return true; + } + + @Override + public Object instantiate(Class actualType, JSONObject json) { + if (isApplicable(actualType, json)) { + LOGGER.log(Level.FINE, "switching to newInstance {0} {1}", new Object[] {actualType.getName(), json}); + try { + final Descriptor descriptor = Jenkins.getActiveInstance().getDescriptor(actualType); + if (descriptor != null) { + return descriptor.newInstance(Stapler.getCurrentRequest(), json); + } else { + LOGGER.log(Level.WARNING, "Descriptor not found. Falling back to default instantiation " + + actualType.getName() + " " + json); + } + } catch (Exception x) { + LOGGER.log(Level.WARNING, "falling back to default instantiation " + actualType.getName() + " " + json, x); + // If nested objects are not using newInstance, bindJSON will wind up throwing the same exception anyway, + // so logging above will result in a duplicated stack trace. + // However if they *are* then this is the only way to find errors in that newInstance. + // Normally oldInterceptor.instantiate will just return DEFAULT, not actually do anything, + // so we cannot try calling the default instantiation and then decide which problem to report. + } + } + return oldInterceptor.instantiate(actualType, json); + } + + @Override + public Object onConvert(Type targetType, Class targetTypeErasure, Object jsonSource) { + if (jsonSource instanceof JSONObject) { + JSONObject json = (JSONObject) jsonSource; + if (isApplicable(targetTypeErasure, json)) { + LOGGER.log(Level.FINE, "switching to newInstance {0} {1}", new Object[] {targetTypeErasure.getName(), json}); + try { + return Jenkins.getActiveInstance().getDescriptor(targetTypeErasure).newInstance(Stapler.getCurrentRequest(), json); + } catch (Exception x) { + LOGGER.log(Level.WARNING, "falling back to default instantiation " + targetTypeErasure.getName() + " " + json, x); + } + } + } else { + LOGGER.log(Level.FINER, "ignoring non-object {0}", jsonSource); + } + return oldInterceptor.onConvert(targetType, targetTypeErasure, jsonSource); + } + + } + /** * Look out for a typical error a plugin developer makes. * See http://hudson.361315.n4.nabble.com/Help-Hint-needed-Post-build-action-doesn-t-stay-activated-td2308833.html @@ -714,7 +812,18 @@ public abstract class Descriptor> implements Saveable { public String getGlobalConfigPage() { return getViewPage(clazz, getPossibleViewNames("global"), null); } - + + /** + * Define the global configuration category the global config of this Descriptor is in. + * + * @return never null, always the same value for a given instance of {@link Descriptor}. + * + * @since 2.0, used to be in {@link GlobalConfiguration} before that. + */ + public GlobalConfigurationCategory getCategory() { + return GlobalConfigurationCategory.get(GlobalConfigurationCategory.Unclassified.class); + } + private String getViewPage(Class clazz, String pageName, String defaultValue) { return getViewPage(clazz,Collections.singleton(pageName),defaultValue); } @@ -1036,7 +1145,7 @@ public abstract class Descriptor> implements Saveable { .generateResponse(req, rsp, node); } else { // for now, we can't really use the field name that caused the problem. - new Failure(getMessage()).generateResponse(req,rsp,node); + new Failure(getMessage()).generateResponse(req,rsp,node,getCause()); } } } diff --git a/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java b/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java index 0a435c6fda0777b070e0b3b24814767bbd800fe1..f092a8bb1094800f7627c66030cda4564dceddff 100644 --- a/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java +++ b/core/src/main/java/hudson/model/DescriptorVisibilityFilter.java @@ -3,14 +3,16 @@ package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.scm.SCMDescriptor; -import jenkins.ExtensionFilter; -import jenkins.model.Jenkins; - import java.util.ArrayList; import java.util.List; - -import java.util.logging.Logger; +import java.util.WeakHashMap; +import java.util.concurrent.TimeUnit; import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import jenkins.ExtensionFilter; +import jenkins.util.SystemProperties; /** * Hides {@link Descriptor}s from users. @@ -23,6 +25,22 @@ public abstract class DescriptorVisibilityFilter implements ExtensionPoint { private static final Logger LOGGER = Logger.getLogger(DescriptorVisibilityFilter.class.getName()); + /** + * Decides if the given descriptor should be visible to the user. + * + * @param contextClass The class of object that indicates where the visibility of a descriptor is evaluated. + * For example, if Jenkins is deciding whether a {@link FreeStyleProject} should gets a + * {@link SCMDescriptor}, the context class will be {@link FreeStyleProject}. + * @param descriptor Descriptor whose visibility is evaluated. Never null. + * @return true to allow the descriptor to be visible. false to hide it. + * If any of the installed {@link DescriptorVisibilityFilter} returns false, + * the descriptor is not shown. + * @since 2.12 + */ + public boolean filterType(@Nonnull Class contextClass, @Nonnull Descriptor descriptor) { + return true; + } + /** * Decides if the given descriptor should be visible to the user. * @@ -39,7 +57,7 @@ public abstract class DescriptorVisibilityFilter implements ExtensionPoint { * If any of the installed {@link DescriptorVisibilityFilter} returns false, * the descriptor is not shown. */ - public abstract boolean filter(Object context, Descriptor descriptor); + public abstract boolean filter(@CheckForNull Object context, @Nonnull Descriptor descriptor); public static ExtensionList all() { return ExtensionList.lookup(DescriptorVisibilityFilter.class); @@ -48,7 +66,8 @@ public abstract class DescriptorVisibilityFilter implements ExtensionPoint { public static List apply(Object context, Iterable source) { ExtensionList filters = all(); List r = new ArrayList(); - + Class contextClass = context == null ? null : context.getClass(); + OUTER: for (T d : source) { if (LOGGER.isLoggable(Level.FINE)) { @@ -58,10 +77,58 @@ public abstract class DescriptorVisibilityFilter implements ExtensionPoint { if (LOGGER.isLoggable(Level.FINER)) { LOGGER.finer("Querying " + f + " for visibility of " + d + " in " + context); } - if (!f.filter(context,d)) { - if (LOGGER.isLoggable(Level.CONFIG)) { - LOGGER.config("Filter " + f + " hides " + d + " in context " + context); + try { + if (contextClass != null && !f.filterType(contextClass, d)) { + if (LOGGER.isLoggable(Level.CONFIG)) { + LOGGER.config("Filter " + f + " hides " + d + " in contexts of type " + contextClass); + } + continue OUTER; // veto-ed. not shown + } + if (!f.filter(context, d)) { + if (LOGGER.isLoggable(Level.CONFIG)) { + LOGGER.config("Filter " + f + " hides " + d + " in context " + context); + } + continue OUTER; // veto-ed. not shown + } + } catch (Error e) { + LOGGER.log(Level.WARNING, "Encountered error while processing filter " + f + " for context " + context, e); + throw e; + } catch (Throwable e) { + LOGGER.log(logLevelFor(f), "Uncaught exception from filter " + f + " for context " + context, e); + continue OUTER; // veto-ed. not shown + } + } + r.add(d); + } + return r; + } + + public static List applyType(Class contextClass, Iterable source) { + ExtensionList filters = all(); + List r = new ArrayList(); + + OUTER: + for (T d : source) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.fine("Determining visibility of " + d + " in contexts of type " + contextClass); + } + for (DescriptorVisibilityFilter f : filters) { + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.finer("Querying " + f + " for visibility of " + d + " in type " + contextClass); + } + try { + if (contextClass != null && !f.filterType(contextClass, d)) { + if (LOGGER.isLoggable(Level.CONFIG)) { + LOGGER.config("Filter " + f + " hides " + d + " in contexts of type " + contextClass); + } + continue OUTER; // veto-ed. not shown } + } catch (Error e) { + LOGGER.log(Level.WARNING, + "Encountered error while processing filter " + f + " for contexts of type " + contextClass, e); + throw e; + } catch (Throwable e) { + LOGGER.log(logLevelFor(f), "Uncaught exception from filter " + f + " for context of type " + contextClass, e); continue OUTER; // veto-ed. not shown } } @@ -69,4 +136,38 @@ public abstract class DescriptorVisibilityFilter implements ExtensionPoint { } return r; } + + /** + * Returns the {@link Level} to log an uncaught exception from a {@link DescriptorVisibilityFilter}. We + * need to suppress repeated exceptions as there can be many invocations of the {@link DescriptorVisibilityFilter} + * triggered by the UI and spamming the logs would be bad. + * + * @param f the {@link DescriptorVisibilityFilter}. + * @return the level to report uncaught exceptions at. + */ + private static Level logLevelFor(DescriptorVisibilityFilter f) { + Long interval = SystemProperties.getLong( + DescriptorVisibilityFilter.class.getName() + ".badFilterLogWarningIntervalMinutes", + 60L); + // the healthy path will never see this synchronized block + synchronized (ResourceHolder.BAD_FILTERS) { + Long lastTime = ResourceHolder.BAD_FILTERS.get(f); + if (lastTime == null || lastTime + TimeUnit.MINUTES.toMillis(interval) < System.currentTimeMillis()) { + ResourceHolder.BAD_FILTERS.put(f, System.currentTimeMillis()); + return Level.WARNING; + } else { + return Level.FINE; + } + } + } + + /** + * Lazy initialization singleton for the map of bad filters. Should never be instantiated in a healthy instance. + */ + private static final class ResourceHolder { + /** + * The last time we complained in the logs about specific filters. + */ + private static final WeakHashMap BAD_FILTERS = new WeakHashMap<>(); + } } diff --git a/core/src/main/java/hudson/model/DirectlyModifiableView.java b/core/src/main/java/hudson/model/DirectlyModifiableView.java index bdc651341b59219520c6ebe8baaa277aab34aa52..b799d2bd9e978d97b06b21f62aca9790deec7b90 100644 --- a/core/src/main/java/hudson/model/DirectlyModifiableView.java +++ b/core/src/main/java/hudson/model/DirectlyModifiableView.java @@ -23,7 +23,6 @@ */ package hudson.model; -import hudson.util.HttpResponses; import java.io.IOException; diff --git a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java index 16dacc90a26e66f9fe5157537409329315f975fe..418efca8793d95d37b2962283ba2fbfe8a610ab0 100644 --- a/core/src/main/java/hudson/model/DirectoryBrowserSupport.java +++ b/core/src/main/java/hudson/model/DirectoryBrowserSupport.java @@ -43,10 +43,13 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; +import jenkins.util.SystemProperties; import jenkins.util.VirtualFile; import org.apache.commons.io.IOUtils; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipOutputStream; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -158,7 +161,7 @@ public final class DirectoryBrowserSupport implements HttpResponse { String pattern = req.getParameter("pattern"); if(pattern==null) pattern = req.getParameter("path"); // compatibility with Hudson<1.129 - if(pattern!=null && !Util.isAbsoluteUri(pattern)) {// avoid open redirect + if(pattern!=null && Util.isSafeToRedirectTo(pattern)) {// avoid open redirect rsp.sendRedirect2(pattern); return; } @@ -220,8 +223,7 @@ public final class DirectoryBrowserSupport implements HttpResponse { } if (plain) { rsp.setContentType("text/plain;charset=UTF-8"); - OutputStream os = rsp.getOutputStream(); - try { + try (OutputStream os = rsp.getOutputStream()) { for (VirtualFile kid : baseFile.list()) { os.write(kid.getName().getBytes("UTF-8")); if (kid.isDirectory()) { @@ -230,8 +232,6 @@ public final class DirectoryBrowserSupport implements HttpResponse { os.write('\n'); } os.flush(); - } finally { - os.close(); } return; } @@ -309,6 +309,13 @@ public final class DirectoryBrowserSupport implements HttpResponse { // pseudo file name to let the Stapler set text/plain rsp.serveFile(req, in, lastModified, -1, length, "plain.txt"); } else { + String csp = SystemProperties.getString(DirectoryBrowserSupport.class.getName() + ".CSP", DEFAULT_CSP_VALUE); + if (!csp.trim().equals("")) { + // allow users to prevent sending this header by setting empty system property + for (String header : new String[]{"Content-Security-Policy", "X-WebKit-CSP", "X-Content-Security-Policy"}) { + rsp.setHeader(header, csp); + } + } rsp.serveFile(req, in, lastModified, -1, length, baseFile.getName() ); } } @@ -346,33 +353,33 @@ public final class DirectoryBrowserSupport implements HttpResponse { } private static void zip(OutputStream outputStream, VirtualFile dir, String glob) throws IOException { - ZipOutputStream zos = new ZipOutputStream(outputStream); - zos.setEncoding(System.getProperty("file.encoding")); // TODO JENKINS-20663 make this overridable via query parameter - for (String n : dir.list(glob.length() == 0 ? "**" : glob)) { - String relativePath; - if (glob.length() == 0) { - // JENKINS-19947: traditional behavior is to prepend the directory name - relativePath = dir.getName() + '/' + n; - } else { - relativePath = n; - } - // In ZIP archives "All slashes MUST be forward slashes" (http://pkware.com/documents/casestudies/APPNOTE.TXT) - // TODO On Linux file names can contain backslashes which should not treated as file separators. - // Unfortunately, only the file separator char of the master is known (File.separatorChar) - // but not the file separator char of the (maybe remote) "dir". - ZipEntry e = new ZipEntry(relativePath.replace('\\', '/')); - VirtualFile f = dir.child(n); - e.setTime(f.lastModified()); - zos.putNextEntry(e); - InputStream in = f.open(); - try { - Util.copyStream(in, zos); - } finally { - IOUtils.closeQuietly(in); + try (ZipOutputStream zos = new ZipOutputStream(outputStream)) { + zos.setEncoding(System.getProperty("file.encoding")); // TODO JENKINS-20663 make this overridable via query parameter + for (String n : dir.list(glob.length() == 0 ? "**" : glob)) { + String relativePath; + if (glob.length() == 0) { + // JENKINS-19947: traditional behavior is to prepend the directory name + relativePath = dir.getName() + '/' + n; + } else { + relativePath = n; + } + // In ZIP archives "All slashes MUST be forward slashes" (http://pkware.com/documents/casestudies/APPNOTE.TXT) + // TODO On Linux file names can contain backslashes which should not treated as file separators. + // Unfortunately, only the file separator char of the master is known (File.separatorChar) + // but not the file separator char of the (maybe remote) "dir". + ZipEntry e = new ZipEntry(relativePath.replace('\\', '/')); + VirtualFile f = dir.child(n); + e.setTime(f.lastModified()); + zos.putNextEntry(e); + InputStream in = f.open(); + try { + Util.copyStream(in, zos); + } finally { + IOUtils.closeQuietly(in); + } + zos.closeEntry(); } - zos.closeEntry(); } - zos.close(); } /** @@ -576,4 +583,7 @@ public final class DirectoryBrowserSupport implements HttpResponse { private static final Logger LOGGER = Logger.getLogger(DirectoryBrowserSupport.class.getName()); + + @Restricted(NoExternalUse.class) + public static final String DEFAULT_CSP_VALUE = "sandbox; default-src 'none'; img-src 'self'; style-src 'self';"; } diff --git a/core/src/main/java/hudson/model/DownloadService.java b/core/src/main/java/hudson/model/DownloadService.java index ff5e3811c91b961f5fa730e4b33bb5ed05189eb6..d7fda884aa14fe32ec95debadd76c6bd2455f5a1 100644 --- a/core/src/main/java/hudson/model/DownloadService.java +++ b/core/src/main/java/hudson/model/DownloadService.java @@ -25,8 +25,12 @@ package hudson.model; import hudson.Extension; import hudson.ExtensionList; +import hudson.ExtensionListListener; import hudson.ExtensionPoint; import hudson.ProxyConfiguration; +import jenkins.util.SystemProperties; +import hudson.init.InitMilestone; +import hudson.init.Initializer; import hudson.util.FormValidation; import hudson.util.FormValidation.Kind; import hudson.util.QuotedStringTokenizer; @@ -35,8 +39,12 @@ import static hudson.util.TimeUnit2.DAYS; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Field; import java.net.URL; import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.DownloadSettings; import jenkins.model.Jenkins; @@ -62,6 +70,11 @@ import org.kohsuke.stapler.StaplerResponse; */ @Extension public class DownloadService extends PageDecorator { + + /** + * the prefix for the signature validator name + */ + private static final String signatureValidatorPrefix = "downloadable"; /** * Builds up an HTML fragment that starts all the download jobs. */ @@ -155,8 +168,7 @@ public class DownloadService extends PageDecorator { */ @Restricted(NoExternalUse.class) public static String loadJSON(URL src) throws IOException { - InputStream is = ProxyConfiguration.open(src).getInputStream(); - try { + try (InputStream is = ProxyConfiguration.open(src).getInputStream()) { String jsonp = IOUtils.toString(is, "UTF-8"); int start = jsonp.indexOf('{'); int end = jsonp.lastIndexOf('}'); @@ -165,8 +177,6 @@ public class DownloadService extends PageDecorator { } else { throw new IOException("Could not find JSON in " + src); } - } finally { - is.close(); } } @@ -178,8 +188,7 @@ public class DownloadService extends PageDecorator { */ @Restricted(NoExternalUse.class) public static String loadJSONHTML(URL src) throws IOException { - InputStream is = ProxyConfiguration.open(src).getInputStream(); - try { + try (InputStream is = ProxyConfiguration.open(src).getInputStream()) { String jsonp = IOUtils.toString(is, "UTF-8"); String preamble = "window.parent.postMessage(JSON.stringify("; int start = jsonp.indexOf(preamble); @@ -189,11 +198,48 @@ public class DownloadService extends PageDecorator { } else { throw new IOException("Could not find JSON in " + src); } - } finally { - is.close(); } } + /** + * This installs itself as a listener to changes to the Downloadable extension list and will download the metadata + * for any newly added Downloadables. + */ + @Restricted(NoExternalUse.class) + public static class DownloadableListener extends ExtensionListListener { + + /** + * Install this listener to the Downloadable extension list after all extensions have been loaded; we only + * care about those that are added after initialization + */ + @Initializer(after = InitMilestone.EXTENSIONS_AUGMENTED) + public static void installListener() { + ExtensionList.lookup(Downloadable.class).addListener(new DownloadableListener()); + } + + /** + * Look for Downloadables that have no data, and update them. + */ + @Override + public void onChange() { + for (Downloadable d : Downloadable.all()) { + TextFile f = d.getDataFile(); + if (f == null || !f.exists()) { + LOGGER.log(Level.FINE, "Updating metadata for " + d.getId()); + try { + d.updateNow(); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Failed to update metadata for " + d.getId(), e); + } + } else { + LOGGER.log(Level.FINER, "Skipping update of metadata for " + d.getId()); + } + } + } + + private static final Logger LOGGER = Logger.getLogger(DownloadableListener.class.getName()); + } + /** * Represents a periodically updated JSON data file obtained from a remote URL. * @@ -258,6 +304,24 @@ public class DownloadService extends PageDecorator { return Jenkins.getInstance().getUpdateCenter().getDefaultBaseUrl()+"updates/"+url; } + /** + * URLs to download from. + */ + public List getUrls() { + List updateSites = new ArrayList(); + for (UpdateSite site : Jenkins.getActiveInstance().getUpdateCenter().getSiteList()) { + String siteUrl = site.getUrl(); + int baseUrlEnd = siteUrl.indexOf("update-center.json"); + if (baseUrlEnd != -1) { + String siteBaseUrl = siteUrl.substring(0, baseUrlEnd); + updateSites.add(siteBaseUrl + "updates/" + url); + } else { + LOGGER.log(Level.WARNING, "Url {0} does not look like an update center:", siteUrl); + } + } + return updateSites; + } + /** * How often do we retrieve the new image? * @@ -321,15 +385,6 @@ public class DownloadService extends PageDecorator { } private FormValidation load(String json, long dataTimestamp) throws IOException { - JSONObject o = JSONObject.fromObject(json); - - if (signatureCheck) { - FormValidation e = new JSONSignatureValidator("downloadable '"+id+"'").verifySignature(o); - if (e.kind!= Kind.OK) { - return e; - } - } - TextFile df = getDataFile(); df.write(json); df.file.setLastModified(dataTimestamp); @@ -339,7 +394,82 @@ public class DownloadService extends PageDecorator { @Restricted(NoExternalUse.class) public FormValidation updateNow() throws IOException { - return load(loadJSONHTML(new URL(getUrl() + ".html?id=" + URLEncoder.encode(getId(), "UTF-8") + "&version=" + URLEncoder.encode(Jenkins.VERSION, "UTF-8"))), System.currentTimeMillis()); + List jsonList = new ArrayList<>(); + boolean toolInstallerMetadataExists = false; + for (UpdateSite updatesite : Jenkins.getActiveInstance().getUpdateCenter().getSiteList()) { + String site = updatesite.getMetadataUrlForDownloadable(url); + if (site == null) { + return FormValidation.warning("The update site " + site + " does not look like an update center"); + } + String jsonString; + try { + jsonString = loadJSONHTML(new URL(site + ".html?id=" + URLEncoder.encode(getId(), "UTF-8") + "&version=" + URLEncoder.encode(Jenkins.VERSION, "UTF-8"))); + toolInstallerMetadataExists = true; + } catch (Exception e) { + LOGGER.log(Level.FINE, "Could not load json from " + site, e ); + continue; + } + JSONObject o = JSONObject.fromObject(jsonString); + if (signatureCheck) { + FormValidation e = updatesite.getJsonSignatureValidator(signatureValidatorPrefix +" '"+id+"'").verifySignature(o); + if (e.kind!= Kind.OK) { + LOGGER.log(Level.WARNING, "signature check failed for " + site, e ); + continue; + } + } + jsonList.add(o); + } + if (jsonList.size() == 0 && toolInstallerMetadataExists) { + return FormValidation.warning("None of the tool installer metadata passed the signature check"); + } else if (!toolInstallerMetadataExists) { + LOGGER.log(Level.WARNING, "No tool installer metadata found for " + id); + return FormValidation.ok(); + } + JSONObject reducedJson = reduce(jsonList); + return load(reducedJson.toString(), System.currentTimeMillis()); + } + + /** + * Function that takes multiple JSONObjects and returns a single one. + * @param jsonList to be processed + * @return a single JSONObject + */ + public JSONObject reduce(List jsonList) { + return jsonList.get(0); + } + + /** + * check if the list of update center entries has duplicates + * @param genericList list of entries coming from multiple update centers + * @param comparator the unique ID of an entry + * @param the generic class + * @return true if the list has duplicates, false otherwise + */ + public static boolean hasDuplicates (List genericList, String comparator) { + if (genericList.isEmpty()) { + return false; + } + Field field; + try { + field = genericList.get(0).getClass().getDeclaredField(comparator); + } catch (NoSuchFieldException e) { + LOGGER.warning("comparator: " + comparator + "does not exist for " + genericList.get(0).getClass() + ", " + e); + return false; + } + for (int i = 0; i < genericList.size(); i ++ ) { + T data1 = genericList.get(i); + for (int j = i + 1; j < genericList.size(); j ++ ) { + T data2 = genericList.get(j); + try { + if (field.get(data1).equals(field.get(data2))) { + return true; + } + } catch (IllegalAccessException e) { + LOGGER.warning("could not access field: " + comparator + ", " + e); + } + } + } + return false; } /** @@ -362,10 +492,10 @@ public class DownloadService extends PageDecorator { private static final Logger LOGGER = Logger.getLogger(Downloadable.class.getName()); private static final long DEFAULT_INTERVAL = - Long.getLong(Downloadable.class.getName()+".defaultInterval", DAYS.toMillis(1)); + SystemProperties.getLong(Downloadable.class.getName()+".defaultInterval", DAYS.toMillis(1)); } - public static boolean neverUpdate = Boolean.getBoolean(DownloadService.class.getName()+".never"); + public static boolean neverUpdate = SystemProperties.getBoolean(DownloadService.class.getName()+".never"); /** * May be used to temporarily disable signature checking on {@link DownloadService} and {@link UpdateCenter}. @@ -373,6 +503,6 @@ public class DownloadService extends PageDecorator { * Should only be used when {@link DownloadSettings#isUseBrowser}; * disabling signature checks for in-browser downloads is very dangerous as unprivileged users could submit spoofed metadata! */ - public static boolean signatureCheck = !Boolean.getBoolean(DownloadService.class.getName()+".noSignatureCheck"); + public static boolean signatureCheck = !SystemProperties.getBoolean(DownloadService.class.getName()+".noSignatureCheck"); } diff --git a/core/src/main/java/hudson/model/EnvironmentContributor.java b/core/src/main/java/hudson/model/EnvironmentContributor.java index d6d630bcb56c47eab192fed8f09a078255757301..77ea159b309b3efa7fcd55a81b811ffaf8e5f4b3 100644 --- a/core/src/main/java/hudson/model/EnvironmentContributor.java +++ b/core/src/main/java/hudson/model/EnvironmentContributor.java @@ -28,7 +28,6 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.scm.SCM; -import jenkins.model.Jenkins; import java.io.IOException; import javax.annotation.Nonnull; diff --git a/core/src/main/java/hudson/model/Executor.java b/core/src/main/java/hudson/model/Executor.java index 08864961ebd9c0f6d5cde2b5f29d208bbbd4ff03..d30ecf5da8892e1b92f2d7e6af7c4cc19ad96314 100644 --- a/core/src/main/java/hudson/model/Executor.java +++ b/core/src/main/java/hudson/model/Executor.java @@ -54,6 +54,7 @@ import java.io.StringWriter; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Vector; import java.util.concurrent.locks.ReadWriteLock; @@ -62,6 +63,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import static hudson.model.queue.Executables.*; +import java.util.Collection; import static java.util.logging.Level.*; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; @@ -113,10 +115,6 @@ public class Executor extends Thread implements ModelObject { @GuardedBy("lock") private WorkUnit workUnit; - private Throwable causeOfDeath; - - private boolean induceDeath; - @GuardedBy("lock") private boolean started; @@ -142,7 +140,34 @@ public class Executor extends Thread implements ModelObject { @Override public void interrupt() { - interrupt(Result.ABORTED); + if (Thread.currentThread() == this) { + // If you catch an InterruptedException the "correct" options are limited to one of two choices: + // 1. Propagate the exception; + // 2. Restore the Thread.currentThread().interrupted() flag + // The JVM locking support assumes such behaviour. + // Evil Jenkins overrides the interrupt() method so that when a different thread interrupts this thread + // we abort the build. + // but that causes JENKINS-28690 style deadlocks when the correctly written code does + // + // try { + // ... some long running thing ... + // } catch (InterruptedException e) { + // ... some tidy up + // // restore interrupted flag + // Thread.currentThread().interrupted(); + // } + // + // What about why we do not set the Result.ABORTED on this branch? + // That is a good question to ask, the answer is that the only time a thread should be restoring + // its own interrupted flag is when that thread has already been interrupted by another thread + // as such we should assume that the result has already been applied. If that assumption were + // incorrect, then the Run.execute's catch (InterruptedException) block will either set the result + // or have been escaped - in which case the result of the run has been sealed anyway so it does not + // matter. + super.interrupt(); + } else { + interrupt(Result.ABORTED); + } } void interruptForShutdown() { @@ -205,7 +230,14 @@ public class Executor extends Thread implements ModelObject { } public Result abortResult() { - lock.readLock().lock(); + // this method is almost always called as a result of the current thread being interrupted + // as a result we need to clean the interrupt flag so that the lock's lock method doesn't + // get confused and think it was interrupted while awaiting the lock + Thread.interrupted(); + // we need to use a write lock as we may be repeatedly interrupted while processing and + // we need the same lock as used in void interrupt(Result,boolean,CauseOfInterruption...) + // JENKINS-28690 + lock.writeLock().lock(); try { Result r = interruptStatus; if (r == null) r = @@ -213,7 +245,7 @@ public class Executor extends Thread implements ModelObject { return r; } finally { - lock.readLock().unlock(); + lock.writeLock().unlock(); } } @@ -250,19 +282,16 @@ public class Executor extends Thread implements ModelObject { */ private void resetWorkUnit(String reason) { StringWriter writer = new StringWriter(); - PrintWriter pw = new PrintWriter(writer); - try { + try (PrintWriter pw = new PrintWriter(writer)) { pw.printf("%s grabbed %s from queue but %s %s. ", getName(), workUnit, owner.getDisplayName(), reason); if (owner.getTerminatedBy().isEmpty()) { pw.print("No termination trace available."); } else { pw.println("Termination trace follows:"); - for (Computer.TerminationRequest request: owner.getTerminatedBy()) { + for (Computer.TerminationRequest request : owner.getTerminatedBy()) { request.printStackTrace(pw); } } - } finally { - pw.close(); } LOGGER.log(WARNING, writer.toString()); lock.writeLock().lock(); @@ -302,8 +331,6 @@ public class Executor extends Thread implements ModelObject { ACL.impersonate(ACL.SYSTEM); try { - if (induceDeath) throw new ThreadDeath(); - SubTask task; // transition from idle to building. // perform this state change as an atomic operation wrt other queue operations @@ -362,6 +389,9 @@ public class Executor extends Thread implements ModelObject { } if (executable instanceof Actionable) { + if (LOGGER.isLoggable(Level.FINER)) { + LOGGER.log(FINER, "when running {0} from {1} we are copying {2} actions whereas the item currently has {3}", new Object[] {executable, workUnit.context.item, workUnit.context.actions, workUnit.context.item.getAllActions()}); + } for (Action action: workUnit.context.actions) { ((Actionable) executable).addAction(action); } @@ -397,11 +427,7 @@ public class Executor extends Thread implements ModelObject { } catch (InterruptedException e) { LOGGER.log(FINE, getName()+" interrupted",e); // die peacefully - } catch(Exception e) { - causeOfDeath = e; - LOGGER.log(SEVERE, "Unexpected executor death", e); - } catch (Error e) { - causeOfDeath = e; + } catch(Exception | Error e) { LOGGER.log(SEVERE, "Unexpected executor death", e); } finally { if (asynchronousExecution == null) { @@ -430,10 +456,10 @@ public class Executor extends Thread implements ModelObject { } private void finish2() { - for (RuntimeException e1: owner.getTerminatedBy()) LOGGER.log(Level.WARNING, String.format("%s termination trace", getName()), e1); - if (causeOfDeath == null) {// let this thread die and be replaced by a fresh unstarted instance - owner.removeExecutor(this); + for (RuntimeException e1 : owner.getTerminatedBy()) { + LOGGER.log(Level.FINE, String.format("%s termination trace", getName()), e1); } + owner.removeExecutor(this); if (this instanceof OneOffExecutor) { owner.remove((OneOffExecutor) this); } @@ -450,13 +476,6 @@ public class Executor extends Thread implements ModelObject { asynchronousExecution = null; } - /** - * For testing only. Simulate a fatal unexpected failure. - */ - public void killHard() { - induceDeath = true; - } - /** * Returns the current build this executor is running. * @@ -472,6 +491,16 @@ public class Executor extends Thread implements ModelObject { lock.readLock().unlock(); } } + + /** + * Returns causes of interruption. + * + * @return Unmodifiable collection of causes of interruption. + * @since 1.617 + */ + public @Nonnull Collection getCausesOfInterruption() { + return Collections.unmodifiableCollection(causes); + } /** * Returns the current {@link WorkUnit} (of {@link #getCurrentExecutable() the current executable}) @@ -561,7 +590,7 @@ public class Executor extends Thread implements ModelObject { * on-demand creation of executor threads. Callers should use * this method instead of {@link #isAlive()}, which would be incorrect for * non-started threads or running {@link AsynchronousExecution}. - * @return True if the executor is available for tasks + * @return true if the executor is available for tasks (usually true) * @since 1.536 */ public boolean isActive() { @@ -615,13 +644,11 @@ public class Executor extends Thread implements ModelObject { } /** - * If this thread dies unexpectedly, obtain the cause of the failure. - * - * @return null if the death is expected death or the thread {@link #isActive}. - * @since 1.142 + * @deprecated no longer used */ - public Throwable getCauseOfDeath() { - return causeOfDeath; + @Deprecated + public @CheckForNull Throwable getCauseOfDeath() { + return null; } /** @@ -825,14 +852,10 @@ public class Executor extends Thread implements ModelObject { } /** - * Throws away this executor and get a new one. + * @deprecated now a no-op */ - @RequirePOST + @Deprecated public HttpResponse doYank() { - Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); - if (isActive()) - throw new Failure("Can't yank a live executor"); - owner.removeExecutor(this); return HttpResponses.redirectViaContextPath("/"); } @@ -910,8 +933,9 @@ public class Executor extends Thread implements ModelObject { * or null if it could not be found (for example because the execution has already completed) * @since 1.607 */ - public static @CheckForNull Executor of(Executable executable) { - Jenkins jenkins = Jenkins.getInstance(); + @CheckForNull + public static Executor of(Executable executable) { + Jenkins jenkins = Jenkins.getInstanceOrNull(); // TODO confirm safe to assume non-null and use getInstance() if (jenkins == null) { return null; } diff --git a/core/src/main/java/hudson/model/ExecutorListener.java b/core/src/main/java/hudson/model/ExecutorListener.java index 3c5e221f17f277d8bc2a9c53a3e587e36039f9cd..678a0ca702ad54314630fa972a5e663160deedc7 100644 --- a/core/src/main/java/hudson/model/ExecutorListener.java +++ b/core/src/main/java/hudson/model/ExecutorListener.java @@ -23,7 +23,6 @@ */ package hudson.model; -import hudson.slaves.SlaveComputer; /** * A listener for task related events from executors. diff --git a/core/src/main/java/hudson/model/Failure.java b/core/src/main/java/hudson/model/Failure.java index fa948901997dc6930271206810b7ffa0da30d83f..37fc2696b54291acebf80ece0a18af4ddcd6d83f 100644 --- a/core/src/main/java/hudson/model/Failure.java +++ b/core/src/main/java/hudson/model/Failure.java @@ -28,6 +28,7 @@ import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; +import javax.annotation.CheckForNull; import javax.servlet.ServletException; import java.io.IOException; @@ -54,6 +55,13 @@ public class Failure extends RuntimeException implements HttpResponse { this.pre = pre; } + public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node, @CheckForNull Throwable throwable) throws IOException, ServletException { + if (throwable != null) { + req.setAttribute("exception", throwable); + } + generateResponse(req, rsp, node); + } + public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { req.setAttribute("message",getMessage()); if(pre) diff --git a/core/src/main/java/hudson/model/FileParameterDefinition.java b/core/src/main/java/hudson/model/FileParameterDefinition.java index 761a179d98899f79bc291f9527aa3a2c33fd108c..c57d2bafc664f054b2a871240e864ada2f6eb20a 100644 --- a/core/src/main/java/hudson/model/FileParameterDefinition.java +++ b/core/src/main/java/hudson/model/FileParameterDefinition.java @@ -24,6 +24,7 @@ package hudson.model; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; import hudson.Extension; @@ -56,7 +57,7 @@ public class FileParameterDefinition extends ParameterDefinition { return p; } - @Extension + @Extension @Symbol({"file","fileParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { @@ -74,13 +75,10 @@ public class FileParameterDefinition extends ParameterDefinition { FileItem src; try { src = req.getFileItem( getName() ); - } catch (ServletException e) { + } catch (ServletException | IOException e) { // Not sure what to do here. We might want to raise this // but that would involve changing the throws for this call return null; - } catch (IOException e) { - // ditto above - return null; } if ( src == null ) { // the requested file parameter wasn't uploaded diff --git a/core/src/main/java/hudson/model/FileParameterValue.java b/core/src/main/java/hudson/model/FileParameterValue.java index 930eb41fd8ae4d7d0ca8c0c28ae9b6540cbad91b..817b67141585fc3ed6703ebde8da307bbe818bde 100644 --- a/core/src/main/java/hudson/model/FileParameterValue.java +++ b/core/src/main/java/hudson/model/FileParameterValue.java @@ -266,11 +266,8 @@ public class FileParameterValue extends ParameterValue { public byte[] get() { try { - FileInputStream inputStream = new FileInputStream(file); - try { + try (FileInputStream inputStream = new FileInputStream(file)) { return IOUtils.toByteArray(inputStream); - } finally { - inputStream.close(); } } catch (IOException e) { throw new Error(e); diff --git a/core/src/main/java/hudson/model/Fingerprint.java b/core/src/main/java/hudson/model/Fingerprint.java index 38927e5a11aef076a75fe259aee2017cc88129c9..2e33bdf2d070c85e6fb6a6f12ff0abc9aaa7be2e 100644 --- a/core/src/main/java/hudson/model/Fingerprint.java +++ b/core/src/main/java/hudson/model/Fingerprint.java @@ -25,7 +25,6 @@ package hudson.model; import com.google.common.collect.ImmutableList; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; @@ -40,6 +39,7 @@ import hudson.Extension; import hudson.model.listeners.ItemListener; import hudson.model.listeners.SaveableListener; import hudson.security.ACL; +import hudson.security.ACLContext; import hudson.util.AtomicFileWriter; import hudson.util.HexBinaryConverter; import hudson.util.Iterators; @@ -50,6 +50,7 @@ import java.io.EOFException; import jenkins.model.FingerprintFacet; import jenkins.model.Jenkins; import jenkins.model.TransientFingerprintFacetFactory; +import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -72,6 +73,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import org.acegisecurity.AccessDeniedException; +import org.acegisecurity.Authentication; import org.xmlpull.v1.XmlPullParserException; /** @@ -104,15 +107,37 @@ public class Fingerprint implements ModelObject, Saveable { /** * Gets {@link Job#getFullName() the full name of the job}. - *

- * Such job could be since then removed, - * so there might not be a corresponding - * {@link Job}. + * Such job could be since then removed, so there might not be a corresponding {@link Job}. + * + * @return A name of the job */ @Exported + @Nonnull public String getName() { return name; } + + /** + * Checks if the current user has permission to see this pointer. + * @return {@code true} if the job exists and user has {@link Item#READ} permissions + * or if the current user has {@link Jenkins#ADMINISTER} permissions. + * If the job exists, but the current user has no permission to discover it, + * {@code false} will be returned. + * If the job has been deleted and the user has no {@link Jenkins#ADMINISTER} permissions, + * it also returns {@code false} in order to avoid the job existence fact exposure. + */ + private boolean hasPermissionToDiscoverBuild() { + // We expose the data to Jenkins administrators in order to + // let them manage the data for deleted jobs (also works for SYSTEM) + final Jenkins instance = Jenkins.getInstance(); + if (instance.hasPermission(Jenkins.ADMINISTER)) { + return true; + } + + return canDiscoverItem(name); + } + + void setName(String newName) { name = newName; @@ -130,10 +155,11 @@ public class Fingerprint implements ModelObject, Saveable { /** * Gets the project build number. *

- * Such {@link Run} could be since then - * discarded. + * Such {@link Run} could be since then discarded. + * @return A build number */ @Exported + @Nonnull public int getNumber() { return number; } @@ -662,23 +688,87 @@ public class Fingerprint implements ModelObject, Saveable { */ public static RangeSet fromString(String list, boolean skipError) { RangeSet rs = new RangeSet(); - for (String s : Util.tokenize(list,",")) { + + // Reject malformed ranges like "1---10", "1,,,,3" etc. + if (list.contains("--") || list.contains(",,")) { + if (!skipError) { + throw new IllegalArgumentException( + String.format("Unable to parse '%s', expected correct notation M,N or M-N", list)); + } + // ignore malformed notation + return rs; + } + + String[] items = Util.tokenize(list,","); + if(items.length > 1 && items.length <= StringUtils.countMatches(list, ",")) { + if (!skipError) { + throw new IllegalArgumentException( + String.format("Unable to parse '%s', expected correct notation M,N or M-N", list)); + } + // ignore malformed notation like ",1,2" or "1,2," + return rs; + } + + for (String s : items) { s = s.trim(); // s is either single number or range "x-y". // note that the end range is inclusive in this notation, but not in the Range class try { + if (s.isEmpty()) { + if (!skipError) { + throw new IllegalArgumentException( + String.format("Unable to parse '%s', expected number", list)); } + // ignore "" element + continue; + } + if(s.contains("-")) { + if(StringUtils.countMatches(s, "-") > 1) { + if (!skipError) { + throw new IllegalArgumentException(String.format( + "Unable to parse '%s', expected correct notation M,N or M-N", list)); + } + // ignore malformed ranges like "-5-2" or "2-5-" + continue; + } String[] tokens = Util.tokenize(s,"-"); - rs.ranges.add(new Range(Integer.parseInt(tokens[0]),Integer.parseInt(tokens[1])+1)); + if (tokens.length == 2) { + int left = Integer.parseInt(tokens[0]); + int right = Integer.parseInt(tokens[1]); + if(left < 0 || right < 0) { + if (!skipError) { + throw new IllegalArgumentException( + String.format("Unable to parse '%s', expected number above zero", list)); + } + // ignore a range which starts or ends under zero like "-5-3" + continue; + } + if(left > right) { + if (!skipError) { + throw new IllegalArgumentException(String.format( + "Unable to parse '%s', expected string with a range M-N where M _getUsages() { List r = new ArrayList(); - for (Entry e : usages.entrySet()) - r.add(new RangeItem(e.getKey(),e.getValue())); + final Jenkins instance = Jenkins.getInstance(); + for (Entry e : usages.entrySet()) { + final String itemName = e.getKey(); + if (instance.hasPermission(Jenkins.ADMINISTER) || canDiscoverItem(itemName)) { + r.add(new RangeItem(itemName, e.getValue())); + } + } return r; } @@ -1314,8 +1411,70 @@ public class Fingerprint implements ModelObject, Saveable { @Override public String toString() { return "Fingerprint[original=" + original + ",hash=" + getHashString() + ",fileName=" + fileName + ",timestamp=" + DATE_CONVERTER.toString(timestamp) + ",usages=" + new TreeMap(usages) + ",facets=" + facets + "]"; } + + /** + * Checks if the current user can Discover the item. + * If yes, it may be displayed as a text in Fingerprint UIs. + * @param fullName Full name of the job + * @return {@code true} if the user can discover the item + */ + private static boolean canDiscoverItem(@Nonnull final String fullName) { + final Jenkins jenkins = Jenkins.getInstance(); + + // Fast check to avoid security context switches + Item item = null; + try { + item = jenkins.getItemByFullName(fullName); + } catch (AccessDeniedException ex) { + // ignore, we will fall-back later + } + if (item != null) { + return true; + } + + // Probably it failed due to the missing Item.DISCOVER + // We try to retrieve the job using SYSTEM user and to check permissions manually. + final Authentication userAuth = Jenkins.getAuthentication(); + try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + final Item itemBySystemUser = jenkins.getItemByFullName(fullName); + if (itemBySystemUser == null) { + return false; + } + + // To get the item existence fact, a user needs Item.DISCOVER for the item + // and Item.READ for all container folders. + boolean canDiscoverTheItem = itemBySystemUser.getACL().hasPermission(userAuth, Item.DISCOVER); + if (canDiscoverTheItem) { + ItemGroup current = itemBySystemUser.getParent(); + do { + if (current instanceof Item) { + final Item i = (Item) current; + current = i.getParent(); + if (!i.getACL().hasPermission(userAuth, Item.READ)) { + canDiscoverTheItem = false; + } + } else { + current = null; + } + } while (canDiscoverTheItem && current != null); + } + return canDiscoverTheItem; + } + } + + private static final XStream2 XSTREAM = new XStream2(); + + /** + * Provides the XStream instance this class is using for serialization. + * + * @return the XStream instance + * @since 1.655 + */ + @Nonnull + public static XStream2 getXStream() { + return XSTREAM; + } - private static final XStream XSTREAM = new XStream2(); static { XSTREAM.alias("fingerprint",Fingerprint.class); XSTREAM.alias("range",Range.class); diff --git a/core/src/main/java/hudson/model/FingerprintCleanupThread.java b/core/src/main/java/hudson/model/FingerprintCleanupThread.java index 98fa48b72c5a594914b6173012088610e580778f..10716d073f761bbd125be8ade55289a21d355908 100644 --- a/core/src/main/java/hudson/model/FingerprintCleanupThread.java +++ b/core/src/main/java/hudson/model/FingerprintCleanupThread.java @@ -26,6 +26,7 @@ package hudson.model; import hudson.Extension; import hudson.ExtensionList; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import java.io.File; import java.io.FileFilter; @@ -42,7 +43,7 @@ import java.util.regex.Pattern; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("fingerprintCleanup") public final class FingerprintCleanupThread extends AsyncPeriodicWork { public FingerprintCleanupThread() { diff --git a/core/src/main/java/hudson/model/FreeStyleProject.java b/core/src/main/java/hudson/model/FreeStyleProject.java index 8ba9672ee8770bd377439acfccddcbf14773ca10..aecfc5cba22d7e1451b0f50a106ecb4fbabf157f 100644 --- a/core/src/main/java/hudson/model/FreeStyleProject.java +++ b/core/src/main/java/hudson/model/FreeStyleProject.java @@ -25,6 +25,10 @@ package hudson.model; import hudson.Extension; import jenkins.model.Jenkins; +import org.jenkins.ui.icon.Icon; +import org.jenkins.ui.icon.IconSet; +import org.jenkinsci.Symbol; +import jenkins.model.item_category.StandaloneProjectsCategory; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -59,12 +63,19 @@ public class FreeStyleProject extends Project i /** * Descriptor is instantiated as a field purely for backward compatibility. * Do not do this in your code. Put @Extension on your DescriptorImpl class instead. + * + * @deprecated as of 2.0 + * Use injection */ @Restricted(NoExternalUse.class) - @Extension(ordinal=1000) - public static final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); + public static /*almost final*/ DescriptorImpl DESCRIPTOR; + + @Extension(ordinal=1000) @Symbol({"freeStyle","freeStyleJob"}) + public static class DescriptorImpl extends AbstractProjectDescriptor { + public DescriptorImpl() { + DESCRIPTOR = this; + } - public static final class DescriptorImpl extends AbstractProjectDescriptor { public String getDisplayName() { return Messages.FreeStyleProject_DisplayName(); } @@ -72,5 +83,32 @@ public class FreeStyleProject extends Project i public FreeStyleProject newInstance(ItemGroup parent, String name) { return new FreeStyleProject(parent,name); } + + @Override + public String getDescription() { + return Messages.FreeStyleProject_Description(); + } + + @Override + public String getCategoryId() { + return StandaloneProjectsCategory.ID; + } + + @Override + public String getIconFilePathPattern() { + return (Jenkins.RESOURCE_PATH + "/images/:size/freestyleproject.png").replaceFirst("^/", ""); + } + + @Override + public String getIconClassName() { + return "icon-freestyle-project"; + } + + static { + IconSet.icons.addIcon(new Icon("icon-freestyle-project icon-sm", "16x16/freestyleproject.png", Icon.ICON_SMALL_STYLE)); + IconSet.icons.addIcon(new Icon("icon-freestyle-project icon-md", "24x24/freestyleproject.png", Icon.ICON_MEDIUM_STYLE)); + IconSet.icons.addIcon(new Icon("icon-freestyle-project icon-lg", "32x32/freestyleproject.png", Icon.ICON_LARGE_STYLE)); + IconSet.icons.addIcon(new Icon("icon-freestyle-project icon-xlg", "48x48/freestyleproject.png", Icon.ICON_XLARGE_STYLE)); + } } } diff --git a/core/src/main/java/hudson/model/FullDuplexHttpChannel.java b/core/src/main/java/hudson/model/FullDuplexHttpChannel.java index 6372b60ed21b917ec65346f035e188f8f5078e87..c0fdafb56f2b71028544dfa7d591d9c2237c3c9b 100644 --- a/core/src/main/java/hudson/model/FullDuplexHttpChannel.java +++ b/core/src/main/java/hudson/model/FullDuplexHttpChannel.java @@ -23,6 +23,7 @@ */ package hudson.model; +import jenkins.util.SystemProperties; import hudson.remoting.Channel; import hudson.remoting.PingThread; import hudson.remoting.Channel.Mode; @@ -39,7 +40,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -154,7 +154,7 @@ abstract public class FullDuplexHttpChannel { * Set to true if the servlet container doesn't support chunked encoding. */ @Restricted(NoExternalUse.class) - public static boolean DIY_CHUNKING = Boolean.getBoolean("hudson.diyChunking"); + public static boolean DIY_CHUNKING = SystemProperties.getBoolean("hudson.diyChunking"); /** * Controls the time out of waiting for the 2nd HTTP request to arrive. diff --git a/core/src/main/java/hudson/model/HealthReport.java b/core/src/main/java/hudson/model/HealthReport.java index bf8c776d77b3a98c900533e1ad242dc698b93afe..0217a211abc600c6fd0b3e4d3f944e6ebd259432 100644 --- a/core/src/main/java/hudson/model/HealthReport.java +++ b/core/src/main/java/hudson/model/HealthReport.java @@ -325,6 +325,7 @@ public class HealthReport implements Serializable, Comparable { /** * {@inheritDoc} */ + @Override public int compareTo(HealthReport o) { return (this.score < o.score ? -1 : (this.score == o.score ? 0 : 1)); } diff --git a/core/src/main/java/hudson/model/Hudson.java b/core/src/main/java/hudson/model/Hudson.java index 17b5721a4568db28e3811365c94b15c796bf2eda..02b9d949a846e9c274abbb436aa1036f76053bb3 100644 --- a/core/src/main/java/hudson/model/Hudson.java +++ b/core/src/main/java/hudson/model/Hudson.java @@ -34,6 +34,7 @@ import hudson.model.listeners.ItemListener; import hudson.slaves.ComputerListener; import hudson.util.CopyOnWriteList; import hudson.util.FormValidation; +import javax.annotation.Nonnull; import jenkins.model.Jenkins; import org.jvnet.hudson.reactor.ReactorException; import org.kohsuke.stapler.QueryParameter; @@ -47,9 +48,7 @@ import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.text.ParseException; -import java.util.Collections; import java.util.List; -import java.util.Map; import static hudson.Util.fixEmpty; import javax.annotation.CheckForNull; @@ -73,7 +72,8 @@ public class Hudson extends Jenkins { /** @deprecated Here only for compatibility. Use {@link Jenkins#getInstance} instead. */ @Deprecated @CLIResolver - public static @CheckForNull Hudson getInstance() { + @Nonnull + public static Hudson getInstance() { return (Hudson)Jenkins.getInstance(); } @@ -108,7 +108,7 @@ public class Hudson extends Jenkins { } /** - * Gets the slave node of the give name, hooked under this Hudson. + * Gets the agent of the give name, hooked under this Hudson. * * @deprecated * Use {@link #getNode(String)}. Since 1.252. @@ -131,7 +131,7 @@ public class Hudson extends Jenkins { } /** - * Updates the slave list. + * Updates the agent list. * * @deprecated * Use {@link #setNodes(List)}. Since 1.252. diff --git a/core/src/main/java/hudson/model/Item.java b/core/src/main/java/hudson/model/Item.java index 94ee4181de75c7394031c213f29b0acc61dc5376..a63a7d49e7227aeea3c02ecff4d01f7c96b1fa07 100644 --- a/core/src/main/java/hudson/model/Item.java +++ b/core/src/main/java/hudson/model/Item.java @@ -25,7 +25,9 @@ package hudson.model; import hudson.Functions; +import jenkins.util.SystemProperties; import hudson.security.PermissionScope; +import jenkins.util.io.OnMaster; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -35,6 +37,7 @@ import hudson.search.SearchableModelObject; import hudson.security.Permission; import hudson.security.PermissionGroup; import hudson.security.AccessControlled; +import hudson.util.Secret; /** * Basic configuration unit in Hudson. @@ -65,7 +68,7 @@ import hudson.security.AccessControlled; * @see Items * @see ItemVisitor */ -public interface Item extends PersistenceRoot, SearchableModelObject, AccessControlled { +public interface Item extends PersistenceRoot, SearchableModelObject, AccessControlled, OnMaster { /** * Gets the parent that contains this item. */ @@ -226,7 +229,12 @@ public interface Item extends PersistenceRoot, SearchableModelObject, AccessCont Permission CONFIGURE = new Permission(PERMISSIONS, "Configure", Messages._Item_CONFIGURE_description(), Permission.CONFIGURE, PermissionScope.ITEM); Permission READ = new Permission(PERMISSIONS, "Read", Messages._Item_READ_description(), Permission.READ, PermissionScope.ITEM); Permission DISCOVER = new Permission(PERMISSIONS, "Discover", Messages._AbstractProject_DiscoverPermission_Description(), READ, PermissionScope.ITEM); - Permission EXTENDED_READ = new Permission(PERMISSIONS,"ExtendedRead", Messages._AbstractProject_ExtendedReadPermission_Description(), CONFIGURE, Boolean.getBoolean("hudson.security.ExtendedReadPermission"), new PermissionScope[]{PermissionScope.ITEM}); + /** + * Ability to view configuration details. + * If the user lacks {@link CONFIGURE} then any {@link Secret}s must be masked out, even in encrypted form. + * @see Secret#ENCRYPTED_VALUE_PATTERN + */ + Permission EXTENDED_READ = new Permission(PERMISSIONS,"ExtendedRead", Messages._AbstractProject_ExtendedReadPermission_Description(), CONFIGURE, SystemProperties.getBoolean("hudson.security.ExtendedReadPermission"), new PermissionScope[]{PermissionScope.ITEM}); // TODO the following really belong in Job, not Item, but too late to move since the owner.name is encoded in the ID: Permission BUILD = new Permission(PERMISSIONS, "Build", Messages._AbstractProject_BuildPermission_Description(), Permission.UPDATE, PermissionScope.ITEM); Permission WORKSPACE = new Permission(PERMISSIONS, "Workspace", Messages._AbstractProject_WorkspacePermission_Description(), Permission.READ, PermissionScope.ITEM); diff --git a/core/src/main/java/hudson/model/ItemGroup.java b/core/src/main/java/hudson/model/ItemGroup.java index ace90e16b4354ec2f98dd022e7dce4d9cced37f6..0de4fa477bd3fda285bd390f787c80fdbe961398 100644 --- a/core/src/main/java/hudson/model/ItemGroup.java +++ b/core/src/main/java/hudson/model/ItemGroup.java @@ -23,7 +23,6 @@ */ package hudson.model; -import hudson.model.listeners.ItemListener; import java.io.IOException; import java.util.Collection; import java.io.File; diff --git a/core/src/main/java/hudson/model/ItemGroupMixIn.java b/core/src/main/java/hudson/model/ItemGroupMixIn.java index ecf4d2d6e802786a1aa4ea303960338d6d8fc3ab..3ec7d8fa5cc24d902d290fc3494bc7238859f62c 100644 --- a/core/src/main/java/hudson/model/ItemGroupMixIn.java +++ b/core/src/main/java/hudson/model/ItemGroupMixIn.java @@ -29,14 +29,18 @@ import hudson.model.listeners.ItemListener; import hudson.security.AccessControlled; import hudson.util.CopyOnWriteMap; import hudson.util.Function1; -import hudson.util.IOUtils; +import hudson.util.Secret; import jenkins.model.Jenkins; -import org.acegisecurity.AccessDeniedException; +import jenkins.util.xml.XMLUtils; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.stream.StreamSource; import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -44,7 +48,10 @@ import java.io.InputStream; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; import jenkins.security.NotReallyRoleSensitiveCallable; +import org.acegisecurity.AccessDeniedException; +import org.xml.sax.SAXException; /** * Defines a bunch of static methods to be used as a "mix-in" for {@link ItemGroup} @@ -104,11 +111,11 @@ public abstract class ItemGroupMixIn { // Try to retain the identity of an existing child object if we can. V item = (V) parent.getItem(subdir.getName()); if (item == null) { - XmlFile xmlFile = Items.getConfigFile( subdir ); + XmlFile xmlFile = Items.getConfigFile(subdir); if (xmlFile.exists()) { - item = (V) Items.load( parent, subdir ); - }else{ - Logger.getLogger( ItemGroupMixIn.class.getName() ).log( Level.WARNING, "could not find file " + xmlFile.getFile()); + item = (V) Items.load(parent, subdir); + } else { + Logger.getLogger(ItemGroupMixIn.class.getName()).log(Level.WARNING, "could not find file " + xmlFile.getFile()); continue; } } else { @@ -133,7 +140,7 @@ public abstract class ItemGroupMixIn { }; /** - * Creates a {@link TopLevelItem} from the submission of the '/lib/hudson/newFromList/formList' + * Creates a {@link TopLevelItem} for example from the submission of the {@code /lib/hudson/newFromList/form} tag * or throws an exception if it fails. */ public synchronized TopLevelItem createTopLevelItem( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { @@ -142,10 +149,14 @@ public abstract class ItemGroupMixIn { TopLevelItem result; String requestContentType = req.getContentType(); - if(requestContentType==null) + String mode = req.getParameter("mode"); + if (requestContentType == null + && !(mode != null && mode.equals("copy"))) throw new Failure("No Content-Type header set"); - boolean isXmlSubmission = requestContentType.startsWith("application/xml") || requestContentType.startsWith("text/xml"); + boolean isXmlSubmission = requestContentType != null + && (requestContentType.startsWith("application/xml") + || requestContentType.startsWith("text/xml")); String name = req.getParameter("name"); if(name==null) @@ -158,17 +169,11 @@ public abstract class ItemGroupMixIn { throw new Failure(Messages.Hudson_JobAlreadyExists(name)); } - String mode = req.getParameter("mode"); if(mode!=null && mode.equals("copy")) { String from = req.getParameter("from"); // resolve a name to Item - Item src = null; - if (!from.startsWith("/")) - src = parent.getItem(from); - if (src==null) - src = Jenkins.getInstance().getItemByFullName(from); - + Item src = Jenkins.getInstance().getItem(from, parent); if(src==null) { if(Util.fixEmpty(from)==null) throw new Failure("Specify which job to copy"); @@ -217,13 +222,23 @@ public abstract class ItemGroupMixIn { public synchronized T copy(T src, String name) throws IOException { acl.checkPermission(Item.CREATE); src.checkPermission(Item.EXTENDED_READ); + XmlFile srcConfigFile = Items.getConfigFile(src); + if (!src.hasPermission(Item.CONFIGURE)) { + Matcher matcher = AbstractItem.SECRET_PATTERN.matcher(srcConfigFile.asString()); + while (matcher.find()) { + if (Secret.decrypt(matcher.group(1)) != null) { + // AccessDeniedException2 does not permit a custom message, and anyway redirecting the user to the login screen is obviously pointless. + throw new AccessDeniedException(Messages.ItemGroupMixIn_may_not_copy_as_it_contains_secrets_and_(src.getFullName(), Jenkins.getAuthentication().getName(), Item.PERMISSIONS.title, Item.EXTENDED_READ.name, Item.CONFIGURE.name)); + } + } + } src.getDescriptor().checkApplicableIn(parent); acl.getACL().checkCreatePermission(parent, src.getDescriptor()); T result = (T)createProject(src.getDescriptor(),name,false); // copy config - Util.copyFile(Items.getConfigFile(src).getFile(),Items.getConfigFile(result).getFile()); + Util.copyFile(srcConfigFile.getFile(), Items.getConfigFile(result).getFile()); // reload from the new config final File rootDir = result.getRootDir(); @@ -256,7 +271,7 @@ public abstract class ItemGroupMixIn { dir.mkdirs(); boolean success = false; try { - IOUtils.copy(xml,configXml); + XMLUtils.safeTransform((Source)new StreamSource(xml), new StreamResult(configXml)); // load it TopLevelItem result = Items.whileUpdatingByXml(new NotReallyRoleSensitiveCallable() { @@ -274,6 +289,12 @@ public abstract class ItemGroupMixIn { Jenkins.getInstance().rebuildDependencyGraphAsync(); return result; + } catch (TransformerException e) { + success = false; + throw new IOException("Failed to persist config.xml", e); + } catch (SAXException e) { + success = false; + throw new IOException("Failed to persist config.xml", e); } catch (IOException e) { success = false; throw e; diff --git a/core/src/main/java/hudson/model/Items.java b/core/src/main/java/hudson/model/Items.java index 26efd209b5e8ce51c2b3f5bf7cc287984fdedc8e..0b457293ab29aa8d61dc2b80405721b7194b0587 100644 --- a/core/src/main/java/hudson/model/Items.java +++ b/core/src/main/java/hudson/model/Items.java @@ -120,7 +120,7 @@ public class Items { * Returns all the registered {@link TopLevelItemDescriptor}s that the current security principal is allowed to * create within the specified item group. * - * @since TODO + * @since 1.607 */ public static List all(ItemGroup c) { return all(Jenkins.getAuthentication(), c); @@ -130,7 +130,7 @@ public class Items { * Returns all the registered {@link TopLevelItemDescriptor}s that the specified security principal is allowed to * create within the specified item group. * - * @since TODO + * @since 1.607 */ public static List all(Authentication a, ItemGroup c) { List result = new ArrayList(); @@ -182,15 +182,21 @@ public class Items { * Does the opposite of {@link #toNameList(Collection)}. */ public static List fromNameList(ItemGroup context, @Nonnull String list, @Nonnull Class type) { - Jenkins hudson = Jenkins.getInstance(); - + final Jenkins jenkins = Jenkins.getInstance(); + List r = new ArrayList(); + if (jenkins == null) { + return r; + } + StringTokenizer tokens = new StringTokenizer(list,","); while(tokens.hasMoreTokens()) { String fullName = tokens.nextToken().trim(); - T item = hudson.getItem(fullName, context, type); - if(item!=null) - r.add(item); + if (StringUtils.isNotEmpty(fullName)) { + T item = jenkins.getItem(fullName, context, type); + if(item!=null) + r.add(item); + } } return r; } @@ -204,7 +210,7 @@ public class Items { String[] c = context.getFullName().split("/"); String[] p = path.split("/"); - Stack name = new Stack(); + Stack name = new Stack(); for (int i=0; i, EnvironmentSpecific { /** - * Name of the “default JDK”, meaning no specific JDK selected. + * Name of the “System JDK”, which is just the JDK on Jenkins' $PATH. * @since 1.577 */ - public static final String DEFAULT_NAME = "(Default)"; + public static final String DEFAULT_NAME = "(System)"; + + @Restricted(NoExternalUse.class) + public static boolean isDefaultName(String name) { + if ("(Default)".equals(name)) { + // DEFAULT_NAME took this value prior to 1.598. + return true; + } + return DEFAULT_NAME.equals(name) || name == null; + } /** * @deprecated since 2009-02-25 @@ -155,7 +167,7 @@ public final class JDK extends ToolInstallation implements NodeSpecific, En } } - @Extension + @Extension @Symbol("jdk") public static class DescriptorImpl extends ToolDescriptor { public String getDisplayName() { @@ -166,11 +178,8 @@ public final class JDK extends ToolInstallation implements NodeSpecific, En return Jenkins.getInstance().getJDKs().toArray(new JDK[0]); } - // this isn't really synchronized well since the list is Hudson.jdks :( - public @Override synchronized void setInstallations(JDK... jdks) { - List list = Jenkins.getInstance().getJDKs(); - list.clear(); - list.addAll(Arrays.asList(jdks)); + public @Override void setInstallations(JDK... jdks) { + Jenkins.getInstance().setJDKs(Arrays.asList(jdks)); } @Override diff --git a/core/src/main/java/hudson/model/Job.java b/core/src/main/java/hudson/model/Job.java index 286c7aba32661221dd06310bd2f87e22d08e80fa..9dc1e2752a951be598374d2a58b440b132c99df9 100644 --- a/core/src/main/java/hudson/model/Job.java +++ b/core/src/main/java/hudson/model/Job.java @@ -23,10 +23,8 @@ */ package hudson.model; -import com.google.common.base.Function; -import com.google.common.collect.Collections2; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; - +import hudson.BulkChange; import hudson.EnvVars; import hudson.Extension; import hudson.ExtensionPoint; @@ -62,15 +60,37 @@ import hudson.util.TextFile; import hudson.widgets.HistoryWidget; import hudson.widgets.HistoryWidget.Adapter; import hudson.widgets.Widget; +import java.awt.Color; +import java.awt.Paint; +import java.io.File; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.GregorianCalendar; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.SortedMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.servlet.ServletException; import jenkins.model.BuildDiscarder; +import jenkins.model.BuildDiscarderProperty; import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; +import jenkins.model.ModelObjectWithChildren; import jenkins.model.ProjectNamingStrategy; +import jenkins.model.RunIdMigrator; +import jenkins.model.lazy.LazyBuildMixIn; import jenkins.security.HexStringConfidentialKey; import jenkins.util.io.OnMaster; import net.sf.json.JSONException; import net.sf.json.JSONObject; - import org.apache.commons.io.FileUtils; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; @@ -83,6 +103,8 @@ import org.jfree.chart.renderer.category.StackedAreaRenderer; import org.jfree.data.category.CategoryDataset; import org.jfree.ui.RectangleInsets; import org.jvnet.localizer.Localizable; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.stapler.StaplerOverridable; @@ -91,24 +113,8 @@ import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.interceptor.RequirePOST; -import javax.servlet.ServletException; - -import java.awt.*; -import java.io.*; -import java.net.URLEncoder; -import java.util.*; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - -import static javax.servlet.http.HttpServletResponse.*; -import jenkins.model.ModelObjectWithChildren; -import jenkins.model.RunIdMigrator; -import jenkins.model.lazy.LazyBuildMixIn; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; +import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; +import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; /** * A job is an runnable entity under the monitoring of Hudson. @@ -122,7 +128,9 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; * @author Kohsuke Kawaguchi */ public abstract class Job, RunT extends Run> - extends AbstractItem implements ExtensionPoint, StaplerOverridable, ModelObjectWithChildren, OnMaster { + extends AbstractItem implements ExtensionPoint, StaplerOverridable, ModelObjectWithChildren { + + private static final Logger LOGGER = Logger.getLogger(Job.class.getName()); /** * Next build number. Kept in a separate file because this is the only @@ -147,6 +155,7 @@ public abstract class Job, RunT extends Run, RunT extends Run> properties = new CopyOnWriteList>(); @@ -203,24 +212,16 @@ public abstract class Job, RunT extends Run foldersInt = Collections2.transform(Arrays.asList(folders), new Function() { - public Integer apply(File file) { - return Integer.parseInt(file.getName()); - } - }); - this.nextBuildNumber = Collections.max(foldersInt) + 1; + RunT lB = getLastBuild(); + synchronized (this) { + this.nextBuildNumber = lB != null ? lB.getNumber() + 1 : 1; + } + saveNextBuildNumber(); } - saveNextBuildNumber(); } } else { // From the old Hudson, or doCreateItem. Create this file now. @@ -366,6 +367,7 @@ public abstract class Job, RunT extends Run, RunT extends Run, RunT extends Run, RunT extends Run> getProperties() { - return Descriptor.toMap((Iterable) properties); + Map result = Descriptor.toMap((Iterable) properties); + if (logRotator != null) { + result.put(Jenkins.getActiveInstance().getDescriptorByType(BuildDiscarderProperty.DescriptorImpl.class), new BuildDiscarderProperty(logRotator)); + } + return result; } /** @@ -561,6 +572,13 @@ public abstract class Job, RunT extends Run T getProperty(Class clazz) { + if (clazz == BuildDiscarderProperty.class && logRotator != null) { + return clazz.cast(new BuildDiscarderProperty(logRotator)); + } + return _getProperty(clazz); + } + + private T _getProperty(Class clazz) { for (JobProperty p : properties) { if (clazz.isInstance(p)) return clazz.cast(p); @@ -680,7 +698,7 @@ public abstract class Job, RunT extends Run getBuilds() { - return RunList.fromRuns(_getRuns().values()); + return RunList.fromRuns(_getRuns().values()); } /** @@ -712,7 +730,7 @@ public abstract class Job, RunT extends Run getBuildsAsMap() { - return Collections.unmodifiableSortedMap(_getRuns()); + return Collections.unmodifiableSortedMap(_getRuns()); } /** @@ -798,7 +816,7 @@ public abstract class Job, RunT extends Run, RunT extends Run, RunT extends Run runs = _getRuns(); + if (runs instanceof RunMap) { + RunMap runMap = (RunMap) runs; + for (int index = i.getNumber(); index > u.getNumber() && totalCount < 5; index--) { + if (runMap.runExists(index)) { + totalCount++; + } + } + if (totalCount < 5) { + // start loading from the first failure as we counted the rest + i = u; + } + } + } while (totalCount < 5 && i != null) { switch (i.getIconColor()) { case BLUE: @@ -1185,10 +1226,7 @@ public abstract class Job, RunT extends Run, JobPropertyDescriptor> t = new DescribableList, JobPropertyDescriptor>(NOOP,getAllProperties()); JSONObject jsonProperties = json.optJSONObject("properties"); @@ -1210,7 +1248,8 @@ public abstract class Job, RunT extends Run, RunT extends Run - * {@link Plugin}s can extend this to define custom properties + * Plugins can extend this to define custom properties * for {@link Job}s. {@link JobProperty}s show up in the user * configuration screen, and they are persisted with the job object. * @@ -63,6 +65,8 @@ import org.kohsuke.stapler.export.ExportedBean; * and {@link #prebuild(AbstractBuild, BuildListener)} are invoked after those * of {@link Publisher}s. * + *

Consider extending {@link OptionalJobProperty} instead. + * * @param * When you restrict your job property to be only applicable to a certain * subtype of {@link Job}, you can use this type parameter to improve @@ -96,6 +100,7 @@ public abstract class JobProperty> implements ReconfigurableD /** * {@inheritDoc} */ + @Override public JobPropertyDescriptor getDescriptor() { return (JobPropertyDescriptor) Jenkins.getInstance().getDescriptorOrDie(getClass()); } @@ -129,6 +134,7 @@ public abstract class JobProperty> implements ReconfigurableD * @see ProminentProjectAction * @see PermalinkProjectAction */ + @Nonnull public Collection getJobActions(J job) { // delegate to getJobAction (singular) for backward compatible behavior Action a = getJobAction(job); @@ -150,6 +156,7 @@ public abstract class JobProperty> implements ReconfigurableD *

* Invoked after {@link Publisher}s have run. */ + @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { return true; } @@ -166,6 +173,7 @@ public abstract class JobProperty> implements ReconfigurableD return getJobAction((J)project); } + @Nonnull public final Collection getProjectActions(AbstractProject project) { return getJobActions((J)project); } diff --git a/core/src/main/java/hudson/model/JobPropertyDescriptor.java b/core/src/main/java/hudson/model/JobPropertyDescriptor.java index a894370fb8eff2cc4fba6e49c8e14bffb0d0b6c3..2af8f74bc14fe5db129b5fbc678da7c089b9a7c3 100644 --- a/core/src/main/java/hudson/model/JobPropertyDescriptor.java +++ b/core/src/main/java/hudson/model/JobPropertyDescriptor.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.Collection; import java.lang.reflect.Type; import java.lang.reflect.ParameterizedType; +import jenkins.model.OptionalJobProperty; import net.sf.json.JSONObject; @@ -60,7 +61,7 @@ public abstract class JobPropertyDescriptor extends Descriptor> { * {@inheritDoc} * * @return - * null to avoid setting an instance of {@link JobProperty} to the target project. + * null to avoid setting an instance of {@link JobProperty} to the target project (or just use {@link OptionalJobProperty}) */ @Override public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { diff --git a/core/src/main/java/hudson/model/Label.java b/core/src/main/java/hudson/model/Label.java index f0a2df24744284c61f61cebcee18ef4f7b1e4b3f..74a9fa6901619b4e5cc581aae998d1e50e439c5b 100644 --- a/core/src/main/java/hudson/model/Label.java +++ b/core/src/main/java/hudson/model/Label.java @@ -85,6 +85,7 @@ public abstract class Label extends Actionable implements Comparable

* The answer is yes if there is a reasonable basis to believe that Hudson can have * an executor under this label, given the current configuration. This includes - * situations such as (1) there are offline slaves that have this label (2) clouds exist - * that can provision slaves that have this label. + * situations such as (1) there are offline agents that have this label (2) clouds exist + * that can provision agents that have this label. */ public boolean isAssignable() { for (Node n : getNodes()) @@ -369,13 +370,17 @@ public abstract class Label extends Actionable implements Comparable

* As a special case, {@link Jenkins} extends from here. @@ -80,20 +83,19 @@ import org.kohsuke.stapler.export.Exported; * *

* There is no URL binding for {@link Node}. {@link Computer} and {@link TransientComputerActionFactory} must - * be used to associate new {@link Action}s to slaves. + * be used to associate new {@link Action}s to agents. * * @author Kohsuke Kawaguchi - * @see NodeMonitor * @see NodeDescriptor * @see Computer */ @ExportedBean -public abstract class Node extends AbstractModelObject implements ReconfigurableDescribable, ExtensionPoint, AccessControlled, OnMaster { +public abstract class Node extends AbstractModelObject implements ReconfigurableDescribable, ExtensionPoint, AccessControlled, OnMaster, Saveable { private static final Logger LOGGER = Logger.getLogger(Node.class.getName()); /** - * Newly copied slaves get this flag set, so that Jenkins doesn't try to start/remove this node until its configuration + * Newly copied agents get this flag set, so that Jenkins doesn't try to start/remove this node until its configuration * is saved once. */ protected volatile transient boolean holdOffLaunchUntilSave; @@ -114,6 +116,24 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable return holdOffLaunchUntilSave; } + /** + * {@inheritDoc} + * @since 1.635. + */ + @Override + public void save() throws IOException { + // this should be a no-op unless this node instance is the node instance in Jenkins' list of nodes + // thus where Jenkins.getInstance() == null there is no list of nodes, so we do a no-op + // Nodes.updateNode(n) will only persist the node record if the node instance is in the list of nodes + // so either path results in the same behaviour: the node instance is only saved if it is in the list of nodes + // for all other cases we do not know where to persist the node record and hence we follow the default + // no-op of a Saveable.NOOP + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + if (jenkins != null) { + jenkins.updateNode(this); + } + } + /** * Name of this node. * @@ -121,7 +141,8 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable * "" if this is master */ @Exported(visibility=999) - public abstract @Nonnull String getNodeName(); + @Nonnull + public abstract String getNodeName(); /** * When the user clones a {@link Node}, Hudson uses this method to change the node name right after @@ -174,7 +195,8 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable * this method can return null if there's no {@link Computer} object for this node, * such as when this node has no executors at all. */ - public final @CheckForNull Computer toComputer() { + @CheckForNull + public final Computer toComputer() { AbstractCIBase ciBase = Jenkins.getInstance(); return ciBase.getComputer(this); } @@ -184,7 +206,8 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable * * This is just a convenience method for {@link Computer#getChannel()} with null check. */ - public final @CheckForNull VirtualChannel getChannel() { + @CheckForNull + public final VirtualChannel getChannel() { Computer c = toComputer(); return c==null ? null : c.getChannel(); } @@ -196,7 +219,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable protected abstract Computer createComputer(); /** - * Returns {@code true} if the node is accepting tasks. Needed to allow slaves programmatic suspension of task + * Returns {@code true} if the node is accepting tasks. Needed to allow agents programmatic suspension of task * scheduling that does not overlap with being offline. Called by {@link Computer#isAcceptingTasks()}. * This method is distinct from {@link Computer#isAcceptingTasks()} as sometimes the {@link Node} concrete * class may not have control over the {@link hudson.model.Computer} concrete class associated with it. @@ -237,7 +260,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable try { if (temporaryOfflineCause != cause) { temporaryOfflineCause = cause; - Jenkins.getInstance().save(); // Gotta be a better way to do this + save(); } } catch (java.io.IOException e) { LOGGER.warning("Unable to complete save, temporary offline status will not be persisted: " + e.getMessage()); @@ -261,7 +284,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable * {@link LabelFinder} extension point. * * This method has a side effect of updating the hudson-wide set of labels - * and should be called after events that will change that - e.g. a slave + * and should be called after events that will change that - e.g. a agent * connecting. */ @Exported @@ -349,7 +372,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable public CauseOfBlockage canTake(Queue.BuildableItem item) { Label l = item.getAssignedLabel(); if(l!=null && !l.contains(this)) - return CauseOfBlockage.fromMessage(Messages._Node_LabelMissing(getNodeName(),l)); // the task needs to be executed on label that this node doesn't have. + return CauseOfBlockage.fromMessage(Messages._Node_LabelMissing(getDisplayName(), l)); // the task needs to be executed on label that this node doesn't have. if(l==null && getMode()== Mode.EXCLUSIVE) { // flyweight tasks need to get executed somewhere, if every node @@ -358,14 +381,14 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable || Jenkins.getInstance().getNumExecutors() < 1 || Jenkins.getInstance().getMode() == Mode.EXCLUSIVE) )) { - return CauseOfBlockage.fromMessage(Messages._Node_BecauseNodeIsReserved(getNodeName())); // this node is reserved for tasks that are tied to it + return CauseOfBlockage.fromMessage(Messages._Node_BecauseNodeIsReserved(getDisplayName())); // this node is reserved for tasks that are tied to it } } Authentication identity = item.authenticate(); if (!getACL().hasPermission(identity,Computer.BUILD)) { // doesn't have a permission - return CauseOfBlockage.fromMessage(Messages._Node_LackingBuildPermission(identity.getName(),getNodeName())); + return CauseOfBlockage.fromMessage(Messages._Node_LackingBuildPermission(identity.getName(), getDisplayName())); } // Check each NodeProperty to see whether they object to this node @@ -376,7 +399,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable } if (!isAcceptingTasks()) { - return CauseOfBlockage.fromMessage(Messages._Node_BecauseNodeIsNotAcceptingTasks(getNodeName())); + return new CauseOfBlockage.BecauseNodeIsNotAcceptingTasks(this); } // Looks like we can take the task @@ -449,10 +472,13 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable if (form==null) return null; final JSONObject jsonForProperties = form.optJSONObject("nodeProperties"); - BindInterceptor old = req.setBindListener(new BindInterceptor() { + final AtomicReference old = new AtomicReference<>(); + old.set(req.setBindListener(new BindInterceptor() { @Override public Object onConvert(Type targetType, Class targetTypeErasure, Object jsonSource) { - if (jsonForProperties!=jsonSource) return DEFAULT; + if (jsonForProperties != jsonSource) { + return old.get().onConvert(targetType, targetTypeErasure, jsonSource); + } try { DescribableList, NodePropertyDescriptor> tmp = new DescribableList, NodePropertyDescriptor>(Saveable.NOOP,getNodeProperties().toList()); @@ -464,19 +490,19 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable throw new IllegalArgumentException(e); } } - }); + })); try { return getDescriptor().newInstance(req, form); } finally { - req.setBindListener(old); + req.setBindListener(old.get()); } } public abstract NodeDescriptor getDescriptor(); /** - * Estimates the clock difference with this slave. + * Estimates the clock difference with this agent. * * @return * always non-null. @@ -501,7 +527,7 @@ public abstract class Node extends AbstractModelObject implements Reconfigurable public abstract Callable getClockDifferenceCallable(); /** - * Constants that control how Hudson allocates jobs to slaves. + * Constants that control how Hudson allocates jobs to agents. */ public enum Mode { NORMAL(Messages._Node_Mode_NORMAL()), diff --git a/core/src/main/java/hudson/model/OverallLoadStatistics.java b/core/src/main/java/hudson/model/OverallLoadStatistics.java index 0f10e12ae8707b030b9b07846740110cbc272491..e95174d0ca60615a17fa8b20a8ca98e1f58a5e79 100644 --- a/core/src/main/java/hudson/model/OverallLoadStatistics.java +++ b/core/src/main/java/hudson/model/OverallLoadStatistics.java @@ -32,7 +32,7 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.export.Exported; /** - * {@link LoadStatistics} for the entire system (the master and all the slaves combined), + * {@link LoadStatistics} for the entire system (the master and all the agents combined), * and all the jobs that are running on it. * * @author Kohsuke Kawaguchi diff --git a/core/src/main/java/hudson/model/PageDecorator.java b/core/src/main/java/hudson/model/PageDecorator.java index 849ef199fce9c5f4b60bef356b1d6d1bc1e0a5d6..5411b346b554942e8f4a90e180749e8e8aa9db25 100644 --- a/core/src/main/java/hudson/model/PageDecorator.java +++ b/core/src/main/java/hudson/model/PageDecorator.java @@ -24,7 +24,6 @@ package hudson.model; import hudson.ExtensionPoint; -import hudson.Plugin; import hudson.Extension; import hudson.ExtensionList; import hudson.util.DescriptorList; @@ -45,7 +44,7 @@ import java.util.List; * *

Life-cycle

*

- * {@link Plugin}s that contribute this extension point + * Plugins that contribute this extension point * should implement a new decorator and put {@link Extension} on the class. * *

Associated Views

@@ -96,14 +95,6 @@ public abstract class PageDecorator extends Descriptor implements return this; } - /** - * Unless this object has additional web presence, display name is not used at all. - * So default to "". - */ - public String getDisplayName() { - return ""; - } - /** * Obtains the URL of this object, excluding the context path. * diff --git a/core/src/main/java/hudson/model/PaneStatusProperties.java b/core/src/main/java/hudson/model/PaneStatusProperties.java index 9f8be772279f2623ae959beec3488e606bc77959..279f72fa64c7434e21aa9567cb4ba324e7b385ff 100644 --- a/core/src/main/java/hudson/model/PaneStatusProperties.java +++ b/core/src/main/java/hudson/model/PaneStatusProperties.java @@ -8,6 +8,7 @@ import java.io.IOException; import javax.servlet.http.HttpSession; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.Stapler; public class PaneStatusProperties extends UserProperty implements Saveable { @@ -43,7 +44,7 @@ public class PaneStatusProperties extends UserProperty implements Saveable { return this; } - @Extension + @Extension @Symbol("paneStatus") public static class DescriptorImpl extends UserPropertyDescriptor { @Override @@ -51,11 +52,6 @@ public class PaneStatusProperties extends UserProperty implements Saveable { return new PaneStatusProperties(); } - @Override - public String getDisplayName() { - return null; - } - @Override public boolean isEnabled() { return false; diff --git a/core/src/main/java/hudson/model/ParameterDefinition.java b/core/src/main/java/hudson/model/ParameterDefinition.java index 63438fbf817379d69e357e543e5908d7ea2fb417..20250924d909dd408ed556da1dc8552d42a3a15e 100644 --- a/core/src/main/java/hudson/model/ParameterDefinition.java +++ b/core/src/main/java/hudson/model/ParameterDefinition.java @@ -155,6 +155,7 @@ public abstract class ParameterDefinition implements /** * {@inheritDoc} */ + @Override public ParameterDescriptor getDescriptor() { return (ParameterDescriptor) Jenkins.getInstance().getDescriptorOrDie(getClass()); } diff --git a/core/src/main/java/hudson/model/ParametersAction.java b/core/src/main/java/hudson/model/ParametersAction.java index 202703036d95f297fbd75030ba21220ddc924dde..be29fc4b04b085aaf282a72ebe7e0d25eaa4391f 100644 --- a/core/src/main/java/hudson/model/ParametersAction.java +++ b/core/src/main/java/hudson/model/ParametersAction.java @@ -32,9 +32,13 @@ import hudson.model.queue.SubTask; import hudson.tasks.BuildStep; import hudson.tasks.BuildWrapper; import hudson.util.VariableResolver; +import jenkins.model.RunAction2; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; @@ -42,11 +46,15 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; -import static com.google.common.collect.Lists.newArrayList; +import com.google.common.collect.Lists; import static com.google.common.collect.Sets.newHashSet; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import jenkins.util.SystemProperties; /** * Records the parameter values used for a build. @@ -57,18 +65,55 @@ import javax.annotation.Nonnull; * that were specified when scheduling. */ @ExportedBean -public class ParametersAction implements Action, Iterable, QueueAction, EnvironmentContributingAction, LabelAssignmentAction { +public class ParametersAction implements RunAction2, Iterable, QueueAction, EnvironmentContributingAction, LabelAssignmentAction { + + @Restricted(NoExternalUse.class) + public static final String KEEP_UNDEFINED_PARAMETERS_SYSTEM_PROPERTY_NAME = ParametersAction.class.getName() + + ".keepUndefinedParameters"; + + @Restricted(NoExternalUse.class) + public static final String SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME = ParametersAction.class.getName() + + ".safeParameters"; + + private Set safeParameters; private final List parameters; + private List parameterDefinitionNames; + /** * @deprecated since 1.283; kept to avoid warnings loading old build data, but now transient. */ @Deprecated private transient AbstractBuild build; + private transient Run run; + public ParametersAction(List parameters) { this.parameters = parameters; + String paramNames = SystemProperties.getString(SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME); + safeParameters = new TreeSet<>(); + if (paramNames != null) { + safeParameters.addAll(Arrays.asList(paramNames.split(","))); + } + } + + /** + * Constructs a new action with additional safe parameters. + * The additional safe parameters should be only those considered safe to override the environment + * and what is declared in the project config in addition to those specified by the user in + * {@link #SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME}. + * See SECURITY-170 + * + * @param parameters the parameters + * @param additionalSafeParameters additional safe parameters + * @since 1.651.2, 2.3 + */ + public ParametersAction(List parameters, Collection additionalSafeParameters) { + this(parameters); + if (additionalSafeParameters != null) { + safeParameters.addAll(additionalSafeParameters); + } } public ParametersAction(ParameterValue... parameters) { @@ -76,7 +121,7 @@ public class ParametersAction implements Action, Iterable, Queue } public void createBuildWrappers(AbstractBuild build, Collection result) { - for (ParameterValue p : parameters) { + for (ParameterValue p : getParameters()) { if (p == null) continue; BuildWrapper w = p.createBuildWrapper(build); if(w!=null) result.add(w); @@ -84,7 +129,7 @@ public class ParametersAction implements Action, Iterable, Queue } public void buildEnvVars(AbstractBuild build, EnvVars env) { - for (ParameterValue p : parameters) { + for (ParameterValue p : getParameters()) { if (p == null) continue; p.buildEnvironment(build, env); } @@ -106,9 +151,9 @@ public class ParametersAction implements Action, Iterable, Queue * If you are a {@link BuildStep}, most likely you should call {@link AbstractBuild#getBuildVariableResolver()}. */ public VariableResolver createVariableResolver(AbstractBuild build) { - VariableResolver[] resolvers = new VariableResolver[parameters.size()+1]; + VariableResolver[] resolvers = new VariableResolver[getParameters().size()+1]; int i=0; - for (ParameterValue p : parameters) { + for (ParameterValue p : getParameters()) { if (p == null) continue; resolvers[i++] = p.createVariableResolver(build); } @@ -119,12 +164,12 @@ public class ParametersAction implements Action, Iterable, Queue } public Iterator iterator() { - return parameters.iterator(); + return getParameters().iterator(); } @Exported(visibility=2) public List getParameters() { - return Collections.unmodifiableList(parameters); + return Collections.unmodifiableList(filter(parameters)); } public ParameterValue getParameter(String name) { @@ -137,7 +182,7 @@ public class ParametersAction implements Action, Iterable, Queue } public Label getAssignedLabel(SubTask task) { - for (ParameterValue p : parameters) { + for (ParameterValue p : getParameters()) { if (p == null) continue; Label l = p.getAssignedLabel(task); if (l!=null) return l; @@ -182,9 +227,11 @@ public class ParametersAction implements Action, Iterable, Queue @Nonnull public ParametersAction createUpdated(Collection overrides) { if(overrides == null) { - return new ParametersAction(parameters); + ParametersAction parametersAction = new ParametersAction(parameters); + parametersAction.safeParameters = this.safeParameters; + return parametersAction; } - List combinedParameters = newArrayList(overrides); + List combinedParameters = Lists.newArrayList(overrides); Set names = newHashSet(); for(ParameterValue v : overrides) { @@ -199,7 +246,7 @@ public class ParametersAction implements Action, Iterable, Queue } } - return new ParametersAction(combinedParameters); + return new ParametersAction(combinedParameters, this.safeParameters); } /* @@ -210,14 +257,93 @@ public class ParametersAction implements Action, Iterable, Queue @Nonnull public ParametersAction merge(@CheckForNull ParametersAction overrides) { if (overrides == null) { - return new ParametersAction(parameters); + ParametersAction parametersAction = new ParametersAction(parameters, this.safeParameters); + return parametersAction; + } + ParametersAction parametersAction = createUpdated(overrides.parameters); + Set safe = new TreeSet<>(); + if (parametersAction.safeParameters != null && this.safeParameters != null) { + safe.addAll(this.safeParameters); + } + if (overrides.safeParameters != null) { + safe.addAll(overrides.safeParameters); } - return createUpdated(overrides.getParameters()); + parametersAction.safeParameters = safe; + return parametersAction; } private Object readResolve() { if (build != null) OldDataMonitor.report(build, "1.283"); + if (safeParameters == null) { + safeParameters = Collections.emptySet(); + } return this; } + + @Override + public void onAttached(Run r) { + ParametersDefinitionProperty p = r.getParent().getProperty(ParametersDefinitionProperty.class); + if (p != null) { + this.parameterDefinitionNames = p.getParameterDefinitionNames(); + } else { + this.parameterDefinitionNames = Collections.emptyList(); + } + this.run = r; + } + + @Override + public void onLoad(Run r) { + this.run = r; + } + + private List filter(List parameters) { + if (this.run == null) { + return parameters; + } + + if (this.parameterDefinitionNames == null) { + return parameters; + } + + if (SystemProperties.getBoolean(KEEP_UNDEFINED_PARAMETERS_SYSTEM_PROPERTY_NAME)) { + return parameters; + } + + List filteredParameters = new ArrayList(); + + for (ParameterValue v : this.parameters) { + if (this.parameterDefinitionNames.contains(v.getName()) || isSafeParameter(v.getName())) { + filteredParameters.add(v); + } else { + LOGGER.log(Level.WARNING, "Skipped parameter `{0}` as it is undefined on `{1}`. Set `-D{2}=true` to allow " + + "undefined parameters to be injected as environment variables or `-D{3}=[comma-separated list]` to whitelist specific parameter names, " + + "even though it represents a security breach", + new Object [] { v.getName(), run.getParent().getFullName(), KEEP_UNDEFINED_PARAMETERS_SYSTEM_PROPERTY_NAME, SAFE_PARAMETERS_SYSTEM_PROPERTY_NAME }); + } + } + + return filteredParameters; + } + + /** + * Returns all parameters. + * + * Be careful in how you process them. It will return parameters even not being defined as + * {@link ParametersDefinitionProperty} in the job, so any external + * caller could inject any parameter (using any key) here. Treat it as untrusted data. + * + * @return all parameters defined here. + * @since 1.651.2, 2.3 + */ + public List getAllParameters() { + return Collections.unmodifiableList(parameters); + } + + private boolean isSafeParameter(String name) { + return safeParameters.contains(name); + } + + private static final Logger LOGGER = Logger.getLogger(ParametersAction.class.getName()); + } diff --git a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java index 13a6156b5c88a26d7ea23dd2f9a064f4fe0dd92d..7dc5f76b176920ae91378e1adf61d9ef5ce18e88 100644 --- a/core/src/main/java/hudson/model/ParametersDefinitionProperty.java +++ b/core/src/main/java/hudson/model/ParametersDefinitionProperty.java @@ -35,15 +35,19 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import javax.servlet.ServletException; import static javax.servlet.http.HttpServletResponse.SC_CREATED; import jenkins.model.Jenkins; +import jenkins.model.OptionalJobProperty; import jenkins.model.ParameterizedJobMixIn; import jenkins.util.TimeDuration; import net.sf.json.JSONArray; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -60,17 +64,28 @@ import org.kohsuke.stapler.export.ExportedBean; * The builds also need a {@code sidepanel.jelly}. */ @ExportedBean(defaultVisibility=2) -public class ParametersDefinitionProperty extends JobProperty> +public class ParametersDefinitionProperty extends OptionalJobProperty> implements Action { private final List parameterDefinitions; - public ParametersDefinitionProperty(List parameterDefinitions) { + @DataBoundConstructor + public ParametersDefinitionProperty(@Nonnull List parameterDefinitions) { + if (parameterDefinitions == null) { + throw new NullPointerException("ParameterDefinitions is null when this is a not valid value"); + } this.parameterDefinitions = parameterDefinitions; } - public ParametersDefinitionProperty(ParameterDefinition... parameterDefinitions) { - this.parameterDefinitions = Arrays.asList(parameterDefinitions); + public ParametersDefinitionProperty(@Nonnull ParameterDefinition... parameterDefinitions) { + if (parameterDefinitions == null) { + throw new NullPointerException("ParameterDefinitions is null when this is a not valid value"); + } + this.parameterDefinitions = Arrays.asList(parameterDefinitions) ; + } + + private Object readResolve() { + return parameterDefinitions == null ? new ParametersDefinitionProperty() : this; } @Deprecated @@ -103,6 +118,7 @@ public class ParametersDefinitionProperty extends JobProperty> }; } + @Nonnull @Override public Collection getJobActions(Job job) { return Collections.singleton(this); @@ -158,7 +174,7 @@ public class ParametersDefinitionProperty extends JobProperty> getJob(), delay.getTime(), new ParametersAction(values), new CauseAction(new Cause.UserIdCause())); if (item!=null) { String url = formData.optString("redirectTo"); - if (url==null || Util.isAbsoluteUri(url)) // avoid open redirect + if (url==null || !Util.isSafeToRedirectTo(url)) // avoid open redirect url = req.getContextPath()+'/'+item.getUrl(); rsp.sendRedirect(formData.optInt("statusCode",SC_CREATED), url); } else @@ -203,33 +219,13 @@ public class ParametersDefinitionProperty extends JobProperty> } @Extension - public static class DescriptorImpl extends JobPropertyDescriptor { + @Symbol("parameters") + public static class DescriptorImpl extends OptionalJobPropertyDescriptor { @Override public boolean isApplicable(Class jobType) { return ParameterizedJobMixIn.ParameterizedJob.class.isAssignableFrom(jobType); } - @Override - public JobProperty newInstance(StaplerRequest req, - JSONObject formData) throws FormException { - if (formData.isNullObject()) { - return null; - } - - JSONObject parameterized = formData.getJSONObject("parameterized"); - - if (parameterized.isNullObject()) { - return null; - } - - List parameterDefinitions = Descriptor.newInstancesFromHeteroList( - req, parameterized, "parameter", ParameterDefinition.all()); - if(parameterDefinitions.isEmpty()) - return null; - - return new ParametersDefinitionProperty(parameterDefinitions); - } - @Override public String getDisplayName() { return Messages.ParametersDefinitionProperty_DisplayName(); diff --git a/core/src/main/java/hudson/model/PasswordParameterDefinition.java b/core/src/main/java/hudson/model/PasswordParameterDefinition.java index ce93144a56c708d07ebcb519cdb6dbc3e5ae85dc..f3dfe793562c6d548e804592cb503e611521e36e 100644 --- a/core/src/main/java/hudson/model/PasswordParameterDefinition.java +++ b/core/src/main/java/hudson/model/PasswordParameterDefinition.java @@ -24,12 +24,14 @@ package hudson.model; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; import hudson.Extension; import hudson.util.Secret; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Parameter whose value is a {@link Secret} and is hidden from the UI. @@ -39,6 +41,9 @@ import org.kohsuke.accmod.restrictions.DoNotUse; */ public class PasswordParameterDefinition extends SimpleParameterDefinition { + @Restricted(NoExternalUse.class) + public static final String DEFAULT_VALUE = ""; + private Secret defaultValue; @DataBoundConstructor @@ -65,6 +70,9 @@ public class PasswordParameterDefinition extends SimpleParameterDefinition { @Override public PasswordParameterValue createValue(StaplerRequest req, JSONObject jo) { PasswordParameterValue value = req.bindJSON(PasswordParameterValue.class, jo); + if (value.getValue().getPlainText().equals(DEFAULT_VALUE)) { + value = new PasswordParameterValue(getName(), getDefaultValue()); + } value.setDescription(getDescription()); return value; } @@ -88,7 +96,7 @@ public class PasswordParameterDefinition extends SimpleParameterDefinition { this.defaultValue = Secret.fromString(defaultValue); } - @Extension + @Extension @Symbol({"password","nonStoredPasswordParam"}) public final static class ParameterDescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/PasswordParameterValue.java b/core/src/main/java/hudson/model/PasswordParameterValue.java index d7d917ee487adf7bb96764f2c4dd2e4841a116d9..9f384fbb22f78dc8922ffc53cd2abf28e618ed04 100644 --- a/core/src/main/java/hudson/model/PasswordParameterValue.java +++ b/core/src/main/java/hudson/model/PasswordParameterValue.java @@ -29,12 +29,14 @@ import hudson.util.VariableResolver; import org.kohsuke.stapler.DataBoundConstructor; import java.util.Locale; +import javax.annotation.Nonnull; /** * @author Kohsuke Kawaguchi */ public class PasswordParameterValue extends ParameterValue { + @Nonnull private final Secret value; // kept for backward compatibility @@ -68,7 +70,8 @@ public class PasswordParameterValue extends ParameterValue { public boolean isSensitive() { return true; } - + + @Nonnull public Secret getValue() { return value; } diff --git a/core/src/main/java/hudson/model/PeriodicWork.java b/core/src/main/java/hudson/model/PeriodicWork.java index c3a1bf4953583f46ce1647b706dd7872dfc8f9be..95de4fb3042d34eecf530154468943b661608f07 100644 --- a/core/src/main/java/hudson/model/PeriodicWork.java +++ b/core/src/main/java/hudson/model/PeriodicWork.java @@ -25,11 +25,9 @@ package hudson.model; import hudson.init.Initializer; import hudson.triggers.SafeTimerTask; -import hudson.triggers.Trigger; import hudson.ExtensionPoint; import hudson.Extension; import hudson.ExtensionList; -import jenkins.model.Jenkins; import jenkins.util.Timer; import java.util.concurrent.TimeUnit; diff --git a/core/src/main/java/hudson/model/PermalinkProjectAction.java b/core/src/main/java/hudson/model/PermalinkProjectAction.java index 60e38d3cd2d4c4d07ea89095b7b71fd30c84e9c8..38e561a982124036add7700fb23d0e070f7a94ee 100644 --- a/core/src/main/java/hudson/model/PermalinkProjectAction.java +++ b/core/src/main/java/hudson/model/PermalinkProjectAction.java @@ -178,6 +178,19 @@ public interface PermalinkProjectAction extends Action { return !run.isBuilding() && run.getResult()!=Result.SUCCESS; } }; + public static final Permalink LAST_COMPLETED_BUILD = new Permalink() { + public String getDisplayName() { + return Messages.Permalink_LastCompletedBuild(); + } + + public String getId() { + return "lastCompletedBuild"; + } + + public Run resolve(Job job) { + return job.getLastCompletedBuild(); + } + }; static { BUILTIN.add(LAST_BUILD); @@ -186,6 +199,7 @@ public interface PermalinkProjectAction extends Action { BUILTIN.add(LAST_FAILED_BUILD); BUILTIN.add(LAST_UNSTABLE_BUILD); BUILTIN.add(LAST_UNSUCCESSFUL_BUILD); + BUILTIN.add(LAST_COMPLETED_BUILD); } } } diff --git a/core/src/main/java/hudson/model/ProxyView.java b/core/src/main/java/hudson/model/ProxyView.java index d8599ce9c2b8f832d73520091ff6ce70986b2e9d..795b94ba8635d64757a30386b35afaca22308602 100644 --- a/core/src/main/java/hudson/model/ProxyView.java +++ b/core/src/main/java/hudson/model/ProxyView.java @@ -32,6 +32,7 @@ import java.util.Collection; import javax.servlet.ServletException; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.Stapler; @@ -120,7 +121,7 @@ public class ProxyView extends View implements StaplerFallback { return FormValidation.error(Messages.ProxyView_NoSuchViewExists(value)); } - @Extension + @Extension @Symbol("proxy") public static class DescriptorImpl extends ViewDescriptor { @Override diff --git a/core/src/main/java/hudson/model/Queue.java b/core/src/main/java/hudson/model/Queue.java index 663a80d5fdabcf6ad336c3ab631fb71b274502be..f4325f7def44189065b50ebbf60e7adc79a2b1a5 100644 --- a/core/src/main/java/hudson/model/Queue.java +++ b/core/src/main/java/hudson/model/Queue.java @@ -26,10 +26,8 @@ package hudson.model; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import com.google.common.collect.ImmutableList; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import hudson.BulkChange; -import hudson.CopyOnWrite; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.Util; @@ -38,7 +36,6 @@ import hudson.init.Initializer; import static hudson.init.InitMilestone.JOB_LOADED; import static hudson.util.Iterators.reverse; -import hudson.cli.declarative.CLIMethod; import hudson.cli.declarative.CLIResolver; import hudson.model.labels.LabelAssignmentAction; import hudson.model.queue.AbstractQueueTask; @@ -65,6 +62,7 @@ import hudson.model.queue.CauseOfBlockage.BecauseLabelIsOffline; import hudson.model.queue.CauseOfBlockage.BecauseNodeIsBusy; import hudson.model.queue.WorkUnitContext; import hudson.security.ACL; +import hudson.security.AccessControlled; import jenkins.security.QueueItemAuthenticatorProvider; import jenkins.util.Timer; import hudson.triggers.SafeTimerTask; @@ -99,7 +97,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; @@ -113,6 +110,8 @@ import jenkins.util.AtmostOneTaskExecutor; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.jenkinsci.bytecode.AdaptField; +import org.jenkinsci.remoting.RoleChecker; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.export.Exported; @@ -123,9 +122,11 @@ import org.kohsuke.accmod.restrictions.DoNotUse; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import javax.annotation.CheckForNull; import javax.annotation.Nonnegative; import jenkins.model.queue.AsynchronousExecution; +import jenkins.model.queue.CompositeCauseOfBlockage; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -170,13 +171,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST; public class Queue extends ResourceController implements Saveable { /** - * Defines the refresh period for of the internal cache ({@link #itemsView}). - * Data should be defined in milliseconds, default value - 1000; - * @since 1.577 - */ - private static int CACHE_REFRESH_PERIOD = Integer.getInteger(Queue.class.getName() + ".cacheRefreshPeriod", 1000); - /** * Items that are waiting for its quiet period to pass. * *

@@ -216,41 +211,6 @@ public class Queue extends ResourceController implements Saveable { */ private final Cache leftItems = CacheBuilder.newBuilder().expireAfterWrite(5*60, TimeUnit.SECONDS).build(); - private final CachedItemList itemsView = new CachedItemList(); - - /** - * Maintains a copy of {@link Queue#getItems()} - * - * @see Queue#getApproximateItemsQuickly() - */ - private class CachedItemList { - /** - * The current cached value. - */ - @CopyOnWrite - private volatile List itemsView = Collections.emptyList(); - /** - * When does the cache info expire? - */ - private final AtomicLong expires = new AtomicLong(); - - List get() { - long t = System.currentTimeMillis(); - long d = expires.get(); - if (t>d) {// need to refresh the cache - long next = t+CACHE_REFRESH_PERIOD; - if (expires.compareAndSet(d,next)) { - // avoid concurrent cache update via CAS. - // if the getItems() lock is contended, - // some threads will end up serving stale data, - // but that's OK. - itemsView = ImmutableList.copyOf(getItems()); - } - } - return itemsView; - } - } - /** * Data structure created for each idle {@link Executor}. * This is a job offer from the queue to an executor. @@ -260,7 +220,7 @@ public class Queue extends ResourceController implements Saveable { * to assign a work. Once a work is assigned, the executor actually gets * started to carry out the task in question. */ - public class JobOffer extends MappingWorksheet.ExecutorSlot { + public static class JobOffer extends MappingWorksheet.ExecutorSlot { public final Executor executor; /** @@ -287,20 +247,44 @@ public class Queue extends ResourceController implements Saveable { } /** - * Verifies that the {@link Executor} represented by this object is capable of executing the given task. + * @deprecated discards information; prefer {@link #getCauseOfBlockage} */ + @Deprecated public boolean canTake(BuildableItem item) { - Node node = getNode(); - if (node==null) return false; // this executor is about to die - - if(node.canTake(item)!=null) - return false; // this node is not able to take the task - - for (QueueTaskDispatcher d : QueueTaskDispatcher.all()) - if (d.canTake(node,item)!=null) - return false; + return getCauseOfBlockage(item) == null; + } - return isAvailable(); + /** + * Checks whether the {@link Executor} represented by this object is capable of executing the given task. + * @return a reason why it cannot, or null if it could + * @since 2.37 + */ + public @CheckForNull CauseOfBlockage getCauseOfBlockage(BuildableItem item) { + Node node = getNode(); + if (node == null) { + return CauseOfBlockage.fromMessage(Messages._Queue_node_has_been_removed_from_configuration(executor.getOwner().getDisplayName())); + } + CauseOfBlockage reason = node.canTake(item); + if (reason != null) { + return reason; + } + for (QueueTaskDispatcher d : QueueTaskDispatcher.all()) { + reason = d.canTake(node, item); + if (reason != null) { + return reason; + } + } + // inlining isAvailable: + if (workUnit != null) { // unlikely in practice (should not have even found this executor if so) + return CauseOfBlockage.fromMessage(Messages._Queue_executor_slot_already_in_use()); + } + if (executor.getOwner().isOffline()) { + return new CauseOfBlockage.BecauseNodeIsOffline(node); + } + if (!executor.getOwner().isAcceptingTasks()) { // Node.canTake (above) does not consider RetentionStrategy.isAcceptingTasks + return new CauseOfBlockage.BecauseNodeIsNotAcceptingTasks(node); + } + return null; } /** @@ -335,9 +319,14 @@ public class Queue extends ResourceController implements Saveable { maintain(); return null; } + + @Override + public String toString() { + return "Periodic Jenkins queue maintenance"; + } }); - private transient final Lock lock = new ReentrantLock(); + private transient final ReentrantLock lock = new ReentrantLock(); private transient final Condition condition = lock.newCondition(); @@ -379,19 +368,21 @@ public class Queue extends ResourceController implements Saveable { public void load() { lock.lock(); try { try { + // Clear items, for the benefit of reloading. + waitingList.clear(); + blockedProjects.clear(); + buildables.clear(); + pendings.clear(); // first try the old format File queueFile = getQueueFile(); if (queueFile.exists()) { - BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(queueFile))); - try { + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(queueFile)))) { String line; while ((line = in.readLine()) != null) { AbstractProject j = Jenkins.getInstance().getItemByFullName(line, AbstractProject.class); if (j != null) j.scheduleBuild(); } - } finally { - in.close(); } // discard the queue file now that we are done queueFile.delete(); @@ -491,7 +482,6 @@ public class Queue extends ResourceController implements Saveable { /** * Wipes out all the items currently in the queue, as if all of them are cancelled at once. */ - @CLIMethod(name="clear-queue") public void clear() { Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); lock.lock(); @@ -647,22 +637,17 @@ public class Queue extends ResourceController implements Saveable { for (Item item : duplicatesInQueue) { for (FoldableAction a : Util.filter(actions, FoldableAction.class)) { a.foldIntoExisting(item, p, actions); + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "after folding {0}, {1} includes {2}", new Object[] {a, item, item.getAllActions()}); + } } } boolean queueUpdated = false; for (WaitingItem wi : Util.filter(duplicatesInQueue, WaitingItem.class)) { - if (quietPeriod <= 0) { - // the user really wants to build now, and they mean NOW. - // so let's pull in the timestamp if we can. - if (wi.timestamp.before(due)) - continue; - } else { - // otherwise we do the normal quiet period implementation - if (wi.timestamp.after(due)) - continue; - // quiet period timer reset. start the period over again - } + // make sure to always use the shorter of the available due times + if (wi.timestamp.before(due)) + continue; // waitingList is sorted, so when we change a timestamp we need to maintain order wi.leave(this); @@ -787,18 +772,69 @@ public class Queue extends ResourceController implements Saveable { @Exported(inline=true) public Item[] getItems() { Snapshot s = this.snapshot; - Item[] r = new Item[s.waitingList.size() + s.blockedProjects.size() + s.buildables.size() + - s.pendings.size()]; - s.waitingList.toArray(r); - int idx = s.waitingList.size(); - for (BlockedItem p : s.blockedProjects) { - r[idx++] = p; + List r = new ArrayList(); + + for(WaitingItem p : s.waitingList) { + r = checkPermissionsAndAddToList(r, p); + } + for (BlockedItem p : s.blockedProjects){ + r = checkPermissionsAndAddToList(r, p); } for (BuildableItem p : reverse(s.buildables)) { - r[idx++] = p; + r = checkPermissionsAndAddToList(r, p); } for (BuildableItem p : reverse(s.pendings)) { - r[idx++] = p; + r= checkPermissionsAndAddToList(r, p); + } + Item[] items = new Item[r.size()]; + r.toArray(items); + return items; + } + + private List checkPermissionsAndAddToList(List r, Item t) { + if (t.task instanceof hudson.security.AccessControlled) { + if (((hudson.security.AccessControlled)t.task).hasPermission(hudson.model.Item.READ) + || ((hudson.security.AccessControlled) t.task).hasPermission(hudson.security.Permission.READ)) { + r.add(t); + } + } + return r; + } + + /** + * Returns an array of Item for which it is only visible the name of the task. + * + * Generally speaking the array is sorted such that the items that are most likely built sooner are + * at the end. + */ + @Restricted(NoExternalUse.class) + @Exported(inline=true) + public StubItem[] getDiscoverableItems() { + Snapshot s = this.snapshot; + List r = new ArrayList(); + + for(WaitingItem p : s.waitingList) { + r = filterDiscoverableItemListBasedOnPermissions(r, p); + } + for (BlockedItem p : s.blockedProjects){ + r = filterDiscoverableItemListBasedOnPermissions(r, p); + } + for (BuildableItem p : reverse(s.buildables)) { + r = filterDiscoverableItemListBasedOnPermissions(r, p); + } + for (BuildableItem p : reverse(s.pendings)) { + r= filterDiscoverableItemListBasedOnPermissions(r, p); + } + StubItem[] items = new StubItem[r.size()]; + r.toArray(items); + return items; + } + + private List filterDiscoverableItemListBasedOnPermissions(List r, Item t) { + if (t.task instanceof hudson.model.Item) { + if (!((hudson.model.Item)t.task).hasPermission(hudson.model.Item.READ) && ((hudson.model.Item)t.task).hasPermission(hudson.model.Item.DISCOVER)) { + r.add(new StubItem(new StubTask(t.task))); + } } return r; } @@ -819,9 +855,11 @@ public class Queue extends ResourceController implements Saveable { * This method is primarily added to make UI threads run faster. * * @since 1.483 + * @deprecated Use {@link #getItems()} directly. As of 1.607 the approximation is no longer needed. */ + @Deprecated public List getApproximateItemsQuickly() { - return itemsView.get(); + return Arrays.asList(getItems()); } public Item getItem(long id) { @@ -884,6 +922,13 @@ public class Queue extends ResourceController implements Saveable { return new ArrayList(snapshot.pendings); } + /** + * Gets the snapshot of all {@link BlockedItem}s. + */ + protected List getBlockedItems() { + return new ArrayList(snapshot.blockedProjects); + } + /** * Returns the snapshot of all {@link LeftItem}s. * @@ -1032,7 +1077,13 @@ public class Queue extends ResourceController implements Saveable { List result = new ArrayList(); result.addAll(blockedProjects.getAll(t)); result.addAll(buildables.getAll(t)); - result.addAll(pendings.getAll(t)); + // Do not include pendings—we have already finalized WorkUnitContext.actions. + if (LOGGER.isLoggable(Level.FINE)) { + List thePendings = pendings.getAll(t); + if (!thePendings.isEmpty()) { + LOGGER.log(Level.FINE, "ignoring {0} during scheduleInternal", thePendings); + } + } for (Item item : waitingList) { if (item.task.equals(t)) { result.add(item); @@ -1079,25 +1130,7 @@ public class Queue extends ResourceController implements Saveable { * Returns true if this queue contains the said project. */ public boolean contains(Task t) { - final Snapshot snapshot = this.snapshot; - for (Item item : snapshot.blockedProjects) { - if (item.task.equals(t)) - return true; - } - for (Item item : snapshot.buildables) { - if (item.task.equals(t)) - return true; - } - for (Item item : snapshot.pendings) { - if (item.task.equals(t)) - return true; - } - for (Item item : snapshot.waitingList) { - if (item.task.equals(t)) { - return true; - } - } - return false; + return getItem(t)!=null; } /** @@ -1169,7 +1202,8 @@ public class Queue extends ResourceController implements Saveable { * @since 1.592 */ public static void withLock(Runnable runnable) { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() final Queue queue = jenkins == null ? null : jenkins.getQueue(); if (queue == null) { runnable.run(); @@ -1179,7 +1213,7 @@ public class Queue extends ResourceController implements Saveable { } /** - * Some operations require to be performed with the {@link Queue} lock held. Use one of these methods rather + * Some operations require the {@link Queue} lock held. Use one of these methods rather * than locking directly on Queue in order to allow for future refactoring. * * @param callable the operation to perform. @@ -1190,7 +1224,8 @@ public class Queue extends ResourceController implements Saveable { * @since 1.592 */ public static V withLock(hudson.remoting.Callable callable) throws T { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() final Queue queue = jenkins == null ? null : jenkins.getQueue(); if (queue == null) { return callable.call(); @@ -1210,7 +1245,8 @@ public class Queue extends ResourceController implements Saveable { * @since 1.592 */ public static V withLock(java.util.concurrent.Callable callable) throws Exception { - final Jenkins jenkins = Jenkins.getInstance(); + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() final Queue queue = jenkins == null ? null : jenkins.getQueue(); if (queue == null) { return callable.call(); @@ -1219,6 +1255,63 @@ public class Queue extends ResourceController implements Saveable { } } + /** + * Invokes the supplied {@link Runnable} if the {@link Queue} lock was obtained without blocking. + * + * @param runnable the operation to perform. + * @return {@code true} if the lock was available and the operation was performed. + * @since 1.618 + */ + public static boolean tryWithLock(Runnable runnable) { + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() + final Queue queue = jenkins == null ? null : jenkins.getQueue(); + if (queue == null) { + runnable.run(); + return true; + } else { + return queue._tryWithLock(runnable); + } + } + /** + * Wraps a {@link Runnable} with the {@link Queue} lock held. + * + * @param runnable the operation to wrap. + * @since 1.618 + */ + public static Runnable wrapWithLock(Runnable runnable) { + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() + final Queue queue = jenkins == null ? null : jenkins.getQueue(); + return queue == null ? runnable : new LockedRunnable(runnable); + } + + /** + * Wraps a {@link hudson.remoting.Callable} with the {@link Queue} lock held. + * + * @param callable the operation to wrap. + * @since 1.618 + */ + public static hudson.remoting.Callable wrapWithLock(hudson.remoting.Callable callable) { + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() + final Queue queue = jenkins == null ? null : jenkins.getQueue(); + return queue == null ? callable : new LockedHRCallable<>(callable); + } + + /** + * Wraps a {@link java.util.concurrent.Callable} with the {@link Queue} lock held. + * + * @param callable the operation to wrap. + * @since 1.618 + */ + public static java.util.concurrent.Callable wrapWithLock(java.util.concurrent.Callable callable) { + final Jenkins jenkins = Jenkins.getInstanceOrNull(); + // TODO confirm safe to assume non-null and use getInstance() + final Queue queue = jenkins == null ? null : jenkins.getQueue(); + return queue == null ? callable : new LockedJUCCallable(callable); + } + @Override protected void _await() throws InterruptedException { condition.await(); @@ -1244,6 +1337,26 @@ public class Queue extends ResourceController implements Saveable { } } + /** + * Invokes the supplied {@link Runnable} if the {@link Queue} lock was obtained without blocking. + * + * @param runnable the operation to perform. + * @return {@code true} if the lock was available and the operation was performed. + * @since 1.618 + */ + protected boolean _tryWithLock(Runnable runnable) { + if (lock.tryLock()) { + try { + runnable.run(); + } finally { + lock.unlock(); + } + return true; + } else { + return false; + } + } + /** * Some operations require to be performed with the {@link Queue} lock held. Use one of these methods rather * than locking directly on Queue in order to allow for future refactoring. @@ -1299,7 +1412,7 @@ public class Queue extends ResourceController implements Saveable { lock.lock(); try { try { - LOGGER.log(Level.FINE, "Queue maintenance started {0}", this); + LOGGER.log(Level.FINE, "Queue maintenance started on {0} with {1}", new Object[] {this, snapshot}); // The executors that are currently waiting for a job to run. Map parked = new HashMap(); @@ -1308,7 +1421,18 @@ public class Queue extends ResourceController implements Saveable { List lostPendings = new ArrayList(pendings); for (Computer c : Jenkins.getInstance().getComputers()) { for (Executor e : c.getExecutors()) { + if (e.isInterrupted()) { + // JENKINS-28840 we will deadlock if we try to touch this executor while interrupt flag set + // we need to clear lost pendings as we cannot know what work unit was on this executor + // while it is interrupted. (All this dancing is a result of Executor extending Thread) + lostPendings.clear(); // we'll get them next time around when the flag is cleared. + LOGGER.log(Level.FINEST, + "Interrupt thread for executor {0} is set and we do not know what work unit was on the executor.", + e.getDisplayName()); + continue; + } if (e.isParking()) { + LOGGER.log(Level.FINEST, "{0} is parking and is waiting for a job to execute.", e.getDisplayName()); parked.put(e, new JobOffer(e)); } final WorkUnit workUnit = e.getCurrentWorkUnit(); @@ -1319,24 +1443,43 @@ public class Queue extends ResourceController implements Saveable { } // pending -> buildable for (BuildableItem p: lostPendings) { - LOGGER.log(Level.INFO, + LOGGER.log(Level.FINE, "BuildableItem {0}: pending -> buildable as the assigned executor disappeared", p.task.getFullDisplayName()); p.isPending = false; pendings.remove(p); - makeBuildable(p); + makeBuildable(p); // TODO whatever this is for, the return value is being ignored, so this does nothing at all } } + final QueueSorter s = sorter; {// blocked -> buildable - for (BlockedItem p : new ArrayList(blockedProjects.values())) {// copy as we'll mutate the list + // copy as we'll mutate the list and we want to process in a potentially different order + List blockedItems = new ArrayList<>(blockedProjects.values()); + // if facing a cycle of blocked tasks, ensure we process in the desired sort order + if (s != null) { + s.sortBlockedItems(blockedItems); + } else { + Collections.sort(blockedItems, QueueSorter.DEFAULT_BLOCKED_ITEM_COMPARATOR); + } + for (BlockedItem p : blockedItems) { + String taskDisplayName = p.task.getFullDisplayName(); + LOGGER.log(Level.FINEST, "Current blocked item: {0}", taskDisplayName); if (!isBuildBlocked(p) && allowNewBuildableTask(p.task)) { + LOGGER.log(Level.FINEST, + "BlockedItem {0}: blocked -> buildable as the build is not blocked and new tasks are allowed", + taskDisplayName); + // ready to be executed Runnable r = makeBuildable(new BuildableItem(p)); if (r != null) { p.leave(this); r.run(); + // JENKINS-28926 we have removed a task from the blocked projects and added to building + // thus we should update the snapshot so that subsequent blocked projects can correctly + // determine if they are blocked by the lucky winner + updateSnapshot(); } } } @@ -1346,17 +1489,22 @@ public class Queue extends ResourceController implements Saveable { while (!waitingList.isEmpty()) { WaitingItem top = peek(); - if (top.timestamp.compareTo(new GregorianCalendar()) > 0) + if (top.timestamp.compareTo(new GregorianCalendar()) > 0) { + LOGGER.log(Level.FINEST, "Finished moving all ready items from queue."); break; // finished moving all ready items from queue + } top.leave(this); Task p = top.task; if (!isBuildBlocked(top) && allowNewBuildableTask(p)) { // ready to be executed immediately Runnable r = makeBuildable(new BuildableItem(top)); + String topTaskDisplayName = top.task.getFullDisplayName(); if (r != null) { + LOGGER.log(Level.FINEST, "Executing runnable {0}", topTaskDisplayName); r.run(); } else { + LOGGER.log(Level.FINEST, "Item {0} was unable to be made a buildable and is now a blocked item.", topTaskDisplayName); new BlockedItem(top).enter(this); } } else { @@ -1366,7 +1514,6 @@ public class Queue extends ResourceController implements Saveable { } } - final QueueSorter s = sorter; if (s != null) s.sortBuildableItems(buildables); @@ -1381,46 +1528,76 @@ public class Queue extends ResourceController implements Saveable { p.leave(this); new BlockedItem(p).enter(this); LOGGER.log(Level.FINE, "Catching that {0} is blocked in the last minute", p); + // JENKINS-28926 we have moved an unblocked task into the blocked state, update snapshot + // so that other buildables which might have been blocked by this can see the state change + updateSnapshot(); continue; } - List candidates = new ArrayList(parked.size()); - for (JobOffer j : parked.values()) - if (j.canTake(p)) - candidates.add(j); - - MappingWorksheet ws = new MappingWorksheet(p, candidates); - Mapping m = loadBalancer.map(p.task, ws); - if (m == null) { - // if we couldn't find the executor that fits, - // just leave it in the buildables list and - // check if we can execute other projects - LOGGER.log(Level.FINER, "Failed to map {0} to executors. candidates={1} parked={2}", - new Object[]{p, candidates, parked.values()}); - continue; - } + String taskDisplayName = p.task.getFullDisplayName(); + + if (p.task instanceof FlyweightTask) { + Runnable r = makeFlyWeightTaskBuildable(new BuildableItem(p)); + if (r != null) { + p.leave(this); + LOGGER.log(Level.FINEST, "Executing flyweight task {0}", taskDisplayName); + r.run(); + updateSnapshot(); + } + } else { - // found a matching executor. use it. - WorkUnitContext wuc = new WorkUnitContext(p); - m.execute(wuc); - - p.leave(this); - if (!wuc.getWorkUnits().isEmpty()) - makePending(p); - else - LOGGER.log(Level.FINE, "BuildableItem {0} with empty work units!?", p); - - // Ensure that identification of blocked tasks is using the live state: JENKINS-27708 & JENKINS-27871 - // The creation of a snapshot itself should be relatively cheap given the expected rate of - // job execution. You probably would need 100's of jobs starting execution every iteration - // of maintain() before this could even start to become an issue and likely the calculation - // of isBuildBlocked(p) will become a bottleneck before updateSnapshot() will. Additionally - // since the snapshot itself only ever has at most one reference originating outside of the stack - // it should remain in the eden space and thus be cheap to GC. - // See https://issues.jenkins-ci.org/browse/JENKINS-27708?focusedCommentId=225819&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225819 - // or https://issues.jenkins-ci.org/browse/JENKINS-27708?focusedCommentId=225906&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225906 - // for alternative fixes of this issue. - updateSnapshot(); + List candidates = new ArrayList<>(parked.size()); + List reasons = new ArrayList<>(parked.size()); + for (JobOffer j : parked.values()) { + CauseOfBlockage reason = j.getCauseOfBlockage(p); + if (reason == null) { + LOGGER.log(Level.FINEST, + "{0} is a potential candidate for task {1}", + new Object[]{j, taskDisplayName}); + candidates.add(j); + } else { + LOGGER.log(Level.FINEST, "{0} rejected {1}: {2}", new Object[] {j, taskDisplayName, reason}); + reasons.add(reason); + } + } + + MappingWorksheet ws = new MappingWorksheet(p, candidates); + Mapping m = loadBalancer.map(p.task, ws); + if (m == null) { + // if we couldn't find the executor that fits, + // just leave it in the buildables list and + // check if we can execute other projects + LOGGER.log(Level.FINER, "Failed to map {0} to executors. candidates={1} parked={2}", + new Object[]{p, candidates, parked.values()}); + p.transientCausesOfBlockage = reasons.isEmpty() ? null : reasons; + continue; + } + + // found a matching executor. use it. + WorkUnitContext wuc = new WorkUnitContext(p); + LOGGER.log(Level.FINEST, "Found a matching executor for {0}. Using it.", taskDisplayName); + m.execute(wuc); + + p.leave(this); + if (!wuc.getWorkUnits().isEmpty()) { + LOGGER.log(Level.FINEST, "BuildableItem {0} marked as pending.", taskDisplayName); + makePending(p); + } + else + LOGGER.log(Level.FINEST, "BuildableItem {0} with empty work units!?", p); + + // Ensure that identification of blocked tasks is using the live state: JENKINS-27708 & JENKINS-27871 + // The creation of a snapshot itself should be relatively cheap given the expected rate of + // job execution. You probably would need 100's of jobs starting execution every iteration + // of maintain() before this could even start to become an issue and likely the calculation + // of isBuildBlocked(p) will become a bottleneck before updateSnapshot() will. Additionally + // since the snapshot itself only ever has at most one reference originating outside of the stack + // it should remain in the eden space and thus be cheap to GC. + // See https://issues.jenkins-ci.org/browse/JENKINS-27708?focusedCommentId=225819&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225819 + // or https://issues.jenkins-ci.org/browse/JENKINS-27708?focusedCommentId=225906&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-225906 + // for alternative fixes of this issue. + updateSnapshot(); + } } } finally { updateSnapshot(); } } finally { lock.unlock(); @@ -1434,9 +1611,42 @@ public class Queue extends ResourceController implements Saveable { */ private @CheckForNull Runnable makeBuildable(final BuildableItem p) { if (p.task instanceof FlyweightTask) { + String taskDisplayName = p.task.getFullDisplayName(); if (!isBlockedByShutdown(p.task)) { + + Runnable runnable = makeFlyWeightTaskBuildable(p); + LOGGER.log(Level.FINEST, "Converting flyweight task: {0} into a BuildableRunnable", taskDisplayName); + if(runnable != null){ + return runnable; + } + + //this is to solve JENKINS-30084: the task has to be buildable to force the provisioning of nodes. + //if the execution gets here, it means the task could not be scheduled since the node + //the task is supposed to run on is offline or not available. + //Thus, the flyweighttask enters the buildables queue and will ask Jenkins to provision a node + LOGGER.log(Level.FINEST, "Flyweight task {0} is entering as buildable to provision a node.", taskDisplayName); + return new BuildableRunnable(p); + } + // if the execution gets here, it means the task is blocked by shutdown and null is returned. + LOGGER.log(Level.FINEST, "Task {0} is blocked by shutdown.", taskDisplayName); + return null; + } else { + // regular heavyweight task + return new BuildableRunnable(p); + } + } + + /** + * This method checks if the flyweight task can be run on any of the available executors + * @param p - the flyweight task to be scheduled + * @return a Runnable if there is an executor that can take the task, null otherwise + */ + @CheckForNull + private Runnable makeFlyWeightTaskBuildable(final BuildableItem p){ + //we double check if this is a flyweight task + if (p.task instanceof FlyweightTask) { Jenkins h = Jenkins.getInstance(); - Map hashSource = new HashMap(h.getNodes().size()); + Map hashSource = new HashMap(h.getNodes().size()); // Even if master is configured with zero executors, we may need to run a flyweight task like MatrixProject on it. hashSource.put(h, Math.max(h.getNumExecutors() * 100, 1)); @@ -1451,9 +1661,17 @@ public class Queue extends ResourceController implements Saveable { Label lbl = p.getAssignedLabel(); for (Node n : hash.list(p.task.getFullDisplayName())) { final Computer c = n.toComputer(); - if (c==null || c.isOffline()) continue; - if (lbl!=null && !lbl.contains(n)) continue; - if (n.canTake(p) != null) continue; + if (c == null || c.isOffline()) { + continue; + } + if (lbl!=null && !lbl.contains(n)) { + continue; + } + if (n.canTake(p) != null) { + continue; + } + + LOGGER.log(Level.FINEST, "Creating flyweight task {0} for computer {1}", new Object[]{p.task.getFullDisplayName(), c.getName()}); return new Runnable() { @Override public void run() { c.startFlyWeightTask(new WorkUnitContext(p).createWorkUnit(p.task)); @@ -1461,19 +1679,10 @@ public class Queue extends ResourceController implements Saveable { } }; } - } - // if the execution get here, it means we couldn't schedule it anywhere. - return null; - } else { // regular heavyweight task - return new Runnable() { - @Override public void run() { - p.enter(Queue.this); - } - }; } + return null; } - private static Hash NODE_HASH = new Hash() { public String hash(Node node) { return node.getNodeName(); @@ -1546,6 +1755,10 @@ public class Queue extends ResourceController implements Saveable { * compatibility with future changes to this interface. * *

+ * Plugins are encouraged to implement {@link AccessControlled} otherwise + * the tasks will be hidden from display in the queue. + * + *

* For historical reasons, {@link Task} object by itself * also represents the "primary" sub-task (and as implied by this * design, a {@link Task} must have at least one sub-task.) @@ -1597,6 +1810,9 @@ public class Queue extends ResourceController implements Saveable { /** * Checks the permission to see if the current user can abort this executable. * Returns normally from this method if it's OK. + *

+ * NOTE: If you have implemented {@link AccessControlled} this should just be + * {@code checkPermission(hudson.model.Item.CANCEL);} * * @throws AccessDeniedException if the permission is not granted. */ @@ -1606,6 +1822,12 @@ public class Queue extends ResourceController implements Saveable { * Works just like {@link #checkAbortPermission()} except it indicates the status by a return value, * instead of exception. * Also used by default for {@link hudson.model.Queue.Item#hasCancelPermission}. + *

+ * NOTE: If you have implemented {@link AccessControlled} this should just be + * {@code return hasPermission(hudson.model.Item.CANCEL);} + * + * @return false + * if the user doesn't have the permission. */ boolean hasAbortPermission(); @@ -2028,6 +2250,42 @@ public class Queue extends ResourceController implements Saveable { } + /** + * A Stub class for {@link Task} which exposes only the name of the Task to be displayed when the user + * has DISCOVERY permissions only. + */ + @Restricted(NoExternalUse.class) + @ExportedBean(defaultVisibility = 999) + public static class StubTask { + + private String name; + + public StubTask(@Nonnull Queue.Task base) { + this.name = base.getName(); + } + + @Exported + public String getName() { + return name; + } + } + + /** + * A Stub class for {@link Item} which exposes only the name of the Task to be displayed when the user + * has DISCOVERY permissions only. + */ + @Restricted(NoExternalUse.class) + @ExportedBean(defaultVisibility = 999) + public class StubItem { + + @Exported public StubTask task; + + public StubItem(StubTask task) { + this.task = task; + } + + } + /** * An optional interface for actions on Queue.Item. * Lets the action cooperate in queue management. @@ -2238,6 +2496,12 @@ public class Queue extends ResourceController implements Saveable { */ private boolean isPending; + /** + * Reasons why the last call to {@link #maintain} left this buildable (but not blocked or executing). + * May be null but not empty. + */ + private transient volatile @CheckForNull List transientCausesOfBlockage; + public BuildableItem(WaitingItem wi) { super(wi); } @@ -2251,10 +2515,12 @@ public class Queue extends ResourceController implements Saveable { if(isBlockedByShutdown(task)) return CauseOfBlockage.fromMessage(Messages._Queue_HudsonIsAboutToShutDown()); + List causesOfBlockage = transientCausesOfBlockage; + Label label = getAssignedLabel(); List allNodes = jenkins.getNodes(); if (allNodes.isEmpty()) - label = null; // no master/slave. pointless to talk about nodes + label = null; // no master/agent. pointless to talk about nodes if (label != null) { Set nodes = label.getNodes(); @@ -2262,9 +2528,14 @@ public class Queue extends ResourceController implements Saveable { if (nodes.size() != 1) return new BecauseLabelIsOffline(label); else return new BecauseNodeIsOffline(nodes.iterator().next()); } else { + if (causesOfBlockage != null && label.getIdleExecutors() > 0) { + return new CompositeCauseOfBlockage(causesOfBlockage); + } if (nodes.size() != 1) return new BecauseLabelIsBusy(label); else return new BecauseNodeIsBusy(nodes.iterator().next()); } + } else if (causesOfBlockage != null && new ComputerSet().getIdleExecutors() > 0) { + return new CompositeCauseOfBlockage(causesOfBlockage); } else { return CauseOfBlockage.createNeedsMoreExecutor(Messages._Queue_WaitingForNextAvailableExecutor()); } @@ -2549,11 +2820,13 @@ public class Queue extends ResourceController implements Saveable { return x; } + @SuppressFBWarnings(value = "IA_AMBIGUOUS_INVOCATION_OF_INHERITED_OR_OUTER_METHOD", + justification = "It will invoke the inherited clear() method according to Java semantics. " + + "FindBugs recommends suppresing warnings in such case") public void cancelAll() { for (T t : new ArrayList(this)) t.cancel(Queue.this); - - clear(); // just to be sure + clear(); } } @@ -2570,6 +2843,70 @@ public class Queue extends ResourceController implements Saveable { this.buildables = new ArrayList(buildables); this.pendings = new ArrayList(pendings); } + + @Override + public String toString() { + return "Queue.Snapshot{waitingList=" + waitingList + ";blockedProjects=" + blockedProjects + ";buildables=" + buildables + ";pendings=" + pendings + "}"; + } + } + + private static class LockedRunnable implements Runnable { + private final Runnable delegate; + + private LockedRunnable(Runnable delegate) { + this.delegate = delegate; + } + + @Override + public void run() { + withLock(delegate); + } + } + + private class BuildableRunnable implements Runnable { + private final BuildableItem buildableItem; + + private BuildableRunnable(BuildableItem p) { + this.buildableItem = p; + } + + @Override + public void run() { + //the flyweighttask enters the buildables queue and will ask Jenkins to provision a node + buildableItem.enter(Queue.this); + } + } + + private static class LockedJUCCallable implements java.util.concurrent.Callable { + private final java.util.concurrent.Callable delegate; + + private LockedJUCCallable(java.util.concurrent.Callable delegate) { + this.delegate = delegate; + } + + @Override + public V call() throws Exception { + return withLock(delegate); + } + } + + private static class LockedHRCallable implements hudson.remoting.Callable { + private static final long serialVersionUID = 1L; + private final hudson.remoting.Callable delegate; + + private LockedHRCallable(hudson.remoting.Callable delegate) { + this.delegate = delegate; + } + + @Override + public V call() throws T { + return withLock(delegate); + } + + @Override + public void checkRoles(RoleChecker checker) throws SecurityException { + delegate.checkRoles(checker); + } } @CLIResolver diff --git a/core/src/main/java/hudson/model/RSS.java b/core/src/main/java/hudson/model/RSS.java index 553a21c85a3a3eb32828200f5d25f59036da8029..bc36830e29c56d3b356c3eb33e14fc0ac1dd8071 100644 --- a/core/src/main/java/hudson/model/RSS.java +++ b/core/src/main/java/hudson/model/RSS.java @@ -50,14 +50,14 @@ public final class RSS { rsp.setStatus(HttpServletResponse.SC_OK); rsp.setContentType("application/xml; charset=UTF-8"); - PrintWriter pw = rsp.getWriter(); - pw.println(""); - pw.println(""+(url!=null?0:1)+""); - if(url==null) { - pw.println("url must be specified"); + try (PrintWriter pw = rsp.getWriter()) { + pw.println(""); + pw.println("" + (url != null ? 0 : 1) + ""); + if (url == null) { + pw.println("url must be specified"); + } + pw.println(""); } - pw.println(""); - pw.close(); } /** diff --git a/core/src/main/java/hudson/model/Resource.java b/core/src/main/java/hudson/model/Resource.java index e92287f8145c379c009b77462ffc51d7da9aa63a..caef6428bc5006669e0a63b23cdc758085b5d65a 100644 --- a/core/src/main/java/hudson/model/Resource.java +++ b/core/src/main/java/hudson/model/Resource.java @@ -25,7 +25,6 @@ package hudson.model; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; -import javax.annotation.Nullable; /** * Represents things that {@link hudson.model.Queue.Executable} uses while running. diff --git a/core/src/main/java/hudson/model/Result.java b/core/src/main/java/hudson/model/Result.java index b17a98a4cf5b11d45b5ea56ac6d83ed2b4e1c656..8b1d05fc4b0f3e7aa7b40b6deee7732cf5f7b5fa 100644 --- a/core/src/main/java/hudson/model/Result.java +++ b/core/src/main/java/hudson/model/Result.java @@ -25,9 +25,11 @@ package hudson.model; import com.thoughtworks.xstream.converters.SingleValueConverter; import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter; + import hudson.cli.declarative.OptionHandlerExtension; import hudson.init.Initializer; import hudson.util.EditDistance; + import org.apache.commons.beanutils.Converter; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; @@ -40,6 +42,9 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + /** * The build outcome. * @@ -49,42 +54,42 @@ public final class Result implements Serializable, CustomExportedBean { /** * The build had no errors. */ - public static final Result SUCCESS = new Result("SUCCESS",BallColor.BLUE,0,true); + public static final @Nonnull Result SUCCESS = new Result("SUCCESS",BallColor.BLUE,0,true); /** * The build had some errors but they were not fatal. * For example, some tests failed. */ - public static final Result UNSTABLE = new Result("UNSTABLE",BallColor.YELLOW,1,true); + public static final @Nonnull Result UNSTABLE = new Result("UNSTABLE",BallColor.YELLOW,1,true); /** * The build had a fatal error. */ - public static final Result FAILURE = new Result("FAILURE",BallColor.RED,2,true); + public static final @Nonnull Result FAILURE = new Result("FAILURE",BallColor.RED,2,true); /** * The module was not built. *

* This status code is used in a multi-stage build (like maven2) * where a problem in earlier stage prevented later stages from building. */ - public static final Result NOT_BUILT = new Result("NOT_BUILT",BallColor.NOTBUILT,3,false); + public static final @Nonnull Result NOT_BUILT = new Result("NOT_BUILT",BallColor.NOTBUILT,3,false); /** * The build was manually aborted. * * If you are catching {@link InterruptedException} and interpreting it as {@link #ABORTED}, * you should check {@link Executor#abortResult()} instead (starting 1.417.) */ - public static final Result ABORTED = new Result("ABORTED",BallColor.ABORTED,4,false); + public static final @Nonnull Result ABORTED = new Result("ABORTED",BallColor.ABORTED,4,false); - private final String name; + private final @Nonnull String name; /** * Bigger numbers are worse. */ - public final int ordinal; + public final @Nonnegative int ordinal; /** * Default ball color for this status. */ - public final BallColor color; + public final @Nonnull BallColor color; /** * Is this a complete build - i.e. did it run to the end (not aborted)? @@ -92,7 +97,7 @@ public final class Result implements Serializable, CustomExportedBean { */ public final boolean completeBuild; - private Result(String name, BallColor color, int ordinal, boolean complete) { + private Result(@Nonnull String name, @Nonnull BallColor color, @Nonnegative int ordinal, boolean complete) { this.name = name; this.color = color; this.ordinal = ordinal; @@ -102,26 +107,26 @@ public final class Result implements Serializable, CustomExportedBean { /** * Combines two {@link Result}s and returns the worse one. */ - public Result combine(Result that) { + public @Nonnull Result combine(@Nonnull Result that) { if(this.ordinal < that.ordinal) return that; else return this; } - public boolean isWorseThan(Result that) { + public boolean isWorseThan(@Nonnull Result that) { return this.ordinal > that.ordinal; } - public boolean isWorseOrEqualTo(Result that) { + public boolean isWorseOrEqualTo(@Nonnull Result that) { return this.ordinal >= that.ordinal; } - public boolean isBetterThan(Result that) { + public boolean isBetterThan(@Nonnull Result that) { return this.ordinal < that.ordinal; } - public boolean isBetterOrEqualTo(Result that) { + public boolean isBetterOrEqualTo(@Nonnull Result that) { return this.ordinal <= that.ordinal; } @@ -133,31 +138,30 @@ public final class Result implements Serializable, CustomExportedBean { return this.completeBuild; } - @Override - public String toString() { + public @Nonnull String toString() { return name; } - public String toExportedObject() { + public @Nonnull String toExportedObject() { return name; } - public static Result fromString(String s) { + public static @Nonnull Result fromString(@Nonnull String s) { for (Result r : all) if (s.equalsIgnoreCase(r.name)) return r; return FAILURE; } - private static List getNames() { + private static @Nonnull List getNames() { List l = new ArrayList(); for (Result r : all) l.add(r.name); return l; } - // Maintain each Result as a singleton deserialized (like build result from a slave node) + // Maintain each Result as a singleton deserialized (like build result from an agent node) private Object readResolve() { for (Result r : all) if (ordinal==r.ordinal) @@ -170,10 +174,12 @@ public final class Result implements Serializable, CustomExportedBean { private static final Result[] all = new Result[] {SUCCESS,UNSTABLE,FAILURE,NOT_BUILT,ABORTED}; public static final SingleValueConverter conv = new AbstractSingleValueConverter () { + @Override public boolean canConvert(Class clazz) { return clazz==Result.class; } + @Override public Object fromString(String s) { return Result.fromString(s); } diff --git a/core/src/main/java/hudson/model/Run.java b/core/src/main/java/hudson/model/Run.java index ff80613a8b97de437c36d989c0e748102df45d28..338475983c023160cdb140390c3973f15beeb9e1 100644 --- a/core/src/main/java/hudson/model/Run.java +++ b/core/src/main/java/hudson/model/Run.java @@ -36,15 +36,16 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.FeedAdapter; import hudson.Functions; -import hudson.Util; -import hudson.XmlFile; -import hudson.cli.declarative.CLIMethod; import hudson.console.AnnotatedLargeText; import hudson.console.ConsoleLogFilter; import hudson.console.ConsoleNote; import hudson.console.ModelHyperlinkNote; +import hudson.console.PlainTextConsoleOutputStream; +import jenkins.util.SystemProperties; +import hudson.Util; +import hudson.XmlFile; +import hudson.cli.declarative.CLIMethod; import hudson.model.Descriptor.FormException; -import hudson.model.Run.RunExecution; import hudson.model.listeners.RunListener; import hudson.model.listeners.SaveableListener; import hudson.model.queue.Executables; @@ -56,12 +57,11 @@ import hudson.security.Permission; import hudson.security.PermissionGroup; import hudson.security.PermissionScope; import hudson.tasks.BuildWrapper; -import hudson.util.FlushProofOutputStream; import hudson.util.FormApply; import hudson.util.LogTaskListener; import hudson.util.ProcessTree; import hudson.util.XStream2; -import java.io.BufferedReader; + import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; @@ -71,6 +71,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; +import java.io.RandomAccessFile; import java.io.Reader; import java.io.StringWriter; import java.nio.charset.Charset; @@ -86,7 +87,6 @@ import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -116,9 +116,14 @@ import org.acegisecurity.AccessDeniedException; import org.acegisecurity.Authentication; import org.apache.commons.io.IOUtils; import org.apache.commons.jelly.XMLOutput; +import org.apache.commons.lang.ArrayUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.*; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.interceptor.RequirePOST; @@ -352,7 +357,7 @@ public abstract class Run ,RunT extends Run,RunT extends Run getBadgeActions() { List r = getActions(BuildBadgeAction.class); if(isKeepLog()) { + r = new ArrayList<>(r); r.add(new KeepLogBuildBadge()); } return r; @@ -630,7 +636,7 @@ public abstract class Run ,RunT extends Run,RunT extends Run,RunT extends Run,RunT extends Run,RunT extends Run,RunT extends Run getLog(int maxLines) throws IOException { - int lineCount = 0; - List logLines = new LinkedList(); if (maxLines == 0) { - return logLines; + return Collections.emptyList(); } - BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(getLogFile()),getCharset())); - try { - for (String line = reader.readLine(); line != null; line = reader.readLine()) { - logLines.add(line); - ++lineCount; - // If we have too many lines, remove the oldest line. This way we - // never have to hold the full contents of a huge log file in memory. - // Adding to and removing from the ends of a linked list are cheap - // operations. - if (lineCount > maxLines) - logLines.remove(0); + + int lines = 0; + long filePointer; + final List lastLines = new ArrayList<>(Math.min(maxLines, 128)); + final List bytes = new ArrayList<>(); + + try (RandomAccessFile fileHandler = new RandomAccessFile(getLogFile(), "r")) { + long fileLength = fileHandler.length() - 1; + + for (filePointer = fileLength; filePointer != -1 && maxLines != lines; filePointer--) { + fileHandler.seek(filePointer); + byte readByte = fileHandler.readByte(); + + if (readByte == 0x0A) { + if (filePointer < fileLength) { + lines = lines + 1; + lastLines.add(convertBytesToString(bytes)); + bytes.clear(); + } + } else if (readByte != 0xD) { + bytes.add(readByte); + } } - } finally { - reader.close(); } + if (lines != maxLines) { + lastLines.add(convertBytesToString(bytes)); + } + + Collections.reverse(lastLines); + // If the log has been truncated, include that information. // Use set (replaces the first element) rather than add so that // the list doesn't grow beyond the specified maximum number of lines. - if (lineCount > maxLines) - logLines.set(0, "[...truncated " + (lineCount - (maxLines - 1)) + " lines...]"); + if (lines == maxLines) { + lastLines.set(0, "[...truncated " + Functions.humanReadableByteSize(filePointer)+ "...]"); + } - return ConsoleNote.removeNotes(logLines); + return ConsoleNote.removeNotes(lastLines); + } + + private String convertBytesToString(List bytes) { + Collections.reverse(bytes); + Byte[] byteArray = bytes.toArray(new Byte[bytes.size()]); + return new String(ArrayUtils.toPrimitive(byteArray), getCharset()); } public void doBuildStatus( StaplerRequest req, StaplerResponse rsp ) throws IOException { @@ -2089,19 +2117,13 @@ public abstract class Run ,RunT extends Run,RunT extends Run job = j.getItemByFullName(jobName, Job.class); if (job == null) { return null; @@ -2316,13 +2335,10 @@ public abstract class Run ,RunT extends Run,RunT extends Run> extends AbstractLazyLoadRunMap // Defense against JENKINS-23152 and its ilk. File rootDir = r.getRootDir(); if (rootDir.isDirectory()) { - throw new IllegalStateException(rootDir + " already existed; will not overwite with " + r); + throw new IllegalStateException("JENKINS-23152: " + rootDir + " already existed; will not overwrite with " + r); } if (!r.getClass().getName().equals("hudson.matrix.MatrixRun")) { // JENKINS-26739: grandfathered in proposeNewNumber(r.getNumber()); diff --git a/core/src/main/java/hudson/model/RunParameterDefinition.java b/core/src/main/java/hudson/model/RunParameterDefinition.java index 07195499d6688d8e509aebcb25c99a8a9f84a1ae..da1e7865e62734ae184fad71e5c0b2b01a53d2df 100644 --- a/core/src/main/java/hudson/model/RunParameterDefinition.java +++ b/core/src/main/java/hudson/model/RunParameterDefinition.java @@ -26,6 +26,7 @@ package hudson.model; import jenkins.model.Jenkins; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.Exported; @@ -133,7 +134,7 @@ public class RunParameterDefinition extends SimpleParameterDefinition { } } - @Extension + @Extension @Symbol({"run","runParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/Saveable.java b/core/src/main/java/hudson/model/Saveable.java index a27d35e27dd235b0341280545bf5838ccb8893a6..79e361cc26ae7b501905b5fe3293b048c868940f 100644 --- a/core/src/main/java/hudson/model/Saveable.java +++ b/core/src/main/java/hudson/model/Saveable.java @@ -24,7 +24,6 @@ package hudson.model; import hudson.BulkChange; -import hudson.model.listeners.SaveableListener; import java.io.IOException; /** diff --git a/core/src/main/java/hudson/model/Slave.java b/core/src/main/java/hudson/model/Slave.java index 30bc6bf217ba84c590a6c43800095a317747eafa..38a7d09a5cf03ff8221a0380f5fe7f50a7c4fa82 100644 --- a/core/src/main/java/hudson/model/Slave.java +++ b/core/src/main/java/hudson/model/Slave.java @@ -24,12 +24,16 @@ */ package hudson.model; +import com.google.common.collect.ImmutableSet; +import hudson.DescriptorExtensionList; import hudson.FilePath; import hudson.Launcher; -import hudson.Util; import hudson.Launcher.RemoteLauncher; +import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.remoting.Callable; +import hudson.remoting.Channel; +import hudson.remoting.Which; import hudson.slaves.CommandLauncher; import hudson.slaves.ComputerLauncher; import hudson.slaves.DumbSlave; @@ -42,7 +46,6 @@ import hudson.slaves.SlaveComputer; import hudson.util.ClockDifference; import hudson.util.DescribableList; import hudson.util.FormValidation; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -51,26 +54,28 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Set; - -import javax.servlet.ServletException; - import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import javax.servlet.ServletException; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import jenkins.slaves.WorkspaceLocator; - +import jenkins.util.SystemProperties; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; /** - * Information about a Hudson slave node. + * Information about a Hudson agent node. * *

* Ideally this would have been in the hudson.slaves package, @@ -78,19 +83,24 @@ import org.kohsuke.stapler.StaplerResponse; * *

* TODO: move out more stuff to {@link DumbSlave}. + * + * On Febrary, 2016 a general renaming was done internally: the "slave" term was replaced by + * "Agent". This change was applied in: UI labels/HTML pages, javadocs and log messages. + * Java classes, fields, methods, etc were not renamed to avoid compatibility issues. + * See JENKINS-27268. * * @author Kohsuke Kawaguchi */ public abstract class Slave extends Node implements Serializable { /** - * Name of this slave node. + * Name of this agent node. */ protected String name; /** * Description of this node. */ - private final String description; + private String description; /** * Path to the root of the workspace from the view point of this node, such as "/hudson", this need not @@ -110,15 +120,15 @@ public abstract class Slave extends Node implements Serializable { /** * Job allocation strategy. */ - private Mode mode; + private Mode mode = Mode.NORMAL; /** - * Slave availablility strategy. + * Agent availablility strategy. */ private RetentionStrategy retentionStrategy; /** - * The starter that will startup this slave. + * The starter that will startup this agent. */ private ComputerLauncher launcher; @@ -127,7 +137,8 @@ public abstract class Slave extends Node implements Serializable { */ private String label=""; - private /*almost final*/ DescribableList,NodePropertyDescriptor> nodeProperties = new DescribableList,NodePropertyDescriptor>(Jenkins.getInstance()); + private /*almost final*/ DescribableList,NodePropertyDescriptor> nodeProperties = + new DescribableList,NodePropertyDescriptor>(Jenkins.getInstance().getNodesObject()); /** * Lazily computed set of labels from {@link #label}. @@ -135,7 +146,7 @@ public abstract class Slave extends Node implements Serializable { private transient volatile Set

* This interface is implemented by Hudson core and passed to extension points so that diff --git a/core/src/main/java/hudson/model/TextParameterDefinition.java b/core/src/main/java/hudson/model/TextParameterDefinition.java index 53605754ea9819e0a82c79e768599791e86b2572..b3f3538b40b68951e21b9df92c25159c4316a607 100644 --- a/core/src/main/java/hudson/model/TextParameterDefinition.java +++ b/core/src/main/java/hudson/model/TextParameterDefinition.java @@ -25,6 +25,7 @@ package hudson.model; import hudson.Extension; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; @@ -37,7 +38,7 @@ public class TextParameterDefinition extends StringParameterDefinition { super(name, defaultValue, description); } - @Extension + @Extension @Symbol({"text","textParam"}) public static class DescriptorImpl extends ParameterDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/model/TextParameterValue.java b/core/src/main/java/hudson/model/TextParameterValue.java index 6e5a50e1613a276039cb9299643e83f8c6699b94..1e2227e303c0ca7cc21d3dfc3a9dd60420cbeaf0 100644 --- a/core/src/main/java/hudson/model/TextParameterValue.java +++ b/core/src/main/java/hudson/model/TextParameterValue.java @@ -26,7 +26,7 @@ package hudson.model; import org.kohsuke.stapler.DataBoundConstructor; /** - * @author Rafa de la Torre + * @author Rafa de la Torre */ public class TextParameterValue extends StringParameterValue { diff --git a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java index 7aa4145a1a214035ba18b72c7befc8829d1a0ccb..8c2383aea74803cb9331558116a3f6635b6154f0 100644 --- a/core/src/main/java/hudson/model/TopLevelItemDescriptor.java +++ b/core/src/main/java/hudson/model/TopLevelItemDescriptor.java @@ -25,15 +25,36 @@ package hudson.model; import hudson.ExtensionList; import jenkins.model.Jenkins; +import jenkins.model.item_category.ItemCategory; import org.acegisecurity.AccessDeniedException; +import org.apache.commons.jelly.Script; +import org.apache.commons.jelly.XMLOutput; +import org.apache.commons.lang.StringUtils; +import org.jenkins.ui.icon.Icon; +import org.jenkins.ui.icon.IconSet; +import org.jenkins.ui.icon.IconSpec; +import org.kohsuke.stapler.MetaClass; +import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.WebApp; +import org.kohsuke.stapler.jelly.DefaultScriptInvoker; +import org.kohsuke.stapler.jelly.JellyClassTearOff; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import java.io.StringWriter; +import java.util.logging.Level; +import java.util.logging.Logger; /** * {@link Descriptor} for {@link TopLevelItem}s. * * @author Kohsuke Kawaguchi */ -public abstract class TopLevelItemDescriptor extends Descriptor { +public abstract class TopLevelItemDescriptor extends Descriptor implements IconSpec { + + private static final Logger LOGGER = Logger.getLogger(TopLevelItemDescriptor.class.getName()); + protected TopLevelItemDescriptor(Class clazz) { super(clazz); } @@ -53,7 +74,7 @@ public abstract class TopLevelItemDescriptor extends Descriptor { * This method allows the subtype of {@link TopLevelItemDescriptor}s to filter them out. * *

- * This is useful for a workflow/company specific job type that wants to eliminate + * This is useful for a workflow/company specific item type that wants to eliminate * options that the user would see. * * @since 1.294 @@ -66,7 +87,7 @@ public abstract class TopLevelItemDescriptor extends Descriptor { * {@link TopLevelItemDescriptor}s often may want to limit the scope within which they can be created. * This method allows the subtype of {@link TopLevelItemDescriptor}s to filter them out. * - * @since TODO + * @since 1.607 */ public boolean isApplicableIn(ItemGroup parent) { return true; @@ -76,7 +97,7 @@ public abstract class TopLevelItemDescriptor extends Descriptor { * Checks if this top level item is applicable within the specified item group. *

* This is just a convenience function. - * @since TODO + * @since 1.607 */ public final void checkApplicableIn(ItemGroup parent) { if (!isApplicableIn(parent)) { @@ -103,16 +124,134 @@ public abstract class TopLevelItemDescriptor extends Descriptor { * {@inheritDoc} * *

- * Used as the caption when the user chooses what job type to create. - * The descriptor implementation also needs to have newJobDetail.jelly + * Used as the caption when the user chooses what item type to create. + * The descriptor implementation also needs to have newInstanceDetail.jelly * script, which will be used to render the text below the caption - * that explains the job type. + * that explains the item type. + */ + @Override + public String getDisplayName() { + return super.getDisplayName(); + } + + /** + * A description of this kind of item type. This description can contain HTML code but it is recommend to use text plain + * in order to avoid how it should be represented. + * + * This method should be called in a thread where Stapler is associated, but it will return an empty string. + * + * @return A string, by default the value from newInstanceDetail view is taken. + * + * @since 2.0 + */ + @Nonnull + public String getDescription() { + Stapler stapler = Stapler.getCurrent(); + if (stapler != null) { + try { + WebApp webapp = WebApp.getCurrent(); + MetaClass meta = webapp.getMetaClass(this); + Script s = meta.loadTearOff(JellyClassTearOff.class).findScript("newInstanceDetail"); + if (s == null) { + return ""; + } + DefaultScriptInvoker dsi = new DefaultScriptInvoker(); + StringWriter sw = new StringWriter(); + XMLOutput xml = dsi.createXMLOutput(sw, true); + dsi.invokeScript(Stapler.getCurrentRequest(), Stapler.getCurrentResponse(), s, this, xml); + return sw.toString(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, null, e); + return ""; + } + } else { + return ""; + } + } + + /** + * Used to categorize this kind of item type. @see {@link ItemCategory} + * + * @return A string with the category identifier, {@link ItemCategory.UncategorizedCategory#getId()} by default. + * + * @since 2.0 */ - public abstract String getDisplayName(); + @Nonnull + public String getCategoryId() { + return ItemCategory.UncategorizedCategory.ID; + } + + /** + * Represents a file path pattern to get the Item icon in different sizes. + * + * For example: plugin/plugin-shortname/images/:size/item.png, where {@code :size} represents the different + * icon sizes used commonly in Jenkins project: 16x16, 24x24, 32x32 or 48x48 + * + * @see {@link FreeStyleProject.DescriptorImpl#getIconFilePathPattern()} + * + * @return A string or null if it is not defined. + * + * @since 2.0 + * @deprecated prefer {@link #getIconClassName()} + */ + @CheckForNull + @Deprecated + public String getIconFilePathPattern() { + return null; + } + + /** + * An icon file path associated to a specific size. + * + * @param size A string with values that represent the common sizes: 16x16, 24x24, 32x32 or 48x48 + * + * @return A string or null if it is not defined. + * + * @since 2.0 + * @deprecated prefer {@link #getIconClassName()} + */ + @CheckForNull + @Deprecated + public String getIconFilePath(String size) { + if (!StringUtils.isBlank(getIconFilePathPattern())) { + return getIconFilePathPattern().replace(":size", size); + } + return null; + } + + /** + * Get the Item's Icon class specification e.g. 'icon-notepad'. + *

+ * Note: do NOT include icon size specifications (such as 'icon-sm'). + * + * @return The Icon class specification e.g. 'icon-notepad'. + */ + @Override + public String getIconClassName() { + // Oh the fun of somebody adding a legacy way of referencing images into 2.0 code + String pattern = getIconFilePathPattern(); + if (pattern != null) { + // here we go with the dance of the IconSet's + String path = pattern.replace(":size", "24x24"); // we'll strip the icon-md to get the class name + if (path.indexOf('/') == -1) { + // this one is easy... too easy... also will never happen + return IconSet.toNormalizedIconNameClass(path); + } + if (Jenkins.RESOURCE_PATH.length() > 0 && path.startsWith(Jenkins.RESOURCE_PATH)) { + // will to live falling + path = path.substring(Jenkins.RESOURCE_PATH.length()); + } + Icon icon = IconSet.icons.getIconByUrl(path); + if (icon != null) { + return icon.getClassSpec().replaceAll("\\s*icon-md\\s*", " ").replaceAll("\\s+", " "); + } + } + return null; + } /** * @deprecated since 2007-01-19. - * This is not a valid operation for {@link Job}s. + * This is not a valid operation for {@link Item}s. */ @Deprecated public TopLevelItem newInstance(StaplerRequest req) throws FormException { diff --git a/core/src/main/java/hudson/model/TransientBuildActionFactory.java b/core/src/main/java/hudson/model/TransientBuildActionFactory.java index 0ac332823f2fcb33c4c6c173dc8e23b32d57c3e2..dfac20cb07808ac000edb1a8807f616c3c77b59b 100644 --- a/core/src/main/java/hudson/model/TransientBuildActionFactory.java +++ b/core/src/main/java/hudson/model/TransientBuildActionFactory.java @@ -3,7 +3,6 @@ package hudson.model; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import java.util.Collection; import java.util.Collections; import jenkins.model.TransientActionFactory; diff --git a/core/src/main/java/hudson/model/TransientComputerActionFactory.java b/core/src/main/java/hudson/model/TransientComputerActionFactory.java index 37fc369e95f51612f2939dd69b21ca0bc237a4e1..3a77db8c5260e77310a790ace88eb8af6c5d5351 100644 --- a/core/src/main/java/hudson/model/TransientComputerActionFactory.java +++ b/core/src/main/java/hudson/model/TransientComputerActionFactory.java @@ -25,7 +25,6 @@ package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import java.util.ArrayList; import java.util.Collection; diff --git a/core/src/main/java/hudson/model/TransientProjectActionFactory.java b/core/src/main/java/hudson/model/TransientProjectActionFactory.java index 35acbaebb9a7b5cda30ac662a1d3d4888da8566b..23fd0a138c78d1e357f45aa09fd425c5fe7f62c9 100644 --- a/core/src/main/java/hudson/model/TransientProjectActionFactory.java +++ b/core/src/main/java/hudson/model/TransientProjectActionFactory.java @@ -27,7 +27,6 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.tasks.BuildStep; -import jenkins.model.Jenkins; import java.util.Collection; import jenkins.model.TransientActionFactory; diff --git a/core/src/main/java/hudson/model/TransientViewActionFactory.java b/core/src/main/java/hudson/model/TransientViewActionFactory.java index 43633bac2d84154343dcea184e6ea2cce2d2d10e..edf9a1c85afce7fccad49c6feda2b6595db3245c 100644 --- a/core/src/main/java/hudson/model/TransientViewActionFactory.java +++ b/core/src/main/java/hudson/model/TransientViewActionFactory.java @@ -2,7 +2,6 @@ package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import java.util.ArrayList; import java.util.List; diff --git a/core/src/main/java/hudson/model/TreeView.java b/core/src/main/java/hudson/model/TreeView.java index 97f6d406c9097b68454cf54e4891efda2b524cb9..a998f8aa07f7c09ab55646e58aa90ce117155ec7 100644 --- a/core/src/main/java/hudson/model/TreeView.java +++ b/core/src/main/java/hudson/model/TreeView.java @@ -27,6 +27,7 @@ import hudson.model.Descriptor.FormException; import hudson.util.CaseInsensitiveComparator; import hudson.Indenter; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.views.ViewsTabBar; import jenkins.model.Jenkins; import org.kohsuke.stapler.DataBoundConstructor; @@ -162,7 +163,7 @@ public class TreeView extends View implements ViewGroup { // this feature is not public yet @Extension public static ViewDescriptor register() { - if(Boolean.getBoolean("hudson.TreeView")) + if(SystemProperties.getBoolean("hudson.TreeView")) return new DescriptorImpl(); else return null; diff --git a/core/src/main/java/hudson/model/UpdateCenter.java b/core/src/main/java/hudson/model/UpdateCenter.java index 875c76ffc3b1f21f9ec91823f620823856726030..0c11acb9e50e44668bb19d23ca4a3b7316b8bc68 100644 --- a/core/src/main/java/hudson/model/UpdateCenter.java +++ b/core/src/main/java/hudson/model/UpdateCenter.java @@ -30,9 +30,14 @@ import hudson.Functions; import hudson.PluginManager; import hudson.PluginWrapper; import hudson.ProxyConfiguration; +import hudson.security.ACLContext; +import jenkins.util.SystemProperties; import hudson.Util; import hudson.XmlFile; import static hudson.init.InitMilestone.PLUGINS_STARTED; +import static java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; + import hudson.init.Initializer; import hudson.lifecycle.Lifecycle; import hudson.lifecycle.RestartNotSupportedException; @@ -49,37 +54,54 @@ import hudson.util.IOException2; import hudson.util.IOUtils; import hudson.util.PersistedList; import hudson.util.XStream2; +import jenkins.MissingDependencyException; import jenkins.RestartRequiredException; +import jenkins.install.InstallUtil; import jenkins.model.Jenkins; import jenkins.util.io.OnMaster; +import net.sf.json.JSONObject; + import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; +import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.input.CountingInputStream; import org.apache.commons.io.output.NullOutputStream; +import org.jenkinsci.Symbol; import org.jvnet.localizer.Localizable; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; +import javax.annotation.Nonnull; import javax.net.ssl.SSLHandshakeException; import javax.servlet.ServletException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.lang.reflect.Constructor; +import java.net.HttpRetryException; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; +import java.security.DigestOutputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; +import java.util.UUID; import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -109,24 +131,40 @@ import org.kohsuke.stapler.interceptor.RequirePOST; * and plugins, and to use alternate strategies for downloading, installing * and updating components. See the Javadocs for {@link UpdateCenterConfiguration} * for more information. - * + *

+ * Extending Update Centers. The update center in {@code Jenkins} can be replaced by defining a + * System Property (hudson.model.UpdateCenter.className). See {@link #createUpdateCenter(hudson.model.UpdateCenter.UpdateCenterConfiguration)}. + * This className should be available on early startup, so it cannot come only from a library + * (e.g. Jenkins module or Extra library dependency in the WAR file project). + * Plugins cannot be used for such purpose. + * In order to be correctly instantiated, the class definition must have two constructors: + * {@link #UpdateCenter()} and {@link #UpdateCenter(hudson.model.UpdateCenter.UpdateCenterConfiguration)}. + * If the class does not comply with the requirements, a fallback to the default UpdateCenter will be performed. + * * @author Kohsuke Kawaguchi * @since 1.220 */ @ExportedBean public class UpdateCenter extends AbstractModelObject implements Saveable, OnMaster { - - private static final String UPDATE_CENTER_URL = System.getProperty(UpdateCenter.class.getName()+".updateCenterUrl","http://updates.jenkins-ci.org/"); + + private static final String UPDATE_CENTER_URL = SystemProperties.getString(UpdateCenter.class.getName()+".updateCenterUrl","http://updates.jenkins-ci.org/"); + + /** + * Read timeout when downloading plugins, defaults to 1 minute + */ + private static final int PLUGIN_DOWNLOAD_READ_TIMEOUT = SystemProperties.getInteger(UpdateCenter.class.getName()+".pluginDownloadReadTimeoutSeconds", 60) * 1000; + + public static final String PREDEFINED_UPDATE_SITE_ID = "default"; /** * {@linkplain UpdateSite#getId() ID} of the default update site. - * @since 1.483 + * @since 1.483; configurable via system property since 2.4 */ - public static final String ID_DEFAULT = "default"; + public static final String ID_DEFAULT = SystemProperties.getString(UpdateCenter.class.getName()+".defaultUpdateSiteId", PREDEFINED_UPDATE_SITE_ID); @Restricted(NoExternalUse.class) public static final String ID_UPLOAD = "_upload"; - + /** * {@link ExecutorService} that performs installation. * @since 1.501 @@ -139,7 +177,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas */ protected final ExecutorService updateService = Executors.newCachedThreadPool( new NamingThreadFactory(new DaemonThreadFactory(), "Update site data downloader")); - + /** * List of created {@link UpdateCenterJob}s. Access needs to be synchronized. */ @@ -163,11 +201,97 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas private boolean requiresRestart; + /** + * Simple connection status enum. + */ + @Restricted(NoExternalUse.class) + static enum ConnectionStatus { + /** + * Connection status has not started yet. + */ + PRECHECK, + /** + * Connection status check has been skipped. + * As example, it may happen if there is no connection check URL defined for the site. + * @since 2.4 + */ + SKIPPED, + /** + * Connection status is being checked at this time. + */ + CHECKING, + /** + * Connection status was not checked. + */ + UNCHECKED, + /** + * Connection is ok. + */ + OK, + /** + * Connection status check failed. + */ + FAILED; + + static final String INTERNET = "internet"; + static final String UPDATE_SITE = "updatesite"; + } + public UpdateCenter() { configure(new UpdateCenterConfiguration()); } + UpdateCenter(@Nonnull UpdateCenterConfiguration configuration) { + configure(configuration); + } + + /** + * Creates an update center. + * @param config Requested configuration. May be {@code null} if defaults should be used + * @return Created Update center. {@link UpdateCenter} by default, but may be overridden + * @since 2.4 + */ + @Nonnull + public static UpdateCenter createUpdateCenter(@CheckForNull UpdateCenterConfiguration config) { + String requiredClassName = SystemProperties.getString(UpdateCenter.class.getName()+".className", null); + if (requiredClassName == null) { + // Use the defaul Update Center + LOGGER.log(Level.FINE, "Using the default Update Center implementation"); + return createDefaultUpdateCenter(config); + } + + LOGGER.log(Level.FINE, "Using the custom update center: {0}", requiredClassName); + try { + final Class clazz = Class.forName(requiredClassName).asSubclass(UpdateCenter.class); + if (!UpdateCenter.class.isAssignableFrom(clazz)) { + LOGGER.log(Level.SEVERE, "The specified custom Update Center {0} is not an instance of {1}. Falling back to default.", + new Object[] {requiredClassName, UpdateCenter.class.getName()}); + return createDefaultUpdateCenter(config); + } + final Class ucClazz = clazz.asSubclass(UpdateCenter.class); + final Constructor defaultConstructor = ucClazz.getConstructor(); + final Constructor configConstructor = ucClazz.getConstructor(UpdateCenterConfiguration.class); + LOGGER.log(Level.FINE, "Using the constructor {0} Update Center configuration for {1}", + new Object[] {config != null ? "with" : "without", requiredClassName}); + return config != null ? configConstructor.newInstance(config) : defaultConstructor.newInstance(); + } catch(ClassCastException e) { + // Should never happen + LOGGER.log(WARNING, "UpdateCenter class {0} does not extend hudson.model.UpdateCenter. Using default.", requiredClassName); + } catch(NoSuchMethodException e) { + LOGGER.log(WARNING, String.format("UpdateCenter class %s does not define one of the required constructors. Using default", requiredClassName), e); + } catch(Exception e) { + LOGGER.log(WARNING, String.format("Unable to instantiate custom plugin manager [%s]. Using default.", requiredClassName), e); + } + return createDefaultUpdateCenter(config); + } + + @Nonnull + private static UpdateCenter createDefaultUpdateCenter(@CheckForNull UpdateCenterConfiguration config) { + return config != null ? new UpdateCenter(config) : new UpdateCenter(); + } + public Api getApi() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); return new Api(this); } @@ -229,6 +353,152 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas return null; } + /** + * Get the current connection status. + *

+ * Supports a "siteId" request parameter, defaulting to {@link #ID_DEFAULT} for the default + * update site. + * + * @return The current connection status. + */ + @Restricted(DoNotUse.class) + public HttpResponse doConnectionStatus(StaplerRequest request) { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + try { + String siteId = request.getParameter("siteId"); + if (siteId == null) { + siteId = ID_DEFAULT; + } else if (siteId.equals("default")) { + // If the request explicitly requires the default ID, ship it + siteId = ID_DEFAULT; + } + ConnectionCheckJob checkJob = getConnectionCheckJob(siteId); + if (checkJob == null) { + UpdateSite site = getSite(siteId); + if (site != null) { + checkJob = addConnectionCheckJob(site); + } + } + if (checkJob != null) { + boolean isOffline = false; + for (ConnectionStatus status : checkJob.connectionStates.values()) { + if(ConnectionStatus.FAILED.equals(status)) { + isOffline = true; + break; + } + } + if (isOffline) { + // retry connection states if determined to be offline + checkJob.run(); + isOffline = false; + for (ConnectionStatus status : checkJob.connectionStates.values()) { + if(ConnectionStatus.FAILED.equals(status)) { + isOffline = true; + break; + } + } + if(!isOffline) { // also need to download the metadata + updateAllSites(); + } + } + return HttpResponses.okJSON(checkJob.connectionStates); + } else { + return HttpResponses.errorJSON(String.format("Cannot check connection status of the update site with ID='%s'" + + ". This update center cannot be resolved", siteId)); + } + } catch (Exception e) { + return HttpResponses.errorJSON(String.format("ERROR: %s", e.getMessage())); + } + } + + /** + * Called to determine if there was an incomplete installation, what the statuses of the plugins are + */ + @Restricted(DoNotUse.class) // WebOnly + public HttpResponse doIncompleteInstallStatus() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + try { + Map jobs = InstallUtil.getPersistedInstallStatus(); + if(jobs == null) { + jobs = Collections.emptyMap(); + } + return HttpResponses.okJSON(jobs); + } catch (Exception e) { + return HttpResponses.errorJSON(String.format("ERROR: %s", e.getMessage())); + } + } + + /** + * Called to persist the currently installing plugin states. This allows + * us to support install resume if Jenkins is restarted while plugins are + * being installed. + */ + @Restricted(NoExternalUse.class) + public synchronized void persistInstallStatus() { + List jobs = getJobs(); + + boolean activeInstalls = false; + for (UpdateCenterJob job : jobs) { + if (job instanceof InstallationJob) { + InstallationJob installationJob = (InstallationJob) job; + if(!installationJob.status.isSuccess()) { + activeInstalls = true; + } + } + } + + if(activeInstalls) { + InstallUtil.persistInstallStatus(jobs); // save this info + } + else { + InstallUtil.clearInstallStatus(); // clear this info + } + } + + /** + * Get the current installation status of a plugin set. + *

+ * Supports a "correlationId" request parameter if you only want to get the + * install status of a set of plugins requested for install through + * {@link PluginManager#doInstallPlugins(org.kohsuke.stapler.StaplerRequest)}. + * + * @return The current installation status of a plugin set. + */ + @Restricted(DoNotUse.class) + public HttpResponse doInstallStatus(StaplerRequest request) { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + try { + String correlationId = request.getParameter("correlationId"); + Map response = new HashMap<>(); + response.put("state", Jenkins.getInstance().getInstallState().name()); + List> installStates = new ArrayList<>(); + response.put("jobs", installStates); + List jobCopy = getJobs(); + + for (UpdateCenterJob job : jobCopy) { + if (job instanceof InstallationJob) { + UUID jobCorrelationId = job.getCorrelationId(); + if (correlationId == null || (jobCorrelationId != null && correlationId.equals(jobCorrelationId.toString()))) { + InstallationJob installationJob = (InstallationJob) job; + Map pluginInfo = new LinkedHashMap<>(); + pluginInfo.put("name", installationJob.plugin.name); + pluginInfo.put("version", installationJob.plugin.version); + pluginInfo.put("title", installationJob.plugin.title); + pluginInfo.put("installStatus", installationJob.status.getType()); + pluginInfo.put("requiresRestart", Boolean.toString(installationJob.status.requiresRestart())); + if (jobCorrelationId != null) { + pluginInfo.put("correlationId", jobCorrelationId.toString()); + } + installStates.add(pluginInfo); + } + } + } + return HttpResponses.okJSON(JSONObject.fromObject(response)); + } catch (Exception e) { + return HttpResponses.errorJSON(String.format("ERROR: %s", e.getMessage())); + } + } + /** * Returns latest Jenkins upgrade job. * @return HudsonUpgradeJob or null if not found @@ -263,7 +533,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * Alias for {@link #getById}. + * @param id ID of the update site to be retrieved + * @return Discovered {@link UpdateSite}. {@code null} if it cannot be found */ + @CheckForNull public UpdateSite getSite(String id) { return getById(id); } @@ -288,7 +561,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * Gets {@link UpdateSite} by its ID. * Used to bind them to URL. + * @param id ID of the update site to be retrieved + * @return Discovered {@link UpdateSite}. {@code null} if it cannot be found */ + @CheckForNull public UpdateSite getById(String id) { for (UpdateSite s : sites) { if (s.getId().equals(id)) { @@ -302,8 +578,9 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * Gets the {@link UpdateSite} from which we receive updates for jenkins.war. * * @return - * null if no such update center is provided. + * {@code null} if no such update center is provided. */ + @CheckForNull public UpdateSite getCoreSource() { for (UpdateSite s : sites) { Data data = s.getData(); @@ -327,6 +604,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * Gets the plugin with the given name from the first {@link UpdateSite} to contain it. + * @return Discovered {@link Plugin}. {@code null} if it cannot be found */ public @CheckForNull Plugin getPlugin(String artifactId) { for (UpdateSite s : sites) { @@ -381,7 +659,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } response.sendRedirect2("."); } - + /** * Cancel all scheduled jenkins restarts */ @@ -474,14 +752,11 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas */ public String getBackupVersion() { try { - JarFile backupWar = new JarFile(new File(Lifecycle.get().getHudsonWar() + ".bak")); - try { + try (JarFile backupWar = new JarFile(new File(Lifecycle.get().getHudsonWar() + ".bak"))) { Attributes attrs = backupWar.getManifest().getMainAttributes(); String v = attrs.getValue("Jenkins-Version"); - if (v==null) v = attrs.getValue("Hudson-Version"); + if (v == null) v = attrs.getValue("Hudson-Version"); return v; - } finally { - backupWar.close(); } } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to read backup version ", e); @@ -490,12 +765,60 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } /*package*/ synchronized Future addJob(UpdateCenterJob job) { - // the first job is always the connectivity check - if (sourcesUsed.add(job.site)) - new ConnectionCheckJob(job.site).submit(); + addConnectionCheckJob(job.site); return job.submit(); } + private @Nonnull ConnectionCheckJob addConnectionCheckJob(@Nonnull UpdateSite site) { + // Create a connection check job if the site was not already in the sourcesUsed set i.e. the first + // job (in the jobs list) relating to a site must be the connection check job. + if (sourcesUsed.add(site)) { + ConnectionCheckJob connectionCheckJob = newConnectionCheckJob(site); + connectionCheckJob.submit(); + return connectionCheckJob; + } else { + // Find the existing connection check job for that site and return it. + ConnectionCheckJob connectionCheckJob = getConnectionCheckJob(site); + if (connectionCheckJob != null) { + return connectionCheckJob; + } else { + throw new IllegalStateException("Illegal addition of an UpdateCenter job without calling UpdateCenter.addJob. " + + "No ConnectionCheckJob found for the site."); + } + } + } + + /** + * Create a {@link ConnectionCheckJob} for the specified update site. + *

+ * Does not start/submit the job. + * @param site The site for which the Job is to be created. + * @return A {@link ConnectionCheckJob} for the specified update site. + */ + @Restricted(NoExternalUse.class) + ConnectionCheckJob newConnectionCheckJob(UpdateSite site) { + return new ConnectionCheckJob(site); + } + + private @CheckForNull ConnectionCheckJob getConnectionCheckJob(@Nonnull String siteId) { + UpdateSite site = getSite(siteId); + if (site == null) { + return null; + } + return getConnectionCheckJob(site); + } + + private @CheckForNull ConnectionCheckJob getConnectionCheckJob(@Nonnull UpdateSite site) { + synchronized (jobs) { + for (UpdateCenterJob job : jobs) { + if (job instanceof ConnectionCheckJob && job.site.getId().equals(site.getId())) { + return (ConnectionCheckJob) job; + } + } + } + return null; + } + public String getDisplayName() { return "Update center"; } @@ -521,7 +844,6 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * Loads the data from the disk into this object. */ public synchronized void load() throws IOException { - UpdateSite defaultSite = new UpdateSite(ID_DEFAULT, config.getUpdateCenterUrl() + "update-center.json"); XmlFile file = getConfigFile(); if(file.exists()) { try { @@ -529,28 +851,37 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } catch (IOException e) { LOGGER.log(Level.WARNING, "Failed to load "+file, e); } + boolean defaultSiteExists = false; for (UpdateSite site : sites) { // replace the legacy site with the new site if (site.isLegacyDefault()) { sites.remove(site); - sites.add(defaultSite); - break; + } else if (ID_DEFAULT.equals(site.getId())) { + defaultSiteExists = true; } } + if (!defaultSiteExists) { + sites.add(createDefaultUpdateSite()); + } } else { if (sites.isEmpty()) { // If there aren't already any UpdateSources, add the default one. // to maintain compatibility with existing UpdateCenterConfiguration, create the default one as specified by UpdateCenterConfiguration - sites.add(defaultSite); + sites.add(createDefaultUpdateSite()); } } } + protected UpdateSite createDefaultUpdateSite() { + return new UpdateSite(PREDEFINED_UPDATE_SITE_ID, config.getUpdateCenterUrl() + "update-center.json"); + } + private XmlFile getConfigFile() { return new XmlFile(XSTREAM,new File(Jenkins.getInstance().root, UpdateCenter.class.getName()+".xml")); } + @Exported public List getAvailables() { Map pluginMap = new LinkedHashMap(); for (UpdateSite site : sites) { @@ -619,16 +950,16 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas return new ArrayList(pluginMap.values()); } - + /** * Ensure that all UpdateSites are up to date, without requiring a user to * browse to the instance. - * + * * @return a list of {@link FormValidation} for each updated Update Site - * @throws ExecutionException - * @throws InterruptedException + * @throws ExecutionException + * @throws InterruptedException * @since 1.501 - * + * */ public List updateAllSites() throws InterruptedException, ExecutionException { List > futures = new ArrayList>(); @@ -638,8 +969,8 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas futures.add(future); } } - - List results = new ArrayList(); + + List results = new ArrayList(); for (Future f : futures) { results.add(f.get()); } @@ -650,8 +981,14 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas /** * {@link AdministrativeMonitor} that checks if there's Jenkins update. */ - @Extension + @Extension @Symbol("coreUpdate") public static final class CoreUpdateMonitor extends AdministrativeMonitor { + + @Override + public String getDisplayName() { + return Messages.UpdateCenter_CoreUpdateMonitor_DisplayName(); + } + public boolean isActivated() { Data data = getData(); return data!=null && data.hasCoreUpdates(); @@ -708,7 +1045,23 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * @throws IOException if a connection to the update center server can't be established. */ public void checkUpdateCenter(ConnectionCheckJob job, String updateCenterUrl) throws IOException { - testConnection(new URL(updateCenterUrl + "?uctest")); + testConnection(toUpdateCenterCheckUrl(updateCenterUrl)); + } + + /** + * Converts an update center URL into the URL to use for checking its connectivity. + * @param updateCenterUrl the URL to convert. + * @return the converted URL. + * @throws MalformedURLException if the supplied URL is malformed. + */ + static URL toUpdateCenterCheckUrl(String updateCenterUrl) throws MalformedURLException { + URL url; + if (updateCenterUrl.startsWith("http://") || updateCenterUrl.startsWith("https://")) { + url = new URL(updateCenterUrl + (updateCenterUrl.indexOf('?') == -1 ? "?uctest" : "&uctest")); + } else { + url = new URL(updateCenterUrl); + } + return url; } /** @@ -748,11 +1101,25 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * @see DownloadJob */ public File download(DownloadJob job, URL src) throws IOException { + MessageDigest sha1 = null; + try { + sha1 = MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException ignored) { + // Irrelevant as the Java spec says SHA-1 must exist. Still, if this fails + // the DownloadJob will just have computedSha1 = null and that is expected + // to be handled by caller + } + CountingInputStream in = null; OutputStream out = null; URLConnection con = null; try { con = connect(job,src); + //JENKINS-34174 - set timeout for downloads, may hang indefinitely + // particularly noticeable during 2.0 install when downloading + // many plugins + con.setReadTimeout(PLUGIN_DOWNLOAD_READ_TIMEOUT); + int total = con.getContentLength(); in = new CountingInputStream(con.getInputStream()); byte[] buf = new byte[8192]; @@ -761,6 +1128,9 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas File dst = job.getDestination(); File tmp = new File(dst.getPath()+".tmp"); out = new FileOutputStream(tmp); + if (sha1 != null) { + out = new DigestOutputStream(out, sha1); + } LOGGER.info("Downloading "+job.getName()); Thread t = Thread.currentThread(); @@ -774,6 +1144,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } catch (IOException e) { throw new IOException("Failed to load "+src+" to "+tmp,e); } finally { + IOUtils.closeQuietly(out); t.setName(oldName); } @@ -784,6 +1155,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas throw new IOException("Inconsistent file length: expected "+total+" but only got "+tmp.length()); } + if (sha1 != null) { + byte[] digest = sha1.digest(); + job.computedSHA1 = Base64.encodeBase64String(digest); + } return tmp; } catch (IOException e) { // assist troubleshooting in case of e.g. "too many redirects" by printing actual URL @@ -878,7 +1253,16 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas private void testConnection(URL url) throws IOException { try { - Util.copyStreamAndClose(ProxyConfiguration.open(url).getInputStream(),new NullOutputStream()); + URLConnection connection = (URLConnection) ProxyConfiguration.open(url); + + if(connection instanceof HttpURLConnection) { + int responseCode = ((HttpURLConnection)connection).getResponseCode(); + if(HttpURLConnection.HTTP_OK != responseCode) { + throw new HttpRetryException("Invalid response code (" + responseCode + ") from URL: " + url, responseCode); + } + } else { + Util.copyStreamAndClose(connection.getInputStream(),new NullOutputStream()); + } } catch (SSLHandshakeException e) { if (e.getMessage().contains("PKIX path building failed")) // fix up this crappy error message from JDK @@ -907,6 +1291,12 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas */ public final UpdateSite site; + /** + * Simple correlation ID that can be used to associated a batch of jobs e.g. the + * installation of a set of plugins. + */ + private UUID correlationId = null; + /** * If this job fails, set to the error. */ @@ -920,6 +1310,17 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas return new Api(this); } + public UUID getCorrelationId() { + return correlationId; + } + + public void setCorrelationId(UUID correlationId) { + if (this.correlationId != null) { + throw new IllegalStateException("Illegal call to set the 'correlationId'. Already set."); + } + this.correlationId = correlationId; + } + /** * @deprecated as of 1.326 * Use {@link #submit()} instead. @@ -941,6 +1342,8 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas */ public Future submit() { LOGGER.fine("Scheduling "+this+" to installerService"); + // TODO: seems like this access to jobs should be synchronized, no? + // It might get synch'd accidentally via the addJob method, but that wouldn't be good. jobs.add(this); return installerService.submit(this,this); } @@ -949,7 +1352,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas public String getErrorMessage() { return error != null ? error.getMessage() : null; } - + public Throwable getError() { return error; } @@ -964,10 +1367,15 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas */ @Exported(inline=true) public volatile RestartJenkinsJobStatus status = new Pending(); - + + /** + * The name of the user that started this job + */ + private String authentication; + /** * Cancel job - */ + */ public synchronized boolean cancel() { if (status instanceof Pending) { status = new Canceled(); @@ -975,9 +1383,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } return false; } - + public RestartJenkinsJob(UpdateSite site) { super(site); + this.authentication = Jenkins.getAuthentication().getName(); } public synchronized void run() { @@ -986,7 +1395,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } status = new Running(); try { - Jenkins.getInstance().safeRestart(); + // safeRestart records the current authentication for the log, so set it to the managing user + try (ACLContext _ = ACL.as(User.get(authentication, false, Collections.emptyMap()))) { + Jenkins.getInstance().safeRestart(); + } } catch (RestartNotSupportedException exception) { // ignore if restart is not allowed status = new Failure(); @@ -998,26 +1410,26 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas public abstract class RestartJenkinsJobStatus { @Exported public final int id = iota.incrementAndGet(); - + } - + public class Pending extends RestartJenkinsJobStatus { @Exported public String getType() { return getClass().getSimpleName(); } } - + public class Running extends RestartJenkinsJobStatus { - + } - + public class Failure extends RestartJenkinsJobStatus { - + } - + public class Canceled extends RestartJenkinsJobStatus { - + } } @@ -1027,42 +1439,76 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas public final class ConnectionCheckJob extends UpdateCenterJob { private final Vector statuses= new Vector(); + final Map connectionStates = new ConcurrentHashMap<>(); + public ConnectionCheckJob(UpdateSite site) { super(site); + connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.PRECHECK); + connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.PRECHECK); } public void run() { + connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.UNCHECKED); + connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.UNCHECKED); if (ID_UPLOAD.equals(site.getId())) { return; } LOGGER.fine("Doing a connectivity check"); + Future internetCheck = null; try { - String connectionCheckUrl = site.getConnectionCheckUrl(); + final String connectionCheckUrl = site.getConnectionCheckUrl(); if (connectionCheckUrl!=null) { + connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.CHECKING); statuses.add(Messages.UpdateCenter_Status_CheckingInternet()); - try { - config.checkConnection(this, connectionCheckUrl); - } catch (IOException e) { - if(e.getMessage().contains("Connection timed out")) { - // Google can't be down, so this is probably a proxy issue - statuses.add(Messages.UpdateCenter_Status_ConnectionFailed(connectionCheckUrl)); - return; + // Run the internet check in parallel + internetCheck = updateService.submit(new Runnable() { + @Override + public void run() { + try { + config.checkConnection(ConnectionCheckJob.this, connectionCheckUrl); + } catch (Exception e) { + if(e.getMessage().contains("Connection timed out")) { + // Google can't be down, so this is probably a proxy issue + connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.FAILED); + statuses.add(Messages.UpdateCenter_Status_ConnectionFailed(connectionCheckUrl)); + return; + } + } + connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.OK); } - } + }); + } else { + LOGGER.log(WARNING, "Update site ''{0}'' does not declare the connection check URL. " + + "Skipping the network availability check.", site.getId()); + connectionStates.put(ConnectionStatus.INTERNET, ConnectionStatus.SKIPPED); } + connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.CHECKING); statuses.add(Messages.UpdateCenter_Status_CheckingJavaNet()); + config.checkUpdateCenter(this, site.getUrl()); + connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.OK); statuses.add(Messages.UpdateCenter_Status_Success()); } catch (UnknownHostException e) { + connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.FAILED); statuses.add(Messages.UpdateCenter_Status_UnknownHostException(e.getMessage())); addStatus(e); error = e; - } catch (IOException e) { + } catch (Exception e) { + connectionStates.put(ConnectionStatus.UPDATE_SITE, ConnectionStatus.FAILED); statuses.add(Functions.printThrowable(e)); error = e; } + + if(internetCheck != null) { + try { + // Wait for internet check to complete + internetCheck.get(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Error completing internet connectivity check: " + e.getMessage(), e); + } + } } private void addStatus(UnknownHostException e) { @@ -1074,8 +1520,77 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas return statuses.toArray(new String[statuses.size()]); } } - } + + } + + /** + * Enables a required plugin, provides feedback in the update center + */ + public class EnableJob extends InstallationJob { + public EnableJob(UpdateSite site, Authentication auth, @Nonnull Plugin plugin, boolean dynamicLoad) { + super(plugin, site, auth, dynamicLoad); + } + + public Plugin getPlugin() { + return plugin; + } + + @Override + public void run() { + try { + PluginWrapper installed = plugin.getInstalled(); + synchronized(installed) { + if (!installed.isEnabled()) { + try { + installed.enable(); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to enable " + plugin.getDisplayName(), e); + error = e; + status = new Failure(e); + } + + if (dynamicLoad) { + try { + // remove the existing, disabled inactive plugin to force a new one to load + pm.dynamicLoad(getDestination(), true); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Failed to dynamically load " + plugin.getDisplayName(), e); + error = e; + requiresRestart = true; + status = new Failure(e); + } + } else { + requiresRestart = true; + } + } + } + } catch(Throwable e) { + LOGGER.log(Level.SEVERE, "An unexpected error occurred while attempting to enable " + plugin.getDisplayName(), e); + error = e; + requiresRestart = true; + status = new Failure(e); + } + if(status instanceof Pending) { + status = new Success(); + } + } + } + + /** + * A no-op, e.g. this plugin is already installed + */ + public class NoOpJob extends EnableJob { + public NoOpJob(UpdateSite site, Authentication auth, @Nonnull Plugin plugin) { + super(site, auth, plugin, false); + } + @Override + public void run() { + // do nothing + status = new Success(); + } + } + /** * Base class for a job that downloads a file from the Jenkins project. */ @@ -1104,6 +1619,17 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas */ protected abstract void onSuccess(); + /** + * During download, an attempt is made to compute the SHA-1 checksum of the file. + * + * @since 1.641 + */ + @CheckForNull + protected String getComputedSHA1() { + return computedSHA1; + } + + private String computedSHA1; private Authentication authentication; @@ -1132,6 +1658,10 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas status = e; if (status.isSuccess()) onSuccess(); requiresRestart |= status.requiresRestart(); + } catch (MissingDependencyException e) { + LOGGER.log(Level.SEVERE, "Failed to install {0}: {1}", new Object[] { getName(), e.getMessage() }); + status = new Failure(e); + error = e; } catch (Throwable e) { LOGGER.log(Level.SEVERE, "Failed to install "+getName(),e); status = new Failure(e); @@ -1234,6 +1764,15 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } } + /** + * Indicates that the plugin was successfully installed. + */ + public class Skipped extends InstallationStatus { + @Override public boolean isSuccess() { + return true; + } + } + /** * Indicates that the plugin is waiting for its turn for installation. */ @@ -1255,22 +1794,42 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas } } + /** + * If expectedSHA1 is non-null, ensure that actualSha1 is the same value, otherwise throw. + * + * Utility method for InstallationJob and HudsonUpgradeJob. + * + * @throws IOException when checksums don't match, or actual checksum was null. + */ + private void verifyChecksums(String expectedSHA1, String actualSha1, File downloadedFile) throws IOException { + if (expectedSHA1 != null) { + if (actualSha1 == null) { + // refuse to install if SHA-1 could not be computed + throw new IOException("Failed to compute SHA-1 of downloaded file, refusing installation"); + } + if (!expectedSHA1.equals(actualSha1)) { + throw new IOException("Downloaded file " + downloadedFile.getAbsolutePath() + " does not match expected SHA-1, expected '" + expectedSHA1 + "', actual '" + actualSha1 + "'"); + // keep 'downloadedFile' around for investigating what's going on + } + } + } + /** * Represents the state of the installation activity of one plugin. */ - public final class InstallationJob extends DownloadJob { + public class InstallationJob extends DownloadJob { /** * What plugin are we trying to install? */ @Exported public final Plugin plugin; - private final PluginManager pm = Jenkins.getInstance().getPluginManager(); + protected final PluginManager pm = Jenkins.getInstance().getPluginManager(); /** * True to load the plugin into this Jenkins, false to wait until restart. */ - private final boolean dynamicLoad; + protected final boolean dynamicLoad; /** * @deprecated as of 1.442 @@ -1294,7 +1853,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas File baseDir = pm.rootDir; return new File(baseDir, plugin.name + ".jpi"); } - + private File getLegacyDestination() { File baseDir = pm.rootDir; return new File(baseDir, plugin.name + ".hpi"); @@ -1306,29 +1865,81 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas @Override public void _run() throws IOException, InstallationStatus { - super._run(); + if (wasInstalled()) { + // Do this first so we can avoid duplicate downloads, too + // check to see if the plugin is already installed at the same version and skip it + LOGGER.info("Skipping duplicate install of: " + plugin.getDisplayName() + "@" + plugin.version); + //throw new Skipped(); // TODO set skipped once we have a status indicator for it + return; + } + try { + super._run(); - // if this is a bundled plugin, make sure it won't get overwritten - PluginWrapper pw = plugin.getInstalled(); - if (pw!=null && pw.isBundled()) { - SecurityContext oldContext = ACL.impersonate(ACL.SYSTEM); - try { - pw.doPin(); - } finally { - SecurityContextHolder.setContext(oldContext); + // if this is a bundled plugin, make sure it won't get overwritten + PluginWrapper pw = plugin.getInstalled(); + if (pw!=null && pw.isBundled()) { + SecurityContext oldContext = ACL.impersonate(ACL.SYSTEM); + try { + pw.doPin(); + } finally { + SecurityContextHolder.setContext(oldContext); + } + } + + if (dynamicLoad) { + try { + pm.dynamicLoad(getDestination()); + } catch (RestartRequiredException e) { + throw new SuccessButRequiresRestart(e.message); + } catch (Exception e) { + throw new IOException("Failed to dynamically deploy this plugin",e); + } + } else { + throw new SuccessButRequiresRestart(Messages._UpdateCenter_DownloadButNotActivated()); + } + } finally { + synchronized(this) { + // There may be other threads waiting on completion + LOGGER.fine("Install complete for: " + plugin.getDisplayName() + "@" + plugin.version); + // some status other than Installing or Downloading needs to be set here + // {@link #isAlreadyInstalling()}, it will be overwritten by {@link DownloadJob#run()} + status = new Skipped(); + notifyAll(); } } + } - if (dynamicLoad) { - try { - pm.dynamicLoad(getDestination()); - } catch (RestartRequiredException e) { - throw new SuccessButRequiresRestart(e.message); - } catch (Exception e) { - throw new IOException("Failed to dynamically deploy this plugin",e); + /** + * Indicates there is another installation job for this plugin + * @since 2.1 + */ + protected boolean wasInstalled() { + synchronized(UpdateCenter.this) { + for (UpdateCenterJob job : getJobs()) { + if (job == this) { + // oldest entries first, if we reach this instance, + // we need it to continue installing + return false; + } + if (job instanceof InstallationJob) { + InstallationJob ij = (InstallationJob)job; + if (ij.plugin.equals(plugin) && ij.plugin.version.equals(plugin.version)) { + // wait until other install is completed + synchronized(ij) { + if(ij.status instanceof Installing || ij.status instanceof Pending) { + try { + LOGGER.fine("Waiting for other plugin install of: " + plugin.getDisplayName() + "@" + plugin.version); + ij.wait(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + return true; + } + } } - } else { - throw new SuccessButRequiresRestart(Messages._UpdateCenter_DownloadButNotActivated()); + return false; } } @@ -1340,25 +1951,31 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas public String toString() { return super.toString()+"[plugin="+plugin.title+"]"; } - + /** * Called when the download is completed to overwrite * the old file with the new file. */ @Override protected void replace(File dst, File src) throws IOException { - File bak = Util.changeExtension(dst,".bak"); - + + verifyChecksums(plugin.getSha1(), getComputedSHA1(), src); + + File bak = Util.changeExtension(dst, ".bak"); bak.delete(); + final File legacy = getLegacyDestination(); - if(legacy.exists()){ - legacy.renameTo(bak); - }else{ - dst.renameTo(bak); + if (legacy.exists()) { + if (!legacy.renameTo(bak)) { + legacy.delete(); + } } - legacy.delete(); - dst.delete(); // any failure up to here is no big deal - + if (dst.exists()) { + if (!dst.renameTo(bak)) { + dst.delete(); + } + } + if(!src.renameTo(dst)) { throw new IOException("Failed to rename "+src+" to "+dst); } @@ -1389,7 +2006,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas File baseDir = pm.rootDir; final File legacy = new File(baseDir, plugin.name + ".hpi"); if(legacy.exists()){ - return legacy; + return legacy; } return new File(baseDir, plugin.name + ".jpi"); } @@ -1476,6 +2093,8 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas @Override protected void replace(File dst, File src) throws IOException { + String expectedSHA1 = site.getData().core.getSha1(); + verifyChecksums(expectedSHA1, getComputedSHA1(), src); Lifecycle.get().rewriteHudsonWar(src); } } @@ -1560,6 +2179,24 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas h.getUpdateCenter().load(); } + @Restricted(NoExternalUse.class) + public static void updateDefaultSite() { + final UpdateSite site = Jenkins.getInstance().getUpdateCenter().getSite(UpdateCenter.ID_DEFAULT); + if (site == null) { + LOGGER.log(Level.SEVERE, "Upgrading Jenkins. Cannot retrieve the default Update Site ''{0}''. " + + "Plugin installation may fail.", UpdateCenter.ID_DEFAULT); + return; + } + try { + // Need to do the following because the plugin manager will attempt to access + // $JENKINS_HOME/updates/$ID_DEFAULT.json. Needs to be up to date. + site.updateDirectlyNow(true); + } catch (Exception e) { + LOGGER.log(WARNING, "Upgrading Jenkins. Failed to update the default Update Site '" + UpdateCenter.ID_DEFAULT + + "'. Plugin upgrades may fail.", e); + } + } + /** * Sequence number generator. */ @@ -1572,7 +2209,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas * Use {@link UpdateSite#neverUpdate} */ @Deprecated - public static boolean neverUpdate = Boolean.getBoolean(UpdateCenter.class.getName()+".never"); + public static boolean neverUpdate = SystemProperties.getBoolean(UpdateCenter.class.getName()+".never"); public static final XStream2 XSTREAM = new XStream2(); diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java index 9fc1caaf46c28925b095759ecabb6267813bd2cd..01bf9c6ddb7976c41092b9e43ad75ddfa205db31 100644 --- a/core/src/main/java/hudson/model/UpdateSite.java +++ b/core/src/main/java/hudson/model/UpdateSite.java @@ -25,8 +25,10 @@ package hudson.model; +import hudson.ClassicPluginStrategy; import hudson.PluginManager; import hudson.PluginWrapper; +import hudson.Util; import hudson.lifecycle.Lifecycle; import hudson.model.UpdateCenter.UpdateCenterJob; import hudson.util.FormValidation; @@ -48,6 +50,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.Future; import java.util.logging.Level; @@ -57,6 +60,7 @@ import javax.annotation.Nonnull; import jenkins.model.Jenkins; import jenkins.model.DownloadSettings; import jenkins.util.JSONSignatureValidator; +import jenkins.util.SystemProperties; import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.apache.commons.io.IOUtils; @@ -126,6 +130,12 @@ public class UpdateSite { */ private final String url; + /** + * the prefix for the signature validator name + */ + private static final String signatureValidatorPrefix = "update site"; + + public UpdateSite(String id, String url) { this.id = id; this.url = url; @@ -212,6 +222,20 @@ public class UpdateSite { return verifySignature(getJSONObject()); } + /** + * Extension point to allow implementations of {@link UpdateSite} to create a custom + * {@link UpdateCenter.InstallationJob}. + * + * @param plugin the plugin to create the {@link UpdateCenter.InstallationJob} for. + * @param uc the {@link UpdateCenter}. + * @param dynamicLoad {@code true} if the plugin should be attempted to be dynamically loaded. + * @return the {@link UpdateCenter.InstallationJob}. + * @since 2.9 + */ + protected UpdateCenter.InstallationJob createInstallationJob(Plugin plugin, UpdateCenter uc, boolean dynamicLoad) { + return uc.new InstallationJob(plugin, this, Jenkins.getAuthentication(), dynamicLoad); + } + /** * Verifies the signature in the update center data file. */ @@ -222,10 +246,28 @@ public class UpdateSite { /** * Let sub-classes of UpdateSite provide their own signature validator. * @return the signature validator. + * @deprecated use {@link #getJsonSignatureValidator(@CheckForNull String)} instead. */ + @Deprecated @Nonnull protected JSONSignatureValidator getJsonSignatureValidator() { - return new JSONSignatureValidator("update site '"+id+"'"); + return getJsonSignatureValidator(null); + } + + /** + * Let sub-classes of UpdateSite provide their own signature validator. + * @param name, the name for the JSON signature Validator object. + * if name is null, then the default name will be used, + * which is "update site" followed by the update site id + * @return the signature validator. + * @since 2.21 + */ + @Nonnull + protected JSONSignatureValidator getJsonSignatureValidator(@CheckForNull String name) { + if (name == null) { + name = signatureValidatorPrefix + " '" + id + "'"; + } + return new JSONSignatureValidator(name); } /** @@ -336,9 +378,11 @@ public class UpdateSite { } /** - * Returns an "always up" server for Internet connectivity testing, or null if we are going to skip the test. + * Gets a URL for the Internet connection check. + * @return an "always up" server for Internet connectivity testing, or {@code null} if we are going to skip the test. */ @Exported + @CheckForNull public String getConnectionCheckUrl() { Data dt = getData(); if(dt==null) return "http://www.google.com/"; @@ -400,6 +444,28 @@ public class UpdateSite { return url; } + + /** + * URL which exposes the metadata location in a specific update site. + * @param downloadable, the downloadable id of a specific metatadata json (e.g. hudson.tasks.Maven.MavenInstaller.json) + * @return the location + * @since 2.20 + */ + @CheckForNull + @Restricted(NoExternalUse.class) + public String getMetadataUrlForDownloadable(String downloadable) { + String siteUrl = getUrl(); + String updateSiteMetadataUrl = null; + int baseUrlEnd = siteUrl.indexOf("update-center.json"); + if (baseUrlEnd != -1) { + String siteBaseUrl = siteUrl.substring(0, baseUrlEnd); + updateSiteMetadataUrl = siteBaseUrl + "updates/" + downloadable; + } else { + LOGGER.log(Level.WARNING, "Url {0} does not look like an update center:", siteUrl); + } + return updateSiteMetadataUrl; + } + /** * Where to actually download the update center? * @@ -427,7 +493,7 @@ public class UpdateSite { * Is this the legacy default update center site? */ public boolean isLegacyDefault() { - return id.equals(UpdateCenter.ID_DEFAULT) && url.startsWith("http://hudson-ci.org/") || url.startsWith("http://updates.hudson-labs.org/"); + return id.equals(UpdateCenter.PREDEFINED_UPDATE_SITE_ID) && url.startsWith("http://hudson-ci.org/") || url.startsWith("http://updates.hudson-labs.org/"); } /** @@ -463,7 +529,17 @@ public class UpdateSite { core = null; } for(Map.Entry e : (Set>)o.getJSONObject("plugins").entrySet()) { - plugins.put(e.getKey(),new Plugin(sourceId, e.getValue())); + Plugin p = new Plugin(sourceId, e.getValue()); + // JENKINS-33308 - include implied dependencies for older plugins that may need them + List implicitDeps = ClassicPluginStrategy.getImpliedDependencies(p.name, p.requiredCore); + if(!implicitDeps.isEmpty()) { + for(PluginWrapper.Dependency dep : implicitDeps) { + if(!p.dependencies.containsKey(dep.shortName)) { + p.dependencies.put(dep.shortName, dep.version); + } + } + } + plugins.put(e.getKey(), p); } connectionCheckUrl = (String)o.get("connectionCheckUrl"); @@ -508,6 +584,11 @@ public class UpdateSite { @Exported public final String url; + + // non-private, non-final for test + @Restricted(NoExternalUse.class) + /* final */ String sha1; + public Entry(String sourceId, JSONObject o) { this(sourceId, o, null); } @@ -516,6 +597,11 @@ public class UpdateSite { this.sourceId = sourceId; this.name = o.getString("name"); this.version = o.getString("version"); + + // Trim this to prevent issues when the other end used Base64.encodeBase64String that added newlines + // to the end in old commons-codec. Not the case on updates.jenkins-ci.org, but let's be safe. + this.sha1 = Util.fixEmptyAndTrim(o.optString("sha1")); + String url = o.getString("url"); if (!URI.create(url).isAbsolute()) { if (baseURL == null) { @@ -526,6 +612,16 @@ public class UpdateSite { this.url = url; } + /** + * The base64 encoded binary SHA-1 checksum of the file. + * Can be null if not provided by the update site. + * @since 1.641 (and 1.625.3 LTS) + */ + // TODO @Exported assuming we want this in the API + public String getSha1() { + return sha1; + } + /** * Checks if the specified "current version" is older than the version of this entry. * @@ -588,7 +684,7 @@ public class UpdateSite { public final String[] categories; /** - * Dependencies of this plugin. + * Dependencies of this plugin, a name -> version mapping. */ @Exported public final Map dependencies = new HashMap(); @@ -610,10 +706,8 @@ public class UpdateSite { this.categories = o.has("labels") ? (String[])o.getJSONArray("labels").toArray(new String[0]) : null; for(Object jo : o.getJSONArray("dependencies")) { JSONObject depObj = (JSONObject) jo; - // Make sure there's a name attribute, that that name isn't maven-plugin - we ignore that one - - // and that the optional value isn't true. - if (get(depObj,"name")!=null - && !get(depObj,"name").equals("maven-plugin")) { + // Make sure there's a name attribute and that the optional value isn't true. + if (get(depObj,"name")!=null) { if (get(depObj, "optional").equals("false")) { dependencies.put(get(depObj, "name"), get(depObj, "version")); } else { @@ -698,6 +792,10 @@ public class UpdateSite { else if (current.isOlderThan(requiredVersion)) { deps.add(depPlugin); } + // JENKINS-34494 - or if the plugin is disabled, this will allow us to enable it + else if (!current.isEnabled()) { + deps.add(depPlugin); + } } for(Map.Entry e : optionalDependencies.entrySet()) { @@ -791,18 +889,50 @@ public class UpdateSite { * See {@link UpdateCenter#isRestartRequiredForCompletion()} */ public Future deploy(boolean dynamicLoad) { + return deploy(dynamicLoad, null); + } + + /** + * Schedules the installation of this plugin. + * + *

+ * This is mainly intended to be called from the UI. The actual installation work happens + * asynchronously in another thread. + * + * @param dynamicLoad + * If true, the plugin will be dynamically loaded into this Jenkins. If false, + * the plugin will only take effect after the reboot. + * See {@link UpdateCenter#isRestartRequiredForCompletion()} + * @param correlationId A correlation ID to be set on the job. + */ + @Restricted(NoExternalUse.class) + public Future deploy(boolean dynamicLoad, @CheckForNull UUID correlationId) { Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); UpdateCenter uc = Jenkins.getInstance().getUpdateCenter(); for (Plugin dep : getNeededDependencies()) { UpdateCenter.InstallationJob job = uc.getJob(dep); if (job == null || job.status instanceof UpdateCenter.DownloadJob.Failure) { - LOGGER.log(Level.WARNING, "Adding dependent install of " + dep.name + " for plugin " + name); + LOGGER.log(Level.INFO, "Adding dependent install of " + dep.name + " for plugin " + name); dep.deploy(dynamicLoad); } else { - LOGGER.log(Level.WARNING, "Dependent install of " + dep.name + " for plugin " + name + " already added, skipping"); + LOGGER.log(Level.INFO, "Dependent install of " + dep.name + " for plugin " + name + " already added, skipping"); + } + } + PluginWrapper pw = getInstalled(); + if(pw != null) { // JENKINS-34494 - check for this plugin being disabled + Future enableJob = null; + if(!pw.isEnabled()) { + UpdateCenter.EnableJob job = uc.new EnableJob(UpdateSite.this, null, this, dynamicLoad); + job.setCorrelationId(correlationId); + enableJob = uc.addJob(job); + } + if(pw.getVersionNumber().equals(new VersionNumber(version))) { + return enableJob != null ? enableJob : uc.addJob(uc.new NoOpJob(UpdateSite.this, null, this)); } } - return uc.addJob(uc.new InstallationJob(this, UpdateSite.this, Jenkins.getAuthentication(), dynamicLoad)); + UpdateCenter.InstallationJob job = createInstallationJob(this, uc, dynamicLoad); + job.setCorrelationId(correlationId); + return uc.addJob(job); } /** @@ -843,6 +973,6 @@ public class UpdateSite { private static final Logger LOGGER = Logger.getLogger(UpdateSite.class.getName()); // The name uses UpdateCenter for compatibility reason. - public static boolean neverUpdate = Boolean.getBoolean(UpdateCenter.class.getName()+".never"); + public static boolean neverUpdate = SystemProperties.getBoolean(UpdateCenter.class.getName()+".never"); } diff --git a/core/src/main/java/hudson/model/UsageStatistics.java b/core/src/main/java/hudson/model/UsageStatistics.java index 805403216b0aad6aaea35fe30e37972772a20a47..4f46b292d4d36630287fb3a5f8cdb3a462113757 100644 --- a/core/src/main/java/hudson/model/UsageStatistics.java +++ b/core/src/main/java/hudson/model/UsageStatistics.java @@ -61,6 +61,7 @@ import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.List; import com.jcraft.jzlib.GZIPOutputStream; +import jenkins.util.SystemProperties; /** * @author Kohsuke Kawaguchi @@ -197,10 +198,10 @@ public class UsageStatistics extends PageDecorator { } /** - * Assymetric cipher is slow and in case of Sun RSA implementation it can only encyrypt the first block. + * Asymmetric cipher is slow and in case of Sun RSA implementation it can only encyrypt the first block. * * So first create a symmetric key, then place this key in the beginning of the stream by encrypting it - * with the assymetric cipher. The rest of the stream will be encrypted by a symmetric cipher. + * with the asymmetric cipher. The rest of the stream will be encrypted by a symmetric cipher. */ public static final class CombinedCipherOutputStream extends FilterOutputStream { public CombinedCipherOutputStream(OutputStream out, Cipher asym, String algorithm) throws IOException, GeneralSecurityException { @@ -272,5 +273,5 @@ public class UsageStatistics extends PageDecorator { private static final long DAY = DAYS.toMillis(1); - public static boolean DISABLED = Boolean.getBoolean(UsageStatistics.class.getName()+".disabled"); + public static boolean DISABLED = SystemProperties.getBoolean(UsageStatistics.class.getName()+".disabled"); } diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java index e2a09768f4737aa4c42c0c43677c3b80eb61965f..6ff891f42d18236afa386d6449dd0af225055031 100644 --- a/core/src/main/java/hudson/model/User.java +++ b/core/src/main/java/hudson/model/User.java @@ -24,6 +24,8 @@ */ package hudson.model; +import jenkins.security.UserDetailsCache; +import jenkins.util.SystemProperties; import com.google.common.base.Predicate; import com.infradna.tool.bridge_method_injector.WithBridgeMethods; import hudson.*; @@ -51,7 +53,10 @@ import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.jenkinsci.Symbol; import org.springframework.dao.DataAccessException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; @@ -66,6 +71,7 @@ import java.io.File; import java.io.IOException; import java.io.FileFilter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; @@ -73,9 +79,11 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ExecutionException; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; @@ -83,6 +91,7 @@ import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.apache.commons.lang.StringUtils; /** * Represents a user. @@ -151,9 +160,6 @@ public class User extends AbstractModelObject implements AccessControlled, Descr @Nonnull public static IdStrategy idStrategy() { Jenkins j = Jenkins.getInstance(); - if (j == null) { - return IdStrategy.CASE_INSENSITIVE; - } SecurityRealm realm = j.getSecurityRealm(); if (realm == null) { return IdStrategy.CASE_INSENSITIVE; @@ -342,7 +348,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * This is used to avoid null {@link User} instance. */ public static @Nonnull User getUnknown() { - return get(UKNOWN_USERNAME); + return getById(UKNOWN_USERNAME, true); } /** @@ -442,7 +448,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr new Object[]{ legacyUserDir, o }); } } catch (IOException e) { - LOGGER.log(Level.FINE, String.format("Exception trying to load user from {0}: {1}", + LOGGER.log(Level.FINE, String.format("Exception trying to load user from %s: %s", new Object[]{ legacyUserDir, e.getMessage() }), e); } } @@ -476,6 +482,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr /** * Gets the {@link User} object by its id or full name. + * Use {@link #getById} when you know you have an ID. */ public static @Nonnull User get(String idOrFullName) { return get(idOrFullName,true); @@ -503,7 +510,23 @@ public class User extends AbstractModelObject implements AccessControlled, Descr // Since we already know this is a name, we can just call getOrCreate with the name directly. String id = a.getName(); - return getOrCreate(id, id, true); + return getById(id, true); + } + + /** + * Gets the {@link User} object by its id + * + * @param id + * the id of the user to retrieve and optionally create if it does not exist. + * @param create + * If true, this method will never return null for valid input (by creating a + * new {@link User} object if none exists.) If false, this method will return + * null if {@link User} object with the given id doesn't exist. + * @return the a User whose id is id, or null if create is false + * and the user does not exist. + */ + public static @Nullable User getById(String id, boolean create) { + return getOrCreate(id, id, create); } private static volatile long lastScanned; @@ -559,6 +582,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr } } finally { byNameLock.readLock().unlock(); + UserDetailsCache.get().invalidateAll(); } } @@ -592,6 +616,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr } } finally { byNameLock.writeLock().unlock(); + UserDetailsCache.get().invalidateAll(); } } @@ -683,12 +708,19 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * prevent anyone from logging in as these users. Therefore, we prevent * saving a User with one of these ids. * - * @return true if the username or fullname is valid + * @param id ID to be checked + * @return {@code true} if the username or fullname is valid. + * For {@code null} or blank IDs returns {@code false}. * @since 1.600 */ - public static boolean isIdOrFullnameAllowed(String id) { + public static boolean isIdOrFullnameAllowed(@CheckForNull String id) { + //TODO: StringUtils.isBlank() checks the null falue, but FindBugs is not smart enough. Remove it later + if (id == null || StringUtils.isBlank(id)) { + return false; + } + final String trimmedId = id.trim(); for (String invalidId : ILLEGAL_PERSISTED_USERNAMES) { - if (id.equalsIgnoreCase(invalidId)) + if (trimmedId.equalsIgnoreCase(invalidId)) return false; } return true; @@ -724,6 +756,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr byNameLock.readLock().unlock(); } Util.deleteRecursive(new File(getRootDir(), strategy.filenameOf(id))); + UserDetailsCache.get().invalidate(strategy.keyFor(id)); } /** @@ -741,7 +774,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr checkPermission(Jenkins.ADMINISTER); JSONObject json = req.getSubmittedForm(); - + String oldFullName = this.fullName; fullName = json.getString("fullName"); description = json.getString("description"); @@ -767,6 +800,10 @@ public class User extends AbstractModelObject implements AccessControlled, Descr save(); + if (oldFullName != null && !oldFullName.equals(this.fullName)) { + UserDetailsCache.get().invalidate(oldFullName); + } + FormApply.success(".").generateResponse(req,rsp,this); } @@ -906,11 +943,11 @@ public class User extends AbstractModelObject implements AccessControlled, Descr public Object getDynamic(String token) { for(Action action: getTransientActions()){ - if(action.getUrlName().equals(token)) + if(Objects.equals(action.getUrlName(), token)) return action; } for(Action action: getPropertyActions()){ - if(action.getUrlName().equals(token)) + if(Objects.equals(action.getUrlName(), token)) return action; } return null; @@ -947,6 +984,19 @@ public class User extends AbstractModelObject implements AccessControlled, Descr public ContextMenu doContextMenu(StaplerRequest request, StaplerResponse response) throws Exception { return new ContextMenu().from(this,request,response); } + + /** + * Gets list of Illegal usernames, for which users should not be created. + * Always includes users from {@link #ILLEGAL_PERSISTED_USERNAMES} + * @return List of usernames + */ + @Restricted(NoExternalUse.class) + /*package*/ static Set getIllegalPersistedUsernames() { + // TODO: This method is designed for further extensibility via system properties. To be extended in a follow-up issue + final Set res = new HashSet<>(); + res.addAll(Arrays.asList(ILLEGAL_PERSISTED_USERNAMES)); + return res; + } public static abstract class CanonicalIdResolver extends AbstractDescribableImpl implements ExtensionPoint, Comparable { @@ -980,7 +1030,7 @@ public class User extends AbstractModelObject implements AccessControlled, Descr /** * Resolve user ID from full name */ - @Extension + @Extension @Symbol("fullName") public static class FullNameIdResolver extends CanonicalIdResolver { @Override @@ -997,6 +1047,57 @@ public class User extends AbstractModelObject implements AccessControlled, Descr } } + + /** + * Tries to verify if an ID is valid. + * If so, we do not want to even consider users who might have the same full name. + */ + @Extension + @Restricted(NoExternalUse.class) + public static class UserIDCanonicalIdResolver extends User.CanonicalIdResolver { + + private static /* not final */ boolean SECURITY_243_FULL_DEFENSE = + SystemProperties.getBoolean(User.class.getName() + ".SECURITY_243_FULL_DEFENSE", true); + + private static final ThreadLocal resolving = new ThreadLocal() { + @Override + protected Boolean initialValue() { + return false; + } + }; + + @Override + public String resolveCanonicalId(String idOrFullName, Map context) { + User existing = getById(idOrFullName, false); + if (existing != null) { + return existing.getId(); + } + if (SECURITY_243_FULL_DEFENSE) { + if (!resolving.get()) { + resolving.set(true); + try { + UserDetails userDetails = UserDetailsCache.get().loadUserByUsername(idOrFullName); + return userDetails.getUsername(); + } catch (UsernameNotFoundException x) { + LOGGER.log(Level.FINE, "not sure whether " + idOrFullName + " is a valid username or not", x); + } catch (DataAccessException | ExecutionException x) { + LOGGER.log(Level.FINE, "could not look up " + idOrFullName, x); + } finally { + resolving.set(false); + } + } + } + return null; + } + + @Override + public int getPriority() { + // should always come first so that ID that are ids get mapped correctly + return Integer.MAX_VALUE; + } + + } + /** * Jenkins now refuses to let the user login if he/she doesn't exist in {@link SecurityRealm}, * which was necessary to make sure users removed from the backend will get removed from the frontend. @@ -1006,6 +1107,6 @@ public class User extends AbstractModelObject implements AccessControlled, Descr * * JENKINS-22346. */ - public static boolean ALLOW_NON_EXISTENT_USER_TO_LOGIN = Boolean.getBoolean(User.class.getName()+".allowNonExistentUserToLogin"); + public static boolean ALLOW_NON_EXISTENT_USER_TO_LOGIN = SystemProperties.getBoolean(User.class.getName()+".allowNonExistentUserToLogin"); } diff --git a/core/src/main/java/hudson/model/UserProperty.java b/core/src/main/java/hudson/model/UserProperty.java index 3400bb27eea1d43b5ca35921de91283b4c59fa9b..48198a28ebbe9400139f48735b15067cf33bbfcc 100644 --- a/core/src/main/java/hudson/model/UserProperty.java +++ b/core/src/main/java/hudson/model/UserProperty.java @@ -24,7 +24,6 @@ package hudson.model; import hudson.ExtensionPoint; -import hudson.Plugin; import hudson.DescriptorExtensionList; import hudson.model.Descriptor.FormException; import jenkins.model.Jenkins; @@ -37,7 +36,7 @@ import org.kohsuke.stapler.export.ExportedBean; * Extensible property of {@link User}. * *

- * {@link Plugin}s can extend this to define custom properties + * Plugins can extend this to define custom properties * for {@link User}s. {@link UserProperty}s show up in the user * configuration screen, and they are persisted with the user object. * @@ -59,7 +58,7 @@ public abstract class UserProperty implements ReconfigurableDescribable for rendering, this method returns columns to be displayed. */ public Iterable getColumns() { - return ListViewColumn.createDefaultInitialColumnList(); + return ListViewColumn.createDefaultInitialColumnList(this); } /** @@ -481,6 +494,11 @@ public abstract class View extends AbstractModelObject implements AccessControll return filterQueue(Arrays.asList(Jenkins.getInstance().getQueue().getItems())); } + /** + * @deprecated Use {@link #getQueueItems()}. As of 1.607 the approximation is no longer needed. + * @return The items in the queue. + */ + @Deprecated public List getApproximateQueueItemsQuickly() { return filterQueue(Jenkins.getInstance().getQueue().getApproximateItemsQuickly()); } @@ -540,7 +558,7 @@ public abstract class View extends AbstractModelObject implements AccessControll for (Action a : getActions()) { String url = a.getUrlName(); if (url==null) continue; - if(a.getUrlName().equals(token)) + if (url.equals(token)) return a; } return null; @@ -913,7 +931,7 @@ public abstract class View extends AbstractModelObject implements AccessControll SearchIndexBuilder sib = super.makeSearchIndex(); sib.add(new CollectionSearchIndex() {// for jobs in the view protected TopLevelItem get(String key) { return getItem(key); } - protected Collection all() { return getItems(); } + protected Collection all() { return getItems(); } @Override protected String getName(TopLevelItem o) { // return the name instead of the display for suggestion searching @@ -996,6 +1014,89 @@ public abstract class View extends AbstractModelObject implements AccessControll */ public abstract Item doCreateItem( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException; + /** + * Makes sure that the given name is good as a job name. + * For use from {@code newJob}. + */ + @Restricted(DoNotUse.class) // called from newJob view + public FormValidation doCheckJobName(@QueryParameter String value) { + // this method can be used to check if a file exists anywhere in the file system, + // so it should be protected. + getOwner().checkPermission(Item.CREATE); + + if (Util.fixEmpty(value) == null) { + return FormValidation.ok(); + } + + try { + Jenkins.checkGoodName(value); + value = value.trim(); // why trim *after* checkGoodName? not sure, but ItemGroupMixIn.createTopLevelItem does the same + Jenkins.getInstance().getProjectNamingStrategy().checkName(value); + } catch (Failure e) { + return FormValidation.error(e.getMessage()); + } + + if (getOwnerItemGroup().getItem(value) != null) { + return FormValidation.error(Messages.Hudson_JobAlreadyExists(value)); + } + + // looks good + return FormValidation.ok(); + } + + /** + * An API REST method to get the allowed {$link TopLevelItem}s and its categories. + * + * @return A {@link Categories} entity that is shown as JSON file. + */ + @Restricted(DoNotUse.class) + public Categories doItemCategories(StaplerRequest req, StaplerResponse rsp, @QueryParameter String iconStyle) throws IOException, ServletException { + getOwner().checkPermission(Item.CREATE); + Categories categories = new Categories(); + int order = 0; + JellyContext ctx; + + if (StringUtils.isNotBlank(iconStyle)) { + ctx = new JellyContext(); + ctx.setVariable("resURL", req.getContextPath() + Jenkins.RESOURCE_PATH); + } else { + ctx = null; + } + for (TopLevelItemDescriptor descriptor : DescriptorVisibilityFilter.apply(getOwnerItemGroup(), Items.all(Jenkins.getAuthentication(), getOwnerItemGroup()))) { + ItemCategory ic = ItemCategory.getCategory(descriptor); + Map metadata = new HashMap(); + + // Information about Item. + metadata.put("class", descriptor.getId()); + metadata.put("order", ++order); + metadata.put("displayName", descriptor.getDisplayName()); + metadata.put("description", descriptor.getDescription()); + metadata.put("iconFilePathPattern", descriptor.getIconFilePathPattern()); + String iconClassName = descriptor.getIconClassName(); + if (StringUtils.isNotBlank(iconClassName)) { + metadata.put("iconClassName", iconClassName); + if (ctx != null) { + Icon icon = IconSet.icons + .getIconByClassSpec(StringUtils.join(new String[]{iconClassName, iconStyle}, " ")); + if (icon != null) { + metadata.put("iconQualifiedUrl", icon.getQualifiedUrl(ctx)); + } + } + } + + Category category = categories.getItem(ic.getId()); + if (category != null) { + category.getItems().add(metadata); + } else { + List> temp = new ArrayList>(); + temp.add(metadata); + category = new Category(ic.getId(), ic.getDisplayName(), ic.getDescription(), ic.getOrder(), ic.getMinToShow(), temp); + categories.getItems().add(category); + } + } + return categories; + } + public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException { rss(req, rsp, " all builds", getBuilds()); } @@ -1080,28 +1181,20 @@ public abstract class View extends AbstractModelObject implements AccessControll // data XMLUtils.safeTransform(source, new StreamResult(out)); out.close(); - } catch (TransformerException e) { - throw new IOException("Failed to persist configuration.xml", e); - } catch (SAXException e) { + } catch (TransformerException|SAXException e) { throw new IOException("Failed to persist configuration.xml", e); } // try to reflect the changes by reloading - InputStream in = new BufferedInputStream(new ByteArrayInputStream(out.toString().getBytes("UTF-8"))); - try { + + try (InputStream in = new BufferedInputStream(new ByteArrayInputStream(out.toString().getBytes("UTF-8")))){ // Do not allow overwriting view name as it might collide with another // view in same ViewGroup and might not satisfy Jenkins.checkGoodName. String oldname = name; - Jenkins.XSTREAM.unmarshal(new XppDriver().createReader(in), this); + Jenkins.XSTREAM.unmarshal(new Xpp3Driver().createReader(in), this); name = oldname; - } catch (StreamException e) { - throw new IOException("Unable to read",e); - } catch(ConversionException e) { - throw new IOException("Unable to read",e); - } catch(Error e) {// mostly reflection errors + } catch (StreamException | ConversionException | Error e) {// mostly reflection errors throw new IOException("Unable to read",e); - } finally { - in.close(); } save(); } @@ -1128,11 +1221,30 @@ public abstract class View extends AbstractModelObject implements AccessControll return Jenkins.getInstance().getDescriptorList(View.class); } + /** + * Returns the {@link ViewDescriptor} instances that can be instantiated for the {@link ViewGroup} in the current + * {@link StaplerRequest}. + *

+ * NOTE: Historically this method is only ever called from a {@link StaplerRequest} + * @return the list of instantiable {@link ViewDescriptor} instances for the current {@link StaplerRequest} + */ + @Nonnull public static List allInstantiable() { List r = new ArrayList(); - for (ViewDescriptor d : all()) - if(d.isInstantiable()) + StaplerRequest request = Stapler.getCurrentRequest(); + if (request == null) { + throw new IllegalStateException("This method can only be invoked from a stapler request"); + } + ViewGroup owner = request.findAncestorObject(ViewGroup.class); + if (owner == null) { + throw new IllegalStateException("This method can only be invoked from a request with a ViewGroup ancestor"); + } + for (ViewDescriptor d : DescriptorVisibilityFilter.apply(owner, all())) { + if (d.isApplicableIn(owner) && d.isInstantiable() + && owner.getACL().hasCreatePermission(Jenkins.getAuthentication(), owner, d)) { r.add(d); + } + } return r; } @@ -1158,21 +1270,26 @@ public abstract class View extends AbstractModelObject implements AccessControll public static View create(StaplerRequest req, StaplerResponse rsp, ViewGroup owner) throws FormException, IOException, ServletException { + String mode = req.getParameter("mode"); + String requestContentType = req.getContentType(); - if(requestContentType==null) + if (requestContentType == null + && !(mode != null && mode.equals("copy"))) throw new Failure("No Content-Type header set"); - boolean isXmlSubmission = requestContentType.startsWith("application/xml") || requestContentType.startsWith("text/xml"); + boolean isXmlSubmission = requestContentType != null + && (requestContentType.startsWith("application/xml") + || requestContentType.startsWith("text/xml")); String name = req.getParameter("name"); checkGoodName(name); if(owner.getView(name)!=null) throw new Failure(Messages.Hudson_ViewAlreadyExists(name)); - String mode = req.getParameter("mode"); if (mode==null || mode.length()==0) { if(isXmlSubmission) { View v = createViewFromXML(name, req.getInputStream()); + owner.getACL().checkCreatePermission(owner, v.getDescriptor()); v.owner = owner; rsp.setStatus(HttpServletResponse.SC_OK); return v; @@ -1181,7 +1298,7 @@ public abstract class View extends AbstractModelObject implements AccessControll } View v; - if (mode!=null && mode.equals("copy")) { + if ("copy".equals(mode)) { v = copy(req, owner, name); } else { ViewDescriptor descriptor = all().findByName(mode); @@ -1192,6 +1309,7 @@ public abstract class View extends AbstractModelObject implements AccessControll // create a view v = descriptor.newInstance(req,req.getSubmittedForm()); } + owner.getACL().checkCreatePermission(owner, v.getDescriptor()); v.owner = owner; // redirect to the config screen @@ -1222,20 +1340,14 @@ public abstract class View extends AbstractModelObject implements AccessControll * @param name Alternative name to use or null to keep the one in xml. */ public static View createViewFromXML(String name, InputStream xml) throws IOException { - InputStream in = new BufferedInputStream(xml); - try { + + try (InputStream in = new BufferedInputStream(xml)) { View v = (View) Jenkins.XSTREAM.fromXML(in); if (name != null) v.name = name; checkGoodName(v.name); return v; - } catch(StreamException e) { - throw new IOException("Unable to read",e); - } catch(ConversionException e) { - throw new IOException("Unable to read",e); - } catch(Error e) {// mostly reflection errors + } catch(StreamException|ConversionException|Error e) {// mostly reflection errors throw new IOException("Unable to read",e); - } finally { - in.close(); } } diff --git a/core/src/main/java/hudson/model/ViewDescriptor.java b/core/src/main/java/hudson/model/ViewDescriptor.java index b8e6344365e7e69562cf57bfeb30ea05e93557dd..c1656cea644919df8ffd122637dcc982a7af1b4d 100644 --- a/core/src/main/java/hudson/model/ViewDescriptor.java +++ b/core/src/main/java/hudson/model/ViewDescriptor.java @@ -23,15 +23,26 @@ */ package hudson.model; +import hudson.util.FormValidation; import hudson.views.ListViewColumn; import hudson.views.ListViewColumnDescriptor; import hudson.views.ViewJobFilter; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Iterator; +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import jenkins.model.DirectlyModifiableTopLevelItemGroup; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +import org.jvnet.tiger_types.Types; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.AncestorInPath; - -import java.util.List; +import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; /** * {@link Descriptor} for {@link View}. @@ -45,7 +56,10 @@ public abstract class ViewDescriptor extends Descriptor { * in the view creation screen. The string should look like * "Abc Def Ghi". */ - public abstract String getDisplayName(); + @Override + public String getDisplayName() { + return super.getDisplayName(); + } /** * Some special views are not instantiable, and for those @@ -73,14 +87,35 @@ public abstract class ViewDescriptor extends Descriptor { * Auto-completion for the "copy from" field in the new job page. */ @Restricted(DoNotUse.class) - public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter final String value, @AncestorInPath ItemGroup container) { - return AutoCompletionCandidates.ofJobNames(TopLevelItem.class, value, container); + public AutoCompletionCandidates doAutoCompleteCopyNewItemFrom(@QueryParameter final String value, @AncestorInPath ItemGroup container) { + // TODO do we need a permissions check here? + AutoCompletionCandidates candidates = AutoCompletionCandidates.ofJobNames(TopLevelItem.class, value, container); + if (container instanceof DirectlyModifiableTopLevelItemGroup) { + DirectlyModifiableTopLevelItemGroup modifiableContainer = (DirectlyModifiableTopLevelItemGroup) container; + Iterator it = candidates.getValues().iterator(); + while (it.hasNext()) { + TopLevelItem item = Jenkins.getInstance().getItem(it.next(), container, TopLevelItem.class); + if (item == null) { + continue; // ? + } + if (!modifiableContainer.canAdd(item)) { + it.remove(); + } + } + } + return candidates; } /** * Possible {@link ListViewColumnDescriptor}s that can be used with this view. */ public List> getColumnsDescriptors() { + StaplerRequest request = Stapler.getCurrentRequest(); + if (request != null) { + View view = request.findAncestorObject(clazz); + return view == null ? DescriptorVisibilityFilter.applyType(clazz, ListViewColumn.all()) + : DescriptorVisibilityFilter.apply(view, ListViewColumn.all()); + } return ListViewColumn.all(); } @@ -88,6 +123,62 @@ public abstract class ViewDescriptor extends Descriptor { * Possible {@link ViewJobFilter} types that can be used with this view. */ public List> getJobFiltersDescriptors() { + StaplerRequest request = Stapler.getCurrentRequest(); + if (request != null) { + View view = request.findAncestorObject(clazz); + return view == null ? DescriptorVisibilityFilter.applyType(clazz, ViewJobFilter.all()) + : DescriptorVisibilityFilter.apply(view, ViewJobFilter.all()); + } return ViewJobFilter.all(); } + + /** + * Validation of the display name field. + * + * @param view the view to check the new display name of. + * @param value the proposed new display name. + * @return the validation result. + * @since 2.37 + */ + @SuppressWarnings("unused") // expose utility check method to subclasses + protected FormValidation checkDisplayName(@Nonnull View view, @CheckForNull String value) { + if (StringUtils.isBlank(value)) { + // no custom name, no need to check + return FormValidation.ok(); + } + for (View v: view.owner.getViews()) { + if (v.getViewName().equals(view.getViewName())) { + continue; + } + if (StringUtils.equals(v.getDisplayName(), value)) { + return FormValidation.warning(Messages.View_DisplayNameNotUniqueWarning(value)); + } + } + return FormValidation.ok(); + } + + /** + * Returns true if this {@link View} type is applicable to the given {@link ViewGroup} type. + *

+ * Default implementation returns {@code true} always. + * + * @return true to indicate applicable, in which case the view will be instantiable within the type of owner. + * @since 2.37 + */ + public boolean isApplicable(Class ownerType) { + return true; + } + + /** + * Returns true if this {@link View} type is applicable in the specific {@link ViewGroup}. + *

+ * Default implementation returns {@link #isApplicable(Class)} for the {@link ViewGroup#getClass()}. + * + * @return true to indicate applicable, in which case the view will be instantiable within the given owner. + * @since 2.37 + */ + public boolean isApplicableIn(ViewGroup owner) { + return isApplicable(owner.getClass()); + } + } diff --git a/core/src/main/java/hudson/model/ViewGroupMixIn.java b/core/src/main/java/hudson/model/ViewGroupMixIn.java index 3134ae06d26e53c9c46ff21d75b1b40d65971be7..dcdc5a803c4de3be55b1fb575ee8a0e5f205e5c8 100644 --- a/core/src/main/java/hudson/model/ViewGroupMixIn.java +++ b/core/src/main/java/hudson/model/ViewGroupMixIn.java @@ -26,13 +26,14 @@ package hudson.model; import hudson.model.ItemGroupMixIn; import hudson.model.View; import hudson.model.ViewGroup; +import java.util.Locale; +import java.util.logging.Level; import org.kohsuke.stapler.export.Exported; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.List; /** @@ -100,6 +101,15 @@ public abstract class ViewGroupMixIn { View pv = getPrimaryView(); if (pv instanceof ViewGroup) return ((ViewGroup)pv).getView(name); + if (pv instanceof AllView && AllView.DEFAULT_VIEW_NAME.equals(pv.name)) { + // JENKINS-38606: primary view is the default AllView, is somebody using an old link to localized form? + for (Locale l : Locale.getAvailableLocales()) { + if (name.equals(Messages._Hudson_ViewName().toString(l))) { + // why yes they are, let's keep that link working + return pv; + } + } + } } return null; } diff --git a/core/src/main/java/hudson/model/ViewJob.java b/core/src/main/java/hudson/model/ViewJob.java index 92e36999e2150c50ae301b9ef4f8e23744237cf3..42c963a4782681c8019fb0764eabfe4fd6266935 100644 --- a/core/src/main/java/hudson/model/ViewJob.java +++ b/core/src/main/java/hudson/model/ViewJob.java @@ -23,6 +23,7 @@ */ package hudson.model; +import jenkins.util.SystemProperties; import hudson.model.Descriptor.FormException; import java.io.IOException; import java.util.LinkedHashSet; @@ -226,5 +227,5 @@ public abstract class ViewJob, RunT extends Run< * when explicitly requested. * */ - public static boolean reloadPeriodically = Boolean.getBoolean(ViewJob.class.getName()+".reloadPeriodically"); + public static boolean reloadPeriodically = SystemProperties.getBoolean(ViewJob.class.getName()+".reloadPeriodically"); } diff --git a/core/src/main/java/hudson/model/WorkspaceBrowser.java b/core/src/main/java/hudson/model/WorkspaceBrowser.java index 35d6280ded2e88c59b7ee79c47955de87968df22..037420d53d9a307e25adcf92087822395f837ef2 100644 --- a/core/src/main/java/hudson/model/WorkspaceBrowser.java +++ b/core/src/main/java/hudson/model/WorkspaceBrowser.java @@ -33,8 +33,8 @@ import javax.annotation.CheckForNull; /** * Allows to access a workspace as an alternative to online build node. *

- * Primary use case is {@link hudson.slaves.Cloud} implementations that don't keep the slave - * node online to browse workspace, but maintain a copy of node workspace on master. + * Primary use case is {@link hudson.slaves.Cloud} implementations that don't keep the agent + * online to browse workspace, but maintain a copy of node workspace on master. * * @author Nicolas De Loof * @since 1.502 diff --git a/core/src/main/java/hudson/model/WorkspaceCleanupThread.java b/core/src/main/java/hudson/model/WorkspaceCleanupThread.java index 9e83e143e5a361b265986746cd8d87968a1596df..e15228f3d75639a941b82c00129c4fae8abbad42 100644 --- a/core/src/main/java/hudson/model/WorkspaceCleanupThread.java +++ b/core/src/main/java/hudson/model/WorkspaceCleanupThread.java @@ -26,7 +26,9 @@ package hudson.model; import hudson.Extension; import hudson.ExtensionList; import hudson.FilePath; +import jenkins.util.SystemProperties; import hudson.Util; +import hudson.slaves.WorkspaceList; import java.io.IOException; import java.util.ArrayList; import java.util.Date; @@ -36,13 +38,14 @@ import java.util.logging.Logger; import javax.annotation.Nonnull; import jenkins.model.Jenkins; import jenkins.model.ModifiableTopLevelItemGroup; +import org.jenkinsci.Symbol; /** - * Clean up old left-over workspaces from slaves. + * Clean up old left-over workspaces from agents. * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("workspaceCleanup") public class WorkspaceCleanupThread extends AsyncPeriodicWork { public WorkspaceCleanupThread() { super("Workspace clean-up"); @@ -89,6 +92,7 @@ public class WorkspaceCleanupThread extends AsyncPeriodicWork { listener.getLogger().println("Deleting " + ws + " on " + node.getDisplayName()); try { ws.deleteRecursive(); + WorkspaceList.tempDir(ws).deleteRecursive(); } catch (IOException x) { x.printStackTrace(listener.error("Failed to delete " + ws + " on " + node.getDisplayName())); } catch (InterruptedException x) { @@ -143,15 +147,15 @@ public class WorkspaceCleanupThread extends AsyncPeriodicWork { /** * Can be used to disable workspace clean up. */ - public static boolean disabled = Boolean.getBoolean(WorkspaceCleanupThread.class.getName()+".disabled"); + public static boolean disabled = SystemProperties.getBoolean(WorkspaceCleanupThread.class.getName()+".disabled"); /** * How often the clean up should run. This is final as Jenkins will not reflect changes anyway. */ - public static final int recurrencePeriodHours = Integer.getInteger(WorkspaceCleanupThread.class.getName()+".recurrencePeriodHours", 24); + public static final int recurrencePeriodHours = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName()+".recurrencePeriodHours", 24); /** * Number of days workspaces should be retained. */ - public static int retainForDays = Integer.getInteger(WorkspaceCleanupThread.class.getName()+".retainForDays", 30); + public static int retainForDays = SystemProperties.getInteger(WorkspaceCleanupThread.class.getName()+".retainForDays", 30); } diff --git a/core/src/main/java/hudson/model/WorkspaceListener.java b/core/src/main/java/hudson/model/WorkspaceListener.java index 9635a42192407ac8262dd64c12671446205aa5be..94d37d41441833998e655823bbc00fd0ce7d772e 100644 --- a/core/src/main/java/hudson/model/WorkspaceListener.java +++ b/core/src/main/java/hudson/model/WorkspaceListener.java @@ -3,7 +3,6 @@ package hudson.model; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.FilePath; -import jenkins.model.Jenkins; public abstract class WorkspaceListener implements ExtensionPoint { diff --git a/core/src/main/java/hudson/model/listeners/RunListener.java b/core/src/main/java/hudson/model/listeners/RunListener.java index e65347bc0299648ce1ddb29bbb54aa94feed3e7b..485a4498f41da4dbe989f8f1f94cfe302cd157f9 100644 --- a/core/src/main/java/hudson/model/listeners/RunListener.java +++ b/core/src/main/java/hudson/model/listeners/RunListener.java @@ -28,10 +28,12 @@ import hudson.ExtensionListView; import hudson.Extension; import hudson.ExtensionList; import hudson.FilePath; +import hudson.Functions; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.Environment; +import hudson.model.Job; import hudson.model.JobProperty; import hudson.model.Run; import hudson.model.Run.RunnerAbortedException; @@ -106,6 +108,14 @@ public abstract class RunListener implements ExtensionPoint { */ public void onFinalized(R r) {} + /** + * Called when a Run is entering execution. + * @param r + * The started build. + * @since 2.9 + */ + public void onInitialize(R r) {} + /** * Called when a build is started (i.e. it was in the queue, and will now start running * on an executor) @@ -205,6 +215,21 @@ public abstract class RunListener implements ExtensionPoint { } } + /** + * Fires the {@link #onInitialize(Run)} event. + */ + public static void fireInitialize(Run r) { + for (RunListener l : all()) { + if(l.targetType.isInstance(r)) + try { + l.onInitialize(r); + } catch (Throwable e) { + report(e); + } + } + } + + /** * Fires the {@link #onStarted(Run, TaskListener)} event. */ @@ -223,7 +248,7 @@ public abstract class RunListener implements ExtensionPoint { * Fires the {@link #onFinalized(Run)} event. */ public static void fireFinalized(Run r) { - if (Jenkins.getInstance() == null) { + if (Jenkins.getInstanceOrNull() == null) { // TODO use !Functions.isExtensionsAvailable() once JENKINS-33377 return; } for (RunListener l : all()) { @@ -262,4 +287,5 @@ public abstract class RunListener implements ExtensionPoint { } private static final Logger LOGGER = Logger.getLogger(RunListener.class.getName()); + } diff --git a/core/src/main/java/hudson/model/listeners/SCMListener.java b/core/src/main/java/hudson/model/listeners/SCMListener.java index 3f570aa24fb2ad361a992328a11d234d3f1b4e2d..161fb0f6033801c5103001fba164c3fd036bb4c6 100644 --- a/core/src/main/java/hudson/model/listeners/SCMListener.java +++ b/core/src/main/java/hudson/model/listeners/SCMListener.java @@ -126,8 +126,8 @@ public abstract class SCMListener implements ExtensionPoint { */ @SuppressWarnings("deprecation") public static Collection all() { - Jenkins j = Jenkins.getInstance(); - if (j == null) { + Jenkins j = Jenkins.getInstanceOrNull(); + if (j == null) { // TODO use !Functions.isExtensionsAvailable() once JENKINS-33377 return Collections.emptySet(); } List r = new ArrayList(j.getExtensionList(SCMListener.class)); @@ -140,20 +140,12 @@ public abstract class SCMListener implements ExtensionPoint { /** @deprecated Use {@link Extension} instead. */ @Deprecated public final void register() { - Jenkins j = Jenkins.getInstance(); - if (j != null) { - j.getSCMListeners().add(this); - } + Jenkins.getInstance().getSCMListeners().add(this); } /** @deprecated Use {@link Extension} instead. */ @Deprecated public final boolean unregister() { - Jenkins j = Jenkins.getInstance(); - if (j != null) { - return j.getSCMListeners().remove(this); - } else { - return false; - } + return Jenkins.getInstance().getSCMListeners().remove(this); } } diff --git a/core/src/main/java/hudson/model/listeners/SCMPollListener.java b/core/src/main/java/hudson/model/listeners/SCMPollListener.java index 7b7b94ba4034124554fae662b39c4461b3dc1d10..55dd8d558930c0ace3445c18f84a2658d4743bf7 100644 --- a/core/src/main/java/hudson/model/listeners/SCMPollListener.java +++ b/core/src/main/java/hudson/model/listeners/SCMPollListener.java @@ -26,7 +26,6 @@ package hudson.model.listeners; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.scm.PollingResult; -import jenkins.model.Jenkins; import hudson.model.AbstractProject; import hudson.model.TaskListener; diff --git a/core/src/main/java/hudson/model/queue/AbstractQueueTask.java b/core/src/main/java/hudson/model/queue/AbstractQueueTask.java index d3586384f0dca4aec809a0377a6a8d05afc6fdf7..7a1bae3f7a71b68ee5e6940d5c21827d179964ee 100644 --- a/core/src/main/java/hudson/model/queue/AbstractQueueTask.java +++ b/core/src/main/java/hudson/model/queue/AbstractQueueTask.java @@ -27,6 +27,7 @@ package hudson.model.queue; import hudson.model.Queue; import hudson.model.Queue.Task; import hudson.security.ACL; +import hudson.security.AccessControlled; import org.acegisecurity.Authentication; import javax.annotation.Nonnull; @@ -37,6 +38,10 @@ import java.util.Collections; * Abstract base class for {@link hudson.model.Queue.Task} to protect plugins * from new additions to the interface. * + *

+ * Plugins are encouraged to implement {@link AccessControlled} otherwise + * the tasks will be hidden from display in the queue. + * * @author Kohsuke Kawaguchi * @since 1.360 */ diff --git a/core/src/main/java/hudson/model/queue/BackFiller.java b/core/src/main/java/hudson/model/queue/BackFiller.java index 0eeea61670929f72a23e26e91d64e30ef9de71f9..6278dd9b99e4cd43ef57b92fe11ff75d7eae0a2c 100644 --- a/core/src/main/java/hudson/model/queue/BackFiller.java +++ b/core/src/main/java/hudson/model/queue/BackFiller.java @@ -2,6 +2,7 @@ package hudson.model.queue; import com.google.common.collect.Iterables; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.model.Computer; import hudson.model.Executor; import jenkins.model.Jenkins; @@ -204,7 +205,7 @@ public class BackFiller extends LoadPredictor { */ @Extension public static BackFiller newInstance() { - if (Boolean.getBoolean(BackFiller.class.getName())) + if (SystemProperties.getBoolean(BackFiller.class.getName())) return new BackFiller(); return null; } diff --git a/core/src/main/java/hudson/model/queue/CauseOfBlockage.java b/core/src/main/java/hudson/model/queue/CauseOfBlockage.java index 5cb65870363776ea7a6f87160d26335d2a28cdc0..e5ba86359771f88092d1ed5982197bc48dad24d7 100644 --- a/core/src/main/java/hudson/model/queue/CauseOfBlockage.java +++ b/core/src/main/java/hudson/model/queue/CauseOfBlockage.java @@ -1,12 +1,14 @@ package hudson.model.queue; import hudson.console.ModelHyperlinkNote; +import hudson.model.Computer; import hudson.model.Queue.Task; import hudson.model.Node; import hudson.model.Messages; import hudson.model.Label; import hudson.model.TaskListener; import hudson.slaves.Cloud; +import javax.annotation.Nonnull; import org.jvnet.localizer.Localizable; /** @@ -42,8 +44,10 @@ public abstract class CauseOfBlockage { /** * Obtains a simple implementation backed by {@link Localizable}. */ - public static CauseOfBlockage fromMessage(final Localizable l) { + public static CauseOfBlockage fromMessage(@Nonnull final Localizable l) { + l.getKey(); // null check return new CauseOfBlockage() { + @Override public String getShortDescription() { return l.toString(); } @@ -103,6 +107,33 @@ public abstract class CauseOfBlockage { } } + /** + * Build is blocked because a node (or its retention strategy) is not accepting tasks. + * @since 2.37 + */ + public static final class BecauseNodeIsNotAcceptingTasks extends CauseOfBlockage implements NeedsMoreExecutor { + + public final Node node; + + public BecauseNodeIsNotAcceptingTasks(Node node) { + this.node = node; + } + + @Override + public String getShortDescription() { + Computer computer = node.toComputer(); + String name = computer != null ? computer.getDisplayName() : node.getDisplayName(); + return Messages.Node_BecauseNodeIsNotAcceptingTasks(name); + } + + @Override + public void print(TaskListener listener) { + listener.getLogger().println( + Messages.Node_BecauseNodeIsNotAcceptingTasks(ModelHyperlinkNote.encodeTo(node))); + } + + } + /** * Build is blocked because all the nodes that match a given label is offline. */ diff --git a/core/src/main/java/hudson/model/queue/Executables.java b/core/src/main/java/hudson/model/queue/Executables.java index a8a524bc8e7d31246c80a7c4390b6c109d7683bb..df57d9caf013e79b04dfd916bbe8337922fe8be4 100644 --- a/core/src/main/java/hudson/model/queue/Executables.java +++ b/core/src/main/java/hudson/model/queue/Executables.java @@ -27,6 +27,7 @@ import hudson.model.Queue.Executable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; /** @@ -61,10 +62,18 @@ public class Executables { /** * Returns the estimated duration for the executable. + * If the Executable is null the Estimated Duration can't be evaluated, then -1 is returned. + * This can happen if Computer.getIdleStartMilliseconds() is called before the executable is set to non-null in Computer.run() + * or if the executor thread exits prematurely, see JENKINS-30456 * Protects against {@link AbstractMethodError}s if the {@link Executable} implementation * was compiled against Hudson < 1.383 + * @param e Executable item + * @return the estimated duration for a given executable, -1 if the executable is null */ - public static long getEstimatedDurationFor(Executable e) { + public static long getEstimatedDurationFor(@CheckForNull Executable e) { + if (e == null) { + return -1; + } try { return e.getEstimatedDuration(); } catch (AbstractMethodError error) { diff --git a/core/src/main/java/hudson/model/queue/LoadPredictor.java b/core/src/main/java/hudson/model/queue/LoadPredictor.java index cb2070b59640c53a06e20c22a41cd225a341aa79..2fc4bf8d657c6aaaf0bd6e587d6fa6f6dcb1b6fd 100644 --- a/core/src/main/java/hudson/model/queue/LoadPredictor.java +++ b/core/src/main/java/hudson/model/queue/LoadPredictor.java @@ -28,7 +28,6 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Computer; import hudson.model.Executor; -import jenkins.model.Jenkins; import java.util.ArrayList; import java.util.Collections; diff --git a/core/src/main/java/hudson/model/queue/MappingWorksheet.java b/core/src/main/java/hudson/model/queue/MappingWorksheet.java index 0e21fa31ad72268b5c0e0ad6d8ae431fc7b16a5d..4ef5af3c8c9fb4f15a52c18e8edb17ee649f5446 100644 --- a/core/src/main/java/hudson/model/queue/MappingWorksheet.java +++ b/core/src/main/java/hudson/model/queue/MappingWorksheet.java @@ -25,7 +25,6 @@ package hudson.model.queue; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import hudson.model.AbstractProject; import hudson.model.Computer; import hudson.model.Executor; import hudson.model.Label; diff --git a/core/src/main/java/hudson/model/queue/QueueListener.java b/core/src/main/java/hudson/model/queue/QueueListener.java index 527a9485b4dc0a82616ad9a3723bfae740fa5ac3..50fbf35e274f8b3f9a059a4042debaa33209acd8 100644 --- a/core/src/main/java/hudson/model/queue/QueueListener.java +++ b/core/src/main/java/hudson/model/queue/QueueListener.java @@ -2,14 +2,12 @@ package hudson.model.queue; import hudson.ExtensionList; import hudson.ExtensionPoint; -import hudson.model.Computer; import hudson.model.Queue; import hudson.model.Queue.BlockedItem; import hudson.model.Queue.BuildableItem; import hudson.model.Queue.Item; import hudson.model.Queue.LeftItem; import hudson.model.Queue.WaitingItem; -import jenkins.model.Jenkins; import java.util.concurrent.Executor; diff --git a/core/src/main/java/hudson/model/queue/QueueSorter.java b/core/src/main/java/hudson/model/queue/QueueSorter.java index fafd9b0c1cc3b59baeefb819f16ececeb0081b28..251f8d72b80723959d266df1d7130326a0c80cf2 100644 --- a/core/src/main/java/hudson/model/queue/QueueSorter.java +++ b/core/src/main/java/hudson/model/queue/QueueSorter.java @@ -8,6 +8,8 @@ import hudson.model.LoadBalancer; import hudson.model.Queue; import hudson.model.Queue.BuildableItem; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.logging.Logger; @@ -19,6 +21,20 @@ import static hudson.init.InitMilestone.JOB_LOADED; * @since 1.343 */ public abstract class QueueSorter implements ExtensionPoint { + /** + * A comparator that sorts {@link Queue.BlockedItem} instances based on how long they have been in the queue. + * (We want the time since in queue by default as blocking on upstream/downstream considers waiting items + * also and thus the blocking starts once the task is in the queue not once the task is buildable) + * + * @since 1.618 + */ + public static final Comparator DEFAULT_BLOCKED_ITEM_COMPARATOR = new Comparator() { + @Override + public int compare(Queue.BlockedItem o1, Queue.BlockedItem o2) { + return Long.compare(o1.getInQueueSince(), o2.getInQueueSince()); + } + }; + /** * Sorts the buildable items list. The items at the beginning will be executed * before the items at the end of the list. @@ -28,6 +44,18 @@ public abstract class QueueSorter implements ExtensionPoint { */ public abstract void sortBuildableItems(List buildables); + /** + * Sorts the blocked items list. The items at the beginning will be considered for removal from the blocked state + * before the items at the end of the list. + * + * @param blockedItems + * List of blocked items in the queue. Never null. + * @since 1.618 + */ + public void sortBlockedItems(List blockedItems) { + Collections.sort(blockedItems, DEFAULT_BLOCKED_ITEM_COMPARATOR); + } + /** * All registered {@link QueueSorter}s. Only the first one will be picked up, * unless explicitly overridden by {@link Queue#setSorter(QueueSorter)}. diff --git a/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java b/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java index 78ac2c527eb33d75647ff00a6defce4f7cff3d2e..cd5c5d5b0cc9a743d41b71e4e360c1ba72a06cce 100644 --- a/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java +++ b/core/src/main/java/hudson/model/queue/QueueTaskDispatcher.java @@ -27,9 +27,7 @@ package hudson.model.queue; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; -import hudson.model.Queue.Item; import hudson.slaves.Cloud; -import jenkins.model.Jenkins; import hudson.model.Node; import hudson.model.Queue; import hudson.model.Queue.BuildableItem; diff --git a/core/src/main/java/hudson/model/queue/ScheduleResult.java b/core/src/main/java/hudson/model/queue/ScheduleResult.java index 95ebf0394ac4ad07784630bc881ff40dcf7d6142..0ba9b08944fba2d6797e54441321430476c4acbd 100644 --- a/core/src/main/java/hudson/model/queue/ScheduleResult.java +++ b/core/src/main/java/hudson/model/queue/ScheduleResult.java @@ -1,9 +1,7 @@ package hudson.model.queue; -import hudson.model.Action; import hudson.model.Queue; import hudson.model.Queue.Item; -import hudson.model.Queue.Task; import hudson.model.Queue.WaitingItem; import javax.annotation.CheckForNull; diff --git a/core/src/main/java/hudson/model/queue/SubTaskContributor.java b/core/src/main/java/hudson/model/queue/SubTaskContributor.java index b61a19ea3384cf2241188386eb92cc3a9e7282ab..313b863601c4d918f55cee0ef2591364c056b51b 100644 --- a/core/src/main/java/hudson/model/queue/SubTaskContributor.java +++ b/core/src/main/java/hudson/model/queue/SubTaskContributor.java @@ -27,7 +27,6 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.AbstractProject; -import jenkins.model.Jenkins; import java.util.Collection; import java.util.Collections; diff --git a/core/src/main/java/hudson/model/queue/WorkUnit.java b/core/src/main/java/hudson/model/queue/WorkUnit.java index 58c4ba31ca7641313aec28fa274daf78d1f98797..68a3d7fce78f58da2a0e6facd5a5067b15113199 100644 --- a/core/src/main/java/hudson/model/queue/WorkUnit.java +++ b/core/src/main/java/hudson/model/queue/WorkUnit.java @@ -71,6 +71,9 @@ public final class WorkUnit { public void setExecutor(@CheckForNull Executor e) { executor = e; + if (e != null) { + context.future.addExecutor(e); + } } /** diff --git a/core/src/main/java/hudson/model/queue/WorkUnitContext.java b/core/src/main/java/hudson/model/queue/WorkUnitContext.java index 503a1774917d53666c0840ddc311b58a13a2b6ff..7c030234aacb2a8910d0c65a490d1314f8b0cf56 100644 --- a/core/src/main/java/hudson/model/queue/WorkUnitContext.java +++ b/core/src/main/java/hudson/model/queue/WorkUnitContext.java @@ -88,14 +88,9 @@ public final class WorkUnitContext { } /** - * Called by the executor that executes a member {@link SubTask} that belongs to this task - * to create its {@link WorkUnit}. + * Called within the queue maintenance process to create a {@link WorkUnit} for the given {@link SubTask} */ public WorkUnit createWorkUnit(SubTask execUnit) { - Executor executor = Executor.currentExecutor(); - if (executor != null) { // TODO is it legal for this to be called by a non-executor thread? - future.addExecutor(executor); - } WorkUnit wu = new WorkUnit(this, execUnit); workUnits.add(wu); return wu; diff --git a/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java index 7a0a0237fd88f80a1d10e71e356c8f633d21d350..a825594798f1f1416c132b68d57075ad2b735f20 100644 --- a/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java +++ b/core/src/main/java/hudson/node_monitors/AbstractAsyncNodeMonitorDescriptor.java @@ -12,7 +12,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.logging.Logger; @@ -21,7 +20,7 @@ import static java.util.logging.Level.WARNING; /** * Sophisticated version of {@link AbstractNodeMonitorDescriptor} that - * performs monitoring on all slaves concurrently and asynchronously. + * performs monitoring on all agents concurrently and asynchronously. * * @param * represents the the result of the monitoring. diff --git a/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java index ff457ffed0beedd0cd3e8b39247142ba7f9e22a3..c79d4ea918e63392e2e08c056278955079db9e05 100644 --- a/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java +++ b/core/src/main/java/hudson/node_monitors/AbstractNodeMonitorDescriptor.java @@ -26,7 +26,6 @@ package hudson.node_monitors; import hudson.Util; import hudson.model.Computer; import hudson.model.Descriptor; -import hudson.model.Run; import jenkins.model.Jenkins; import hudson.model.ComputerSet; import hudson.model.AdministrativeMonitor; @@ -170,12 +169,7 @@ public abstract class AbstractNodeMonitorDescriptor extends Descriptor extends Descriptor inProgressStarted + getMonitoringTimeOut() + 1000) { + if (!inProgress.isAlive()) { + LOGGER.log(Level.WARNING, "Previous {0} monitoring activity died without cleaning up after itself", + getDisplayName()); + inProgress = null; + } else if (System.currentTimeMillis() > inProgressStarted + getMonitoringTimeOut() + 1000) { // maybe it got stuck? LOGGER.log(Level.WARNING, "Previous {0} monitoring activity still in progress. Interrupting", getDisplayName()); diff --git a/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java b/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java index ec0618f807872aad3efd37b30285552b85b67305..ff5a18d8f70a6916514def76ef6a18b17e39397a 100644 --- a/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java +++ b/core/src/main/java/hudson/node_monitors/ArchitectureMonitor.java @@ -28,17 +28,18 @@ import hudson.remoting.Callable; import hudson.Extension; import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; /** - * Discovers the architecture of the system to display in the slave list page. + * Discovers the architecture of the system to display in the agent list page. * * @author Kohsuke Kawaguchi */ public class ArchitectureMonitor extends NodeMonitor { - @Extension + @Extension @Symbol("architecture") public static final class DescriptorImpl extends AbstractAsyncNodeMonitorDescriptor { @Override protected Callable createCallable(Computer c) { diff --git a/core/src/main/java/hudson/node_monitors/ClockMonitor.java b/core/src/main/java/hudson/node_monitors/ClockMonitor.java index cf3f02599715ff3a6ae25f3f63c4e98559022609..176f77bfab29255df079e5fb8de92c318266b62e 100644 --- a/core/src/main/java/hudson/node_monitors/ClockMonitor.java +++ b/core/src/main/java/hudson/node_monitors/ClockMonitor.java @@ -28,6 +28,9 @@ import hudson.model.Node; import hudson.remoting.Callable; import hudson.util.ClockDifference; import hudson.Extension; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -46,8 +49,19 @@ public class ClockMonitor extends NodeMonitor { return DESCRIPTOR.get(c); } - @Extension - public static final AbstractNodeMonitorDescriptor DESCRIPTOR = new AbstractAsyncNodeMonitorDescriptor() { + /** + * @deprecated as of 2.0 + * Don't use this field, use injection. + */ + @Restricted(NoExternalUse.class) + public static /*almost final*/ AbstractNodeMonitorDescriptor DESCRIPTOR; + + @Extension @Symbol("clock") + public static class DescriptorImpl extends AbstractAsyncNodeMonitorDescriptor { + public DescriptorImpl() { + DESCRIPTOR = this; + } + @Override protected Callable createCallable(Computer c) { Node n = c.getNode(); diff --git a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java index 4bd1c939c622c890ae81d59977b82225e2db6f9d..3fb829710001a9e9d138057be74882ab62cefef1 100644 --- a/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java +++ b/core/src/main/java/hudson/node_monitors/DiskSpaceMonitorDescriptor.java @@ -27,7 +27,6 @@ import hudson.Functions; import jenkins.MasterToSlaveFileCallable; import hudson.remoting.VirtualChannel; import hudson.Util; -import hudson.slaves.OfflineCause; import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace; import java.io.File; @@ -37,6 +36,8 @@ import java.math.BigDecimal; import java.text.ParseException; import java.util.Locale; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.Exported; @@ -81,6 +82,14 @@ public abstract class DiskSpaceMonitorDescriptor extends AbstractAsyncNodeMonito return path; } + // Needed for jelly that does not seem to be able to access properties + // named 'size' as it confuses it with built-in size method and fails + // to parse the expression expecting '()'. + @Restricted(DoNotUse.class) + public long getFreeSize() { + return size; + } + /** * Gets GB left. */ diff --git a/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java b/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java index a881b745cb923b728e3ae3d53cd1f6ccf64d8435..6a75d5c14b71154477c5e13a0d7373f6c29b41bd 100644 --- a/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java +++ b/core/src/main/java/hudson/node_monitors/MonitorMarkedNodeOffline.java @@ -37,6 +37,11 @@ import hudson.Extension; */ @Extension public class MonitorMarkedNodeOffline extends AdministrativeMonitor { + @Override + public String getDisplayName() { + return Messages.MonitorMarkedNodeOffline_DisplayName(); + } + public boolean active = false; public boolean isActivated() { diff --git a/core/src/main/java/hudson/node_monitors/NodeMonitor.java b/core/src/main/java/hudson/node_monitors/NodeMonitor.java index 9429af2c1b548a307c930775809365d06ccef54c..17ddf7343ef29036b32c6eef2ebf26dcb07f59af 100644 --- a/core/src/main/java/hudson/node_monitors/NodeMonitor.java +++ b/core/src/main/java/hudson/node_monitors/NodeMonitor.java @@ -114,11 +114,11 @@ public abstract class NodeMonitor implements ExtensionPoint, Describable * Many {@link NodeMonitor}s implement a logic that if the value goes above/below - * a threshold, the slave will be marked offline as a preventive measure. + * a threshold, the agent will be marked offline as a preventive measure. * This flag controls that. * *

diff --git a/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java b/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java index 41573e5d0f6cc08225467c1f1c8970185dce979c..c23b069f8f4a6669ea99ff49e90e07845430738b 100644 --- a/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java +++ b/core/src/main/java/hudson/node_monitors/NodeMonitorUpdater.java @@ -10,12 +10,11 @@ import jenkins.model.Jenkins; import java.io.IOException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; import jenkins.util.Timer; /** - * When a slave is connected, redo the node monitoring. + * When an agent is connected, redo the node monitoring. * * @author Kohsuke Kawaguchi */ @@ -35,7 +34,7 @@ public class NodeMonitorUpdater extends ComputerListener { /** * Triggers the update with 5 seconds quiet period, to avoid triggering data check too often - * when multiple slaves become online at about the same time. + * when multiple agents become online at about the same time. */ @Override public void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException { diff --git a/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java b/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java index 69da2e6bcddc404dbdd75d506c91eed55c3e2576..652b2217fbb142363ac76fc8c572c10023270287 100644 --- a/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java +++ b/core/src/main/java/hudson/node_monitors/ResponseTimeMonitor.java @@ -25,7 +25,6 @@ package hudson.node_monitors; import hudson.Util; import hudson.Extension; -import hudson.slaves.OfflineCause; import hudson.model.Computer; import hudson.remoting.Callable; import jenkins.security.MasterToSlaveCallable; @@ -41,7 +40,7 @@ import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; /** - * Monitors the round-trip response time to this slave. + * Monitors the round-trip response time to this agent. * * @author Kohsuke Kawaguchi */ @@ -65,9 +64,9 @@ public class ResponseTimeMonitor extends NodeMonitor { } if(d.hasTooManyTimeouts() && !isIgnored()) { - // unlike other monitors whose failure still allow us to communicate with the slave, + // unlike other monitors whose failure still allow us to communicate with the agent, // the failure in this monitor indicates that we are just unable to make any requests - // to this slave. So we should severe the connection, as opposed to marking it temporarily + // to this agent. So we should severe the connection, as opposed to marking it temporarily // off line, which still keeps the underlying channel open. c.disconnect(d); LOGGER.warning(Messages.ResponseTimeMonitor_MarkedOffline(c.getName())); @@ -188,7 +187,7 @@ public class ResponseTimeMonitor extends NodeMonitor { } /** - * HTML rendering of the data + * String rendering of the data */ @Override public String toString() { @@ -200,7 +199,7 @@ public class ResponseTimeMonitor extends NodeMonitor { // return buf.toString(); int fc = failureCount(); if(fc>0) - return Util.wrapToErrorSpan(Messages.ResponseTimeMonitor_TimeOut(fc)); + return Messages.ResponseTimeMonitor_TimeOut(fc); return getAverage()+"ms"; } diff --git a/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java b/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java index c289d0fbddcc25faa7e1bf265d1e625af57c8aff..1fe298b4f3dd876152982cf397b6d14c9fe1d843 100644 --- a/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java +++ b/core/src/main/java/hudson/node_monitors/SwapSpaceMonitor.java @@ -30,6 +30,7 @@ import hudson.model.Computer; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.jvnet.hudson.MemoryMonitor; import org.jvnet.hudson.MemoryUsage; import org.kohsuke.stapler.StaplerRequest; @@ -80,8 +81,18 @@ public class SwapSpaceMonitor extends NodeMonitor { return Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER) ? super.getColumnCaption() : null; } - @Extension - public static final AbstractNodeMonitorDescriptor DESCRIPTOR = new AbstractAsyncNodeMonitorDescriptor() { + /** + * @deprecated as of 2.0 + * use injection + */ + public static /*almost final*/ AbstractNodeMonitorDescriptor DESCRIPTOR; + + @Extension @Symbol("swapSpace") + public static class DescriptorImpl extends AbstractAsyncNodeMonitorDescriptor { + public DescriptorImpl() { + DESCRIPTOR = this; + } + @Override protected MonitorTask createCallable(Computer c) { return new MonitorTask(); diff --git a/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java b/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java index 07e99b886629a10027d6d4eaeb9b03d60823f81b..05e148cf6a064434f8bdae0245edeb50aa1e390a 100644 --- a/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java +++ b/core/src/main/java/hudson/node_monitors/TemporarySpaceMonitor.java @@ -32,6 +32,7 @@ import hudson.remoting.Callable; import jenkins.model.Jenkins; import hudson.node_monitors.DiskSpaceMonitorDescriptor.DiskSpace; import hudson.remoting.VirtualChannel; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.io.File; @@ -61,7 +62,18 @@ public class TemporarySpaceMonitor extends AbstractDiskSpaceMonitor { return Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER) ? super.getColumnCaption() : null; } - public static final DiskSpaceMonitorDescriptor DESCRIPTOR = new DiskSpaceMonitorDescriptor() { + /** + * @deprecated as of 2.0 + * Use injection + */ + public static /*almost final*/ DiskSpaceMonitorDescriptor DESCRIPTOR; + + @Extension @Symbol("tmpSpace") + public static class DescriptorImpl extends DiskSpaceMonitorDescriptor { + public DescriptorImpl() { + DESCRIPTOR = this; + } + public String getDisplayName() { return Messages.TemporarySpaceMonitor_DisplayName(); } @@ -76,9 +88,11 @@ public class TemporarySpaceMonitor extends AbstractDiskSpaceMonitor { return p.asCallableWith(new GetTempSpace()); } - }; + } - @Extension + /** + * @deprecated as of 2.0 + */ public static DiskSpaceMonitorDescriptor install() { return DESCRIPTOR; } diff --git a/core/src/main/java/hudson/node_monitors/package.html b/core/src/main/java/hudson/node_monitors/package.html index e7c11a07420fb3b29cd6dc3c4f9110b9b522da6e..e178fe411c749fcb8ddecf07df11f398c5dfc624 100644 --- a/core/src/main/java/hudson/node_monitors/package.html +++ b/core/src/main/java/hudson/node_monitors/package.html @@ -23,5 +23,5 @@ THE SOFTWARE. --> -Code that monitors the health of slaves +Code that monitors the health of agents \ No newline at end of file diff --git a/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java b/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java index f2d10c1c39960b09cb7ee9fd89505ba8fc9cb79a..d7d8a5b54da3e24bd7f83ea3f1d1f1306d63d77c 100644 --- a/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java +++ b/core/src/main/java/hudson/org/apache/tools/tar/TarInputStream.java @@ -37,8 +37,9 @@ import java.io.ByteArrayOutputStream; * methods are provided to position at each successive entry in * the archive, and the read each entry as a normal input stream * using read(). - * + * @deprecated Use {@link org.apache.commons.compress.archivers.tar.TarArchiveInputStream} instead */ +@Deprecated public class TarInputStream extends FilterInputStream { // CheckStyle:VisibilityModifier OFF - bc diff --git a/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java b/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java index f23e44262847de611c21231223966e8f78d1c5b7..48f4876bd45c3cfee3fb0bd9a7d102df85162d19 100644 --- a/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java +++ b/core/src/main/java/hudson/org/apache/tools/tar/TarOutputStream.java @@ -35,8 +35,11 @@ import java.io.IOException; * The TarOutputStream writes a UNIX tar archive as an OutputStream. * Methods are provided to put entries, and then write their contents * by writing to this stream using write(). + * + * @deprecated Use {@link org.apache.commons.compress.archivers.tar.TarArchiveOutputStream} instead * */ +@Deprecated public class TarOutputStream extends FilterOutputStream { /** Fail if a long file name is required in the archive. */ public static final int LONGFILE_ERROR = 0; diff --git a/core/src/main/java/hudson/os/PosixAPI.java b/core/src/main/java/hudson/os/PosixAPI.java index 2e69069c1c2e4a94e7dfbb782be4e12d9112cbc4..f54f29331e8a1f3c7dfc4169e8c9089dac13f1b0 100644 --- a/core/src/main/java/hudson/os/PosixAPI.java +++ b/core/src/main/java/hudson/os/PosixAPI.java @@ -22,6 +22,7 @@ public class PosixAPI { /** * Load the JNR implementation of the POSIX APIs for the current platform. * Runtime exceptions will be of type {@link PosixException}. + * {@link IllegalStateException} will be thrown for methods not implemented on this platform. * @return some implementation (even on Windows or unsupported Unix) * @since 1.518 */ diff --git a/core/src/main/java/hudson/os/SU.java b/core/src/main/java/hudson/os/SU.java index 6a2b8abfa204be7534b9ae376e46a6db2c15ef9a..5998d366c0b753b5c85e382fee17cc7fcbead9c1 100644 --- a/core/src/main/java/hudson/os/SU.java +++ b/core/src/main/java/hudson/os/SU.java @@ -62,7 +62,7 @@ public abstract class SU { } /** - * Returns a {@link VirtualChannel} that's connected to the priviledge-escalated environment. + * Returns a {@link VirtualChannel} that's connected to the privilege-escalated environment. * * @param listener * What this method is doing (such as what process it's invoking) will be sent here. @@ -122,7 +122,7 @@ public abstract class SU { } /** - * Starts a new priviledge-escalated environment, execute a closure, and shut it down. + * Starts a new privilege-escalated environment, execute a closure, and shut it down. */ public static V execute(TaskListener listener, String rootUsername, String rootPassword, final Callable closure) throws T, IOException, InterruptedException { VirtualChannel ch = start(listener, rootUsername, rootPassword); diff --git a/core/src/main/java/hudson/os/solaris/ZFSInstaller.java b/core/src/main/java/hudson/os/solaris/ZFSInstaller.java index 17a3bb48ac264566530a1d7e462ec4e049911b40..398b0a6d54bb71b5f82862c4480c328e4ef005d8 100644 --- a/core/src/main/java/hudson/os/solaris/ZFSInstaller.java +++ b/core/src/main/java/hudson/os/solaris/ZFSInstaller.java @@ -28,11 +28,11 @@ import com.sun.akuma.JavaVMArguments; import hudson.Launcher.LocalLauncher; import hudson.Util; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.os.SU; import hudson.model.AdministrativeMonitor; import jenkins.model.Jenkins; import hudson.model.TaskListener; -import hudson.remoting.Callable; import hudson.util.ForkOutputStream; import hudson.util.HudsonIsRestarting; import hudson.util.StreamTaskListener; @@ -272,9 +272,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable JavaVMArguments args = JavaVMArguments.current(); args.setSystemProperty(ZFSInstaller.class.getName()+".migrate",datasetName); Daemon.selfExec(args); - } catch (InterruptedException e) { - LOGGER.log(Level.SEVERE, "Restart failed",e); - } catch (IOException e) { + } catch (InterruptedException | IOException e) { LOGGER.log(Level.SEVERE, "Restart failed",e); } } @@ -283,7 +281,7 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable @Extension public static AdministrativeMonitor init() { - String migrationTarget = System.getProperty(ZFSInstaller.class.getName() + ".migrate"); + String migrationTarget = SystemProperties.getString(ZFSInstaller.class.getName() + ".migrate"); if(migrationTarget!=null) { ByteArrayOutputStream out = new ByteArrayOutputStream(); StreamTaskListener listener = new StreamTaskListener(new ForkOutputStream(System.out, out)); @@ -437,5 +435,5 @@ public class ZFSInstaller extends AdministrativeMonitor implements Serializable /** * Escape hatch in case JNI calls fatally crash, like in HUDSON-3733. */ - public static boolean disabled = Boolean.getBoolean(ZFSInstaller.class.getName()+".disabled"); + public static boolean disabled = SystemProperties.getBoolean(ZFSInstaller.class.getName()+".disabled"); } diff --git a/core/src/main/java/hudson/os/solaris/ZFSProvisioner.java b/core/src/main/java/hudson/os/solaris/ZFSProvisioner.java index a2ba279f3b0c6bb58d3638ca38c77c51a0a47e23..229b5affb54e7cb9404a0f0c246381e349a0c78d 100644 --- a/core/src/main/java/hudson/os/solaris/ZFSProvisioner.java +++ b/core/src/main/java/hudson/os/solaris/ZFSProvisioner.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.io.File; import java.io.Serializable; +import org.jenkinsci.Symbol; import org.jvnet.solaris.libzfs.LibZFS; import org.jvnet.solaris.libzfs.ZFSFileSystem; @@ -59,7 +60,7 @@ public class ZFSProvisioner extends FileSystemProvisioner implements Serializabl ZFSFileSystem fs = libzfs.getFileSystemByMountPoint(f); if(fs!=null) return fs.getName(); - // TODO: for now, only support slaves that are already on ZFS. + // TODO: for now, only support agents that are already on ZFS. throw new IOException("Not on ZFS"); } }); @@ -111,7 +112,7 @@ public class ZFSProvisioner extends FileSystemProvisioner implements Serializabl throw new UnsupportedOperationException(); } - @Extension + @Extension @Symbol("zfs") public static final class DescriptorImpl extends FileSystemProvisionerDescriptor { public boolean discard(FilePath ws, TaskListener listener) throws IOException, InterruptedException { // TODO diff --git a/core/src/main/java/hudson/scheduler/BaseParser.java b/core/src/main/java/hudson/scheduler/BaseParser.java index 476bc41e5e3a98e417e497f5e0e9239658c83a40..3e43a32d7c3d343f4aa997723169f4678ed6c9ab 100644 --- a/core/src/main/java/hudson/scheduler/BaseParser.java +++ b/core/src/main/java/hudson/scheduler/BaseParser.java @@ -31,6 +31,7 @@ import antlr.Token; import antlr.TokenBuffer; import antlr.TokenStream; import antlr.TokenStreamException; +import jenkins.util.SystemProperties; /** * @author Kohsuke Kawaguchi @@ -145,7 +146,7 @@ abstract class BaseParser extends LLkParser { /** * This property hashes tokens in the cron tab tokens like @daily so that they spread evenly. */ - public static boolean HASH_TOKENS = !"false".equals(System.getProperty(BaseParser.class.getName()+".hash")); + public static boolean HASH_TOKENS = !"false".equals(SystemProperties.getString(BaseParser.class.getName()+".hash")); /** * Constant that indicates no step value. diff --git a/core/src/main/java/hudson/scheduler/CronTab.java b/core/src/main/java/hudson/scheduler/CronTab.java index dd8e0efa9d7664d313486cfddd508129d5a9b9a2..d289dc32efd0aeeb809e6663d9fcf6fb9b82ca5c 100644 --- a/core/src/main/java/hudson/scheduler/CronTab.java +++ b/core/src/main/java/hudson/scheduler/CronTab.java @@ -92,7 +92,7 @@ public final class CronTab { /** * @param timezone - * Used to schedule cron in a differnt timezone. Null to use the default system + * Used to schedule cron in a different timezone. Null to use the default system * timezone * @since 1.615 */ diff --git a/core/src/main/java/hudson/scheduler/CronTabList.java b/core/src/main/java/hudson/scheduler/CronTabList.java index 34a3c6df1e8698f9ce5c07183aea2fdf9e302d18..3243dda38e113fa50573e516230b9be82555c7c0 100644 --- a/core/src/main/java/hudson/scheduler/CronTabList.java +++ b/core/src/main/java/hudson/scheduler/CronTabList.java @@ -29,6 +29,8 @@ import java.util.TimeZone; import java.util.Collection; import java.util.Vector; import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -44,7 +46,7 @@ public final class CronTabList { private final Vector tabs; public CronTabList(Collection tabs) { - this.tabs = new Vector(tabs); + this.tabs = new Vector<>(tabs); } /** @@ -90,12 +92,12 @@ public final class CronTabList { return null; } - public static CronTabList create(String format) throws ANTLRException { + public static CronTabList create(@Nonnull String format) throws ANTLRException { return create(format,null); } - public static CronTabList create(String format, Hash hash) throws ANTLRException { - Vector r = new Vector(); + public static CronTabList create(@Nonnull String format, Hash hash) throws ANTLRException { + Vector r = new Vector<>(); int lineNumber = 0; String timezone = null; diff --git a/core/src/main/java/hudson/scm/AutoBrowserHolder.java b/core/src/main/java/hudson/scm/AutoBrowserHolder.java index 9f6dd18024f6f83aec47fc40260a5005a69a7d21..10e03cb0f64af8ffa641ffd05b65f65212f752e9 100644 --- a/core/src/main/java/hudson/scm/AutoBrowserHolder.java +++ b/core/src/main/java/hudson/scm/AutoBrowserHolder.java @@ -37,7 +37,9 @@ import jenkins.model.Jenkins; * *

* This class makes such tracking easy by hiding this logic. + * @deprecated Disabled by default: JENKINS-35098 */ +@Deprecated final class AutoBrowserHolder { private int cacheGeneration; private RepositoryBrowser cache; diff --git a/core/src/main/java/hudson/scm/ChangeLogAnnotator.java b/core/src/main/java/hudson/scm/ChangeLogAnnotator.java index ebe0227ea952b8da9e88c0bfba8e097021c13e56..c9544b69a2ffd20e52a51e85d37a7ca08ea6b932 100644 --- a/core/src/main/java/hudson/scm/ChangeLogAnnotator.java +++ b/core/src/main/java/hudson/scm/ChangeLogAnnotator.java @@ -33,8 +33,8 @@ import hudson.model.AbstractBuild; import hudson.model.Run; import hudson.scm.ChangeLogSet.Entry; import hudson.util.CopyOnWriteList; +import java.util.logging.Level; import java.util.logging.Logger; -import jenkins.model.Jenkins; /** * Performs mark up on changelog messages to be displayed. @@ -82,7 +82,7 @@ public abstract class ChangeLogAnnotator implements ExtensionPoint { if (build instanceof AbstractBuild && Util.isOverridden(ChangeLogAnnotator.class, getClass(), "annotate", AbstractBuild.class, Entry.class, MarkupText.class)) { annotate((AbstractBuild) build, change, text); } else { - throw new AbstractMethodError("You must override the newer overload of annotate"); + Logger.getLogger(ChangeLogAnnotator.class.getName()).log(Level.WARNING, "You must override the newer overload of annotate from {0}", getClass().getName()); } } diff --git a/core/src/main/java/hudson/scm/NullSCM.java b/core/src/main/java/hudson/scm/NullSCM.java index d2edf827330c8a85f1abd8174f1f462e7f800bb0..777db3759e47442b2913f62e0a18076c780e2f69 100644 --- a/core/src/main/java/hudson/scm/NullSCM.java +++ b/core/src/main/java/hudson/scm/NullSCM.java @@ -31,8 +31,8 @@ import hudson.model.Run; import hudson.model.TaskListener; import java.io.File; import java.io.IOException; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; /** * No {@link SCM}. @@ -40,6 +40,10 @@ import org.kohsuke.stapler.StaplerRequest; * @author Kohsuke Kawaguchi */ public class NullSCM extends SCM { + + @DataBoundConstructor + public NullSCM() {} + @Override public SCMRevisionState calcRevisionsFromBuild(Run build, FilePath workspace, Launcher launcher, TaskListener listener) throws IOException, InterruptedException { return null; } @@ -58,7 +62,7 @@ public class NullSCM extends SCM { return NullChangeLogParser.INSTANCE; } - @Extension(ordinal = Integer.MAX_VALUE) + @Extension(ordinal = Integer.MAX_VALUE) @Symbol("none") public static class DescriptorImpl extends SCMDescriptor { public DescriptorImpl() { super(null); @@ -68,9 +72,5 @@ public class NullSCM extends SCM { return Messages.NullSCM_DisplayName(); } - @Override - public SCM newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return new NullSCM(); - } } } diff --git a/core/src/main/java/hudson/scm/PollingResult.java b/core/src/main/java/hudson/scm/PollingResult.java index a5ec21fb4079b51b9bb17357a92f945a003baeac..39b3a0caba817158fc398b612127250641c05e7b 100644 --- a/core/src/main/java/hudson/scm/PollingResult.java +++ b/core/src/main/java/hudson/scm/PollingResult.java @@ -7,7 +7,6 @@ import hudson.FilePath; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import java.io.Serializable; /** diff --git a/core/src/main/java/hudson/scm/RepositoryBrowsers.java b/core/src/main/java/hudson/scm/RepositoryBrowsers.java index c7d8ab90daaed28b6eedcb6884e21154d54326fb..e32f0210ef42c86dd910d1542feac3ded368caf2 100644 --- a/core/src/main/java/hudson/scm/RepositoryBrowsers.java +++ b/core/src/main/java/hudson/scm/RepositoryBrowsers.java @@ -74,7 +74,10 @@ public class RepositoryBrowsers { if(value==null || value.equals("auto")) return null; - return type.cast(list.get(Integer.parseInt(value)).newInstance(req,null/*TODO*/)); + // TODO: There was a TODO in the original code, which presumes passing something meaningful to the newInstance() JSON param + // Now we just pass empty JSON in order to make the code compliant with the defined interface + final JSONObject emptyJSON = new JSONObject(); + return type.cast(list.get(Integer.parseInt(value)).newInstance(req, emptyJSON)); } /** diff --git a/core/src/main/java/hudson/scm/SCM.java b/core/src/main/java/hudson/scm/SCM.java index e7597933d093dba6072f6e823752097dc0acf173..2cf33416658b9ad63725b6ea95920e96a94aac09 100644 --- a/core/src/main/java/hudson/scm/SCM.java +++ b/core/src/main/java/hudson/scm/SCM.java @@ -58,6 +58,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; @@ -84,8 +85,13 @@ import org.kohsuke.stapler.export.ExportedBean; */ @ExportedBean public abstract class SCM implements Describable, ExtensionPoint { + + /** JENKINS-35098: discouraged */ + @SuppressWarnings("FieldMayBeFinal") + private static boolean useAutoBrowserHolder = SystemProperties.getBoolean(SCM.class.getName() + ".useAutoBrowserHolder"); /** * Stores {@link AutoBrowserHolder}. Lazily created. + * @deprecated Unused by default. */ private transient AutoBrowserHolder autoBrowserHolder; @@ -124,17 +130,21 @@ public abstract class SCM implements Describable, ExtensionPoint { * Returns the applicable {@link RepositoryBrowser} for files * controlled by this {@link SCM}. * @see #guessBrowser - * @see SCMDescriptor#isBrowserReusable */ + @SuppressWarnings("deprecation") @Exported(name="browser") public final @CheckForNull RepositoryBrowser getEffectiveBrowser() { RepositoryBrowser b = getBrowser(); if(b!=null) return b; - if(autoBrowserHolder==null) - autoBrowserHolder = new AutoBrowserHolder(this); - return autoBrowserHolder.get(); - + if (useAutoBrowserHolder) { + if (autoBrowserHolder == null) { + autoBrowserHolder = new AutoBrowserHolder(this); + } + return autoBrowserHolder.get(); + } else { + return guessBrowser(); + } } /** @@ -152,7 +162,7 @@ public abstract class SCM implements Describable, ExtensionPoint { * *

* This flag affects the behavior of Hudson when a job lost its workspace - * (typically due to a slave outage.) If this method returns false and + * (typically due to a agent outage.) If this method returns false and * polling is configured, then that would immediately trigger a new build. * *

@@ -177,9 +187,9 @@ public abstract class SCM implements Describable, ExtensionPoint { * Called before a workspace is deleted on the given node, to provide SCM an opportunity to perform clean up. * *

- * Hudson periodically scans through all the slaves and removes old workspaces that are deemed unnecessary. + * Hudson periodically scans through all the agents and removes old workspaces that are deemed unnecessary. * This behavior is implemented in {@link WorkspaceCleanupThread}, and it is necessary to control the - * disk consumption on slaves. If we don't do this, in a long run, all the slaves will have workspaces + * disk consumption on agents. If we don't do this, in a long run, all the agents will have workspaces * for all the projects, which will be prohibitive in big Hudson. * *

@@ -191,7 +201,7 @@ public abstract class SCM implements Describable, ExtensionPoint { * recursive directory deletion happens. * *

- * Note that this method does not guarantee that such a clean up will happen. For example, slaves can be + * Note that this method does not guarantee that such a clean up will happen. For example, agents can be * taken offline by being physically removed from the network, and in such a case there's no opportunity * to perform this clean up. * @@ -233,7 +243,7 @@ public abstract class SCM implements Describable, ExtensionPoint { * Checks if there has been any changes to this module in the repository. * * TODO: we need to figure out a better way to communicate an error back, - * so that we won't keep retrying the same node (for example a slave might be down.) + * so that we won't keep retrying the same node (for example an agent might be down.) * *

* If the SCM doesn't implement polling, have the {@link #supportsPolling()} method diff --git a/core/src/main/java/hudson/scm/SCMDescriptor.java b/core/src/main/java/hudson/scm/SCMDescriptor.java index 242ad88c6d518ca9f43919b39e47c47dad9e6aa2..9929e95d3ae7a06f35fec779d4fb1ed39e775997 100644 --- a/core/src/main/java/hudson/scm/SCMDescriptor.java +++ b/core/src/main/java/hudson/scm/SCMDescriptor.java @@ -53,7 +53,9 @@ public abstract class SCMDescriptor extends Descriptor { * This is used to invalidate cache of {@link SCM#getEffectiveBrowser}. Due to the lack of synchronization and serialization, * this field doesn't really count the # of instances created to date, * but it's good enough for the cache invalidation. + * @deprecated No longer used by default. */ + @Deprecated public volatile int generation = 1; protected SCMDescriptor(Class clazz, Class repositoryBrowser) { @@ -102,7 +104,9 @@ public abstract class SCMDescriptor extends Descriptor { * @return * true if the two given SCM configurations are similar enough * that they can reuse {@link RepositoryBrowser} between them. + * @deprecated No longer used by default. {@link SCM#getKey} could be used to implement similar features if needed. */ + @Deprecated public boolean isBrowserReusable(T x, T y) { return false; } diff --git a/core/src/main/java/hudson/scm/SCMS.java b/core/src/main/java/hudson/scm/SCMS.java index e79af364de0155313afcd770524439d8356cb410..5a821eb1fc52adb8a5e2ca6c3ecbdd322c0cf3a7 100644 --- a/core/src/main/java/hudson/scm/SCMS.java +++ b/core/src/main/java/hudson/scm/SCMS.java @@ -54,14 +54,14 @@ public class SCMS { * @param target * The project for which this SCM is configured to. */ + @SuppressWarnings("deprecation") public static SCM parseSCM(StaplerRequest req, AbstractProject target) throws FormException, ServletException { - String scm = req.getParameter("scm"); - if(scm==null) return new NullSCM(); - - int scmidx = Integer.parseInt(scm); - SCMDescriptor d = SCM._for(target).get(scmidx); - d.generation++; - return d.newInstance(req, req.getSubmittedForm().getJSONObject("scm")); + SCM scm = SCM.all().newInstanceFromRadioList(req.getSubmittedForm().getJSONObject("scm")); + if (scm == null) { + scm = new NullSCM(); // JENKINS-36043 workaround for AbstractMultiBranchProject.submit + } + scm.getDescriptor().generation++; + return scm; } /** diff --git a/core/src/main/java/hudson/search/SearchFactory.java b/core/src/main/java/hudson/search/SearchFactory.java index 850672ffe9fc8ba61609a5ec8c865284f4217903..0e1290addb6a21eb0c4116e3c45ae4620230d427 100644 --- a/core/src/main/java/hudson/search/SearchFactory.java +++ b/core/src/main/java/hudson/search/SearchFactory.java @@ -3,7 +3,6 @@ package hudson.search; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; /** * Creates a {@link Search} instance for a {@link SearchableModelObject}. diff --git a/core/src/main/java/hudson/search/SearchResult.java b/core/src/main/java/hudson/search/SearchResult.java index 927fced6483d0ca165d1ca5f2e8e5cf0387122e3..2d6cdb1d656220362a8d976a74daaf6f036a19d5 100644 --- a/core/src/main/java/hudson/search/SearchResult.java +++ b/core/src/main/java/hudson/search/SearchResult.java @@ -3,7 +3,7 @@ package hudson.search; import java.util.List; /** - * @author Nicolas De Loof + * @author Nicolas De Loof */ public interface SearchResult extends List { diff --git a/core/src/main/java/hudson/search/UserSearchProperty.java b/core/src/main/java/hudson/search/UserSearchProperty.java index bae9fa1da3be5457ae1e0248ba2b181c9c6f44e1..3d74013d3bbd7c45b17e9490d4d2db1d636e22e4 100644 --- a/core/src/main/java/hudson/search/UserSearchProperty.java +++ b/core/src/main/java/hudson/search/UserSearchProperty.java @@ -6,6 +6,7 @@ import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.export.Exported; @@ -32,7 +33,7 @@ public class UserSearchProperty extends hudson.model.UserProperty { } - @Extension + @Extension @Symbol("search") public static final class DescriptorImpl extends UserPropertyDescriptor { public String getDisplayName() { return Messages.UserSearchProperty_DisplayName(); diff --git a/core/src/main/java/hudson/security/ACL.java b/core/src/main/java/hudson/security/ACL.java index b0ed675d8be6f884ec163e366cfdcdd85e989884..2febef6650cc90e4787b34fd3f7c8ab6e7630b56 100644 --- a/core/src/main/java/hudson/security/ACL.java +++ b/core/src/main/java/hudson/security/ACL.java @@ -23,6 +23,11 @@ */ package hudson.security; +import hudson.model.User; +import hudson.model.View; +import hudson.model.ViewDescriptor; +import hudson.model.ViewGroup; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import hudson.model.Item; @@ -91,7 +96,7 @@ public abstract class ACL { * @param d the descriptor of the item to be created. * @throws AccessDeniedException * if the user doesn't have the permission. - * @since TODO + * @since 1.607 */ public final void checkCreatePermission(@Nonnull ItemGroup c, @Nonnull TopLevelItemDescriptor d) { @@ -111,13 +116,49 @@ public abstract class ACL { * @param d the descriptor of the item to be created. * @return false * if the user doesn't have the permission. - * @since TODO + * @since 1.607 */ public boolean hasCreatePermission(@Nonnull Authentication a, @Nonnull ItemGroup c, @Nonnull TopLevelItemDescriptor d) { return true; } + /** + * Checks if the current security principal has the permission to create views within the specified view group. + *

+ * This is just a convenience function. + * + * @param c the container of the item. + * @param d the descriptor of the view to be created. + * @throws AccessDeniedException if the user doesn't have the permission. + * @since 1.607 + */ + public final void checkCreatePermission(@Nonnull ViewGroup c, + @Nonnull ViewDescriptor d) { + Authentication a = Jenkins.getAuthentication(); + if (!hasCreatePermission(a, c, d)) { + throw new AccessDeniedException(Messages.AccessDeniedException2_MissingPermission(a.getName(), + View.CREATE.group.title + "/" + View.CREATE.name + View.CREATE + "/" + d.getDisplayName())); + } + } + + /** + * Checks if the given principal has the permission to create views within the specified view group. + *

+ * Note that {@link #SYSTEM} can be passed in as the authentication parameter, + * in which case you should probably just assume it can create anything anywhere. + * @param a the principal. + * @param c the container of the view. + * @param d the descriptor of the view to be created. + * @return false + * if the user doesn't have the permission. + * @since 2.37 + */ + public boolean hasCreatePermission(@Nonnull Authentication a, @Nonnull ViewGroup c, + @Nonnull ViewDescriptor d) { + return true; + } + // // Sid constants // @@ -127,7 +168,7 @@ public abstract class ACL { * *

* This doesn't need to be included in {@link Authentication#getAuthorities()}, - * but {@link ACL} is responsible for checking it nontheless, as if it was the + * but {@link ACL} is responsible for checking it nonetheless, as if it was the * last entry in the granted authority. */ public static final Sid EVERYONE = new Sid() { @@ -179,7 +220,9 @@ public abstract class ACL { * We need to create a new {@link SecurityContext} instead of {@link SecurityContext#setAuthentication(Authentication)} * because the same {@link SecurityContext} object is reused for all the concurrent requests from the same session. * @since 1.462 + * @deprecated use try with resources and {@link #as(Authentication)} */ + @Deprecated public static @Nonnull SecurityContext impersonate(@Nonnull Authentication auth) { SecurityContext old = SecurityContextHolder.getContext(); SecurityContextHolder.setContext(new NonSerializableSecurityContext(auth)); @@ -191,7 +234,9 @@ public abstract class ACL { * @param auth authentication, such as {@link #SYSTEM} * @param body an action to run with this alternate authentication in effect * @since 1.509 + * @deprecated use try with resources and {@link #as(Authentication)} */ + @Deprecated public static void impersonate(@Nonnull Authentication auth, @Nonnull Runnable body) { SecurityContext old = impersonate(auth); try { @@ -206,7 +251,9 @@ public abstract class ACL { * @param auth authentication, such as {@link #SYSTEM} * @param body an action to run with this alternate authentication in effect (try {@link NotReallyRoleSensitiveCallable}) * @since 1.587 + * @deprecated use try with resources and {@link #as(Authentication)} */ + @Deprecated public static V impersonate(Authentication auth, Callable body) throws T { SecurityContext old = impersonate(auth); try { @@ -216,4 +263,47 @@ public abstract class ACL { } } + /** + * Changes the {@link Authentication} associated with the current thread to the specified one and returns an + * {@link AutoCloseable} that restores the previous security context. + * + *

+ * This makes impersonation much easier within code as it can now be used using the try with resources construct: + *

+     *     try (ACLContext _ = ACL.as(auth)) {
+     *        ...
+     *     }
+     * 
+ * @param auth the new authentication. + * @return the previous authentication context + * @since 2.14 + */ + @Nonnull + public static ACLContext as(@Nonnull Authentication auth) { + final ACLContext context = new ACLContext(SecurityContextHolder.getContext()); + SecurityContextHolder.setContext(new NonSerializableSecurityContext(auth)); + return context; + } + + /** + * Changes the {@link Authentication} associated with the current thread to the specified one and returns an + * {@link AutoCloseable} that restores the previous security context. + * + *

+ * This makes impersonation much easier within code as it can now be used using the try with resources construct: + *

+     *     try (ACLContext _ = ACL.as(auth)) {
+     *        ...
+     *     }
+     * 
+ * + * @param user the user to impersonate. + * @return the previous authentication context + * @since 2.14 + */ + @Nonnull + public static ACLContext as(@CheckForNull User user) { + return as(user == null ? Jenkins.ANONYMOUS : user.impersonate()); + } + } diff --git a/core/src/main/java/hudson/security/ACLContext.java b/core/src/main/java/hudson/security/ACLContext.java new file mode 100644 index 0000000000000000000000000000000000000000..95c333769289390146cfdc00da6f79c70f8a3dca --- /dev/null +++ b/core/src/main/java/hudson/security/ACLContext.java @@ -0,0 +1,67 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.security; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import org.acegisecurity.Authentication; +import org.acegisecurity.context.SecurityContext; +import org.acegisecurity.context.SecurityContextHolder; + +/** + * A {@link AutoCloseable} that captures the previous {@link SecurityContext} and restores it on {@link #close()} + * + * @since 2.14 + */ +public class ACLContext implements AutoCloseable { + + /** + * The previous context. + */ + @Nonnull + private final SecurityContext previousContext; + + /** + * Private constructor to ensure only instance creation is from {@link ACL#as(Authentication)}. + * @param previousContext the previous context + */ + ACLContext(@Nonnull SecurityContext previousContext) { + this.previousContext = previousContext; + } + + /** + * Accessor for the previous context. + * @return the previous context. + */ + @Nonnull + public SecurityContext getPreviousContext() { + return previousContext; + } + + /** {@inheritDoc} */ + @Override + public void close() { + SecurityContextHolder.setContext(previousContext); + } +} diff --git a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java index de1a0cb3ce99e9a65688ced2df173602e9bf92e2..bda002cf106fd51e1c09345ae1b3f160759e3466 100644 --- a/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java +++ b/core/src/main/java/hudson/security/AuthenticationProcessingFilter2.java @@ -53,7 +53,7 @@ public class AuthenticationProcessingFilter2 extends AuthenticationProcessingFil if (targetUrl == null) return getDefaultTargetUrl(); - if (Util.isAbsoluteUri(targetUrl)) + if (!Util.isSafeToRedirectTo(targetUrl)) return "."; // avoid open redirect // URL returned from determineTargetUrl() is resolved against the context path, diff --git a/core/src/main/java/hudson/security/AuthorizationStrategy.java b/core/src/main/java/hudson/security/AuthorizationStrategy.java index f544e8ad300ad4ebe01dbe6f7ca9206e944e5a7f..a875908f212d7ec472f589dad9a27f93090e9260 100644 --- a/core/src/main/java/hudson/security/AuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/AuthorizationStrategy.java @@ -39,6 +39,7 @@ import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.acegisecurity.Authentication; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; /** @@ -231,7 +232,7 @@ public abstract class AuthorizationStrategy extends AbstractDescribableImpl { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java index 8d18afff06274a2f6e1be20ea75f85b0a7f2de1d..3e055d25847292dbf4ba9276021976db3f8fefdf 100644 --- a/core/src/main/java/hudson/security/BasicAuthenticationFilter.java +++ b/core/src/main/java/hudson/security/BasicAuthenticationFilter.java @@ -28,8 +28,6 @@ import jenkins.model.Jenkins; import hudson.util.Scrambler; import jenkins.security.ApiTokenProperty; import org.acegisecurity.context.SecurityContextHolder; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -135,7 +133,9 @@ public class BasicAuthenticationFilter implements Filter { } {// attempt to authenticate as API token - User u = User.get(username); + // create is true as the user may not have been saved and the default api token may be in use. + // validation of the user will be performed against the underlying realm in impersonate. + User u = User.getById(username, true); ApiTokenProperty t = u.getProperty(ApiTokenProperty.class); if (t!=null && t.matchesPassword(password)) { SecurityContextHolder.getContext().setAuthentication(u.impersonate()); diff --git a/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java b/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java index c9808c43712e6a9f159affbc5af0a69d5687aa9b..9c009f3ae6c682c580a3bf9b5bccd07a19d0a1b9 100644 --- a/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/FullControlOnceLoggedInAuthorizationStrategy.java @@ -23,50 +23,84 @@ */ package hudson.security; +import hudson.Extension; import hudson.model.Descriptor; import jenkins.model.Jenkins; -import hudson.Extension; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import javax.inject.Inject; import java.util.Collections; import java.util.List; -import net.sf.json.JSONObject; - -import org.kohsuke.stapler.StaplerRequest; - /** * {@link AuthorizationStrategy} that grants full-control to authenticated user - * (other than anonymous users.) + * and optionally read access to anonymous users * * @author Kohsuke Kawaguchi */ public class FullControlOnceLoggedInAuthorizationStrategy extends AuthorizationStrategy { + /** + * Whether to allow anonymous read access, for backward compatibility + * default is to allow it + */ + private boolean denyAnonymousReadAccess = false; + + @DataBoundConstructor + public FullControlOnceLoggedInAuthorizationStrategy() { + } + @Override public ACL getRootACL() { - return THE_ACL; + return denyAnonymousReadAccess ? AUTHENTICATED_READ : ANONYMOUS_READ; } public List getGroups() { return Collections.emptyList(); } + + /** + * If true, anonymous read access will be allowed + */ + public boolean isAllowAnonymousRead() { + return !denyAnonymousReadAccess; + } + + @DataBoundSetter + public void setAllowAnonymousRead(boolean allowAnonymousRead) { + this.denyAnonymousReadAccess = !allowAnonymousRead; + } - private static final SparseACL THE_ACL = new SparseACL(null); + private static final SparseACL AUTHENTICATED_READ = new SparseACL(null); + private static final SparseACL ANONYMOUS_READ = new SparseACL(null); static { - THE_ACL.add(ACL.EVERYONE, Jenkins.ADMINISTER,true); - THE_ACL.add(ACL.ANONYMOUS, Jenkins.ADMINISTER,false); - THE_ACL.add(ACL.ANONYMOUS,Permission.READ,true); + ANONYMOUS_READ.add(ACL.EVERYONE, Jenkins.ADMINISTER,true); + ANONYMOUS_READ.add(ACL.ANONYMOUS, Jenkins.ADMINISTER,false); + ANONYMOUS_READ.add(ACL.ANONYMOUS, Permission.READ,true); + + AUTHENTICATED_READ.add(ACL.EVERYONE, Jenkins.ADMINISTER, true); + AUTHENTICATED_READ.add(ACL.ANONYMOUS, Jenkins.ADMINISTER, false); } - @Extension - public static final Descriptor DESCRIPTOR = new Descriptor() { - public String getDisplayName() { - return Messages.FullControlOnceLoggedInAuthorizationStrategy_DisplayName(); + /** + * @deprecated as of 1.643 + * Inject descriptor via {@link Inject}. + */ + @Restricted(NoExternalUse.class) + public static Descriptor DESCRIPTOR; + + @Extension @Symbol("loggedInUsersCanDoAnything") + public static class DescriptorImpl extends Descriptor { + public DescriptorImpl() { + DESCRIPTOR = this; } - @Override - public AuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return new FullControlOnceLoggedInAuthorizationStrategy(); + public String getDisplayName() { + return Messages.FullControlOnceLoggedInAuthorizationStrategy_DisplayName(); } - }; + } } diff --git a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java index de5deceebd35155d03c3e1e7e9ab0939983f4be5..c6db287dffbc40201731b4dfcbdedad64eb7d2ec 100644 --- a/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java +++ b/core/src/main/java/hudson/security/GlobalSecurityConfiguration.java @@ -35,6 +35,8 @@ import hudson.model.ManagementLink; import hudson.util.FormApply; import java.io.IOException; +import java.util.Set; +import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,8 +45,13 @@ import javax.servlet.ServletException; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import jenkins.util.ServerTcpPort; +import net.sf.json.JSONArray; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -55,7 +62,7 @@ import org.kohsuke.stapler.StaplerResponse; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal = Integer.MAX_VALUE - 210) +@Extension(ordinal = Integer.MAX_VALUE - 210) @Symbol("securityConfig") public class GlobalSecurityConfiguration extends ManagementLink implements Describable { private static final Logger LOGGER = Logger.getLogger(GlobalSecurityConfiguration.class.getName()); @@ -68,6 +75,19 @@ public class GlobalSecurityConfiguration extends ManagementLink implements Descr return Jenkins.getInstance().getSlaveAgentPort(); } + /** + * @since 2.24 + * @return true if the slave agent port is enforced on this instance. + */ + @Restricted(DoNotUse.class) // only for index.groovy + public boolean isSlaveAgentPortEnforced() { + return Jenkins.getInstance().isSlaveAgentPortEnforced(); + } + + public Set getAgentProtocols() { + return Jenkins.getInstance().getAgentProtocols(); + } + public boolean isDisableRememberMe() { return Jenkins.getInstance().isDisableRememberMe(); } @@ -99,6 +119,18 @@ public class GlobalSecurityConfiguration extends ManagementLink implements Descr } catch (IOException e) { throw new hudson.model.Descriptor.FormException(e, "slaveAgentPortType"); } + Set agentProtocols = new TreeSet<>(); + if (security.has("agentProtocol")) { + Object protocols = security.get("agentProtocol"); + if (protocols instanceof JSONArray) { + for (int i = 0; i < ((JSONArray) protocols).size(); i++) { + agentProtocols.add(((JSONArray) protocols).getString(i)); + } + } else { + agentProtocols.add(protocols.toString()); + } + } + j.setAgentProtocols(agentProtocols); } else { j.disableSecurity(); } @@ -167,7 +199,7 @@ public class GlobalSecurityConfiguration extends ManagementLink implements Descr return Jenkins.getInstance().getDescriptorOrDie(getClass()); } - @Extension + @Extension @Symbol("security") public static final class DescriptorImpl extends Descriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java index 30f386eb1fa086e1183a7092aa96fdcc81b033cf..b590dce40842558b814c84d65a179261b08374f7 100644 --- a/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java +++ b/core/src/main/java/hudson/security/HudsonAuthenticationEntryPoint.java @@ -24,8 +24,6 @@ package hudson.security; import hudson.Functions; -import jenkins.model.Jenkins; -import hudson.TcpSlaveAgentListener; import com.google.common.base.Strings; import org.acegisecurity.AuthenticationException; diff --git a/core/src/main/java/hudson/security/HudsonFilter.java b/core/src/main/java/hudson/security/HudsonFilter.java index 3a1868344a71babec7d6ab4a09e9e6dcb225f2af..b37b2ea4ea4ea3106f42cc515f1f497ec2109b0c 100644 --- a/core/src/main/java/hudson/security/HudsonFilter.java +++ b/core/src/main/java/hudson/security/HudsonFilter.java @@ -104,7 +104,7 @@ public class HudsonFilter implements Filter { // this is how we make us available to the rest of Hudson. filterConfig.getServletContext().setAttribute(HudsonFilter.class.getName(),this); try { - Jenkins hudson = Jenkins.getInstance(); + Jenkins hudson = Jenkins.getInstanceOrNull(); if (hudson != null) { // looks like we are initialized after Hudson came into being. initialize it now. See #3069 LOGGER.fine("Security wasn't initialized; Initializing it..."); diff --git a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java index ad09166da5fc92a6aae890f1336652e0da0c5c86..ca95fba12940d941dfb515a2ccaa7b83ee826d89 100644 --- a/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java +++ b/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.java @@ -1,18 +1,18 @@ /* * The MIT License - * + * * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, David Calavera, Seiji Sogabe - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -52,6 +52,7 @@ import org.acegisecurity.providers.encoding.PasswordEncoder; import org.acegisecurity.providers.encoding.ShaPasswordEncoder; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.ForwardToView; import org.kohsuke.stapler.HttpResponse; @@ -79,7 +80,6 @@ import java.util.Collections; import java.util.List; import java.util.MissingResourceException; import java.util.ResourceBundle; -import java.util.logging.Level; import java.util.logging.Logger; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -97,7 +97,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea /** * If true, sign up is not allowed. *

- * This is a negative switch so that the default value 'false' remains compatible with older installations. + * This is a negative switch so that the default value 'false' remains compatible with older installations. */ private final boolean disableSignup; @@ -169,7 +169,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea @Override public Details loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - User u = User.get(username,false); + User u = User.getById(username, false); Details p = u!=null ? u.getProperty(Details.class) : null; if(p==null) throw new UsernameNotFoundException("Password is not set: "+username); @@ -260,16 +260,26 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea } /** - * Creates an user account. Used by admins. + * Creates a user account. Used by admins. * * This version behaves differently from {@link #doCreateAccount(StaplerRequest, StaplerResponse)} in that * this is someone creating another user. */ public void doCreateAccountByAdmin(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + createAccountByAdmin(req, rsp, "addUser.jelly", "."); // send the user back to the listing page on success + } + + /** + * Creates a user account. Requires {@link Jenkins#ADMINISTER} + */ + @Restricted(NoExternalUse.class) + public User createAccountByAdmin(StaplerRequest req, StaplerResponse rsp, String addUserView, String successView) throws IOException, ServletException { checkPermission(Jenkins.ADMINISTER); - if(createAccount(req, rsp, false, "addUser.jelly")!=null) { - rsp.sendRedirect("."); // send the user back to the listing page + User u = createAccount(req, rsp, false, addUserView); + if(u != null) { + rsp.sendRedirect(successView); } + return u; } /** @@ -324,7 +334,8 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea if(si.username==null || si.username.length()==0) si.errorMessage = Messages.HudsonPrivateSecurityRealm_CreateAccount_UserNameRequired(); else { - User user = User.get(si.username, false); + // do not create the user - we just want to check if the user already exists but is not a "login" user. + User user = User.getById(si.username, false); if (null != user) // Allow sign up. SCM people has no such property. if (user.getProperty(Details.class) != null) @@ -334,7 +345,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea if(si.fullname==null || si.fullname.length()==0) si.fullname = si.username; - if(si.email==null || !si.email.contains("@")) + if(isMailerPluginPresent() && (si.email==null || !si.email.contains("@"))) si.errorMessage = Messages.HudsonPrivateSecurityRealm_CreateAccount_InvalidEmailAddress(); if (! User.isIdOrFullnameAllowed(si.username)) { @@ -355,25 +366,36 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea // register the user User user = createAccount(si.username,si.password1); user.setFullName(si.fullname); - try { - // legacy hack. mail support has moved out to a separate plugin - Class up = Jenkins.getInstance().pluginManager.uberClassLoader.loadClass("hudson.tasks.Mailer$UserProperty"); - Constructor c = up.getDeclaredConstructor(String.class); - user.addProperty((UserProperty)c.newInstance(si.email)); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - LOGGER.log(Level.WARNING, "Failed to set the e-mail address",e); + if(isMailerPluginPresent()) { + try { + // legacy hack. mail support has moved out to a separate plugin + Class up = Jenkins.getInstance().pluginManager.uberClassLoader.loadClass("hudson.tasks.Mailer$UserProperty"); + Constructor c = up.getDeclaredConstructor(String.class); + user.addProperty((UserProperty)c.newInstance(si.email)); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } } user.save(); return user; } + + @Restricted(NoExternalUse.class) + public boolean isMailerPluginPresent() { + try { + // mail support has moved to a separate plugin + return null != Jenkins.getInstance().pluginManager.uberClassLoader.loadClass("hudson.tasks.Mailer$UserProperty"); + } catch (ClassNotFoundException e) { + LOGGER.finer("Mailer plugin not present"); + } + return false; + } /** * Creates a new user account by registering a password to the user. */ public User createAccount(String userName, String password) throws IOException { - User user = User.get(userName); + User user = User.getById(userName, true); user.addProperty(Details.fromPlainPassword(password)); return user; } @@ -416,7 +438,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea * This in turn helps us set up the right navigation breadcrumb. */ public User getUser(String id) { - return User.get(id); + return User.getById(id, true); } // TODO @@ -539,18 +561,19 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea } } - @Extension + @Extension @Symbol("password") public static final class DescriptorImpl extends UserPropertyDescriptor { + @Override public String getDisplayName() { - // this feature is only when HudsonPrivateSecurityRealm is enabled - if(isEnabled()) - return Messages.HudsonPrivateSecurityRealm_Details_DisplayName(); - else - return null; + return Messages.HudsonPrivateSecurityRealm_Details_DisplayName(); } @Override public Details newInstance(StaplerRequest req, JSONObject formData) throws FormException { + if (req == null) { + // Should never happen, see newInstance() Javadoc + throw new FormException("Stapler request is missing in the call", "staplerRequest"); + } String pwd = Util.fixEmpty(req.getParameter("user.password")); String pwd2= Util.fixEmpty(req.getParameter("user.password2")); @@ -568,6 +591,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea @Override public boolean isEnabled() { + // this feature is only when HudsonPrivateSecurityRealm is enabled return Jenkins.getInstance().getSecurityRealm() instanceof HudsonPrivateSecurityRealm; } @@ -581,7 +605,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea * Displays "manage users" link in the system config if {@link HudsonPrivateSecurityRealm} * is in effect. */ - @Extension + @Extension @Symbol("localUsers") public static final class ManageUserLinks extends ManagementLink { public String getIconFileName() { if(Jenkins.getInstance().getSecurityRealm() instanceof HudsonPrivateSecurityRealm) @@ -692,7 +716,7 @@ public class HudsonPrivateSecurityRealm extends AbstractPasswordBasedSecurityRea private static final String JBCRYPT_HEADER = "#jbcrypt:"; }; - @Extension + @Extension @Symbol("local") public static final class DescriptorImpl extends Descriptor { public String getDisplayName() { return Messages.HudsonPrivateSecurityRealm_DisplayName(); diff --git a/core/src/main/java/hudson/security/LegacyAuthorizationStrategy.java b/core/src/main/java/hudson/security/LegacyAuthorizationStrategy.java index f9a50993f1734de6f11407804b8562a1f890a969..5bc470d78a5b18a161babb53332fc2f3258f0247 100644 --- a/core/src/main/java/hudson/security/LegacyAuthorizationStrategy.java +++ b/core/src/main/java/hudson/security/LegacyAuthorizationStrategy.java @@ -23,12 +23,12 @@ */ package hudson.security; +import hudson.Extension; import hudson.model.Descriptor; import jenkins.model.Jenkins; -import hudson.Extension; import org.acegisecurity.acls.sid.GrantedAuthoritySid; -import org.kohsuke.stapler.StaplerRequest; -import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; import java.util.Collection; import java.util.Collections; @@ -43,6 +43,10 @@ public final class LegacyAuthorizationStrategy extends AuthorizationStrategy { add(new GrantedAuthoritySid("admin"), Jenkins.ADMINISTER,true); }}; + @DataBoundConstructor + public LegacyAuthorizationStrategy() { + } + public ACL getRootACL() { return LEGACY_ACL; } @@ -51,14 +55,10 @@ public final class LegacyAuthorizationStrategy extends AuthorizationStrategy { return Collections.singleton("admin"); } - @Extension + @Extension @Symbol("legacy") public static final class DescriptorImpl extends Descriptor { public String getDisplayName() { return Messages.LegacyAuthorizationStrategy_DisplayName(); } - - public LegacyAuthorizationStrategy newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return new LegacyAuthorizationStrategy(); - } } } diff --git a/core/src/main/java/hudson/security/LegacySecurityRealm.java b/core/src/main/java/hudson/security/LegacySecurityRealm.java index 1ce175185e7ec6c2b4e52a1c6c2bb59217eaec46..116e50b2c9e237aaa3bc409ba060f978f01c14c8 100644 --- a/core/src/main/java/hudson/security/LegacySecurityRealm.java +++ b/core/src/main/java/hudson/security/LegacySecurityRealm.java @@ -26,6 +26,9 @@ package hudson.security; import org.acegisecurity.AuthenticationManager; import org.acegisecurity.Authentication; import org.acegisecurity.AuthenticationException; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.springframework.web.context.WebApplicationContext; import org.kohsuke.stapler.StaplerRequest; import groovy.lang.Binding; @@ -88,8 +91,19 @@ public final class LegacySecurityRealm extends SecurityRealm implements Authenti return (Filter) context.getBean("legacy"); } - @Extension - public static final Descriptor DESCRIPTOR = new Descriptor() { + /** + * @deprecated as of 2.0 + * Don't use this field, use injection. + */ + @Restricted(NoExternalUse.class) + public static /*almost final*/ Descriptor DESCRIPTOR; + + @Extension @Symbol("legacy") + public static class DescriptorImpl extends Descriptor { + public DescriptorImpl() { + DESCRIPTOR = this; + } + public SecurityRealm newInstance(StaplerRequest req, JSONObject formData) throws FormException { return new LegacySecurityRealm(); } diff --git a/core/src/main/java/hudson/security/PermissionAdder.java b/core/src/main/java/hudson/security/PermissionAdder.java index 9c6186e667eca5486ed1944be4ee74f5e3da19f4..1e963fa0702ce7be4ea14619937c111e7d67725a 100644 --- a/core/src/main/java/hudson/security/PermissionAdder.java +++ b/core/src/main/java/hudson/security/PermissionAdder.java @@ -26,7 +26,6 @@ package hudson.security; import hudson.ExtensionPoint; import hudson.model.User; -import jenkins.model.Jenkins; /** * Service which can add permissions for a given user to the configured authorization strategy. diff --git a/core/src/main/java/hudson/security/PermissionScope.java b/core/src/main/java/hudson/security/PermissionScope.java index c647b33e2ccbd10ea4b03099f52f8b9b815e0d12..cf258d62ead74ff5e036cbda94536cc9c637426f 100644 --- a/core/src/main/java/hudson/security/PermissionScope.java +++ b/core/src/main/java/hudson/security/PermissionScope.java @@ -29,6 +29,8 @@ import hudson.model.Computer; import hudson.model.Item; import hudson.model.ItemGroup; import hudson.model.Job; +import hudson.model.ModelObject; +import hudson.model.Node; import hudson.model.Run; import jenkins.model.Jenkins; @@ -56,7 +58,7 @@ public final class PermissionScope { /** * Domain model type that approximates this scope. */ - public final Class modelClass; + public final Class modelClass; /** * Other bigger scopes that this scope divides. For example, permissions scoped to {@link ItemGroup} @@ -65,7 +67,7 @@ public final class PermissionScope { */ private final Set containers; - public PermissionScope(Class modelClass, PermissionScope... containers) { + public PermissionScope(Class modelClass, PermissionScope... containers) { this.modelClass = modelClass; this.containers = ImmutableSet.copyOf(containers); } @@ -110,7 +112,7 @@ public final class PermissionScope { public static final PermissionScope RUN = new PermissionScope(Run.class,ITEM); /** - * Permissions scoped to current instances of {@link Computer}s. + * Permissions scoped to {@link Node}s or {@link Computer}s (generally interchangeably). */ public static final PermissionScope COMPUTER = new PermissionScope(Computer.class,JENKINS); } diff --git a/core/src/main/java/hudson/security/SecurityRealm.java b/core/src/main/java/hudson/security/SecurityRealm.java index 3c598632ab639105308670049c3aa0e0d5069ee9..ade4465c177754948dc62a8a9d7d8252287ca58f 100644 --- a/core/src/main/java/hudson/security/SecurityRealm.java +++ b/core/src/main/java/hudson/security/SecurityRealm.java @@ -48,6 +48,9 @@ import static org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices.ACEGI import org.acegisecurity.userdetails.UserDetailsService; import org.acegisecurity.userdetails.UserDetails; import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; @@ -62,6 +65,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpSession; import javax.servlet.http.Cookie; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; import java.util.logging.Logger; @@ -202,6 +206,7 @@ public abstract class SecurityRealm extends AbstractDescribableImplconfig.jelly and never with * global.jelly. */ + @Override public Descriptor getDescriptor() { return super.getDescriptor(); } @@ -357,7 +362,7 @@ public abstract class SecurityRealm extends AbstractDescribableImpl paramNames = request.getParameterNames(); - while (paramNames.hasMoreElements()) { - String paramName = (String) paramNames.nextElement(); - if (crumbFieldName.equals(paramName)) { - crumb = request.getParameter(paramName); - break; - } - } + // compatibility for clients that hard-code the default crumb name up to Jenkins 1.TODO + extractCrumbFromRequest(httpRequest, ".crumb"); } if (crumb != null) { if (crumbIssuer.validateCrumb(httpRequest, crumbSalt, crumb)) { @@ -80,8 +75,8 @@ public class CrumbFilter implements Filter { LOGGER.log(Level.WARNING, "Found invalid crumb {0}. Will check remaining parameters for a valid one...", crumb); } } - // Multipart requests need to be handled by each handler. - if (valid || isMultipart(httpRequest)) { + + if (valid) { chain.doFilter(request, response); } else { LOGGER.log(Level.WARNING, "No valid crumb was included in request for {0}. Returning {1}.", new Object[] {httpRequest.getRequestURI(), HttpServletResponse.SC_FORBIDDEN}); @@ -92,33 +87,33 @@ public class CrumbFilter implements Filter { } } - protected static boolean isMultipart(HttpServletRequest request) { - if (request == null) { - return false; - } - - String contentType = request.getContentType(); - if (contentType == null) { - return false; + private String extractCrumbFromRequest(HttpServletRequest httpRequest, String crumbFieldName) { + String crumb = httpRequest.getHeader(crumbFieldName); + if (crumb == null) { + Enumeration paramNames = httpRequest.getParameterNames(); + while (paramNames.hasMoreElements()) { + String paramName = (String) paramNames.nextElement(); + if (crumbFieldName.equals(paramName)) { + crumb = httpRequest.getParameter(paramName); + break; + } + } } + return crumb; + } - String[] parts = contentType.split(";"); - if (parts.length == 0) { + protected static boolean isMultipart(HttpServletRequest request) { + if (request == null) { return false; } - for (int i = 0; i < parts.length; i++) { - if ("multipart/form-data".equals(parts[i])) { - return true; - } - } - - return false; + return MultipartFormDataParser.isMultiPartForm(request.getContentType()); } /** * {@inheritDoc} */ + @Override public void destroy() { } diff --git a/core/src/main/java/hudson/security/csrf/CrumbIssuer.java b/core/src/main/java/hudson/security/csrf/CrumbIssuer.java index 6daacd364da1b3d6942ce9df369f07389a0fe499..349e69a136b62152d767aadf1ba429d1d275841c 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbIssuer.java +++ b/core/src/main/java/hudson/security/csrf/CrumbIssuer.java @@ -44,6 +44,9 @@ public abstract class CrumbIssuer implements Describable, Extension private static final String CRUMB_ATTRIBUTE = CrumbIssuer.class.getName() + "_crumb"; + @Restricted(NoExternalUse.class) + public static final String DEFAULT_CRUMB_NAME = "Jenkins-Crumb"; + /** * Get the name of the request parameter the crumb will be stored in. Exposed * here for the remote API. @@ -199,7 +202,7 @@ public abstract class CrumbIssuer implements Describable, Extension } else if ("concat(//crumbRequestField,\":\",//crumb)".equals(xpath)) { // new FullDuplexHttpStream; Main text = ci.getCrumbRequestField() + ':' + ci.getCrumb(); } else if ("concat(//crumbRequestField,'=',//crumb)".equals(xpath)) { // NetBeans - if (ci.getCrumbRequestField().startsWith(".")) { + if (ci.getCrumbRequestField().startsWith(".") || ci.getCrumbRequestField().contains("-")) { text = ci.getCrumbRequestField() + '=' + ci.getCrumb(); } else { text = null; @@ -208,12 +211,9 @@ public abstract class CrumbIssuer implements Describable, Extension text = null; } if (text != null) { - OutputStream o = rsp.getCompressedOutputStream(req); - try { + try (OutputStream o = rsp.getCompressedOutputStream(req)) { rsp.setContentType("text/plain;charset=UTF-8"); o.write(text.getBytes("UTF-8")); - } finally { - o.close(); } } else { super.doXml(req, rsp, xpath, wrapper, tree, depth); diff --git a/core/src/main/java/hudson/security/csrf/CrumbIssuerDescriptor.java b/core/src/main/java/hudson/security/csrf/CrumbIssuerDescriptor.java index 013405b66adfa0b0fb470236830993fb8253db9f..84d9fb5c16de5b5dd300ad7506f0d421c2414403 100644 --- a/core/src/main/java/hudson/security/csrf/CrumbIssuerDescriptor.java +++ b/core/src/main/java/hudson/security/csrf/CrumbIssuerDescriptor.java @@ -64,7 +64,7 @@ public abstract class CrumbIssuerDescriptor extends Descr */ public void setCrumbRequestField(String requestField) { if (Util.fixEmptyAndTrim(requestField) == null) { - crumbRequestField = ".crumb"; + crumbRequestField = CrumbIssuer.DEFAULT_CRUMB_NAME; } else { crumbRequestField = requestField; } diff --git a/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java b/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java index f23699b7581d128896d1e2d861e28c2b286a0781..7f833c17f3263f7afa4e6ba255702cf049509f30 100644 --- a/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java +++ b/core/src/main/java/hudson/security/csrf/DefaultCrumbIssuer.java @@ -5,22 +5,26 @@ */ package hudson.security.csrf; +import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.logging.Level; import java.util.logging.Logger; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.Util; import jenkins.model.Jenkins; import hudson.model.ModelObject; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; +import jenkins.security.HexStringConfidentialKey; import net.sf.json.JSONObject; import org.acegisecurity.Authentication; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; @@ -94,7 +98,9 @@ public class DefaultCrumbIssuer extends CrumbIssuer { if (request instanceof HttpServletRequest) { String newCrumb = issueCrumb(request, salt); if ((newCrumb != null) && (crumb != null)) { - return newCrumb.equals(crumb); + // String.equals() is not constant-time, but this is + return MessageDigest.isEqual(newCrumb.getBytes(Charset.forName("US-ASCII")), + crumb.getBytes(Charset.forName("US-ASCII"))); } } return false; @@ -114,12 +120,13 @@ public class DefaultCrumbIssuer extends CrumbIssuer { return defaultAddress; } - @Extension + @Extension @Symbol("standard") public static final class DescriptorImpl extends CrumbIssuerDescriptor implements ModelObject { + private final static HexStringConfidentialKey CRUMB_SALT = new HexStringConfidentialKey(Jenkins.class,"crumbSalt",16); + public DescriptorImpl() { - // salt just needs to be unique, and it doesn't have to be a secret - super(Jenkins.getInstance().getLegacyInstanceId(), System.getProperty("hudson.security.csrf.requestfield", ".crumb")); + super(CRUMB_SALT.get(), SystemProperties.getString("hudson.security.csrf.requestfield", CrumbIssuer.DEFAULT_CRUMB_NAME)); load(); } @@ -130,6 +137,11 @@ public class DefaultCrumbIssuer extends CrumbIssuer { @Override public DefaultCrumbIssuer newInstance(StaplerRequest req, JSONObject formData) throws FormException { + if (req == null) { + // This state is prohibited according to the Javadoc of the super method. + throw new FormException("DefaultCrumbIssuer new instance method is called for null Stapler request. " + + "Such call is prohibited.", "req"); + } return req.bindJSON(DefaultCrumbIssuer.class, formData); } } diff --git a/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java b/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java index 904dbb37d53c315c0917432841bc3f8eca93562a..a93c70cc23630bfb4e219ff4b11c6005bab13614 100644 --- a/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java +++ b/core/src/main/java/hudson/security/csrf/GlobalCrumbIssuerConfiguration.java @@ -28,6 +28,7 @@ import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; /** @@ -35,7 +36,7 @@ import org.kohsuke.stapler.StaplerRequest; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=195) // immediately after the security setting +@Extension(ordinal=195) @Symbol("crumb") // immediately after the security setting public class GlobalCrumbIssuerConfiguration extends GlobalConfiguration { @Override public GlobalConfigurationCategory getCategory() { diff --git a/core/src/main/java/hudson/slaves/AbstractCloudComputer.java b/core/src/main/java/hudson/slaves/AbstractCloudComputer.java index 32acc2030a2bcc56ccc5ed4a93ce4b4e09bb27f9..ee6b32c0ffaa30688387bc00867f04afd6cc44c9 100644 --- a/core/src/main/java/hudson/slaves/AbstractCloudComputer.java +++ b/core/src/main/java/hudson/slaves/AbstractCloudComputer.java @@ -50,7 +50,7 @@ public class AbstractCloudComputer extends SlaveCo } /** - * When the slave is deleted, free the node right away. + * When the agent is deleted, free the node right away. */ @Override public HttpResponse doDoDelete() throws IOException { diff --git a/core/src/main/java/hudson/slaves/AbstractCloudSlave.java b/core/src/main/java/hudson/slaves/AbstractCloudSlave.java index cc7967d8efd319ef6ab7ba46b7629eb048dcd528..93f0f93b0c9a946ba6939bb1d4b141abbb0103f5 100644 --- a/core/src/main/java/hudson/slaves/AbstractCloudSlave.java +++ b/core/src/main/java/hudson/slaves/AbstractCloudSlave.java @@ -55,7 +55,7 @@ public abstract class AbstractCloudSlave extends Slave { public abstract AbstractCloudComputer createComputer(); /** - * Releases and removes this slave. + * Releases and removes this agent. */ public void terminate() throws InterruptedException, IOException { final Computer computer = toComputer(); diff --git a/core/src/main/java/hudson/slaves/ChannelPinger.java b/core/src/main/java/hudson/slaves/ChannelPinger.java index 49ae7c1cf997e71d13d45fda9bf063d8857eb501..2bc6d4cffba786883e005f1adf79f40221c8c304 100644 --- a/core/src/main/java/hudson/slaves/ChannelPinger.java +++ b/core/src/main/java/hudson/slaves/ChannelPinger.java @@ -25,6 +25,7 @@ package hudson.slaves; import hudson.Extension; import hudson.FilePath; +import jenkins.util.SystemProperties; import hudson.model.Computer; import hudson.model.Slave; import hudson.model.TaskListener; @@ -50,21 +51,15 @@ import static java.util.logging.Level.*; public class ChannelPinger extends ComputerListener { private static final Logger LOGGER = Logger.getLogger(ChannelPinger.class.getName()); private static final String SYS_PROPERTY_NAME = ChannelPinger.class.getName() + ".pingInterval"; - + private static final int DEFAULT_PING_INTERVAL_MIN = 5; + /** * Interval for the ping in minutes. */ - private int pingInterval = 5; + private final int pingInterval; public ChannelPinger() { - String interval = System.getProperty(SYS_PROPERTY_NAME); - if (interval != null) { - try { - pingInterval = Integer.valueOf(interval); - } catch (NumberFormatException e) { - LOGGER.warning("Ignoring invalid " + SYS_PROPERTY_NAME + "=" + interval); - } - } + pingInterval = SystemProperties.getInteger(SYS_PROPERTY_NAME, DEFAULT_PING_INTERVAL_MIN); } @Override @@ -74,7 +69,7 @@ public class ChannelPinger extends ComputerListener { public void install(Channel channel) { if (pingInterval < 1) { - LOGGER.fine("Slave ping is disabled"); + LOGGER.fine("Agent ping is disabled"); return; } @@ -87,7 +82,7 @@ public class ChannelPinger extends ComputerListener { // set up ping from both directions, so that in case of a router dropping a connection, // both sides can notice it and take compensation actions. - setUpPingForChannel(channel, pingInterval); + setUpPingForChannel(channel, pingInterval, true); } private static class SetUpRemotePing extends MasterToSlaveCallable { @@ -98,18 +93,20 @@ public class ChannelPinger extends ComputerListener { } public Void call() throws IOException { - setUpPingForChannel(Channel.current(), pingInterval); + setUpPingForChannel(Channel.current(), pingInterval, false); return null; } } - private static void setUpPingForChannel(final Channel channel, int interval) { + private static void setUpPingForChannel(final Channel channel, int interval, final boolean analysis) { + LOGGER.log(FINE, "setting up ping on {0} at interval {1}m", new Object[] {channel.getName(), interval}); final AtomicBoolean isInClosed = new AtomicBoolean(false); final PingThread t = new PingThread(channel, interval * 60 * 1000) { + @Override protected void onDead(Throwable cause) { try { - for (PingFailureAnalyzer pfa : PingFailureAnalyzer.all()) { - pfa.onPingFailure(channel,cause); + if (analysis) { + analyze(cause); } if (isInClosed.get()) { LOGGER.log(FINE,"Ping failed after the channel "+channel.getName()+" is already partially closed.",cause); @@ -121,6 +118,14 @@ public class ChannelPinger extends ComputerListener { LOGGER.log(SEVERE,"Failed to terminate the channel "+channel.getName(),e); } } + /** Keep in a separate method so we do not even try to do class loading on {@link PingFailureAnalyzer} from an agent JVM. */ + private void analyze(Throwable cause) throws IOException { + for (PingFailureAnalyzer pfa : PingFailureAnalyzer.all()) { + pfa.onPingFailure(channel,cause); + } + } + @Deprecated + @Override protected void onDead() { onDead(null); } diff --git a/core/src/main/java/hudson/slaves/Cloud.java b/core/src/main/java/hudson/slaves/Cloud.java index c3e3679474c1585382b4c117a6efcdecd33a2165..ee35c0442657e7b25e9b8456f3d604cb64de0665 100644 --- a/core/src/main/java/hudson/slaves/Cloud.java +++ b/core/src/main/java/hudson/slaves/Cloud.java @@ -28,6 +28,7 @@ import hudson.Extension; import hudson.DescriptorExtensionList; import hudson.model.Computer; import hudson.model.Slave; +import hudson.security.PermissionScope; import hudson.slaves.NodeProvisioner.PlannedNode; import hudson.model.Describable; import jenkins.model.Jenkins; @@ -42,25 +43,26 @@ import hudson.util.DescriptorList; import org.kohsuke.stapler.DataBoundConstructor; import java.util.Collection; +import java.util.concurrent.Future; /** - * Creates {@link Node}s to dynamically expand/shrink the slaves attached to Hudson. + * Creates {@link Node}s to dynamically expand/shrink the agents attached to Hudson. * *

* Put another way, this class encapsulates different communication protocols - * needed to start a new slave programmatically. + * needed to start a new agent programmatically. * *

Notes for implementers

- *

Automatically delete idle slaves

+ *

Automatically delete idle agents

*

* Nodes provisioned from a cloud do not automatically get released just because it's created from {@link Cloud}. * Doing so requires a use of {@link RetentionStrategy}. Instantiate your {@link Slave} subtype with something * like {@link CloudSlaveRetentionStrategy} so that it gets automatically deleted after some idle time. * - *

Freeing an external resource when a slave is removed

+ *

Freeing an external resource when an agent is removed

*

* Whether you do auto scale-down or not, you often want to release an external resource tied to a cloud-allocated - * slave when it is removed. + * agent when it is removed. * *

* To do this, have your {@link Slave} subtype remember the necessary handle (such as EC2 instance ID) @@ -137,7 +139,7 @@ public abstract class Cloud extends AbstractModelObject implements ExtensionPoin * @param excessWorkload * Number of total executors needed to meet the current demand. * Always >= 1. For example, if this is 3, the implementation - * should launch 3 slaves with 1 executor each, or 1 slave with + * should launch 3 agents with 1 executor each, or 1 agent with * 3 executors, etc. * @return * {@link PlannedNode}s that represent asynchronous {@link Node} @@ -175,10 +177,14 @@ public abstract class Cloud extends AbstractModelObject implements ExtensionPoin return Jenkins.getInstance().>getDescriptorList(Cloud.class); } + private static final PermissionScope PERMISSION_SCOPE = new PermissionScope(Cloud.class); + /** * Permission constant to control mutation operations on {@link Cloud}. * * This includes provisioning a new node, as well as removing it. */ - public static final Permission PROVISION = Jenkins.ADMINISTER; + public static final Permission PROVISION = new Permission( + Computer.PERMISSIONS, "Provision", Messages._Cloud_ProvisionPermission_Description(), Jenkins.ADMINISTER, PERMISSION_SCOPE + ); } diff --git a/core/src/main/java/hudson/slaves/CloudProvisioningListener.java b/core/src/main/java/hudson/slaves/CloudProvisioningListener.java index 0041ebfefcb631dd3c7a04732d23823db52b8b6d..7789824d5f9ae777de5822cab951d9bb094c7a70 100644 --- a/core/src/main/java/hudson/slaves/CloudProvisioningListener.java +++ b/core/src/main/java/hudson/slaves/CloudProvisioningListener.java @@ -5,8 +5,6 @@ import hudson.ExtensionPoint; import hudson.model.Label; import hudson.model.Node; import hudson.model.queue.CauseOfBlockage; -import jenkins.model.Jenkins; -import org.jvnet.localizer.Localizable; import java.util.Collection; diff --git a/core/src/main/java/hudson/slaves/CloudRetentionStrategy.java b/core/src/main/java/hudson/slaves/CloudRetentionStrategy.java index 8dece9422349d483463076868def1f8f76f22d0a..db2b80cf455abbeb2fa939776ed5f418268fa805 100644 --- a/core/src/main/java/hudson/slaves/CloudRetentionStrategy.java +++ b/core/src/main/java/hudson/slaves/CloudRetentionStrategy.java @@ -23,11 +23,8 @@ */ package hudson.slaves; -import hudson.model.Computer; -import hudson.model.Node; -import hudson.model.Queue; -import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; import javax.annotation.concurrent.GuardedBy; import java.io.IOException; import java.util.logging.Logger; @@ -80,5 +77,5 @@ public class CloudRetentionStrategy extends RetentionStrategyTODO {@link CloudRetentionStrategy} seems to be a better implementation. @@ -64,14 +65,14 @@ public class CloudSlaveRetentionStrategy extends RetentionSt } /** - * If the computer has been idle longer than this time, we'll kill the slave. + * If the computer has been idle longer than this time, we'll kill the agent. */ protected long getIdleMaxTime() { return TIMEOUT; } // for debugging, it's convenient to be able to reduce this time - public static long TIMEOUT = Long.getLong(CloudSlaveRetentionStrategy.class.getName()+".timeout", TimeUnit2.MINUTES.toMillis(10)); + public static long TIMEOUT = SystemProperties.getLong(CloudSlaveRetentionStrategy.class.getName()+".timeout", TimeUnit2.MINUTES.toMillis(10)); private static final Logger LOGGER = Logger.getLogger(CloudSlaveRetentionStrategy.class.getName()); } diff --git a/core/src/main/java/hudson/slaves/CommandConnector.java b/core/src/main/java/hudson/slaves/CommandConnector.java index 19d37ea750225c17139e7237b9fa22fd9256abc6..327b3ba9dcb2d555ce7ceafff8b851d393af0690 100644 --- a/core/src/main/java/hudson/slaves/CommandConnector.java +++ b/core/src/main/java/hudson/slaves/CommandConnector.java @@ -26,6 +26,7 @@ package hudson.slaves; import hudson.EnvVars; import hudson.Extension; import hudson.model.TaskListener; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.io.IOException; @@ -48,7 +49,7 @@ public class CommandConnector extends ComputerConnector { return new CommandLauncher(command,new EnvVars("SLAVE",host)); } - @Extension + @Extension @Symbol("command") public static class DescriptorImpl extends ComputerConnectorDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/slaves/CommandLauncher.java b/core/src/main/java/hudson/slaves/CommandLauncher.java index 66cfaaf05636a18ae4e6ad53f0a9cc56d9442ae6..832e392ea3abf24e19492f31fb48fa8d16c675d6 100644 --- a/core/src/main/java/hudson/slaves/CommandLauncher.java +++ b/core/src/main/java/hudson/slaves/CommandLauncher.java @@ -42,6 +42,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -140,7 +141,7 @@ public class CommandLauncher extends ComputerLauncher { } }); - LOGGER.info("slave agent launched for " + computer.getDisplayName()); + LOGGER.info("agent launched for " + computer.getDisplayName()); } catch (InterruptedException e) { e.printStackTrace(listener.error(Messages.ComputerLauncher_abortedLaunch())); } catch (RuntimeException e) { @@ -182,7 +183,7 @@ public class CommandLauncher extends ComputerLauncher { private static final Logger LOGGER = Logger.getLogger(CommandLauncher.class.getName()); - @Extension + @Extension @Symbol("command") public static class DescriptorImpl extends Descriptor { public String getDisplayName() { return Messages.CommandLauncher_displayName(); diff --git a/core/src/main/java/hudson/slaves/ComputerLauncher.java b/core/src/main/java/hudson/slaves/ComputerLauncher.java index 18c44d7b6024c9cc9c92d6b7fb2a1351da65f44b..cbca34f3ff52bdf1434b4280c7f89315cc143cdb 100644 --- a/core/src/main/java/hudson/slaves/ComputerLauncher.java +++ b/core/src/main/java/hudson/slaves/ComputerLauncher.java @@ -37,7 +37,7 @@ import org.apache.tools.ant.util.DeweyDecimal; /** * Extension point to allow control over how {@link Computer}s are "launched", - * meaning how they get connected to their slave agent program. + * meaning how they get connected to their agent program. * *

Associated View

*
@@ -54,17 +54,17 @@ import org.apache.tools.ant.util.DeweyDecimal; public abstract class ComputerLauncher extends AbstractDescribableImpl implements ExtensionPoint { /** * Returns true if this {@link ComputerLauncher} supports - * programatic launch of the slave agent in the target {@link Computer}. + * programatic launch of the agent in the target {@link Computer}. */ public boolean isLaunchSupported() { return true; } /** - * Launches the slave agent for the given {@link Computer}. + * Launches the agent for the given {@link Computer}. * *

- * If the slave agent is launched successfully, {@link SlaveComputer#setChannel(InputStream, OutputStream, TaskListener, Channel.Listener)} + * If the agent is launched successfully, {@link SlaveComputer#setChannel(InputStream, OutputStream, TaskListener, Channel.Listener)} * should be invoked in the end to notify Hudson of the established connection. * The operation could also fail, in which case there's no need to make any callback notification, * (except to notify the user of the failure through {@link StreamTaskListener}.) diff --git a/core/src/main/java/hudson/slaves/ComputerListener.java b/core/src/main/java/hudson/slaves/ComputerListener.java index 96e1abe937c8c140511e4b7ce86df785baa5d480..b166a6c40db3b576864163f25cc06c265993be13 100644 --- a/core/src/main/java/hudson/slaves/ComputerListener.java +++ b/core/src/main/java/hudson/slaves/ComputerListener.java @@ -31,10 +31,7 @@ import hudson.FilePath; import hudson.model.Computer; import hudson.model.Node; import hudson.model.TaskListener; -import org.jenkinsci.remoting.CallableDecorator; import hudson.remoting.Channel; -import hudson.remoting.ChannelBuilder; -import jenkins.model.Jenkins; import java.io.IOException; @@ -54,7 +51,7 @@ public abstract class ComputerListener implements ExtensionPoint { * *

* This enables you to do some configurable checks to see if we - * want to bring this slave online or if there are considerations + * want to bring this agent online or if there are considerations * that would keep us from doing so. * *

@@ -64,7 +61,7 @@ public abstract class ComputerListener implements ExtensionPoint { * @param c * Computer that's being launched. Never null. * @param taskListener - * Connected to the slave console log. Useful for reporting progress/errors on a lengthy operation. + * Connected to the agent console log. Useful for reporting progress/errors on a lengthy operation. * Never null. * @throws AbortException * Exceptions will be recorded to the listener, and @@ -76,12 +73,12 @@ public abstract class ComputerListener implements ExtensionPoint { } /** - * Called when a slave attempted to connect via {@link ComputerLauncher} but it failed. + * Called when an agent attempted to connect via {@link ComputerLauncher} but it failed. * * @param c * Computer that was trying to launch. Never null. * @param taskListener - * Connected to the slave console log. Useful for reporting progress/errors on a lengthy operation. + * Connected to the agent console log. Useful for reporting progress/errors on a lengthy operation. * Never null. * * @since 1.402 @@ -93,19 +90,19 @@ public abstract class ComputerListener implements ExtensionPoint { * Called before a {@link Computer} is marked online. * *

- * This enables you to do some work on all the slaves + * This enables you to do some work on all the agents * as they get connected. Unlike {@link #onOnline(Computer, TaskListener)}, * a failure to carry out this function normally will prevent * a computer from marked as online. * * @param channel - * This is the channel object to talk to the slave. + * This is the channel object to talk to the agent. * (This is the same object returned by {@link Computer#getChannel()} once * it's connected. * @param root - * The directory where this slave stores files. + * The directory where this agent stores files. * The same as {@link Node#getRootPath()}, except that method returns - * null until the slave is connected. So this parameter is passed explicitly instead. + * null until the agent is connected. So this parameter is passed explicitly instead. * @param listener * This is connected to the launch log of the computer. * Since this method is called synchronously from the thread @@ -139,14 +136,14 @@ public abstract class ComputerListener implements ExtensionPoint { * Called right after a {@link Computer} comes online. * *

- * This enables you to do some work on all the slaves + * This enables you to do some work on all the agents * as they get connected. * *

- * Starting Hudson 1.312, this method is also invoked for the master, not just for slaves. + * Starting Hudson 1.312, this method is also invoked for the master, not just for agents. * * @param listener - * This is connected to the launch log of the computer. + * This is connected to the launch log of the computer or Jenkins master. * Since this method is called synchronously from the thread * that launches a computer, if this method performs a time-consuming * operation, this listener should be notified of the progress. @@ -202,7 +199,7 @@ public abstract class ComputerListener implements ExtensionPoint { * Called when configuration of the node was changed, a node is added/removed, etc. * *

- * This callback is to signal when there's any change to the list of slaves registered to the system, + * This callback is to signal when there's any change to the list of agents registered to the system, * including addition, removal, changing of the setting, and so on. * * @since 1.377 diff --git a/core/src/main/java/hudson/slaves/ComputerRetentionWork.java b/core/src/main/java/hudson/slaves/ComputerRetentionWork.java index 1a1ad382e4fca282c8623dcc3cd5681c0c38f56a..8b33592b2261652973a22c8f69ce4808a15d9889 100644 --- a/core/src/main/java/hudson/slaves/ComputerRetentionWork.java +++ b/core/src/main/java/hudson/slaves/ComputerRetentionWork.java @@ -32,14 +32,15 @@ import jenkins.model.Jenkins; import hudson.model.Node; import hudson.model.PeriodicWork; import hudson.Extension; +import org.jenkinsci.Symbol; /** - * Periodically checks the slaves and try to reconnect dead slaves. + * Periodically checks the agents and try to reconnect dead agents. * * @author Kohsuke Kawaguchi * @author Stephen Connolly */ -@Extension +@Extension @Symbol("computerRetention") public class ComputerRetentionWork extends PeriodicWork { /** @@ -55,6 +56,7 @@ public class ComputerRetentionWork extends PeriodicWork { * {@inheritDoc} */ @SuppressWarnings("unchecked") + @Override protected void doRun() { final long startRun = System.currentTimeMillis(); for (final Computer c : Jenkins.getInstance().getComputers()) { diff --git a/core/src/main/java/hudson/slaves/ConnectionActivityMonitor.java b/core/src/main/java/hudson/slaves/ConnectionActivityMonitor.java index 41d9aaa431f7f6b8bd06a27813997f28db79f25d..4bd542d7de3d1e2c77e3024cce7f862c7d590eb0 100644 --- a/core/src/main/java/hudson/slaves/ConnectionActivityMonitor.java +++ b/core/src/main/java/hudson/slaves/ConnectionActivityMonitor.java @@ -31,13 +31,15 @@ import hudson.util.TimeUnit2; import hudson.remoting.VirtualChannel; import hudson.remoting.Channel; import hudson.Extension; +import jenkins.util.SystemProperties; import jenkins.security.SlaveToMasterCallable; +import org.jenkinsci.Symbol; import java.io.IOException; import java.util.logging.Logger; /** - * Makes sure that connections to slaves are alive, and if they are not, cut them off. + * Makes sure that connections to agents are alive, and if they are not, cut them off. * *

* If we only rely on TCP retransmission time out for this, the time it takes to detect a bad connection @@ -46,10 +48,10 @@ import java.util.logging.Logger; * @author Kohsuke Kawaguchi * @since 1.325 */ -@Extension +@Extension @Symbol("connectionActivityMonitor") public class ConnectionActivityMonitor extends AsyncPeriodicWork { public ConnectionActivityMonitor() { - super("Connection Activity monitoring to slaves"); + super("Connection Activity monitoring to agents"); } protected void execute(TaskListener listener) throws IOException, InterruptedException { @@ -61,7 +63,7 @@ public class ConnectionActivityMonitor extends AsyncPeriodicWork { if (ch instanceof Channel) { Channel channel = (Channel) ch; if (now-channel.getLastHeard() > TIME_TILL_PING) { - // haven't heard from this slave for a while. + // haven't heard from this agent for a while. Long lastPing = (Long)channel.getProperty(ConnectionActivityMonitor.class); if (lastPing!=null && now-lastPing > TIMEOUT) { @@ -88,18 +90,18 @@ public class ConnectionActivityMonitor extends AsyncPeriodicWork { /** * Time till initial ping */ - private static final long TIME_TILL_PING = Long.getLong(ConnectionActivityMonitor.class.getName()+".timeToPing",TimeUnit2.MINUTES.toMillis(3)); + private static final long TIME_TILL_PING = SystemProperties.getLong(ConnectionActivityMonitor.class.getName()+".timeToPing",TimeUnit2.MINUTES.toMillis(3)); - private static final long FREQUENCY = Long.getLong(ConnectionActivityMonitor.class.getName()+".frequency",TimeUnit2.SECONDS.toMillis(10)); + private static final long FREQUENCY = SystemProperties.getLong(ConnectionActivityMonitor.class.getName()+".frequency",TimeUnit2.SECONDS.toMillis(10)); /** * When do we abandon the effort and cut off? */ - private static final long TIMEOUT = Long.getLong(ConnectionActivityMonitor.class.getName()+".timeToPing",TimeUnit2.MINUTES.toMillis(4)); + private static final long TIMEOUT = SystemProperties.getLong(ConnectionActivityMonitor.class.getName()+".timeToPing",TimeUnit2.MINUTES.toMillis(4)); // disabled by default until proven in the production - public boolean enabled = Boolean.getBoolean(ConnectionActivityMonitor.class.getName()+".enabled"); + public boolean enabled = SystemProperties.getBoolean(ConnectionActivityMonitor.class.getName()+".enabled"); private static final PingCommand PING_COMMAND = new PingCommand(); private static final class PingCommand extends SlaveToMasterCallable { diff --git a/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java b/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java index 34f8154eadfa511ff5bb42327f7b664aa4b5775b..44b18b4f6b0cceea2df137fc42018f36ffbee8b8 100644 --- a/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java +++ b/core/src/main/java/hudson/slaves/DelegatingComputerLauncher.java @@ -23,20 +23,28 @@ */ package hudson.slaves; -import hudson.Functions; +import hudson.RestrictedSince; import hudson.model.Descriptor; +import hudson.model.Slave; import hudson.model.TaskListener; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import jenkins.model.Jenkins; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; /** - * Convenient base implementation of {@link ComputerLauncher} that allows - * subtypes to perform some initialization (typically something cloud/v12n related - * to power up the machine), then to delegate to another {@link ComputerLauncher} + * Base implementation of {@link ComputerLauncher} that to be used by launchers that + * perform some initialization (typically something cloud/v12n related + * to power up the machine), and then delegate to another {@link ComputerLauncher} * to connect. * + * If you are delegating to another {@link ComputerLauncher} you must extend this base class + * * @author Kohsuke Kawaguchi * @since 1.382 */ @@ -70,11 +78,30 @@ public abstract class DelegatingComputerLauncher extends ComputerLauncher { /** * Returns the applicable nested computer launcher types. * The default implementation avoids all delegating descriptors, as that creates infinite recursion. + * @since 2.12 + */ + public List> applicableDescriptors(@CheckForNull Slave it, + @Nonnull Slave.SlaveDescriptor itDescriptor) { + List> r = new ArrayList>(); + for (Descriptor d : itDescriptor.computerLauncherDescriptors(it)) { + if (DelegatingComputerLauncher.class.isAssignableFrom(d.getKlass().toJavaClass())) continue; + r.add(d); + } + return r; + } + /** + * Returns the applicable nested computer launcher types. + * The default implementation avoids all delegating descriptors, as that creates infinite recursion. + * @deprecated use {@link #applicableDescriptors(Slave, Slave.SlaveDescriptor)} */ + @Deprecated + @Restricted(DoNotUse.class) + @RestrictedSince("2.12") public List> getApplicableDescriptors() { List> r = new ArrayList>(); - for (Descriptor d : Functions.getComputerLauncherDescriptors()) { - if (DelegatingComputerLauncher.class.isInstance(d)) continue; + for (Descriptor d : + Jenkins.getInstance().>getDescriptorList(ComputerLauncher.class)) { + if (DelegatingComputerLauncher.class.isAssignableFrom(d.getKlass().toJavaClass())) continue; r.add(d); } return r; diff --git a/core/src/main/java/hudson/slaves/DumbSlave.java b/core/src/main/java/hudson/slaves/DumbSlave.java index 618cb976db09507e10e2e4ade5720b828ebf9899..835cf004ad23d02fb8fc8de08468f2122084a295 100644 --- a/core/src/main/java/hudson/slaves/DumbSlave.java +++ b/core/src/main/java/hudson/slaves/DumbSlave.java @@ -31,8 +31,11 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; +import javax.annotation.Nonnull; + /** * Default {@link Slave} implementation for computers that do not belong to a higher level structure, * like grid or cloud. @@ -49,12 +52,21 @@ public final class DumbSlave extends Slave { this(name, nodeDescription, remoteFS, numExecutors, mode, labelString, launcher, retentionStrategy, new ArrayList()); } - @DataBoundConstructor + /** + * @deprecated as of 1.XXX. + * Use {@link #DumbSlave(String, String, ComputerLauncher)} and configure the rest through setters. + */ public DumbSlave(String name, String nodeDescription, String remoteFS, String numExecutors, Mode mode, String labelString, ComputerLauncher launcher, RetentionStrategy retentionStrategy, List> nodeProperties) throws IOException, FormException { super(name, nodeDescription, remoteFS, numExecutors, mode, labelString, launcher, retentionStrategy, nodeProperties); } - @Extension + @DataBoundConstructor + public DumbSlave(@Nonnull String name, String remoteFS, ComputerLauncher launcher) throws FormException, IOException { + super(name, remoteFS, launcher); + } + + @Extension @Symbol({"dumb", + "slave"/*because this is in effect the canonical slave type*/}) public static final class DescriptorImpl extends SlaveDescriptor { public String getDisplayName() { return Messages.DumbSlave_displayName(); diff --git a/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java b/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java index ca6e954feb18da7bf41e5c233396599c2d750982..d41b8c49a12326d819a993dd3e923221004f88d5 100644 --- a/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java +++ b/core/src/main/java/hudson/slaves/EnvironmentVariablesNodeProperty.java @@ -32,6 +32,7 @@ import hudson.model.ComputerSet; import hudson.model.Environment; import hudson.model.Node; import hudson.model.TaskListener; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.Stapler; @@ -47,7 +48,7 @@ import java.util.List; public class EnvironmentVariablesNodeProperty extends NodeProperty { /** - * Slave-specific environment variables + * Agent-specific environment variables */ private final EnvVars envVars; @@ -75,7 +76,7 @@ public class EnvironmentVariablesNodeProperty extends NodeProperty { env.putAll(envVars); } - @Extension + @Extension @Symbol("envVars") public static class DescriptorImpl extends NodePropertyDescriptor { @Override diff --git a/core/src/main/java/hudson/slaves/JNLPLauncher.java b/core/src/main/java/hudson/slaves/JNLPLauncher.java index b89178a13e694fd09e86fed7f26f9c8899abae8b..c83382f796261c1283bb411fa4b90248665bf3ab 100644 --- a/core/src/main/java/hudson/slaves/JNLPLauncher.java +++ b/core/src/main/java/hudson/slaves/JNLPLauncher.java @@ -23,10 +23,15 @@ */ package hudson.slaves; +import hudson.Extension; +import hudson.Util; import hudson.model.Descriptor; +import hudson.model.DescriptorVisibilityFilter; import hudson.model.TaskListener; -import hudson.Util; -import hudson.Extension; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -37,7 +42,7 @@ import org.kohsuke.stapler.DataBoundConstructor; */ public class JNLPLauncher extends ComputerLauncher { /** - * If the slave needs to tunnel the connection to the master, + * If the agent needs to tunnel the connection to the master, * specify the "host:port" here. This can include the special * syntax "host:" and ":port" to indicate the default host/port * shall be used. @@ -75,11 +80,46 @@ public class JNLPLauncher extends ComputerLauncher { // do nothing as we cannot self start } - @Extension - public static final Descriptor DESCRIPTOR = new Descriptor() { + /** + * @deprecated as of 1.XXX + * Use {@link Jenkins#getDescriptor(Class)} + */ + public static /*almost final*/ Descriptor DESCRIPTOR; + + @Extension @Symbol("jnlp") + public static class DescriptorImpl extends Descriptor { + public DescriptorImpl() { + DESCRIPTOR = this; + } + public String getDisplayName() { return Messages.JNLPLauncher_displayName(); } }; + /** + * Hides the JNLP launcher when the JNLP agent port is not enabled. + * + * @since 2.16 + */ + @Extension + public static class DescriptorVisibilityFilterImpl extends DescriptorVisibilityFilter { + + /** + * {@inheritDoc} + */ + @Override + public boolean filter(@CheckForNull Object context, @Nonnull Descriptor descriptor) { + return descriptor.clazz != JNLPLauncher.class || Jenkins.getInstance().getTcpSlaveAgentListener() != null; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean filterType(@Nonnull Class contextClass, @Nonnull Descriptor descriptor) { + return descriptor.clazz != JNLPLauncher.class || Jenkins.getInstance().getTcpSlaveAgentListener() != null; + } + } + } diff --git a/core/src/main/java/hudson/slaves/NodeProperty.java b/core/src/main/java/hudson/slaves/NodeProperty.java index 7f71adebef227b98150a9807c2770dc15d58f15a..4a8240d268a1e5123af449dca8a3e66840268d32 100644 --- a/core/src/main/java/hudson/slaves/NodeProperty.java +++ b/core/src/main/java/hudson/slaves/NodeProperty.java @@ -39,7 +39,6 @@ import hudson.model.BuildListener; import hudson.model.Environment; import jenkins.model.Jenkins; import hudson.model.Node; -import hudson.model.Queue; import hudson.model.Queue.Task; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; @@ -161,7 +160,7 @@ public abstract class NodeProperty implements ReconfigurableDesc * @param env * Manipulate this variable (normally by adding more entries.) * Note that this is an override, so it doesn't contain environment variables that are - * currently set for the slave process itself. + * currently set for the agent process itself. * @param listener * Can be used to send messages. * diff --git a/core/src/main/java/hudson/slaves/NodeProvisioner.java b/core/src/main/java/hudson/slaves/NodeProvisioner.java index bf326d79563e906049603b434d570ac1f7599a2c..bcde3623b4e6ce325c8ecc6f577f31ca891040f2 100644 --- a/core/src/main/java/hudson/slaves/NodeProvisioner.java +++ b/core/src/main/java/hudson/slaves/NodeProvisioner.java @@ -30,6 +30,8 @@ import jenkins.model.Jenkins; import static hudson.model.LoadStatistics.DECAY; import hudson.model.MultiStageTimeSeries.TimeScale; import hudson.Extension; +import jenkins.util.SystemProperties; +import org.jenkinsci.Symbol; import javax.annotation.Nonnull; import javax.annotation.concurrent.GuardedBy; @@ -42,6 +44,7 @@ import java.util.Collection; import java.util.ArrayList; import java.util.Iterator; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; @@ -122,8 +125,8 @@ public class NodeProvisioner { */ private final Label label; - @GuardedBy("provisioningLock") - private final List pendingLaunches = new ArrayList(); + private final AtomicReference> pendingLaunches + = new AtomicReference>(new ArrayList()); private final Lock provisioningLock = new ReentrantLock(); @@ -155,12 +158,7 @@ public class NodeProvisioner { * @since 1.401 */ public List getPendingLaunches() { - provisioningLock.lock(); - try { - return new ArrayList(pendingLaunches); - } finally { - provisioningLock.unlock(); - } + return new ArrayList(pendingLaunches.get()); } /** @@ -213,48 +211,73 @@ public class NodeProvisioner { // bring up. int plannedCapacitySnapshot = 0; - List completedLaunches = new ArrayList(); - for (Iterator itr = pendingLaunches.iterator(); itr.hasNext(); ) { + List snapPendingLaunches = new ArrayList(pendingLaunches.get()); + for (Iterator itr = snapPendingLaunches.iterator(); itr.hasNext(); ) { PlannedNode f = itr.next(); if (f.future.isDone()) { - completedLaunches.add(f); - itr.remove(); + try { + Node node = f.future.get(); + for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { + cl.onComplete(f, node); + } + + jenkins.addNode(node); + LOGGER.log(Level.INFO, + "{0} provisioning successfully completed. " + + "We have now {1,number,integer} computer(s)", + new Object[]{f.displayName, jenkins.getComputers().length}); + } catch (InterruptedException e) { + throw new AssertionError(e); // since we confirmed that the future is already done + } catch (ExecutionException e) { + LOGGER.log(Level.WARNING, "Provisioned agent " + f.displayName + " failed to launch", + e.getCause()); + for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { + cl.onFailure(f, e.getCause()); + } + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Provisioned agent " + f.displayName + " failed to launch", + e); + for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { + cl.onFailure(f, e); + } + } catch (Error e) { + // we are not supposed to try and recover from Errors + throw e; + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, "Unexpected uncaught exception encountered while " + + "processing provisioned agent " + f.displayName, e); + } finally { + while (true) { + List orig = pendingLaunches.get(); + List repl = new ArrayList(orig); + // the contract for List.remove(o) is that the first element i where + // (o==null ? get(i)==null : o.equals(get(i))) + // is true will be removed from the list + // since PlannedNode.equals(o) is not final and we cannot assume + // that subclasses do not override with an equals which does not + // assure object identity comparison, we need to manually + // do the removal based on instance identity not equality + boolean changed = false; + for (Iterator iterator = repl.iterator(); iterator.hasNext(); ) { + PlannedNode p = iterator.next(); + if (p == f) { + iterator.remove(); + changed = true; + break; + } + } + if (!changed || pendingLaunches.compareAndSet(orig, repl)) { + break; + } + } + f.spent(); + } } else { plannedCapacitySnapshot += f.numExecutors; } } - for (PlannedNode f : completedLaunches) { - try { - Node node = f.future.get(); - for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { - cl.onComplete(f, node); - } - - jenkins.addNode(node); - LOGGER.log(Level.INFO, - "{0} provisioning successfully completed. We have now {1,number,integer} computer" - + "(s)", - new Object[]{f.displayName, jenkins.getComputers().length}); - } catch (InterruptedException e) { - throw new AssertionError(e); // since we confirmed that the future is already done - } catch (ExecutionException e) { - LOGGER.log(Level.WARNING, "Provisioned slave " + f.displayName + " failed to launch", - e.getCause()); - for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { - cl.onFailure(f, e.getCause()); - } - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Provisioned slave " + f.displayName + " failed to launch", e); - for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { - cl.onFailure(f, e); - } - } - - f.spent(); - } - float plannedCapacity = plannedCapacitySnapshot; plannedCapacitiesEMA.update(plannedCapacity); @@ -264,7 +287,7 @@ public class NodeProvisioner { int queueLengthSnapshot = snapshot.getQueueLength(); if (queueLengthSnapshot <= availableSnapshot) { - LOGGER.log(Level.FINE, + LOGGER.log(Level.FINER, "Queue length {0} is less than the available capacity {1}. No provisioning strategy required", new Object[]{queueLengthSnapshot, availableSnapshot}); provisioningState = null; @@ -353,7 +376,6 @@ public class NodeProvisioner { * The current statistics snapshot for this {@link #label}. */ private final LoadStatistics.LoadStatisticsSnapshot snapshot; - private final List pendingLaunches; /** * The additional planned capacity for this {@link #label} and provisioned by previous strategies during the * current updating of the {@link NodeProvisioner}. @@ -370,7 +392,6 @@ public class NodeProvisioner { this.snapshot = snapshot; this.label = label; this.plannedCapacitySnapshot = plannedCapacitySnapshot; - pendingLaunches = NodeProvisioner.this.pendingLaunches; } /** @@ -426,13 +447,8 @@ public class NodeProvisioner { * The additional planned capacity for this {@link #getLabel()} and provisioned by previous strategies during * the current updating of the {@link NodeProvisioner}. */ - public int getAdditionalPlannedCapacity() { - provisioningLock.lock(); - try { - return additionalPlannedCapacity; - } finally { - provisioningLock.unlock(); - } + public synchronized int getAdditionalPlannedCapacity() { + return additionalPlannedCapacity; } /** @@ -541,23 +557,26 @@ public class NodeProvisioner { if (node != null) { additionalPlannedCapacity += node.getNumExecutors(); } - } catch (InterruptedException e) { - // ignore, this will be caught by others later - } catch (ExecutionException e) { - // ignore, this will be caught by others later + } catch (InterruptedException | ExecutionException e) { + // InterruptedException: should never happen as we were told the future was done + // ExecutionException: ignore, this will be caught by others later } } else { additionalPlannedCapacity += f.numExecutors; } } - provisioningLock.lock(); - try { - pendingLaunches.addAll(plannedNodes); - if (additionalPlannedCapacity > 0) { - this.additionalPlannedCapacity += additionalPlannedCapacity; + while (!plannedNodes.isEmpty()) { + List orig = pendingLaunches.get(); + List repl = new ArrayList(orig); + repl.addAll(plannedNodes); + if (pendingLaunches.compareAndSet(orig, repl)) { + if (additionalPlannedCapacity > 0) { + synchronized (this) { + this.additionalPlannedCapacity += additionalPlannedCapacity; + } + } + break; } - } finally { - provisioningLock.unlock(); } } @@ -581,7 +600,7 @@ public class NodeProvisioner { * * @since 1.588 */ - @Extension + @Extension @Symbol("standard") public static class StandardStrategyImpl extends Strategy { /** {@inheritDoc} */ @@ -589,23 +608,23 @@ public class NodeProvisioner { @Override public StrategyDecision apply(@Nonnull StrategyState state) { /* - Here we determine how many additional slaves we need to keep up with the load (if at all), + Here we determine how many additional agents we need to keep up with the load (if at all), which involves a simple math. Broadly speaking, first we check that all the executors are fully utilized before attempting - to start any new slave (this also helps to ignore the temporary gap between different numbers, + to start any new agent (this also helps to ignore the temporary gap between different numbers, as changes in them are not necessarily synchronized --- for example, there's a time lag between - when a slave launches (thus bringing the planned capacity down) and the time when its executors + when an agent launches (thus bringing the planned capacity down) and the time when its executors pick up builds (thus bringing the queue length down.) - Once we confirm that, we compare the # of buildable items against the additional slaves - that are being brought online. If we have more jobs than our executors can handle, we'll launch a new slave. + Once we confirm that, we compare the # of buildable items against the additional agents + that are being brought online. If we have more jobs than our executors can handle, we'll launch a new agent. So this computation involves three stats: 1. # of idle executors 2. # of jobs that are starving for executors - 3. # of additional slaves being provisioned (planned capacities.) + 3. # of additional agents being provisioned (planned capacities.) To ignore a temporary surge/drop, we make conservative estimates on each one of them. That is, we take the current snapshot value, and we take the current exponential moving average (EMA) value, @@ -657,14 +676,14 @@ public class NodeProvisioner { CLOUD: for (Cloud c : Jenkins.getInstance().clouds) { if (excessWorkload < 0) { - break; // enough slaves allocated + break; // enough agents allocated } // Make sure this cloud actually can provision for this label. if (c.canProvision(state.getLabel())) { // provisioning a new node should be conservative --- for example if excessWorkload is 1.4, // we don't want to allocate two nodes but just one. - // OTOH, because of the exponential decay, even when we need one slave, + // OTOH, because of the exponential decay, even when we need one agent, // excess workload is always // something like 0.95, in which case we want to allocate one node. // so the threshold here is 1-MARGIN, and hence floor(excessWorkload+MARGIN) is needed to @@ -672,11 +691,10 @@ public class NodeProvisioner { int workloadToProvision = (int) Math.round(Math.floor(excessWorkload + m)); - for (CloudProvisioningListener cl : CloudProvisioningListener.all()) - // consider displaying reasons in a future cloud ux - { + for (CloudProvisioningListener cl : CloudProvisioningListener.all()) { if (cl.canProvision(c, state.getLabel(), workloadToProvision) != null) { - break CLOUD; + // consider displaying reasons in a future cloud ux + continue CLOUD; } } @@ -757,11 +775,11 @@ public class NodeProvisioner { @Extension public static class NodeProvisionerInvoker extends PeriodicWork { /** - * Give some initial warm up time so that statically connected slaves + * Give some initial warm up time so that statically connected agents * can be brought online before we start allocating more. */ - public static int INITIALDELAY = Integer.getInteger(NodeProvisioner.class.getName()+".initialDelay",LoadStatistics.CLOCK*10); - public static int RECURRENCEPERIOD = Integer.getInteger(NodeProvisioner.class.getName()+".recurrencePeriod",LoadStatistics.CLOCK); + public static int INITIALDELAY = SystemProperties.getInteger(NodeProvisioner.class.getName()+".initialDelay",LoadStatistics.CLOCK*10); + public static int RECURRENCEPERIOD = SystemProperties.getInteger(NodeProvisioner.class.getName()+".recurrencePeriod",LoadStatistics.CLOCK); @Override public long getInitialDelay() { @@ -782,7 +800,7 @@ public class NodeProvisioner { } private static final Logger LOGGER = Logger.getLogger(NodeProvisioner.class.getName()); - private static final float MARGIN = Integer.getInteger(NodeProvisioner.class.getName()+".MARGIN",10)/100f; + private static final float MARGIN = SystemProperties.getInteger(NodeProvisioner.class.getName()+".MARGIN",10)/100f; private static final float MARGIN0 = Math.max(MARGIN, getFloatSystemProperty(NodeProvisioner.class.getName()+".MARGIN0",0.5f)); private static final float MARGIN_DECAY = getFloatSystemProperty(NodeProvisioner.class.getName()+".MARGIN_DECAY",0.5f); @@ -790,7 +808,7 @@ public class NodeProvisioner { private static final TimeScale TIME_SCALE = TimeScale.SEC10; private static float getFloatSystemProperty(String propName, float defaultValue) { - String v = System.getProperty(propName); + String v = SystemProperties.getString(propName); if (v!=null) try { return Float.parseFloat(v); diff --git a/core/src/main/java/hudson/slaves/NodeSpecific.java b/core/src/main/java/hudson/slaves/NodeSpecific.java index 59ee2ca217dfaeb99db40d7c69bbefbf58f46f00..e40ef509dfaf96284d7c92d5913af9fa185e698b 100644 --- a/core/src/main/java/hudson/slaves/NodeSpecific.java +++ b/core/src/main/java/hudson/slaves/NodeSpecific.java @@ -24,10 +24,11 @@ package hudson.slaves; -import edu.umd.cs.findbugs.annotations.NonNull; import hudson.model.Node; import hudson.model.EnvironmentSpecific; import hudson.model.TaskListener; + +import javax.annotation.Nonnull; import java.io.IOException; /** @@ -45,5 +46,5 @@ public interface NodeSpecific> { /** * Returns a specialized copy of T for functioning in the given node. */ - T forNode(@NonNull Node node, TaskListener log) throws IOException, InterruptedException; + T forNode(@Nonnull Node node, TaskListener log) throws IOException, InterruptedException; } diff --git a/core/src/main/java/hudson/slaves/OfflineCause.java b/core/src/main/java/hudson/slaves/OfflineCause.java index 41319f01e92a1b60f34aa827db30f5208b21f11c..7f7704d712162073f05e9ef300f155391d30323a 100644 --- a/core/src/main/java/hudson/slaves/OfflineCause.java +++ b/core/src/main/java/hudson/slaves/OfflineCause.java @@ -155,4 +155,14 @@ public abstract class OfflineCause { this.message = message; } } + + /** + * Caused by idle period. + * @since 1.644 + */ + public static class IdleOfflineCause extends SimpleOfflineCause { + public IdleOfflineCause () { + super(hudson.slaves.Messages._RetentionStrategy_Demand_OfflineIdle()); + } + } } diff --git a/core/src/main/java/hudson/slaves/RetentionStrategy.java b/core/src/main/java/hudson/slaves/RetentionStrategy.java index 106d1a90c27e90128b5611216671e50adcde9930..90fa17331de5f39f0e7d54271d45a9f9d31d52d0 100644 --- a/core/src/main/java/hudson/slaves/RetentionStrategy.java +++ b/core/src/main/java/hudson/slaves/RetentionStrategy.java @@ -28,11 +28,11 @@ import hudson.Util; import hudson.DescriptorExtensionList; import hudson.Extension; import hudson.model.*; -import hudson.model.Queue.*; import hudson.util.DescriptorList; import java.util.Collections; import java.util.HashMap; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import javax.annotation.concurrent.GuardedBy; @@ -49,7 +49,7 @@ import java.util.logging.Logger; public abstract class RetentionStrategy extends AbstractDescribableImpl> implements ExtensionPoint { /** - * This method will be called periodically to allow this strategy to decide what to do with it's owning slave. + * This method will be called periodically to allow this strategy to decide what to do with it's owning agent. * * @param c {@link Computer} for which this strategy is assigned. This computer may be online or offline. * This object also exposes a bunch of properties that the callee can use to decide what action to take. @@ -60,11 +60,11 @@ public abstract class RetentionStrategy extends AbstractDesc public abstract long check(T c); /** - * This method is called to determine whether manual launching of the slave is allowed at this point in time. + * This method is called to determine whether manual launching of the agent is allowed at this point in time. * @param c {@link Computer} for which this strategy is assigned. This computer may be online or offline. * This object also exposes a bunch of properties that the callee can use to decide if manual launching is * allowed at this time. - * @return {@code true} if manual launching of the slave is allowed at this point in time. + * @return {@code true} if manual launching of the agent is allowed at this point in time. */ public boolean isManualLaunchAllowed(T c) { return true; @@ -86,7 +86,7 @@ public abstract class RetentionStrategy extends AbstractDesc /** * Called when a new {@link Computer} object is introduced (such as when Hudson started, or when - * a new slave is added.) + * a new agent is added.) * *

* The default implementation of this method delegates to {@link #check(Computer)}, @@ -139,11 +139,7 @@ public abstract class RetentionStrategy extends AbstractDesc private final DescriptorImpl DESCRIPTOR = new DescriptorImpl(); - class DescriptorImpl extends Descriptor> { - public String getDisplayName() { - return ""; - } - } + class DescriptorImpl extends Descriptor> {} }; /** @@ -169,7 +165,7 @@ public abstract class RetentionStrategy extends AbstractDesc return 1; } - @Extension(ordinal=100) + @Extension(ordinal=100) @Symbol("always") public static class DescriptorImpl extends Descriptor> { public String getDisplayName() { return Messages.RetentionStrategy_Always_displayName(); @@ -185,12 +181,12 @@ public abstract class RetentionStrategy extends AbstractDesc private static final Logger logger = Logger.getLogger(Demand.class.getName()); /** - * The delay (in minutes) for which the slave must be in demand before tring to launch it. + * The delay (in minutes) for which the agent must be in demand before tring to launch it. */ private final long inDemandDelay; /** - * The delay (in minutes) for which the slave must be idle before taking it offline. + * The delay (in minutes) for which the agent must be idle before taking it offline. */ private final long idleDelay; @@ -272,7 +268,7 @@ public abstract class RetentionStrategy extends AbstractDesc // we've been idle for long enough logger.log(Level.INFO, "Disconnecting computer {0} as it has been idle for {1}", new Object[]{c.getName(), Util.getTimeSpanString(idleMilliseconds)}); - c.disconnect(OfflineCause.create(Messages._RetentionStrategy_Demand_OfflineIdle())); + c.disconnect(new OfflineCause.IdleOfflineCause()); } else { // no point revisiting until we can be confident we will be idle return TimeUnit.MILLISECONDS.toMinutes(TimeUnit.MINUTES.toMillis(idleDelay) - idleMilliseconds); @@ -281,7 +277,7 @@ public abstract class RetentionStrategy extends AbstractDesc return 1; } - @Extension + @Extension @Symbol("demand") public static class DescriptorImpl extends Descriptor> { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/slaves/SimpleScheduledRetentionStrategy.java b/core/src/main/java/hudson/slaves/SimpleScheduledRetentionStrategy.java index 5a1e804b7992b6a9f22b10962ef24b4d53e6d285..df9ff8ce07dae867c7bea0236b79a4ea799385de 100644 --- a/core/src/main/java/hudson/slaves/SimpleScheduledRetentionStrategy.java +++ b/core/src/main/java/hudson/slaves/SimpleScheduledRetentionStrategy.java @@ -31,6 +31,7 @@ import hudson.model.Descriptor; import hudson.model.Queue; import hudson.scheduler.CronTabList; import hudson.util.FormValidation; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -45,7 +46,7 @@ import java.util.logging.Logger; import static java.util.logging.Level.INFO; /** - * {@link RetentionStrategy} that controls the slave based on a schedule. + * {@link RetentionStrategy} that controls the agent based on a schedule. * * @author Stephen Connolly * @since 1.275 @@ -186,8 +187,7 @@ public class SimpleScheduledRetentionStrategy extends RetentionStrategy now) || (nextStart < now && nextStop > now); } - @Extension + @Extension @Symbol("schedule") public static class DescriptorImpl extends Descriptor> { public String getDisplayName() { return Messages.SimpleScheduledRetentionStrategy_displayName(); diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index c62401dc767b975ae8485ae0fcb3d02c69ed37b1..080af48bd08f6a077d72ef089cc1c6dc0b303ae4 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -23,11 +23,10 @@ */ package hudson.slaves; -import edu.umd.cs.findbugs.annotations.OverrideMustInvoke; -import edu.umd.cs.findbugs.annotations.When; import hudson.AbortException; import hudson.FilePath; import hudson.Util; +import hudson.console.ConsoleLogFilter; import hudson.model.Computer; import hudson.model.Executor; import hudson.model.ExecutorListener; @@ -47,14 +46,15 @@ import hudson.util.IOUtils; import hudson.util.NullStream; import hudson.util.RingBufferLogHandler; import hudson.util.StreamTaskListener; -import hudson.util.io.ReopenableFileOutputStream; -import hudson.util.io.ReopenableRotatingFileOutputStream; +import hudson.util.io.RewindableFileOutputStream; +import hudson.util.io.RewindableRotatingFileOutputStream; import jenkins.model.Jenkins; import jenkins.security.ChannelConfigurator; import jenkins.security.MasterToSlaveCallable; import jenkins.slaves.EncryptedSlaveAgentJnlpFile; import jenkins.slaves.JnlpSlaveAgentProtocol; import jenkins.slaves.systemInfo.SlaveSystemInfo; +import jenkins.util.SystemProperties; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.kohsuke.stapler.HttpRedirect; @@ -66,6 +66,7 @@ import org.kohsuke.stapler.WebMethod; import org.kohsuke.stapler.interceptor.RequirePOST; import javax.annotation.CheckForNull; +import javax.annotation.OverridingMethodsMustInvokeSuper; import javax.servlet.ServletException; import java.io.File; import java.io.IOException; @@ -98,7 +99,7 @@ public class SlaveComputer extends Computer { private Boolean isUnix; /** * Effective {@link ComputerLauncher} that hides the details of - * how we launch a slave agent on this computer. + * how we launch a agent agent on this computer. * *

* This is normally the same as {@link Slave#getLauncher()} but @@ -109,7 +110,7 @@ public class SlaveComputer extends Computer { /** * Perpetually writable log file. */ - private final ReopenableFileOutputStream log; + private final RewindableFileOutputStream log; /** * {@link StreamTaskListener} that wraps {@link #log}, hence perpetually writable. @@ -136,18 +137,32 @@ public class SlaveComputer extends Computer { public SlaveComputer(Slave slave) { super(slave); - this.log = new ReopenableRotatingFileOutputStream(getLogFile(),10); - this.taskListener = new StreamTaskListener(log); + this.log = new RewindableRotatingFileOutputStream(getLogFile(), 10); + this.taskListener = new StreamTaskListener(decorate(this.log)); assert slave.getNumExecutors()!=0 : "Computer created with 0 executors"; } + /** + * Uses {@link ConsoleLogFilter} to decorate logger. + */ + private OutputStream decorate(OutputStream os) { + for (ConsoleLogFilter f : ConsoleLogFilter.all()) { + try { + os = f.decorateLogger(this,os); + } catch (IOException|InterruptedException e) { + LOGGER.log(Level.WARNING, "Failed to filter log with "+f, e); + } + } + return os; + } + /** * {@inheritDoc} */ @Override - @OverrideMustInvoke(When.ANYTIME) + @OverridingMethodsMustInvokeSuper public boolean isAcceptingTasks() { - // our boolean flag is an override on any additional programmatic reasons why this slave might not be + // our boolean flag is an override on any additional programmatic reasons why this agent might not be // accepting tasks. return acceptingTasks && super.isAcceptingTasks(); } @@ -160,24 +175,19 @@ public class SlaveComputer extends Computer { } /** - * Allows suspension of tasks being accepted by the slave computer. While this could be called by a + * Allows suspension of tasks being accepted by the agent computer. While this could be called by a * {@linkplain hudson.slaves.ComputerLauncher} or a {@linkplain hudson.slaves.RetentionStrategy}, such usage * can result in fights between multiple actors calling setting differential values. A better approach * is to override {@link hudson.slaves.RetentionStrategy#isAcceptingTasks(hudson.model.Computer)} if the * {@link hudson.slaves.RetentionStrategy} needs to control availability. * - * @param acceptingTasks {@code true} if the slave can accept tasks. + * @param acceptingTasks {@code true} if the agent can accept tasks. */ public void setAcceptingTasks(boolean acceptingTasks) { this.acceptingTasks = acceptingTasks; } - /** - * True if this computer is a Unix machine (as opposed to Windows machine). - * - * @return - * null if the computer is disconnected and therefore we don't know whether it is Unix or not. - */ + @Override public Boolean isUnix() { return isUnix; } @@ -194,6 +204,14 @@ public class SlaveComputer extends Computer { } } + /** + * Return the {@code TaskListener} for this SlaveComputer. Never null + * @since 2.9 + */ + public TaskListener getListener() { + return taskListener; + } + @Override public String getIcon() { Future l = lastConnectActivity; @@ -239,7 +257,7 @@ public class SlaveComputer extends Computer { try { for (ComputerListener cl : ComputerListener.all()) cl.preLaunch(SlaveComputer.this, taskListener); - + offlineCause = null; launcher.launch(SlaveComputer.this, taskListener); } catch (AbortException e) { taskListener.error(e.getMessage()); @@ -256,7 +274,7 @@ public class SlaveComputer extends Computer { throw e; } } finally { - if (channel==null) { + if (channel==null && offlineCause == null) { offlineCause = new OfflineCause.LaunchFailed(); for (ComputerListener cl : ComputerListener.all()) cl.onLaunchFailure(SlaveComputer.this, taskListener); @@ -264,7 +282,7 @@ public class SlaveComputer extends Computer { } if (channel==null) - throw new IOException("Slave failed to connect, even though the launcher didn't report it. See the log output for details."); + throw new IOException("Agent failed to connect, even though the launcher didn't report it. See the log output for details."); return null; } }); @@ -340,7 +358,7 @@ public class SlaveComputer extends Computer { } /** - * Creates a {@link Channel} from the given stream and sets that to this slave. + * Creates a {@link Channel} from the given stream and sets that to this agent. * * @param in * Stream connected to the remote "slave.jar". It's the caller's responsibility to do @@ -416,11 +434,11 @@ public class SlaveComputer extends Computer { } /** - * Returns the remote FS root absolute path or {@code null} if the slave is off-line. The absolute path may change + * Returns the remote FS root absolute path or {@code null} if the agent is off-line. The absolute path may change * between connections if the connection method does not provide a consistent working directory and the node's * remote FS is specified as a relative path. * - * @return the remote FS root absolute path or {@code null} if the slave is off-line. + * @return the remote FS root absolute path or {@code null} if the agent is off-line. * @since 1.606 */ @CheckForNull @@ -458,7 +476,7 @@ public class SlaveComputer extends Computer { /** * Sets up the connection through an existing channel. - * + * @param channel the channel to use; warning: callers are expected to have called {@link ChannelConfigurator} already * @since 1.444 */ public void setChannel(Channel channel, OutputStream launchLog, Channel.Listener listener) throws IOException, InterruptedException { @@ -523,7 +541,7 @@ public class SlaveComputer extends Computer { // it'll have a catastrophic impact on the communication. channel.pinClassLoader(getClass().getClassLoader()); - channel.call(new SlaveInitializer()); + channel.call(new SlaveInitializer(DEFAULT_RING_BUFFER_SIZE)); SecurityContext old = ACL.impersonate(ACL.SYSTEM); try { for (ComputerListener cl : ComputerListener.all()) { @@ -565,7 +583,7 @@ public class SlaveComputer extends Computer { } finally { SecurityContextHolder.setContext(old); } - log.println("Slave successfully connected and online"); + log.println("Agent successfully connected and online"); Jenkins.getInstance().getQueue().scheduleMaintenance(); } @@ -634,11 +652,11 @@ public class SlaveComputer extends Computer { } /** - * Serves jar files for JNLP slave agents. + * Serves jar files for JNLP agents. * * @deprecated since 2008-08-18. * This URL binding is no longer used and moved up directly under to {@link jenkins.model.Jenkins}, - * but it's left here for now just in case some old JNLP slave agents request it. + * but it's left here for now just in case some old JNLP agents request it. */ @Deprecated public Slave.JnlpJar getJnlpJars(String fileName) { @@ -659,7 +677,7 @@ public class SlaveComputer extends Computer { try { Util.deleteRecursive(getLogDir()); } catch (IOException ex) { - logger.log(Level.WARNING, "Unable to delete slave logs", ex); + logger.log(Level.WARNING, "Unable to delete agent logs", ex); } } @@ -696,7 +714,7 @@ public class SlaveComputer extends Computer { super.setNode(node); launcher = grabLauncher(node); - // maybe the configuration was changed to relaunch the slave, so try to re-launch now. + // maybe the configuration was changed to relaunch the agent, so try to re-launch now. // "constructed==null" test is an ugly hack to avoid launching before the object is fully // constructed. if(constructed!=null) { @@ -730,7 +748,7 @@ public class SlaveComputer extends Computer { } /** - * Get the slave version + * Get the agent version */ public String getSlaveVersion() throws IOException, InterruptedException { return channel.call(new SlaveVersion()); @@ -784,13 +802,21 @@ public class SlaveComputer extends Computer { */ static final class LogHolder { /** - * This field is used on each slave node to record log records on the slave. + * This field is used on each agent to record logs on the agent. */ - static final RingBufferLogHandler SLAVE_LOG_HANDLER = new RingBufferLogHandler(); + static RingBufferLogHandler SLAVE_LOG_HANDLER; } private static class SlaveInitializer extends MasterToSlaveCallable { + final int ringBufferSize; + + public SlaveInitializer(int ringBufferSize) { + this.ringBufferSize = ringBufferSize; + } + public Void call() { + SLAVE_LOG_HANDLER = new RingBufferLogHandler(ringBufferSize); + // avoid double installation of the handler. JNLP slaves can reconnect to the master multiple times // and each connection gets a different RemoteClassLoader, so we need to evict them by class name, // not by their identity. @@ -817,18 +843,18 @@ public class SlaveComputer extends Computer { /** * Obtains a {@link VirtualChannel} that allows some computation to be performed on the master. - * This method can be called from any thread on the master, or from slave (more precisely, - * it only works from the remoting request-handling thread in slaves, which means if you've started - * separate thread on slaves, that'll fail.) + * This method can be called from any thread on the master, or from agent (more precisely, + * it only works from the remoting request-handling thread in agents, which means if you've started + * separate thread on agents, that'll fail.) * * @return null if the calling thread doesn't have any trace of where its master is. * @since 1.362 */ public static VirtualChannel getChannelToMaster() { - if (Jenkins.getInstance()!=null) + if (Jenkins.getInstanceOrNull()!=null) // check if calling thread is on master or on slave return FilePath.localChannel; - // if this method is called from within the slave computation thread, this should work + // if this method is called from within the agent computation thread, this should work Channel c = Channel.current(); if (c!=null && Boolean.TRUE.equals(c.getProperty("slave"))) return c; @@ -848,4 +874,9 @@ public class SlaveComputer extends Computer { return new ArrayList(SLAVE_LOG_HANDLER.getView()); } } + + // use RingBufferLogHandler class name to configure for backward compatibility + private static final int DEFAULT_RING_BUFFER_SIZE = SystemProperties.getInteger(RingBufferLogHandler.class.getName() + ".defaultSize", 256); + + private static final Logger LOGGER = Logger.getLogger(SlaveComputer.class.getName()); } diff --git a/core/src/main/java/hudson/slaves/WorkspaceList.java b/core/src/main/java/hudson/slaves/WorkspaceList.java index a344b45aacb87a3fd56bf540b2d27588677fb60b..17b789d6bc75fe4dbf2ead513c045ea90cefb051 100644 --- a/core/src/main/java/hudson/slaves/WorkspaceList.java +++ b/core/src/main/java/hudson/slaves/WorkspaceList.java @@ -25,7 +25,9 @@ package hudson.slaves; import hudson.FilePath; import hudson.Functions; +import jenkins.util.SystemProperties; import hudson.model.Computer; +import hudson.model.DirectoryBrowserSupport; import java.io.Closeable; import java.util.Date; @@ -283,10 +285,29 @@ public final class WorkspaceList { }; } + /** + * Locates a conventional temporary directory to be associated with a workspace. + *

This directory is suitable for temporary files to be deleted later in the course of a build, + * or caches and local repositories which should persist across builds done in the same workspace. + * (If multiple workspaces are present for a single job built concurrently, via {@link #allocate(FilePath)}, each will get its own temporary directory.) + *

It may also be used for security-sensitive files which {@link DirectoryBrowserSupport} ought not serve, + * acknowledging that these will be readable by builds of other jobs done on the same node. + *

Each plugin using this directory is responsible for specifying sufficiently unique subdirectory/file names. + * {@link FilePath#createTempFile} may be used for this purpose if desired. + *

The resulting directory may not exist; you may call {@link FilePath#mkdirs} on it if you need it to. + * It may be deleted alongside the workspace itself during cleanup actions. + * @param ws a directory such as a build workspace + * @return a sibling directory, for example {@code …/something@tmp} for {@code …/something} + * @since 1.652 + */ + public static FilePath tempDir(FilePath ws) { + return ws.sibling(ws.getName() + COMBINATOR + "tmp"); + } + private static final Logger LOGGER = Logger.getLogger(WorkspaceList.class.getName()); /** * The token that combines the project name and unique number to create unique workspace directory. */ - private static final String COMBINATOR = System.getProperty(WorkspaceList.class.getName(),"@"); + private static final String COMBINATOR = SystemProperties.getString(WorkspaceList.class.getName(),"@"); } diff --git a/core/src/main/java/hudson/slaves/package.html b/core/src/main/java/hudson/slaves/package.html index 9a8c33215d0fa4125bf1b4707d90d361e105fb62..a5080940f2ac071bdf59bf4e3cc7795d76feb757 100644 --- a/core/src/main/java/hudson/slaves/package.html +++ b/core/src/main/java/hudson/slaves/package.html @@ -23,5 +23,5 @@ THE SOFTWARE. --> -Code related to slaves. +Code related to agents. \ No newline at end of file diff --git a/core/src/main/java/hudson/tasks/ArtifactArchiver.java b/core/src/main/java/hudson/tasks/ArtifactArchiver.java index 17ad02f7c5948bc00292ea7583dddc6ec48b5e5a..ca1f154f156378212e0da302b6fbf947e0d4e16a 100644 --- a/core/src/main/java/hudson/tasks/ArtifactArchiver.java +++ b/core/src/main/java/hudson/tasks/ArtifactArchiver.java @@ -28,6 +28,7 @@ import jenkins.MasterToSlaveFileCallable; import hudson.Launcher; import hudson.Util; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.model.AbstractProject; import hudson.model.Result; import hudson.model.Run; @@ -38,6 +39,7 @@ import hudson.util.FormValidation; import java.io.File; import org.apache.tools.ant.types.FileSet; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.AncestorInPath; @@ -48,6 +50,7 @@ import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.CheckForNull; import net.sf.json.JSONObject; import javax.annotation.Nonnull; @@ -74,7 +77,7 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { /** * Possibly null 'excludes' pattern as in Ant. */ - private String excludes = ""; + private String excludes; @Deprecated private Boolean latestOnly; @@ -97,6 +100,12 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { */ @Nonnull private Boolean defaultExcludes = true; + + /** + * Indicate whether include and exclude patterns should be considered as case sensitive + */ + @Nonnull + private Boolean caseSensitive = true; @DataBoundConstructor public ArtifactArchiver(String artifacts) { this.artifacts = artifacts.trim(); @@ -131,11 +140,14 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { // Backwards compatibility for older builds public Object readResolve() { if (allowEmptyArchive == null) { - this.allowEmptyArchive = Boolean.getBoolean(ArtifactArchiver.class.getName()+".warnOnEmpty"); + this.allowEmptyArchive = SystemProperties.getBoolean(ArtifactArchiver.class.getName()+".warnOnEmpty"); } if (defaultExcludes == null){ defaultExcludes = true; } + if (caseSensitive == null) { + caseSensitive = true; + } return this; } @@ -143,11 +155,11 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { return artifacts; } - public String getExcludes() { + public @CheckForNull String getExcludes() { return excludes; } - @DataBoundSetter public final void setExcludes(String excludes) { + @DataBoundSetter public final void setExcludes(@CheckForNull String excludes) { this.excludes = Util.fixEmptyAndTrim(excludes); } @@ -188,6 +200,14 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { @DataBoundSetter public final void setDefaultExcludes(boolean defaultExcludes) { this.defaultExcludes = defaultExcludes; } + + public boolean isCaseSensitive() { + return caseSensitive; + } + + @DataBoundSetter public final void setCaseSensitive(boolean caseSensitive) { + this.caseSensitive = caseSensitive; + } private void listenerWarnOrError(TaskListener listener, String message) { if (allowEmptyArchive) { @@ -214,7 +234,7 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { try { String artifacts = build.getEnvironment(listener).expand(this.artifacts); - Map files = ws.act(new ListFiles(artifacts, excludes, defaultExcludes)); + Map files = ws.act(new ListFiles(artifacts, excludes, defaultExcludes, caseSensitive)); if (!files.isEmpty()) { build.pickArtifactManager().archive(ws, launcher, BuildListenerAdapter.wrap(listener), files); if (fingerprint) { @@ -228,7 +248,7 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { listenerWarnOrError(listener, Messages.ArtifactArchiver_NoMatchFound(artifacts)); String msg = null; try { - msg = ws.validateAntFileMask(artifacts, FilePath.VALIDATE_ANT_FILE_MASK_BOUND); + msg = ws.validateAntFileMask(artifacts, FilePath.VALIDATE_ANT_FILE_MASK_BOUND, caseSensitive); } catch (Exception e) { listenerWarnOrError(listener, e.getMessage()); } @@ -253,17 +273,21 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { private static final long serialVersionUID = 1; private final String includes, excludes; private final boolean defaultExcludes; + private final boolean caseSensitive; - ListFiles(String includes, String excludes, boolean defaultExcludes) { + ListFiles(String includes, String excludes, boolean defaultExcludes, boolean caseSensitive) { this.includes = includes; this.excludes = excludes; this.defaultExcludes = defaultExcludes; + this.caseSensitive = caseSensitive; } + @Override public Map invoke(File basedir, VirtualChannel channel) throws IOException, InterruptedException { Map r = new HashMap(); FileSet fileSet = Util.createFileSet(basedir, includes, excludes); fileSet.setDefaultexcludes(defaultExcludes); + fileSet.setCaseSensitive(caseSensitive); for (String f : fileSet.getDirectoryScanner().getIncludedFiles()) { f = f.replace(File.separatorChar, '/'); @@ -285,7 +309,7 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { @Deprecated public static volatile DescriptorImpl DESCRIPTOR; - @Extension + @Extension @Symbol("archiveArtifacts") public static class DescriptorImpl extends BuildStepDescriptor { public DescriptorImpl() { DESCRIPTOR = this; // backward compatibility @@ -296,13 +320,19 @@ public class ArtifactArchiver extends Recorder implements SimpleBuildStep { } /** - * Performs on-the-fly validation on the file mask wildcard. + * Performs on-the-fly validation of the file mask wildcard, when the artifacts + * textbox or the caseSensitive checkbox are modified */ - public FormValidation doCheckArtifacts(@AncestorInPath AbstractProject project, @QueryParameter String value) throws IOException { + public FormValidation doCheckArtifacts(@AncestorInPath AbstractProject project, + @QueryParameter String value, + @QueryParameter(value = "caseSensitive") String caseSensitive) + throws IOException { if (project == null) { return FormValidation.ok(); } - return FilePath.validateFileMask(project.getSomeWorkspace(),value); + // defensive approach to remain case sensitive in doubtful situations + boolean bCaseSensitive = caseSensitive == null || !"false".equals(caseSensitive); + return FilePath.validateFileMask(project.getSomeWorkspace(), value, bCaseSensitive); } @Override diff --git a/core/src/main/java/hudson/tasks/BatchFile.java b/core/src/main/java/hudson/tasks/BatchFile.java index b2506474be6bdb6aa7cc06a4d289329d2892b336..675c316eeb26f8ffb0f2d45d52f0b918ab8dd841 100644 --- a/core/src/main/java/hudson/tasks/BatchFile.java +++ b/core/src/main/java/hudson/tasks/BatchFile.java @@ -25,13 +25,21 @@ package hudson.tasks; import hudson.FilePath; import hudson.Extension; +import hudson.Util; import hudson.model.AbstractProject; +import hudson.util.FormValidation; import hudson.util.LineEndingConversion; -import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.QueryParameter; + import java.io.ObjectStreamException; +import javax.annotation.CheckForNull; + /** * Executes commands by using Windows batch file. * @@ -43,6 +51,8 @@ public class BatchFile extends CommandInterpreter { super(LineEndingConversion.convertEOL(command, LineEndingConversion.EOLType.Windows)); } + private Integer unstableReturn; + public String[] buildCommandLine(FilePath script) { return new String[] {"cmd","/c","call",script.getRemote()}; } @@ -55,11 +65,26 @@ public class BatchFile extends CommandInterpreter { return ".bat"; } + @CheckForNull + public final Integer getUnstableReturn() { + return new Integer(0).equals(unstableReturn) ? null : unstableReturn; + } + + @DataBoundSetter + public void setUnstableReturn(Integer unstableReturn) { + this.unstableReturn = unstableReturn; + } + + @Override + protected boolean isErrorlevelForUnstableBuild(int exitCode) { + return this.unstableReturn != null && exitCode != 0 && this.unstableReturn.equals(exitCode); + } + private Object readResolve() throws ObjectStreamException { return new BatchFile(command); } - @Extension + @Extension @Symbol("batchFile") public static final class DescriptorImpl extends BuildStepDescriptor { @Override public String getHelpFile() { @@ -70,9 +95,28 @@ public class BatchFile extends CommandInterpreter { return Messages.BatchFile_DisplayName(); } - @Override - public Builder newInstance(StaplerRequest req, JSONObject data) { - return new BatchFile(data.getString("command")); + /** + * Performs on-the-fly validation of the errorlevel. + */ + @Restricted(DoNotUse.class) + public FormValidation doCheckUnstableReturn(@QueryParameter String value) { + value = Util.fixEmptyAndTrim(value); + if (value == null) { + return FormValidation.ok(); + } + long unstableReturn; + try { + unstableReturn = Long.parseLong(value); + } catch (NumberFormatException e) { + return FormValidation.error(hudson.model.Messages.Hudson_NotANumber()); + } + if (unstableReturn == 0) { + return FormValidation.warning(hudson.tasks.Messages.BatchFile_invalid_exit_code_zero()); + } + if (unstableReturn < Integer.MIN_VALUE || unstableReturn > Integer.MAX_VALUE) { + return FormValidation.error(hudson.tasks.Messages.BatchFile_invalid_exit_code_range(unstableReturn)); + } + return FormValidation.ok(); } public boolean isApplicable(Class jobType) { diff --git a/core/src/main/java/hudson/tasks/BuildStep.java b/core/src/main/java/hudson/tasks/BuildStep.java index 83b351673bb52dc60c87f0ffe4e528616e93c096..e006adb8dd4f608fe165862cecf0e8dfc4d27db3 100644 --- a/core/src/main/java/hudson/tasks/BuildStep.java +++ b/core/src/main/java/hudson/tasks/BuildStep.java @@ -46,10 +46,11 @@ import java.util.List; import java.util.AbstractList; import java.util.Iterator; import java.util.WeakHashMap; -import jenkins.model.Jenkins; import jenkins.security.QueueItemAuthenticator; import org.acegisecurity.Authentication; +import javax.annotation.Nonnull; + /** * One step of the whole build process. * @@ -155,6 +156,7 @@ public interface BuildStep { * @return * can be empty but never null. */ + @Nonnull Collection getProjectActions(AbstractProject project); diff --git a/core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java b/core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java index 4f2db842a83a032c5a6b03b2bea7c9c17e096a6e..24e2093c106e837b3e04825ef5120d0b2ef9afd2 100644 --- a/core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java +++ b/core/src/main/java/hudson/tasks/BuildStepCompatibilityLayer.java @@ -41,6 +41,8 @@ import hudson.model.Run; import hudson.model.TaskListener; import jenkins.tasks.SimpleBuildStep; +import javax.annotation.Nonnull; + /** * Provides compatibility with {@link BuildStep} before 1.150 * so that old plugin binaries can continue to function with new Hudson. @@ -62,9 +64,10 @@ public abstract class BuildStepCompatibilityLayer implements BuildStep { } /** - * @inheritDoc + * {@inheritDoc} * @return Delegates to {@link SimpleBuildStep#perform(Run, FilePath, Launcher, TaskListener)} if possible, always returning true or throwing an error. */ + @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { if (this instanceof SimpleBuildStep) { // delegate to the overloaded version defined in SimpleBuildStep @@ -89,6 +92,7 @@ public abstract class BuildStepCompatibilityLayer implements BuildStep { return null; } + @Nonnull public Collection getProjectActions(AbstractProject project) { // delegate to getJobAction (singular) for backward compatible behavior Action a = getProjectAction(project); diff --git a/core/src/main/java/hudson/tasks/BuildTrigger.java b/core/src/main/java/hudson/tasks/BuildTrigger.java index 75b1b68a01100b8864636e84fb7494400ceb83ed..21dd6b3d0c9bb1ca328792275bddd4376f502f3b 100644 --- a/core/src/main/java/hudson/tasks/BuildTrigger.java +++ b/core/src/main/java/hudson/tasks/BuildTrigger.java @@ -46,6 +46,7 @@ import hudson.model.TaskListener; import hudson.model.listeners.ItemListener; import hudson.model.queue.Tasks; import hudson.security.ACL; +import hudson.security.ACLContext; import hudson.util.FormValidation; import java.io.IOException; import java.io.PrintStream; @@ -68,6 +69,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -331,7 +333,7 @@ public class BuildTrigger extends Recorder implements DependencyDeclarer { return this; } - @Extension + @Extension @Symbol("downstream") public static class DescriptorImpl extends BuildStepDescriptor { public String getDisplayName() { return Messages.BuildTrigger_DisplayName(); @@ -367,6 +369,8 @@ public class BuildTrigger extends Recorder implements DependencyDeclarer { * Form validation method. */ public FormValidation doCheck(@AncestorInPath AbstractProject project, @QueryParameter String value) { + // JENKINS-32525: Check that it behaves gracefully for an unknown context + if (project == null) return FormValidation.ok(Messages.BuildTrigger_ok_ancestor_is_null()); // Require CONFIGURE permission on this project if(!project.hasPermission(Item.CONFIGURE)) return FormValidation.ok(); @@ -409,11 +413,9 @@ public class BuildTrigger extends Recorder implements DependencyDeclarer { public static class ItemListenerImpl extends ItemListener { @Override public void onLocationChanged(final Item item, final String oldFullName, final String newFullName) { - ACL.impersonate(ACL.SYSTEM, new Runnable() { - @Override public void run() { - locationChanged(item, oldFullName, newFullName); - } - }); + try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + locationChanged(item, oldFullName, newFullName); + } } private void locationChanged(Item item, String oldFullName, String newFullName) { // update BuildTrigger of other projects that point to this object. diff --git a/core/src/main/java/hudson/tasks/BuildWrappers.java b/core/src/main/java/hudson/tasks/BuildWrappers.java index 8a969c4ad6d52c9fc3968e1188a81191ad2b3e12..874caedc30fe4a5c0413dd6204de995d6d465098 100644 --- a/core/src/main/java/hudson/tasks/BuildWrappers.java +++ b/core/src/main/java/hudson/tasks/BuildWrappers.java @@ -45,7 +45,7 @@ public class BuildWrappers { * for listing them. */ @Deprecated - public static final List> WRAPPERS = new DescriptorList(BuildWrapper.class); + public static final List> WRAPPERS = new DescriptorList<>(BuildWrapper.class); /** * List up all {@link BuildWrapperDescriptor}s that are applicable for the given project. @@ -55,7 +55,7 @@ public class BuildWrappers { * with {@link BuildWrapper} implementations before 1.150. */ public static List> getFor(AbstractProject project) { - List> result = new ArrayList>(); + List> result = new ArrayList<>(); Descriptor pd = Jenkins.getInstance().getDescriptor((Class)project.getClass()); for (Descriptor w : BuildWrapper.all()) { diff --git a/core/src/main/java/hudson/tasks/CommandInterpreter.java b/core/src/main/java/hudson/tasks/CommandInterpreter.java index bfab1c639d7583331f65255379e41f1685985eeb..fc45e20f0db1fd78dec94f6ed39e3ecb27c8eebb 100644 --- a/core/src/main/java/hudson/tasks/CommandInterpreter.java +++ b/core/src/main/java/hudson/tasks/CommandInterpreter.java @@ -25,7 +25,6 @@ package hudson.tasks; import hudson.FilePath; import hudson.Launcher; -import hudson.Launcher.ProcStarter; import hudson.Proc; import hudson.Util; import hudson.EnvVars; @@ -66,6 +65,18 @@ public abstract class CommandInterpreter extends Builder { return perform(build,launcher,(TaskListener)listener); } + /** + * Determines whether a non-zero exit code from the process should change the build + * status to {@link Result#UNSTABLE} instead of default {@link Result#FAILURE}. + * + * Changing to {@link Result#UNSTABLE} does not abort the build, next steps are continued. + * + * @since 2.26 + */ + protected boolean isErrorlevelForUnstableBuild(int exitCode) { + return false; + } + public boolean perform(AbstractBuild build, Launcher launcher, TaskListener listener) throws InterruptedException { FilePath ws = build.getWorkspace(); if (ws == null) { @@ -95,6 +106,11 @@ public abstract class CommandInterpreter extends Builder { envVars.put(e.getKey(),e.getValue()); r = join(launcher.launch().cmds(buildCommandLine(script)).envs(envVars).stdout(listener).pwd(ws).start()); + + if(isErrorlevelForUnstableBuild(r)) { + build.setResult(Result.UNSTABLE); + r = 0; + } } catch (IOException e) { Util.displayIOException(e, listener); e.printStackTrace(listener.fatalError(Messages.CommandInterpreter_CommandFailed())); @@ -129,7 +145,8 @@ public abstract class CommandInterpreter extends Builder { * * This allows subtypes to treat the exit code differently (for example by treating non-zero exit code * as if it's zero, or to set the status to {@link Result#UNSTABLE}). Any non-zero exit code will cause - * the build step to fail. + * the build step to fail. Use {@link #isErrorlevelForUnstableBuild(int exitCode)} to redefine the default + * behaviour. * * @since 1.549 */ diff --git a/core/src/main/java/hudson/tasks/Fingerprinter.java b/core/src/main/java/hudson/tasks/Fingerprinter.java index 051809dfca8a14db6825b8abc00ec339a5524368..1385e645b41ccc43b60ae46f1d60e68684efedfb 100644 --- a/core/src/main/java/hudson/tasks/Fingerprinter.java +++ b/core/src/main/java/hudson/tasks/Fingerprinter.java @@ -29,6 +29,7 @@ import hudson.Extension; import hudson.FilePath; import jenkins.MasterToSlaveFileCallable; import hudson.Launcher; +import jenkins.util.SystemProperties; import hudson.Util; import hudson.model.AbstractBuild; import hudson.model.AbstractProject; @@ -52,6 +53,7 @@ import net.sf.json.JSONObject; import org.acegisecurity.AccessDeniedException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.types.FileSet; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -82,7 +84,7 @@ import jenkins.tasks.SimpleBuildStep; * @author Kohsuke Kawaguchi */ public class Fingerprinter extends Recorder implements Serializable, DependencyDeclarer, SimpleBuildStep { - public static boolean enableFingerprintsInDependencyGraph = Boolean.getBoolean(Fingerprinter.class.getName() + ".enableFingerprintsInDependencyGraph"); + public static boolean enableFingerprintsInDependencyGraph = SystemProperties.getBoolean(Fingerprinter.class.getName() + ".enableFingerprintsInDependencyGraph"); /** * Comma-separated list of files/directories to be fingerprinted. @@ -248,7 +250,7 @@ public class Fingerprinter extends Recorder implements Serializable, DependencyD } } - @Extension + @Extension @Symbol("fingerprint") public static class DescriptorImpl extends BuildStepDescriptor { public String getDisplayName() { return Messages.Fingerprinter_DisplayName(); diff --git a/core/src/main/java/hudson/tasks/LogRotator.java b/core/src/main/java/hudson/tasks/LogRotator.java index 36efff2145ceb9cfcf3561c45de4008ab5601e14..c1efa625cf6e25977cff376c6945c31df66569db 100644 --- a/core/src/main/java/hudson/tasks/LogRotator.java +++ b/core/src/main/java/hudson/tasks/LogRotator.java @@ -29,6 +29,7 @@ import hudson.model.Job; import hudson.model.Run; import jenkins.model.BuildDiscarder; import jenkins.model.BuildDiscarderDescriptor; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.io.IOException; @@ -252,7 +253,7 @@ public class LogRotator extends BuildDiscarder { return String.valueOf(i); } - @Extension + @Extension @Symbol("logRotator") public static final class LRDescriptor extends BuildDiscarderDescriptor { public String getDisplayName() { return "Log Rotation"; diff --git a/core/src/main/java/hudson/tasks/Maven.java b/core/src/main/java/hudson/tasks/Maven.java index c61255afcaea074188c9087b1636c49d92811e80..a8d78ed344d97da22cdaefac3c9e418c7676e52e 100644 --- a/core/src/main/java/hudson/tasks/Maven.java +++ b/core/src/main/java/hudson/tasks/Maven.java @@ -62,11 +62,16 @@ import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.StaplerRequest; +import javax.annotation.Nonnull; import java.io.File; import java.io.IOException; +import java.io.ObjectStreamException; import java.util.ArrayList; import java.util.Properties; import java.util.StringTokenizer; @@ -137,6 +142,15 @@ public class Maven extends Builder { */ private GlobalSettingsProvider globalSettings; + /** + * Skip injecting build variables as properties into maven process. + * + * Defaults to false unless user requests otherwise. Old configurations are set to true to mimic the legacy behaviour. + * + * @since 2.12 + */ + private @Nonnull Boolean injectBuildVariables; + private final static String MAVEN_1_INSTALLATION_COMMON_FILE = "bin/maven"; private final static String MAVEN_2_INSTALLATION_COMMON_FILE = "bin/mvn"; @@ -155,8 +169,12 @@ public class Maven extends Builder { this(targets, name, pom, properties, jvmOptions, usePrivateRepository, null, null); } - @DataBoundConstructor public Maven(String targets,String name, String pom, String properties, String jvmOptions, boolean usePrivateRepository, SettingsProvider settings, GlobalSettingsProvider globalSettings) { + this(targets, name, pom, properties, jvmOptions, usePrivateRepository, settings, globalSettings, false); + } + + @DataBoundConstructor + public Maven(String targets,String name, String pom, String properties, String jvmOptions, boolean usePrivateRepository, SettingsProvider settings, GlobalSettingsProvider globalSettings, boolean injectBuildVariables) { this.targets = targets; this.mavenName = name; this.pom = Util.fixEmptyAndTrim(pom); @@ -165,6 +183,7 @@ public class Maven extends Builder { this.usePrivateRepository = usePrivateRepository; this.settings = settings != null ? settings : GlobalMavenConfig.get().getSettingsProvider(); this.globalSettings = globalSettings != null ? globalSettings : GlobalMavenConfig.get().getGlobalSettingsProvider(); + this.injectBuildVariables = injectBuildVariables; } public String getTargets() { @@ -201,6 +220,11 @@ public class Maven extends Builder { return usePrivateRepository; } + @Restricted(NoExternalUse.class) // Exposed for view + public boolean isInjectBuildVariables() { + return injectBuildVariables; + } + /** * Gets the Maven to invoke, * or null to invoke the default one. @@ -213,6 +237,13 @@ public class Maven extends Builder { return null; } + private Object readResolve() throws ObjectStreamException { + if (injectBuildVariables == null) { + injectBuildVariables = true; + } + return this; + } + /** * Looks for pom.xlm or project.xml to determine the maven executable * name. @@ -250,8 +281,6 @@ public class Maven extends Builder { seed = new File(ws,"project.xml").exists() ? "maven" : "mvn"; } - if(Functions.isWindows()) - seed += ".bat"; return seed; } } @@ -311,11 +340,13 @@ public class Maven extends Builder { } } - Set sensitiveVars = build.getSensitiveBuildVariables(); + if (isInjectBuildVariables()) { + Set sensitiveVars = build.getSensitiveBuildVariables(); + args.addKeyValuePairs("-D",build.getBuildVariables(),sensitiveVars); + final VariableResolver resolver = new Union(new ByMap(env), vr); + args.addKeyValuePairsFromPropertyString("-D",this.properties,resolver,sensitiveVars); + } - args.addKeyValuePairs("-D",build.getBuildVariables(),sensitiveVars); - final VariableResolver resolver = new Union(new ByMap(env), vr); - args.addKeyValuePairsFromPropertyString("-D",this.properties,resolver,sensitiveVars); if (usesPrivateRepository()) args.add("-Dmaven.repo.local=" + build.getWorkspace().child(".repository")); args.addTokenized(normalizedTarget); @@ -388,7 +419,7 @@ public class Maven extends Builder { @Deprecated public static DescriptorImpl DESCRIPTOR; - @Extension + @Extension @Symbol("maven") public static final class DescriptorImpl extends BuildStepDescriptor { @CopyOnWrite private volatile MavenInstallation[] installations = new MavenInstallation[0]; @@ -441,6 +472,11 @@ public class Maven extends Builder { @Override public Builder newInstance(StaplerRequest req, JSONObject formData) throws FormException { + if (req == null) { + // This state is prohibited according to the Javadoc of the super method. + throw new FormException("Maven Build Step new instance method is called for null Stapler request. " + + "Such call is prohibited.", "req"); + } return req.bindJSON(Maven.class,formData); } } @@ -460,7 +496,7 @@ public class Maven extends Builder { /** * @deprecated since 2009-02-25. */ - @Deprecated // kept for backward compatiblity - use getHome() + @Deprecated // kept for backward compatibility - use getHome() private transient String mavenHome; /** @@ -607,9 +643,7 @@ public class Maven extends Builder { public boolean getExists() { try { return getExecutable(new LocalLauncher(new StreamTaskListener(new NullStream())))!=null; - } catch (IOException e) { - return false; - } catch (InterruptedException e) { + } catch (IOException | InterruptedException e) { return false; } } @@ -624,7 +658,7 @@ public class Maven extends Builder { return new MavenInstallation(getName(), translateFor(node, log), getProperties().toList()); } - @Extension + @Extension @Symbol("maven") public static class DescriptorImpl extends ToolDescriptor { @Override public String getDisplayName() { @@ -682,7 +716,7 @@ public class Maven extends Builder { super(id); } - @Extension + @Extension @Symbol("maven") public static final class DescriptorImpl extends DownloadFromUrlInstaller.DescriptorImpl { public String getDisplayName() { return Messages.InstallFromApache(); diff --git a/core/src/main/java/hudson/tasks/Shell.java b/core/src/main/java/hudson/tasks/Shell.java index 45d9c7d84cefe1d1214c9f6dfdc5dab1750d5b08..bdd3ca44cfd743e922682818a9d6f9c69c6d36bc 100644 --- a/core/src/main/java/hudson/tasks/Shell.java +++ b/core/src/main/java/hudson/tasks/Shell.java @@ -35,7 +35,11 @@ import java.io.ObjectStreamException; import hudson.util.LineEndingConversion; import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.QueryParameter; @@ -45,17 +49,24 @@ import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.CheckForNull; + /** * Executes a series of commands by using a shell. * * @author Kohsuke Kawaguchi */ public class Shell extends CommandInterpreter { + @DataBoundConstructor public Shell(String command) { super(LineEndingConversion.convertEOL(command, LineEndingConversion.EOLType.Unix)); } + private Integer unstableReturn; + + + /** * Older versions of bash have a bug where non-ASCII on the first line * makes the shell think the file is a binary file and not a script. Adding @@ -81,7 +92,7 @@ public class Shell extends CommandInterpreter { args.add(script.getRemote()); args.set(0,args.get(0).substring(2)); // trim off "#!" return args.toArray(new String[args.size()]); - } else + } else return new String[] { getDescriptor().getShellOrDefault(script.getChannel()), "-xe", script.getRemote()}; } @@ -93,6 +104,21 @@ public class Shell extends CommandInterpreter { return ".sh"; } + @CheckForNull + public final Integer getUnstableReturn() { + return new Integer(0).equals(unstableReturn) ? null : unstableReturn; + } + + @DataBoundSetter + public void setUnstableReturn(Integer unstableReturn) { + this.unstableReturn = unstableReturn; + } + + @Override + protected boolean isErrorlevelForUnstableBuild(int exitCode) { + return this.unstableReturn != null && exitCode != 0 && this.unstableReturn.equals(exitCode); + } + @Override public DescriptorImpl getDescriptor() { return (DescriptorImpl)super.getDescriptor(); @@ -102,7 +128,7 @@ public class Shell extends CommandInterpreter { return new Shell(command); } - @Extension + @Extension @Symbol("shell") public static class DescriptorImpl extends BuildStepDescriptor { /** * Shell executable, or null to default. @@ -133,7 +159,7 @@ public class Shell extends CommandInterpreter { } public String getShellOrDefault(VirtualChannel channel) { - if (shell != null) + if (shell != null) return shell; String interpreter = null; @@ -150,7 +176,7 @@ public class Shell extends CommandInterpreter { return interpreter; } - + public void setShell(String shell) { this.shell = Util.fixEmptyAndTrim(shell); save(); @@ -160,6 +186,30 @@ public class Shell extends CommandInterpreter { return Messages.Shell_DisplayName(); } + /** + * Performs on-the-fly validation of the exit code. + */ + @Restricted(DoNotUse.class) + public FormValidation doCheckUnstableReturn(@QueryParameter String value) { + value = Util.fixEmptyAndTrim(value); + if (value == null) { + return FormValidation.ok(); + } + long unstableReturn; + try { + unstableReturn = Long.parseLong(value); + } catch (NumberFormatException e) { + return FormValidation.error(hudson.model.Messages.Hudson_NotANumber()); + } + if (unstableReturn == 0) { + return FormValidation.warning(hudson.tasks.Messages.Shell_invalid_exit_code_zero()); + } + if (unstableReturn < 1 || unstableReturn > 255) { + return FormValidation.error(hudson.tasks.Messages.Shell_invalid_exit_code_range(unstableReturn)); + } + return FormValidation.ok(); + } + @Override public boolean configure(StaplerRequest req, JSONObject data) throws FormException { req.bindJSON(this, data); @@ -171,9 +221,9 @@ public class Shell extends CommandInterpreter { */ public FormValidation doCheckShell(@QueryParameter String value) { // Executable requires admin permission - return FormValidation.validateExecutable(value); + return FormValidation.validateExecutable(value); } - + private static final class Shellinterpreter extends MasterToSlaveCallable { private static final long serialVersionUID = 1L; @@ -182,8 +232,8 @@ public class Shell extends CommandInterpreter { return Functions.isWindows() ? "sh" : "/bin/sh"; } } - + } - + private static final Logger LOGGER = Logger.getLogger(Shell.class.getName()); } diff --git a/core/src/main/java/hudson/tasks/UserNameResolver.java b/core/src/main/java/hudson/tasks/UserNameResolver.java index 49e518a6c60bcea84d8cd6b113ba798600644998..5aa7af3768737af85d837bc70f75e7c0cc89a17f 100644 --- a/core/src/main/java/hudson/tasks/UserNameResolver.java +++ b/core/src/main/java/hudson/tasks/UserNameResolver.java @@ -27,7 +27,6 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionListView; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import hudson.model.User; import java.util.List; diff --git a/core/src/main/java/hudson/tasks/_maven/Maven3MojoNote.java b/core/src/main/java/hudson/tasks/_maven/Maven3MojoNote.java index 8dfb2c7d9140705796a8d99e7ba918bf5d80a5ad..9f2fc0ee0df13be96df149421e1ce39f71241032 100644 --- a/core/src/main/java/hudson/tasks/_maven/Maven3MojoNote.java +++ b/core/src/main/java/hudson/tasks/_maven/Maven3MojoNote.java @@ -28,6 +28,7 @@ import hudson.MarkupText; import hudson.console.ConsoleAnnotationDescriptor; import hudson.console.ConsoleAnnotator; import hudson.console.ConsoleNote; +import org.jenkinsci.Symbol; import java.util.regex.Pattern; @@ -57,7 +58,7 @@ public class Maven3MojoNote extends ConsoleNote { return null; } - @Extension + @Extension @Symbol("maven3Mojos") public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { public String getDisplayName() { return "Maven 3 Mojos"; diff --git a/core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java b/core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java index 5b13137bc848ca01c64a9c6fe953d9b28f57dd0c..caecd18acf391054f7ba9c284d20aa680fc84f26 100644 --- a/core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java +++ b/core/src/main/java/hudson/tasks/_maven/MavenErrorNote.java @@ -28,6 +28,7 @@ import hudson.MarkupText; import hudson.console.ConsoleAnnotationDescriptor; import hudson.console.ConsoleAnnotator; import hudson.console.ConsoleNote; +import org.jenkinsci.Symbol; import java.util.regex.Pattern; @@ -44,7 +45,7 @@ public class MavenErrorNote extends ConsoleNote { return null; } - @Extension + @Extension @Symbol("mavenErrors") public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { public String getDisplayName() { return "Maven Errors"; diff --git a/core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java b/core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java index 68ade17692b7d6bff1468cfb9e1efb267d09e45e..99775fbaef7c5c220b57fc6898930ec3f3d7dfad 100644 --- a/core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java +++ b/core/src/main/java/hudson/tasks/_maven/MavenMojoNote.java @@ -28,6 +28,7 @@ import hudson.MarkupText; import hudson.console.ConsoleAnnotationDescriptor; import hudson.console.ConsoleAnnotator; import hudson.console.ConsoleNote; +import org.jenkinsci.Symbol; import java.util.regex.Pattern; @@ -49,7 +50,7 @@ public class MavenMojoNote extends ConsoleNote { return null; } - @Extension + @Extension @Symbol("mavenMojos") public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { public String getDisplayName() { return "Maven Mojos"; diff --git a/core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java b/core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java index afecf58dda016e0eb355f802849b63b61e6c9c1f..41b3080efa059d0520014302c4f0c337cc35bc07 100644 --- a/core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java +++ b/core/src/main/java/hudson/tasks/_maven/MavenWarningNote.java @@ -28,6 +28,7 @@ import hudson.MarkupText; import hudson.console.ConsoleAnnotationDescriptor; import hudson.console.ConsoleAnnotator; import hudson.console.ConsoleNote; +import org.jenkinsci.Symbol; import java.util.regex.Pattern; @@ -46,7 +47,7 @@ public class MavenWarningNote extends ConsoleNote { return null; } - @Extension + @Extension @Symbol("mavenWarnings") public static final class DescriptorImpl extends ConsoleAnnotationDescriptor { public String getDisplayName() { return "Maven Warnings"; diff --git a/core/src/main/java/hudson/tools/BatchCommandInstaller.java b/core/src/main/java/hudson/tools/BatchCommandInstaller.java index 2085fe7fa0341b88c07fc35106387537a092f7b2..48b6a8d24bfc08343820ac8e1bd429d4db6acdfe 100644 --- a/core/src/main/java/hudson/tools/BatchCommandInstaller.java +++ b/core/src/main/java/hudson/tools/BatchCommandInstaller.java @@ -27,6 +27,7 @@ package hudson.tools; import hudson.Extension; import hudson.FilePath; import hudson.util.LineEndingConversion; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.io.ObjectStreamException; @@ -57,7 +58,7 @@ public class BatchCommandInstaller extends AbstractCommandInstaller { return new BatchCommandInstaller(getLabel(), getCommand(), getToolHome()); } - @Extension + @Extension @Symbol("batchFile") public static class DescriptorImpl extends Descriptor { @Override diff --git a/core/src/main/java/hudson/tools/CommandInstaller.java b/core/src/main/java/hudson/tools/CommandInstaller.java index 6f2506dd04f4e83f9675b3fa1c5cb5d5b2660538..a9ac484808c05d24732e121efb4ea25a699ae131 100644 --- a/core/src/main/java/hudson/tools/CommandInstaller.java +++ b/core/src/main/java/hudson/tools/CommandInstaller.java @@ -27,6 +27,7 @@ package hudson.tools; import hudson.Extension; import hudson.FilePath; import hudson.util.LineEndingConversion; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.io.ObjectStreamException; @@ -56,7 +57,7 @@ public class CommandInstaller extends AbstractCommandInstaller { return new CommandInstaller(getLabel(), getCommand(), getToolHome()); } - @Extension + @Extension @Symbol("command") public static class DescriptorImpl extends Descriptor { @Override diff --git a/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java b/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java index 938325f6681de75c893be2ceb6169f5596773a44..5ad04e76ef63e1d6a0215e9c5048412ab3ffa2de 100644 --- a/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java +++ b/core/src/main/java/hudson/tools/DownloadFromUrlInstaller.java @@ -4,11 +4,13 @@ import hudson.FilePath; import hudson.model.DownloadService.Downloadable; import hudson.model.Node; import hudson.model.TaskListener; +import hudson.slaves.NodeSpecific; import net.sf.json.JSONObject; import java.io.IOException; import java.util.Arrays; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.net.URL; @@ -64,6 +66,10 @@ public abstract class DownloadFromUrlInstaller extends ToolInstaller { return expected; } + if (inst instanceof NodeSpecific) { + inst = (Installable) ((NodeSpecific) inst).forNode(node, log); + } + if(isUpToDate(expected,inst)) return expected; @@ -121,10 +127,94 @@ public abstract class DownloadFromUrlInstaller extends ToolInstaller { Downloadable.all().add(createDownloadable()); } - protected Downloadable createDownloadable() { + /** + * function that creates a {@link Downloadable}. + * @return a downloadable object + */ + public Downloadable createDownloadable() { + if (this instanceof DownloadFromUrlInstaller.DescriptorImpl) { + final DownloadFromUrlInstaller.DescriptorImpl delegate = (DownloadFromUrlInstaller.DescriptorImpl)this; + return new Downloadable(getId()) { + public JSONObject reduce(List jsonList) { + if (isDefaultSchema(jsonList)) { + return delegate.reduce(jsonList); + } else { + //if it's not default schema fall back to the super class implementation + return super.reduce(jsonList); + } + } + }; + } return new Downloadable(getId()); } + /** + * this function checks is the update center tool has the default schema + * @param jsonList the list of Update centers json files + * @return true if the schema is the default one (id, name, url), false otherwise + */ + private boolean isDefaultSchema(List jsonList) { + JSONObject jsonToolInstallerList = jsonList.get(0); + ToolInstallerList toolInstallerList = (ToolInstallerList) JSONObject.toBean(jsonToolInstallerList, ToolInstallerList.class); + + if (toolInstallerList != null) { + ToolInstallerEntry[] entryList = toolInstallerList.list; + ToolInstallerEntry sampleEntry = entryList[0]; + if (sampleEntry != null) { + if (sampleEntry.id != null && sampleEntry.name != null && sampleEntry.url != null) { + return true; + } + } + } + return false; + } + + private JSONObject reduce(List jsonList) { + List reducedToolEntries = new LinkedList<>(); + //collect all tool installers objects from the multiple json objects + for (JSONObject jsonToolList : jsonList) { + ToolInstallerList toolInstallerList = (ToolInstallerList) JSONObject.toBean(jsonToolList, ToolInstallerList.class); + reducedToolEntries.addAll(Arrays.asList(toolInstallerList.list)); + } + + while (Downloadable.hasDuplicates(reducedToolEntries, "id")) { + List tmpToolInstallerEntries = new LinkedList<>(); + //we need to skip the processed entries + boolean processed[] = new boolean[reducedToolEntries.size()]; + for (int i = 0; i < reducedToolEntries.size(); i++) { + if (processed[i] == true) { + continue; + } + ToolInstallerEntry data1 = reducedToolEntries.get(i); + boolean hasDuplicate = false; + for (int j = i + 1; j < reducedToolEntries.size(); j ++) { + ToolInstallerEntry data2 = reducedToolEntries.get(j); + //if we found a duplicate we choose the first one + if (data1.id.equals(data2.id)) { + hasDuplicate = true; + processed[j] = true; + tmpToolInstallerEntries.add(data1); + //after the first duplicate has been found we break the loop since the duplicates are + //processed two by two + break; + } + } + //if no duplicate has been found we just insert the entry in the tmp list + if (!hasDuplicate) { + tmpToolInstallerEntries.add(data1); + } + } + reducedToolEntries = tmpToolInstallerEntries; + } + + ToolInstallerList toolInstallerList = new ToolInstallerList(); + toolInstallerList.list = new ToolInstallerEntry[reducedToolEntries.size()]; + reducedToolEntries.toArray(toolInstallerList.list); + JSONObject reducedToolEntriesJsonList = JSONObject.fromObject(toolInstallerList); + //return the list with no duplicates + return reducedToolEntriesJsonList; + } + /** * This ID needs to be unique, and needs to match the ID token in the JSON update file. *

@@ -175,4 +265,17 @@ public abstract class DownloadFromUrlInstaller extends ToolInstaller { */ public String url; } + + /** + * Convenient abstract class to implement a NodeSpecificInstallable based on an existing Installable + * @since 1.626 + */ + public abstract class NodeSpecificInstallable extends Installable implements NodeSpecific { + + public NodeSpecificInstallable(Installable inst) { + this.id = inst.id; + this.name = inst.name; + this.url = inst.url; + } + } } diff --git a/core/src/main/java/hudson/tools/InstallSourceProperty.java b/core/src/main/java/hudson/tools/InstallSourceProperty.java index 3680a8f68eaeef7ceee50ef39b6531dfa8866640..7ef474d015f32b0135b37bface45273e71ea3040 100644 --- a/core/src/main/java/hudson/tools/InstallSourceProperty.java +++ b/core/src/main/java/hudson/tools/InstallSourceProperty.java @@ -27,6 +27,7 @@ import hudson.Extension; import hudson.util.DescribableList; import hudson.model.Descriptor; import hudson.model.Saveable; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.util.List; @@ -61,7 +62,7 @@ public class InstallSourceProperty extends ToolProperty { return ToolInstallation.class; } - @Extension + @Extension @Symbol("installSource") public static class DescriptorImpl extends ToolPropertyDescriptor { public String getDisplayName() { return Messages.InstallSourceProperty_DescriptorImpl_displayName(); diff --git a/core/src/main/java/hudson/tools/InstallerTranslator.java b/core/src/main/java/hudson/tools/InstallerTranslator.java index 87d1dcd1e3656ad197c6d71b8e3e7812a51f343f..fd45212bd7401bc565438296ce140f2abd2c0b1c 100644 --- a/core/src/main/java/hudson/tools/InstallerTranslator.java +++ b/core/src/main/java/hudson/tools/InstallerTranslator.java @@ -28,6 +28,7 @@ import hudson.Extension; import hudson.model.Node; import hudson.model.TaskListener; import java.io.IOException; +import java.util.ArrayList; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.Semaphore; @@ -50,6 +51,9 @@ public class InstallerTranslator extends ToolLocationTranslator { if (isp == null) { return null; } + + ArrayList inapplicableInstallersMessages = new ArrayList(); + for (ToolInstaller installer : isp.installers) { if (installer.appliesTo(node)) { Semaphore semaphore; @@ -69,8 +73,16 @@ public class InstallerTranslator extends ToolLocationTranslator { } finally { semaphore.release(); } + } else { + inapplicableInstallersMessages.add(Messages.CannotBeInstalled( + installer.getDescriptor().getDisplayName(), + tool.getName(), + node.getDisplayName())); } } + for (String message : inapplicableInstallersMessages) { + log.getLogger().println(message); + } return null; } diff --git a/core/src/main/java/hudson/tools/JDKInstaller.java b/core/src/main/java/hudson/tools/JDKInstaller.java index 8248d416a4a3862248637bf7954787e1ae8a36b8..c77ce7e9577d0bf6e4b9ed98db0b280ab6bbf4ef 100644 --- a/core/src/main/java/hudson/tools/JDKInstaller.java +++ b/core/src/main/java/hudson/tools/JDKInstaller.java @@ -32,9 +32,9 @@ import hudson.ProxyConfiguration; import hudson.Util; import hudson.model.DownloadService.Downloadable; import hudson.model.JDK; +import hudson.model.Job; import hudson.model.Node; import hudson.model.TaskListener; -import hudson.remoting.Callable; import hudson.util.ArgumentListBuilder; import hudson.util.FormValidation; import hudson.util.HttpResponses; @@ -42,6 +42,7 @@ import hudson.util.Secret; import jenkins.model.Jenkins; import jenkins.security.MasterToSlaveCallable; import net.sf.json.JSONObject; +import net.sf.json.JsonConfig; import org.apache.commons.httpclient.Cookie; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethodBase; @@ -51,6 +52,7 @@ import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.io.IOUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; @@ -70,6 +72,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.logging.Logger; @@ -270,11 +273,8 @@ public class JDKInstaller extends ToolInstaller { if (r != 0) { out.println(Messages.JDKInstaller_FailedToInstallJDK(r)); // log file is in UTF-16 - InputStreamReader in = new InputStreamReader(fs.read(logFile), "UTF-16"); - try { - IOUtils.copy(in,new OutputStreamWriter(out)); - } finally { - in.close(); + try (InputStreamReader in = new InputStreamReader(fs.read(logFile), "UTF-16")) { + IOUtils.copy(in, new OutputStreamWriter(out)); } throw new AbortException(); } @@ -446,8 +446,7 @@ public class JDKInstaller extends ToolInstaller { HttpClient hc = new HttpClient(); hc.getParams().setParameter("http.useragent","Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)"); - Jenkins j = Jenkins.getInstance(); - ProxyConfiguration jpc = j!=null ? j.proxy : null; + ProxyConfiguration jpc = Jenkins.getInstance().proxy; if(jpc != null) { hc.getHostConfiguration().setProxy(jpc.name, jpc.port); if(jpc.getUserName() != null) @@ -513,17 +512,14 @@ public class JDKInstaller extends ToolInstaller { m = post; } else { - log.getLogger().println("Downloading " + m.getResponseContentLength() + "bytes"); + log.getLogger().println("Downloading " + m.getResponseContentLength() + " bytes"); // download to a temporary file and rename it in to handle concurrency and failure correctly, File tmp = new File(cache.getPath()+".tmp"); try { tmp.getParentFile().mkdirs(); - FileOutputStream out = new FileOutputStream(tmp); - try { + try (FileOutputStream out = new FileOutputStream(tmp)) { IOUtils.copy(m.getResponseBodyAsStream(), out); - } finally { - out.close(); } tmp.renameTo(cache); @@ -670,8 +666,8 @@ public class JDKInstaller extends ToolInstaller { } public static final class JDKFamilyList { - public int version; public JDKFamily[] data = new JDKFamily[0]; + public int version; public boolean isEmpty() { for (JDKFamily f : data) { @@ -698,6 +694,18 @@ public class JDKInstaller extends ToolInstaller { } public static final class JDKRelease { + /** + * the list of {@Link JDKFile}s + */ + public JDKFile[] files; + /** + * the license path + */ + public String licpath; + /** + * the license title + */ + public String lictitle; /** * This maps to the former product code, like "jdk-6u13-oth-JPR" */ @@ -706,7 +714,6 @@ public class JDKInstaller extends ToolInstaller { * This is human readable. */ public String title; - public JDKFile[] files; /** * We used to use IDs like "jdk-6u13-oth-JPR@CDS-CDS_Developer", but Oracle switched to just "jdk-6u13-oth-JPR". @@ -718,9 +725,9 @@ public class JDKInstaller extends ToolInstaller { } public static final class JDKFile { + public String filepath; public String name; public String title; - public String filepath; } @Override @@ -728,7 +735,7 @@ public class JDKInstaller extends ToolInstaller { return (DescriptorImpl)super.getDescriptor(); } - @Extension + @Extension @Symbol("jdkInstaller") public static final class DescriptorImpl extends ToolInstallerDescriptor { private String username; private Secret password; @@ -792,7 +799,7 @@ public class JDKInstaller extends ToolInstaller { /** * JDK list. */ - @Extension + @Extension @Symbol("jdk") public static final class JDKList extends Downloadable { public JDKList() { super(JDKInstaller.class); @@ -803,6 +810,123 @@ public class JDKInstaller extends ToolInstaller { if(d==null) return new JDKFamilyList(); return (JDKFamilyList)JSONObject.toBean(d,JDKFamilyList.class); } + + /** + * @{inheritDoc} + */ + @Override + public JSONObject reduce (List jsonObjectList) { + List reducedFamilies = new LinkedList<>(); + int version = 0; + JsonConfig jsonConfig = new JsonConfig(); + jsonConfig.registerPropertyExclusion(JDKFamilyList.class, "empty"); + jsonConfig.setRootClass(JDKFamilyList.class); + //collect all JDKFamily objects from the multiple json objects + for (JSONObject jsonJdkFamilyList : jsonObjectList) { + JDKFamilyList jdkFamilyList = (JDKFamilyList)JSONObject.toBean(jsonJdkFamilyList, jsonConfig); + if (version == 0) { + //we set as version the version of the first update center + version = jdkFamilyList.version; + } + JDKFamily[] jdkFamilies = jdkFamilyList.data; + reducedFamilies.addAll(Arrays.asList(jdkFamilies)); + } + //we iterate on the list and reduce it until there are no more duplicates + //this could be made recursive + while (hasDuplicates(reducedFamilies, "name")) { + //create a temporary list to store the tmp result + List tmpReducedFamilies = new LinkedList<>(); + //we need to skip the processed families + boolean processed [] = new boolean[reducedFamilies.size()]; + for (int i = 0; i < reducedFamilies.size(); i ++ ) { + if (processed [i] == true) { + continue; + } + JDKFamily data1 = reducedFamilies.get(i); + boolean hasDuplicate = false; + for (int j = i + 1; j < reducedFamilies.size(); j ++ ) { + JDKFamily data2 = reducedFamilies.get(j); + //if we found a duplicate we need to merge the families + if (data1.name.equals(data2.name)) { + hasDuplicate = true; + processed [j] = true; + JDKFamily reducedData = reduceData(data1.name, new LinkedList(Arrays.asList(data1.releases)), new LinkedList(Arrays.asList(data2.releases))); + tmpReducedFamilies.add(reducedData); + //after the first duplicate has been found we break the loop since the duplicates are + //processed two by two + break; + } + } + //if no duplicate has been found we just insert the whole family in the tmp list + if (!hasDuplicate) { + tmpReducedFamilies.add(data1); + } + } + reducedFamilies = tmpReducedFamilies; + } + JDKFamilyList jdkFamilyList = new JDKFamilyList(); + jdkFamilyList.version = version; + jdkFamilyList.data = new JDKFamily[reducedFamilies.size()]; + reducedFamilies.toArray(jdkFamilyList.data); + JSONObject reducedJdkFamilyList = JSONObject.fromObject(jdkFamilyList, jsonConfig); + //return the list with no duplicates + return reducedJdkFamilyList; + } + + private JDKFamily reduceData(String name, List releases1, List releases2) { + LinkedList reducedReleases = new LinkedList<>(); + for (Iterator iterator = releases1.iterator(); iterator.hasNext(); ) { + JDKRelease release1 = iterator.next(); + boolean hasDuplicate = false; + for (Iterator iterator2 = releases2.iterator(); iterator2.hasNext(); ) { + JDKRelease release2 = iterator2.next(); + if (release1.name.equals(release2.name)) { + hasDuplicate = true; + JDKRelease reducedRelease = reduceReleases(release1, new LinkedList(Arrays.asList(release1.files)), new LinkedList(Arrays.asList(release2.files))); + iterator2.remove(); + reducedReleases.add(reducedRelease); + //we assume that in one release list there are no duplicates so we stop at the first one + break; + } + } + if (!hasDuplicate) { + reducedReleases.add(release1); + } + } + reducedReleases.addAll(releases2); + JDKFamily reducedFamily = new JDKFamily(); + reducedFamily.name = name; + reducedFamily.releases = new JDKRelease[reducedReleases.size()]; + reducedReleases.toArray(reducedFamily.releases); + return reducedFamily; + } + + private JDKRelease reduceReleases(JDKRelease release, List files1, List files2) { + LinkedList reducedFiles = new LinkedList<>(); + for (Iterator iterator1 = files1.iterator(); iterator1.hasNext(); ) { + JDKFile file1 = iterator1.next(); + for (Iterator iterator2 = files2.iterator(); iterator2.hasNext(); ) { + JDKFile file2 = iterator2.next(); + if (file1.name.equals(file2.name)) { + iterator2.remove(); + //we assume the in one file list there are no duplicates so we break after we find the + //first match + break; + } + } + } + reducedFiles.addAll(files1); + reducedFiles.addAll(files2); + + JDKRelease jdkRelease = new JDKRelease(); + jdkRelease.files = new JDKFile[reducedFiles.size()]; + reducedFiles.toArray(jdkRelease.files); + jdkRelease.name = release.name; + jdkRelease.licpath = release.licpath; + jdkRelease.lictitle = release.lictitle; + jdkRelease.title = release.title; + return jdkRelease; + } } private static final Logger LOGGER = Logger.getLogger(JDKInstaller.class.getName()); diff --git a/core/src/main/java/hudson/tools/ToolDescriptor.java b/core/src/main/java/hudson/tools/ToolDescriptor.java index 567c298a0dd89802f31acf62ed8b1be18f67e5c2..3c944d86dc31c9b326268bcf8c361ed25a27e337 100644 --- a/core/src/main/java/hudson/tools/ToolDescriptor.java +++ b/core/src/main/java/hudson/tools/ToolDescriptor.java @@ -24,6 +24,7 @@ package hudson.tools; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.Descriptor; import hudson.util.DescribableList; import hudson.util.FormValidation; @@ -34,7 +35,10 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Collections; import java.util.List; + +import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; +import jenkins.tools.ToolConfigurationCategory; import net.sf.json.JSONObject; import org.jvnet.tiger_types.Types; import org.kohsuke.stapler.QueryParameter; @@ -56,6 +60,7 @@ public abstract class ToolDescriptor extends Descrip * @return read-only list of installations; * can be empty but never null. */ + @SuppressWarnings("unchecked") public T[] getInstallations() { if (installations != null) return installations.clone(); @@ -67,10 +72,19 @@ public abstract class ToolDescriptor extends Descrip Class t = Types.erasure(pt.getActualTypeArguments()[0]); return (T[])Array.newInstance(t,0); } else { - // can't infer the type. fallacbk - return (T[])new Object[0]; + // can't infer the type. Fallback + return emptyArray_unsafeCast(); } } + + //TODO: Get rid of it? + //It's unsafe according to http://stackoverflow.com/questions/2927391/whats-the-reason-i-cant-create-generic-array-types-in-java + @SuppressWarnings("unchecked") + @SuppressFBWarnings(value = "BC_IMPOSSIBLE_DOWNCAST", + justification = "Such casting is generally unsafe, but we use it as a last resort.") + private T[] emptyArray_unsafeCast() { + return (T[])new Object[0]; + } /** * Overwrites {@link ToolInstallation}s. @@ -86,7 +100,13 @@ public abstract class ToolDescriptor extends Descrip * Lists up {@link ToolPropertyDescriptor}s that are applicable to this {@link ToolInstallation}. */ public List getPropertyDescriptors() { - return PropertyDescriptor.for_(ToolProperty.all(),clazz); + return PropertyDescriptor.for_(ToolProperty.all(), clazz); + } + + + @Override + public GlobalConfigurationCategory getCategory() { + return GlobalConfigurationCategory.get(ToolConfigurationCategory.class); } /** diff --git a/core/src/main/java/hudson/tools/ToolInstallation.java b/core/src/main/java/hudson/tools/ToolInstallation.java index a14fed1c1bf257ef7ad13cab3861d486f321418c..e6f104dffc4cce3a27d6d17e2a297a85f85865c9 100644 --- a/core/src/main/java/hudson/tools/ToolInstallation.java +++ b/core/src/main/java/hudson/tools/ToolInstallation.java @@ -53,8 +53,8 @@ import jenkins.model.Jenkins; * this class, but choosing this class as a base class has several benefits: * *

    - *
  • Hudson allows admins to specify different locations for tools on some slaves. - * For example, JDK on the master might be on /usr/local/java but on a Windows slave + *
  • Hudson allows admins to specify different locations for tools on some agents. + * For example, JDK on the master might be on /usr/local/java but on a Windows agent * it could be at c:\Program Files\Java *
  • Hudson can verify the existence of tools and provide warnings and diagnostics for * admins. (TBD) diff --git a/core/src/main/java/hudson/tools/ToolInstaller.java b/core/src/main/java/hudson/tools/ToolInstaller.java index 0c798b4f525d6459d64a9520307401ed73893630..2aaec73d1d3787244e1e9b776479a2fdf2634698 100644 --- a/core/src/main/java/hudson/tools/ToolInstaller.java +++ b/core/src/main/java/hudson/tools/ToolInstaller.java @@ -36,6 +36,8 @@ import hudson.model.TaskListener; import java.io.File; import java.io.IOException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -95,7 +97,7 @@ public abstract class ToolInstaller implements Describable, Exten * @return the (directory) path at which the tool can be found, * typically coming from {@link #preferredLocation} * @throws IOException if installation fails - * @throws InterruptedException if communication with a slave is interrupted + * @throws InterruptedException if communication with a agent is interrupted */ public abstract FilePath performInstallation(ToolInstallation tool, Node node, TaskListener log) throws IOException, InterruptedException; @@ -129,4 +131,47 @@ public abstract class ToolInstaller implements Describable, Exten public ToolInstallerDescriptor getDescriptor() { return (ToolInstallerDescriptor) Jenkins.getInstance().getDescriptorOrDie(getClass()); } + + @Restricted(NoExternalUse.class) + public static final class ToolInstallerList { + /** + * the list of {@link ToolInstallerEntry} + */ + public ToolInstallerEntry [] list; + } + + @Restricted(NoExternalUse.class) + public static final class ToolInstallerEntry { + /** + * the id of the of the release entry + */ + public String id; + /** + * the name of the release entry + */ + public String name; + /** + * the url of the release + */ + public String url; + + /** + * public default constructor needed by the JSON parser + */ + public ToolInstallerEntry() { + + } + + /** + * The constructor + * @param id the id of the release + * @param name the name of the release + * @param url the URL of thr release + */ + public ToolInstallerEntry (String id, String name, String url) { + this.id = id; + this.name = name; + this.url = url; + } + } } diff --git a/core/src/main/java/hudson/tools/ToolLocationNodeProperty.java b/core/src/main/java/hudson/tools/ToolLocationNodeProperty.java index cd5157ed46ee357b7c33c7253e9dc112d61b4a6f..d5a3560839538b7b935954f11abe0f5ffdf195c4 100644 --- a/core/src/main/java/hudson/tools/ToolLocationNodeProperty.java +++ b/core/src/main/java/hudson/tools/ToolLocationNodeProperty.java @@ -35,6 +35,7 @@ import hudson.slaves.NodeSpecific; import java.io.IOException; import java.util.ArrayList; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import java.util.Arrays; @@ -115,7 +116,7 @@ public class ToolLocationNodeProperty extends NodeProperty { return installation.getHome(); } - @Extension + @Extension @Symbol("toolLocation") public static class DescriptorImpl extends NodePropertyDescriptor { public String getDisplayName() { diff --git a/core/src/main/java/hudson/tools/ToolLocationTranslator.java b/core/src/main/java/hudson/tools/ToolLocationTranslator.java index 09350475077fc6265a3158b30ccc54a33f730079..47194ef37f57b90220408fa9045ab7d945189531 100644 --- a/core/src/main/java/hudson/tools/ToolLocationTranslator.java +++ b/core/src/main/java/hudson/tools/ToolLocationTranslator.java @@ -26,7 +26,6 @@ package hudson.tools; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.slaves.NodeSpecific; -import jenkins.model.Jenkins; import hudson.model.Node; import hudson.model.TaskListener; diff --git a/core/src/main/java/hudson/tools/ZipExtractionInstaller.java b/core/src/main/java/hudson/tools/ZipExtractionInstaller.java index 38e536bfd3cde5d2b530ceca0c02c822110c9b41..ba91cfe45763c984eb0e6de05ee817ed51546031 100644 --- a/core/src/main/java/hudson/tools/ZipExtractionInstaller.java +++ b/core/src/main/java/hudson/tools/ZipExtractionInstaller.java @@ -41,6 +41,8 @@ import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; + +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -86,7 +88,7 @@ public class ZipExtractionInstaller extends ToolInstaller { } } - @Extension + @Extension @Symbol("zip") public static class DescriptorImpl extends ToolInstallerDescriptor { public String getDisplayName() { diff --git a/core/src/main/java/hudson/triggers/SCMTrigger.java b/core/src/main/java/hudson/triggers/SCMTrigger.java index c1b2dde483dd4a0f163cd9083c50f66688e557b0..577df2acf50bcf80c91c078188a33c5a646dcb01 100644 --- a/core/src/main/java/hudson/triggers/SCMTrigger.java +++ b/core/src/main/java/hudson/triggers/SCMTrigger.java @@ -2,6 +2,7 @@ * The MIT License * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Jean-Baptiste Quenot, id:cactusman + * 2015 Kanstantsin Shautsou * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,6 +25,7 @@ package hudson.triggers; import antlr.ANTLRException; +import com.google.common.base.Preconditions; import hudson.Extension; import hudson.Util; import hudson.console.AnnotatedLargeText; @@ -44,13 +46,6 @@ import hudson.util.NamingThreadFactory; import hudson.util.SequentialExecutionQueue; import hudson.util.StreamTaskListener; import hudson.util.TimeUnit2; -import org.apache.commons.io.FileUtils; -import org.apache.commons.jelly.XMLOutput; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.DoNotUse; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.DataBoundConstructor; - import java.io.File; import java.io.IOException; import java.io.PrintStream; @@ -69,14 +64,24 @@ import java.util.concurrent.ThreadFactory; import java.util.logging.Level; import java.util.logging.Logger; import jenkins.model.Jenkins; +import jenkins.model.RunAction2; +import jenkins.scm.SCMDecisionHandler; import jenkins.triggers.SCMTriggerItem; +import jenkins.util.SystemProperties; import net.sf.json.JSONObject; +import org.apache.commons.io.FileUtils; +import org.apache.commons.jelly.XMLOutput; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.QueryParameter; +import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; -import static java.util.logging.Level.*; -import jenkins.model.RunAction2; +import static java.util.logging.Level.WARNING; /** @@ -93,17 +98,28 @@ import jenkins.model.RunAction2; public class SCMTrigger extends Trigger { private boolean ignorePostCommitHooks; - + + @DataBoundConstructor public SCMTrigger(String scmpoll_spec) throws ANTLRException { - this(scmpoll_spec, false); + super(scmpoll_spec); } - - @DataBoundConstructor + + /** + * Backwards-compatibility constructor. + * + * @param scmpoll_spec + * The spec to poll with. + * @param ignorePostCommitHooks + * Whether to ignore post commit hooks. + * + * @deprecated since 2.21 + */ + @Deprecated public SCMTrigger(String scmpoll_spec, boolean ignorePostCommitHooks) throws ANTLRException { super(scmpoll_spec); this.ignorePostCommitHooks = ignorePostCommitHooks; } - + /** * This trigger wants to ignore post-commit hooks. *

    @@ -115,8 +131,29 @@ public class SCMTrigger extends Trigger { return this.ignorePostCommitHooks; } + /** + * Data-bound setter for ignoring post commit hooks. + * + * @param ignorePostCommitHooks + * True if we should ignore post commit hooks, false otherwise. + * + * @since 2.22 + */ + @DataBoundSetter + public void setIgnorePostCommitHooks(boolean ignorePostCommitHooks) { + this.ignorePostCommitHooks = ignorePostCommitHooks; + } + + public String getScmpoll_spec() { + return super.getSpec(); + } + @Override public void run() { + if (job == null) { + return; + } + run(null); } @@ -128,6 +165,10 @@ public class SCMTrigger extends Trigger { * @since 1.375 */ public void run(Action[] additionalActions) { + if (job == null) { + return; + } + DescriptorImpl d = getDescriptor(); LOGGER.fine("Scheduling a polling for "+job); @@ -152,6 +193,10 @@ public class SCMTrigger extends Trigger { @Override public Collection getProjectActions() { + if (job == null) { + return Collections.emptyList(); + } + return Collections.singleton(new SCMAction()); } @@ -162,7 +207,7 @@ public class SCMTrigger extends Trigger { return new File(job.getRootDir(),"scm-polling.log"); } - @Extension + @Extension @Symbol("pollSCM") public static class DescriptorImpl extends TriggerDescriptor { private static ThreadFactory threadFactory() { @@ -304,6 +349,12 @@ public class SCMTrigger extends Trigger { @Extension public static final class AdministrativeMonitorImpl extends AdministrativeMonitor { + + @Override + public String getDisplayName() { + return Messages.SCMTrigger_AdministrativeMonitorImpl_DisplayName(); + } + private boolean on; public boolean isActivated() { @@ -457,10 +508,12 @@ public class SCMTrigger extends Trigger { private Action[] additionalActions; public Runner() { - additionalActions = new Action[0]; + this(null); } public Runner(Action[] actions) { + Preconditions.checkNotNull(job, "Runner can't be instantiated when job is null"); + if (actions == null) { additionalActions = new Action[0]; } else { @@ -514,11 +567,7 @@ public class SCMTrigger extends Trigger { else logger.println("No changes"); return result; - } catch (Error e) { - e.printStackTrace(listener.error("Failed to record SCM polling for "+job)); - LOGGER.log(Level.SEVERE,"Failed to record SCM polling for "+job,e); - throw e; - } catch (RuntimeException e) { + } catch (Error | RuntimeException e) { e.printStackTrace(listener.error("Failed to record SCM polling for "+job)); LOGGER.log(Level.SEVERE,"Failed to record SCM polling for "+job,e); throw e; @@ -532,6 +581,27 @@ public class SCMTrigger extends Trigger { } public void run() { + if (job == null) { + return; + } + // we can pre-emtively check the SCMDecisionHandler instances here + // note that job().poll(listener) should also check this + SCMDecisionHandler veto = SCMDecisionHandler.firstShouldPollVeto(job); + if (veto != null) { + try (StreamTaskListener listener = new StreamTaskListener(getLogFile())) { + listener.getLogger().println( + "Skipping polling on " + DateFormat.getDateTimeInstance().format(new Date()) + + " due to veto from " + veto); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to record SCM polling for " + job, e); + } + + LOGGER.log(Level.FINE, "Skipping polling for {0} due to veto from {1}", + new Object[]{job.getFullDisplayName(), veto} + ); + return; + } + String threadName = Thread.currentThread().getName(); Thread.currentThread().setName("SCM polling for "+job); try { @@ -598,7 +668,7 @@ public class SCMTrigger extends Trigger { /** * @deprecated - * Use {@link #SCMTrigger.SCMTriggerCause(String)}. + * Use {@link SCMTrigger.SCMTriggerCause#SCMTriggerCause(String)}. */ @Deprecated public SCMTriggerCause() { @@ -647,5 +717,5 @@ public class SCMTrigger extends Trigger { /** * How long is too long for a polling activity to be in the queue? */ - public static long STARVATION_THRESHOLD =Long.getLong(SCMTrigger.class.getName()+".starvationThreshold", TimeUnit2.HOURS.toMillis(1)); + public static long STARVATION_THRESHOLD = SystemProperties.getLong(SCMTrigger.class.getName()+".starvationThreshold", TimeUnit2.HOURS.toMillis(1)); } diff --git a/core/src/main/java/hudson/triggers/SafeTimerTask.java b/core/src/main/java/hudson/triggers/SafeTimerTask.java index e47dfc61e62b52872beaede1f3a03317cf5f5bfe..08a6e16dcd3f66609fe83154f8ce13507bf37760 100644 --- a/core/src/main/java/hudson/triggers/SafeTimerTask.java +++ b/core/src/main/java/hudson/triggers/SafeTimerTask.java @@ -29,7 +29,6 @@ import hudson.security.ACL; import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; -import jenkins.util.Timer; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; diff --git a/core/src/main/java/hudson/triggers/TimerTrigger.java b/core/src/main/java/hudson/triggers/TimerTrigger.java index 0466c8a4c31404b2b3babf6d112a0829b98c3481..4380c0797cd82afb80c887d5c630aaf5c5869bd7 100644 --- a/core/src/main/java/hudson/triggers/TimerTrigger.java +++ b/core/src/main/java/hudson/triggers/TimerTrigger.java @@ -2,6 +2,7 @@ * The MIT License * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Jean-Baptiste Quenot, Martin Eigenbrodt + * 2015 Kanstantsin Shautsou * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,11 +34,17 @@ import hudson.scheduler.CronTabList; import hudson.scheduler.Hash; import hudson.util.FormValidation; import java.text.DateFormat; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; + +import org.jenkinsci.Symbol; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; +import javax.annotation.Nonnull; + /** * {@link Trigger} that runs a job periodically. * @@ -46,16 +53,20 @@ import org.kohsuke.stapler.QueryParameter; public class TimerTrigger extends Trigger { @DataBoundConstructor - public TimerTrigger(String spec) throws ANTLRException { + public TimerTrigger(@Nonnull String spec) throws ANTLRException { super(spec); } @Override public void run() { + if (job == null) { + return; + } + job.scheduleBuild(0, new TimerTriggerCause()); } - @Extension + @Extension @Symbol("cron") public static class DescriptorImpl extends TriggerDescriptor { public boolean isApplicable(Item item) { return item instanceof BuildableItem; @@ -76,22 +87,32 @@ public class TimerTrigger extends Trigger { public FormValidation doCheckSpec(@QueryParameter String value, @AncestorInPath Item item) { try { CronTabList ctl = CronTabList.create(fixNull(value), item != null ? Hash.from(item.getFullName()) : null); - String msg = ctl.checkSanity(); - if(msg!=null) return FormValidation.warning(msg); - Calendar prev = ctl.previous(); - Calendar next = ctl.next(); - if (prev != null && next != null) { - DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); - return FormValidation.ok(Messages.TimerTrigger_would_last_have_run_at_would_next_run_at(fmt.format(prev.getTime()), fmt.format(next.getTime()))); - } else { - return FormValidation.warning(Messages.TimerTrigger_no_schedules_so_will_never_run()); - } + Collection validations = new ArrayList<>(); + updateValidationsForSanity(validations, ctl); + updateValidationsForNextRun(validations, ctl); + return FormValidation.aggregate(validations); } catch (ANTLRException e) { if (value.trim().indexOf('\n')==-1 && value.contains("**")) return FormValidation.error(Messages.TimerTrigger_MissingWhitespace()); return FormValidation.error(e.getMessage()); } } + + private void updateValidationsForSanity(Collection validations, CronTabList ctl) { + String msg = ctl.checkSanity(); + if(msg!=null) validations.add(FormValidation.warning(msg)); + } + + private void updateValidationsForNextRun(Collection validations, CronTabList ctl) { + Calendar prev = ctl.previous(); + Calendar next = ctl.next(); + if (prev != null && next != null) { + DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); + validations.add(FormValidation.ok(Messages.TimerTrigger_would_last_have_run_at_would_next_run_at(fmt.format(prev.getTime()), fmt.format(next.getTime())))); + } else { + validations.add(FormValidation.warning(Messages.TimerTrigger_no_schedules_so_will_never_run())); + } + } } public static class TimerTriggerCause extends Cause { diff --git a/core/src/main/java/hudson/triggers/Trigger.java b/core/src/main/java/hudson/triggers/Trigger.java index 6f5c922d2603d06c324cc8858cc1a585bca5f84e..1da137237c7c88942634f596934476f0e90b8a20 100644 --- a/core/src/main/java/hudson/triggers/Trigger.java +++ b/core/src/main/java/hudson/triggers/Trigger.java @@ -2,7 +2,8 @@ * The MIT License * * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Brian Westrich, Jean-Baptiste Quenot, Stephen Connolly, Tom Huybrechts - * + * 2015 Kanstantsin Shautsou + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights @@ -57,9 +58,12 @@ import java.util.logging.Logger; import antlr.ANTLRException; import javax.annotation.CheckForNull; -import edu.umd.cs.findbugs.annotations.SuppressWarnings; +import javax.annotation.Nonnull; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.Items; import jenkins.model.ParameterizedJobMixIn; +import org.jenkinsci.Symbol; /** * Triggers a {@link Build}. @@ -86,11 +90,15 @@ public abstract class Trigger implements Describable> this.job = project; try {// reparse the tabs with the job as the hash - this.tabs = CronTabList.create(spec, Hash.from(project.getFullName())); + if (spec != null) { + this.tabs = CronTabList.create(spec, Hash.from(project.getFullName())); + } else { + LOGGER.log(Level.WARNING, "The job {0} has a null crontab spec which is incorrect", job.getFullName()); + } } catch (ANTLRException e) { // this shouldn't fail because we've already parsed stuff in the constructor, // so if it fails, use whatever 'tabs' that we already have. - LOGGER.log(Level.FINE, "Failed to parse crontab spec: "+spec,e); + LOGGER.log(Level.WARNING, String.format("Failed to parse crontab spec %s in job %s", spec, project.getFullName()), e); } } @@ -99,6 +107,8 @@ public abstract class Trigger implements Describable> * * This method is invoked when {@link #Trigger(String)} is used * to create an instance, and the crontab matches the current time. + *

    + * Maybe run even before {@link #start(hudson.model.Item, boolean)}, prepare for it. */ public void run() {} @@ -147,6 +157,7 @@ public abstract class Trigger implements Describable> protected final String spec; protected transient CronTabList tabs; + @CheckForNull protected transient J job; /** @@ -154,7 +165,7 @@ public abstract class Trigger implements Describable> * periodically. This is useful when your trigger does * some polling work. */ - protected Trigger(String cronTabSpec) throws ANTLRException { + protected Trigger(@Nonnull String cronTabSpec) throws ANTLRException { this.spec = cronTabSpec; this.tabs = CronTabList.create(cronTabSpec); } @@ -191,7 +202,7 @@ public abstract class Trigger implements Describable> /** * Runs every minute to check {@link TimerTrigger} and schedules build. */ - @Extension + @Extension @Symbol("cron") public static class Cron extends PeriodicWork { private final Calendar cal = new GregorianCalendar(); @@ -257,20 +268,24 @@ public abstract class Trigger implements Describable> // Process all triggers, except SCMTriggers when synchronousPolling is set for (ParameterizedJobMixIn.ParameterizedJob p : inst.getAllItems(ParameterizedJobMixIn.ParameterizedJob.class)) { for (Trigger t : p.getTriggers().values()) { - if (! (t instanceof SCMTrigger && scmd.synchronousPolling)) { - LOGGER.log(Level.FINE, "cron checking {0} with spec ‘{1}’", new Object[] {p, t.spec.trim()}); - - if (t.tabs.check(cal)) { - LOGGER.log(Level.CONFIG, "cron triggered {0}", p); - try { - t.run(); - } catch (Throwable e) { - // t.run() is a plugin, and some of them throw RuntimeException and other things. - // don't let that cancel the polling activity. report and move on. - LOGGER.log(Level.WARNING, t.getClass().getName() + ".run() failed for " + p, e); + if (!(t instanceof SCMTrigger && scmd.synchronousPolling)) { + if (t !=null && t.spec != null && t.tabs != null) { + LOGGER.log(Level.FINE, "cron checking {0} with spec ‘{1}’", new Object[]{p, t.spec.trim()}); + + if (t.tabs.check(cal)) { + LOGGER.log(Level.CONFIG, "cron triggered {0}", p); + try { + t.run(); + } catch (Throwable e) { + // t.run() is a plugin, and some of them throw RuntimeException and other things. + // don't let that cancel the polling activity. report and move on. + LOGGER.log(Level.WARNING, t.getClass().getName() + ".run() failed for " + p, e); + } + } else { + LOGGER.log(Level.FINER, "did not trigger {0}", p); } } else { - LOGGER.log(Level.FINER, "did not trigger {0}", p); + LOGGER.log(Level.WARNING, "The job {0} has a syntactically incorrect config and is missing the cron spec for a trigger", p.getFullName()); } } } @@ -304,7 +319,7 @@ public abstract class Trigger implements Describable> * Returns a subset of {@link TriggerDescriptor}s that applys to the given item. */ public static List for_(Item i) { - List r = new ArrayList(); + List r = new ArrayList<>(); for (TriggerDescriptor t : all()) { if(!t.isApplicable(i)) continue; diff --git a/core/src/main/java/hudson/util/AlternativeUiTextProvider.java b/core/src/main/java/hudson/util/AlternativeUiTextProvider.java index 9b4aa3b458530478e5f7e0c7445aafe070d495d0..45605bb7626df713495a30d34d9b91210166b789 100644 --- a/core/src/main/java/hudson/util/AlternativeUiTextProvider.java +++ b/core/src/main/java/hudson/util/AlternativeUiTextProvider.java @@ -27,7 +27,6 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.AbstractProject; -import jenkins.model.Jenkins; /** * Provides the alternative text to be rendered in the UI. diff --git a/core/src/main/java/hudson/util/ArgumentListBuilder.java b/core/src/main/java/hudson/util/ArgumentListBuilder.java index d89744a413ca08db2c6154856bb80963c4524e49..255208737abe6af15ffb19f154ab275ce782c3e5 100644 --- a/core/src/main/java/hudson/util/ArgumentListBuilder.java +++ b/core/src/main/java/hudson/util/ArgumentListBuilder.java @@ -24,7 +24,6 @@ */ package hudson.util; -import hudson.FilePath; import hudson.Launcher; import hudson.Util; @@ -315,42 +314,46 @@ public class ArgumentListBuilder implements Serializable, Cloneable { * @since 1.386 */ public ArgumentListBuilder toWindowsCommand(boolean escapeVars) { - StringBuilder quotedArgs = new StringBuilder(); + ArgumentListBuilder windowsCommand = new ArgumentListBuilder().add("cmd.exe", "/C"); boolean quoted, percent; - for (String arg : args) { + for (int i = 0; i < args.size(); i++) { + StringBuilder quotedArgs = new StringBuilder(); + String arg = args.get(i); quoted = percent = false; - for (int i = 0; i < arg.length(); i++) { - char c = arg.charAt(i); + for (int j = 0; j < arg.length(); j++) { + char c = arg.charAt(j); if (!quoted && (c == ' ' || c == '*' || c == '?' || c == ',' || c == ';')) { - quoted = startQuoting(quotedArgs, arg, i); + quoted = startQuoting(quotedArgs, arg, j); } else if (c == '^' || c == '&' || c == '<' || c == '>' || c == '|') { - if (!quoted) quoted = startQuoting(quotedArgs, arg, i); + if (!quoted) quoted = startQuoting(quotedArgs, arg, j); // quotedArgs.append('^'); See note in javadoc above } else if (c == '"') { - if (!quoted) quoted = startQuoting(quotedArgs, arg, i); + if (!quoted) quoted = startQuoting(quotedArgs, arg, j); quotedArgs.append('"'); } else if (percent && escapeVars && ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) { - if (!quoted) quoted = startQuoting(quotedArgs, arg, i); + if (!quoted) quoted = startQuoting(quotedArgs, arg, j); quotedArgs.append('"').append(c); c = '"'; } percent = (c == '%'); if (quoted) quotedArgs.append(c); } + if(i == 0 && quoted) quotedArgs.insert(0, '"'); else if (i == 0 && !quoted) quotedArgs.append('"'); if (quoted) quotedArgs.append('"'); else quotedArgs.append(arg); - quotedArgs.append(' '); + + windowsCommand.add(quotedArgs, mask.get(i)); } // (comment copied from old code in hudson.tasks.Ant) // on Windows, executing batch file can't return the correct error code, // so we need to wrap it into cmd.exe. // double %% is needed because we want ERRORLEVEL to be expanded after // batch file executed, not before. This alone shows how broken Windows is... - quotedArgs.append("&& exit %%ERRORLEVEL%%"); - return new ArgumentListBuilder().add("cmd.exe", "/C").addQuoted(quotedArgs.toString()); + windowsCommand.add("&&").add("exit").add("%%ERRORLEVEL%%\""); + return windowsCommand; } /** diff --git a/core/src/main/java/hudson/util/BootFailure.java b/core/src/main/java/hudson/util/BootFailure.java index 8ad6bedc29ff2fa369dc7c1597fcab0dcf47f49e..8d1055b1c29787ce3e8b09c21d6044cc0216ef74 100644 --- a/core/src/main/java/hudson/util/BootFailure.java +++ b/core/src/main/java/hudson/util/BootFailure.java @@ -40,7 +40,10 @@ public abstract class BootFailure extends ErrorObject { LOGGER.log(Level.SEVERE, "Failed to initialize Jenkins",this); WebApp.get(context).setApp(this); - new GroovyHookScript("boot-failure") + if (home == null) { + return; + } + new GroovyHookScript("boot-failure", context, home, BootFailure.class.getClassLoader()) .bind("exception",this) .bind("home",home) .bind("servletContext", context) @@ -57,8 +60,7 @@ public abstract class BootFailure extends ErrorObject { File f = getBootFailureFile(home); try { if (f.exists()) { - BufferedReader failureFileReader = new BufferedReader(new FileReader(f)); - try { + try (BufferedReader failureFileReader = new BufferedReader(new FileReader(f))) { String line; while ((line=failureFileReader.readLine())!=null) { try { @@ -67,8 +69,6 @@ public abstract class BootFailure extends ErrorObject { // ignore any parse error } } - } finally { - failureFileReader.close(); } } } catch (IOException e) { diff --git a/core/src/main/java/hudson/util/CharacterEncodingFilter.java b/core/src/main/java/hudson/util/CharacterEncodingFilter.java index f9ddffc2b3b6a349f8c20d9afdde6e221e3cb921..5e7ea94d937698db457b521ea6810e1f34a010e8 100644 --- a/core/src/main/java/hudson/util/CharacterEncodingFilter.java +++ b/core/src/main/java/hudson/util/CharacterEncodingFilter.java @@ -23,6 +23,7 @@ */ package hudson.util; +import jenkins.util.SystemProperties; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; @@ -48,13 +49,13 @@ public class CharacterEncodingFilter implements Filter { private static final String ENCODING = "UTF-8"; private static final Boolean DISABLE_FILTER - = Boolean.getBoolean(CharacterEncodingFilter.class.getName() + ".disableFilter"); + = SystemProperties.getBoolean(CharacterEncodingFilter.class.getName() + ".disableFilter"); /** * The character encoding sets forcibly? */ private static final Boolean FORCE_ENCODING - = Boolean.getBoolean(CharacterEncodingFilter.class.getName() + ".forceEncoding"); + = SystemProperties.getBoolean(CharacterEncodingFilter.class.getName() + ".forceEncoding"); public void init(FilterConfig filterConfig) throws ServletException { LOGGER.log(Level.FINE, diff --git a/core/src/main/java/hudson/util/ChartUtil.java b/core/src/main/java/hudson/util/ChartUtil.java index e6a14cc8d8e4bb2a91ebe4abaf54613243ee947a..f7341d545a1f0832e61626e08d4aa9ec0858c334 100644 --- a/core/src/main/java/hudson/util/ChartUtil.java +++ b/core/src/main/java/hudson/util/ChartUtil.java @@ -23,6 +23,7 @@ */ package hudson.util; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.model.AbstractBuild; import hudson.model.Run; import org.jfree.chart.JFreeChart; @@ -103,9 +104,13 @@ public class ChartUtil { @Deprecated public static boolean awtProblem = false; + //TODO: prevent usage of this APIs in plugins. Needs to be deprecated and replaced by a getter method /** * See issue 93. Detect an error in X11 and handle it gracefully. */ + @SuppressFBWarnings(value = "MS_SHOULD_BE_REFACTORED_TO_BE_FINAL", + justification = "It's actually being widely used by plugins. " + + "Obsolete approach, should be ideally replaced by Getter") public static Throwable awtProblemCause = null; /** @@ -113,7 +118,7 @@ public class ChartUtil { * * @param defaultSize * The size of the picture to be generated. These values can be overridden - * by the query paramter 'width' and 'height' in the request. + * by the query parameter 'width' and 'height' in the request. * @deprecated as of 1.320 * Bind {@link Graph} to the URL space. See {@code hudson.tasks.junit.History} as an example (note that doing so involves * a bit of URL structure change.) @@ -129,7 +134,7 @@ public class ChartUtil { * @param defaultW * @param defaultH * The size of the picture to be generated. These values can be overridden - * by the query paramter 'width' and 'height' in the request. + * by the query parameter 'width' and 'height' in the request. * @deprecated as of 1.320 * Bind {@link Graph} to the URL space. See {@code hudson.tasks.junit.History} as an example (note that doing so involves * a bit of URL structure change.) diff --git a/core/src/main/java/hudson/util/ClockDifference.java b/core/src/main/java/hudson/util/ClockDifference.java index 444d101494d819adae74c397716b8770e7f87106..ee56d328d0c5e84f57e2415f068b9afddbb47202 100644 --- a/core/src/main/java/hudson/util/ClockDifference.java +++ b/core/src/main/java/hudson/util/ClockDifference.java @@ -41,8 +41,8 @@ public final class ClockDifference { /** * The difference in milliseconds. * - * Positive value means the slave is behind the master, - * negative value means the slave is ahead of the master. + * Positive value means the agent is behind the master, + * negative value means the agent is ahead of the master. */ @Exported public final long diff; diff --git a/core/src/main/java/hudson/util/ComboBoxModel.java b/core/src/main/java/hudson/util/ComboBoxModel.java index 48351bc16b5acacc1fc729dafc6516e5f5b8a6d5..f39f9bc555319eb6aed33a0f3c965e23dab4f700 100644 --- a/core/src/main/java/hudson/util/ComboBoxModel.java +++ b/core/src/main/java/hudson/util/ComboBoxModel.java @@ -33,7 +33,6 @@ import javax.servlet.ServletException; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import static java.util.Arrays.asList; diff --git a/core/src/main/java/hudson/util/CompressedFile.java b/core/src/main/java/hudson/util/CompressedFile.java index b6ccf22c3071f022282175548922904de589b4fd..fb691e298de375dfc7e71a66baaf300f37a176f5 100644 --- a/core/src/main/java/hudson/util/CompressedFile.java +++ b/core/src/main/java/hudson/util/CompressedFile.java @@ -138,13 +138,8 @@ public class CompressedFile { compressionThread.submit(new Runnable() { public void run() { try { - InputStream in = read(); - OutputStream out = new GZIPOutputStream(new FileOutputStream(gz)); - try { - Util.copyStream(in,out); - } finally { - in.close(); - out.close(); + try (InputStream in = read(); OutputStream out = new GZIPOutputStream(new FileOutputStream(gz))) { + Util.copyStream(in, out); } // if the compressed file is created successfully, remove the original file.delete(); diff --git a/core/src/main/java/hudson/util/ConcurrentHashMapConverter.java b/core/src/main/java/hudson/util/ConcurrentHashMapConverter.java deleted file mode 100644 index ae917d499673581c84488806ec416aed3818d33f..0000000000000000000000000000000000000000 --- a/core/src/main/java/hudson/util/ConcurrentHashMapConverter.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010, InfraDNA, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package hudson.util; - -import com.thoughtworks.xstream.XStream; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.converters.collections.MapConverter; -import com.thoughtworks.xstream.converters.reflection.ReflectionProvider; -import com.thoughtworks.xstream.converters.reflection.SerializableConverter; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.mapper.Mapper; - -import java.util.concurrent.ConcurrentHashMap; - -/** - * {@link ConcurrentHashMap} should convert like a map, instead of via serialization. - * - * @author Kohsuke Kawaguchi - */ -public class ConcurrentHashMapConverter extends MapConverter { - private final SerializableConverter sc; - - public ConcurrentHashMapConverter(XStream xs) { - this(xs.getMapper(),xs.getReflectionProvider()); - } - - public ConcurrentHashMapConverter(Mapper mapper, ReflectionProvider reflectionProvider) { - super(mapper); - sc = new SerializableConverter(mapper,reflectionProvider); - } - - @Override - public boolean canConvert(Class type) { - return type==ConcurrentHashMap.class; - } - - @Override - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - // ConcurrentHashMap used to serialize as custom serialization, - // so read it in a compatible fashion. - String s = reader.getAttribute("serialization"); - if(s!=null && s.equals("custom")) { - return sc.unmarshal(reader,context); - } else { - return super.unmarshal(reader, context); - } - } -} diff --git a/core/src/main/java/hudson/util/CopyOnWriteList.java b/core/src/main/java/hudson/util/CopyOnWriteList.java index 179d2d08250ae155ded9d3514230ace799b47dce..4e6af51dc66059910aedd71201e43e3e493bd698 100644 --- a/core/src/main/java/hudson/util/CopyOnWriteList.java +++ b/core/src/main/java/hudson/util/CopyOnWriteList.java @@ -39,6 +39,8 @@ import java.util.Iterator; import java.util.List; import java.util.Arrays; +import jenkins.util.xstream.CriticalXStreamException; + /** * {@link List}-like implementation that has copy-on-write semantics. @@ -141,7 +143,7 @@ public class CopyOnWriteList implements Iterable { } public List getView() { - return Collections.unmodifiableList(core); + return Collections.unmodifiableList(core); } public void addAllTo(Collection dst) { @@ -194,6 +196,8 @@ public class CopyOnWriteList implements Iterable { try { Object item = readItem(reader, context, items); items.add(item); + } catch (CriticalXStreamException e) { + throw e; } catch (XStreamException e) { RobustReflectionConverter.addErrorInContext(context, e); } catch (LinkageError e) { diff --git a/core/src/main/java/hudson/util/CyclicGraphDetector.java b/core/src/main/java/hudson/util/CyclicGraphDetector.java index 74f7fdeb48afc155a1aa7ecfd22ffc087cb25c50..7e0bf2029db3de6b84bf54c2148aa68d2333582f 100644 --- a/core/src/main/java/hudson/util/CyclicGraphDetector.java +++ b/core/src/main/java/hudson/util/CyclicGraphDetector.java @@ -3,9 +3,7 @@ package hudson.util; import hudson.Util; import java.util.ArrayList; -import java.util.Collection; import java.util.HashSet; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.Stack; diff --git a/core/src/main/java/hudson/util/DescriptorList.java b/core/src/main/java/hudson/util/DescriptorList.java index f7f716860fc02ce19d7e4f2578cf5a331f4f5d6d..75fedaab399d26866d538fa0f2d1624a2e7f0924 100644 --- a/core/src/main/java/hudson/util/DescriptorList.java +++ b/core/src/main/java/hudson/util/DescriptorList.java @@ -36,6 +36,7 @@ import java.util.AbstractList; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import javax.annotation.CheckForNull; /** * List of {@link Descriptor}s. @@ -152,7 +153,11 @@ public final class DescriptorList> extends AbstractList * Creates a new instance of a {@link Describable} * from the structured form submission data posted * by a radio button group. + * @param config Submitted configuration for Radio List + * @return new instance or {@code null} if none was selected in the radio list + * @throws FormException Data submission error */ + @CheckForNull public T newInstanceFromRadioList(JSONObject config) throws FormException { if(config.isNullObject()) return null; // none was selected @@ -160,15 +165,26 @@ public final class DescriptorList> extends AbstractList return get(idx).newInstance(Stapler.getCurrentRequest(),config); } + /** + * Creates a new instance of a {@link Describable} + * from the structured form submission data posted + * by a radio button group. + * @param parent JSON, which contains the configuration entry for the radio list + * @param name Name of the configuration entry for the radio list + * @return new instance or {@code null} if none was selected in the radio list + * @throws FormException Data submission error + */ + @CheckForNull public T newInstanceFromRadioList(JSONObject parent, String name) throws FormException { return newInstanceFromRadioList(parent.getJSONObject(name)); } /** * Finds a descriptor by their {@link Descriptor#getId()}. - * - * If none is found, null is returned. + * @param id Descriptor ID + * @return If none is found, {@code null} is returned. */ + @CheckForNull public Descriptor findByName(String id) { for (Descriptor d : this) if(d.getId().equals(id)) @@ -201,6 +217,7 @@ public final class DescriptorList> extends AbstractList * Finds the descriptor that has the matching fully-qualified class name. * @deprecated Underspecified what the parameter is. {@link Descriptor#getId}? A {@link Describable} class name? */ + @CheckForNull public Descriptor find(String fqcn) { return Descriptor.find(this,fqcn); } diff --git a/core/src/main/java/hudson/util/DoubleLaunchChecker.java b/core/src/main/java/hudson/util/DoubleLaunchChecker.java index 340465023394189bdee0a4e801a98583d7cd394e..801b9fe5c657b9a9173d50186e9d8df7f43dea38 100644 --- a/core/src/main/java/hudson/util/DoubleLaunchChecker.java +++ b/core/src/main/java/hudson/util/DoubleLaunchChecker.java @@ -28,7 +28,6 @@ import jenkins.model.Jenkins; import hudson.triggers.SafeTimerTask; import jenkins.util.Timer; import org.apache.commons.io.FileUtils; -import org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -51,7 +50,7 @@ import java.lang.reflect.Method; * to forestall the problem of running multiple instances of Hudson that point to the same data directory. * *

    - * This set up error occasionally happens especialy when the user is trying to reassign the context path of the app, + * This set up error occasionally happens especially when the user is trying to reassign the context path of the app, * and it results in a hard-to-diagnose error, so we actively check this. * *

    diff --git a/core/src/main/java/hudson/util/FormFieldValidator.java b/core/src/main/java/hudson/util/FormFieldValidator.java index a1932c6dc6b0c3d4df6a9fb3d2babf661ad81491..2fc8874a9683153985d8c99dd110b5a14c261e80 100644 --- a/core/src/main/java/hudson/util/FormFieldValidator.java +++ b/core/src/main/java/hudson/util/FormFieldValidator.java @@ -350,7 +350,7 @@ public abstract class FormFieldValidator { * Checks the file mask (specified in the 'value' query parameter) against * the current workspace. * @since 1.90. - * @deprecated as of 1.294. Use {@link FilePath#validateFileMask(String, boolean)} + * @deprecated as of 1.294. Use {@link FilePath#validateFileMask(String, boolean, boolean)} */ @Deprecated public static class WorkspaceFileMask extends FormFieldValidator { diff --git a/core/src/main/java/hudson/util/FormValidation.java b/core/src/main/java/hudson/util/FormValidation.java index 4c52f19b6d909f07ccc703c5de43a2d490ea1460..c6dddca1832518543028ad662adc2da044c2ffa9 100644 --- a/core/src/main/java/hudson/util/FormValidation.java +++ b/core/src/main/java/hudson/util/FormValidation.java @@ -638,7 +638,7 @@ public abstract class FormValidation extends IOException implements HttpResponse */ public String toStemUrl() { if (names==null) return null; - return jsStringEscape(Descriptor.getCurrentDescriptorByNameUrl()) + '/' + relativePath(); + return Descriptor.getCurrentDescriptorByNameUrl() + '/' + relativePath(); } public String getDependsOn() { diff --git a/core/src/main/java/hudson/util/Graph.java b/core/src/main/java/hudson/util/Graph.java index 8009286eac4f2647e6835ef8fa0a73833a2feeb4..bef25b2d9e06bece21efe418c82a0bacccde552d 100644 --- a/core/src/main/java/hudson/util/Graph.java +++ b/core/src/main/java/hudson/util/Graph.java @@ -26,6 +26,7 @@ package hudson.util; import org.jfree.chart.JFreeChart; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.ChartUtilities; +import org.jfree.chart.plot.Plot; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -35,6 +36,8 @@ import java.io.IOException; import java.util.Calendar; import java.awt.image.BufferedImage; import java.awt.*; +import javax.annotation.Nonnull; +import javax.annotation.CheckForNull; /** * A JFreeChart-generated graph that's bound to UI. @@ -84,10 +87,29 @@ public abstract class Graph { String h = req.getParameter("height"); if(h==null) h=String.valueOf(defaultH); + Color graphBg = stringToColor(req.getParameter("graphBg")); + Color plotBg = stringToColor(req.getParameter("plotBg")); + if (graph==null) graph = createGraph(); + graph.setBackgroundPaint(graphBg); + Plot p = graph.getPlot(); + p.setBackgroundPaint(plotBg); + return graph.createBufferedImage(Integer.parseInt(w),Integer.parseInt(h),info); } + @Nonnull private static Color stringToColor(@CheckForNull String s) { + if (s != null) { + try { + return Color.decode("0x" + s); + } catch (NumberFormatException e) { + return Color.WHITE; + } + } else { + return Color.WHITE; + } + } + /** * Renders a graph. */ diff --git a/core/src/main/java/hudson/util/HttpResponses.java b/core/src/main/java/hudson/util/HttpResponses.java index 16755adc4c981e40e711407aca06cb778dc77fe6..ccef89059e1adbc3bda2d76f96d97c219303ab8d 100644 --- a/core/src/main/java/hudson/util/HttpResponses.java +++ b/core/src/main/java/hudson/util/HttpResponses.java @@ -23,10 +23,19 @@ */ package hudson.util; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.servlet.ServletException; import java.io.File; import java.io.IOException; +import java.nio.charset.Charset; +import java.util.Map; /** * Various {@link HttpResponse} implementations. @@ -40,4 +49,136 @@ public class HttpResponses extends org.kohsuke.stapler.HttpResponses { public static HttpResponse staticResource(File f) throws IOException { return staticResource(f.toURI().toURL()); } + + /** + * Create an empty "ok" response. + * + * @since 2.0 + */ + public static HttpResponse okJSON() { + return new JSONObjectResponse(); + } + + /** + * Create a response containing the supplied "data". + * @param data The data. + * + * @since 2.0 + */ + public static HttpResponse okJSON(@Nonnull JSONObject data) { + return new JSONObjectResponse(data); + } + + /** + * Create a response containing the supplied "data". + * @param data The data. + * + * @since 2.0 + */ + public static HttpResponse okJSON(@Nonnull JSONArray data) { + return new JSONObjectResponse(data); + } + + /** + * Create a response containing the supplied "data". + * @param data The data. + * + * @since 2.0 + */ + public static HttpResponse okJSON(@Nonnull Map data) { + return new JSONObjectResponse(data); + } + + /** + * Set the response as an error response. + * @param message The error "message" set on the response. + * @return {@link this} object. + * + * @since 2.0 + */ + public static HttpResponse errorJSON(@Nonnull String message) { + return new JSONObjectResponse().error(message); + } + + /** + * {@link net.sf.json.JSONObject} response. + * + * @author tom.fennelly@gmail.com + */ + static class JSONObjectResponse implements HttpResponse { + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private final JSONObject jsonObject; + + /** + * Create an empty "ok" response. + */ + JSONObjectResponse() { + this.jsonObject = new JSONObject(); + status("ok"); + } + + /** + * Create a response containing the supplied "data". + * @param data The data. + */ + JSONObjectResponse(@Nonnull JSONObject data) { + this(); + this.jsonObject.put("data", data); + } + + /** + * Create a response containing the supplied "data". + * @param data The data. + */ + JSONObjectResponse(@Nonnull JSONArray data) { + this(); + this.jsonObject.put("data", data); + } + + /** + * Create a response containing the supplied "data". + * @param data The data. + */ + JSONObjectResponse(@Nonnull Map data) { + this(); + this.jsonObject.put("data", JSONObject.fromObject(data)); + } + + /** + * Set the response as an error response. + * @param message The error "message" set on the response. + * @return {@link this} object. + */ + @Nonnull JSONObjectResponse error(@Nonnull String message) { + status("error"); + this.jsonObject.put("message", message); + return this; + } + + /** + * Get the JSON response object. + * @return The JSON response object. + */ + @Nonnull JSONObject getJsonObject() { + return jsonObject; + } + + private @Nonnull JSONObjectResponse status(@Nonnull String status) { + this.jsonObject.put("status", status); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + byte[] bytes = jsonObject.toString().getBytes(UTF8); + rsp.setContentType("application/json; charset=UTF-8"); + rsp.setContentLength(bytes.length); + rsp.getOutputStream().write(bytes); + } + } } diff --git a/core/src/main/java/hudson/util/IOUtils.java b/core/src/main/java/hudson/util/IOUtils.java index b8edc312426a650da8a380f22f98d673209e6ecc..221004fd1103a4e9dfcedbc2103a9b9779c61d3f 100644 --- a/core/src/main/java/hudson/util/IOUtils.java +++ b/core/src/main/java/hudson/util/IOUtils.java @@ -136,12 +136,9 @@ public class IOUtils { * @since 1.422 */ public static String readFirstLine(InputStream is, String encoding) throws IOException { - BufferedReader reader = new BufferedReader( - encoding==null ? new InputStreamReader(is) : new InputStreamReader(is,encoding)); - try { + try (BufferedReader reader = new BufferedReader( + encoding == null ? new InputStreamReader(is) : new InputStreamReader(is, encoding))) { return reader.readLine(); - } finally { - reader.close(); } } diff --git a/core/src/main/java/hudson/util/Iterators.java b/core/src/main/java/hudson/util/Iterators.java index 2b5d88f74bdbad1378d9ee83581dbe2bfc7b046a..74d82950dc298e8d79b0ccc471dd95d340e12163 100644 --- a/core/src/main/java/hudson/util/Iterators.java +++ b/core/src/main/java/hudson/util/Iterators.java @@ -24,6 +24,7 @@ package hudson.util; import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableList; import java.util.Collections; import java.util.Iterator; @@ -314,12 +315,13 @@ public class Iterators { *

    * That is, this creates {A,B,C,D} from {A,B},{C,D}. */ + @SafeVarargs public static Iterable sequence( final Iterable... iterables ) { return new Iterable() { public Iterator iterator() { - return new FlattenIterator>(Arrays.asList(iterables)) { + return new FlattenIterator>(ImmutableList.copyOf(iterables)) { protected Iterator expand(Iterable iterable) { - return cast(iterable).iterator(); + return Iterators.cast(iterable).iterator(); } }; } @@ -350,8 +352,9 @@ public class Iterators { }; } + @SafeVarargs public static Iterator sequence(Iterator... iterators) { - return com.google.common.collect.Iterators.concat(iterators); + return com.google.common.collect.Iterators.concat(iterators); } /** diff --git a/core/src/main/java/hudson/util/MaskingClassLoader.java b/core/src/main/java/hudson/util/MaskingClassLoader.java index 4a85d76d0f868519b8caba400910f2068baad0d9..47563439d4a7561f14a9586c61c590e2e4d96fb8 100644 --- a/core/src/main/java/hudson/util/MaskingClassLoader.java +++ b/core/src/main/java/hudson/util/MaskingClassLoader.java @@ -23,11 +23,14 @@ */ package hudson.util; +import java.io.IOException; import java.net.URL; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Enumeration; +import java.util.Collections; +import java.util.concurrent.CopyOnWriteArrayList; /** * {@link ClassLoader} that masks a specified set of classes @@ -42,9 +45,9 @@ public class MaskingClassLoader extends ClassLoader { /** * Prefix of the packages that should be hidden. */ - private final List masksClasses = new ArrayList(); + private final List masksClasses = new CopyOnWriteArrayList<>(); - private final List masksResources = new ArrayList(); + private final List masksResources = new CopyOnWriteArrayList<>(); public MaskingClassLoader(ClassLoader parent, String... masks) { this(parent, Arrays.asList(masks)); @@ -63,7 +66,7 @@ public class MaskingClassLoader extends ClassLoader { } @Override - protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { for (String mask : masksClasses) { if(name.startsWith(mask)) throw new ClassNotFoundException(); @@ -73,19 +76,31 @@ public class MaskingClassLoader extends ClassLoader { } @Override - public synchronized URL getResource(String name) { - for (String mask : masksResources) { - if(name.startsWith(mask)) - return null; - } + public URL getResource(String name) { + if (isMasked(name)) return null; return super.getResource(name); } - public synchronized void add(String prefix) { + @Override + public Enumeration getResources(String name) throws IOException { + if (isMasked(name)) return Collections.emptyEnumeration(); + + return super.getResources(name); + } + + public void add(String prefix) { masksClasses.add(prefix); if(prefix !=null){ masksResources.add(prefix.replace(".","/")); } } + + private boolean isMasked(String name) { + for (String mask : masksResources) { + if(name.startsWith(mask)) + return true; + } + return false; + } } diff --git a/core/src/main/java/hudson/util/MultipartFormDataParser.java b/core/src/main/java/hudson/util/MultipartFormDataParser.java index ee579b839055ee11ec7ea15f5cb21edcfbe40a07..1789759d128943cfd4a0a4570f33749edd7f2950 100644 --- a/core/src/main/java/hudson/util/MultipartFormDataParser.java +++ b/core/src/main/java/hudson/util/MultipartFormDataParser.java @@ -28,6 +28,7 @@ import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; +import javax.annotation.CheckForNull; import javax.servlet.http.HttpServletRequest; import javax.servlet.ServletException; import java.util.List; @@ -71,4 +72,30 @@ public class MultipartFormDataParser { for (FileItem item : byName.values()) item.delete(); } + + /** + * Checks a Content-Type string to assert if it is "multipart/form-data". + * + * @param contentType Content-Type string. + * @return {@code true} if the content type is "multipart/form-data", otherwise {@code false}. + * @since 1.620 + */ + public static boolean isMultiPartForm(@CheckForNull String contentType) { + if (contentType == null) { + return false; + } + + String[] parts = contentType.split(";"); + if (parts.length == 0) { + return false; + } + + for (int i = 0; i < parts.length; i++) { + if ("multipart/form-data".equals(parts[i])) { + return true; + } + } + + return false; + } } diff --git a/core/src/main/java/hudson/util/NamingThreadFactory.java b/core/src/main/java/hudson/util/NamingThreadFactory.java index e55b7dd4a5c9f05129e6b2a93fecca62e3f00c0b..a1994a0433b04174e68ee0f7bbc86dbe84e31443 100644 --- a/core/src/main/java/hudson/util/NamingThreadFactory.java +++ b/core/src/main/java/hudson/util/NamingThreadFactory.java @@ -24,7 +24,6 @@ package hudson.util; -import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; diff --git a/core/src/main/java/hudson/util/NoClientBindProtocolSocketFactory.java b/core/src/main/java/hudson/util/NoClientBindProtocolSocketFactory.java index d23660b4e4aa90f7babe1f88a925da4e52dd0bd3..18a3e3e76173b60abd175993ab108c51888746b7 100644 --- a/core/src/main/java/hudson/util/NoClientBindProtocolSocketFactory.java +++ b/core/src/main/java/hudson/util/NoClientBindProtocolSocketFactory.java @@ -31,9 +31,7 @@ import java.net.UnknownHostException; import org.apache.commons.httpclient.ConnectTimeoutException; import org.apache.commons.httpclient.params.HttpConnectionParams; -import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; -import org.apache.commons.httpclient.protocol.ReflectionSocketFactory; /** * A SecureProtocolSocketFactory that creates sockets without binding to a specific interface. diff --git a/core/src/main/java/hudson/util/NoTempDir.java b/core/src/main/java/hudson/util/NoTempDir.java index b45aff8d4feacd48f6a1ddece06fc991b0a33dc5..10cfceb5ac04e446d2bb0c45c1836a8b2130a341 100644 --- a/core/src/main/java/hudson/util/NoTempDir.java +++ b/core/src/main/java/hudson/util/NoTempDir.java @@ -23,7 +23,6 @@ */ package hudson.util; -import hudson.Functions; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; diff --git a/core/src/main/java/hudson/util/PluginServletFilter.java b/core/src/main/java/hudson/util/PluginServletFilter.java index dfc8bdf03e38f670f9bbeec4273627959ea531a5..9b311aa790b1ad73c40f304869ce59cf3ee0e573 100644 --- a/core/src/main/java/hudson/util/PluginServletFilter.java +++ b/core/src/main/java/hudson/util/PluginServletFilter.java @@ -25,8 +25,10 @@ package hudson.util; import hudson.ExtensionPoint; import hudson.security.SecurityRealm; +import java.util.ArrayList; import jenkins.model.Jenkins; +import javax.annotation.CheckForNull; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -41,6 +43,8 @@ import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Servlet {@link Filter} that chains multiple {@link Filter}s, provided by plugins @@ -71,8 +75,11 @@ public class PluginServletFilter implements Filter, ExtensionPoint { /** * Lookup the instance from servlet context. + * + * @param c the ServletContext most of the time taken from a Jenkins instance + * @return get the current PluginServletFilter if it is already available */ - private static PluginServletFilter getInstance(ServletContext c) { + private static @CheckForNull PluginServletFilter getInstance(ServletContext c) { return (PluginServletFilter)c.getAttribute(KEY); } @@ -89,21 +96,26 @@ public class PluginServletFilter implements Filter, ExtensionPoint { } public static void addFilter(Filter filter) throws ServletException { - Jenkins j = Jenkins.getInstance(); - if (j==null) { + Jenkins j = Jenkins.getInstanceOrNull(); + + PluginServletFilter container = null; + if(j != null) { + container = getInstance(j.servletContext); + } + // https://marvelution.atlassian.net/browse/JJI-188 + if (j==null || container == null) { // report who is doing legacy registration LOGGER.log(Level.WARNING, "Filter instance is registered too early: "+filter, new Exception()); LEGACY.add(filter); } else { - PluginServletFilter container = getInstance(j.servletContext); filter.init(container.config); container.list.add(filter); } } public static void removeFilter(Filter filter) throws ServletException { - Jenkins j = Jenkins.getInstance(); - if (j==null) { + Jenkins j = Jenkins.getInstanceOrNull(); + if (j==null || getInstance(j.servletContext) == null) { LEGACY.remove(filter); } else { getInstance(j.servletContext).list.remove(filter); @@ -133,5 +145,33 @@ public class PluginServletFilter implements Filter, ExtensionPoint { list.clear(); } + @Restricted(NoExternalUse.class) + public static void cleanUp() { + PluginServletFilter instance = getInstance(Jenkins.getInstance().servletContext); + if (instance != null) { + // While we could rely on the current implementation of list being a CopyOnWriteArrayList + // safer to just take an explicit copy of the list and operate on the copy + for (Filter f: new ArrayList<>(instance.list)) { + instance.list.remove(f); + // remove from the list even if destroy() fails as a failed destroy is still a destroy + try { + f.destroy(); + } catch (RuntimeException e) { + LOGGER.log(Level.WARNING, "Filter " + f + " propagated an exception from its destroy method", + e); + } catch (Error e) { + throw e; // we are not supposed to catch errors, don't log as could be an OOM + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, "Filter " + f + " propagated an exception from its destroy method", e); + } + } + // if some fool adds a filter while we are terminating, we should just log the fact + if (!instance.list.isEmpty()) { + LOGGER.log(Level.SEVERE, "The following filters appear to have been added during clean up: {0}", + instance.list); + } + } + } + private static final Logger LOGGER = Logger.getLogger(PluginServletFilter.class.getName()); } diff --git a/core/src/main/java/hudson/util/ProcessKiller.java b/core/src/main/java/hudson/util/ProcessKiller.java index 81cb4b91a959e6e8205218105789661cdd377fee..a6fd99a542b5ca65bb3d894eab87e363939a344d 100644 --- a/core/src/main/java/hudson/util/ProcessKiller.java +++ b/core/src/main/java/hudson/util/ProcessKiller.java @@ -26,8 +26,6 @@ package hudson.util; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; -import hudson.util.ProcessTree.OSProcess; import java.io.IOException; import java.io.Serializable; @@ -40,7 +38,7 @@ import java.io.Serializable; *

    * Each implementation of {@link ProcessKiller} is instantiated once on the master. * Whenever a process needs to be killed, those implementations are serialized and sent over - * to the appropriate slave, then the {@link #kill(ProcessTree.OSProcess)} method is invoked + * to the appropriate agent, then the {@link #kill(ProcessTree.OSProcess)} method is invoked * to attempt to kill the process. * *

    diff --git a/core/src/main/java/hudson/util/ProcessKillingVeto.java b/core/src/main/java/hudson/util/ProcessKillingVeto.java new file mode 100644 index 0000000000000000000000000000000000000000..b8b874e42a55c8cd82f319af0cd5e7e5ab3cb39f --- /dev/null +++ b/core/src/main/java/hudson/util/ProcessKillingVeto.java @@ -0,0 +1,103 @@ +/* + * The MIT License + * + * Copyright (c) 2015, Daniel Weber + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.util.ProcessTreeRemoting.IOSProcess; + +import java.util.Collections; +import java.util.List; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +import jenkins.util.JenkinsJVM; + +/** + * Allows extensions to veto killing processes. If at least one extension vetoes + * the killing of a process, it will not be killed. This can be useful to keep + * daemon processes alive. An example is mspdbsrv.exe used by Microsoft + * compilers. + * + * See JENKINS-9104 + * + * @since 1.619 + * + * @author Daniel Weber + */ +public abstract class ProcessKillingVeto implements ExtensionPoint { + + /** + * Describes the cause for a process killing veto. + */ + public static class VetoCause { + private final String message; + + /** + * @param message A string describing the reason for the veto + */ + public VetoCause(@Nonnull String message) { + this.message = message; + } + + /** + * @return A string describing the reason for the veto. + */ + public @Nonnull String getMessage() { + return message; + } + } + + /** + * @return All ProcessKillingVeto extensions currently registered. An empty + * list if Jenkins is not available, never null. + */ + public static List all() { + if (JenkinsJVM.isJenkinsJVM()) { + return _all(); + } + return Collections.emptyList(); + } + + /** + * As classloading is lazy, the classes referenced in this method will not be resolved + * until the first time the method is invoked, so we use this method to guard access to Jenkins JVM only classes. + * + * @return All ProcessKillingVeto extensions currently registered. + */ + private static List _all() { + return ExtensionList.lookup(ProcessKillingVeto.class); + } + + /** + * Ask the extension whether it vetoes killing of the given process + * + * @param p The process that is about to be killed + * @return a {@link VetoCause} if the process should not be killed, + * null else. + */ + @CheckForNull + public abstract VetoCause vetoProcessKilling(@Nonnull IOSProcess p); +} diff --git a/core/src/main/java/hudson/util/ProcessTree.java b/core/src/main/java/hudson/util/ProcessTree.java index 00d64f5d75f7e5392f8c92cfab45bf9fb11a400a..5fae26a4d36c2aa08dd3b1d1f5d66af065ac5527 100644 --- a/core/src/main/java/hudson/util/ProcessTree.java +++ b/core/src/main/java/hudson/util/ProcessTree.java @@ -25,6 +25,9 @@ package hudson.util; import com.sun.jna.Memory; import com.sun.jna.Native; +import com.sun.jna.NativeLong; +import com.sun.jna.Pointer; +import com.sun.jna.LastErrorException; import com.sun.jna.ptr.IntByReference; import hudson.EnvVars; import hudson.FilePath; @@ -32,6 +35,7 @@ import hudson.Util; import hudson.remoting.Channel; import hudson.remoting.VirtualChannel; import hudson.slaves.SlaveComputer; +import hudson.util.ProcessKillingVeto.VetoCause; import hudson.util.ProcessTree.OSProcess; import hudson.util.ProcessTreeRemoting.IOSProcess; import hudson.util.ProcessTreeRemoting.IProcessTree; @@ -56,7 +60,9 @@ import java.util.SortedMap; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.CheckForNull; import static com.sun.jna.Pointer.NULL; +import jenkins.util.SystemProperties; import static hudson.util.jna.GNUCLibrary.LIBC; import static java.util.logging.Level.FINE; import static java.util.logging.Level.FINER; @@ -227,6 +233,22 @@ public abstract class ProcessTree implements Iterable, IProcessTree, */ public abstract void killRecursively() throws InterruptedException; + /** + * @return The first non-null {@link VetoCause} provided by a process killing veto extension for this OSProcess. + * null if no one objects killing the process. + */ + protected @CheckForNull VetoCause getVeto() { + for (ProcessKillingVeto vetoExtension : ProcessKillingVeto.all()) { + VetoCause cause = vetoExtension.vetoProcessKilling(this); + if (cause != null) { + if (LOGGER.isLoggable(FINEST)) + LOGGER.finest("Killing of pid " + getPid() + " vetoed by " + vetoExtension.getClass().getName() + ": " + cause.getMessage()); + return cause; + } + } + return null; + } + /** * Gets the command-line arguments of this process. * @@ -363,6 +385,8 @@ public abstract class ProcessTree implements Iterable, IProcessTree, } public void kill() throws InterruptedException { + if (getVeto() != null) + return; proc.destroy(); killByKiller(); } @@ -398,12 +422,18 @@ public abstract class ProcessTree implements Iterable, IProcessTree, } public void killRecursively() throws InterruptedException { + if (getVeto() != null) + return; + LOGGER.finer("Killing recursively "+getPid()); p.killRecursively(); killByKiller(); } public void kill() throws InterruptedException { + if (getVeto() != null) + return; + LOGGER.finer("Killing "+getPid()); p.kill(); killByKiller(); @@ -537,6 +567,8 @@ public abstract class ProcessTree implements Iterable, IProcessTree, * Tries to kill this process. */ public void kill() throws InterruptedException { + if (getVeto() != null) + return; try { int pid = getPid(); LOGGER.fine("Killing pid="+pid); @@ -557,6 +589,7 @@ public abstract class ProcessTree implements Iterable, IProcessTree, } public void killRecursively() throws InterruptedException { + // We kill individual processes of a tree, so handling vetoes inside #kill() is enough for UnixProcess es LOGGER.fine("Recursively killing pid="+getPid()); for (OSProcess p : getChildren()) p.killRecursively(); @@ -722,8 +755,28 @@ public abstract class ProcessTree implements Iterable, IProcessTree, /** * Implementation for Solaris that uses /proc. * - * Amazingly, this single code works for both 32bit and 64bit Solaris, despite the fact - * that does a lot of pointer manipulation and what not. + * /proc/PID/psinfo contains a psinfo_t struct. We use it to determine where the + * process arguments and environment are located in PID's address space. + * Note that the psinfo_t struct is different (different sized elements) for 32-bit + * vs 64-bit processes and the kernel will provide the version of the struct that + * matches the _reader_ (this Java process) regardless of whether PID is a + * 32-bit or 64-bit process. + * + * Note that this means that if PID is a 64-bit process, then a 32-bit Java + * process can not get meaningful values for envp and argv out of the psinfo_t. The + * values will have been truncated to 32-bits. + * + * /proc/PID/as contains the address space of the process we are inspecting. We can + * follow the envp and argv pointers from psinfo_t to find the environment variables + * and process arguments. When following pointers in this address space we need to + * make sure to use 32-bit or 64-bit pointers depending on what sized pointers + * PID uses, regardless of what size pointers the Java process uses. + * + * Note that the size of a 64-bit address space is larger than Long.MAX_VALUE (because + * longs are signed). So normal Java utilities like RandomAccessFile and FileChannel + * (which use signed longs as offsets) are not able to read from the end of the address + * space, where envp and argv will be. Therefore we need to use LIBC.pread() directly. + * when accessing this file. */ static class Solaris extends ProcfsUnix { protected OSProcess createProcess(final int pid) throws IOException { @@ -731,15 +784,23 @@ public abstract class ProcessTree implements Iterable, IProcessTree, } private class SolarisProcess extends UnixProcess { + private static final byte PR_MODEL_ILP32 = 1; + private static final byte PR_MODEL_LP64 = 2; + + /* + * True if target process is 64-bit (Java process may be different). + */ + private final boolean b64; + private final int ppid; /** - * Address of the environment vector. Even on 64bit Solaris this is still 32bit pointer. + * Address of the environment vector. */ - private final int envp; + private final long envp; /** - * Similarly, address of the arguments vector. + * Similarly, address of the arguments vector. */ - private final int argp; + private final long argp; private final int argc; private EnvVars envVars; private List arguments; @@ -791,10 +852,23 @@ public abstract class ProcessTree implements Iterable, IProcessTree, throw new IOException("psinfo PID mismatch"); // sanity check ppid = adjust(psinfo.readInt()); - psinfo.seek(188); // now jump to pr_argc - argc = adjust(psinfo.readInt()); - argp = adjust(psinfo.readInt()); - envp = adjust(psinfo.readInt()); + /* + * Read the remainder of psinfo_t differently depending on whether the + * Java process is 32-bit or 64-bit. + */ + if (Pointer.SIZE == 8) { + psinfo.seek(236); // offset of pr_argc + argc = adjust(psinfo.readInt()); + argp = adjustL(psinfo.readLong()); + envp = adjustL(psinfo.readLong()); + b64 = (psinfo.readByte() == PR_MODEL_LP64); + } else { + psinfo.seek(188); // offset of pr_argc + argc = adjust(psinfo.readInt()); + argp = to64(adjust(psinfo.readInt())); + envp = to64(adjust(psinfo.readInt())); + b64 = (psinfo.readByte() == PR_MODEL_LP64); + } } finally { psinfo.close(); } @@ -812,23 +886,28 @@ public abstract class ProcessTree implements Iterable, IProcessTree, return arguments; arguments = new ArrayList(argc); + if (argc == 0) { + return arguments; + } + int psize = b64 ? 8 : 4; + Memory m = new Memory(psize); try { - RandomAccessFile as = new RandomAccessFile(getFile("as"),"r"); if(LOGGER.isLoggable(FINER)) LOGGER.finer("Reading "+getFile("as")); + int fd = LIBC.open(getFile("as").getAbsolutePath(), 0); try { for( int n=0; n, IProcessTree, return envVars; envVars = new EnvVars(); + if (envp == 0) { + return envVars; + } + + int psize = b64 ? 8 : 4; + Memory m = new Memory(psize); try { - RandomAccessFile as = new RandomAccessFile(getFile("as"),"r"); if(LOGGER.isLoggable(FINER)) LOGGER.finer("Reading "+getFile("as")); + int fd = LIBC.open(getFile("as").getAbsolutePath(), 0); try { for( int n=0; ; n++ ) { // read a pointer to one entry - as.seek(to64(envp+n*4)); - int p = adjust(as.readInt()); - if(p==0) - break; // completed the walk + LIBC.pread(fd, m, new NativeLong(psize), new NativeLong(envp+n*psize)); + long addr = b64 ? m.getLong(0) : m.getInt(0); + if (addr == 0) // completed the walk + break; // now read the null-terminated string - envVars.addLine(readLine(as, p, "env["+ n +"]")); + envVars.addLine(readLine(fd, addr, "env["+ n +"]")); } } finally { - as.close(); + LIBC.close(fd); } - } catch (IOException e) { + } catch (IOException | LastErrorException e) { // failed to read. this can happen under normal circumstances (most notably permission denied) // so don't report this as an error. } - return envVars; } - private String readLine(RandomAccessFile as, int p, String prefix) throws IOException { + private String readLine(int fd, long addr, String prefix) throws IOException { if(LOGGER.isLoggable(FINEST)) - LOGGER.finest("Reading "+prefix+" at "+p); + LOGGER.finest("Reading "+prefix+" at "+addr); - as.seek(to64(p)); + Memory m = new Memory(1); + byte ch = 1; ByteArrayOutputStream buf = new ByteArrayOutputStream(); - int ch,i=0; - while((ch=as.read())>0) { - if((++i)%100==0 && LOGGER.isLoggable(FINEST)) - LOGGER.finest(prefix +" is so far "+buf.toString()); - + while(true) { + LIBC.pread(fd, m, new NativeLong(1), new NativeLong(addr)); + ch = m.getByte(0); + if (ch == 0) + break; buf.write(ch); + addr++; } String line = buf.toString(); if(LOGGER.isLoggable(FINEST)) @@ -906,6 +992,13 @@ public abstract class ProcessTree implements Iterable, IProcessTree, return i; } + public static long adjustL(long i) { + if(IS_LITTLE_ENDIAN) { + return Long.reverseBytes(i); + } else { + return i; + } + } } /** @@ -1255,6 +1348,6 @@ public abstract class ProcessTree implements Iterable, IProcessTree, *

    * This property supports two names for a compatibility reason. */ - public static boolean enabled = !Boolean.getBoolean(ProcessTreeKiller.class.getName()+".disable") - && !Boolean.getBoolean(ProcessTree.class.getName()+".disable"); + public static boolean enabled = !SystemProperties.getBoolean(ProcessTreeKiller.class.getName()+".disable") + && !SystemProperties.getBoolean(ProcessTree.class.getName()+".disable"); } diff --git a/core/src/main/java/hudson/util/QuotedStringTokenizer.java b/core/src/main/java/hudson/util/QuotedStringTokenizer.java index 248f1ac95402496b3874f8aa350e588cf8bdcf02..e33b15ccab968c6b7ee980010ef2de8dda94ee8a 100644 --- a/core/src/main/java/hudson/util/QuotedStringTokenizer.java +++ b/core/src/main/java/hudson/util/QuotedStringTokenizer.java @@ -44,7 +44,7 @@ import java.util.ArrayList; /** StringTokenizer with Quoting support. * * This class is a copy of the java.util.StringTokenizer API and - * the behaviour is the same, except that single and doulbe quoted + * the behaviour is the same, except that single and double quoted * string values are recognized. * Delimiters within quotes are not considered delimiters. * Quotes can be escaped with '\'. @@ -328,7 +328,7 @@ public class QuotedStringTokenizer /* ------------------------------------------------------------ */ /** Quote a string. * The string is quoted only if quoting is required due to - * embeded delimiters, quote characters or the + * embedded delimiters, quote characters or the * empty string. * @param s The string to quote. * @return quoted string @@ -358,7 +358,7 @@ public class QuotedStringTokenizer /* ------------------------------------------------------------ */ /** Quote a string. * The string is quoted only if quoting is required due to - * embeded delimiters, quote characters or the + * embedded delimiters, quote characters or the * empty string. * @param s The string to quote. * @return quoted string diff --git a/core/src/main/java/hudson/util/RemotingDiagnostics.java b/core/src/main/java/hudson/util/RemotingDiagnostics.java index 8a2a51aa28608fc251652dbd90ef4f7715a26b16..ed3a4c814b5f1f73ed2efa72f894b5a843f8a406 100644 --- a/core/src/main/java/hudson/util/RemotingDiagnostics.java +++ b/core/src/main/java/hudson/util/RemotingDiagnostics.java @@ -61,7 +61,7 @@ import java.util.TreeMap; * Various remoting operations related to diagnostics. * *

    - * These code are useful wherever {@link VirtualChannel} is used, such as master, slaves, Maven JVMs, etc. + * These code are useful wherever {@link VirtualChannel} is used, such as master, agents, Maven JVMs, etc. * * @author Kohsuke Kawaguchi * @since 1.175 diff --git a/core/src/main/java/hudson/util/RingBufferLogHandler.java b/core/src/main/java/hudson/util/RingBufferLogHandler.java index 469cdbba4bcefa29d142b24b732a1091d2b3e36d..89d0b124d78e0d1b9e5712a181c4f36467b79b04 100644 --- a/core/src/main/java/hudson/util/RingBufferLogHandler.java +++ b/core/src/main/java/hudson/util/RingBufferLogHandler.java @@ -41,6 +41,11 @@ public class RingBufferLogHandler extends Handler { private final LogRecord[] records; private volatile int size = 0; + /** + * This constructor is deprecated. It can't access system properties with {@link jenkins.util.SystemProperties} + * as it's not legal to use it on remoting agents. + */ + @Deprecated public RingBufferLogHandler() { this(DEFAULT_RING_BUFFER_SIZE); } diff --git a/core/src/main/java/hudson/util/RobustCollectionConverter.java b/core/src/main/java/hudson/util/RobustCollectionConverter.java index 78dc2b2f2fdf3f85fcde05cea9271628969f4e57..d0903ff82b5c9cdc9e15d933bf51202a8ee2962b 100644 --- a/core/src/main/java/hudson/util/RobustCollectionConverter.java +++ b/core/src/main/java/hudson/util/RobustCollectionConverter.java @@ -36,6 +36,8 @@ import java.util.Collection; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; +import jenkins.util.xstream.CriticalXStreamException; + /** * {@link CollectionConverter} that ignores {@link XStreamException}. @@ -82,6 +84,8 @@ public class RobustCollectionConverter extends CollectionConverter { try { Object item = readItem(reader, context, collection); collection.add(item); + } catch (CriticalXStreamException e) { + throw e; } catch (XStreamException e) { RobustReflectionConverter.addErrorInContext(context, e); } catch (LinkageError e) { diff --git a/core/src/main/java/hudson/util/RobustMapConverter.java b/core/src/main/java/hudson/util/RobustMapConverter.java index 6a52bfb0162070778f3d92386ff3c07f4fde8824..48bdf94c79200449ed2edf16c42fe8e9aed58962 100644 --- a/core/src/main/java/hudson/util/RobustMapConverter.java +++ b/core/src/main/java/hudson/util/RobustMapConverter.java @@ -30,6 +30,7 @@ import com.thoughtworks.xstream.converters.collections.MapConverter; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.mapper.Mapper; import java.util.Map; +import jenkins.util.xstream.CriticalXStreamException; /** * Loads a {@link Map} while tolerating read errors on its keys and values. @@ -55,6 +56,8 @@ final class RobustMapConverter extends MapConverter { reader.moveDown(); try { return readItem(reader, context, map); + } catch (CriticalXStreamException x) { + throw x; } catch (XStreamException x) { RobustReflectionConverter.addErrorInContext(context, x); return ERROR; diff --git a/core/src/main/java/hudson/util/RobustReflectionConverter.java b/core/src/main/java/hudson/util/RobustReflectionConverter.java index 18909ba74f52d144e05b3ecd1938ca812a3f36ce..3ec65ec994cc9c08c85e931f5c4106b485521c06 100644 --- a/core/src/main/java/hudson/util/RobustReflectionConverter.java +++ b/core/src/main/java/hudson/util/RobustReflectionConverter.java @@ -51,9 +51,13 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Map; import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import static java.util.logging.Level.FINE; import java.util.logging.Logger; import javax.annotation.Nonnull; +import javax.annotation.concurrent.GuardedBy; +import jenkins.util.xstream.CriticalXStreamException; /** * Custom {@link ReflectionConverter} that handle errors more gracefully. @@ -74,7 +78,14 @@ public class RobustReflectionConverter implements Converter { private transient ReflectionProvider pureJavaReflectionProvider; private final @Nonnull XStream2.ClassOwnership classOwnership; /** {@code pkg.Clazz#fieldName} */ - private final Set criticalFields = Collections.synchronizedSet(new HashSet()); + /** There are typically few critical fields around, but we end up looking up in this map a lot. + in addition, this map is really only written to during static initialization, so we should use + reader writer lock to avoid locking as much as possible. In addition, to avoid looking up + the class name (which requires calling class.getName, which may not be cached, the map is inverted + with the fields as the keys.**/ + private final ReadWriteLock criticalFieldsLock = new ReentrantReadWriteLock(); + @GuardedBy("criticalFieldsLock") + private final Map> criticalFields = new HashMap>(); public RobustReflectionConverter(Mapper mapper, ReflectionProvider reflectionProvider) { this(mapper, reflectionProvider, new XStream2().new PluginClassOwnership()); @@ -88,7 +99,38 @@ public class RobustReflectionConverter implements Converter { } void addCriticalField(Class clazz, String field) { - criticalFields.add(clazz.getName() + '#' + field); + // Lock the write lock + criticalFieldsLock.writeLock().lock(); + try { + // If the class already exists, then add a new field, otherwise + // create the hash map field + if (!criticalFields.containsKey(field)) { + criticalFields.put(field, new HashSet()); + } + criticalFields.get(field).add(clazz.getName()); + } + finally { + // Unlock + criticalFieldsLock.writeLock().unlock(); + } + } + + private boolean hasCriticalField(Class clazz, String field) { + // Lock the write lock + criticalFieldsLock.readLock().lock(); + try { + Set classesWithField = criticalFields.get(field); + if (classesWithField == null) { + return false; + } + if (!classesWithField.contains(clazz.getName())) { + return false; + } + return true; + } + finally { + criticalFieldsLock.readLock().unlock(); + } } public boolean canConvert(Class type) { @@ -272,7 +314,7 @@ public class RobustReflectionConverter implements Converter { String fieldName = mapper.realMember(result.getClass(), reader.getNodeName()); for (Class concrete = result.getClass(); concrete != null; concrete = concrete.getSuperclass()) { // Not quite right since a subclass could shadow a field, but probably suffices: - if (criticalFields.contains(concrete.getName() + '#' + fieldName)) { + if (hasCriticalField(concrete, fieldName)) { critical = true; break; } @@ -307,9 +349,11 @@ public class RobustReflectionConverter implements Converter { implicitCollectionsForCurrentObject = writeValueToImplicitCollection(context, value, implicitCollectionsForCurrentObject, result, fieldName); } } + } catch (CriticalXStreamException e) { + throw e; } catch (XStreamException e) { if (critical) { - throw e; + throw new CriticalXStreamException(e); } addErrorInContext(context, e); } catch (LinkageError e) { diff --git a/core/src/main/java/hudson/util/Secret.java b/core/src/main/java/hudson/util/Secret.java index 80be75b8ffa93d38cd099ab0d79773a374c2cb0d..a2a2bcb97167cabcd03b207a0e299dd1af93b729 100644 --- a/core/src/main/java/hudson/util/Secret.java +++ b/core/src/main/java/hudson/util/Secret.java @@ -29,6 +29,7 @@ import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.trilead.ssh2.crypto.Base64; +import jenkins.util.SystemProperties; import jenkins.model.Jenkins; import hudson.Util; import jenkins.security.CryptoConfidentialKey; @@ -40,6 +41,11 @@ import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.io.IOException; import java.security.GeneralSecurityException; +import java.util.regex.Pattern; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Glorified {@link String} that uses encryption in the persisted form, to avoid accidental exposure of a secret. @@ -58,6 +64,7 @@ public final class Secret implements Serializable { /** * Unencrypted secret text. */ + @Nonnull private final String value; private Secret(String value) { @@ -83,6 +90,7 @@ public final class Secret implements Serializable { * Before using this method, ask yourself if you'd be better off using {@link Secret#toString(Secret)} * to avoid NPE. */ + @Nonnull public String getPlainText() { return value; } @@ -128,11 +136,20 @@ public final class Secret implements Serializable { } } + /** + * Pattern matching a possible output of {@link #getEncryptedValue}. + * Basically, any Base64-encoded value. + * You must then call {@link #decrypt} to eliminate false positives. + */ + @Restricted(NoExternalUse.class) + public static final Pattern ENCRYPTED_VALUE_PATTERN = Pattern.compile("[A-Za-z0-9+/]+={0,2}"); + /** * Reverse operation of {@link #getEncryptedValue()}. Returns null * if the given cipher text was invalid. */ - public static Secret decrypt(String data) { + @CheckForNull + public static Secret decrypt(@CheckForNull String data) { if(data==null) return null; try { byte[] in = Base64.decode(data.toCharArray()); @@ -180,10 +197,9 @@ public final class Secret implements Serializable { * *

    * Useful for recovering a value from a form field. - * - * @return never null */ - public static Secret fromString(String data) { + @Nonnull + public static Secret fromString(@CheckForNull String data) { data = Util.fixNull(data); Secret s = decrypt(data); if(s==null) s=new Secret(data); @@ -195,7 +211,8 @@ public final class Secret implements Serializable { * To be consistent with {@link #fromString(String)}, this method doesn't distinguish * empty password and null password. */ - public static String toString(Secret s) { + @Nonnull + public static String toString(@CheckForNull Secret s) { return s==null ? "" : s.value; } @@ -223,7 +240,7 @@ public final class Secret implements Serializable { * Workaround for JENKINS-6459 / http://java.net/jira/browse/GLASSFISH-11862 * @see #getCipher(String) */ - private static final String PROVIDER = System.getProperty(Secret.class.getName()+".provider"); + private static final String PROVIDER = SystemProperties.getString(Secret.class.getName()+".provider"); /** * For testing only. Override the secret key so that we can test this class without {@link Jenkins}. diff --git a/core/src/main/java/hudson/util/SecretRewriter.java b/core/src/main/java/hudson/util/SecretRewriter.java index 37dc9fb2ede19377bdd3c3ddc6232d33734e2786..45e5b6ae27ac97681587dc47b0a761dd690f7339 100644 --- a/core/src/main/java/hudson/util/SecretRewriter.java +++ b/core/src/main/java/hudson/util/SecretRewriter.java @@ -13,6 +13,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; +import java.nio.file.LinkOption; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.util.HashSet; @@ -78,42 +79,36 @@ public class SecretRewriter { public boolean rewrite(File f, File backup) throws InvalidKeyException, IOException { AtomicFileWriter w = new AtomicFileWriter(f, "UTF-8"); try { - PrintWriter out = new PrintWriter(new BufferedWriter(w)); boolean modified = false; // did we actually change anything? - try { - FileInputStream fin = new FileInputStream(f); - try { + try (PrintWriter out = new PrintWriter(new BufferedWriter(w))) { + try (FileInputStream fin = new FileInputStream(f)) { BufferedReader r = new BufferedReader(new InputStreamReader(fin, "UTF-8")); String line; StringBuilder buf = new StringBuilder(); - while ((line=r.readLine())!=null) { - int copied=0; + while ((line = r.readLine()) != null) { + int copied = 0; buf.setLength(0); while (true) { - int sidx = line.indexOf('>',copied); - if (sidx<0) break; - int eidx = line.indexOf('<',sidx); - if (eidx<0) break; + int sidx = line.indexOf('>', copied); + if (sidx < 0) break; + int eidx = line.indexOf('<', sidx); + if (eidx < 0) break; - String elementText = line.substring(sidx+1,eidx); + String elementText = line.substring(sidx + 1, eidx); String replacement = tryRewrite(elementText); if (!replacement.equals(elementText)) modified = true; - buf.append(line.substring(copied,sidx+1)); + buf.append(line.substring(copied, sidx + 1)); buf.append(replacement); copied = eidx; } buf.append(line.substring(copied)); out.println(buf.toString()); } - } finally { - fin.close(); } - } finally { - out.close(); } if (modified) { @@ -145,7 +140,7 @@ public class SecretRewriter { private int rewriteRecursive(File dir, String relative, TaskListener listener) throws InvalidKeyException { String canonical; try { - canonical = dir.getCanonicalPath(); + canonical = dir.toPath().toRealPath(new LinkOption[0]).toString(); } catch (IOException e) { canonical = dir.getAbsolutePath(); // } diff --git a/core/src/main/java/hudson/util/SequentialExecutionQueue.java b/core/src/main/java/hudson/util/SequentialExecutionQueue.java index 31f10e049d9a672c5bbb5a747ac884e2e1863df3..a1cfa3ccba97beff3fbb220db77674ca2f65557a 100644 --- a/core/src/main/java/hudson/util/SequentialExecutionQueue.java +++ b/core/src/main/java/hudson/util/SequentialExecutionQueue.java @@ -1,5 +1,6 @@ package hudson.util; +import javax.annotation.Nonnull; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -58,7 +59,7 @@ public class SequentialExecutionQueue implements Executor { } - public synchronized void execute(Runnable item) { + public synchronized void execute(@Nonnull Runnable item) { QueueEntry e = entries.get(item); if(e==null) { e = new QueueEntry(item); diff --git a/core/src/main/java/hudson/util/Service.java b/core/src/main/java/hudson/util/Service.java index 56ec8928f03e947854e66033202188db58159209..6275b07e3f9f1132e07a867a5f1c34ee483ffc39 100644 --- a/core/src/main/java/hudson/util/Service.java +++ b/core/src/main/java/hudson/util/Service.java @@ -50,28 +50,25 @@ public class Service { final Enumeration e = classLoader.getResources("META-INF/services/"+type.getName()); while (e.hasMoreElements()) { URL url = e.nextElement(); - BufferedReader configFile = new BufferedReader(new InputStreamReader(url.openStream(),"UTF-8")); - try { + try (BufferedReader configFile = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"))) { String line; while ((line = configFile.readLine()) != null) { line = line.trim(); - if (line.startsWith("#") || line.length()==0) continue; + if (line.startsWith("#") || line.length() == 0) continue; try { Class t = classLoader.loadClass(line); - if (!type.isAssignableFrom(t)) continue; // invalid type + if (!type.isAssignableFrom(t)) continue; // invalid type result.add(type.cast(t.newInstance())); } catch (ClassNotFoundException x) { - LOGGER.log(WARNING,"Failed to load "+line,x); + LOGGER.log(WARNING, "Failed to load " + line, x); } catch (InstantiationException x) { - LOGGER.log(WARNING,"Failed to load "+line,x); + LOGGER.log(WARNING, "Failed to load " + line, x); } catch (IllegalAccessException x) { - LOGGER.log(WARNING,"Failed to load "+line,x); + LOGGER.log(WARNING, "Failed to load " + line, x); } } - } finally { - configFile.close(); } } @@ -87,26 +84,23 @@ public class Service { Enumeration e = cl.getResources("META-INF/services/" + spi.getName()); while(e.hasMoreElements()) { final URL url = e.nextElement(); - final BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream(),"UTF-8")); - try { + try (BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"))) { String line; - while((line=r.readLine())!=null) { - if(line.startsWith("#")) + while ((line = r.readLine()) != null) { + if (line.startsWith("#")) continue; // comment line line = line.trim(); - if(line.length()==0) + if (line.length() == 0) continue; // empty line. ignore. try { result.add(cl.loadClass(line).asSubclass(spi)); } catch (ClassNotFoundException x) { - LOGGER.log(Level.WARNING, "Failed to load "+line, x); + LOGGER.log(Level.WARNING, "Failed to load " + line, x); } } } catch (IOException x) { - LOGGER.log(Level.WARNING, "Failed to load "+url, x); - } finally { - r.close(); + LOGGER.log(Level.WARNING, "Failed to load " + url, x); } } } catch (IOException x) { diff --git a/core/src/main/java/hudson/util/StreamTaskListener.java b/core/src/main/java/hudson/util/StreamTaskListener.java index 4d6aea568d74bce91f31172e5150c0a866ebb2b6..5e4a294fb06069d87ed9987a0f6ef738b242235c 100644 --- a/core/src/main/java/hudson/util/StreamTaskListener.java +++ b/core/src/main/java/hudson/util/StreamTaskListener.java @@ -28,8 +28,6 @@ import hudson.console.ConsoleNote; import hudson.console.HudsonExceptionNote; import hudson.model.TaskListener; import hudson.remoting.RemoteOutputStream; -import org.kohsuke.stapler.framework.io.WriterOutputStream; - import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; @@ -46,6 +44,7 @@ import java.io.Writer; import java.nio.charset.Charset; import java.util.logging.Level; import java.util.logging.Logger; +import org.kohsuke.stapler.framework.io.WriterOutputStream; /** * {@link TaskListener} that generates output into a single stream. @@ -98,6 +97,22 @@ public class StreamTaskListener extends AbstractTaskListener implements Serializ this(new FileOutputStream(out),charset); } + /** + * Constructs a {@link StreamTaskListener} that sends the output to a specified file. + * + * @param out the file. + * @param append if {@code true}, then output will be written to the end of the file rather than the beginning. + * @param charset if non-{@code null} then the charset to use when writing. + * @throws IOException if the file could not be opened. + * @since 1.651 + */ + public StreamTaskListener(File out, boolean append, Charset charset) throws IOException { + // don't do buffering so that what's written to the listener + // gets reflected to the file immediately, which can then be + // served to the browser immediately + this(new FileOutputStream(out, append),charset); + } + public StreamTaskListener(Writer w) throws IOException { this(new WriterOutputStream(w)); } diff --git a/core/src/main/java/hudson/util/SubClassGenerator.java b/core/src/main/java/hudson/util/SubClassGenerator.java index f6076ddda175394a05119708462b9de4d40b85a3..0dbb8d6dec3bde12ec9d8ee7f24f9ccf174fa690 100644 --- a/core/src/main/java/hudson/util/SubClassGenerator.java +++ b/core/src/main/java/hudson/util/SubClassGenerator.java @@ -76,7 +76,7 @@ public class SubClassGenerator extends ClassLoader { Class c = defineClass(name, image, 0, image.length).asSubclass(base); - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if (h!=null) // null only during tests. ((UberClassLoader)h.pluginManager.uberClassLoader).addNamedClass(name,c); // can't change the field type as it breaks binary compatibility diff --git a/core/src/main/java/hudson/util/TextFile.java b/core/src/main/java/hudson/util/TextFile.java index 4e16532044291ec497acfcdd05daa925ae972f77..b6fb8341e8e3b23abac560f363ab145c8dd94355 100644 --- a/core/src/main/java/hudson/util/TextFile.java +++ b/core/src/main/java/hudson/util/TextFile.java @@ -67,13 +67,10 @@ public class TextFile { public String read() throws IOException { StringWriter out = new StringWriter(); PrintWriter w = new PrintWriter(out); - BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8")); - try { + try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) { String line; - while((line=in.readLine())!=null) + while ((line = in.readLine()) != null) w.println(line); - } finally{ - in.close(); } return out.toString(); } @@ -177,23 +174,20 @@ public class TextFile { * So all in all, this algorithm should work decently, and it works quite efficiently on a large text. */ public @Nonnull String fastTail(int numChars, Charset cs) throws IOException { - RandomAccessFile raf = new RandomAccessFile(file,"r"); - try { + try (RandomAccessFile raf = new RandomAccessFile(file, "r")) { long len = raf.length(); // err on the safe side and assume each char occupies 4 bytes // additional 1024 byte margin is to bring us back in sync in case we started reading from non-char boundary. - long pos = Math.max(0, len - (numChars*4+1024)); + long pos = Math.max(0, len - (numChars * 4 + 1024)); raf.seek(pos); - byte[] tail = new byte[(int) (len-pos)]; + byte[] tail = new byte[(int) (len - pos)]; raf.readFully(tail); String tails = cs.decode(java.nio.ByteBuffer.wrap(tail)).toString(); - return new String(tails.substring(Math.max(0,tails.length()-numChars))); // trim the baggage of substring by allocating a new String - } finally { - raf.close(); + return new String(tails.substring(Math.max(0, tails.length() - numChars))); // trim the baggage of substring by allocating a new String } } diff --git a/core/src/main/java/hudson/util/XStream2.java b/core/src/main/java/hudson/util/XStream2.java index 325f4a8556f342e2bdb18e24641bac21c2ab00a8..48d967880b76e247aac944545494048062c0746b 100644 --- a/core/src/main/java/hudson/util/XStream2.java +++ b/core/src/main/java/hudson/util/XStream2.java @@ -43,10 +43,11 @@ import com.thoughtworks.xstream.io.HierarchicalStreamDriver; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.mapper.CannotResolveClassException; -import edu.umd.cs.findbugs.annotations.SuppressWarnings; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import hudson.PluginManager; import hudson.PluginWrapper; import hudson.diagnosis.OldDataMonitor; +import hudson.remoting.ClassFilter; import hudson.util.xstream.ImmutableSetConverter; import hudson.util.xstream.ImmutableSortedSetConverter; import jenkins.model.Jenkins; @@ -105,7 +106,7 @@ public class XStream2 extends XStream { public Object unmarshal(HierarchicalStreamReader reader, Object root, DataHolder dataHolder) { // init() is too early to do this // defensive because some use of XStream happens before plugins are initialized. - Jenkins h = Jenkins.getInstance(); + Jenkins h = Jenkins.getInstanceOrNull(); if(h!=null && h.pluginManager!=null && h.pluginManager.uberClassLoader!=null) { setClassLoader(h.pluginManager.uberClassLoader); } @@ -150,7 +151,6 @@ public class XStream2 extends XStream { registerConverter(new ImmutableSortedSetConverter(getMapper(),getReflectionProvider()),10); registerConverter(new ImmutableSetConverter(getMapper(),getReflectionProvider()),10); registerConverter(new ImmutableListConverter(getMapper(),getReflectionProvider()),10); - registerConverter(new ConcurrentHashMapConverter(getMapper(),getReflectionProvider()),10); registerConverter(new CopyOnWriteMap.Tree.ConverterImpl(getMapper()),10); // needs to override MapConverter registerConverter(new DescribableList.ConverterImpl(getMapper()),10); // explicitly added to handle subtypes registerConverter(new Label.ConverterImpl(),10); @@ -159,6 +159,8 @@ public class XStream2 extends XStream { // but before reflection-based one kicks in. registerConverter(new AssociatedConverterImpl(this), -10); + registerConverter(new BlacklistedTypesConverter(), PRIORITY_VERY_HIGH); // SECURITY-247 defense + registerConverter(new DynamicProxyConverter(getMapper()) { // SECURITY-105 defense @Override public boolean canConvert(Class type) { return /* this precedes NullConverter */ type != null && super.canConvert(type); @@ -413,13 +415,13 @@ public class XStream2 extends XStream { private PluginManager pm; - @SuppressWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") // classOwnership checked for null so why does FB complain? + @SuppressFBWarnings("NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") // classOwnership checked for null so why does FB complain? @Override public String ownerOf(Class clazz) { if (classOwnership != null) { return classOwnership.ownerOf(clazz); } if (pm == null) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); if (j != null) { pm = j.getPluginManager(); } @@ -434,4 +436,30 @@ public class XStream2 extends XStream { } + private static class BlacklistedTypesConverter implements Converter { + @Override + public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) { + throw new UnsupportedOperationException("Refusing to marshal " + source.getClass().getName() + " for security reasons"); + } + + @Override + public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { + throw new ConversionException("Refusing to unmarshal " + reader.getNodeName() + " for security reasons"); + } + + @Override + public boolean canConvert(Class type) { + if (type == null) { + return false; + } + try { + ClassFilter.DEFAULT.check(type); + ClassFilter.DEFAULT.check(type.getName()); + } catch (SecurityException se) { + // claim we can convert all the scary stuff so we can throw exceptions when attempting to do so + return true; + } + return false; + } + } } diff --git a/core/src/main/java/hudson/util/io/ParserConfigurator.java b/core/src/main/java/hudson/util/io/ParserConfigurator.java index bac60c7e790910425a671f391aed175f89469dde..878fba535b030361fdc9be6e527b1c691c621aa9 100644 --- a/core/src/main/java/hudson/util/io/ParserConfigurator.java +++ b/core/src/main/java/hudson/util/io/ParserConfigurator.java @@ -75,7 +75,7 @@ public abstract class ParserConfigurator implements ExtensionPoint, Serializable public static void applyConfiguration(SAXReader reader, Object context) throws IOException, InterruptedException { Collection all = Collections.emptyList(); - if (Jenkins.getInstance()==null) { + if (Jenkins.getInstanceOrNull()==null) { Channel ch = Channel.current(); if (ch!=null) all = ch.call(new SlaveToMasterCallable, IOException>() { diff --git a/core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java b/core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java index e35d8816e38d988f96457457e8233912f4574457..1cac1df91a13f892a793647059a97512086bfa72 100644 --- a/core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java +++ b/core/src/main/java/hudson/util/io/ReopenableFileOutputStream.java @@ -37,8 +37,9 @@ import java.io.OutputStream; * and then keep writing. * * @author Kohsuke Kawaguchi + * @deprecated due to risk for file leak. Prefer {@link RewindableFileOutputStream} */ -public class ReopenableFileOutputStream extends OutputStream { +@Deprecated public class ReopenableFileOutputStream extends OutputStream { protected final File out; private OutputStream current; diff --git a/core/src/main/java/hudson/util/io/ReopenableRotatingFileOutputStream.java b/core/src/main/java/hudson/util/io/ReopenableRotatingFileOutputStream.java index 7bcab185ac12c0abecaa3c396c4fd621f36d3657..3800f54c16dc5cc61d24722c4e9b3edc327a8b00 100644 --- a/core/src/main/java/hudson/util/io/ReopenableRotatingFileOutputStream.java +++ b/core/src/main/java/hudson/util/io/ReopenableRotatingFileOutputStream.java @@ -31,8 +31,9 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi * @since 1.416 + * @deprecated due to risk for file leak. Prefer {@link RewindableRotatingFileOutputStream} */ -public class ReopenableRotatingFileOutputStream extends ReopenableFileOutputStream { +@Deprecated public class ReopenableRotatingFileOutputStream extends ReopenableFileOutputStream { /** * Number of log files to keep. */ diff --git a/core/src/main/java/hudson/util/io/RewindableFileOutputStream.java b/core/src/main/java/hudson/util/io/RewindableFileOutputStream.java new file mode 100644 index 0000000000000000000000000000000000000000..444040d5894cdc5a9f0db1122994d13fc1910f8e --- /dev/null +++ b/core/src/main/java/hudson/util/io/RewindableFileOutputStream.java @@ -0,0 +1,103 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util.io; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +/** + * {@link OutputStream} that writes to a file. + *

    + * Allows the caller to rewind the stream and override previous content with fresh new data. + * @since 2.18 + */ +public class RewindableFileOutputStream extends OutputStream { + protected final File out; + private boolean closed; + + private OutputStream current; + + public RewindableFileOutputStream(File out) { + this.out = out; + } + + private synchronized OutputStream current() throws IOException { + if (current == null) { + if (!closed) { + try { + current = new FileOutputStream(out,false); + } catch (FileNotFoundException e) { + throw new IOException("Failed to open "+out,e); + } + } + else { + throw new IOException(out.getName()+" stream is closed"); + } + } + return current; + } + + @Override + public void write(int b) throws IOException { + current().write(b); + } + + @Override + public void write(byte[] b) throws IOException { + current().write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + current().write(b, off, len); + } + + @Override + public void flush() throws IOException { + current().flush(); + } + + @Override + public synchronized void close() throws IOException { + closeCurrent(); + closed = true; + } + + /** + * In addition to close, ensure that the next "open" would truncate the file. + */ + public synchronized void rewind() throws IOException { + closeCurrent(); + } + + private void closeCurrent() throws IOException { + if (current != null) { + current.close(); + current = null; + } + } +} diff --git a/test/src/main/java/org/jvnet/hudson/test/ClosureExecuterAction.java b/core/src/main/java/hudson/util/io/RewindableRotatingFileOutputStream.java similarity index 52% rename from test/src/main/java/org/jvnet/hudson/test/ClosureExecuterAction.java rename to core/src/main/java/hudson/util/io/RewindableRotatingFileOutputStream.java index 9feb531faf3d15299b04e35da700d7604e92badd..aa53ea9f4c46dbd13284da0ebc48ac7efaf42269 100644 --- a/test/src/main/java/org/jvnet/hudson/test/ClosureExecuterAction.java +++ b/core/src/main/java/hudson/util/io/RewindableRotatingFileOutputStream.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2011, CloudBees, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,50 +21,52 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; - -import hudson.Extension; -import hudson.model.RootAction; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerResponse; +package hudson.util.io; +import java.io.File; import java.io.IOException; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; /** - * Server-side logic that implements {@link HudsonTestCase#executeOnServer(Callable)}. + * {@link ReopenableFileOutputStream} that does log rotation upon rewind. * * @author Kohsuke Kawaguchi + * @since 2.18 */ -@Extension -public final class ClosureExecuterAction implements RootAction { - private final Map runnables = Collections.synchronizedMap(new HashMap()); - - public void add(UUID uuid, Runnable r) { - runnables.put(uuid,r); - } +public class RewindableRotatingFileOutputStream extends RewindableFileOutputStream { + /** + * Number of log files to keep. + */ + private final int size; - public void doIndex(StaplerResponse rsp, @QueryParameter("uuid") String uuid) throws IOException { - Runnable r = runnables.remove(UUID.fromString(uuid)); - if (r!=null) { - r.run(); - } else { - rsp.sendError(404); - } + public RewindableRotatingFileOutputStream(File out, int size) { + super(out); + this.size = size; } - public String getIconFileName() { - return null; + protected File getNumberedFileName(int n) { + if (n==0) return out; + return new File(out.getPath()+"."+n); } - public String getDisplayName() { - return null; + @Override + public void rewind() throws IOException { + super.rewind(); + for (int i=size-1;i>=0;i--) { + File fi = getNumberedFileName(i); + if (fi.exists()) { + File next = getNumberedFileName(i+1); + next.delete(); + fi.renameTo(next); + } + } } - public String getUrlName() { - return "closures"; + /** + * Deletes all the log files, including rotated files. + */ + public void deleteAll() { + for (int i=0; i<=size; i++) { + getNumberedFileName(i).delete(); + } } } diff --git a/core/src/main/java/hudson/util/io/TarArchiver.java b/core/src/main/java/hudson/util/io/TarArchiver.java index 7e7a3dd4f0ec1a14981f98fc64a2cfdfbb40a87d..013027a1880405d1ba38f417543db9cbe597077e 100644 --- a/core/src/main/java/hudson/util/io/TarArchiver.java +++ b/core/src/main/java/hudson/util/io/TarArchiver.java @@ -25,20 +25,20 @@ package hudson.util.io; import hudson.Functions; -import hudson.org.apache.tools.tar.TarOutputStream; import hudson.os.PosixException; import hudson.util.FileVisitor; import hudson.util.IOUtils; -import org.apache.tools.tar.TarEntry; -import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; -import java.lang.reflect.Field; -import static org.apache.tools.tar.TarConstants.LF_SYMLINK; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; +import org.apache.commons.compress.archivers.tar.TarConstants; +import org.apache.commons.compress.utils.BoundedInputStream; + /** * {@link FileVisitor} that creates a tar archive. @@ -47,24 +47,17 @@ import static org.apache.tools.tar.TarConstants.LF_SYMLINK; */ final class TarArchiver extends Archiver { private final byte[] buf = new byte[8192]; - private final TarOutputStream tar; + private final TarArchiveOutputStream tar; TarArchiver(OutputStream out) { - tar = new TarOutputStream(new BufferedOutputStream(out) { - // TarOutputStream uses TarBuffer internally, - // which flushes the stream for each block. this creates unnecessary - // data stream fragmentation, and flush request to a remote, which slows things down. - @Override - public void flush() throws IOException { - // so don't do anything in flush - } - }); - tar.setLongFileMode(TarOutputStream.LONGFILE_GNU); + tar = new TarArchiveOutputStream(out); + tar.setBigNumberMode(TarArchiveOutputStream.BIGNUMBER_STAR); + tar.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU); } @Override public void visitSymlink(File link, String target, String relativePath) throws IOException { - TarEntry e = new TarEntry(relativePath, LF_SYMLINK); + TarArchiveEntry e = new TarArchiveEntry(relativePath, TarConstants.LF_SYMLINK); try { int mode = IOUtils.mode(link); if (mode != -1) { @@ -73,16 +66,11 @@ final class TarArchiver extends Archiver { } catch (PosixException x) { // ignore } + + e.setLinkName(target); - try { - StringBuffer linkName = (StringBuffer) LINKNAME_FIELD.get(e); - linkName.setLength(0); - linkName.append(target); - } catch (IllegalAccessException x) { - throw new IOException("Failed to set linkName", x); - } - - tar.putNextEntry(e); + tar.putArchiveEntry(e); + tar.closeArchiveEntry(); entriesWritten++; } @@ -97,45 +85,39 @@ final class TarArchiver extends Archiver { if(file.isDirectory()) relativePath+='/'; - TarEntry te = new TarEntry(relativePath); + TarArchiveEntry te = new TarArchiveEntry(relativePath); int mode = IOUtils.mode(file); if (mode!=-1) te.setMode(mode); te.setModTime(file.lastModified()); - if(!file.isDirectory()) - te.setSize(file.length()); - - tar.putNextEntry(te); + long size = 0; if (!file.isDirectory()) { - FileInputStream in = new FileInputStream(file); - try { - int len; - while((len=in.read(buf))>=0) - tar.write(buf,0,len); - } finally { - in.close(); + size = file.length(); + te.setSize(size); + } + tar.putArchiveEntry(te); + try { + if (!file.isDirectory()) { + // ensure we don't write more bytes than the declared when we created the entry + + try (FileInputStream fin = new FileInputStream(file); + BoundedInputStream in = new BoundedInputStream(fin, size)) { + int len; + while ((len = in.read(buf)) >= 0) { + tar.write(buf, 0, len); + } + } catch (IOException e) {// log the exception in any case + IOException ioE = new IOException("Error writing to tar file from: " + file, e); + throw ioE; + } } + } finally { // always close the entry + tar.closeArchiveEntry(); } - - tar.closeEntry(); entriesWritten++; } public void close() throws IOException { tar.close(); } - - private static final Field LINKNAME_FIELD = getTarEntryLinkNameField(); - - private static Field getTarEntryLinkNameField() { - try { - Field f = TarEntry.class.getDeclaredField("linkName"); - f.setAccessible(true); - return f; - } catch (SecurityException e) { - throw new AssertionError(e); - } catch (NoSuchFieldException e) { - throw new AssertionError(e); - } - } } diff --git a/core/src/main/java/hudson/util/jna/DotNet.java b/core/src/main/java/hudson/util/jna/DotNet.java index 4011767b1941026670e09fd0b5ea5861c804559f..4d820149ca0afb78100f23e5fed90166d1017dab 100644 --- a/core/src/main/java/hudson/util/jna/DotNet.java +++ b/core/src/main/java/hudson/util/jna/DotNet.java @@ -46,7 +46,7 @@ public class DotNet { try { // see http://support.microsoft.com/?scid=kb;en-us;315291 for the basic algorithm // observation in my registry shows that the actual key name can be things like "v2.0 SP1" - // or "v2.0.50727", so the regexp is written to accomodate this. + // or "v2.0.50727", so the regexp is written to accommodate this. RegistryKey key = RegistryKey.LOCAL_MACHINE.openReadonly("SOFTWARE\\Microsoft\\.NETFramework"); try { for( String keyName : key.getSubKeys() ) { diff --git a/core/src/main/java/hudson/util/jna/GNUCLibrary.java b/core/src/main/java/hudson/util/jna/GNUCLibrary.java index 28cdfabb5f6544c49dbe0dbf4d1223ad61581aeb..6cfa2a4b83f57fa60c00404599e9e4140a550cd6 100644 --- a/core/src/main/java/hudson/util/jna/GNUCLibrary.java +++ b/core/src/main/java/hudson/util/jna/GNUCLibrary.java @@ -29,8 +29,8 @@ import com.sun.jna.Pointer; import com.sun.jna.Native; import com.sun.jna.Memory; import com.sun.jna.NativeLong; +import com.sun.jna.LastErrorException; import com.sun.jna.ptr.IntByReference; -import hudson.os.PosixAPI; import jnr.posix.POSIX; import org.jvnet.libpam.impl.CLibrary.passwd; @@ -75,8 +75,10 @@ public interface GNUCLibrary extends Library { int chown(String fileName, int uid, int gid); int chmod(String fileName, int i); + int open(String pathname, int flags) throws LastErrorException; int dup(int old); int dup2(int old, int _new); + long pread(int fd, Memory buffer, NativeLong size, NativeLong offset) throws LastErrorException; int close(int fd); // see http://www.gnu.org/s/libc/manual/html_node/Renaming-Files.html diff --git a/core/src/main/java/hudson/util/jna/InitializationErrorInvocationHandler.java b/core/src/main/java/hudson/util/jna/InitializationErrorInvocationHandler.java index 5e6ad17a7f05080e52c70c877f0776f1af046ab8..c23343c15ccd6286132c90d70d639a18deabd5b0 100644 --- a/core/src/main/java/hudson/util/jna/InitializationErrorInvocationHandler.java +++ b/core/src/main/java/hudson/util/jna/InitializationErrorInvocationHandler.java @@ -12,7 +12,6 @@ import java.lang.reflect.Proxy; * * @author Kohsuke Kawaguchi * @since 1.487 - * @see Related bug report against JDK */ public class InitializationErrorInvocationHandler implements InvocationHandler { private final Throwable cause; diff --git a/core/src/main/java/hudson/util/spring/BeanBuilder.java b/core/src/main/java/hudson/util/spring/BeanBuilder.java index e1d1cba514ba6b29446ab3274cc1292113662045..38482703fdc96b717673bfb59cf25b897e11e5ad 100644 --- a/core/src/main/java/hudson/util/spring/BeanBuilder.java +++ b/core/src/main/java/hudson/util/spring/BeanBuilder.java @@ -39,6 +39,7 @@ import org.springframework.web.context.WebApplicationContext; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -132,7 +133,7 @@ public class BeanBuilder extends GroovyObjectSupport { cc.setScriptBaseClass(ClosureScript.class.getName()); GroovyShell shell = new GroovyShell(classLoader,binding,cc); - ClosureScript s = (ClosureScript)shell.parse(script); + ClosureScript s = (ClosureScript)shell.parse(new InputStreamReader(script)); s.setDelegate(this); s.run(); } @@ -336,7 +337,7 @@ public class BeanBuilder extends GroovyObjectSupport { GroovyShell shell = classLoader != null ? new GroovyShell(classLoader,b) : new GroovyShell(b); for (Resource resource : resources) { - shell.evaluate(resource.getInputStream()); + shell.evaluate(new InputStreamReader(resource.getInputStream())); } } diff --git a/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java b/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java index 18fd97ec98ada93a66984ac3ed62b68eceac8ed6..3734c472454fa4e4c8fab16d57104c02914c7196 100644 --- a/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java +++ b/core/src/main/java/hudson/util/xstream/ImmutableListConverter.java @@ -39,6 +39,8 @@ import hudson.util.RobustReflectionConverter; import java.util.ArrayList; import java.util.List; +import jenkins.util.xstream.CriticalXStreamException; + /** * {@link ImmutableList} should convert like a list, instead of via serialization. * @@ -76,6 +78,8 @@ public class ImmutableListConverter extends CollectionConverter { try { Object item = readItem(reader, context, items); items.add(item); + } catch (CriticalXStreamException e) { + throw e; } catch (XStreamException e) { RobustReflectionConverter.addErrorInContext(context, e); } catch (LinkageError e) { diff --git a/core/src/main/java/hudson/views/BuildButtonColumn.java b/core/src/main/java/hudson/views/BuildButtonColumn.java index 83f314597994a184cbf8104f63f07c4168922d1a..3f7cbbc7d3f93f70ca83d125233fe5aa095a4e34 100644 --- a/core/src/main/java/hudson/views/BuildButtonColumn.java +++ b/core/src/main/java/hudson/views/BuildButtonColumn.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; public class BuildButtonColumn extends ListViewColumn { @@ -31,7 +32,7 @@ public class BuildButtonColumn extends ListViewColumn { public BuildButtonColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ACTIONS_START-1) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ACTIONS_START-1) @Symbol("buildButton") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java b/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java index 3edc40f2c154d6d6c39ef9fbcb5a02993a164709..9ebc1e63599cfc4177efac47476fc78827f71d14 100644 --- a/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java +++ b/core/src/main/java/hudson/views/DefaultMyViewsTabBar.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -38,7 +39,7 @@ public class DefaultMyViewsTabBar extends MyViewsTabBar { public DefaultMyViewsTabBar() { } - @Extension + @Extension @Symbol("standard") public static class DescriptorImpl extends MyViewsTabBarDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/DefaultViewsTabBar.java b/core/src/main/java/hudson/views/DefaultViewsTabBar.java index 169874864a853ad6ccdef9518d390f37cddda67c..e9e9f56dbe1148c82d0218294ae291b1bbbd54dc 100644 --- a/core/src/main/java/hudson/views/DefaultViewsTabBar.java +++ b/core/src/main/java/hudson/views/DefaultViewsTabBar.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -38,7 +39,7 @@ public class DefaultViewsTabBar extends ViewsTabBar { public DefaultViewsTabBar() { } - @Extension + @Extension @Symbol("standard") public static class DescriptorImpl extends ViewsTabBarDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java b/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java index 65e020a06c8d69e79aaee674b3c143e17daf51c3..40a045a0844ca6d4c27213fac6d5d6474299618a 100644 --- a/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java +++ b/core/src/main/java/hudson/views/GlobalDefaultViewConfiguration.java @@ -24,12 +24,10 @@ package hudson.views; import hudson.Extension; -import hudson.markup.MarkupFormatter; -import hudson.security.AuthorizationStrategy; -import hudson.security.SecurityRealm; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; /** @@ -37,7 +35,7 @@ import org.kohsuke.stapler.StaplerRequest; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=300) +@Extension(ordinal=300) @Symbol("defaultView") public class GlobalDefaultViewConfiguration extends GlobalConfiguration { @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { diff --git a/core/src/main/java/hudson/views/JobColumn.java b/core/src/main/java/hudson/views/JobColumn.java index d34b49415ad3d65a127c7ce3a7e57b476ad68f7d..b6f581c154c2342d7214e43a674280a2cc512ce8 100644 --- a/core/src/main/java/hudson/views/JobColumn.java +++ b/core/src/main/java/hudson/views/JobColumn.java @@ -25,6 +25,7 @@ package hudson.views; import hudson.Extension; import hudson.model.Item; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -36,7 +37,7 @@ public class JobColumn extends ListViewColumn { } // put this in the middle of icons and properties - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_END+1) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_END+1) @Symbol("jobName") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastDurationColumn.java b/core/src/main/java/hudson/views/LastDurationColumn.java index 7379d7b6a321251ab6e4164531cf06d7af3f913c..04696704a65ddde11fcc2ada920e8a15b3a15c52 100644 --- a/core/src/main/java/hudson/views/LastDurationColumn.java +++ b/core/src/main/java/hudson/views/LastDurationColumn.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; public class LastDurationColumn extends ListViewColumn { @@ -31,7 +32,7 @@ public class LastDurationColumn extends ListViewColumn { public LastDurationColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-4) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-4) @Symbol("lastDuration") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastFailureColumn.java b/core/src/main/java/hudson/views/LastFailureColumn.java index 28276df9e130e167e8c663242c1695f493488848..1c272b855f8bb68dde9ba6d2879f0a8cfde9983c 100644 --- a/core/src/main/java/hudson/views/LastFailureColumn.java +++ b/core/src/main/java/hudson/views/LastFailureColumn.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; public class LastFailureColumn extends ListViewColumn { @@ -31,7 +32,7 @@ public class LastFailureColumn extends ListViewColumn { public LastFailureColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-2) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-2) @Symbol("lastFailure") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastStableColumn.java b/core/src/main/java/hudson/views/LastStableColumn.java index 408c70b726a5d3acb544c81bf0657647a8042d8e..0844121e5dcb4ea79d5d37555f5583d58f0d1cbc 100644 --- a/core/src/main/java/hudson/views/LastStableColumn.java +++ b/core/src/main/java/hudson/views/LastStableColumn.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; public class LastStableColumn extends ListViewColumn { @@ -31,7 +32,7 @@ public class LastStableColumn extends ListViewColumn { public LastStableColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-3) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-3) @Symbol("lastStable") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/LastSuccessColumn.java b/core/src/main/java/hudson/views/LastSuccessColumn.java index c0232075e564c2c8241250bdb1cbb2af9d87a630..ebb5bc1bc94462c8a03ab2682bc35473c4769b91 100644 --- a/core/src/main/java/hudson/views/LastSuccessColumn.java +++ b/core/src/main/java/hudson/views/LastSuccessColumn.java @@ -24,6 +24,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; public class LastSuccessColumn extends ListViewColumn { @@ -31,7 +32,7 @@ public class LastSuccessColumn extends ListViewColumn { public LastSuccessColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-1) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_PROPERTIES_START-1) @Symbol("lastSuccess") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/ListViewColumn.java b/core/src/main/java/hudson/views/ListViewColumn.java index 4fd010d8616e03f53d064c9f5da2ae5a5ebee258..06d8ba2f14d17007f5734d944bb51f1afb85f1eb 100644 --- a/core/src/main/java/hudson/views/ListViewColumn.java +++ b/core/src/main/java/hudson/views/ListViewColumn.java @@ -29,6 +29,7 @@ import hudson.ExtensionPoint; import hudson.model.Describable; import hudson.model.Descriptor; import hudson.model.Descriptor.FormException; +import hudson.model.DescriptorVisibilityFilter; import jenkins.model.Jenkins; import hudson.model.Item; import hudson.model.ItemGroup; @@ -41,6 +42,7 @@ import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import net.sf.json.JSONObject; /** * Extension point for adding a column to a table rendering of {@link Item}s, such as {@link ListView}. @@ -120,20 +122,50 @@ public abstract class ListViewColumn implements ExtensionPoint, Describable createDefaultInitialColumnList() { + return createDefaultInitialColumnList(ListViewColumn.all()); + } + + /** + * Creates the list of {@link ListViewColumn}s to be used for newly created {@link ListView}s and their likes. + * + * @see ListView#initColumns() + * @since 2.37 + */ + public static List createDefaultInitialColumnList(Class context) { + return createDefaultInitialColumnList(DescriptorVisibilityFilter.applyType(context, ListViewColumn.all())); + } + + /** + * Creates the list of {@link ListViewColumn}s to be used for a {@link ListView}s and their likes. + * + * @see View#getColumns() + * @since 2.37 + */ + public static List createDefaultInitialColumnList(View view) { + return createDefaultInitialColumnList(DescriptorVisibilityFilter.apply(view, ListViewColumn.all())); + } + + private static List createDefaultInitialColumnList(List> descriptors) { // OK, set up default list of columns: // create all instances ArrayList r = new ArrayList(); - - for (Descriptor d : ListViewColumn.all()) + final JSONObject emptyJSON = new JSONObject(); + for (Descriptor d : descriptors) try { if (d instanceof ListViewColumnDescriptor) { ListViewColumnDescriptor ld = (ListViewColumnDescriptor) d; - if (!ld.shownByDefault()) continue; // skip this + if (!ld.shownByDefault()) { + continue; // skip this + } + } + ListViewColumn lvc = d.newInstance(null, emptyJSON); + if (!lvc.shownByDefault()) { + continue; // skip this } - ListViewColumn lvc = d.newInstance(null, null); - if (!lvc.shownByDefault()) continue; // skip this r.add(lvc); } catch (FormException e) { diff --git a/core/src/main/java/hudson/views/MyViewsTabBar.java b/core/src/main/java/hudson/views/MyViewsTabBar.java index d06ad0b7ebdaddfc476fce7bfded62c16163c2af..1d2fe44db1fc2e0b080759dabba478d4b88220d6 100644 --- a/core/src/main/java/hudson/views/MyViewsTabBar.java +++ b/core/src/main/java/hudson/views/MyViewsTabBar.java @@ -28,10 +28,19 @@ import hudson.Extension; import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; +import hudson.model.View; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import javax.annotation.Nonnull; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; import hudson.model.MyViewsProperty; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; /** @@ -62,12 +71,33 @@ public abstract class MyViewsTabBar extends AbstractDescribableImpl sort(@Nonnull List views) { + List result = new ArrayList<>(views); + Collections.sort(result, new Comparator() { + @Override + public int compare(View o1, View o2) { + return o1.getDisplayName().compareTo(o2.getDisplayName()); + } + }); + return result; + } + /** * Configures {@link ViewsTabBar} in the system configuration. * * @author Kohsuke Kawaguchi */ - @Extension(ordinal=305) + @Extension(ordinal=305) @Symbol("myView") public static class GlobalConfigurationImpl extends GlobalConfiguration { public MyViewsTabBar getMyViewsTabBar() { return Jenkins.getInstance().getMyViewsTabBar(); diff --git a/core/src/main/java/hudson/views/StatusColumn.java b/core/src/main/java/hudson/views/StatusColumn.java index 47f82643d2c87e6767494a20b548b2b6e54ce164..80813e00ea20664b51164a25b95f9639d9d82e86 100644 --- a/core/src/main/java/hudson/views/StatusColumn.java +++ b/core/src/main/java/hudson/views/StatusColumn.java @@ -25,6 +25,7 @@ package hudson.views; import hudson.Extension; import hudson.model.StatusIcon; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -37,7 +38,7 @@ public class StatusColumn extends ListViewColumn { public StatusColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_START-1) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_START-1) @Symbol("status") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/views/ViewsTabBar.java b/core/src/main/java/hudson/views/ViewsTabBar.java index 4304290b48e6c823275905c445623407946f4a3b..3556254c5ac5b6618ba55889829031d7aee2ecdd 100644 --- a/core/src/main/java/hudson/views/ViewsTabBar.java +++ b/core/src/main/java/hudson/views/ViewsTabBar.java @@ -29,10 +29,19 @@ import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; import hudson.model.Descriptor; import hudson.model.Descriptor.FormException; +import hudson.model.View; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import javax.annotation.Nonnull; import jenkins.model.GlobalConfiguration; import jenkins.model.Jenkins; import hudson.model.ListView; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; /** @@ -64,12 +73,33 @@ public abstract class ViewsTabBar extends AbstractDescribableImpl i return (ViewsTabBarDescriptor)super.getDescriptor(); } + /** + * Sorts the views by {@link View#getDisplayName()}. + * + * @param views the views. + * @return the sorted views + * @since 2.37 + */ + @Nonnull + @Restricted(NoExternalUse.class) + @SuppressWarnings("unused") // invoked from stapler view + public List sort(@Nonnull List views) { + List result = new ArrayList<>(views); + Collections.sort(result, new Comparator() { + @Override + public int compare(View o1, View o2) { + return o1.getDisplayName().compareTo(o2.getDisplayName()); + } + }); + return result; + } + /** * Configures {@link ViewsTabBar} in the system configuration. * * @author Kohsuke Kawaguchi */ - @Extension(ordinal=310) + @Extension(ordinal=310) @Symbol("viewsTabBar") public static class GlobalConfigurationImpl extends GlobalConfiguration { public ViewsTabBar getViewsTabBar() { return Jenkins.getInstance().getViewsTabBar(); diff --git a/core/src/main/java/hudson/views/WeatherColumn.java b/core/src/main/java/hudson/views/WeatherColumn.java index 1e8436a08af391300457616d2397521674d4dc0c..d14e9ca5582bf678951f3966d13bd81a80fb3534 100644 --- a/core/src/main/java/hudson/views/WeatherColumn.java +++ b/core/src/main/java/hudson/views/WeatherColumn.java @@ -25,6 +25,7 @@ package hudson.views; import hudson.Extension; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; public class WeatherColumn extends ListViewColumn { @@ -32,7 +33,7 @@ public class WeatherColumn extends ListViewColumn { public WeatherColumn() { } - @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_START-2) + @Extension(ordinal=DEFAULT_COLUMNS_ORDINAL_ICON_START-2) @Symbol("weather") public static class DescriptorImpl extends ListViewColumnDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/hudson/widgets/BuildHistoryWidget.java b/core/src/main/java/hudson/widgets/BuildHistoryWidget.java index ec80e138a828514b26faf083d32148e7b4611a38..efd81da9d1fc6a5afdc52287de472130517ef2c1 100644 --- a/core/src/main/java/hudson/widgets/BuildHistoryWidget.java +++ b/core/src/main/java/hudson/widgets/BuildHistoryWidget.java @@ -26,7 +26,9 @@ package hudson.widgets; import jenkins.model.Jenkins; import hudson.model.Queue.Item; import hudson.model.Queue.Task; +import jenkins.widgets.HistoryPageFilter; +import java.util.Collection; import java.util.LinkedList; import java.util.List; @@ -60,11 +62,21 @@ public class BuildHistoryWidget extends HistoryWidget { */ public List getQueuedItems() { LinkedList list = new LinkedList(); - for (Item item : Jenkins.getInstance().getQueue().getApproximateItemsQuickly()) { + for (Item item : Jenkins.getInstance().getQueue().getItems()) { if (item.task == owner) { list.addFirst(item); } } return list; } + + @Override + public HistoryPageFilter getHistoryPageFilter() { + final HistoryPageFilter historyPageFilter = newPageFilter(); + + historyPageFilter.add(baseList, getQueuedItems()); + historyPageFilter.widget = this; + + return updateFirstTransientBuildKey(historyPageFilter); + } } diff --git a/core/src/main/java/hudson/widgets/HistoryWidget.java b/core/src/main/java/hudson/widgets/HistoryWidget.java index a2ec051839581c236dd5a277984713ae21f5a8c2..e82e78ad75b25b31bcca01ad1e6259ed2dab0db0 100644 --- a/core/src/main/java/hudson/widgets/HistoryWidget.java +++ b/core/src/main/java/hudson/widgets/HistoryWidget.java @@ -24,24 +24,25 @@ package hudson.widgets; import hudson.Functions; +import jenkins.util.SystemProperties; import hudson.model.ModelObject; import hudson.model.Run; -import hudson.util.Iterators; +import jenkins.widgets.HistoryPageEntry; +import jenkins.widgets.HistoryPageFilter; import org.kohsuke.stapler.Header; -import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.Stapler; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; +import javax.annotation.CheckForNull; import javax.servlet.ServletException; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; - /** * Displays the history of records (normally {@link Run}s) on the side panel. * @@ -73,6 +74,10 @@ public class HistoryWidget extends Widget { public final Adapter adapter; + final Long newerThan; + final Long olderThan; + final String searchString; + /** * First transient build record. Everything >= this will be discarded when AJAX call is made. */ @@ -83,10 +88,14 @@ public class HistoryWidget extends Widget { * The parent model object that owns this widget. */ public HistoryWidget(O owner, Iterable baseList, Adapter adapter) { + StaplerRequest currentRequest = Stapler.getCurrentRequest(); this.adapter = adapter; this.baseList = baseList; - this.baseUrl = Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(),owner); + this.baseUrl = Functions.getNearestAncestorUrl(currentRequest,owner); this.owner = owner; + this.newerThan = getPagingParam(currentRequest, "newer-than"); + this.olderThan = getPagingParam(currentRequest, "older-than"); + this.searchString = currentRequest.getParameter("search");; } /** @@ -105,11 +114,27 @@ public class HistoryWidget extends Widget { return firstTransientBuildKey; } - private Iterable updateFirstTransientBuildKey(Iterable source) { + /** + * Calculates the first transient build record. Everything >= this will be discarded when AJAX call is made. + * + * @param historyPageFilter + * The history page filter containing the list of builds. + * @return + * The history page filter that was passed in. + */ + @SuppressWarnings("unchecked") + protected HistoryPageFilter updateFirstTransientBuildKey(HistoryPageFilter historyPageFilter) { + updateFirstTransientBuildKey(historyPageFilter.runs); + return historyPageFilter; + } + + private Iterable> updateFirstTransientBuildKey(Iterable> source) { String key=null; - for (T t : source) - if(adapter.isBuilding(t)) - key = adapter.getKey(t); + for (HistoryPageEntry t : source) { + if(adapter.isBuilding(t.getEntry())) { + key = adapter.getKey(t.getEntry()); + } + } firstTransientBuildKey = key; return source; } @@ -117,27 +142,61 @@ public class HistoryWidget extends Widget { /** * The records to be rendered this time. */ - public Iterable getRenderList() { + public Iterable> getRenderList() { if(trimmed) { - List lst; - if (baseList instanceof List) { - lst = (List) baseList; - if(lst.size()>THRESHOLD) - return updateFirstTransientBuildKey(lst.subList(0,THRESHOLD)); - trimmed=false; - return updateFirstTransientBuildKey(lst); + List> pageEntries = toPageEntries(baseList); + if(pageEntries.size() > THRESHOLD) { + return updateFirstTransientBuildKey(pageEntries.subList(0,THRESHOLD)); } else { - lst = new ArrayList(THRESHOLD); - Iterator itr = baseList.iterator(); - while(lst.size()<=THRESHOLD && itr.hasNext()) - lst.add(itr.next()); - trimmed = itr.hasNext(); // if we don't have enough items in the base list, setting this to false will optimize the next getRenderList() invocation. - return updateFirstTransientBuildKey(lst); + trimmed=false; + return updateFirstTransientBuildKey(pageEntries); } } else { - // to prevent baseList's concrete type from getting picked up by in view - return updateFirstTransientBuildKey(Iterators.wrap(baseList)); + // to prevent baseList's concrete type from getting picked up by in view + return updateFirstTransientBuildKey(toPageEntries(baseList)); + } + } + + private List> toPageEntries(Iterable historyItemList) { + Iterator iterator = historyItemList.iterator(); + + if (!iterator.hasNext()) { + return Collections.emptyList(); + } + + List> pageEntries = new ArrayList>(); + while (iterator.hasNext()) { + pageEntries.add(new HistoryPageEntry(iterator.next())); + } + + return pageEntries; + } + + /** + * Get a {@link jenkins.widgets.HistoryPageFilter} for rendering a page of queue items. + */ + public HistoryPageFilter getHistoryPageFilter() { + HistoryPageFilter historyPageFilter = newPageFilter(); + + historyPageFilter.add(baseList); + historyPageFilter.widget = this; + return updateFirstTransientBuildKey(historyPageFilter); + } + + protected HistoryPageFilter newPageFilter() { + HistoryPageFilter historyPageFilter = new HistoryPageFilter(THRESHOLD); + + if (newerThan != null) { + historyPageFilter.setNewerThan(newerThan); + } else if (olderThan != null) { + historyPageFilter.setOlderThan(olderThan); } + + if (searchString != null) { + historyPageFilter.setSearchString(searchString); + } + + return historyPageFilter; } public boolean isTrimmed() { @@ -156,46 +215,47 @@ public class HistoryWidget extends Widget { * uses non-numbers as the build key. */ public void doAjax( StaplerRequest req, StaplerResponse rsp, - @Header("n") String n ) throws IOException, ServletException { - - if (n==null) throw HttpResponses.error(SC_BAD_REQUEST,new Exception("Missing the 'n' HTTP header")); + @Header("n") String n ) throws IOException, ServletException { rsp.setContentType("text/html;charset=UTF-8"); // pick up builds to send back List items = new ArrayList(); - String nn=null; // we'll compute next n here + if (n != null) { + String nn=null; // we'll compute next n here - // list up all builds >=n. - for (T t : baseList) { - if(adapter.compare(t,n)>=0) { - items.add(t); - if(adapter.isBuilding(t)) + // list up all builds >=n. + for (T t : baseList) { + if(adapter.compare(t,n)>=0) { + items.add(t); + if(adapter.isBuilding(t)) nn = adapter.getKey(t); // the next fetch should start from youngest build in progress - } else - break; - } + } else + break; + } - if (nn==null) { - if (items.isEmpty()) { - // nothing to report back. next fetch should retry the same 'n' - nn=n; - } else { - // every record fetched this time is frozen. next fetch should start from the next build - nn=adapter.getNextKey(adapter.getKey(items.get(0))); + if (nn==null) { + if (items.isEmpty()) { + // nothing to report back. next fetch should retry the same 'n' + nn=n; + } else { + // every record fetched this time is frozen. next fetch should start from the next build + nn=adapter.getNextKey(adapter.getKey(items.get(0))); + } } - } - baseList = items; + baseList = items; - rsp.setHeader("n",nn); - firstTransientBuildKey = nn; // all builds >= nn should be marked transient + rsp.setHeader("n",nn); + firstTransientBuildKey = nn; // all builds >= nn should be marked transient + } - req.getView(this,"ajaxBuildHistory.jelly").forward(req,rsp); + HistoryPageFilter page = getHistoryPageFilter(); + req.getView(page,"ajaxBuildHistory.jelly").forward(req,rsp); } - private static final int THRESHOLD = Integer.getInteger(HistoryWidget.class.getName()+".threshold",30); + static final int THRESHOLD = SystemProperties.getInteger(HistoryWidget.class.getName()+".threshold",30); public String getNextBuildNumberToFetch() { return nextBuildNumberToFetch; @@ -214,4 +274,20 @@ public class HistoryWidget extends Widget { boolean isBuilding(T record); String getNextKey(String key); } + + private Long getPagingParam(@CheckForNull StaplerRequest currentRequest, @CheckForNull String name) { + if (currentRequest == null || name == null) { + return null; + } + + String paramVal = currentRequest.getParameter(name); + if (paramVal == null) { + return null; + } + try { + return new Long(paramVal); + } catch (NumberFormatException nfe) { + return null; + } + } } diff --git a/core/src/main/java/jenkins/AgentProtocol.java b/core/src/main/java/jenkins/AgentProtocol.java index 68ad9ace8a8a39e1789756d2135030849c5c03f4..93140b71c15299190c6e16400bb8bb016dd3ab4d 100644 --- a/core/src/main/java/jenkins/AgentProtocol.java +++ b/core/src/main/java/jenkins/AgentProtocol.java @@ -4,10 +4,11 @@ import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.TcpSlaveAgentListener; -import jenkins.model.Jenkins; import java.io.IOException; import java.net.Socket; +import java.util.Set; +import jenkins.model.Jenkins; /** * Pluggable Jenkins TCP agent protocol handler called from {@link TcpSlaveAgentListener}. @@ -22,6 +23,36 @@ import java.net.Socket; * @see TcpSlaveAgentListener */ public abstract class AgentProtocol implements ExtensionPoint { + /** + * Allow experimental {@link AgentProtocol} implementations to declare being opt-in. + * Note that {@link Jenkins#setAgentProtocols(Set)} only records the protocols where the admin has made a + * conscious decision thus: + *

      + *
    • if a protocol is opt-in, it records the admin enabling it
    • + *
    • if a protocol is opt-out, it records the admin disabling it
    • + *
    + * Implementations should not transition rapidly from {@code opt-in -> opt-out -> opt-in}. + * Implementations should never flip-flop: {@code opt-in -> opt-out -> opt-in -> opt-out} as that will basically + * clear any preference that an admin has set. This latter restriction should be ok as we only ever will be + * adding new protocols and retiring old ones. + * + * @return {@code true} if the protocol requires explicit opt-in. + * @since 2.16 + * @see Jenkins#setAgentProtocols(Set) + */ + public boolean isOptIn() { + return false; + } + /** + * Allow essential {@link AgentProtocol} implementations (basically {@link TcpSlaveAgentListener.PingAgentProtocol}) + * to be always enabled. + * + * @return {@code true} if the protocol can never be disabled. + * @since 2.16 + */ + public boolean isRequired() { + return false; + } /** * Protocol name. * @@ -33,6 +64,16 @@ public abstract class AgentProtocol implements ExtensionPoint { */ public abstract String getName(); + /** + * Returns the human readable protocol display name. + * + * @return the human readable protocol display name. + * @since 2.16 + */ + public String getDisplayName() { + return getName(); + } + /** * Called by the connection handling thread to execute the protocol. */ diff --git a/core/src/main/java/jenkins/CLI.java b/core/src/main/java/jenkins/CLI.java new file mode 100644 index 0000000000000000000000000000000000000000..970e59dc62db197646b2080c8aa91d0531ccd2af --- /dev/null +++ b/core/src/main/java/jenkins/CLI.java @@ -0,0 +1,17 @@ +package jenkins; + +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Kill switch to disable the entire Jenkins CLI system. + * + * Marked as no external use because the CLI subsystem is nearing EOL. + * + * @author Kohsuke Kawaguchi + */ +@Restricted(NoExternalUse.class) +public class CLI { + // non-final to allow setting from $JENKINS_HOME/init.groovy.d + public static boolean DISABLED = Boolean.getBoolean(CLI.class.getName()+".disabled"); +} diff --git a/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java b/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java index 49b2b76908eac010467d0be4df53289cb6a42f70..cfa342e5134ad11c81ef769880f0c93ac26248cf 100644 --- a/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java +++ b/core/src/main/java/jenkins/ClassLoaderReflectionToolkit.java @@ -34,7 +34,7 @@ public class ClassLoaderReflectionToolkit { gCLL = ClassLoader.class.getDeclaredMethod("getClassLoadingLock", String.class); gCLL.setAccessible(true); } catch (NoSuchMethodException x) { - // OK, Java 6 + throw new AssertionError(x); } GET_CLASS_LOADING_LOCK = gCLL; } @@ -59,12 +59,7 @@ public class ClassLoaderReflectionToolkit { } private static Object getClassLoadingLock(ClassLoader cl, String name) { - if (GET_CLASS_LOADING_LOCK != null) { - return invoke(GET_CLASS_LOADING_LOCK, RuntimeException.class, cl, name); - } else { - // Java 6 expects you to always synchronize on this. - return cl; - } + return invoke(GET_CLASS_LOADING_LOCK, RuntimeException.class, cl, name); } /** diff --git a/core/src/main/java/jenkins/ExtensionFilter.java b/core/src/main/java/jenkins/ExtensionFilter.java index 6b20d805e25f87b62a4901f3b34ccb9b292c4561..1f3ec5c8865f0bc0873f8c50f8315950f4a813e1 100644 --- a/core/src/main/java/jenkins/ExtensionFilter.java +++ b/core/src/main/java/jenkins/ExtensionFilter.java @@ -31,7 +31,6 @@ import hudson.model.AdministrativeMonitor; import hudson.model.Describable; import hudson.model.Descriptor; import hudson.model.DescriptorVisibilityFilter; -import jenkins.model.Jenkins; /** * Filters out {@link ExtensionComponent}s discovered by {@link ExtensionFinder}s, diff --git a/core/src/main/java/jenkins/I18n.java b/core/src/main/java/jenkins/I18n.java new file mode 100644 index 0000000000000000000000000000000000000000..35722c4941faacd72268d62a289d91dac0d75ef0 --- /dev/null +++ b/core/src/main/java/jenkins/I18n.java @@ -0,0 +1,124 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins; + +import hudson.Extension; +import hudson.model.RootAction; +import hudson.util.HttpResponses; +import jenkins.util.ResourceBundleUtil; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest; + +import java.util.Locale; + +/** + * Internationalization REST (ish) API. + * @author tom.fennelly@gmail.com + * @since 2.0 + */ +@Extension +@Restricted(NoExternalUse.class) +public class I18n implements RootAction { + + /** + * {@inheritDoc} + */ + @Override + public String getIconFileName() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getUrlName() { + return "i18n"; + } + + /** + * Get a localised resource bundle. + *

    + * URL: {@code i18n/resourceBundle}. + *

    + * Parameters: + *

      + *
    • {@code baseName}: The resource bundle base name.
    • + *
    • {@code language}: {@link Locale} Language. (optional)
    • + *
    • {@code country}: {@link Locale} Country. (optional)
    • + *
    • {@code variant}: {@link Locale} Language variant. (optional)
    • + *
    + * + * @param request The request. + * @return The JSON response. + */ + public HttpResponse doResourceBundle(StaplerRequest request) { + String baseName = request.getParameter("baseName"); + + if (baseName == null) { + return HttpResponses.errorJSON("Mandatory parameter 'baseName' not specified."); + } + + String language = request.getParameter("language"); + String country = request.getParameter("country"); + String variant = request.getParameter("variant"); + // https://www.w3.org/International/questions/qa-lang-priorities + // in case we have regions/countries in the language query parameter + if (language != null) { + String[] languageTokens = language.split("-|_"); + language = languageTokens[0]; + if (country == null && languageTokens.length > 1) { + country = languageTokens[1]; + if (variant == null && languageTokens.length > 2) { + variant = languageTokens[2]; + } + } + } + try { + Locale locale = request.getLocale(); + + if (language != null && country != null && variant != null) { + locale = new Locale(language, country, variant); + } else if (language != null && country != null) { + locale = new Locale(language, country); + } else if (language != null) { + locale = new Locale(language); + } + + return HttpResponses.okJSON(ResourceBundleUtil.getBundle(baseName, locale)); + } catch (Exception e) { + return HttpResponses.errorJSON(e.getMessage()); + } + } +} diff --git a/core/src/main/java/jenkins/InitReactorRunner.java b/core/src/main/java/jenkins/InitReactorRunner.java index f3b8711e32a31e319abbc587a40e69a6d7650f58..c5c2bfb844484ba8bff5b6c0f76c082581fbda45 100644 --- a/core/src/main/java/jenkins/InitReactorRunner.java +++ b/core/src/main/java/jenkins/InitReactorRunner.java @@ -1,5 +1,6 @@ package jenkins; +import jenkins.util.SystemProperties; import hudson.init.InitMilestone; import hudson.init.InitReactorListener; import hudson.util.DaemonThreadFactory; @@ -24,6 +25,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import static java.util.logging.Level.SEVERE; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Executes the {@link Reactor} for the purpose of bootup. @@ -60,15 +63,15 @@ public class InitReactorRunner { r.add(new ReactorListener() { final Level level = Level.parse( Configuration.getStringConfigParameter("initLogLevel", "FINE") ); public void onTaskStarted(Task t) { - LOGGER.log(level,"Started "+t.getDisplayName()); + LOGGER.log(level, "Started {0}", getDisplayName(t)); } public void onTaskCompleted(Task t) { - LOGGER.log(level,"Completed "+t.getDisplayName()); + LOGGER.log(level, "Completed {0}", getDisplayName(t)); } public void onTaskFailed(Task t, Throwable err, boolean fatal) { - LOGGER.log(SEVERE, "Failed "+t.getDisplayName(),err); + LOGGER.log(SEVERE, "Failed " + getDisplayName(t), err); } public void onAttained(Milestone milestone) { @@ -85,13 +88,24 @@ public class InitReactorRunner { return new ReactorListener.Aggregator(r); } + /** Like {@link Task#getDisplayName} but more robust. */ + @Restricted(NoExternalUse.class) + public static String getDisplayName(Task t) { + try { + return t.getDisplayName(); + } catch (RuntimeException | Error x) { + LOGGER.log(Level.WARNING, "failed to find displayName of " + t, x); + return t.toString(); + } + } + /** * Called when the init milestone is attained. */ protected void onInitMilestoneAttained(InitMilestone milestone) { } - private static final int TWICE_CPU_NUM = Integer.getInteger( + private static final int TWICE_CPU_NUM = SystemProperties.getInteger( InitReactorRunner.class.getName()+".concurrency", Runtime.getRuntime().availableProcessors() * 2); diff --git a/core/src/main/java/jenkins/JenkinsHttpSessionListener.java b/core/src/main/java/jenkins/JenkinsHttpSessionListener.java new file mode 100644 index 0000000000000000000000000000000000000000..be58ae3bd7f7268799ed57abbabb4f257d117bea --- /dev/null +++ b/core/src/main/java/jenkins/JenkinsHttpSessionListener.java @@ -0,0 +1,70 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins; + +import jenkins.util.HttpSessionListener; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import javax.servlet.http.HttpSessionEvent; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Web container hook for the {@link HttpSessionListener} {@link hudson.ExtensionPoint}. + * + * @author tom.fennelly@gmail.com + */ +@Restricted(NoExternalUse.class) +public final class JenkinsHttpSessionListener implements javax.servlet.http.HttpSessionListener { + + // TODO: Seems like classes like this should live in the /war/src/java + // But that applies to a number of other classes too and it has never happened, so will + // not do it with this class for now anyway. + + private static final Logger LOGGER = Logger.getLogger(JenkinsHttpSessionListener.class.getName()); + + @Override + public void sessionCreated(HttpSessionEvent httpSessionEvent) { + for (HttpSessionListener listener : HttpSessionListener.all()) { + try { + listener.sessionCreated(httpSessionEvent); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Error calling HttpSessionListener ExtensionPoint sessionCreated().", e); + } + } + } + + @Override + public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { + for (HttpSessionListener listener : HttpSessionListener.all()) { + try { + listener.sessionDestroyed(httpSessionEvent); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Error calling HttpSessionListener ExtensionPoint sessionDestroyed().", e); + } + } + } + +} diff --git a/test/src/main/java/org/jvnet/hudson/test/ExtractChangeLogSet.java b/core/src/main/java/jenkins/MissingDependencyException.java similarity index 54% rename from test/src/main/java/org/jvnet/hudson/test/ExtractChangeLogSet.java rename to core/src/main/java/jenkins/MissingDependencyException.java index 5e36aaeb243eb866c002c0d62f1f72f8eb4c564f..efd36b84071025dc5cf27002b756fba64527d80f 100644 --- a/test/src/main/java/org/jvnet/hudson/test/ExtractChangeLogSet.java +++ b/core/src/main/java/jenkins/MissingDependencyException.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2016, CloudBees, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,37 +21,40 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; -import hudson.model.AbstractBuild; -import hudson.scm.ChangeLogSet; +package jenkins; +import java.io.IOException; import java.util.List; -import java.util.Collections; -import java.util.Iterator; +import hudson.PluginWrapper.Dependency; +import hudson.Util; /** - * @author Andrew Bayer + * Exception thrown if plugin resolution fails due to missing dependencies + * + * @author Carlos Sanchez + * @since 2.4 + * */ -public class ExtractChangeLogSet extends ChangeLogSet { - private List changeLogs = null; - - public ExtractChangeLogSet(AbstractBuild build, List changeLogs) { - super(build); - for (ExtractChangeLogParser.ExtractChangeLogEntry entry : changeLogs) { - entry.setParent(this); - } - this.changeLogs = Collections.unmodifiableList(changeLogs); +public class MissingDependencyException extends IOException { + + private String pluginShortName; + private List missingDependencies; + + public MissingDependencyException(String pluginShortName, List missingDependencies) { + super("One or more dependencies could not be resolved for " + pluginShortName + " : " + + Util.join(missingDependencies, ", ")); + this.pluginShortName = pluginShortName; + this.missingDependencies = missingDependencies; } - @Override - public boolean isEmptySet() { - return changeLogs.isEmpty(); + public List getMissingDependencies() { + return missingDependencies; } - public Iterator iterator() { - return changeLogs.iterator(); + public String getPluginShortName() { + return pluginShortName; } } diff --git a/core/src/main/java/jenkins/PluginSubtypeMarker.java b/core/src/main/java/jenkins/PluginSubtypeMarker.java index 6dba87f5cbc5a41ae731b1c83621ba6b0409bc77..d10427a33d8f1c849d4cc9ecf9e4cd28956aebab 100644 --- a/core/src/main/java/jenkins/PluginSubtypeMarker.java +++ b/core/src/main/java/jenkins/PluginSubtypeMarker.java @@ -30,7 +30,6 @@ import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; -import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -54,7 +53,6 @@ import java.util.Set; * @author Kohsuke Kawaguchi * @since 1.420 */ -@SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedAnnotationTypes("*") @MetaInfServices(Processor.class) @SuppressWarnings({"Since15"}) @@ -80,6 +78,11 @@ public class PluginSubtypeMarker extends AbstractProcessor { return super.visitType(e, aVoid); } + + @Override + public Void visitUnknown(Element e, Void aVoid) { + return DEFAULT_VALUE; + } }; for (Element e : roundEnv.getRootElements()) { @@ -100,14 +103,16 @@ public class PluginSubtypeMarker extends AbstractProcessor { } } + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + private void write(TypeElement c) throws IOException { FileObject f = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/hudson.Plugin"); - Writer w = new OutputStreamWriter(f.openOutputStream(),"UTF-8"); - try { + try (Writer w = new OutputStreamWriter(f.openOutputStream(), "UTF-8")) { w.write(c.getQualifiedName().toString()); - } finally { - w.close(); } } diff --git a/core/src/main/java/jenkins/SlaveToMasterFileCallable.java b/core/src/main/java/jenkins/SlaveToMasterFileCallable.java index f196a88cf361e08ce8c029a25b42be437bdce593..bda39cff47f8e9bfb88538f768e0b041e7dfc8bb 100644 --- a/core/src/main/java/jenkins/SlaveToMasterFileCallable.java +++ b/core/src/main/java/jenkins/SlaveToMasterFileCallable.java @@ -5,7 +5,7 @@ import jenkins.security.Roles; import org.jenkinsci.remoting.RoleChecker; /** - * {@link FileCallable}s that can be executed on the master, sent by the slave. + * {@link FileCallable}s that can be executed on the master, sent by the agent. * * @since 1.THU */ diff --git a/core/src/main/java/jenkins/SoloFilePathFilter.java b/core/src/main/java/jenkins/SoloFilePathFilter.java index c2cfa58ef051a5e376aab4aee0ba702915568fe9..989728458231393097e29780157ce661032afc45 100644 --- a/core/src/main/java/jenkins/SoloFilePathFilter.java +++ b/core/src/main/java/jenkins/SoloFilePathFilter.java @@ -28,7 +28,7 @@ public final class SoloFilePathFilter extends FilePathFilter { private boolean noFalse(String op, File f, boolean b) { if (!b) - throw new SecurityException("slave may not " + op + " " + f+"\nSee http://jenkins-ci.org/security-144 for more details"); + throw new SecurityException("agent may not " + op + " " + f+"\nSee http://jenkins-ci.org/security-144 for more details"); return true; } diff --git a/core/src/main/java/jenkins/diagnosis/HsErrPidList.java b/core/src/main/java/jenkins/diagnosis/HsErrPidList.java index ac60a307eb4b6cbfcedd8c3e9067540b181bb359..f11090a4b4d88d19cb550a863978108ceee07ff7 100644 --- a/core/src/main/java/jenkins/diagnosis/HsErrPidList.java +++ b/core/src/main/java/jenkins/diagnosis/HsErrPidList.java @@ -24,13 +24,15 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.io.IOUtils; +import org.jenkinsci.Symbol; /** * Finds crash dump reports and show them in the UI. * * @author Kohsuke Kawaguchi */ -@Extension(optional=true) // TODO why would an extension using a built-in extension point need to be marked optional? +@Extension(optional=true) @Symbol("hsErrPid") +// TODO why would an extension using a built-in extension point need to be marked optional? public class HsErrPidList extends AdministrativeMonitor { /** * hs_err_pid files that we think belong to us. @@ -47,14 +49,8 @@ public class HsErrPidList extends AdministrativeMonitor { return; } try { - FileChannel ch = null; - try { - ch = new FileInputStream(getSecretKeyFile()).getChannel(); + try (FileChannel ch = new FileInputStream(getSecretKeyFile()).getChannel()) { map = ch.map(MapMode.READ_ONLY,0,1); - } finally { - if (ch != null) { - ch.close(); - } } scan("./hs_err_pid%p.log"); diff --git a/core/src/main/java/jenkins/diagnostics/CompletedInitializationMonitor.java b/core/src/main/java/jenkins/diagnostics/CompletedInitializationMonitor.java new file mode 100644 index 0000000000000000000000000000000000000000..84803aa006ca2af0c4335fa604e56dace04ef772 --- /dev/null +++ b/core/src/main/java/jenkins/diagnostics/CompletedInitializationMonitor.java @@ -0,0 +1,56 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.diagnostics; + +import hudson.Extension; +import hudson.init.InitMilestone; +import hudson.model.AdministrativeMonitor; +import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Performs monitoring of {@link Jenkins} {@link InitMilestone} status. + * + * @author Oleg Nenashev + * @since 2.21 + */ +@Restricted(NoExternalUse.class) +@Extension @Symbol("completedInitialization") +public class CompletedInitializationMonitor extends AdministrativeMonitor { + + @Override + public String getDisplayName() { + return Messages.CompletedInitializationMonitor_DisplayName(); + } + + @Override + public boolean isActivated() { + final Jenkins instance = Jenkins.getInstance(); + // Safe to check in such way, because monitors are being checked in UI only. + // So Jenkins class construction and initialization must be always finished by the call of this extension. + return instance.getInitLevel() != InitMilestone.COMPLETED; + } +} diff --git a/core/src/main/java/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor.java b/core/src/main/java/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor.java deleted file mode 100644 index 0fb30e10fbaf1c4c91d7fe102de098bdbb72e3e1..0000000000000000000000000000000000000000 --- a/core/src/main/java/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor.java +++ /dev/null @@ -1,44 +0,0 @@ -package jenkins.diagnostics; - -import com.google.common.collect.ImmutableList; -import hudson.Extension; -import hudson.PluginWrapper; -import hudson.model.AdministrativeMonitor; -import jenkins.model.Jenkins; - -import javax.inject.Inject; -import java.util.ArrayList; -import java.util.List; - -/** - * Fires off when we have any pinned plugins that's blocking upgrade from the bundled version. - * - * @author Kohsuke Kawaguchi - */ -@Extension -public class PinningIsBlockingBundledPluginMonitor extends AdministrativeMonitor { - @Inject - Jenkins jenkins; - - private List offenders; - - @Override - public boolean isActivated() { - return !getOffenders().isEmpty(); - } - - private void compute() { - List offenders = new ArrayList(); - for (PluginWrapper p : jenkins.pluginManager.getPlugins()) { - if (p.isPinningForcingOldVersion()) - offenders.add(p); - } - this.offenders = ImmutableList.copyOf(offenders); - } - - public List getOffenders() { - if (offenders==null) - compute(); - return offenders; - } -} diff --git a/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java b/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java index 23148724b23ba1f40eacabeb7c7983a2ce91cdf5..0fcefc9caacac071bc25efb630cf427ac5f08c62 100644 --- a/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java +++ b/core/src/main/java/jenkins/diagnostics/SecurityIsOffMonitor.java @@ -3,6 +3,7 @@ package jenkins.diagnostics; import hudson.Extension; import hudson.model.AdministrativeMonitor; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; @@ -17,8 +18,14 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("securityIsOff") public class SecurityIsOffMonitor extends AdministrativeMonitor { + + @Override + public String getDisplayName() { + return Messages.SecurityIsOffMonitor_DisplayName(); + } + @Override public boolean isActivated() { return !Jenkins.getInstance().isUseSecurity(); diff --git a/core/src/main/java/jenkins/install/InstallState.java b/core/src/main/java/jenkins/install/InstallState.java new file mode 100644 index 0000000000000000000000000000000000000000..622a552c078c9fb66affb3f09b3b9842a3253575 --- /dev/null +++ b/core/src/main/java/jenkins/install/InstallState.java @@ -0,0 +1,240 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.install; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +import hudson.Extension; +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import java.util.logging.Level; +import java.util.logging.Logger; +import jenkins.model.Jenkins; +import org.apache.commons.lang.StringUtils; +/** + * Jenkins install state. + * + * In order to hook into the setup wizard lifecycle, you should + * include something in a script that call + * to `onSetupWizardInitialized` with a callback, for example: + * + * See upgradeWizard.js for an example + * + * @author tom.fennelly@gmail.com + */ +public class InstallState implements ExtensionPoint { + /** + * Need InstallState != NEW for tests by default + */ + @Extension + public static final InstallState UNKNOWN = new InstallState("UNKNOWN", true); + + /** + * After any setup / restart / etc. hooks are done, states hould be running + */ + @Extension + public static final InstallState RUNNING = new InstallState("RUNNING", true); + + /** + * The initial set up has been completed + */ + @Extension + public static final InstallState INITIAL_SETUP_COMPLETED = new InstallState("INITIAL_SETUP_COMPLETED", true) { + public void initializeState() { + Jenkins j = Jenkins.getInstance(); + try { + j.getSetupWizard().completeSetup(); + } catch (Exception e) { + throw new RuntimeException(e); + } + j.setInstallState(RUNNING); + } + }; + + /** + * Creating an admin user for an initial Jenkins install. + */ + @Extension + public static final InstallState CREATE_ADMIN_USER = new InstallState("CREATE_ADMIN_USER", false) { + public void initializeState() { + Jenkins j = Jenkins.getInstance(); + // Skip this state if not using the security defaults + // e.g. in an init script set up security already + if (!j.getSetupWizard().isUsingSecurityDefaults()) { + InstallUtil.proceedToNextStateFrom(this); + } + } + }; + + /** + * New Jenkins install. The user has kicked off the process of installing an + * initial set of plugins (via the install wizard). + */ + @Extension + public static final InstallState INITIAL_PLUGINS_INSTALLING = new InstallState("INITIAL_PLUGINS_INSTALLING", false); + + /** + * Security setup for a new Jenkins install. + */ + @Extension + public static final InstallState INITIAL_SECURITY_SETUP = new InstallState("INITIAL_SECURITY_SETUP", false) { + public void initializeState() { + try { + Jenkins.getInstance().getSetupWizard().init(true); + } catch (Exception e) { + throw new RuntimeException(e); + } + + InstallUtil.proceedToNextStateFrom(INITIAL_SECURITY_SETUP); + } + }; + + /** + * New Jenkins install. + */ + @Extension + public static final InstallState NEW = new InstallState("NEW", false); + + /** + * Restart of an existing Jenkins install. + */ + @Extension + public static final InstallState RESTART = new InstallState("RESTART", true) { + public void initializeState() { + InstallUtil.saveLastExecVersion(); + } + }; + + /** + * Upgrade of an existing Jenkins install. + */ + @Extension + public static final InstallState UPGRADE = new UpgradeWizard(); + + /** + * Downgrade of an existing Jenkins install. + */ + @Extension + public static final InstallState DOWNGRADE = new InstallState("DOWNGRADE", true) { + public void initializeState() { + InstallUtil.saveLastExecVersion(); + } + }; + + private static final Logger LOGGER = Logger.getLogger(InstallState.class.getName()); + + /** + * Jenkins started in test mode (JenkinsRule). + */ + public static final InstallState TEST = new InstallState("TEST", true); + + /** + * Jenkins started in development mode: Bolean.getBoolean("hudson.Main.development"). + * Can be run normally with the -Djenkins.install.runSetupWizard=true + */ + public static final InstallState DEVELOPMENT = new InstallState("DEVELOPMENT", true); + + private final boolean isSetupComplete; + private final String name; + + public InstallState(@Nonnull String name, boolean isSetupComplete) { + this.name = name; + this.isSetupComplete = isSetupComplete; + } + + /** + * Process any initialization this install state requires + */ + public void initializeState() { + } + + public Object readResolve() { + // If we get invalid state from the configuration, fallback to unknown + if (StringUtils.isBlank(name)) { + LOGGER.log(Level.WARNING, "Read install state with blank name: ''{0}''. It will be ignored", name); + return UNKNOWN; + } + + InstallState state = InstallState.valueOf(name); + if (state == null) { + LOGGER.log(Level.WARNING, "Cannot locate an extension point for the state ''{0}''. It will be ignored", name); + return UNKNOWN; + } + + // Otherwise we return the actual state + return state; + } + + /** + * Indicates the initial setup is complete + */ + public boolean isSetupComplete() { + return isSetupComplete; + } + + public String name() { + return name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof InstallState) { + return name.equals(((InstallState)obj).name()); + } + return false; + } + + @Override + public String toString() { + return "InstallState (" + name + ")"; + } + + /** + * Find an install state by name + * @param name + * @return + */ + @CheckForNull + public static InstallState valueOf(@Nonnull String name) { + for (InstallState state : all()) { + if (name.equals(state.name)) { + return state; + } + } + return null; + } + + /** + * Returns all install states in the system + */ + static ExtensionList all() { + return ExtensionList.lookup(InstallState.class); + } +} diff --git a/core/src/main/java/jenkins/install/InstallStateFilter.java b/core/src/main/java/jenkins/install/InstallStateFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..06959e34db67a88872b7148da9cc3bb04807f5e0 --- /dev/null +++ b/core/src/main/java/jenkins/install/InstallStateFilter.java @@ -0,0 +1,26 @@ +package jenkins.install; + +import java.util.List; + +import javax.inject.Provider; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; + +/** + * Allows plugging in to the lifecycle when determining InstallState + * from {@link InstallUtil#getNextInstallState(InstallState)} + */ +public abstract class InstallStateFilter implements ExtensionPoint { + /** + * Determine the current or next install state, proceed with `return proceed.next()` + */ + public abstract InstallState getNextInstallState(InstallState current, Provider proceed); + + /** + * Get all the InstallStateFilters, in extension order + */ + public static List all() { + return ExtensionList.lookup(InstallStateFilter.class); + } +} diff --git a/core/src/main/java/jenkins/install/InstallUtil.java b/core/src/main/java/jenkins/install/InstallUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..45fb5ce3a623f0e7221bdf1e98cfb60790a57c74 --- /dev/null +++ b/core/src/main/java/jenkins/install/InstallUtil.java @@ -0,0 +1,351 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.install; + +import static java.util.logging.Level.SEVERE; +import static java.util.logging.Level.WARNING; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.inject.Provider; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import com.google.common.base.Function; +import com.thoughtworks.xstream.XStream; + +import hudson.Functions; +import hudson.Main; +import hudson.model.UpdateCenter.DownloadJob.InstallationStatus; +import hudson.model.UpdateCenter.DownloadJob.Installing; +import hudson.model.UpdateCenter.InstallationJob; +import hudson.model.UpdateCenter.UpdateCenterJob; +import hudson.util.VersionNumber; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import jenkins.util.xml.XMLUtils; + +/** + * Jenkins install utilities. + * + * @author tom.fennelly@gmail.com + */ +@Restricted(NoExternalUse.class) +public class InstallUtil { + + private static final Logger LOGGER = Logger.getLogger(InstallUtil.class.getName()); + + // tests need this to be 1.0 + private static final VersionNumber NEW_INSTALL_VERSION = new VersionNumber("1.0"); + private static final VersionNumber FORCE_NEW_INSTALL_VERSION = new VersionNumber("0.0"); + + /** + * Simple chain pattern using iterator.next() + */ + private static class ProviderChain implements Provider { + private final Iterator,T>> functions; + public ProviderChain(Iterator,T>> functions) { + this.functions = functions; + } + @Override + public T get() { + return functions.next().apply(this); + } + } + + /** + * Proceed to the state following the provided one + */ + public static void proceedToNextStateFrom(InstallState prior) { + InstallState next = getNextInstallState(prior); + if (Main.isDevelopmentMode) LOGGER.info("Install state tranisitioning from: " + prior + " to: " + next); + if (next != null) { + Jenkins.getInstance().setInstallState(next); + } + } + + /** + * Returns the next state during a transition from the current install state + */ + /*package*/ static InstallState getNextInstallState(final InstallState current) { + List,InstallState>> installStateFilterChain = new ArrayList<>(); + for (final InstallStateFilter setupExtension : InstallStateFilter.all()) { + installStateFilterChain.add(new Function, InstallState>() { + @Override + public InstallState apply(Provider next) { + return setupExtension.getNextInstallState(current, next); + } + }); + } + // Terminal condition: getNextState() on the current install state + installStateFilterChain.add(new Function, InstallState>() { + @Override + public InstallState apply(Provider input) { + // Initially, install state is unknown and + // needs to be determined + if (current == null || InstallState.UNKNOWN.equals(current)) { + return getDefaultInstallState(); + } + final Map states = new HashMap(); + { + states.put(InstallState.CREATE_ADMIN_USER, InstallState.INITIAL_SETUP_COMPLETED); + states.put(InstallState.INITIAL_PLUGINS_INSTALLING, InstallState.CREATE_ADMIN_USER); + states.put(InstallState.INITIAL_SECURITY_SETUP, InstallState.NEW); + states.put(InstallState.RESTART, InstallState.RUNNING); + states.put(InstallState.UPGRADE, InstallState.INITIAL_SETUP_COMPLETED); + states.put(InstallState.DOWNGRADE, InstallState.INITIAL_SETUP_COMPLETED); + states.put(InstallState.INITIAL_SETUP_COMPLETED, InstallState.RUNNING); + } + return states.get(current); + } + }); + + ProviderChain chain = new ProviderChain<>(installStateFilterChain.iterator()); + return chain.get(); + } + + private static InstallState getDefaultInstallState() { + // Support a simple state override. Useful for testing. + String stateOverride = System.getProperty("jenkins.install.state", System.getenv("jenkins.install.state")); + if (stateOverride != null) { + try { + return InstallState.valueOf(stateOverride.toUpperCase()); + } catch (RuntimeException e) { + throw new IllegalStateException("Unknown install state override specified on the commandline: '" + stateOverride + "'."); + } + } + + // Support a 3-state flag for running or disabling the setup wizard + String shouldRunFlag = SystemProperties.getString("jenkins.install.runSetupWizard"); + boolean shouldRun = "true".equalsIgnoreCase(shouldRunFlag); + boolean shouldNotRun = "false".equalsIgnoreCase(shouldRunFlag); + + // install wizard will always run if environment specified + if (!shouldRun) { + if (Functions.getIsUnitTest()) { + return InstallState.TEST; + } + + if (SystemProperties.getBoolean("hudson.Main.development")) { + return InstallState.DEVELOPMENT; + } + } + + VersionNumber lastRunVersion = new VersionNumber(getLastExecVersion()); + + // Neither the top level config or the lastExecVersionFile have a version + // stored in them, which means it's a new install. + if (FORCE_NEW_INSTALL_VERSION.equals(lastRunVersion) || lastRunVersion.compareTo(NEW_INSTALL_VERSION) == 0) { + Jenkins j = Jenkins.getInstance(); + + // Allow for skipping + if(shouldNotRun) { + try { + InstallState.INITIAL_SETUP_COMPLETED.initializeState(); + return j.getInstallState(); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + if (!FORCE_NEW_INSTALL_VERSION.equals(lastRunVersion)) { + // Edge case: used Jenkins 1 but did not save the system config page, + // the version is not persisted and returns 1.0, so try to check if + // they actually did anything + if (!j.getItemMap().isEmpty() || !j.getNodes().isEmpty()) { + return InstallState.UPGRADE; + } + } + + return InstallState.INITIAL_SECURITY_SETUP; + } + + // We have a last version. + + VersionNumber currentRunVersion = new VersionNumber(getCurrentExecVersion()); + if (lastRunVersion.isOlderThan(currentRunVersion)) { + return InstallState.UPGRADE; + } else if (lastRunVersion.isNewerThan(currentRunVersion)) { + return InstallState.DOWNGRADE; + } else { + // Last running version was the same as "this" running version. + return InstallState.RESTART; + } + } + + /** + * Save the current Jenkins instance version as the last executed version. + *

    + * This state information is required in order to determine whether or not the Jenkins instance + * is just restarting, or is being upgraded from an earlier version. + */ + public static void saveLastExecVersion() { + if (Jenkins.VERSION.equals(Jenkins.UNCOMPUTED_VERSION)) { + // This should never happen!! Only adding this check in case someone moves the call to this method to the wrong place. + throw new IllegalStateException("Unexpected call to InstallUtil.saveLastExecVersion(). Jenkins.VERSION has not been initialized. Call computeVersion() first."); + } + saveLastExecVersion(Jenkins.VERSION); + } + + /** + * Get the last saved Jenkins instance version. + * @return The last saved Jenkins instance version. + * @see #saveLastExecVersion() + */ + public static @Nonnull String getLastExecVersion() { + File lastExecVersionFile = getLastExecVersionFile(); + if (lastExecVersionFile.exists()) { + try { + String version = FileUtils.readFileToString(lastExecVersionFile); + // JENKINS-37438 blank will force the setup + // wizard regardless of current state of the system + if (StringUtils.isBlank(version)) { + return FORCE_NEW_INSTALL_VERSION.toString(); + } + return version; + } catch (IOException e) { + LOGGER.log(SEVERE, "Unexpected Error. Unable to read " + lastExecVersionFile.getAbsolutePath(), e); + LOGGER.log(WARNING, "Unable to determine the last running version (see error above). Treating this as a restart. No plugins will be updated."); + return getCurrentExecVersion(); + } + } else { + // Backward compatibility. Use the last version stored in the top level config.xml. + // Going to read the value directly from the config.xml file Vs hoping that the + // Jenkins startup sequence has moved far enough along that it has loaded the + // global config. It can't load the global config until well into the startup + // sequence because the unmarshal requires numerous objects to be created e.g. + // it requires the Plugin Manager. It happens too late and it's too risky to + // change how it currently works. + File configFile = getConfigFile(); + if (configFile.exists()) { + try { + String lastVersion = XMLUtils.getValue("/hudson/version", configFile); + if (lastVersion.length() > 0) { + return lastVersion; + } + } catch (Exception e) { + LOGGER.log(SEVERE, "Unexpected error reading global config.xml", e); + } + } + return NEW_INSTALL_VERSION.toString(); + } + } + + /** + * Save a specific version as the last execute version. + * @param version The version to save. + */ + static void saveLastExecVersion(@Nonnull String version) { + File lastExecVersionFile = getLastExecVersionFile(); + try { + FileUtils.write(lastExecVersionFile, version); + } catch (IOException e) { + LOGGER.log(SEVERE, "Failed to save " + lastExecVersionFile.getAbsolutePath(), e); + } + } + + static File getConfigFile() { + return new File(Jenkins.getInstance().getRootDir(), "config.xml"); + } + + static File getLastExecVersionFile() { + return new File(Jenkins.getInstance().getRootDir(), "jenkins.install.InstallUtil.lastExecVersion"); + } + + static File getInstallingPluginsFile() { + return new File(Jenkins.getInstance().getRootDir(), "jenkins.install.InstallUtil.installingPlugins"); + } + + private static String getCurrentExecVersion() { + if (Jenkins.VERSION.equals(Jenkins.UNCOMPUTED_VERSION)) { + // This should never happen!! Only adding this check in case someone moves the call to this method to the wrong place. + throw new IllegalStateException("Unexpected call to InstallUtil.getCurrentExecVersion(). Jenkins.VERSION has not been initialized. Call computeVersion() first."); + } + return Jenkins.VERSION; + } + + /** + * Returns a list of any plugins that are persisted in the installing list + */ + @SuppressWarnings("unchecked") + public static synchronized @CheckForNull Map getPersistedInstallStatus() { + File installingPluginsFile = getInstallingPluginsFile(); + if(installingPluginsFile == null || !installingPluginsFile.exists()) { + return null; + } + return (Map)new XStream().fromXML(installingPluginsFile); + } + + /** + * Persists a list of installing plugins; this is used in the case Jenkins fails mid-installation and needs to be restarted + * @param installingPlugins + */ + public static synchronized void persistInstallStatus(List installingPlugins) { + File installingPluginsFile = getInstallingPluginsFile(); + if(installingPlugins == null || installingPlugins.isEmpty()) { + installingPluginsFile.delete(); + return; + } + LOGGER.fine("Writing install state to: " + installingPluginsFile.getAbsolutePath()); + Map statuses = new HashMap(); + for(UpdateCenterJob j : installingPlugins) { + if(j instanceof InstallationJob && j.getCorrelationId() != null) { // only include install jobs with a correlation id (directly selected) + InstallationJob ij = (InstallationJob)j; + InstallationStatus status = ij.status; + String statusText = status.getType(); + if(status instanceof Installing) { // flag currently installing plugins as pending + statusText = "Pending"; + } + statuses.put(ij.plugin.name, statusText); + } + } + try { + String installingPluginXml = new XStream().toXML(statuses); + FileUtils.write(installingPluginsFile, installingPluginXml); + } catch (IOException e) { + LOGGER.log(SEVERE, "Failed to save " + installingPluginsFile.getAbsolutePath(), e); + } + } + + /** + * Call to remove any active install status + */ + public static void clearInstallStatus() { + persistInstallStatus(null); + } +} diff --git a/core/src/main/java/jenkins/install/SetupWizard.java b/core/src/main/java/jenkins/install/SetupWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..6368fb4b8f32f03a6ee9327f211b3f735ede9883 --- /dev/null +++ b/core/src/main/java/jenkins/install/SetupWizard.java @@ -0,0 +1,521 @@ +package jenkins.install; + +import static org.apache.commons.io.FileUtils.readFileToString; +import static org.apache.commons.lang.StringUtils.defaultIfBlank; + +import java.io.IOException; +import java.util.Locale; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.annotation.CheckForNull; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletResponse; + +import jenkins.util.SystemProperties; +import org.acegisecurity.Authentication; +import org.acegisecurity.context.SecurityContextHolder; +import org.acegisecurity.providers.UsernamePasswordAuthenticationToken; +import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import hudson.BulkChange; +import hudson.Extension; +import hudson.FilePath; +import hudson.ProxyConfiguration; +import hudson.model.PageDecorator; +import hudson.model.UpdateCenter; +import hudson.model.UpdateSite; +import hudson.model.User; +import hudson.security.FullControlOnceLoggedInAuthorizationStrategy; +import hudson.security.HudsonPrivateSecurityRealm; +import hudson.security.SecurityRealm; +import hudson.security.csrf.DefaultCrumbIssuer; +import hudson.util.HttpResponses; +import hudson.util.PluginServletFilter; +import hudson.util.VersionNumber; +import java.io.File; +import java.net.HttpRetryException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.Iterator; +import java.util.List; + +import jenkins.model.Jenkins; +import jenkins.security.s2m.AdminWhitelistRule; +import net.sf.json.JSONArray; +import net.sf.json.JSONObject; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.kohsuke.accmod.restrictions.DoNotUse; + +/** + * A Jenkins instance used during first-run to provide a limited set of services while + * initial installation is in progress + * + * @since 2.0 + */ +@Restricted(NoExternalUse.class) +@Extension +public class SetupWizard extends PageDecorator { + /** + * The security token parameter name + */ + public static String initialSetupAdminUserName = "admin"; + + private static final Logger LOGGER = Logger.getLogger(SetupWizard.class.getName()); + + /** + * Used to determine if this was a new install (vs. an upgrade, restart, or otherwise) + */ + private static boolean isUsingSecurityToken = false; + + /** + * Initialize the setup wizard, this will process any current state initializations + */ + /*package*/ void init(boolean newInstall) throws IOException, InterruptedException { + Jenkins jenkins = Jenkins.getInstance(); + + if(newInstall) { + // this was determined to be a new install, don't run the update wizard here + setCurrentLevel(Jenkins.getVersion()); + + // Create an admin user by default with a + // difficult password + FilePath iapf = getInitialAdminPasswordFile(); + if(jenkins.getSecurityRealm() == null || jenkins.getSecurityRealm() == SecurityRealm.NO_AUTHENTICATION) { // this seems very fragile + try (BulkChange bc = new BulkChange(jenkins)) { + HudsonPrivateSecurityRealm securityRealm = new HudsonPrivateSecurityRealm(false, false, null); + jenkins.setSecurityRealm(securityRealm); + String randomUUID = UUID.randomUUID().toString().replace("-", "").toLowerCase(Locale.ENGLISH); + + // create an admin user + securityRealm.createAccount(SetupWizard.initialSetupAdminUserName, randomUUID); + + // JENKINS-33599 - write to a file in the jenkins home directory + // most native packages of Jenkins creates a machine user account 'jenkins' to run Jenkins, + // and use group 'jenkins' for admins. So we allow groups to read this file + iapf.touch(System.currentTimeMillis()); + iapf.chmod(0640); + iapf.write(randomUUID + System.lineSeparator(), "UTF-8"); + + + // Lock Jenkins down: + FullControlOnceLoggedInAuthorizationStrategy authStrategy = new FullControlOnceLoggedInAuthorizationStrategy(); + authStrategy.setAllowAnonymousRead(false); + jenkins.setAuthorizationStrategy(authStrategy); + + // Disable jnlp by default, but honor system properties + jenkins.setSlaveAgentPort(SystemProperties.getInteger(Jenkins.class.getName()+".slaveAgentPort",-1)); + + // require a crumb issuer + jenkins.setCrumbIssuer(new DefaultCrumbIssuer(false)); + + // set master -> slave security: + jenkins.getInjector().getInstance(AdminWhitelistRule.class) + .setMasterKillSwitch(false); + + jenkins.save(); // !! + bc.commit(); + } + } + + if(iapf.exists()) { + String setupKey = iapf.readToString().trim(); + String ls = System.lineSeparator(); + LOGGER.info(ls + ls + "*************************************************************" + ls + + "*************************************************************" + ls + + "*************************************************************" + ls + + ls + + "Jenkins initial setup is required. An admin user has been created and " + + "a password generated." + ls + + "Please use the following password to proceed to installation:" + ls + + ls + + setupKey + ls + + ls + + "This may also be found at: " + iapf.getRemote() + ls + + ls + + "*************************************************************" + ls + + "*************************************************************" + ls + + "*************************************************************" + ls); + } + + try { + PluginServletFilter.addFilter(FORCE_SETUP_WIZARD_FILTER); + // if we're not using security defaults, we should not show the security token screen + // users will likely be sent to a login screen instead + isUsingSecurityToken = isUsingSecurityDefaults(); + } catch (ServletException e) { + throw new RuntimeException("Unable to add PluginServletFilter for the SetupWizard", e); + } + } + + try { + // Make sure plugin metadata is up to date + UpdateCenter.updateDefaultSite(); + } catch (Exception e) { + LOGGER.log(Level.WARNING, e.getMessage(), e); + } + } + + /** + * Indicates a generated password should be used - e.g. this is a new install, no security realm set up + */ + public boolean isUsingSecurityToken() { + try { + return isUsingSecurityToken // only ever show the unlock page if using the security token + && !Jenkins.getInstance().getInstallState().isSetupComplete() + && isUsingSecurityDefaults(); + } catch (Exception e) { + // ignore + } + return false; + } + + /** + * Determines if the security settings seem to match the defaults. Here, we only + * really care about and test for HudsonPrivateSecurityRealm and the user setup. + * Other settings are irrelevant. + */ + /*package*/ boolean isUsingSecurityDefaults() { + Jenkins j = Jenkins.getInstance(); + if (j.getSecurityRealm() instanceof HudsonPrivateSecurityRealm) { + HudsonPrivateSecurityRealm securityRealm = (HudsonPrivateSecurityRealm)j.getSecurityRealm(); + try { + if(securityRealm.getAllUsers().size() == 1) { + HudsonPrivateSecurityRealm.Details details = securityRealm.loadUserByUsername(SetupWizard.initialSetupAdminUserName); + FilePath iapf = getInitialAdminPasswordFile(); + if (iapf.exists()) { + if (details.isPasswordCorrect(iapf.readToString().trim())) { + return true; + } + } + } + } catch(UsernameNotFoundException | IOException | InterruptedException e) { + return false; // Not initial security setup if no transitional admin user / password found + } + } + return false; + } + + /** + * Called during the initial setup to create an admin user + */ + public void doCreateAdminUser(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + Jenkins j = Jenkins.getInstance(); + j.checkPermission(Jenkins.ADMINISTER); + + // This will be set up by default. if not, something changed, ok to fail + HudsonPrivateSecurityRealm securityRealm = (HudsonPrivateSecurityRealm)j.getSecurityRealm(); + + User admin = securityRealm.getUser(SetupWizard.initialSetupAdminUserName); + try { + if(admin != null) { + admin.delete(); // assume the new user may well be 'admin' + } + + User u = securityRealm.createAccountByAdmin(req, rsp, "/jenkins/install/SetupWizard/setupWizardFirstUser.jelly", req.getContextPath() + "/"); + if (u != null) { + if(admin != null) { + admin = null; + } + + // Success! Delete the temporary password file: + try { + getInitialAdminPasswordFile().delete(); + } catch (InterruptedException e) { + throw new IOException(e); + } + + InstallUtil.proceedToNextStateFrom(InstallState.CREATE_ADMIN_USER); + + // ... and then login + Authentication a = new UsernamePasswordAuthenticationToken(u.getId(),req.getParameter("password1")); + a = securityRealm.getSecurityComponents().manager.authenticate(a); + SecurityContextHolder.getContext().setAuthentication(a); + } + } finally { + if(admin != null) { + admin.save(); // recreate this initial user if something failed + } + } + } + + /*package*/ void setCurrentLevel(VersionNumber v) throws IOException { + FileUtils.writeStringToFile(getUpdateStateFile(), v.toString()); + } + + /** + * File that captures the state of upgrade. + * + * This file records the version number that the installation has upgraded to. + */ + /*package*/ static File getUpdateStateFile() { + return new File(Jenkins.getInstance().getRootDir(),"jenkins.install.UpgradeWizard.state"); + } + + /** + * What is the version the upgrade wizard has run the last time and upgraded to?. + * If {@link #getUpdateStateFile()} is missing, presumes the baseline is 1.0 + * @return Current baseline. {@code null} if it cannot be retrieved. + */ + @Restricted(NoExternalUse.class) + @CheckForNull + public VersionNumber getCurrentLevel() { + VersionNumber from = new VersionNumber("1.0"); + File state = getUpdateStateFile(); + if (state.exists()) { + try { + from = new VersionNumber(defaultIfBlank(readFileToString(state), "1.0").trim()); + } catch (IOException ex) { + LOGGER.log(Level.SEVERE, "Cannot read the current version file", ex); + return null; + } + } + return from; + } + + /** + * Returns the initial plugin list in JSON format + */ + @Restricted(DoNotUse.class) // WebOnly + public HttpResponse doPlatformPluginList() throws IOException { + jenkins.install.SetupWizard setupWizard = Jenkins.getInstance().getSetupWizard(); + if (setupWizard != null) { + if (InstallState.UPGRADE.equals(Jenkins.getInstance().getInstallState())) { + JSONArray initialPluginData = getPlatformPluginUpdates(); + if(initialPluginData != null) { + return HttpResponses.okJSON(initialPluginData); + } + } else { + JSONArray initialPluginData = getPlatformPluginList(); + if(initialPluginData != null) { + return HttpResponses.okJSON(initialPluginData); + } + } + } + return HttpResponses.okJSON(); + } + + /** + * Returns whether the system needs a restart, and if it is supported + * e.g. { restartRequired: true, restartSupported: false } + */ + @Restricted(DoNotUse.class) // WebOnly + public HttpResponse doRestartStatus() throws IOException { + JSONObject response = new JSONObject(); + Jenkins jenkins = Jenkins.getInstance(); + response.put("restartRequired", jenkins.getUpdateCenter().isRestartRequiredForCompletion()); + response.put("restartSupported", jenkins.getLifecycle().canRestart()); + return HttpResponses.okJSON(response); + } + + /** + * Provides the list of platform plugin updates from the last time + * the upgrade was run. + * @return {@code null} if the version range cannot be retrieved. + */ + @CheckForNull + public JSONArray getPlatformPluginUpdates() { + final VersionNumber version = getCurrentLevel(); + if (version == null) { + return null; + } + return getPlatformPluginsForUpdate(version, Jenkins.getVersion()); + } + + /** + * Gets the suggested plugin list from the update sites, falling back to a local version + * @return JSON array with the categorized plugon list + */ + @CheckForNull + /*package*/ JSONArray getPlatformPluginList() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + JSONArray initialPluginList = null; + updateSiteList: for (UpdateSite updateSite : Jenkins.getInstance().getUpdateCenter().getSiteList()) { + String updateCenterJsonUrl = updateSite.getUrl(); + String suggestedPluginUrl = updateCenterJsonUrl.replace("/update-center.json", "/platform-plugins.json"); + try { + URLConnection connection = ProxyConfiguration.open(new URL(suggestedPluginUrl)); + + try { + if(connection instanceof HttpURLConnection) { + int responseCode = ((HttpURLConnection)connection).getResponseCode(); + if(HttpURLConnection.HTTP_OK != responseCode) { + throw new HttpRetryException("Invalid response code (" + responseCode + ") from URL: " + suggestedPluginUrl, responseCode); + } + } + + String initialPluginJson = IOUtils.toString(connection.getInputStream(), "utf-8"); + initialPluginList = JSONArray.fromObject(initialPluginJson); + break updateSiteList; + } catch(Exception e) { + // not found or otherwise unavailable + LOGGER.log(Level.FINE, e.getMessage(), e); + continue updateSiteList; + } + } catch(Exception e) { + LOGGER.log(Level.FINE, e.getMessage(), e); + } + } + if (initialPluginList == null) { + // fall back to local file + try { + ClassLoader cl = getClass().getClassLoader(); + URL localPluginData = cl.getResource("jenkins/install/platform-plugins.json"); + String initialPluginJson = IOUtils.toString(localPluginData.openStream(), "utf-8"); + initialPluginList = JSONArray.fromObject(initialPluginJson); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, e.getMessage(), e); + } + } + return initialPluginList; + } + + /** + * Get the platform plugins added in the version range + */ + /*package*/ JSONArray getPlatformPluginsForUpdate(VersionNumber from, VersionNumber to) { + Jenkins jenkins = Jenkins.getInstance(); + JSONArray pluginCategories = JSONArray.fromObject(getPlatformPluginList().toString()); + for (Iterator categoryIterator = pluginCategories.iterator(); categoryIterator.hasNext();) { + Object category = categoryIterator.next(); + if (category instanceof JSONObject) { + JSONObject cat = (JSONObject)category; + JSONArray plugins = cat.getJSONArray("plugins"); + + nextPlugin: for (Iterator pluginIterator = plugins.iterator(); pluginIterator.hasNext();) { + Object pluginData = pluginIterator.next(); + if (pluginData instanceof JSONObject) { + JSONObject plugin = (JSONObject)pluginData; + if (plugin.has("added")) { + String sinceVersion = plugin.getString("added"); + if (sinceVersion != null) { + VersionNumber v = new VersionNumber(sinceVersion); + if(v.compareTo(to) <= 0 && v.compareTo(from) > 0) { + // This plugin is valid, we'll leave "suggested" state + // to match the experience during install + // but only add it if it's currently uninstalled + String pluginName = plugin.getString("name"); + if (null == jenkins.getPluginManager().getPlugin(pluginName)) { + // Also check that a compatible version exists in an update site + boolean foundCompatibleVersion = false; + for (UpdateSite site : jenkins.getUpdateCenter().getSiteList()) { + UpdateSite.Plugin sitePlug = site.getPlugin(pluginName); + if (sitePlug != null + && !sitePlug.isForNewerHudson() + && !sitePlug.isNeededDependenciesForNewerJenkins()) { + foundCompatibleVersion = true; + break; + } + } + if (foundCompatibleVersion) { + continue nextPlugin; + } + } + } + } + } + } + + pluginIterator.remove(); + } + + if (plugins.isEmpty()) { + categoryIterator.remove(); + } + } + } + return pluginCategories; + } + + /** + * Gets the file used to store the initial admin password + */ + public FilePath getInitialAdminPasswordFile() { + return Jenkins.getInstance().getRootPath().child("secrets/initialAdminPassword"); + } + + /** + * Remove the setupWizard filter, ensure all updates are written to disk, etc + */ + public HttpResponse doCompleteInstall() throws IOException, ServletException { + completeSetup(); + return HttpResponses.okJSON(); + } + + /*package*/ void completeSetup() throws IOException, ServletException { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + InstallUtil.saveLastExecVersion(); + setCurrentLevel(Jenkins.getVersion()); + PluginServletFilter.removeFilter(FORCE_SETUP_WIZARD_FILTER); + isUsingSecurityToken = false; // this should not be considered new anymore + InstallUtil.proceedToNextStateFrom(InstallState.INITIAL_SETUP_COMPLETED); + } + + /** + * Gets all the install states + */ + public List getInstallStates() { + return InstallState.all(); + } + + /** + * Returns an installState by name + */ + public InstallState getInstallState(String name) { + if (name == null) { + return null; + } + return InstallState.valueOf(name); + } + + /** + * This filter will validate that the security token is provided + */ + private final Filter FORCE_SETUP_WIZARD_FILTER = new Filter() { + @Override + public void init(FilterConfig cfg) throws ServletException { + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + // Force root requests to the setup wizard + if (request instanceof HttpServletRequest) { + HttpServletRequest req = (HttpServletRequest) request; + String requestURI = req.getRequestURI(); + if (requestURI.equals(req.getContextPath()) && !requestURI.endsWith("/")) { + ((HttpServletResponse) response).sendRedirect(req.getContextPath() + "/"); + return; + } else if (req.getRequestURI().equals(req.getContextPath() + "/")) { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + chain.doFilter(new HttpServletRequestWrapper(req) { + public String getRequestURI() { + return getContextPath() + "/setupWizard/"; + } + }, response); + return; + } + // fall through to handling the request normally + } + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + }; +} diff --git a/core/src/main/java/jenkins/install/UpgradeWizard.java b/core/src/main/java/jenkins/install/UpgradeWizard.java new file mode 100644 index 0000000000000000000000000000000000000000..ab7e243a7039e125d757e5e2748d38e456bd13dd --- /dev/null +++ b/core/src/main/java/jenkins/install/UpgradeWizard.java @@ -0,0 +1,164 @@ +package jenkins.install; + +import static java.util.logging.Level.FINE; + +import java.io.File; +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.inject.Provider; +import javax.servlet.http.HttpSession; + +import org.apache.commons.io.FileUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.WebApp; +import org.kohsuke.stapler.interceptor.RequirePOST; + +import hudson.Extension; +import hudson.util.HttpResponses; +import jenkins.model.Jenkins; +import net.sf.json.JSONArray; + +/** + * This class is responsible for specific upgrade behaviors in the Jenkins UI. + * + * Note an instance of this class is already an @Extension in {@link InstallState#UPGRADE} + * + * @author Kohsuke Kawaguchi, Keith Zantow + */ +@Restricted(NoExternalUse.class) +public class UpgradeWizard extends InstallState { + /** + * Is this instance fully upgraded? + */ + private volatile boolean isUpToDate = true; + + /** + * Whether to show the upgrade wizard + */ + private static final String SHOW_UPGRADE_WIZARD_FLAG = UpgradeWizard.class.getName() + ".show"; + + /*package*/ UpgradeWizard() { + super("UPGRADE", false); + } + + /** + * Get the upgrade wizard instance + */ + public static UpgradeWizard get() { + return (UpgradeWizard)InstallState.UPGRADE; + } + + @Override + public void initializeState() { + // Initializing this state is directly related to + // running the detached plugin checks, these should be consolidated somehow + updateUpToDate(); + + // If there are no platform updates, proceed to running + if (isUpToDate) { + if (Jenkins.getInstance().getSetupWizard().getPlatformPluginUpdates().isEmpty()) { + Jenkins.getInstance().setInstallState(InstallState.RUNNING); + } + } + } + + @Override + public boolean isSetupComplete() { + return !isDue(); + } + + private void updateUpToDate() { + // If we don't have any platform plugins, it's considered 'up to date' in terms + // of the updater + try { + JSONArray platformPlugins = Jenkins.getInstance().getSetupWizard().getPlatformPluginUpdates(); + isUpToDate = platformPlugins.isEmpty(); + } catch(Exception e) { + LOGGER.log(Level.WARNING, "Unable to get the platform plugin update list.", e); + } + } + + /** + * Do we need to show the upgrade wizard prompt? + */ + public boolean isDue() { + if (isUpToDate) + return false; + + // only admin users should see this + if (!Jenkins.getInstance().hasPermission(Jenkins.ADMINISTER)) + return false; + + // only show when Jenkins is fully up & running + WebApp wa = WebApp.getCurrent(); + if (wa==null || !(wa.getApp() instanceof Jenkins)) + return false; + + return System.currentTimeMillis() > SetupWizard.getUpdateStateFile().lastModified(); + } + + /** + * Whether to show the upgrade wizard + */ + public boolean isShowUpgradeWizard() { + HttpSession session = Stapler.getCurrentRequest().getSession(false); + if(session != null) { + return Boolean.TRUE.equals(session.getAttribute(SHOW_UPGRADE_WIZARD_FLAG)); + } + return false; + } + /** + * Call this to show the upgrade wizard + */ + public HttpResponse doShowUpgradeWizard() throws Exception { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + HttpSession session = Stapler.getCurrentRequest().getSession(true); + session.setAttribute(SHOW_UPGRADE_WIZARD_FLAG, true); + return HttpResponses.redirectToContextRoot(); + } + + /** + * Call this to hide the upgrade wizard + */ + public HttpResponse doHideUpgradeWizard() { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + HttpSession session = Stapler.getCurrentRequest().getSession(false); + if(session != null) { + session.removeAttribute(SHOW_UPGRADE_WIZARD_FLAG); + } + return HttpResponses.redirectToContextRoot(); + } + + /** + * Snooze the upgrade wizard notice. + */ + @RequirePOST + public HttpResponse doSnooze() throws IOException { + Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); + File f = SetupWizard.getUpdateStateFile(); + FileUtils.touch(f); + f.setLastModified(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)); + LOGGER.log(FINE, "Snoozed the upgrade wizard notice"); + return HttpResponses.redirectToContextRoot(); + } + + @Extension + public static class ListenForInstallComplete extends InstallStateFilter { + @Override + public InstallState getNextInstallState(InstallState current, Provider proceed) { + InstallState next = proceed.get(); + if (InstallState.INITIAL_SETUP_COMPLETED.equals(current)) { + UpgradeWizard.get().isUpToDate = true; + } + return next; + } + } + + private static final Logger LOGGER = Logger.getLogger(UpgradeWizard.class.getName()); +} diff --git a/test/src/main/java/org/jvnet/hudson/test/CaptureEnvironmentBuilder.java b/core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java similarity index 55% rename from test/src/main/java/org/jvnet/hudson/test/CaptureEnvironmentBuilder.java rename to core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java index 775eb8d14648ed06ed9d9d0fd5101a8b470b333b..390d5a3eecd48cd71648a2cbf971b74f0262ffa2 100644 --- a/test/src/main/java/org/jvnet/hudson/test/CaptureEnvironmentBuilder.java +++ b/core/src/main/java/jenkins/management/AdministrativeMonitorsConfiguration.java @@ -1,7 +1,7 @@ /* * The MIT License * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. + * Copyright (c) 2016, CloudBees, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,46 +21,36 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; -import hudson.Launcher; +package jenkins.management; + import hudson.Extension; -import hudson.EnvVars; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.model.Descriptor; -import hudson.tasks.Builder; +import hudson.model.AdministrativeMonitor; +import jenkins.model.GlobalConfiguration; import net.sf.json.JSONObject; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; -/** - * {@link Builder} that captures the environment variables used during a build. - * - * @author Kohsuke Kawaguchi - */ -public class CaptureEnvironmentBuilder extends Builder { - - private EnvVars envVars; - - public EnvVars getEnvVars() { - return envVars; - } - - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - envVars = build.getEnvironment(listener); +@Extension +@Restricted(NoExternalUse.class) +public class AdministrativeMonitorsConfiguration extends GlobalConfiguration { + @Override + public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + for (AdministrativeMonitor am : AdministrativeMonitor.all()) { + try { + boolean disable = !json.getJSONArray("administrativeMonitor").contains(am.id); + am.disable(disable); + } catch (IOException e) { + LOGGER.log(Level.WARNING, "Failed to process form submission for " + am.id, e); + } + } return true; } - @Extension - public static final class DescriptorImpl extends Descriptor { - public Builder newInstance(StaplerRequest req, JSONObject data) { - throw new UnsupportedOperationException(); - } - - public String getDisplayName() { - return "Capture Environment Variables"; - } - } + private static Logger LOGGER = Logger.getLogger(AdministrativeMonitorsConfiguration.class.getName()); } diff --git a/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java b/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java new file mode 100644 index 0000000000000000000000000000000000000000..5d88cf74b97e7526c4b6cc5b9f2570f61d9be947 --- /dev/null +++ b/core/src/main/java/jenkins/management/AdministrativeMonitorsDecorator.java @@ -0,0 +1,143 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Daniel Beck, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.management; + +import hudson.Extension; +import hudson.Functions; +import hudson.diagnosis.ReverseProxySetupMonitor; +import hudson.model.AdministrativeMonitor; +import hudson.model.PageDecorator; +import hudson.util.HttpResponses; +import hudson.util.HudsonIsLoading; +import hudson.util.HudsonIsRestarting; +import jenkins.model.Jenkins; +import net.sf.json.JSON; +import net.sf.json.JSONObject; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.Ancestor; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Show a notification and popup for active administrative monitors on all pages. + */ +@Extension +@Restricted(NoExternalUse.class) +public class AdministrativeMonitorsDecorator extends PageDecorator { + private final Collection ignoredJenkinsRestOfUrls = new ArrayList<>(); + + public AdministrativeMonitorsDecorator() { + // redundant + ignoredJenkinsRestOfUrls.add("manage"); + + // otherwise this would be added to every internal context menu building request + ignoredJenkinsRestOfUrls.add("contextMenu"); + + // don't show here to allow admins to disable malfunctioning monitors via AdministrativeMonitorsDecorator + ignoredJenkinsRestOfUrls.add("configure"); + } + + @Override + public String getDisplayName() { + return Messages.AdministrativeMonitorsDecorator_DisplayName(); + } + + public int getActiveAdministrativeMonitorsCount() { + return getActiveAdministrativeMonitors().size(); + } + + public Collection getActiveAdministrativeMonitors() { + Collection active = new ArrayList<>(); + Collection ams = new ArrayList<>(Jenkins.getInstance().administrativeMonitors); + for (AdministrativeMonitor am : ams) { + if (am instanceof ReverseProxySetupMonitor) { + // TODO make reverse proxy monitor work when shown on any URL + continue; + } + if (am.isEnabled() && am.isActivated()) { + active.add(am); + } + } + return active; + } + + /** + * Whether the administrative monitors notifier should be shown. + * @return true iff the administrative monitors notifier should be shown. + * @throws IOException + * @throws ServletException + */ + public boolean shouldDisplay() throws IOException, ServletException { + if (!Functions.hasPermission(Jenkins.ADMINISTER)) { + return false; + } + + StaplerRequest req = Stapler.getCurrentRequest(); + + if (req == null) { + return false; + } + List ancestors = req.getAncestors(); + + if (ancestors == null || ancestors.size() == 0) { + // ??? + return false; + } + + Ancestor a = ancestors.get(ancestors.size() - 1); + Object o = a.getObject(); + + // don't show while Jenkins is loading + if (o instanceof HudsonIsLoading) { + return false; + } + // … or restarting + if (o instanceof HudsonIsRestarting) { + return false; + } + + // don't show for some URLs served directly by Jenkins + if (o instanceof Jenkins) { + String url = a.getRestOfUrl(); + + if (ignoredJenkinsRestOfUrls.contains(url)) { + return false; + } + } + + if (getActiveAdministrativeMonitorsCount() == 0) { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java b/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java index 766f036bbbb2d99874ca68756be58121cb05d6e5..50d4e6cbebd205c6c30b58cc16d6ea41e586f0f5 100644 --- a/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java +++ b/core/src/main/java/jenkins/management/AsynchronousAdministrativeMonitor.java @@ -8,7 +8,6 @@ import hudson.security.ACL; import hudson.util.StreamTaskListener; import jenkins.model.Jenkins; import jenkins.security.RekeySecretAdminMonitor; -import org.apache.commons.io.output.NullOutputStream; import java.io.File; import java.io.IOException; diff --git a/core/src/main/java/jenkins/management/CliLink.java b/core/src/main/java/jenkins/management/CliLink.java index 4dfd09a86d20ccef9b42c08d082eac22d7324bcb..718504727fc027aba1453dbe24926f338a3644dc 100644 --- a/core/src/main/java/jenkins/management/CliLink.java +++ b/core/src/main/java/jenkins/management/CliLink.java @@ -26,11 +26,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 800) +@Extension(ordinal = Integer.MAX_VALUE - 800) @Symbol("cli") public class CliLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/ConfigureLink.java b/core/src/main/java/jenkins/management/ConfigureLink.java index bc7ab1bc1681fbc588cef7f169b8c0d83dced69e..a10df71b2289b05b13c9486bc44d6cf526591f6f 100644 --- a/core/src/main/java/jenkins/management/ConfigureLink.java +++ b/core/src/main/java/jenkins/management/ConfigureLink.java @@ -26,16 +26,17 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 200) +@Extension(ordinal = Integer.MAX_VALUE - 200) @Symbol("configure") public class ConfigureLink extends ManagementLink { @Override public String getIconFileName() { - return "setting.png"; + return "gear2.png"; } public String getDisplayName() { diff --git a/core/src/main/java/jenkins/management/ConsoleLink.java b/core/src/main/java/jenkins/management/ConsoleLink.java index effa29d799e7b56b521173284d954b6f8f6adb26..edd7c628cc4f7ddc53a438aa4178f7621dd33925 100644 --- a/core/src/main/java/jenkins/management/ConsoleLink.java +++ b/core/src/main/java/jenkins/management/ConsoleLink.java @@ -28,11 +28,12 @@ import hudson.Extension; import hudson.model.ManagementLink; import hudson.security.Permission; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 900) +@Extension(ordinal = Integer.MAX_VALUE - 900) @Symbol("console") public class ConsoleLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/NodesLink.java b/core/src/main/java/jenkins/management/NodesLink.java index 5bff1b525308a8de6e623cef1440cccc4b54f9a2..90038450cebccf98c3a0bc900f7faf0894cd1b3b 100644 --- a/core/src/main/java/jenkins/management/NodesLink.java +++ b/core/src/main/java/jenkins/management/NodesLink.java @@ -27,12 +27,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; import jenkins.management.Messages; -import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 1000) +@Extension(ordinal = Integer.MAX_VALUE - 1000) @Symbol("nodes") public class NodesLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/PluginsLink.java b/core/src/main/java/jenkins/management/PluginsLink.java index 0309d77d4dca0e520fa9209f640ac8d04482358c..cae9c139c45944739db918f2112dec02239e6723 100644 --- a/core/src/main/java/jenkins/management/PluginsLink.java +++ b/core/src/main/java/jenkins/management/PluginsLink.java @@ -26,11 +26,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 400) +@Extension(ordinal = Integer.MAX_VALUE - 400) @Symbol("plugins") public class PluginsLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/ReloadLink.java b/core/src/main/java/jenkins/management/ReloadLink.java index 40da1cc37067100dec91e739cfe63a37badd59ba..9159788379eaa942ce6526f92372bcdc67e8b92a 100644 --- a/core/src/main/java/jenkins/management/ReloadLink.java +++ b/core/src/main/java/jenkins/management/ReloadLink.java @@ -26,11 +26,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 300) +@Extension(ordinal = Integer.MAX_VALUE - 300) @Symbol("reload") public class ReloadLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/ShutdownLink.java b/core/src/main/java/jenkins/management/ShutdownLink.java index 488b2c0e13fe38d6433c9852b552d9bf01f59504..76fb7439e58167971bd3266b46d5a6f13e2106ff 100644 --- a/core/src/main/java/jenkins/management/ShutdownLink.java +++ b/core/src/main/java/jenkins/management/ShutdownLink.java @@ -27,11 +27,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MIN_VALUE) +@Extension(ordinal = Integer.MIN_VALUE) @Symbol("shutDown") public class ShutdownLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/StatisticsLink.java b/core/src/main/java/jenkins/management/StatisticsLink.java index 6ec5536af349b3fc6e80fd559374dee7d8f6c109..9821781d789aea6c19380fc2465e2d58ee32efc3 100644 --- a/core/src/main/java/jenkins/management/StatisticsLink.java +++ b/core/src/main/java/jenkins/management/StatisticsLink.java @@ -26,11 +26,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 700) +@Extension(ordinal = Integer.MAX_VALUE - 700) @Symbol("loadStatistics") public class StatisticsLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/SystemInfoLink.java b/core/src/main/java/jenkins/management/SystemInfoLink.java index 9f36eb6962a0c0ede5fe43004f68dd836760cc59..c45ce41de8ee11b2980af509993ffe744f4ae4ed 100644 --- a/core/src/main/java/jenkins/management/SystemInfoLink.java +++ b/core/src/main/java/jenkins/management/SystemInfoLink.java @@ -26,11 +26,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 500) +@Extension(ordinal = Integer.MAX_VALUE - 500) @Symbol("systemInfo") public class SystemInfoLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/management/SystemLogLink.java b/core/src/main/java/jenkins/management/SystemLogLink.java index 88c832d2e233b20fbcc92ab148e382e9a60da3eb..1ee08aca008033733607d5b891f3da1112e87a30 100644 --- a/core/src/main/java/jenkins/management/SystemLogLink.java +++ b/core/src/main/java/jenkins/management/SystemLogLink.java @@ -26,11 +26,12 @@ package jenkins.management; import hudson.Extension; import hudson.model.ManagementLink; +import org.jenkinsci.Symbol; /** * @author Nicolas De Loof */ -@Extension(ordinal = Integer.MAX_VALUE - 600) +@Extension(ordinal = Integer.MAX_VALUE - 600) @Symbol("log") public class SystemLogLink extends ManagementLink { @Override diff --git a/core/src/main/java/jenkins/model/ArtifactManager.java b/core/src/main/java/jenkins/model/ArtifactManager.java index bb5fde97e2fe250e1f99396bea55b1b9241f95fb..eeca67143c5d3debbfaec7bcf9f053d4963acea7 100644 --- a/core/src/main/java/jenkins/model/ArtifactManager.java +++ b/core/src/main/java/jenkins/model/ArtifactManager.java @@ -26,7 +26,6 @@ package jenkins.model; import hudson.FilePath; import hudson.Launcher; -import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.Run; import hudson.model.TaskListener; diff --git a/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java b/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java index c2bb1135dddf43c58c63b81ba562aeea29202a96..43f98aae8dbbb53afd121a5046f67391594e0a13 100644 --- a/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java +++ b/core/src/main/java/jenkins/model/ArtifactManagerConfiguration.java @@ -28,13 +28,14 @@ import hudson.Extension; import hudson.util.DescribableList; import java.io.IOException; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; /** * List of configured {@link ArtifactManagerFactory}s. * @since 1.532 */ -@Extension +@Extension @Symbol("artifactManager") public class ArtifactManagerConfiguration extends GlobalConfiguration { public static ArtifactManagerConfiguration get() { diff --git a/core/src/main/java/jenkins/model/ArtifactManagerFactory.java b/core/src/main/java/jenkins/model/ArtifactManagerFactory.java index f0d08c4e05ef35fc59879803cc236c4fdf85e7a3..efff30c5654d5d04791accb5f6affdc72e88c3b5 100644 --- a/core/src/main/java/jenkins/model/ArtifactManagerFactory.java +++ b/core/src/main/java/jenkins/model/ArtifactManagerFactory.java @@ -45,7 +45,7 @@ public abstract class ArtifactManagerFactory extends AbstractDescribableImpl build); diff --git a/core/src/main/java/jenkins/model/AssetManager.java b/core/src/main/java/jenkins/model/AssetManager.java new file mode 100644 index 0000000000000000000000000000000000000000..f6308e631da23859109416b4d40575d72cc664e0 --- /dev/null +++ b/core/src/main/java/jenkins/model/AssetManager.java @@ -0,0 +1,115 @@ +package jenkins.model; + +import hudson.Extension; +import hudson.model.UnprotectedRootAction; +import hudson.util.TimeUnit2; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.Enumeration; + +/** + * Serves files located in the {@code /assets} classpath directory via the Jenkins core ClassLoader. + * e.g. the URL {@code /assets/jquery-detached/jsmodules/jquery2.js} will load {@code jquery-detached/jsmodules/jquery2.js} + * resource from the classpath below {@code /assets}. + * + * @author Kohsuke Kawaguchi + * + * @since 2.0 + */ +@Extension @Symbol("assetManager") +public class AssetManager implements UnprotectedRootAction { + + // not shown in the UI + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getUrlName() { + return "assets"; + } + + /** + * Exposes assets in the core classloader over HTTP. + */ + public void doDynamic(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + String path = req.getRestOfPath(); + URL resource = findResource(path); + + if (resource == null) { + rsp.setStatus(HttpServletResponse.SC_NOT_FOUND); + return; + } + + // Stapler routes requests like the "/static/.../foo/bar/zot" to be treated like "/foo/bar/zot" + // and this is used to serve long expiration header, by using Jenkins.VERSION_HASH as "..." + // to create unique URLs. Recognize that and set a long expiration header. + String requestPath = req.getRequestURI().substring(req.getContextPath().length()); + boolean staticLink = requestPath.startsWith("/static/"); + long expires = staticLink ? TimeUnit2.DAYS.toMillis(365) : -1; + + // use serveLocalizedFile to support automatic locale selection + rsp.serveLocalizedFile(req, resource, expires); + } + + /** + * Locates the asset from the classloader. + * + *

    + * To allow plugins to bring its own assets without worrying about colliding with the assets in core, + * look for child classloader first. But to support plugins that get split, if the child classloader + * doesn't find it, fall back to the parent classloader. + */ + private URL findResource(String path) throws IOException { + try { + if (path.contains("..")) // crude avoidance of directory traversal attack + throw new IllegalArgumentException(path); + + String name; + if (path.charAt(0) == '/') { + name = "assets" + path; + } else { + name = "assets/" + path; + } + + ClassLoader cl = Jenkins.class.getClassLoader(); + URL url = (URL) $findResource.invoke(cl, name); + if (url==null) { + // pick the last one, which is the one closest to the leaf of the classloader tree. + Enumeration e = cl.getResources(name); + while (e.hasMoreElements()) { + url = e.nextElement(); + } + } + return url; + } catch (InvocationTargetException|IllegalAccessException e) { + throw new Error(e); + } + } + + private static final Method $findResource = init(); + + private static Method init() { + try { + Method m = ClassLoader.class.getDeclaredMethod("findResource", String.class); + m.setAccessible(true); + return m; + } catch (NoSuchMethodException e) { + throw (Error)new NoSuchMethodError().initCause(e); + } + } +} diff --git a/core/src/main/java/jenkins/model/BlockedBecauseOfBuildInProgress.java b/core/src/main/java/jenkins/model/BlockedBecauseOfBuildInProgress.java new file mode 100644 index 0000000000000000000000000000000000000000..9abdd8fa8870cf5017392392852d167e5822e794 --- /dev/null +++ b/core/src/main/java/jenkins/model/BlockedBecauseOfBuildInProgress.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright 2015 Jesse Glick. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model; + +import hudson.model.Executor; +import hudson.model.Job; +import hudson.model.Run; +import hudson.model.queue.CauseOfBlockage; +import javax.annotation.Nonnull; + +/** + * Indicates that a new build is blocked because the previous build is already in progress. + * Useful for implementing {@link hudson.model.Queue.Task#getCauseOfBlockage} from a {@link Job} which supports {@link hudson.model.Queue.Task#isConcurrentBuild}. + * @since 1.624 + */ +public class BlockedBecauseOfBuildInProgress extends CauseOfBlockage { + + @Nonnull + private final Run build; + + /** + * Creates a cause for the specified build. + * @param build Build, which is already in progress + */ + public BlockedBecauseOfBuildInProgress(@Nonnull Run build) { + this.build = build; + } + + @Override public String getShortDescription() { + Executor e = build.getExecutor(); + String eta = ""; + if (e != null) { + eta = Messages.BlockedBecauseOfBuildInProgress_ETA(e.getEstimatedRemainingTime()); + } + int lbn = build.getNumber(); + return Messages.BlockedBecauseOfBuildInProgress_shortDescription(lbn, eta); + } + +} diff --git a/core/src/main/java/jenkins/model/BuildDiscarder.java b/core/src/main/java/jenkins/model/BuildDiscarder.java index 72e6552aa9da40251d2557c301b0927bf2b97abf..8e4c3abadc57c506a42e8957f59151223106fdf2 100644 --- a/core/src/main/java/jenkins/model/BuildDiscarder.java +++ b/core/src/main/java/jenkins/model/BuildDiscarder.java @@ -9,7 +9,6 @@ import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.mapper.Mapper; import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; -import hudson.model.AbstractProject; import hudson.model.Job; import hudson.model.Run; import hudson.tasks.LogRotator; diff --git a/core/src/main/java/jenkins/model/BuildDiscarderProperty.java b/core/src/main/java/jenkins/model/BuildDiscarderProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..9231fb40bd9fb78f54194317df8853d1a9965c90 --- /dev/null +++ b/core/src/main/java/jenkins/model/BuildDiscarderProperty.java @@ -0,0 +1,81 @@ +/* + * The MIT License + * + * Copyright 2015 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model; + +import hudson.Extension; +import hudson.model.Descriptor; +import hudson.model.DescriptorVisibilityFilter; +import hudson.model.Items; +import hudson.model.Job; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; + +/** + * Defines a {@link BuildDiscarder}. + * @since 1.637 + */ +public class BuildDiscarderProperty extends OptionalJobProperty> { + + private final BuildDiscarder strategy; + + @DataBoundConstructor + public BuildDiscarderProperty(BuildDiscarder strategy) { + this.strategy = strategy; + } + + public BuildDiscarder getStrategy() { + return strategy; + } + + @Extension + @Symbol("buildDiscarder") + public static class DescriptorImpl extends OptionalJobPropertyDescriptor { + + @Override + public String getDisplayName() { + return Messages.BuildDiscarderProperty_displayName(); + } + + static { + Items.XSTREAM2.addCompatibilityAlias("org.jenkinsci.plugins.workflow.job.properties.BuildDiscarderProperty", BuildDiscarderProperty.class); + } + + } + + @Extension + public static class ConditionallyHidden extends DescriptorVisibilityFilter { + + @SuppressWarnings("rawtypes") + @Override + public boolean filter(Object context, Descriptor descriptor) { + if (descriptor instanceof DescriptorImpl && context instanceof Job) { + return ((Job) context).supportsLogRotator(); + } + return true; + } + + } + +} diff --git a/core/src/main/java/jenkins/model/CauseOfInterruption.java b/core/src/main/java/jenkins/model/CauseOfInterruption.java index d733ffe33eabcb6480b679ecde34a0beaebad5c2..7a8c173f212198258c2327347490a1c2a8229636 100644 --- a/core/src/main/java/jenkins/model/CauseOfInterruption.java +++ b/core/src/main/java/jenkins/model/CauseOfInterruption.java @@ -25,13 +25,15 @@ package jenkins.model; import hudson.console.ModelHyperlinkNote; import hudson.model.Executor; -import hudson.model.Result; import hudson.model.TaskListener; import hudson.model.User; import org.kohsuke.stapler.export.Exported; import org.kohsuke.stapler.export.ExportedBean; import java.io.Serializable; +import java.util.Collections; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; /** * Records why an {@linkplain Executor#interrupt() executor is interrupted}. @@ -70,21 +72,50 @@ public abstract class CauseOfInterruption implements Serializable { } /** - * Indicates that the build was interrupted from UI by an user. + * Indicates that the build was interrupted from UI. */ public static final class UserInterruption extends CauseOfInterruption { + + @Nonnull private final String user; - public UserInterruption(User user) { + public UserInterruption(@Nonnull User user) { this.user = user.getId(); } - public UserInterruption(String userId) { + public UserInterruption(@Nonnull String userId) { this.user = userId; } + /** + * Gets ID of the user, who interrupted the build. + * @return User ID + * @since 2.31 + */ + @Nonnull + public String getUserId() { + return user; + } + + /** + * Gets user, who caused the interruption. + * @return User instance if it can be located. + * Result of {@link User#getUnknown()} otherwise + */ + @Nonnull public User getUser() { - return User.get(user); + final User userInstance = getUserOrNull(); + return userInstance != null ? userInstance : User.getUnknown(); + } + + /** + * Gets user, who caused the interruption. + * @return User or {@code null} if it has not been found + * @since 2.31 + */ + @CheckForNull + public User getUserOrNull() { + return User.get(user, false, Collections.emptyMap()); } public String getShortDescription() { @@ -93,8 +124,10 @@ public abstract class CauseOfInterruption implements Serializable { @Override public void print(TaskListener listener) { + final User userInstance = getUser(); listener.getLogger().println( - Messages.CauseOfInterruption_ShortDescription(ModelHyperlinkNote.encodeTo(getUser()))); + Messages.CauseOfInterruption_ShortDescription( + userInstance != null ? ModelHyperlinkNote.encodeTo(userInstance) : user)); } @Override @@ -112,32 +145,5 @@ public abstract class CauseOfInterruption implements Serializable { private static final long serialVersionUID = 1L; } - /** - * Indicates that the build was interrupted as a result of another a problem. - * - *

    - * This is a less specific (thus less desirable) {@link CauseOfInterruption} - * in case there's no suitable {@link CauseOfInterruption}. Use sparingly. - */ - class ExceptionInterruption extends CauseOfInterruption { - private final Throwable cause; - - public ExceptionInterruption(Throwable cause) { - this.cause = cause; - } - - public Throwable getCause() { - return cause; - } - - @Override - public String getShortDescription() { - return "Exception: "+ cause.getMessage(); - } - - private static final long serialVersionUID = 1L; - } - - private static final long serialVersionUID = 1L; } diff --git a/core/src/main/java/jenkins/model/Configuration.java b/core/src/main/java/jenkins/model/Configuration.java index 9de56f968c27a88f2bccea090c57429f65fc463c..8b4cea7ac7fa7f257044bc90a76b9dac55faad24 100644 --- a/core/src/main/java/jenkins/model/Configuration.java +++ b/core/src/main/java/jenkins/model/Configuration.java @@ -23,6 +23,7 @@ */ package jenkins.model; +import jenkins.util.SystemProperties; import hudson.model.Hudson; @@ -34,9 +35,9 @@ public class Configuration { } public static String getStringConfigParameter(String name, String defaultValue) { - String value = System.getProperty(Jenkins.class.getName()+"." + name); + String value = SystemProperties.getString(Jenkins.class.getName()+"." + name); if( value == null ) - value = System.getProperty(Hudson.class.getName()+"." + name); + value = SystemProperties.getString(Hudson.class.getName()+"." + name); return (value==null)?defaultValue:value; } } diff --git a/core/src/main/java/jenkins/model/CoreEnvironmentContributor.java b/core/src/main/java/jenkins/model/CoreEnvironmentContributor.java index 5c58a90e82299c6b73791be555007a655161d914..86ba69eb58d85cd8e26e40bb052563e849bab3bc 100644 --- a/core/src/main/java/jenkins/model/CoreEnvironmentContributor.java +++ b/core/src/main/java/jenkins/model/CoreEnvironmentContributor.java @@ -11,6 +11,7 @@ import hudson.model.Node; import hudson.model.Run; import hudson.model.TaskListener; import jenkins.model.Jenkins.MasterComputer; +import org.jenkinsci.Symbol; import java.io.IOException; @@ -20,7 +21,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=-100) +@Extension(ordinal=-100) @Symbol("core") public class CoreEnvironmentContributor extends EnvironmentContributor { @Override public void buildEnvironmentFor(Run r, EnvVars env, TaskListener listener) throws IOException, InterruptedException { diff --git a/core/src/main/java/jenkins/model/DependencyDeclarer.java b/core/src/main/java/jenkins/model/DependencyDeclarer.java index a6cb2c52c61ee54787d5101ade9927a44caf61a7..5d53d472685b7e546e74db064a477f66c5e2fbe4 100644 --- a/core/src/main/java/jenkins/model/DependencyDeclarer.java +++ b/core/src/main/java/jenkins/model/DependencyDeclarer.java @@ -29,7 +29,6 @@ import hudson.tasks.BuildWrapper; import hudson.tasks.Builder; import hudson.tasks.Publisher; import hudson.triggers.Trigger; -import hudson.util.DescribableList; /** * Marker interface for project-associated objects that can participate diff --git a/core/src/main/java/jenkins/model/DirectlyModifiableTopLevelItemGroup.java b/core/src/main/java/jenkins/model/DirectlyModifiableTopLevelItemGroup.java index f08d3f3faf0249883baaa70c51631a240e700460..1d80e5d7b068460c2590cd9f9cc89cc7c2bfb653 100644 --- a/core/src/main/java/jenkins/model/DirectlyModifiableTopLevelItemGroup.java +++ b/core/src/main/java/jenkins/model/DirectlyModifiableTopLevelItemGroup.java @@ -24,9 +24,7 @@ package jenkins.model; -import hudson.model.Item; import hudson.model.TopLevelItem; -import hudson.model.listeners.ItemListener; import java.io.IOException; /** diff --git a/core/src/main/java/jenkins/model/DownloadSettings.java b/core/src/main/java/jenkins/model/DownloadSettings.java index e16898ab86dc83dc6816f31c744f860c91376e8c..e4c78c2ef3fe1cc54270b6b55caa895733745052 100644 --- a/core/src/main/java/jenkins/model/DownloadSettings.java +++ b/core/src/main/java/jenkins/model/DownloadSettings.java @@ -29,16 +29,18 @@ import hudson.Main; import hudson.model.AdministrativeMonitor; import hudson.model.AsyncPeriodicWork; import hudson.model.DownloadService; +import hudson.model.DownloadService.Downloadable; import hudson.model.TaskListener; import hudson.model.UpdateSite; import hudson.util.FormValidation; import java.io.IOException; -import net.sf.json.JSONObject; +import java.util.logging.Level; +import java.util.logging.Logger; import org.acegisecurity.AccessDeniedException; +import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.stapler.HttpResponse; -import org.kohsuke.stapler.StaplerRequest; /** * Lets user configure how metadata files should be downloaded. @@ -46,7 +48,8 @@ import org.kohsuke.stapler.StaplerRequest; * @see DownloadService */ @Restricted(NoExternalUse.class) // no clear reason for this to be an API -@Extension public final class DownloadSettings extends GlobalConfiguration { +@Extension @Symbol("downloadSettings") +public final class DownloadSettings extends GlobalConfiguration { public static DownloadSettings get() { return Jenkins.getInstance().getInjector().getInstance(DownloadSettings.class); @@ -58,11 +61,6 @@ import org.kohsuke.stapler.StaplerRequest; load(); } - @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { - req.bindJSON(this, json); - return true; - } - public boolean isUseBrowser() { return useBrowser; } @@ -87,7 +85,9 @@ import org.kohsuke.stapler.StaplerRequest; Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER); } - @Extension public static final class DailyCheck extends AsyncPeriodicWork { + @Extension @Symbol("updateCenterCheck") + public static final class DailyCheck extends AsyncPeriodicWork { + private static final Logger LOGGER = Logger.getLogger(DailyCheck.class.getName()); public DailyCheck() { super("Download metadata"); @@ -113,8 +113,21 @@ import org.kohsuke.stapler.StaplerRequest; } } if (!due) { + // JENKINS-32886: downloadables like the tool installer data may have never been tried if the plugin + // was installed "after a restart", so let's give them a try here. + final long now = System.currentTimeMillis(); + for (Downloadable d : Downloadable.all()) { + if (d.getDue() <= now) { + try { + d.updateNow(); + } catch(Exception e) { + LOGGER.log(Level.WARNING, String.format("Unable to update downloadable [%s]", d.getId()), e); + } + } + } return; } + // This checks updates of the update sites and downloadables. HttpResponse rsp = Jenkins.getInstance().getPluginManager().doCheckUpdatesServer(); if (rsp instanceof FormValidation) { listener.error(((FormValidation) rsp).renderHtml()); @@ -125,6 +138,11 @@ import org.kohsuke.stapler.StaplerRequest; @Extension public static final class Warning extends AdministrativeMonitor { + @Override + public String getDisplayName() { + return Messages.DownloadSettings_Warning_DisplayName(); + } + @Override public boolean isActivated() { return DownloadSettings.get().isUseBrowser(); } diff --git a/core/src/main/java/jenkins/model/GlobalCloudConfiguration.java b/core/src/main/java/jenkins/model/GlobalCloudConfiguration.java index afe4c97ba65978dcf71cc6b8dbe05978d5609799..a4aa432e20765e28010cbed48405bf95dbef72f2 100644 --- a/core/src/main/java/jenkins/model/GlobalCloudConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalCloudConfiguration.java @@ -3,6 +3,7 @@ package jenkins.model; import hudson.Extension; import hudson.slaves.Cloud; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -15,7 +16,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=-100) // historically this was placed at the very end of the configuration page +@Extension(ordinal=-100) @Symbol("cloud") // historically this was placed at the very end of the configuration page public class GlobalCloudConfiguration extends GlobalConfiguration { @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { diff --git a/core/src/main/java/jenkins/model/GlobalConfiguration.java b/core/src/main/java/jenkins/model/GlobalConfiguration.java index 92eabc4ea7b7f52638204f01a4ae268f39d0cfe8..f751404bed11274f520ea1037a00775b0d763f1c 100644 --- a/core/src/main/java/jenkins/model/GlobalConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalConfiguration.java @@ -4,6 +4,8 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Describable; import hudson.model.Descriptor; +import net.sf.json.JSONObject; +import org.kohsuke.stapler.StaplerRequest; /** * Convenient base class for extensions that contributes to the system configuration page but nothing @@ -12,8 +14,8 @@ import hudson.model.Descriptor; *

    * All {@link Descriptor}s are capable of contributing fragment to the system config page. If you are * implementing other extension points that need to expose some global configuration, you can do so - * with global.groovy or global.jelly from your {@link Descriptor} instance. However - * each global.* file will appear as its own section in the global configuration page. + * with {@code global.groovy} or {@code global.jelly} from your {@link Descriptor} instance. However + * each {@code global.*} file will appear as its own section in the global configuration page. * *

    * An option to present a single section for your plugin in the Jenkins global configuration page is @@ -21,14 +23,20 @@ import hudson.model.Descriptor; * properties defined in your GlobalConfiguration subclass, here are two possibilities: *

    • @{@link javax.inject.Inject} into your other {@link hudson.Extension}s (so this does not work * for classes not annotated with {@link hudson.Extension})
    • - *
    • access it via a call to GlobalConfiguration.all().get(<your GlobalConfiguration subclass>.class) - *
    + *
  • access it via a call to {@code GlobalConfiguration.all().get(.class)}
+ * + *

+ * While an implementation might store its actual configuration data in various ways, + * meaning {@link #configure(StaplerRequest, JSONObject)} must be overridden, + * in the normal case you would simply define persistable fields with getters and setters. + * The {@code config} view would use data-bound controls like {@code f:entry}. + * Then make sure your constructor calls {@link #load} and your setters call {@link #save}. * *

Views

*

- * Subtypes of this class should define a config.groovy file or config.jelly file + * Subtypes of this class should define a {@code config.groovy} file or {@code config.jelly} file * that gets pulled into the system configuration page. - * + * Typically its contents should be wrapped in an {@code f:section}. * * @author Kohsuke Kawaguchi * @since 1.425 @@ -42,26 +50,20 @@ public abstract class GlobalConfiguration extends Descriptor{@inheritDoc} */ - public String getDisplayName() { - return ""; - } - @Override - public String getGlobalConfigPage() { - return getConfigPage(); + public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + req.bindJSON(this, json); + return true; } /** diff --git a/core/src/main/java/jenkins/model/GlobalConfigurationCategory.java b/core/src/main/java/jenkins/model/GlobalConfigurationCategory.java index f78c1eb3f9be8d6993a984c8827154bbdada7f55..d46329a404882bfff7d5505cb7509fe51a60c97b 100644 --- a/core/src/main/java/jenkins/model/GlobalConfigurationCategory.java +++ b/core/src/main/java/jenkins/model/GlobalConfigurationCategory.java @@ -6,6 +6,7 @@ import hudson.ExtensionPoint; import hudson.model.ModelObject; import hudson.security.*; import hudson.security.Messages; +import org.jenkinsci.Symbol; /** * Grouping of related {@link GlobalConfiguration}s. @@ -54,7 +55,7 @@ public abstract class GlobalConfigurationCategory implements ExtensionPoint, Mod * * In the current UI, this corresponds to the /configure link. */ - @Extension + @Extension @Symbol("unclassified") public static class Unclassified extends GlobalConfigurationCategory { @Override public String getShortDescription() { @@ -69,15 +70,16 @@ public abstract class GlobalConfigurationCategory implements ExtensionPoint, Mod /** * Security related configurations. */ - @Extension + @Extension @Symbol("security") public static class Security extends GlobalConfigurationCategory { @Override public String getShortDescription() { - return Messages.GlobalSecurityConfiguration_Description(); + return hudson.security.Messages.GlobalSecurityConfiguration_Description(); } public String getDisplayName() { return hudson.security.Messages.GlobalSecurityConfiguration_DisplayName(); } } + } diff --git a/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java b/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java index 97956794062444cc3cc11cf17d4209baf4f1e04e..68bfc2bf0127c96a330964f06e5f988fb3e35635 100644 --- a/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalNodePropertiesConfiguration.java @@ -4,6 +4,7 @@ import hudson.Extension; import hudson.slaves.NodeProperty; import hudson.slaves.NodePropertyDescriptor; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -13,7 +14,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=110) // historically this was placed above GlobalPluginConfiguration +@Extension(ordinal=110) @Symbol("nodeProperties") // historically this was placed above GlobalPluginConfiguration public class GlobalNodePropertiesConfiguration extends GlobalConfiguration { @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { diff --git a/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java b/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java index fd0c57dc3ced71a7cd3075b3ea9dd91f8bac8883..a706573c0782ef2fee4c43899b1218abb93719a4 100644 --- a/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalPluginConfiguration.java @@ -4,6 +4,7 @@ import hudson.Extension; import hudson.Plugin; import hudson.StructuredForm; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import javax.servlet.ServletException; @@ -17,7 +18,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=100) // historically this was placed above general configuration from arbitrary descriptors +@Extension(ordinal=100) @Symbol("plugin") // historically this was placed above general configuration from arbitrary descriptors public class GlobalPluginConfiguration extends GlobalConfiguration { @Override public boolean configure(StaplerRequest req, JSONObject json) throws FormException { @@ -25,9 +26,7 @@ public class GlobalPluginConfiguration extends GlobalConfiguration { for( JSONObject o : StructuredForm.toList(json, "plugin")) Jenkins.getInstance().pluginManager.getPlugin(o.getString("name")).getPlugin().configure(req, o); return true; - } catch (IOException e) { - throw new FormException(e,"plugin"); - } catch (ServletException e) { + } catch (IOException | ServletException e) { throw new FormException(e,"plugin"); } } diff --git a/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java b/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java index 9289a23f1b559aefba66473f7e7e763fc0c6984e..ca07798af16ff9462546b704a6a7936f0da6e2ee 100644 --- a/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalProjectNamingStrategyConfiguration.java @@ -27,6 +27,7 @@ import hudson.Extension; import jenkins.model.ProjectNamingStrategy.DefaultProjectNamingStrategy; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; /** @@ -34,7 +35,7 @@ import org.kohsuke.stapler.StaplerRequest; * * @author Dominik Bartholdi (imod) */ -@Extension(ordinal = 250) +@Extension(ordinal = 250) @Symbol("projectNamingStrategy") public class GlobalProjectNamingStrategyConfiguration extends GlobalConfiguration { @Override diff --git a/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java b/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java index 36ee9c0e1ad41e3205ae48e3bf5cc1cc5f9ee53a..cf1001793ac53d3d4e4fe4fc036980388852ae29 100644 --- a/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalQuietPeriodConfiguration.java @@ -25,6 +25,7 @@ package jenkins.model; import hudson.Extension; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -34,7 +35,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=400) +@Extension(ordinal=400) @Symbol("quietPeriod") public class GlobalQuietPeriodConfiguration extends GlobalConfiguration { public int getQuietPeriod() { return Jenkins.getInstance().getQuietPeriod(); diff --git a/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java b/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java index d364b6fbe8d14549f5d306cd9bb9233cfd214db0..3e4d3afafa3a28d92c56f776755d7e2bbdbb8698 100644 --- a/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java +++ b/core/src/main/java/jenkins/model/GlobalSCMRetryCountConfiguration.java @@ -24,7 +24,9 @@ package jenkins.model; import hudson.Extension; +import net.sf.json.JSONException; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -34,7 +36,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=395) +@Extension(ordinal=395) @Symbol("scmRetryCount") public class GlobalSCMRetryCountConfiguration extends GlobalConfiguration { public int getScmCheckoutRetryCount() { return Jenkins.getInstance().getScmCheckoutRetryCount(); @@ -48,6 +50,8 @@ public class GlobalSCMRetryCountConfiguration extends GlobalConfiguration { return true; } catch (IOException e) { throw new FormException(e,"quietPeriod"); + } catch (JSONException e) { + throw new FormException(e.getMessage(), "quietPeriod"); } } -} \ No newline at end of file +} diff --git a/core/src/main/java/jenkins/model/IdStrategy.java b/core/src/main/java/jenkins/model/IdStrategy.java index 8ccf691898e2eafe9e17f0476256201ff425356b..f3f37186b7dec43d5187fe135278ddefe56228ec 100644 --- a/core/src/main/java/jenkins/model/IdStrategy.java +++ b/core/src/main/java/jenkins/model/IdStrategy.java @@ -29,6 +29,7 @@ import hudson.ExtensionPoint; import hudson.model.AbstractDescribableImpl; import hudson.util.CaseInsensitiveComparator; import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import javax.annotation.Nonnull; @@ -161,6 +162,7 @@ public abstract class IdStrategy extends AbstractDescribableImpl imp /** * {@inheritDoc} */ + @Override @Nonnull public String keyFor(@Nonnull String id) { return id.toLowerCase(Locale.ENGLISH); @@ -174,7 +176,7 @@ public abstract class IdStrategy extends AbstractDescribableImpl imp return CaseInsensitiveComparator.INSTANCE.compare(id1, id2); } - @Extension + @Extension @Symbol("caseInsensitive") public static class DescriptorImpl extends IdStrategyDescriptor { /** @@ -288,6 +290,7 @@ public abstract class IdStrategy extends AbstractDescribableImpl imp /** * {@inheritDoc} */ + @Override @Nonnull public String keyFor(@Nonnull String id) { return id; @@ -301,7 +304,7 @@ public abstract class IdStrategy extends AbstractDescribableImpl imp return id1.compareTo(id2); } - @Extension + @Extension @Symbol("caseSensitive") public static class DescriptorImpl extends IdStrategyDescriptor { /** @@ -348,6 +351,7 @@ public abstract class IdStrategy extends AbstractDescribableImpl imp /** * {@inheritDoc} */ + @Override @Nonnull public String keyFor(@Nonnull String id) { int index = id.lastIndexOf('@'); // The @ can be used in local-part if quoted correctly diff --git a/core/src/main/java/jenkins/model/InterruptedBuildAction.java b/core/src/main/java/jenkins/model/InterruptedBuildAction.java index b5f9c6b6f5654f8f05a96daa352f23a7e2cad3f8..c734d58bbb3033bc587e2bddaebe01fff450fbd7 100644 --- a/core/src/main/java/jenkins/model/InterruptedBuildAction.java +++ b/core/src/main/java/jenkins/model/InterruptedBuildAction.java @@ -43,7 +43,7 @@ public class InterruptedBuildAction extends InvisibleAction { private final List causes; public InterruptedBuildAction(Collection causes) { - this.causes = ImmutableList.copyOf(causes); + this.causes = ImmutableList.copyOf(causes); } @Exported diff --git a/core/src/main/java/jenkins/model/Jenkins.java b/core/src/main/java/jenkins/model/Jenkins.java index 585717288fcbbe14f66f7fa8ba420fd650a60a4b..7c61deebdd87a01b4ca54421130e25fd0baa1ea3 100644 --- a/core/src/main/java/jenkins/model/Jenkins.java +++ b/core/src/main/java/jenkins/model/Jenkins.java @@ -28,7 +28,9 @@ package jenkins.model; import antlr.ANTLRException; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.inject.Inject; import com.google.inject.Injector; import com.thoughtworks.xstream.XStream; import hudson.BulkChange; @@ -43,12 +45,14 @@ import hudson.FilePath; import hudson.Functions; import hudson.Launcher; import hudson.Launcher.LocalLauncher; -import hudson.LocalPluginManager; import hudson.Lookup; +import hudson.Main; import hudson.Plugin; import hudson.PluginManager; import hudson.PluginWrapper; import hudson.ProxyConfiguration; +import jenkins.AgentProtocol; +import jenkins.util.SystemProperties; import hudson.TcpSlaveAgentListener; import hudson.UDPBroadcastThread; import hudson.Util; @@ -58,6 +62,7 @@ import hudson.cli.declarative.CLIMethod; import hudson.cli.declarative.CLIResolver; import hudson.init.InitMilestone; import hudson.init.InitStrategy; +import hudson.init.TermMilestone; import hudson.init.TerminatorFinder; import hudson.lifecycle.Lifecycle; import hudson.lifecycle.RestartNotSupportedException; @@ -146,7 +151,6 @@ import hudson.security.csrf.CrumbIssuer; import hudson.slaves.Cloud; import hudson.slaves.ComputerListener; import hudson.slaves.DumbSlave; -import hudson.slaves.EphemeralNode; import hudson.slaves.NodeDescriptor; import hudson.slaves.NodeList; import hudson.slaves.NodeProperty; @@ -178,6 +182,7 @@ import hudson.util.JenkinsReloadFailed; import hudson.util.Memoizer; import hudson.util.MultipartFormDataParser; import hudson.util.NamingThreadFactory; +import hudson.util.PluginServletFilter; import hudson.util.RemotingDiagnostics; import hudson.util.RemotingDiagnostics.HeapDump; import hudson.util.TextFile; @@ -189,17 +194,28 @@ import hudson.views.DefaultViewsTabBar; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; import hudson.widgets.Widget; + +import java.util.Objects; +import java.util.TimerTask; +import java.util.concurrent.CountDownLatch; import jenkins.ExtensionComponentSet; import jenkins.ExtensionRefreshException; import jenkins.InitReactorRunner; +import jenkins.install.InstallState; +import jenkins.install.InstallUtil; +import jenkins.install.SetupWizard; import jenkins.model.ProjectNamingStrategy.DefaultProjectNamingStrategy; import jenkins.security.ConfidentialKey; import jenkins.security.ConfidentialStore; import jenkins.security.SecurityListener; import jenkins.security.MasterToSlaveCallable; import jenkins.slaves.WorkspaceLocator; +import jenkins.util.JenkinsJVM; import jenkins.util.Timer; import jenkins.util.io.FileBoolean; +import jenkins.util.io.OnMaster; +import jenkins.util.xml.XMLUtils; +import net.jcip.annotations.GuardedBy; import net.sf.json.JSONObject; import org.acegisecurity.AccessDeniedException; import org.acegisecurity.AcegiSecurityException; @@ -213,8 +229,10 @@ import org.apache.commons.jelly.JellyException; import org.apache.commons.jelly.Script; import org.apache.commons.logging.LogFactory; import org.jvnet.hudson.reactor.Executable; +import org.jvnet.hudson.reactor.Milestone; import org.jvnet.hudson.reactor.Reactor; import org.jvnet.hudson.reactor.ReactorException; +import org.jvnet.hudson.reactor.ReactorListener; import org.jvnet.hudson.reactor.Task; import org.jvnet.hudson.reactor.TaskBuilder; import org.jvnet.hudson.reactor.TaskGraphBuilder; @@ -222,7 +240,6 @@ import org.jvnet.hudson.reactor.TaskGraphBuilder.Handle; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; import org.kohsuke.args4j.Argument; -import org.kohsuke.args4j.Option; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; @@ -288,16 +305,17 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; import static hudson.Util.*; import static hudson.init.InitMilestone.*; +import hudson.init.Initializer; import hudson.util.LogTaskListener; import static java.util.logging.Level.*; import static javax.servlet.http.HttpServletResponse.*; +import org.kohsuke.stapler.WebMethod; /** * Root object of the system. @@ -307,7 +325,7 @@ import static javax.servlet.http.HttpServletResponse.*; @ExportedBean public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLevelItemGroup, StaplerProxy, StaplerFallback, ModifiableViewGroup, AccessControlled, DescriptorByNameOwner, - ModelObjectWithContextMenu, ModelObjectWithChildren { + ModelObjectWithContextMenu, ModelObjectWithChildren, OnMaster { private transient final Queue queue; /** @@ -329,6 +347,17 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve // this field needs to be at the very top so that other components can look at this value even during unmarshalling private String version = "1.0"; + /** + * The Jenkins instance startup type i.e. NEW, UPGRADE etc + */ + private transient InstallState installState = InstallState.UNKNOWN; + + /** + * If we're in the process of an initial setup, + * this will be set + */ + private transient SetupWizard setupWizard; + /** * Number of executors of the master node. */ @@ -431,8 +460,10 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve private transient volatile boolean isQuietingDown; private transient volatile boolean terminating; + @GuardedBy("Jenkins.class") + private transient boolean cleanUpStarted; - private List jdks = new ArrayList(); + private volatile List jdks = new ArrayList(); private transient volatile DependencyGraph dependencyGraph; private final transient AtomicBoolean dependencyGraphDirty = new AtomicBoolean(); @@ -552,6 +583,8 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve public transient volatile TcpSlaveAgentListener tcpSlaveAgentListener; + private transient final Object tcpSlaveAgentListenerLock = new Object(); + private transient UDPBroadcastThread udpBroadcastThread; private transient DNSMultiCast dnsMultiCast; @@ -562,10 +595,57 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve private transient final CopyOnWriteList scmListeners = new CopyOnWriteList(); /** - * TCP slave agent port. + * TCP agent port. * 0 for random, -1 to disable. */ - private int slaveAgentPort =0; + private int slaveAgentPort = getSlaveAgentPortInitialValue(0); + + private static int getSlaveAgentPortInitialValue(int def) { + return SystemProperties.getInteger(Jenkins.class.getName()+".slaveAgentPort", def); + } + + /** + * If -Djenkins.model.Jenkins.slaveAgentPort is defined, enforce it on every start instead of only the first one. + */ + private static final boolean SLAVE_AGENT_PORT_ENFORCE = SystemProperties.getBoolean(Jenkins.class.getName()+".slaveAgentPortEnforce", false); + + /** + * The TCP agent protocols that are explicitly disabled (we store the disabled ones so that newer protocols + * are enabled by default). Will be {@code null} instead of empty to simplify XML format. + * + * @since 2.16 + */ + @CheckForNull + private List disabledAgentProtocols; + /** + * @deprecated Just a temporary buffer for XSTream migration code from JENKINS-39465, do not use + */ + @Deprecated + private transient String[] _disabledAgentProtocols; + + /** + * The TCP agent protocols that are {@link AgentProtocol#isOptIn()} and explicitly enabled. + * Will be {@code null} instead of empty to simplify XML format. + * + * @since 2.16 + */ + @CheckForNull + private List enabledAgentProtocols; + /** + * @deprecated Just a temporary buffer for XSTream migration code from JENKINS-39465, do not use + */ + @Deprecated + private transient String[] _enabledAgentProtocols; + + /** + * The TCP agent protocols that are enabled. Built from {@link #disabledAgentProtocols} and + * {@link #enabledAgentProtocols}. + * + * @since 2.16 + * @see #setAgentProtocols(Set) + * @see #getAgentProtocols() + */ + private transient Set agentProtocols; /** * Whitespace-separated labels assigned to the master as a {@link Node}. @@ -592,7 +672,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve public transient final OverallLoadStatistics overallLoad = new OverallLoadStatistics(); /** - * Load statistics of the free roaming jobs and slaves. + * Load statistics of the free roaming jobs and agents. * * This includes all executors on {@link hudson.model.Node.Mode#NORMAL} nodes and jobs that do not have any assigned nodes. * @@ -612,7 +692,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * Use {@link #unlabeledNodeProvisioner}. * This was broken because it was tracking all the executors in the system, but it was only tracking * free-roaming jobs in the queue. So {@link Cloud} fails to launch nodes when you have some exclusive - * slaves and free-roaming jobs in the queue. + * agents and free-roaming jobs in the queue. */ @Restricted(NoExternalUse.class) @Deprecated @@ -687,12 +767,15 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve /** * Gets the {@link Jenkins} singleton. - * {@link #getInstance()} provides the unchecked versions of the method. + * {@link #getInstanceOrNull()} provides the unchecked versions of the method. * @return {@link Jenkins} instance * @throws IllegalStateException {@link Jenkins} has not been started, or was already shut down * @since 1.590 + * @deprecated use {@link #getInstance()} */ - public static @Nonnull Jenkins getActiveInstance() throws IllegalStateException { + @Deprecated + @Nonnull + public static Jenkins getActiveInstance() throws IllegalStateException { Jenkins instance = HOLDER.getInstance(); if (instance == null) { throw new IllegalStateException("Jenkins has not been started, or was already shut down"); @@ -705,13 +788,37 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * {@link #getActiveInstance()} provides the checked versions of the method. * @return The instance. Null if the {@link Jenkins} instance has not been started, * or was already shut down + * @since 1.653 */ - @CLIResolver @CheckForNull - public static Jenkins getInstance() { + public static Jenkins getInstanceOrNull() { return HOLDER.getInstance(); } + /** + * Gets the {@link Jenkins} singleton. In certain rare cases you may have code that is intended to run before + * Jenkins starts or while Jenkins is being shut-down. For those rare cases use {@link #getInstanceOrNull()}. + * In other cases you may have code that might end up running on a remote JVM and not on the Jenkins master, + * for those cases you really should rewrite your code so that when the {@link Callable} is sent over the remoting + * channel it uses a {@code writeReplace} method or similar to ensure that the {@link Jenkins} class is not being + * loaded into the remote class loader + * @return The instance. + * @throws IllegalStateException {@link Jenkins} has not been started, or was already shut down + */ + @CLIResolver + @Nonnull + public static Jenkins getInstance() { + Jenkins instance = HOLDER.getInstance(); + if (instance == null) { + if(SystemProperties.getBoolean(Jenkins.class.getName()+".enableExceptionOnNullInstance")) { + // TODO: remove that second block around 2.20 (that is: ~20 versions to battle test it) + // See https://github.com/jenkinsci/jenkins/pull/2297#issuecomment-216710150 + throw new IllegalStateException("Jenkins has not been started, or was already shut down"); + } + } + return instance; + } + /** * Secret key generated once and used for a long time, beyond * container start/stop. Persisted outside config.xml to avoid @@ -719,7 +826,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve */ private transient final String secretKey; - private transient final UpdateCenter updateCenter = new UpdateCenter(); + private transient final UpdateCenter updateCenter = UpdateCenter.createUpdateCenter(null); /** * True if the user opted out from the statistics tracking. We'll never send anything if this is true. @@ -736,22 +843,26 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve */ private transient final LogRecorderManager log = new LogRecorderManager(); + private transient final boolean oldJenkinsJVM; + protected Jenkins(File root, ServletContext context) throws IOException, InterruptedException, ReactorException { - this(root,context,null); + this(root, context, null); } /** * @param pluginManager * If non-null, use existing plugin manager. create a new one. */ - @edu.umd.cs.findbugs.annotations.SuppressWarnings({ + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings({ "SC_START_IN_CTOR", // bug in FindBugs. It flags UDPBroadcastThread.start() call but that's for another class "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD" // Trigger.timer }) protected Jenkins(File root, ServletContext context, PluginManager pluginManager) throws IOException, InterruptedException, ReactorException { + oldJenkinsJVM = JenkinsJVM.isJenkinsJVM(); // capture to restore in cleanUp() + JenkinsJVMAccess._setJenkinsJVM(true); // set it for unit tests as they will not have gone through WebAppMain long start = System.currentTimeMillis(); - // As Jenkins is starting, grant this process full control + // As Jenkins is starting, grant this process full control ACL.impersonate(ACL.SYSTEM); try { this.root = root; @@ -762,7 +873,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve theInstance = this; if (!new File(root,"jobs").exists()) { - // if this is a fresh install, use more modern default layout that's consistent with slaves + // if this is a fresh install, use more modern default layout that's consistent with agents workspaceDir = "${JENKINS_HOME}/workspace/${ITEM_FULLNAME}"; } @@ -804,7 +915,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } if (pluginManager==null) - pluginManager = new LocalPluginManager(this); + pluginManager = PluginManager.createDefault(this); this.pluginManager = pluginManager; // JSON binding needs to be able to see all the classes from all the plugins WebApp.get(servletContext).setClassLoader(pluginManager.uberClassLoader); @@ -818,19 +929,25 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve InitMilestone.ordering() // forced ordering among key milestones ); + // Ensure we reached the final initialization state. Log the error otherwise + if (initLevel != InitMilestone.COMPLETED) { + LOGGER.log(SEVERE, "Jenkins initialization has not reached the COMPLETED initialization milestone after the startup. " + + "Current state: {0}. " + + "It may cause undefined incorrect behavior in Jenkins plugin relying on this state. " + + "It is likely an issue with the Initialization task graph. " + + "Example: usage of @Initializer(after = InitMilestone.COMPLETED) in a plugin (JENKINS-37759). " + + "Please create a bug in Jenkins bugtracker. ", + initLevel); + } + + if(KILL_AFTER_LOAD) System.exit(0); - if(slaveAgentPort!=-1) { - try { - tcpSlaveAgentListener = new TcpSlaveAgentListener(slaveAgentPort); - } catch (BindException e) { - new AdministrativeError(getClass().getName()+".tcpBind", - "Failed to listen to incoming slave connection", - "Failed to listen to incoming slave connection. Change the port number to solve the problem.",e); - } - } else - tcpSlaveAgentListener = null; + setupWizard = new SetupWizard(); + InstallUtil.proceedToNextStateFrom(InstallState.UNKNOWN); + + launchTcpSlaveAgentListener(); if (UDPBroadcastThread.PORT != -1) { try { @@ -851,11 +968,25 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve updateComputerList(); - {// master is online now - Computer c = toComputer(); - if(c!=null) - for (ComputerListener cl : ComputerListener.all()) - cl.onOnline(c, new LogTaskListener(LOGGER, INFO)); + {// master is online now, it's instance must always exist + final Computer c = toComputer(); + if(c != null) { + for (ComputerListener cl : ComputerListener.all()) { + try { + cl.onOnline(c, new LogTaskListener(LOGGER, INFO)); + } catch (Throwable t) { + if (t instanceof Error) { + // We propagate Runtime errors, because they are fatal. + throw t; + } + + // Other exceptions should be logged instead of failing the Jenkins startup (See listener's Javadoc) + // We also throw it for InterruptedException since it's what is expected according to the javadoc + LOGGER.log(SEVERE, String.format("Invocation of the computer listener %s failed for the Jenkins master node", + cl.getClass()), t); + } + } + } } for (ItemListener l : ItemListener.all()) { @@ -878,6 +1009,56 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } } + /** + * Maintains backwards compatibility. Invoked by XStream when this object is de-serialized. + */ + @SuppressWarnings({"unused"}) + private Object readResolve() { + if (jdks == null) { + jdks = new ArrayList<>(); + } + if (SLAVE_AGENT_PORT_ENFORCE) { + slaveAgentPort = getSlaveAgentPortInitialValue(slaveAgentPort); + } + if (disabledAgentProtocols == null && _disabledAgentProtocols != null) { + disabledAgentProtocols = Arrays.asList(_disabledAgentProtocols); + _disabledAgentProtocols = null; + } + if (enabledAgentProtocols == null && _enabledAgentProtocols != null) { + enabledAgentProtocols = Arrays.asList(_enabledAgentProtocols); + _enabledAgentProtocols = null; + } + // Invalidate the protocols cache after the reload + agentProtocols = null; + return this; + } + + /** + * Get the Jenkins {@link jenkins.install.InstallState install state}. + * @return The Jenkins {@link jenkins.install.InstallState install state}. + */ + @Nonnull + @Restricted(NoExternalUse.class) + public InstallState getInstallState() { + if (installState == null || installState.name() == null) { + return InstallState.UNKNOWN; + } + return installState; + } + + /** + * Update the current install state. This will invoke state.initializeState() + * when the state has been transitioned. + */ + @Restricted(NoExternalUse.class) + public void setInstallState(@Nonnull InstallState newState) { + InstallState prior = installState; + installState = newState; + if (!prior.equals(newState)) { + newState.initializeState(); + } + } + /** * Executes a reactor. * @@ -894,7 +1075,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve if (is!=null && is.skipInitTask(task)) return; ACL.impersonate(ACL.SYSTEM); // full access in the initialization thread - String taskName = task.getDisplayName(); + String taskName = InitReactorRunner.getDisplayName(task); Thread t = Thread.currentThread(); String name = t.getName(); @@ -906,17 +1087,35 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve if(LOG_STARTUP_PERFORMANCE) LOGGER.info(String.format("Took %dms for %s by %s", System.currentTimeMillis()-start, taskName, name)); + } catch (Exception | Error x) { + if (containsLinkageError(x)) { + LOGGER.log(Level.WARNING, taskName + " failed perhaps due to plugin dependency issues", x); + } else { + throw x; + } } finally { t.setName(name); SecurityContextHolder.clearContext(); } } + private boolean containsLinkageError(Throwable x) { + if (x instanceof LinkageError) { + return true; + } + Throwable x2 = x.getCause(); + return x2 != null && containsLinkageError(x2); + } }; new InitReactorRunner() { @Override protected void onInitMilestoneAttained(InitMilestone milestone) { initLevel = milestone; + if (milestone==PLUGINS_PREPARED) { + // set up Guice to enable injection as early as possible + // before this milestone, ExtensionList.ensureLoaded() won't actually try to locate instances + ExtensionList.lookup(ExtensionFinder.class).getComponents(); + } } }.run(reactor); } @@ -940,27 +1139,171 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve return slaveAgentPort; } + /** + * @since 2.24 + */ + public boolean isSlaveAgentPortEnforced() { + return Jenkins.SLAVE_AGENT_PORT_ENFORCE; + } + /** * @param port * 0 to indicate random available TCP port. -1 to disable this service. */ public void setSlaveAgentPort(int port) throws IOException { + if (SLAVE_AGENT_PORT_ENFORCE) { + LOGGER.log(Level.WARNING, "setSlaveAgentPort({0}) call ignored because system property {1} is true", new String[] { Integer.toString(port), Jenkins.class.getName()+".slaveAgentPortEnforce" }); + } else { + forceSetSlaveAgentPort(port); + } + } + + private void forceSetSlaveAgentPort(int port) throws IOException { this.slaveAgentPort = port; + launchTcpSlaveAgentListener(); + } - // relaunch the agent - if(tcpSlaveAgentListener==null) { - if(slaveAgentPort!=-1) - tcpSlaveAgentListener = new TcpSlaveAgentListener(slaveAgentPort); - } else { - if(tcpSlaveAgentListener.configuredPort!=slaveAgentPort) { + /** + * Returns the enabled agent protocols. + * + * @return the enabled agent protocols. + * @since 2.16 + */ + public Set getAgentProtocols() { + if (agentProtocols == null) { + // idempotent, so don't care if we do this concurrently, should all get same result + Set result = new TreeSet<>(); + Set disabled = new TreeSet<>(); + for (String p : Util.fixNull(disabledAgentProtocols)) { + disabled.add(p.trim()); + } + Set enabled = new TreeSet<>(); + for (String p : Util.fixNull(enabledAgentProtocols)) { + enabled.add(p.trim()); + } + for (AgentProtocol p : AgentProtocol.all()) { + String name = p.getName(); + if (name != null && (p.isRequired() + || (!disabled.contains(name) && (!p.isOptIn() || enabled.contains(name))))) { + result.add(name); + } + } + agentProtocols = result; + return result; + } + return agentProtocols; + } + + /** + * Sets the enabled agent protocols. + * + * @param protocols the enabled agent protocols. + * @since 2.16 + */ + public void setAgentProtocols(Set protocols) { + Set disabled = new TreeSet<>(); + Set enabled = new TreeSet<>(); + for (AgentProtocol p : AgentProtocol.all()) { + String name = p.getName(); + if (name != null && !p.isRequired()) { + // we want to record the protocols where the admin has made a conscious decision + // thus, if a protocol is opt-in, we record the admin enabling it + // if a protocol is opt-out, we record the admin disabling it + // We should not transition rapidly from opt-in -> opt-out -> opt-in + // the scenario we want to have work is: + // 1. We introduce a new protocol, it starts off as opt-in. Some admins decide to test and opt-in + // 2. We decide that the protocol is ready for general use. It gets marked as opt-out. Any admins + // that took part in early testing now have their config switched to not mention the new protocol + // at all when they save their config as the protocol is now opt-out. Any admins that want to + // disable it can do so and will have their preference recorded. + // 3. We decide that the protocol needs to be retired. It gets switched back to opt-in. At this point + // the initial opt-in admins, assuming they visited an upgrade to a master with step 2, will + // have the protocol disabled for them. This is what we want. If they didn't upgrade to a master + // with step 2, well there is not much we can do to differentiate them from somebody who is upgrading + // from a previous step 3 master and had needed to keep the protocol turned on. + // + // What we should never do is flip-flop: opt-in -> opt-out -> opt-in -> opt-out as that will basically + // clear any preference that an admin has set, but this should be ok as we only ever will be + // adding new protocols and retiring old ones. + if (p.isOptIn()) { + if (protocols.contains(name)) { + enabled.add(name); + } + } else { + if (!protocols.contains(name)) { + disabled.add(name); + } + } + } + } + disabledAgentProtocols = disabled.isEmpty() ? null : new ArrayList<>(disabled); + enabledAgentProtocols = enabled.isEmpty() ? null : new ArrayList<>(enabled); + agentProtocols = null; + } + + private void launchTcpSlaveAgentListener() throws IOException { + synchronized(tcpSlaveAgentListenerLock) { + // shutdown previous agent if the port has changed + if (tcpSlaveAgentListener != null && tcpSlaveAgentListener.configuredPort != slaveAgentPort) { tcpSlaveAgentListener.shutdown(); tcpSlaveAgentListener = null; - if(slaveAgentPort!=-1) + } + if (slaveAgentPort != -1 && tcpSlaveAgentListener == null) { + final String administrativeMonitorId = getClass().getName() + ".tcpBind"; + try { tcpSlaveAgentListener = new TcpSlaveAgentListener(slaveAgentPort); + // remove previous monitor in case of previous error + AdministrativeMonitor toBeRemoved = null; + ExtensionList all = AdministrativeMonitor.all(); + for (AdministrativeMonitor am : all) { + if (administrativeMonitorId.equals(am.id)) { + toBeRemoved = am; + break; + } + } + all.remove(toBeRemoved); + } catch (BindException e) { + LOGGER.log(Level.WARNING, String.format("Failed to listen to incoming agent connections through JNLP port %s. Change the JNLP port number", slaveAgentPort), e); + new AdministrativeError(administrativeMonitorId, + "Failed to listen to incoming agent connections through JNLP", + "Failed to listen to incoming agent connections through JNLP. Change the JNLP port number to solve the problem.", e); + } } } } + @Extension + @Restricted(NoExternalUse.class) + public static class EnforceSlaveAgentPortAdministrativeMonitor extends AdministrativeMonitor { + @Inject + Jenkins j; + + @Override + public String getDisplayName() { + return jenkins.model.Messages.EnforceSlaveAgentPortAdministrativeMonitor_displayName(); + } + + public String getSystemPropertyName() { + return Jenkins.class.getName() + ".slaveAgentPort"; + } + + public int getExpectedPort() { + int slaveAgentPort = j.slaveAgentPort; + return Jenkins.getSlaveAgentPortInitialValue(slaveAgentPort); + } + + public void doAct(StaplerRequest req, StaplerResponse rsp) throws IOException { + j.forceSetSlaveAgentPort(getExpectedPort()); + rsp.sendRedirect2(req.getContextPath() + "/manage"); + } + + @Override + public boolean isActivated() { + int slaveAgentPort = Jenkins.getInstance().slaveAgentPort; + return SLAVE_AGENT_PORT_ENFORCE && slaveAgentPort != Jenkins.getSlaveAgentPortInitialValue(slaveAgentPort); + } + } + public void setNodeName(String name) { throw new UnsupportedOperationException(); // not allowed } @@ -1060,7 +1403,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * Gets the SCM descriptor by name. Primarily used for making them web-visible. */ public Descriptor getScm(String shortClassName) { - return findDescriptor(shortClassName,SCM.all()); + return findDescriptor(shortClassName, SCM.all()); } /** @@ -1169,6 +1512,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * If you have an instance of {@code type} and call {@link Describable#getDescriptor()}, * you'll get the same instance that this method returns. */ + @CheckForNull public Descriptor getDescriptor(Class type) { for( Descriptor d : getExtensionList(Descriptor.class) ) if(d.clazz==type) @@ -1204,7 +1548,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve * Gets the {@link SecurityRealm} descriptors by name. Primarily used for making them web-visible. */ public Descriptor getSecurityRealms(String shortClassName) { - return findDescriptor(shortClassName,SecurityRealm.all()); + return findDescriptor(shortClassName, SecurityRealm.all()); } /** @@ -1365,10 +1709,10 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve */ @Exported(name="jobs") public List getItems() { - if (authorizationStrategy instanceof AuthorizationStrategy.Unsecured || - authorizationStrategy instanceof FullControlOnceLoggedInAuthorizationStrategy) { - return new ArrayList(items.values()); - } + if (authorizationStrategy instanceof AuthorizationStrategy.Unsecured || + authorizationStrategy instanceof FullControlOnceLoggedInAuthorizationStrategy) { + return new ArrayList(items.values()); + } List viewableItems = new ArrayList(); for (TopLevelItem item : items.values()) { @@ -1429,7 +1773,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve */ @Deprecated public List getProjects() { - return Util.createSubList(items.values(),Project.class); + return Util.createSubList(items.values(), Project.class); } /** @@ -1473,6 +1817,28 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve viewGroupMixIn.addView(v); } + /** + * Completely replaces views. + * + *

+ * This operation is NOT provided as an atomic operation, but rather + * the sole purpose of this is to define a setter for this to help + * introspecting code, such as system-config-dsl plugin + */ + // even if we want to offer this atomic operation, CopyOnWriteArrayList + // offers no such operation + public void setViews(Collection views) throws IOException { + BulkChange bc = new BulkChange(this); + try { + this.views.clear(); + for (View v : views) { + addView(v); + } + } finally { + bc.commit(); + } + } + public boolean canDelete(View view) { return viewGroupMixIn.canDelete(view); } @@ -1482,7 +1848,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } public void onViewRenamed(View view, String oldName, String newName) { - viewGroupMixIn.onViewRenamed(view,oldName,newName); + viewGroupMixIn.onViewRenamed(view, oldName, newName); } /** @@ -1641,11 +2007,20 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } public List getJDKs() { - if(jdks==null) - jdks = new ArrayList(); return jdks; } + /** + * Replaces all JDK installations with those from the given collection. + * + * Use {@link hudson.model.JDK.DescriptorImpl#setInstallations(JDK...)} to + * set JDK installations from external code. + */ + @Restricted(NoExternalUse.class) + public void setJDKs(Collection jdks) { + this.jdks = new ArrayList(jdks); + } + /** * Gets the JDK installation of the given name, or returns null. */ @@ -1666,7 +2041,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve /** - * Gets the slave node of the give name, hooked under this Jenkins. + * Gets the agent node of the give name, hooked under this Jenkins. */ public @CheckForNull Node getNode(String name) { return nodes.getNode(name); @@ -1691,6 +2066,16 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve return nodes.getNodes(); } + /** + * Get the {@link Nodes} object that handles maintaining individual {@link Node}s. + * @return The Nodes object. + */ + @Restricted(NoExternalUse.class) + public Nodes getNodesObject() { + // TODO replace this with something better when we properly expose Nodes. + return nodes; + } + /** * Adds one more {@link Node} to Jenkins. */ @@ -1705,16 +2090,30 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve nodes.removeNode(n); } + /** + * Saves an existing {@link Node} on disk, called by {@link Node#save()}. This method is preferred in those cases + * where you need to determine atomically that the node being saved is actually in the list of nodes. + * + * @param n the node to be updated. + * @return {@code true}, if the node was updated. {@code false}, if the node was not in the list of nodes. + * @throws IOException if the node could not be persisted. + * @see Nodes#updateNode + * @since 1.634 + */ + public boolean updateNode(Node n) throws IOException { + return nodes.updateNode(n); + } + public void setNodes(final List n) throws IOException { nodes.setNodes(n); } public DescribableList, NodePropertyDescriptor> getNodeProperties() { - return nodeProperties; + return nodeProperties; } public DescribableList, NodePropertyDescriptor> getGlobalNodeProperties() { - return globalNodeProperties; + return globalNodeProperties; } /** @@ -1750,10 +2149,6 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve @Extension public static final DescriptorImpl INSTANCE = new DescriptorImpl(); - public String getDisplayName() { - return ""; - } - @Override public boolean isInstantiable() { return false; @@ -2327,7 +2722,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve */ @Override public TopLevelItem getItem(String name) throws AccessDeniedException { if (name==null) return null; - TopLevelItem item = items.get(name); + TopLevelItem item = items.get(name); if (item==null) return null; if (!item.hasPermission(Item.READ)) { @@ -2463,8 +2858,8 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve /** * Gets the user of the given name. * - * @return the user of the given name, if that person exists or the invoker {@link #hasPermission} on {@link #ADMINISTER}; else null - * @see User#get(String,boolean) + * @return the user of the given name (which may or may not be an id), if that person exists or the invoker {@link #hasPermission} on {@link #ADMINISTER}; else null + * @see User#get(String,boolean), {@link User#getById(String, boolean)} */ public @CheckForNull User getUser(String name) { return User.get(name,hasPermission(ADMINISTER)); @@ -2608,6 +3003,19 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve return new Hudson.MasterComputer(); } + private void loadConfig() throws IOException { + XmlFile cfg = getConfigFile(); + if (cfg.exists()) { + // reset some data that may not exist in the disk file + // so that we can take a proper compensation action later. + primaryView = null; + views.clear(); + + // load from disk + cfg.unmarshal(Jenkins.this); + } + } + private synchronized TaskBuilder loadTasks() throws IOException { File projectsDir = new File(root,"jobs"); if(!projectsDir.getCanonicalFile().isDirectory() && !projectsDir.mkdirs()) { @@ -2622,17 +3030,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve TaskGraphBuilder g = new TaskGraphBuilder(); Handle loadJenkins = g.requires(EXTENSIONS_AUGMENTED).attains(JOB_LOADED).add("Loading global config", new Executable() { public void run(Reactor session) throws Exception { - XmlFile cfg = getConfigFile(); - if (cfg.exists()) { - // reset some data that may not exist in the disk file - // so that we can take a proper compensation action later. - primaryView = null; - views.clear(); - - // load from disk - cfg.unmarshal(Jenkins.this); - } - + loadConfig(); // if we are loading old data that doesn't have this field if (slaves != null && !slaves.isEmpty() && nodes.isLegacy()) { nodes.setNodes(slaves); @@ -2680,7 +3078,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve {// recompute label objects - populates the labels mapping. for (Node slave : nodes.getNodes()) - // Note that not all labels are visible until the slaves have connected. + // Note that not all labels are visible until the agents have connected. slave.getAssignedLabels(); getAssignedLabels(); } @@ -2688,11 +3086,12 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve // initialize views by inserting the default view if necessary // this is both for clean Jenkins and for backward compatibility. if(views.size()==0 || primaryView==null) { - View v = new AllView(Messages.Hudson_ViewName()); + View v = new AllView(AllView.DEFAULT_VIEW_NAME); setViewOwner(v); views.add(0,v); primaryView = v.getViewName(); } + primaryView = AllView.migrateLegacyPrimaryAllViewLocalizedName(views, primaryView); if (useSecurity!=null && !useSecurity) { // forced reset to the unsecure mode. @@ -2744,11 +3143,101 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve /** * Called to shut down the system. */ - @edu.umd.cs.findbugs.annotations.SuppressWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings("ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD") public void cleanUp() { - for (ItemListener l : ItemListener.all()) - l.onBeforeShutdown(); + if (theInstance != this && theInstance != null) { + LOGGER.log(Level.WARNING, "This instance is no longer the singleton, ignoring cleanUp()"); + return; + } + synchronized (Jenkins.class) { + if (cleanUpStarted) { + LOGGER.log(Level.WARNING, "Jenkins.cleanUp() already started, ignoring repeated cleanUp()"); + return; + } + cleanUpStarted = true; + } + try { + LOGGER.log(Level.INFO, "Stopping Jenkins"); + + final List errors = new ArrayList<>(); + + fireBeforeShutdown(errors); + + _cleanUpRunTerminators(errors); + + terminating = true; + + final Set> pending = _cleanUpDisconnectComputers(errors); + + _cleanUpShutdownUDPBroadcast(errors); + + _cleanUpCloseDNSMulticast(errors); + + _cleanUpInterruptReloadThread(errors); + + _cleanUpShutdownTriggers(errors); + + _cleanUpShutdownTimer(errors); + _cleanUpShutdownTcpSlaveAgent(errors); + + _cleanUpShutdownPluginManager(errors); + + _cleanUpPersistQueue(errors); + + _cleanUpShutdownThreadPoolForLoad(errors); + + _cleanUpAwaitDisconnects(errors, pending); + + _cleanUpPluginServletFilters(errors); + + _cleanUpReleaseAllLoggers(errors); + + LOGGER.log(Level.INFO, "Jenkins stopped"); + + if (!errors.isEmpty()) { + StringBuilder message = new StringBuilder("Unexpected issues encountered during cleanUp: "); + Iterator iterator = errors.iterator(); + message.append(iterator.next().getMessage()); + while (iterator.hasNext()) { + message.append("; "); + message.append(iterator.next().getMessage()); + } + iterator = errors.iterator(); + RuntimeException exception = new RuntimeException(message.toString(), iterator.next()); + while (iterator.hasNext()) { + exception.addSuppressed(iterator.next()); + } + throw exception; + } + } finally { + theInstance = null; + if (JenkinsJVM.isJenkinsJVM()) { + JenkinsJVMAccess._setJenkinsJVM(oldJenkinsJVM); + } + } + } + + private void fireBeforeShutdown(List errors) { + LOGGER.log(Level.FINE, "Notifying termination"); + for (ItemListener l : ItemListener.all()) { + try { + l.onBeforeShutdown(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(Level.WARNING, "ItemListener " + l + ": " + e.getMessage(), e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(Level.WARNING, "ItemListener " + l + ": " + e.getMessage(), e); + // save for later + errors.add(e); + } + } + } + + private void _cleanUpRunTerminators(List errors) { try { final TerminatorFinder tf = new TerminatorFinder( pluginManager != null ? pluginManager.uberClassLoader : Thread.currentThread().getContextClassLoader()); @@ -2757,65 +3246,325 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve public void execute(Runnable command) { command.run(); } + }, new ReactorListener() { + final Level level = Level.parse(Configuration.getStringConfigParameter("termLogLevel", "FINE")); + + public void onTaskStarted(Task t) { + LOGGER.log(level, "Started {0}", InitReactorRunner.getDisplayName(t)); + } + + public void onTaskCompleted(Task t) { + LOGGER.log(level, "Completed {0}", InitReactorRunner.getDisplayName(t)); + } + + public void onTaskFailed(Task t, Throwable err, boolean fatal) { + LOGGER.log(SEVERE, "Failed " + InitReactorRunner.getDisplayName(t), err); + } + + public void onAttained(Milestone milestone) { + Level lv = level; + String s = "Attained " + milestone.toString(); + if (milestone instanceof TermMilestone) { + lv = Level.INFO; // noteworthy milestones --- at least while we debug problems further + s = milestone.toString(); + } + LOGGER.log(lv, s); + } }); - } catch (InterruptedException e) { - LOGGER.log(SEVERE, "Failed to execute termination",e); - e.printStackTrace(); - } catch (ReactorException e) { - LOGGER.log(SEVERE, "Failed to execute termination",e); - } catch (IOException e) { + } catch (InterruptedException | ReactorException | IOException e) { LOGGER.log(SEVERE, "Failed to execute termination",e); + errors.add(e); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to execute termination", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to execute termination", e); + // save for later + errors.add(e); } + } + + private Set> _cleanUpDisconnectComputers(final List errors) { + LOGGER.log(Level.INFO, "Starting node disconnection"); + final Set> pending = new HashSet>(); + // JENKINS-28840 we know we will be interrupting all the Computers so get the Queue lock once for all + Queue.withLock(new Runnable() { + @Override + public void run() { + for( Computer c : computers.values() ) { + try { + c.interrupt(); + killComputer(c); + pending.add(c.disconnect(null)); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(Level.WARNING, "Could not disconnect " + c + ": " + e.getMessage(), e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(Level.WARNING, "Could not disconnect " + c + ": " + e.getMessage(), e); + // save for later + errors.add(e); + } + } + } + }); + return pending; + } - Set> pending = new HashSet>(); - terminating = true; - for( Computer c : computers.values() ) { - c.interrupt(); - killComputer(c); - pending.add(c.disconnect(null)); + private void _cleanUpShutdownUDPBroadcast(List errors) { + if(udpBroadcastThread!=null) { + LOGGER.log(Level.FINE, "Shutting down {0}", udpBroadcastThread.getName()); + try { + udpBroadcastThread.shutdown(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to shutdown UDP Broadcast Thread", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to shutdown UDP Broadcast Thread", e); + // save for later + errors.add(e); + } } - if(udpBroadcastThread!=null) - udpBroadcastThread.shutdown(); - if(dnsMultiCast!=null) - dnsMultiCast.close(); - interruptReloadThread(); + } - java.util.Timer timer = Trigger.timer; - if (timer != null) { - timer.cancel(); + private void _cleanUpCloseDNSMulticast(List errors) { + if(dnsMultiCast!=null) { + LOGGER.log(Level.FINE, "Closing DNS Multicast service"); + try { + dnsMultiCast.close(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to close DNS Multicast service", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to close DNS Multicast service", e); + // save for later + errors.add(e); + } } - // TODO: how to wait for the completion of the last job? - Trigger.timer = null; + } - Timer.shutdown(); + private void _cleanUpInterruptReloadThread(List errors) { + LOGGER.log(Level.FINE, "Interrupting reload thread"); + try { + interruptReloadThread(); + } catch (SecurityException e) { + LOGGER.log(WARNING, "Not permitted to interrupt reload thread", e); + errors.add(e); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to interrupt reload thread", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to interrupt reload thread", e); + // save for later + errors.add(e); + } + } - if(tcpSlaveAgentListener!=null) - tcpSlaveAgentListener.shutdown(); + private void _cleanUpShutdownTriggers(List errors) { + LOGGER.log(Level.FINE, "Shutting down triggers"); + try { + final java.util.Timer timer = Trigger.timer; + if (timer != null) { + final CountDownLatch latch = new CountDownLatch(1); + timer.schedule(new TimerTask() { + @Override + public void run() { + timer.cancel(); + latch.countDown(); + } + }, 0); + if (latch.await(10, TimeUnit.SECONDS)) { + LOGGER.log(Level.FINE, "Triggers shut down successfully"); + } else { + timer.cancel(); + LOGGER.log(Level.INFO, "Gave up waiting for triggers to finish running"); + } + } + Trigger.timer = null; + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to shut down triggers", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to shut down triggers", e); + // save for later + errors.add(e); + } + } - if(pluginManager!=null) // be defensive. there could be some ugly timing related issues - pluginManager.stop(); + private void _cleanUpShutdownTimer(List errors) { + LOGGER.log(Level.FINE, "Shutting down timer"); + try { + Timer.shutdown(); + } catch (SecurityException e) { + LOGGER.log(WARNING, "Not permitted to shut down Timer", e); + errors.add(e); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to shut down Timer", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to shut down Timer", e); + // save for later + errors.add(e); + } + } - if(getRootDir().exists()) + private void _cleanUpShutdownTcpSlaveAgent(List errors) { + if(tcpSlaveAgentListener!=null) { + LOGGER.log(FINE, "Shutting down TCP/IP slave agent listener"); + try { + tcpSlaveAgentListener.shutdown(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to shut down TCP/IP slave agent listener", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to shut down TCP/IP slave agent listener", e); + // save for later + errors.add(e); + } + } + } + + private void _cleanUpShutdownPluginManager(List errors) { + if(pluginManager!=null) {// be defensive. there could be some ugly timing related issues + LOGGER.log(Level.INFO, "Stopping plugin manager"); + try { + pluginManager.stop(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to stop plugin manager", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to stop plugin manager", e); + // save for later + errors.add(e); + } + } + } + + private void _cleanUpPersistQueue(List errors) { + if(getRootDir().exists()) { // if we are aborting because we failed to create JENKINS_HOME, // don't try to save. Issue #536 - getQueue().save(); + LOGGER.log(Level.INFO, "Persisting build queue"); + try { + getQueue().save(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to persist build queue", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to persist build queue", e); + // save for later + errors.add(e); + } + } + } - threadPoolForLoad.shutdown(); - for (Future f : pending) + private void _cleanUpShutdownThreadPoolForLoad(List errors) { + LOGGER.log(FINE, "Shuting down Jenkins load thread pool"); + try { + threadPoolForLoad.shutdown(); + } catch (SecurityException e) { + LOGGER.log(WARNING, "Not permitted to shut down Jenkins load thread pool", e); + errors.add(e); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to shut down Jenkins load thread pool", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to shut down Jenkins load thread pool", e); + // save for later + errors.add(e); + } + } + + private void _cleanUpAwaitDisconnects(List errors, Set> pending) { + if (!pending.isEmpty()) { + LOGGER.log(Level.INFO, "Waiting for node disconnection completion"); + } + for (Future f : pending) { try { f.get(10, TimeUnit.SECONDS); // if clean up operation didn't complete in time, we fail the test } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; // someone wants us to die now. quick! } catch (ExecutionException e) { - LOGGER.log(Level.WARNING, "Failed to shut down properly",e); + LOGGER.log(Level.WARNING, "Failed to shut down remote computer connection cleanly", e); } catch (TimeoutException e) { - LOGGER.log(Level.WARNING, "Failed to shut down properly",e); + LOGGER.log(Level.WARNING, "Failed to shut down remote computer connection within 10 seconds", e); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(Level.WARNING, "Failed to shut down remote computer connection", e); + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, "Unexpected error while waiting for remote computer connection disconnect", e); + errors.add(e); } + } + } - LogFactory.releaseAll(); + private void _cleanUpPluginServletFilters(List errors) { + LOGGER.log(Level.FINE, "Stopping filters"); + try { + PluginServletFilter.cleanUp(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to stop filters", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to stop filters", e); + // save for later + errors.add(e); + } + } - theInstance = null; + private void _cleanUpReleaseAllLoggers(List errors) { + LOGGER.log(Level.FINE, "Releasing all loggers"); + try { + LogFactory.releaseAll(); + } catch (OutOfMemoryError e) { + // we should just propagate this, no point trying to log + throw e; + } catch (LinkageError e) { + LOGGER.log(SEVERE, "Failed to release all loggers", e); + // safe to ignore and continue for this one + } catch (Throwable e) { + LOGGER.log(SEVERE, "Failed to release all loggers", e); + // save for later + errors.add(e); + } } public Object getDynamic(String token) { @@ -2826,7 +3575,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve return a; } for (Action a : getManagementLinks()) - if(a.getUrlName().equals(token)) + if (Objects.equals(a.getUrlName(), token)) return a; return null; } @@ -2852,9 +3601,6 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve systemMessage = Util.nullify(req.getParameter("system_message")); - jdks.clear(); - jdks.addAll(req.bindJSONToList(JDK.class,json.get("jdks"))); - boolean result = true; for (Descriptor d : Functions.getSortedDescriptorsForGlobalConfigUnclassified()) result &= configureDescriptor(req,json,d); @@ -2939,11 +3685,14 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } } - @CLIMethod(name="quiet-down") + /** + * Quiet down Jenkins - preparation for a restart + * + * @param block Block until the system really quiets down and no builds are running + * @param timeout If non-zero, only block up to the specified number of milliseconds + */ @RequirePOST - public HttpRedirect doQuietDown( - @Option(name="-block",usage="Block until the system really quiets down and no builds are running") @QueryParameter boolean block, - @Option(name="-timeout",usage="If non-zero, only block up to the specified number of milliseconds") @QueryParameter int timeout) throws InterruptedException, IOException { + public HttpRedirect doQuietDown(@QueryParameter boolean block, @QueryParameter int timeout) throws InterruptedException, IOException { synchronized (this) { checkPermission(ADMINISTER); isQuietingDown = true; @@ -2960,7 +3709,9 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve return new HttpRedirect("."); } - @CLIMethod(name="cancel-quiet-down") + /** + * Cancel previous quiet down Jenkins - preparation for a restart + */ @RequirePOST // TODO the cancel link needs to be updated accordingly public synchronized HttpRedirect doCancelQuietDown() { checkPermission(ADMINISTER); @@ -2970,10 +3721,10 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } public HttpResponse doToggleCollapse() throws ServletException, IOException { - final StaplerRequest request = Stapler.getCurrentRequest(); - final String paneId = request.getParameter("paneId"); + final StaplerRequest request = Stapler.getCurrentRequest(); + final String paneId = request.getParameter("paneId"); - PaneStatusProperties.forCurrentUser().toggleCollapsed(paneId); + PaneStatusProperties.forCurrentUser().toggleCollapsed(paneId); return HttpResponses.forwardToPreviousPage(); } @@ -2986,10 +3737,10 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } /** - * Obtains the thread dump of all slaves (including the master.) + * Obtains the thread dump of all agents (including the master.) * *

- * Since this is for diagnostics, it has a built-in precautionary measure against hang slaves. + * Since this is for diagnostics, it has a built-in precautionary measure against hang agents. */ public Map> getAllThreadDumps() throws IOException, InterruptedException { checkPermission(ADMINISTER); @@ -3004,9 +3755,9 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve LOGGER.info("Failed to get thread dump for node " + c.getName() + ": " + e.getMessage()); } } - if (toComputer() == null) { - future.put("master", RemotingDiagnostics.getThreadDumpAsync(FilePath.localChannel)); - } + if (toComputer() == null) { + future.put("master", RemotingDiagnostics.getThreadDumpAsync(FilePath.localChannel)); + } // if the result isn't available in 5 sec, ignore that. // this is a precaution against hang nodes @@ -3082,20 +3833,6 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve // looks good } - /** - * Makes sure that the given name is good as a job name. - * @return trimmed name if valid; throws Failure if not - */ - private String checkJobName(String name) throws Failure { - checkGoodName(name); - name = name.trim(); - projectNamingStrategy.checkName(name); - if(getItem(name)!=null) - throw new Failure(Messages.Hudson_JobAlreadyExists(name)); - // looks good - return name; - } - private static String toPrintableName(String name) { StringBuilder printableName = new StringBuilder(); for( int i=0; i getManagementLinks() { return ManagementLink.all(); } - + + /** + * If set, a currently active setup wizard - e.g. installation + * + * @since 2.0 + */ + @Restricted(NoExternalUse.class) + public SetupWizard getSetupWizard() { + return setupWizard; + } + /** * Exposes the current user to /me URL. */ @@ -3809,26 +4550,24 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve checkPermission(READ); } catch (AccessDeniedException e) { String rest = Stapler.getCurrentRequest().getRestOfPath(); - if(rest.startsWith("/login") - || rest.startsWith("/logout") - || rest.startsWith("/accessDenied") - || rest.startsWith("/adjuncts/") - || rest.startsWith("/error") - || rest.startsWith("/oops") - || rest.startsWith("/signup") - || rest.startsWith("/tcpSlaveAgentListener") - // TODO SlaveComputer.doSlaveAgentJnlp; there should be an annotation to request unprotected access - || rest.matches("/computer/[^/]+/slave-agent[.]jnlp") && "true".equals(Stapler.getCurrentRequest().getParameter("encrypt")) - || rest.startsWith("/federatedLoginService/") - || rest.startsWith("/securityRealm")) - return this; // URLs that are always visible without READ permission - + for (String name : ALWAYS_READABLE_PATHS) { + if (rest.startsWith(name)) { + return this; + } + } for (String name : getUnprotectedRootActions()) { if (rest.startsWith("/" + name + "/") || rest.equals("/" + name)) { return this; } } + // TODO SlaveComputer.doSlaveAgentJnlp; there should be an annotation to request unprotected access + if (rest.matches("/computer/[^/]+/slave-agent[.]jnlp") + && "true".equals(Stapler.getCurrentRequest().getParameter("encrypt"))) { + return this; + } + + throw e; } return this; @@ -3847,7 +4586,9 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve // TODO consider caching (expiring cache when actions changes) for (Action a : getActions()) { if (a instanceof UnprotectedRootAction) { - names.add(a.getUrlName()); + String url = a.getUrlName(); + if (url == null) continue; + names.add(url); } } return names; @@ -3982,6 +4723,11 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve return true; } + @Override + public Boolean isUnix() { + return !Functions.isWindows(); + } + /** * Report an error. */ @@ -3995,6 +4741,12 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve Jenkins.getInstance().doConfigExecutorsSubmit(req, rsp); } + @WebMethod(name="config.xml") + @Override + public void doConfigDotXml(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException { + throw HttpResponses.status(SC_BAD_REQUEST); + } + @Override public boolean hasPermission(Permission permission) { // no one should be allowed to delete the master. @@ -4041,10 +4793,10 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve } /** - * Shortcut for {@code Jenkins.getInstance().lookup.get(type)} + * Shortcut for {@code Jenkins.getInstanceOrNull()?.lookup.get(type)} */ public static @CheckForNull T lookup(Class type) { - Jenkins j = Jenkins.getInstance(); + Jenkins j = Jenkins.getInstanceOrNull(); return j != null ? j.lookup.get(type) : null; } @@ -4089,14 +4841,34 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve IOUtils.closeQuietly(is); } String ver = props.getProperty("version"); - if(ver==null) ver="?"; + if(ver==null) ver = UNCOMPUTED_VERSION; + if(Main.isDevelopmentMode && "${build.version}".equals(ver)) { + // in dev mode, unable to get version (ahem Eclipse) + try { + File dir = new File(".").getAbsoluteFile(); + while(dir != null) { + File pom = new File(dir, "pom.xml"); + if (pom.exists() && "pom".equals(XMLUtils.getValue("/project/artifactId", pom))) { + pom = pom.getCanonicalFile(); + LOGGER.info("Reading version from: " + pom.getAbsolutePath()); + ver = XMLUtils.getValue("/project/version", pom); + break; + } + dir = dir.getParentFile(); + } + LOGGER.info("Jenkins is in dev mode, using version: " + ver); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unable to read Jenkins version: " + e.getMessage(), e); + } + } + VERSION = ver; context.setAttribute("version",ver); VERSION_HASH = Util.getDigestOf(ver).substring(0, 8); SESSION_HASH = Util.getDigestOf(ver+System.currentTimeMillis()).substring(0, 8); - if(ver.equals("?") || Boolean.getBoolean("hudson.script.noCache")) + if(ver.equals(UNCOMPUTED_VERSION) || SystemProperties.getBoolean("hudson.script.noCache")) RESOURCE_PATH = ""; else RESOURCE_PATH = "/static/"+SESSION_HASH; @@ -4104,24 +4876,57 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve VIEW_RESOURCE_PATH = "/resources/"+ SESSION_HASH; } + /** + * The version number before it is "computed" (by a call to computeVersion()). + * @since 2.0 + */ + @Restricted(NoExternalUse.class) + public static final String UNCOMPUTED_VERSION = "?"; + /** * Version number of this Jenkins. */ - public static String VERSION="?"; + public static String VERSION = UNCOMPUTED_VERSION; /** * Parses {@link #VERSION} into {@link VersionNumber}, or null if it's not parseable as a version number * (such as when Jenkins is run with "mvn hudson-dev:run") */ - public static VersionNumber getVersion() { + public @CheckForNull static VersionNumber getVersion() { + return toVersion(VERSION); + } + + /** + * Get the stored version of Jenkins, as stored by + * {@link #doConfigSubmit(org.kohsuke.stapler.StaplerRequest, org.kohsuke.stapler.StaplerResponse)}. + *

+ * Parses the version into {@link VersionNumber}, or null if it's not parseable as a version number + * (such as when Jenkins is run with "mvn hudson-dev:run") + * @since 2.0 + */ + @Restricted(NoExternalUse.class) + public @CheckForNull static VersionNumber getStoredVersion() { + return toVersion(Jenkins.getActiveInstance().version); + } + + /** + * Parses a version string into {@link VersionNumber}, or null if it's not parseable as a version number + * (such as when Jenkins is run with "mvn hudson-dev:run") + */ + private static @CheckForNull VersionNumber toVersion(@CheckForNull String versionString) { + if (versionString == null) { + return null; + } + try { - return new VersionNumber(VERSION); + return new VersionNumber(versionString); } catch (NumberFormatException e) { try { // for non-released version of Jenkins, this looks like "1.345 (private-foobar), so try to approximate. - int idx = VERSION.indexOf(' '); - if (idx>0) - return new VersionNumber(VERSION.substring(0,idx)); + int idx = versionString.indexOf(' '); + if (idx > 0) { + return new VersionNumber(versionString.substring(0,idx)); + } } catch (NumberFormatException _) { // fall through } @@ -4192,7 +4997,7 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve private static final String WORKSPACE_DIRNAME = Configuration.getStringConfigParameter("workspaceDirName", "workspace"); /** - * Automatically try to launch a slave when Jenkins is initialized or a new slave is created. + * Automatically try to launch an agent when Jenkins is initialized or a new agent computer is created. */ public static boolean AUTOMATIC_SLAVE_LAUNCH = true; @@ -4203,6 +5008,25 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve public static final Permission READ = new Permission(PERMISSIONS,"Read",Messages._Hudson_ReadPermission_Description(),Permission.READ,PermissionScope.JENKINS); public static final Permission RUN_SCRIPTS = new Permission(PERMISSIONS, "RunScripts", Messages._Hudson_RunScriptsPermission_Description(),ADMINISTER,PermissionScope.JENKINS); + /** + * Urls that are always visible without READ permission. + * + *

See also:{@link #getUnprotectedRootActions}. + */ + private static final ImmutableSet ALWAYS_READABLE_PATHS = ImmutableSet.of( + "/login", + "/logout", + "/accessDenied", + "/adjuncts/", + "/error", + "/oops", + "/signup", + "/tcpSlaveAgentListener", + "/federatedLoginService/", + "/securityRealm", + "/instance-identity" + ); + /** * {@link Authentication} object that represents the anonymous user. * Because Acegi creates its own {@link AnonymousAuthenticationToken} instances, the code must not @@ -4224,6 +5048,8 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve // for backward compatibility with <1.75, recognize the tag name "view" as well. XSTREAM.alias("view", ListView.class); XSTREAM.alias("listView", ListView.class); + XSTREAM.addImplicitArray(Jenkins.class, "_disabledAgentProtocols", "disabledAgentProtocol"); + XSTREAM.addImplicitArray(Jenkins.class, "_enabledAgentProtocols", "enabledAgentProtocol"); XSTREAM2.addCriticalField(Jenkins.class, "securityRealm"); XSTREAM2.addCriticalField(Jenkins.class, "authorizationStrategy"); // this seems to be necessary to force registration of converter early enough @@ -4232,16 +5058,20 @@ public class Jenkins extends AbstractCIBase implements DirectlyModifiableTopLeve // double check that initialization order didn't do any harm assert PERMISSIONS != null; assert ADMINISTER != null; - } catch (RuntimeException e) { - // when loaded on a slave and this fails, subsequent NoClassDefFoundError will fail to chain the cause. + + } catch (RuntimeException | Error e) { + // when loaded on an agent and this fails, subsequent NoClassDefFoundError will fail to chain the cause. // see http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8051847 // As we don't know where the first exception will go, let's also send this to logging so that // we have a known place to look at. LOGGER.log(SEVERE, "Failed to load Jenkins.class", e); throw e; - } catch (Error e) { - LOGGER.log(SEVERE, "Failed to load Jenkins.class", e); - throw e; + } + } + + private static final class JenkinsJVMAccess extends JenkinsJVM { + private static void _setJenkinsJVM(boolean jenkinsJVM) { + JenkinsJVM.setJenkinsJVM(jenkinsJVM); } } diff --git a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java index d9ed205ef00d7c79bbb5508d9ef0af0e74eb0f2c..981ef9a3a665cf6ff6373c93860fc731160a5f64 100644 --- a/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java +++ b/core/src/main/java/jenkins/model/JenkinsLocationConfiguration.java @@ -5,9 +5,8 @@ import hudson.Util; import hudson.XmlFile; import hudson.util.FormValidation; import hudson.util.XStream2; -import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; @@ -29,7 +28,7 @@ import javax.annotation.Nonnull; * @author Kohsuke Kawaguchi * @since 1.494 */ -@Extension +@Extension @Symbol("location") public class JenkinsLocationConfiguration extends GlobalConfiguration { /** * @deprecated replaced by {@link #jenkinsUrl} @@ -77,7 +76,7 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration { /** * Gets the service administrator e-mail address. - * @return Admin adress or "address not configured" stub + * @return Admin address or "address not configured" stub */ public @Nonnull String getAdminAddress() { String v = adminAddress; @@ -92,7 +91,7 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration { public void setAdminAddress(@CheckForNull String adminAddress) { String address = Util.nullify(adminAddress); if(address != null && address.startsWith("\"") && address.endsWith("\"")) { - // some users apparently quote the whole thing. Don't konw why + // some users apparently quote the whole thing. Don't know why // anyone does this, but it's a machine's job to forgive human mistake address = address.substring(1,address.length()-1); } @@ -146,12 +145,6 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration { } } - @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { - req.bindJSON(this,json); - return true; - } - /** * Checks the URL in global.jelly */ diff --git a/core/src/main/java/jenkins/model/MasterBuildConfiguration.java b/core/src/main/java/jenkins/model/MasterBuildConfiguration.java index 231b25bd5adf2de7043ba2a982cad457baa7d39f..6ae797adf2a0addc4c7984d498292b539267f099 100644 --- a/core/src/main/java/jenkins/model/MasterBuildConfiguration.java +++ b/core/src/main/java/jenkins/model/MasterBuildConfiguration.java @@ -26,6 +26,7 @@ package jenkins.model; import hudson.Extension; import hudson.model.Node.Mode; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import java.io.IOException; @@ -35,7 +36,7 @@ import java.io.IOException; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=500) +@Extension(ordinal=500) @Symbol("masterBuild") public class MasterBuildConfiguration extends GlobalConfiguration { public int getNumExecutors() { return Jenkins.getInstance().getNumExecutors(); diff --git a/core/src/main/java/jenkins/model/NodeListener.java b/core/src/main/java/jenkins/model/NodeListener.java new file mode 100644 index 0000000000000000000000000000000000000000..43d26922922733ddd1607bdef1ee1bd8e1e97593 --- /dev/null +++ b/core/src/main/java/jenkins/model/NodeListener.java @@ -0,0 +1,112 @@ +/* + * The MIT License + * + * Copyright (c) Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.model; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Node; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Listen to {@link Node} CRUD operations. + * + * @author ogondza. + * @since 2.8 + */ +public abstract class NodeListener implements ExtensionPoint { + + private static final Logger LOGGER = Logger.getLogger(NodeListener.class.getName()); + + /** + * Node is being created. + */ + protected void onCreated(@Nonnull Node node) {} + + /** + * Node is being updated. + */ + protected void onUpdated(@Nonnull Node oldOne, @Nonnull Node newOne) {} + + /** + * Node is being deleted. + */ + protected void onDeleted(@Nonnull Node node) {} + + /** + * Inform listeners that node is being created. + * + * @param node A node being created. + */ + public static void fireOnCreated(@Nonnull Node node) { + for (NodeListener nl: all()) { + try { + nl.onCreated(node); + } catch (Throwable ex) { + LOGGER.log(Level.WARNING, "Listener invocation failed", ex); + } + } + } + + /** + * Inform listeners that node is being updated. + * + * @param oldOne Old configuration. + * @param newOne New Configuration. + */ + public static void fireOnUpdated(@Nonnull Node oldOne, @Nonnull Node newOne) { + for (NodeListener nl: all()) { + try { + nl.onUpdated(oldOne, newOne); + } catch (Throwable ex) { + LOGGER.log(Level.WARNING, "Listener invocation failed", ex); + } + } + } + + /** + * Inform listeners that node is being removed. + * + * @param node A node being removed. + */ + public static void fireOnDeleted(@Nonnull Node node) { + for (NodeListener nl: all()) { + try { + nl.onDeleted(node); + } catch (Throwable ex) { + LOGGER.log(Level.WARNING, "Listener invocation failed", ex); + } + } + } + + /** + * Get all {@link NodeListener}s registered in Jenkins. + */ + public static @Nonnull List all() { + return ExtensionList.lookup(NodeListener.class); + } +} diff --git a/core/src/main/java/jenkins/model/Nodes.java b/core/src/main/java/jenkins/model/Nodes.java index ab301055961c2b0378cd882074e65934607581e8..2b1116bb86b1f802bb356f45bbe15886c74fb648 100644 --- a/core/src/main/java/jenkins/model/Nodes.java +++ b/core/src/main/java/jenkins/model/Nodes.java @@ -27,13 +27,14 @@ import hudson.BulkChange; import hudson.Util; import hudson.XmlFile; import hudson.model.Computer; -import hudson.model.ItemGroupMixIn; import hudson.model.Node; import hudson.model.Queue; import hudson.model.Saveable; import hudson.model.listeners.SaveableListener; import hudson.slaves.EphemeralNode; import hudson.slaves.OfflineCause; +import java.util.concurrent.Callable; + import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -137,14 +138,90 @@ public class Nodes implements Saveable { jenkins.trimLabels(); } }); - // no need for a full save() so we just do the minimum - if (node instanceof EphemeralNode) { - Util.deleteRecursive(new File(getNodesDir(), node.getNodeName())); - } else { - XmlFile xmlFile = new XmlFile(Jenkins.XSTREAM, - new File(new File(getNodesDir(), node.getNodeName()), "config.xml")); - xmlFile.write(node); - } + // TODO there is a theoretical race whereby the node instance is updated/removed after lock release + persistNode(node); + NodeListener.fireOnCreated(node); + } + } + + /** + * Actually persists a node on disk. + * + * @param node the node to be persisted. + * @throws IOException if the node could not be persisted. + */ + private void persistNode(final @Nonnull Node node) throws IOException { + // no need for a full save() so we just do the minimum + if (node instanceof EphemeralNode) { + Util.deleteRecursive(new File(getNodesDir(), node.getNodeName())); + } else { + XmlFile xmlFile = new XmlFile(Jenkins.XSTREAM, + new File(new File(getNodesDir(), node.getNodeName()), "config.xml")); + xmlFile.write(node); + SaveableListener.fireOnChange(this, xmlFile); + } + jenkins.getQueue().scheduleMaintenance(); + } + + /** + * Updates an existing node on disk. If the node instance is not in the list of nodes, then this + * will be a no-op, even if there is another instance with the same {@link Node#getNodeName()}. + * + * @param node the node to be updated. + * @return {@code true}, if the node was updated. {@code false}, if the node was not in the list of nodes. + * @throws IOException if the node could not be persisted. + * @since 1.634 + */ + public boolean updateNode(final @Nonnull Node node) throws IOException { + boolean exists; + try { + exists = Queue.withLock(new Callable() { + @Override + public Boolean call() throws Exception { + if (node == nodes.get(node.getNodeName())) { + jenkins.trimLabels(); + return true; + } + return false; + } + }); + } catch (RuntimeException e) { + // should never happen, but if it does let's do the right thing + throw e; + } catch (Exception e) { + // can never happen + exists = false; + } + if (exists) { + // TODO there is a theoretical race whereby the node instance is updated/removed after lock release + persistNode(node); + return true; + } + return false; + } + + /** + * Replace node of given name. + * + * @return {@code true} if node was replaced. + * @since 2.8 + */ + public boolean replaceNode(final Node oldOne, final @Nonnull Node newOne) throws IOException { + if (oldOne == nodes.get(oldOne.getNodeName())) { + // use the queue lock until Nodes has a way of directly modifying a single node. + Queue.withLock(new Runnable() { + public void run() { + Nodes.this.nodes.remove(oldOne.getNodeName()); + Nodes.this.nodes.put(newOne.getNodeName(), newOne); + jenkins.updateComputerList(); + jenkins.trimLabels(); + } + }); + updateNode(newOne); + NodeListener.fireOnUpdated(oldOne, newOne); + return true; + } else { + return false; } } @@ -173,6 +250,8 @@ public class Nodes implements Saveable { }); // no need for a full save() so we just do the minimum Util.deleteRecursive(new File(getNodesDir(), node.getNodeName())); + + NodeListener.fireOnDeleted(node); } } @@ -238,7 +317,7 @@ public class Nodes implements Saveable { newNodes.put(node.getNodeName(), node); } } catch (IOException e) { - Logger.getLogger(ItemGroupMixIn.class.getName()).log(Level.WARNING, "could not load " + subdir, e); + Logger.getLogger(Nodes.class.getName()).log(Level.WARNING, "could not load " + subdir, e); } } } diff --git a/core/src/main/java/jenkins/model/OptionalJobProperty.java b/core/src/main/java/jenkins/model/OptionalJobProperty.java new file mode 100644 index 0000000000000000000000000000000000000000..996ea3a8a482c27ba0f1f19d297189035f180feb --- /dev/null +++ b/core/src/main/java/jenkins/model/OptionalJobProperty.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright 2015 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model; + +import hudson.model.Job; +import hudson.model.JobProperty; +import hudson.model.JobPropertyDescriptor; +import net.sf.json.JSONObject; +import org.kohsuke.stapler.StaplerRequest; + +/** + * Job property which may or may not be present. + * Must define {@code config-details.jelly} or {@code config-details.groovy}. + * May define {@code help.html}. + * @since 1.637 + */ +public abstract class OptionalJobProperty> extends JobProperty { + + @Override + public OptionalJobPropertyDescriptor getDescriptor() { + return (OptionalJobPropertyDescriptor) super.getDescriptor(); + } + + public static abstract class OptionalJobPropertyDescriptor extends JobPropertyDescriptor { + + protected OptionalJobPropertyDescriptor(Class> clazz) { + super(clazz); + } + + protected OptionalJobPropertyDescriptor() {} + + @Override + public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { + return formData.optBoolean("specified") ? super.newInstance(req, formData) : null; + } + + } + +} diff --git a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java index 1fff85ec128f8fe7df87d938c62f8e21a5216224..da17b0d23a0d80153337c76fa251fa0d8a47934a 100644 --- a/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java +++ b/core/src/main/java/jenkins/model/ParameterizedJobMixIn.java @@ -41,6 +41,7 @@ import hudson.model.queue.QueueTaskFuture; import hudson.search.SearchIndexBuilder; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; +import hudson.util.AlternativeUiTextProvider; import hudson.views.BuildButtonColumn; import java.io.IOException; import java.util.ArrayList; @@ -51,7 +52,7 @@ import java.util.Map; import javax.annotation.CheckForNull; import javax.servlet.ServletException; import static javax.servlet.http.HttpServletResponse.SC_CREATED; -import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR; +import static javax.servlet.http.HttpServletResponse.SC_CONFLICT; import jenkins.util.TimeDuration; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -94,17 +95,39 @@ public abstract class ParameterizedJobMixIn & Param } /** - * Convenience method to schedule a build with the ability to wait for its result. - * Often used during functional tests ({@code JenkinsRule.assertBuildStatusSuccess}). + * Provides a standard implementation of an optional method of the same name in a {@link Job} type to schedule a build with the ability to wait for its result. + * That job method is often used during functional tests ({@code JenkinsRule.assertBuildStatusSuccess}). * @param quietPeriod seconds to wait before starting (normally 0) * @param actions various actions to associate with the scheduling, such as {@link ParametersAction} or {@link CauseAction} * @return a handle by which you may wait for the build to complete (or just start); or null if the build was not actually scheduled for some reason */ public final @CheckForNull QueueTaskFuture scheduleBuild2(int quietPeriod, Action... actions) { - return scheduleBuild2(quietPeriod, Arrays.asList(actions)); + Queue.Item i = scheduleBuild2(quietPeriod, Arrays.asList(actions)); + return i != null ? (QueueTaskFuture) i.getFuture() : null; } - private @CheckForNull QueueTaskFuture scheduleBuild2(int quietPeriod, List actions) { + /** + * Convenience method to schedule a build. + * Useful for {@link Trigger} implementations, for example. + * If you need to wait for the build to start (or finish), use {@link Queue.Item#getFuture}. + * @param job a job which might be schedulable + * @param quietPeriod seconds to wait before starting; use {@code -1} to use the job’s default settings + * @param actions various actions to associate with the scheduling, such as {@link ParametersAction} or {@link CauseAction} + * @return a newly created, or reused, queue item if the job could be scheduled; null if it was refused for some reason (e.g., some {@link Queue.QueueDecisionHandler} rejected it), or if {@code job} is not a {@link ParameterizedJob} or it is not {@link Job#isBuildable}) + * @since 1.621 + */ + public static @CheckForNull Queue.Item scheduleBuild2(final Job job, int quietPeriod, Action... actions) { + if (!(job instanceof ParameterizedJob)) { + return null; + } + return new ParameterizedJobMixIn() { + @Override protected Job asJob() { + return job; + } + }.scheduleBuild2(quietPeriod == -1 ? ((ParameterizedJob) job).getQuietPeriod() : quietPeriod, Arrays.asList(actions)); + } + + @CheckForNull Queue.Item scheduleBuild2(int quietPeriod, List actions) { if (!asJob().isBuildable()) return null; @@ -112,8 +135,7 @@ public abstract class ParameterizedJobMixIn & Param if (isParameterized() && Util.filter(queueActions, ParametersAction.class).isEmpty()) { queueActions.add(new ParametersAction(getDefaultParametersValues())); } - Queue.Item i = Jenkins.getInstance().getQueue().schedule2(asJob(), quietPeriod, queueActions).getItem(); - return i != null ? (QueueTaskFuture) i.getFuture() : null; + return Jenkins.getInstance().getQueue().schedule2(asJob(), quietPeriod, queueActions).getItem(); } private List getDefaultParametersValues() { @@ -155,6 +177,10 @@ public abstract class ParameterizedJobMixIn & Param delay = new TimeDuration(asJob().getQuietPeriod()); } + if (!asJob().isBuildable()) { + throw HttpResponses.error(SC_CONFLICT, new IOException(asJob().getFullName() + " is not buildable")); + } + // if a build is parameterized, let that take over ParametersDefinitionProperty pp = asJob().getProperty(ParametersDefinitionProperty.class); if (pp != null && !req.getMethod().equals("POST")) { @@ -170,9 +196,6 @@ public abstract class ParameterizedJobMixIn & Param return; } - if (!asJob().isBuildable()) { - throw HttpResponses.error(SC_INTERNAL_SERVER_ERROR, new IOException(asJob().getFullName() + " is not buildable")); - } Queue.Item item = Jenkins.getInstance().getQueue().schedule2(asJob(), delay.getTime(), getBuildCause(asJob(), req)).getItem(); if (item != null) { @@ -192,6 +215,9 @@ public abstract class ParameterizedJobMixIn & Param hudson.model.BuildAuthorizationToken.checkPermission(asJob(), asJob().getAuthToken(), req, rsp); ParametersDefinitionProperty pp = asJob().getProperty(ParametersDefinitionProperty.class); + if (!asJob().isBuildable()) { + throw HttpResponses.error(SC_CONFLICT, new IOException(asJob().getFullName() + " is not buildable!")); + } if (pp != null) { pp.buildWithParameters(req, rsp, delay); } else { @@ -240,13 +266,39 @@ public abstract class ParameterizedJobMixIn & Param return new CauseAction(cause); } + /** + * Allows customization of the human-readable display name to be rendered in the Build Now link. + * @see #getBuildNowText + * @since 1.624 + */ + public static final AlternativeUiTextProvider.Message BUILD_NOW_TEXT = new AlternativeUiTextProvider.Message(); + /** * Suggested implementation of {@link ParameterizedJob#getBuildNowText}. + * Uses {@link #BUILD_NOW_TEXT}. */ public final String getBuildNowText() { - // TODO is it worthwhile to define a replacement for AbstractProject.BUILD_NOW_TEXT? - // TODO move these messages (& translations) to this package - return isParameterized() ? hudson.model.Messages.AbstractProject_build_with_parameters() : hudson.model.Messages.AbstractProject_BuildNow(); + return isParameterized() ? Messages.ParameterizedJobMixIn_build_with_parameters() : AlternativeUiTextProvider.get(BUILD_NOW_TEXT, asJob(), Messages.ParameterizedJobMixIn_build_now()); + } + + /** + * Checks for the existence of a specific trigger on a job. + * @param a trigger type + * @param job a job + * @param clazz the type of the trigger + * @return a configured trigger of the requested type, or null if there is none such, or {@code job} is not a {@link ParameterizedJob} + * @since 1.621 + */ + public static @CheckForNull > T getTrigger(Job job, Class clazz) { + if (!(job instanceof ParameterizedJob)) { + return null; + } + for (Trigger t : ((ParameterizedJob) job).getTriggers().values()) { + if (clazz.isInstance(t)) { + return clazz.cast(t); + } + } + return null; } /** @@ -265,6 +317,7 @@ public abstract class ParameterizedJobMixIn & Param * Gets currently configured triggers. * You may use {@code } to configure them. * @return a map from trigger kind to instance + * @see #getTrigger */ Map> getTriggers(); diff --git a/core/src/main/java/jenkins/model/ProjectNamingStrategy.java b/core/src/main/java/jenkins/model/ProjectNamingStrategy.java index 31e4b9e81f911ecba6eaf059049edc0e0c524d1e..71863b354cabd7d859d5c783ae31a2347e65ee30 100644 --- a/core/src/main/java/jenkins/model/ProjectNamingStrategy.java +++ b/core/src/main/java/jenkins/model/ProjectNamingStrategy.java @@ -40,6 +40,7 @@ import java.util.regex.PatternSyntaxException; import javax.servlet.ServletException; import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; @@ -108,7 +109,7 @@ public abstract class ProjectNamingStrategy implements Describable pathC; try { - pathC = Class.forName("java.nio.file.Path"); - } catch (ClassNotFoundException x) { - // Java 6, do our best - if (dest.exists()) { - throw new IOException(dest + " already exists"); - } - if (src.renameTo(dest)) { - return; - } - throw new IOException("could not move " + src + " to " + dest); - } - try { - Method toPath = File.class.getMethod("toPath"); - Class copyOptionAC = Class.forName("[Ljava.nio.file.CopyOption;"); - Class.forName("java.nio.file.Files").getMethod("move", pathC, pathC, copyOptionAC).invoke(null, toPath.invoke(src), toPath.invoke(dest), Array.newInstance(copyOptionAC.getComponentType(), 0)); - } catch (InvocationTargetException x) { - Throwable cause = x.getCause(); - if (cause instanceof IOException) { - throw (IOException) cause; - } else { - throw new IOException(cause); - } + Files.move(src.toPath(), dest.toPath()); + } catch (IOException x) { + throw x; } catch (Exception x) { throw new IOException(x); } @@ -350,6 +330,12 @@ public final class RunIdMigrator { return; } for (File job : jobDirs) { + + if (job.getName().equals("builds")) { + // Might be maven modules, matrix builds, etc. which are direct children of job + unmigrateBuildsDir(job); + } + File[] kids = job.listFiles(); if (kids == null) { continue; @@ -361,7 +347,8 @@ public final class RunIdMigrator { if (kid.getName().equals("builds")) { unmigrateBuildsDir(kid); } else { - // Might be jobs, modules, promotions, etc.; we assume an ItemGroup.getRootDirFor implementation returns grandchildren. + // Might be jobs, modules, promotions, etc.; we assume an ItemGroup.getRootDirFor implementation + // returns grandchildren, unmigrateJobsDir(job) call above handles children. unmigrateJobsDir(kid); } } diff --git a/core/src/main/java/jenkins/model/TransientActionFactory.java b/core/src/main/java/jenkins/model/TransientActionFactory.java index f0871920eaf6f6fc98c271999eb1b3bade581a5b..b3d0579abce06df05795256b7adba024c616d139 100644 --- a/core/src/main/java/jenkins/model/TransientActionFactory.java +++ b/core/src/main/java/jenkins/model/TransientActionFactory.java @@ -24,12 +24,22 @@ package jenkins.model; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import hudson.ExtensionList; +import hudson.ExtensionListListener; import hudson.ExtensionPoint; import hudson.model.Action; import hudson.model.Actionable; import hudson.model.TopLevelItem; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.List; import javax.annotation.Nonnull; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Allows you to add actions to any kind of object at once. @@ -48,12 +58,77 @@ public abstract class TransientActionFactory implements ExtensionPoint { */ public abstract Class type(); + /** + * A supertype of any actions this factory might produce. + * Defined so that factories which produce irrelevant actions need not be consulted by, e.g., {@link Actionable#getAction(Class)}. + * For historical reasons this defaults to {@link Action} itself. + * If your implementation was returning multiple disparate kinds of actions, it is best to split it into two factories. + *

If an API defines a abstract {@link Action} subtype and you are providing a concrete implementation, + * you may return the API type here to delay class loading. + * @return a bound for the result of {@link #createFor} + * @since 2.34 + */ + public /* abstract */ Class actionType() { + return Action.class; + } + /** * Creates actions for a given object. * This may be called frequently for the same object, so if your implementation is expensive, do your own caching. * @param target an actionable object - * @return a possible empty set of actions + * @return a possible empty set of actions (typically either using {@link Collections#emptySet} or {@link Collections#singleton}) */ public abstract @Nonnull Collection createFor(@Nonnull T target); + /** @see no pairs/tuples in Java */ + private static class CacheKey { + private final Class type; + private final Class actionType; + CacheKey(Class type, Class actionType) { + this.type = type; + this.actionType = actionType; + } + @Override + public boolean equals(Object obj) { + return obj instanceof CacheKey && type == ((CacheKey) obj).type && actionType == ((CacheKey) obj).actionType; + } + @Override + public int hashCode() { + return type.hashCode() ^ actionType.hashCode(); + } + } + @SuppressWarnings("rawtypes") + private static final LoadingCache, LoadingCache>>> cache = + CacheBuilder.newBuilder().weakKeys().build(new CacheLoader, LoadingCache>>>() { + @Override + public LoadingCache>> load(final ExtensionList allFactories) throws Exception { + final LoadingCache>> perJenkinsCache = + CacheBuilder.newBuilder().build(new CacheLoader>>() { + @Override + public List> load(CacheKey key) throws Exception { + List> factories = new ArrayList<>(); + for (TransientActionFactory taf : allFactories) { + Class actionType = taf.actionType(); + if (taf.type().isAssignableFrom(key.type) && (key.actionType.isAssignableFrom(actionType) || actionType.isAssignableFrom(key.actionType))) { + factories.add(taf); + } + } + return factories; + } + }); + allFactories.addListener(new ExtensionListListener() { + @Override + public void onChange() { + perJenkinsCache.invalidateAll(); + } + }); + return perJenkinsCache; + } + }); + + @Restricted(NoExternalUse.class) // pending a need for it outside Actionable + public static Iterable> factoriesFor(Class type, Class actionType) { + return cache.getUnchecked(ExtensionList.lookup(TransientActionFactory.class)).getUnchecked(new CacheKey(type, actionType)); + } + } diff --git a/core/src/main/java/jenkins/model/TransientFingerprintFacetFactory.java b/core/src/main/java/jenkins/model/TransientFingerprintFacetFactory.java index 96cf7ebec4af2886c97685ba5e2a58e417de13ca..5e7826cbdde3a9bcaf475da1b239909bc100857f 100644 --- a/core/src/main/java/jenkins/model/TransientFingerprintFacetFactory.java +++ b/core/src/main/java/jenkins/model/TransientFingerprintFacetFactory.java @@ -27,7 +27,6 @@ import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Fingerprint; -import java.util.Collection; import java.util.List; /** diff --git a/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java b/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java index 008e5d2c743ef198de75121be00ec6cab23bc365..158316f00f3f818195243a423a23523f833c513b 100644 --- a/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java +++ b/core/src/main/java/jenkins/model/UnlabeledLoadStatistics.java @@ -31,11 +31,9 @@ import hudson.model.OverallLoadStatistics; import hudson.model.Queue; import hudson.model.Queue.Task; import hudson.model.queue.SubTask; -import hudson.model.queue.Tasks; import hudson.util.Iterators; import java.util.Iterator; -import java.util.List; /** * {@link LoadStatistics} that track the "free roam" jobs (whose {@link Task#getAssignedLabel()} is null) @@ -80,11 +78,7 @@ public class UnlabeledLoadStatistics extends LoadStatistics { @Override public int computeQueueLength() { - final Jenkins j = Jenkins.getInstance(); - if (j == null) { // Consider queue as empty when Jenkins is inactive - return 0; - } - return j.getQueue().strictCountBuildableItemsFor(null); + return Jenkins.getInstance().getQueue().strictCountBuildableItemsFor(null); } @Override diff --git a/core/src/main/java/jenkins/model/Uptime.java b/core/src/main/java/jenkins/model/Uptime.java index 81cce79374e30de28ea6d6d846d69a096b808f4d..190c678ff7df60f1d9f4022498d5925428b4673c 100644 --- a/core/src/main/java/jenkins/model/Uptime.java +++ b/core/src/main/java/jenkins/model/Uptime.java @@ -27,7 +27,7 @@ public class Uptime { } @Initializer(after=InitMilestone.JOB_LOADED) - public static void init() { - ExtensionList.lookup(Uptime.class).get(0).startTime = System.currentTimeMillis(); + public void init() { + startTime = System.currentTimeMillis(); } } diff --git a/core/src/main/java/jenkins/model/identity/IdentityRootAction.java b/core/src/main/java/jenkins/model/identity/IdentityRootAction.java new file mode 100644 index 0000000000000000000000000000000000000000..6497c012d1f64e678b384f0f76bb6575324e3c8b --- /dev/null +++ b/core/src/main/java/jenkins/model/identity/IdentityRootAction.java @@ -0,0 +1,97 @@ +package jenkins.model.identity; + +import hudson.Extension; +import hudson.model.UnprotectedRootAction; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import org.apache.commons.codec.Charsets; +import org.apache.commons.codec.binary.Base64; + +/** + * A simple root action that exposes the public key to users so that they do not need to search for the + * {@code X-Instance-Identity} response header, also exposes the fingerprint of the public key so that people + * can verify a fingerprint of a master before connecting to it. + * + * @since 2.16 + */ +@Extension +public class IdentityRootAction implements UnprotectedRootAction { + /** + * {@inheritDoc} + */ + @Override + public String getIconFileName() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getUrlName() { + return InstanceIdentityProvider.RSA.getKeyPair() == null ? null : "instance-identity"; + } + + /** + * Returns the PEM encoded public key. + * + * @return the PEM encoded public key. + */ + public String getPublicKey() { + RSAPublicKey key = InstanceIdentityProvider.RSA.getPublicKey(); + if (key == null) { + return null; + } + byte[] encoded = Base64.encodeBase64(key.getEncoded()); + int index = 0; + StringBuilder buf = new StringBuilder(encoded.length + 20); + while (index < encoded.length) { + int len = Math.min(64, encoded.length - index); + if (index > 0) { + buf.append("\n"); + } + buf.append(new String(encoded, index, len, Charsets.UTF_8)); + index += len; + } + return String.format("-----BEGIN PUBLIC KEY-----%n%s%n-----END PUBLIC KEY-----%n", buf.toString()); + } + + /** + * Returns the fingerprint of the public key. + * + * @return the fingerprint of the public key. + */ + public String getFingerprint() { + RSAPublicKey key = InstanceIdentityProvider.RSA.getPublicKey(); + if (key == null) { + return null; + } + // TODO replace with org.jenkinsci.remoting.util.KeyUtils once JENKINS-36871 changes are merged + try { + MessageDigest digest = MessageDigest.getInstance("MD5"); + digest.reset(); + byte[] bytes = digest.digest(key.getEncoded()); + StringBuilder result = new StringBuilder(Math.max(0, bytes.length * 3 - 1)); + for (int i = 0; i < bytes.length; i++) { + if (i > 0) { + result.append(':'); + } + int b = bytes[i] & 0xFF; + result.append(Character.forDigit((b>>4)&0x0f, 16)).append(Character.forDigit(b&0xf, 16)); + } + return result.toString(); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("JLS mandates MD5 support"); + } + } +} diff --git a/core/src/main/java/jenkins/model/identity/InstanceIdentityProvider.java b/core/src/main/java/jenkins/model/identity/InstanceIdentityProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..c65e27fa908171f2202d7fa4b61392f3bd6869cf --- /dev/null +++ b/core/src/main/java/jenkins/model/identity/InstanceIdentityProvider.java @@ -0,0 +1,301 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.model.identity; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.X509Certificate; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * A source of instance identity. + * + * @param the type of public key. + * @param the type of private key. + * @since 2.16 + */ +public abstract class InstanceIdentityProvider implements + ExtensionPoint { + + /** + * Our logger. + */ + private static final Logger LOGGER = Logger.getLogger(InstanceIdentityProvider.class.getName()); + /** + * RSA keys. + */ + public static final KeyTypes RSA = + new KeyTypes<>(RSAPublicKey.class, RSAPrivateKey.class); + /** + * DSA keys. + */ + public static final KeyTypes DSA = + new KeyTypes<>(DSAPublicKey.class, DSAPrivateKey.class); + /** + * EC keys + */ + public static final KeyTypes EC = + new KeyTypes<>(ECPublicKey.class, ECPrivateKey.class); + + /** + * Gets the {@link KeyPair} that comprises the instance identity. + * + * @return the {@link KeyPair} that comprises the instance identity. {@code null} could technically be returned in + * the event that a keypair could not be generated, for example if the specific key type of this provider + * is not permitted at the required length by the JCA policy. + */ + @CheckForNull + protected abstract KeyPair getKeyPair(); + + /** + * Shortcut to {@link KeyPair#getPublic()}. + * + * @return the public key. {@code null} if {@link #getKeyPair()} is {@code null}. + */ + @SuppressWarnings("unchecked") + @CheckForNull + protected PUB getPublicKey() { + KeyPair keyPair = getKeyPair(); + return keyPair == null ? null : (PUB) keyPair.getPublic(); + } + + /** + * Shortcut to {@link KeyPair#getPrivate()}. + * + * @return the private key. {@code null} if {@link #getKeyPair()} is {@code null}. + */ + @SuppressWarnings("unchecked") + @CheckForNull + protected PRIV getPrivateKey() { + KeyPair keyPair = getKeyPair(); + return keyPair == null ? null : (PRIV) keyPair.getPrivate(); + } + + /** + * Gets the self-signed {@link X509Certificate} that is associated with this identity. The certificate + * will must be currently valid. Repeated calls to this method may result in new certificates being generated. + * + * @return the certificate. {@code null} if {@link #getKeyPair()} is {@code null}. + */ + @CheckForNull + protected abstract X509Certificate getCertificate(); + + /** + * Holds information about the paired keytypes that can be used to form the various identity keys. + * + * @param the type of public key. + * @param the type of private key. + */ + public static final class KeyTypes { + /** + * The interface for the public key. + */ + private final Class pubKeyType; + /** + * The interface for the private key. + */ + private final Class privKeyType; + + /** + * Constructor. + * + * @param pubKeyType the interface for the public key. + * @param privKeyType the interface for the private key. + */ + private KeyTypes(Class pubKeyType, Class privKeyType) { + this.pubKeyType = pubKeyType; + this.privKeyType = privKeyType; + } + + /** + * Gets the provider of the required identity type. + * + * @param type the type of keys. + * @param the type of public key. + * @param the type of private key. + * @return the provider or {@code null} if no provider of the specified type is available. + */ + @CheckForNull + @SuppressWarnings("unchecked") + private static InstanceIdentityProvider get( + @Nonnull KeyTypes type) { + for (InstanceIdentityProvider provider : ExtensionList.lookup(InstanceIdentityProvider.class)) { + try { + KeyPair keyPair = provider.getKeyPair(); + if (keyPair != null + && type.pubKeyType.isInstance(keyPair.getPublic()) + && type.privKeyType.isInstance(keyPair.getPrivate())) { + return (InstanceIdentityProvider) provider; + } + } catch (RuntimeException e) { + LOGGER.log(Level.WARNING, + "Instance identity provider " + provider + " propagated a runtime exception", e); + } catch (Error e) { + LOGGER.log(Level.INFO, + "Encountered an error while consulting instance identity provider " + provider, e); + throw e; + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, + "Instance identity provider " + provider + " propagated an uncaught exception", e); + } + } + return null; + } + + /** + * Gets the interface for the public key. + * + * @return the interface for the public key. + */ + public Class getPublicKeyClass() { + return pubKeyType; + } + + /** + * Gets the interface for the private key. + * + * @return the interface for the private key. + */ + public Class getPrivateKeyClass() { + return privKeyType; + } + + /** + * Gets the {@link KeyPair} that comprises the instance identity. + * + * @return the {@link KeyPair} that comprises the instance identity. {@code null} could technically be + * returned in + * the event that a keypair could not be generated, for example if the specific key type of this provider + * is not permitted at the required length by the JCA policy. + */ + @CheckForNull + public KeyPair getKeyPair() { + InstanceIdentityProvider provider = get(this); + try { + return provider == null ? null : provider.getKeyPair(); + } catch (RuntimeException e) { + LOGGER.log(Level.WARNING, + "Instance identity provider " + provider + " propagated a runtime exception", e); + return null; + } catch (Error e) { + LOGGER.log(Level.INFO, + "Encountered an error while consulting instance identity provider " + provider, e); + throw e; + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, + "Instance identity provider " + provider + " propagated an uncaught exception", e); + return null; + } + } + + /** + * Shortcut to {@link KeyPair#getPublic()}. + * + * @return the public key. {@code null} if {@link #getKeyPair()} is {@code null}. + */ + @CheckForNull + public PUB getPublicKey() { + InstanceIdentityProvider provider = get(this); + try { + return provider == null ? null : provider.getPublicKey(); + } catch (RuntimeException e) { + LOGGER.log(Level.WARNING, + "Instance identity provider " + provider + " propagated a runtime exception", e); + return null; + } catch (Error e) { + LOGGER.log(Level.INFO, + "Encountered an error while consulting instance identity provider " + provider, e); + throw e; + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, + "Instance identity provider " + provider + " propagated an uncaught exception", e); + return null; + } + } + + /** + * Shortcut to {@link KeyPair#getPrivate()}. + * + * @return the private key. {@code null} if {@link #getKeyPair()} is {@code null}. + */ + @CheckForNull + public PRIV getPrivateKey() { + InstanceIdentityProvider provider = get(this); + try { + return provider == null ? null : provider.getPrivateKey(); + } catch (RuntimeException e) { + LOGGER.log(Level.WARNING, + "Instance identity provider " + provider + " propagated a runtime exception", e); + return null; + } catch (Error e) { + LOGGER.log(Level.INFO, + "Encountered an error while consulting instance identity provider " + provider, e); + throw e; + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, + "Instance identity provider " + provider + " propagated an uncaught exception", e); + return null; + } + } + + /** + * Gets the self-signed {@link X509Certificate} that is associated with this identity. The certificate + * will must be currently valid. Repeated calls to this method may result in new certificates being generated. + * + * @return the certificate. {@code null} if {@link #getKeyPair()} is {@code null}. + */ + @CheckForNull + public X509Certificate getCertificate() { + InstanceIdentityProvider provider = get(this); + try { + return provider == null ? null : provider.getCertificate(); + } catch (RuntimeException e) { + LOGGER.log(Level.WARNING, + "Instance identity provider " + provider + " propagated a runtime exception", e); + return null; + } catch (Error e) { + LOGGER.log(Level.INFO, + "Encountered an error while consulting instance identity provider " + provider, e); + throw e; + } catch (Throwable e) { + LOGGER.log(Level.SEVERE, + "Instance identity provider " + provider + " propagated an uncaught exception", e); + return null; + } + } + } + +} diff --git a/core/src/main/java/jenkins/model/item_category/Categories.java b/core/src/main/java/jenkins/model/item_category/Categories.java new file mode 100644 index 0000000000000000000000000000000000000000..fe188dafbe363332edf5108179e1b8fd3f8668ac --- /dev/null +++ b/core/src/main/java/jenkins/model/item_category/Categories.java @@ -0,0 +1,81 @@ +/* + * The MIT License + * + * Copyright (c) 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.item_category; + +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; +import org.kohsuke.stapler.export.Flavor; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import javax.servlet.ServletException; +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * It is a logic representation of a set of {@link Category}. + * + * This class is not thread-safe. + * + * @since 2.0 + */ +@ExportedBean +@Restricted(NoExternalUse.class) +public class Categories implements HttpResponse, Serializable { + + private List items; + + public Categories() { + items = new ArrayList(); + } + + @Exported(name = "categories") + public List getItems() { + return items; + } + + @Override + public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { + rsp.serveExposedBean(req, this, Flavor.JSON); + } + + @CheckForNull + public Category getItem(@Nonnull String id) { + for (Category category : items) { + if (category.getId().equals(id)) { + return category; + } + } + return null; + } + +} diff --git a/core/src/main/java/jenkins/model/item_category/Category.java b/core/src/main/java/jenkins/model/item_category/Category.java new file mode 100644 index 0000000000000000000000000000000000000000..391d7ab8e3c8f1aa95cbf10f5a54cc164f7de6a1 --- /dev/null +++ b/core/src/main/java/jenkins/model/item_category/Category.java @@ -0,0 +1,97 @@ +/* + * The MIT License + * + * Copyright 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.item_category; + +import hudson.model.TopLevelItem; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.export.Exported; +import org.kohsuke.stapler.export.ExportedBean; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * Represents an {@link ItemCategory} and its {@link TopLevelItem}s. + * + * This class is not thread-safe. + */ +@ExportedBean +@Restricted(NoExternalUse.class) +public class Category implements Serializable { + + private String id; + + private String name; + + private String description; + + private int order; + + private int minToShow; + + private List> items; + + public Category(String id, String name, String description, int order, int minToShow, List> items) { + this.id= id; + this.name = name; + this.description = description; + this.order = order; + this.minToShow = minToShow; + this.items = items; + } + + @Exported + public String getId() { + return id; + } + + @Exported + public String getName() { + return name; + } + + @Exported + public String getDescription() { + return description; + } + + @Exported + public int getOrder() { + return order; + } + + @Exported + public int getMinToShow() { + return minToShow; + } + + @Exported + public List> getItems() { + return items; + } + +} diff --git a/core/src/main/java/jenkins/model/item_category/ItemCategory.java b/core/src/main/java/jenkins/model/item_category/ItemCategory.java new file mode 100644 index 0000000000000000000000000000000000000000..6efdefd2f82e58923375478d19c1222fbfc9ae74 --- /dev/null +++ b/core/src/main/java/jenkins/model/item_category/ItemCategory.java @@ -0,0 +1,142 @@ +/* + * The MIT License + * + * Copyright (c) 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.item_category; + +import hudson.Extension; +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.TopLevelItemDescriptor; + +import javax.annotation.Nonnull; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * A category for {@link hudson.model.Item}s. + * + * @since 2.0 + */ +public abstract class ItemCategory implements ExtensionPoint { + + /** + * This field indicates how much non-default categories are required in + * order to start showing them in Jenkins. + * This field is restricted for the internal use only, because all other changes would cause binary compatibility issues. + * See JENKINS-36593 for more info. + */ + @Restricted(NoExternalUse.class) + public static int MIN_TOSHOW = 1; + + /** + * Helpful to set the order. + */ + private int order = 1; + + /** + * Identifier, e.g. "standaloneprojects", etc. + * + * @return the identifier + */ + public abstract String getId(); + + /** + * The description in plain text + * + * @return the description + */ + public abstract String getDescription(); + + /** + * A human readable name. + * + * @return the display name + */ + public abstract String getDisplayName(); + + /** + * Minimum number of items required to show the category. + * + * @return the minimum items required + */ + public abstract int getMinToShow(); + + private void setOrder(int order) { + this.order = order; + } + + public int getOrder() { + return order; + } + + /** + * A {@link ItemCategory} associated to this {@link TopLevelItemDescriptor}. + * + * @return A {@link ItemCategory}, if not found, {@link ItemCategory.UncategorizedCategory} is returned + */ + @Nonnull + public static ItemCategory getCategory(TopLevelItemDescriptor descriptor) { + int order = 0; + ExtensionList categories = ExtensionList.lookup(ItemCategory.class); + for (ItemCategory category : categories) { + if (category.getId().equals(descriptor.getCategoryId())) { + category.setOrder(++order); + return category; + } + order++; + } + return new UncategorizedCategory(); + } + + /** + * The default {@link ItemCategory}, if an item doesn't belong anywhere else, this is where it goes by default. + */ + @Extension(ordinal = Integer.MIN_VALUE) + public static final class UncategorizedCategory extends ItemCategory { + + public static final String ID = "uncategorized"; + + @Override + public String getId() { + return ID; + } + + @Override + public String getDescription() { + return Messages.Uncategorized_Description(); + } + + @Override + public String getDisplayName() { + return Messages.Uncategorized_DisplayName(); + } + + @Override + public int getMinToShow() { + return ItemCategory.MIN_TOSHOW; + } + + } + +} diff --git a/core/src/main/java/jenkins/model/item_category/NestedProjectsCategory.java b/core/src/main/java/jenkins/model/item_category/NestedProjectsCategory.java new file mode 100644 index 0000000000000000000000000000000000000000..b4501d01e44a43c91912bc72eac9c197ca00d000 --- /dev/null +++ b/core/src/main/java/jenkins/model/item_category/NestedProjectsCategory.java @@ -0,0 +1,67 @@ +/* + * The MIT License + * + * Copyright (c) 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.item_category; + +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.DoNotUse; + +/** + * Designed for project hierarchies with folders. + * + * This category should be moved to cloudbees-folder-plugin short-term. + * Really when upgrades its baseline to 2.0. + * + * @since 2.0 + */ +@Restricted(DoNotUse.class) +@Extension(ordinal = -100) +public class NestedProjectsCategory extends ItemCategory { + + /** + * TODO Make public when be moved to cloudbees-folder-plugin. + */ + private static final String ID = "nested-projects"; + + @Override + public String getId() { + return ID; + } + + @Override + public String getDescription() { + return Messages.NestedProjects_Description(); + } + + @Override + public String getDisplayName() { + return Messages.NestedProjects_DisplayName(); + } + + @Override + public int getMinToShow() { + return ItemCategory.MIN_TOSHOW; + } +} diff --git a/core/src/main/java/jenkins/model/item_category/StandaloneProjectsCategory.java b/core/src/main/java/jenkins/model/item_category/StandaloneProjectsCategory.java new file mode 100644 index 0000000000000000000000000000000000000000..cf6d0daeaf93401147ece819e1861cd5349e1809 --- /dev/null +++ b/core/src/main/java/jenkins/model/item_category/StandaloneProjectsCategory.java @@ -0,0 +1,58 @@ +/* + * The MIT License + * + * Copyright (c) 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.item_category; + +import hudson.Extension; + +/** + * Designed for projects with a self-contained configuration and history. + * + * @since 2.0 + */ +@Extension(ordinal = -100) +public class StandaloneProjectsCategory extends ItemCategory { + + public static final String ID = "standalone-projects"; + + @Override + public String getId() { + return ID; + } + + @Override + public String getDescription() { + return Messages.StandaloneProjects_Description(); + } + + @Override + public String getDisplayName() { + return Messages.StandaloneProjects_DisplayName(); + } + + @Override + public int getMinToShow() { + return ItemCategory.MIN_TOSHOW; + } +} diff --git a/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java b/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java index c93b4e8be1ce187a1f6efed13f130fe11cfabfa7..a36da7421bbb26118dff34086197a99294e5d1c4 100644 --- a/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java +++ b/core/src/main/java/jenkins/model/lazy/AbstractLazyLoadRunMap.java @@ -41,11 +41,12 @@ import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.CheckForNull; - -import static jenkins.model.lazy.AbstractLazyLoadRunMap.Direction.*; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import static jenkins.model.lazy.AbstractLazyLoadRunMap.Direction.ASC; +import static jenkins.model.lazy.AbstractLazyLoadRunMap.Direction.DESC; + /** * {@link SortedMap} that keeps build records by their build numbers, in the descending order * (newer ones first.) @@ -291,6 +292,18 @@ public abstract class AbstractLazyLoadRunMap extends AbstractMap i return getByNumber(n); } + /** + * Checks if the the specified build exists. + * + * @param number the build number to probe. + * @return {@code true} if there is an run for the corresponding number, note that this does not mean that + * the corresponding record will load. + * @since 2.14 + */ + public boolean runExists(int number) { + return numberOnDisk.contains(number); + } + /** * Finds the build #M where M is nearby the given 'n'. * @@ -353,12 +366,32 @@ public abstract class AbstractLazyLoadRunMap extends AbstractMap i if (v!=null) return v; // already in memory // otherwise fall through to load } - return load(n, null); + synchronized (this) { + if (index.byNumber.containsKey(n)) { // JENKINS-22767: recheck inside lock + BuildReference ref = index.byNumber.get(n); + if (ref == null) { + return null; + } + R v = unwrap(ref); + if (v != null) { + return v; + } + } + return load(n, null); + } + } + + /** + * @return the highest recorded build number, or 0 if there are none + */ + @Restricted(NoExternalUse.class) + public synchronized int maxNumberOnDisk() { + return numberOnDisk.max(); } protected final synchronized void proposeNewNumber(int number) throws IllegalStateException { - if (numberOnDisk.isInRange(numberOnDisk.ceil(number))) { - throw new IllegalStateException("cannot create a build with number " + number + " since that (or higher) is already in use among " + numberOnDisk); + if (number <= maxNumberOnDisk()) { + throw new IllegalStateException("JENKINS-27530: cannot create a build with number " + number + " since that (or higher) is already in use among " + numberOnDisk); } } @@ -443,7 +476,8 @@ public abstract class AbstractLazyLoadRunMap extends AbstractMap i * * @return null if the data failed to load. */ - protected R load(int n, Index editInPlace) { + private R load(int n, Index editInPlace) { + assert Thread.holdsLock(this); assert dir != null; R v = load(new File(dir, String.valueOf(n)), editInPlace); if (v==null && editInPlace!=null) { @@ -460,7 +494,8 @@ public abstract class AbstractLazyLoadRunMap extends AbstractMap i * If non-null, update this data structure. * Otherwise do a copy-on-write of {@link #index} */ - protected synchronized R load(File dataDir, Index editInPlace) { + private R load(File dataDir, Index editInPlace) { + assert Thread.holdsLock(this); try { R r = retrieve(dataDir); if (r==null) return null; diff --git a/core/src/main/java/jenkins/model/lazy/BuildReference.java b/core/src/main/java/jenkins/model/lazy/BuildReference.java index 93546d46e15e7882f25ac6b9491c3574c23e73d5..25f460b27fc9f8d69098b5bd0fb83703093ee151 100644 --- a/core/src/main/java/jenkins/model/lazy/BuildReference.java +++ b/core/src/main/java/jenkins/model/lazy/BuildReference.java @@ -3,6 +3,7 @@ package jenkins.model.lazy; import hudson.Extension; import hudson.ExtensionList; import hudson.ExtensionPoint; +import jenkins.util.SystemProperties; import hudson.model.Run; import java.lang.ref.Reference; import java.lang.ref.SoftReference; @@ -144,7 +145,7 @@ public final class BuildReference { @Extension(ordinal=Double.NEGATIVE_INFINITY) public static final class DefaultHolderFactory implements HolderFactory { public static final String MODE_PROPERTY = "jenkins.model.lazy.BuildReference.MODE"; - private static final String mode = System.getProperty(MODE_PROPERTY); + private static final String mode = SystemProperties.getString(MODE_PROPERTY); @Override public Holder make(R referent) { if (mode == null || mode.equals("soft")) { diff --git a/core/src/main/java/jenkins/model/lazy/LazyBuildMixIn.java b/core/src/main/java/jenkins/model/lazy/LazyBuildMixIn.java index 99c48f820b1357a39f3636603852eb09a04577e1..bd727d5d5808635e9edb14b2684a513c450dcc4a 100644 --- a/core/src/main/java/jenkins/model/lazy/LazyBuildMixIn.java +++ b/core/src/main/java/jenkins/model/lazy/LazyBuildMixIn.java @@ -102,6 +102,12 @@ public abstract class LazyBuildMixIn & Queue.Task & @SuppressWarnings("unchecked") public void onLoad(ItemGroup parent, String name) throws IOException { RunMap _builds = createBuildRunMap(); + int max = _builds.maxNumberOnDisk(); + int next = asJob().getNextBuildNumber(); + if (next <= max) { + LOGGER.log(Level.WARNING, "JENKINS-27530: improper nextBuildNumber {0} detected in {1} with highest build number {2}; adjusting", new Object[] {next, asJob(), max}); + asJob().updateNextBuildNumber(max + 1); + } RunMap currentBuilds = this.builds; if (parent != null) { // are we overwriting what currently exist? @@ -123,6 +129,7 @@ public abstract class LazyBuildMixIn & Queue.Task & if (r.isBuilding()) { // Do not use RunMap.put(Run): _builds.put(r.getNumber(), r); + LOGGER.log(Level.FINE, "keeping reloaded {0}", r); } } } @@ -178,13 +185,11 @@ public abstract class LazyBuildMixIn & Queue.Task & builds.put(lastBuild); lastBuild.getPreviousBuild(); // JENKINS-20662: create connection to previous build return lastBuild; - } catch (InstantiationException e) { - throw new Error(e); - } catch (IllegalAccessException e) { - throw new Error(e); } catch (InvocationTargetException e) { + LOGGER.log(Level.WARNING, String.format("A new build could not be created in job %s", asJob().getFullName()), e); throw handleInvocationTargetException(e); - } catch (NoSuchMethodException e) { + } catch (ReflectiveOperationException | IllegalStateException e) { + LOGGER.log(Level.WARNING, String.format("A new build could not be created in job %s", asJob().getFullName()), e); throw new Error(e); } } diff --git a/core/src/main/java/jenkins/model/lazy/SortedIntList.java b/core/src/main/java/jenkins/model/lazy/SortedIntList.java index 27933fd47e44476f42b5e6a0146c990d6e33c9fd..24f0835f7a0cd7fb75aa022b418fd582a5391769 100644 --- a/core/src/main/java/jenkins/model/lazy/SortedIntList.java +++ b/core/src/main/java/jenkins/model/lazy/SortedIntList.java @@ -83,6 +83,10 @@ class SortedIntList extends AbstractList { return size; } + public int max() { + return size > 0 ? data[size - 1] : 0; + } + @Override public boolean add(Integer i) { return add(i.intValue()); diff --git a/core/src/main/java/jenkins/model/queue/AsynchronousExecution.java b/core/src/main/java/jenkins/model/queue/AsynchronousExecution.java index e75a12e295085e8c04a14eae4388d3a420e7add8..9189a4e630b72d3948739121d0d9a0091f9dd6e5 100644 --- a/core/src/main/java/jenkins/model/queue/AsynchronousExecution.java +++ b/core/src/main/java/jenkins/model/queue/AsynchronousExecution.java @@ -24,19 +24,16 @@ package jenkins.model.queue; -import hudson.model.Computer; import hudson.model.Executor; -import hudson.model.ExecutorListener; import hudson.model.OneOffExecutor; -import hudson.model.Queue.Executable; import hudson.model.Queue.FlyweightTask; import hudson.model.Resource; import hudson.model.ResourceActivity; import hudson.model.ResourceController; import hudson.model.ResourceList; import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import javax.annotation.concurrent.GuardedBy; -import jenkins.model.Jenkins; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -97,13 +94,16 @@ public abstract class AsynchronousExecution extends RuntimeException { /** * Obtains the associated executor. + * @return Associated Executor. May be {@code null} if {@link #setExecutor(hudson.model.Executor)} + * has not been called yet. */ + @CheckForNull public synchronized final Executor getExecutor() { return executor; } @Restricted(NoExternalUse.class) - public synchronized final void setExecutor(Executor executor) { + public synchronized final void setExecutor(@Nonnull Executor executor) { assert this.executor==null; this.executor = executor; diff --git a/core/src/main/java/jenkins/model/queue/CompositeCauseOfBlockage.java b/core/src/main/java/jenkins/model/queue/CompositeCauseOfBlockage.java new file mode 100644 index 0000000000000000000000000000000000000000..9cb04c3bb7d60743fdfacff93fe998af930be5dd --- /dev/null +++ b/core/src/main/java/jenkins/model/queue/CompositeCauseOfBlockage.java @@ -0,0 +1,63 @@ +/* + * The MIT License + * + * Copyright 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.model.queue; + +import hudson.model.TaskListener; +import hudson.model.queue.CauseOfBlockage; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Represents the fact that there was at least one {@link hudson.model.Queue.JobOffer} which rejected a task. + */ +@Restricted(NoExternalUse.class) +public class CompositeCauseOfBlockage extends CauseOfBlockage { + + public final Map uniqueReasons; + + public CompositeCauseOfBlockage(List delegates) { + uniqueReasons = new TreeMap<>(); + for (CauseOfBlockage delegate : delegates) { + uniqueReasons.put(delegate.getShortDescription(), delegate); + } + } + + @Override + public String getShortDescription() { + return StringUtils.join(uniqueReasons.keySet(), "; "); + } + + @Override + public void print(TaskListener listener) { + for (CauseOfBlockage delegate : uniqueReasons.values()) { + delegate.print(listener); + } + } + +} diff --git a/core/src/main/java/jenkins/mvn/DefaultGlobalSettingsProvider.java b/core/src/main/java/jenkins/mvn/DefaultGlobalSettingsProvider.java index f6b9d0ed602eff39f70c8d50af77886dcafb3bf6..8aaf5b2fa86b2e725cb1ce588c0065b4a3219f2d 100644 --- a/core/src/main/java/jenkins/mvn/DefaultGlobalSettingsProvider.java +++ b/core/src/main/java/jenkins/mvn/DefaultGlobalSettingsProvider.java @@ -5,6 +5,7 @@ import hudson.FilePath; import hudson.model.AbstractBuild; import hudson.model.TaskListener; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -23,7 +24,7 @@ public class DefaultGlobalSettingsProvider extends GlobalSettingsProvider { return null; } - @Extension(ordinal = 99) + @Extension(ordinal = 99) @Symbol("standard") public static class DescriptorImpl extends GlobalSettingsProviderDescriptor { @Override diff --git a/core/src/main/java/jenkins/mvn/DefaultSettingsProvider.java b/core/src/main/java/jenkins/mvn/DefaultSettingsProvider.java index cc01a999268de7d4cedf3b46d6189db5bbaa137b..5a5bb9facaf8690516c4023f78cf64013effa6cb 100644 --- a/core/src/main/java/jenkins/mvn/DefaultSettingsProvider.java +++ b/core/src/main/java/jenkins/mvn/DefaultSettingsProvider.java @@ -5,6 +5,7 @@ import hudson.FilePath; import hudson.model.AbstractBuild; import hudson.model.TaskListener; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -23,7 +24,7 @@ public class DefaultSettingsProvider extends SettingsProvider { return null; } - @Extension(ordinal = 99) + @Extension(ordinal = 99) @Symbol("standard") public static class DescriptorImpl extends SettingsProviderDescriptor { @Override diff --git a/core/src/main/java/jenkins/mvn/FilePathGlobalSettingsProvider.java b/core/src/main/java/jenkins/mvn/FilePathGlobalSettingsProvider.java index 4e5b9ed3229d0d56e92ca1f400290c3b361738cd..39690a04725dce102185039a7a75b02a3e8035e1 100644 --- a/core/src/main/java/jenkins/mvn/FilePathGlobalSettingsProvider.java +++ b/core/src/main/java/jenkins/mvn/FilePathGlobalSettingsProvider.java @@ -9,7 +9,6 @@ import hudson.model.TaskListener; import hudson.util.IOUtils; import java.io.File; -import java.io.IOException; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.DataBoundConstructor; diff --git a/core/src/main/java/jenkins/mvn/FilePathSettingsProvider.java b/core/src/main/java/jenkins/mvn/FilePathSettingsProvider.java index a4de07bdf60639a6ec6c051a9bb6669056ab5947..f4c22cd35626c73f115794f283d796e77dd829ca 100644 --- a/core/src/main/java/jenkins/mvn/FilePathSettingsProvider.java +++ b/core/src/main/java/jenkins/mvn/FilePathSettingsProvider.java @@ -11,6 +11,7 @@ import hudson.util.IOUtils; import java.io.File; import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -61,7 +62,7 @@ public class FilePathSettingsProvider extends SettingsProvider { } } - @Extension(ordinal = 10) + @Extension(ordinal = 10) @Symbol("filePath") public static class DescriptorImpl extends SettingsProviderDescriptor { @Override diff --git a/core/src/main/java/jenkins/mvn/GlobalMavenConfig.java b/core/src/main/java/jenkins/mvn/GlobalMavenConfig.java index 67ace424e899676b31c69784a0fe2edef9d40e94..b8d0ebe4a5f0b6b7d8c9afe7ae252d68429cc734 100644 --- a/core/src/main/java/jenkins/mvn/GlobalMavenConfig.java +++ b/core/src/main/java/jenkins/mvn/GlobalMavenConfig.java @@ -2,12 +2,13 @@ package jenkins.mvn; import hudson.Extension; import jenkins.model.GlobalConfiguration; -import net.sf.json.JSONObject; +import jenkins.model.GlobalConfigurationCategory; +import jenkins.tools.ToolConfigurationCategory; -import org.kohsuke.stapler.StaplerRequest; +import org.jenkinsci.Symbol; //as close as it gets to the global Maven Project configuration -@Extension(ordinal = 50) +@Extension(ordinal = 50) @Symbol("maven") public class GlobalMavenConfig extends GlobalConfiguration { private SettingsProvider settingsProvider; private GlobalSettingsProvider globalSettingsProvider; @@ -17,9 +18,8 @@ public class GlobalMavenConfig extends GlobalConfiguration { } @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { - req.bindJSON(this, json); - return true; + public ToolConfigurationCategory getCategory() { + return GlobalConfigurationCategory.get(ToolConfigurationCategory.class); } public void setGlobalSettingsProvider(GlobalSettingsProvider globalSettingsProvider) { diff --git a/core/src/main/java/jenkins/scm/DefaultSCMCheckoutStrategyImpl.java b/core/src/main/java/jenkins/scm/DefaultSCMCheckoutStrategyImpl.java index 95291915e5ab018ef069034d3013b793d8eb7950..ec0ca2ecdc521c5f4fc0a55338c2b6054e0d5b6b 100644 --- a/core/src/main/java/jenkins/scm/DefaultSCMCheckoutStrategyImpl.java +++ b/core/src/main/java/jenkins/scm/DefaultSCMCheckoutStrategyImpl.java @@ -2,6 +2,7 @@ package jenkins.scm; import hudson.Extension; import hudson.model.AbstractProject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.DataBoundConstructor; /** @@ -12,7 +13,7 @@ public class DefaultSCMCheckoutStrategyImpl extends SCMCheckoutStrategy { @DataBoundConstructor public DefaultSCMCheckoutStrategyImpl() {} - @Extension + @Extension @Symbol("standard") public static class DescriptorImpl extends SCMCheckoutStrategyDescriptor { @Override public String getDisplayName() { diff --git a/core/src/main/java/jenkins/scm/SCMDecisionHandler.java b/core/src/main/java/jenkins/scm/SCMDecisionHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..cd6ba8fdb4113ff5be55ac4d381b487b12d4e783 --- /dev/null +++ b/core/src/main/java/jenkins/scm/SCMDecisionHandler.java @@ -0,0 +1,87 @@ +/* + * The MIT License + * + * Copyright (c) 2016, Stephen Connolly. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.scm; + +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Item; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * Extension point for various decisions about SCM operations for {@link Item} instances. + * + * @since 2.11 + */ +public abstract class SCMDecisionHandler implements ExtensionPoint { + /** + * This handler is consulted every time someone tries to run a polling of an {@link Item}. + * If any of the registered handlers returns false, the {@link Item} will not be polled. + * + * @param item The item. + */ + public abstract boolean shouldPoll(@Nonnull Item item); + + /** + * All registered {@link SCMDecisionHandler}s + */ + @Nonnull + public static ExtensionList all() { + return ExtensionList.lookup(SCMDecisionHandler.class); + } + + /** + * Returns the first {@link SCMDecisionHandler} that returns {@code false} from {@link #shouldPoll(Item)} + * @param item the item + * @return the first veto or {@code null} if there are no vetos + */ + @CheckForNull + public static SCMDecisionHandler firstShouldPollVeto(@Nonnull Item item) { + for (SCMDecisionHandler handler : all()) { + if (!handler.shouldPoll(item)) { + return handler; + } + } + return null; + } + + /** + * Returns the {@link SCMDecisionHandler} instances that return {@code false} from {@link #shouldPoll(Item)} + * @param item the item + * @return the {@link SCMDecisionHandler} instances vetoing the polling of the specified item. + */ + @Nonnull + public static List listShouldPollVetos(@Nonnull Item item) { + List result = new ArrayList<>(); + for (SCMDecisionHandler handler : all()) { + if (!handler.shouldPoll(item)) { + result.add(handler); + } + } + return result; + } + +} diff --git a/core/src/main/java/jenkins/security/ApiTokenProperty.java b/core/src/main/java/jenkins/security/ApiTokenProperty.java index 202696243ce5a0559d143ea17213f772b955045f..34fe62ebb42b7c9cf2dadbcb9d31f5531a616f0c 100644 --- a/core/src/main/java/jenkins/security/ApiTokenProperty.java +++ b/core/src/main/java/jenkins/security/ApiTokenProperty.java @@ -24,15 +24,18 @@ package jenkins.security; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.model.User; import hudson.model.UserProperty; import hudson.model.UserPropertyDescriptor; +import hudson.security.ACL; import hudson.util.HttpResponses; import hudson.util.Secret; import jenkins.model.Jenkins; import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.HttpResponse; @@ -40,7 +43,13 @@ import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import java.io.IOException; +import java.nio.charset.Charset; +import java.security.MessageDigest; import java.security.SecureRandom; +import javax.annotation.Nonnull; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** * Remembers the API token for this user, that can be used like a password to login. @@ -53,6 +62,16 @@ import java.security.SecureRandom; public class ApiTokenProperty extends UserProperty { private volatile Secret apiToken; + /** + * If enabled, shows API tokens to users with {@link Jenkins#ADMINISTER) permissions. + * Disabled by default due to the security reasons. + * If enabled, it restores the original Jenkins behavior (SECURITY-200). + * @since 1.638 + */ + private static final boolean SHOW_TOKEN_TO_ADMINS = + SystemProperties.getBoolean(ApiTokenProperty.class.getName() + ".showTokenToAdmins"); + + @DataBoundConstructor public ApiTokenProperty() { _changeApiToken(); @@ -66,7 +85,24 @@ public class ApiTokenProperty extends UserProperty { apiToken = Secret.fromString(seed); } + /** + * Gets the API token. + * The method performs security checks since 1.638. Only the current user and SYSTEM may see it. + * Users with {@link Jenkins#ADMINISTER} may be allowed to do it using {@link #SHOW_TOKEN_TO_ADMINS}. + * + * @return API Token. Never null, but may be {@link Messages#ApiTokenProperty_ChangeToken_TokenIsHidden()} + * if the user has no appropriate permissions. + * @since 1.426, and since 1.638 the method performs security checks + */ + @Nonnull public String getApiToken() { + return hasPermissionToSeeToken() ? getApiTokenInsecure() + : Messages.ApiTokenProperty_ChangeToken_TokenIsHidden(); + } + + @Nonnull + @Restricted(NoExternalUse.class) + /*package*/ String getApiTokenInsecure() { String p = apiToken.getPlainText(); if (p.equals(Util.getDigestOf(Jenkins.getInstance().getSecretKey()+":"+user.getId()))) { // if the current token is the initial value created by pre SECURITY-49 Jenkins, we can't use that. @@ -77,7 +113,34 @@ public class ApiTokenProperty extends UserProperty { } public boolean matchesPassword(String password) { - return getApiToken().equals(password); + String token = getApiTokenInsecure(); + // String.equals isn't constant time, but this is + return MessageDigest.isEqual(password.getBytes(Charset.forName("US-ASCII")), + token.getBytes(Charset.forName("US-ASCII"))); + } + + private boolean hasPermissionToSeeToken() { + final Jenkins jenkins = Jenkins.getInstance(); + + // Administrators can do whatever they want + if (SHOW_TOKEN_TO_ADMINS && jenkins.hasPermission(Jenkins.ADMINISTER)) { + return true; + } + + + final User current = User.current(); + if (current == null) { // Anonymous + return false; + } + + // SYSTEM user is always eligible to see tokens + if (Jenkins.getAuthentication() == ACL.SYSTEM) { + return true; + } + + //TODO: replace by IdStrategy in newer Jenkins versions + //return User.idStrategy().equals(user.getId(), current.getId()); + return StringUtils.equals(user.getId(), current.getId()); } public void changeApiToken() throws IOException { @@ -97,7 +160,7 @@ public class ApiTokenProperty extends UserProperty { return this; } - @Extension + @Extension @Symbol("apiToken") public static final class DescriptorImpl extends UserPropertyDescriptor { public String getDisplayName() { return Messages.ApiTokenProperty_DisplayName(); @@ -124,7 +187,9 @@ public class ApiTokenProperty extends UserProperty { p.changeApiToken(); } rsp.setHeader("script","document.getElementById('apiToken').value='"+p.getApiToken()+"'"); - return HttpResponses.html(Messages.ApiTokenProperty_ChangeToken_Success()); + return HttpResponses.html(p.hasPermissionToSeeToken() + ? Messages.ApiTokenProperty_ChangeToken_Success() + : Messages.ApiTokenProperty_ChangeToken_SuccessHidden()); } } diff --git a/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java b/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java index 6f8c56ba465a71dcf1f135ea7365ea06c0b93dea..a192dddc5fc3abff2c05705aab255344ca2f6ce2 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java +++ b/core/src/main/java/jenkins/security/BasicHeaderApiTokenAuthenticator.java @@ -24,7 +24,7 @@ public class BasicHeaderApiTokenAuthenticator extends BasicHeaderAuthenticator { @Override public Authentication authenticate(HttpServletRequest req, HttpServletResponse rsp, String username, String password) throws ServletException { // attempt to authenticate as API token - User u = User.get(username); + User u = User.getById(username, true); ApiTokenProperty t = u.getProperty(ApiTokenProperty.class); if (t!=null && t.matchesPassword(password)) { try { @@ -38,7 +38,6 @@ public class BasicHeaderApiTokenAuthenticator extends BasicHeaderAuthenticator { throw new ServletException(x); } } - return null; } diff --git a/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java b/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java index bd6a9bd7e8b4a5c408c689be27f063ff5a29bfd8..ade67de48a51a28443255c1c31b7c82fae483099 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java +++ b/core/src/main/java/jenkins/security/BasicHeaderAuthenticator.java @@ -2,7 +2,6 @@ package jenkins.security; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import org.acegisecurity.Authentication; import javax.servlet.ServletException; diff --git a/core/src/main/java/jenkins/security/BasicHeaderProcessor.java b/core/src/main/java/jenkins/security/BasicHeaderProcessor.java index 6bec1a2e4a2a660565113aaf7d54b77dc13f333a..1469fa841eacca4bf5cd6d01a21def7d85bad7c3 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderProcessor.java +++ b/core/src/main/java/jenkins/security/BasicHeaderProcessor.java @@ -158,5 +158,5 @@ public class BasicHeaderProcessor implements Filter { public void destroy() { } - private static final Logger LOGGER = Logger.getLogger(ApiTokenFilter.class.getName()); + private static final Logger LOGGER = Logger.getLogger(BasicHeaderProcessor.class.getName()); } diff --git a/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java b/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java index 3b41c006ddcc9f89cac44f042ca425bdc523c011..4e3d60f7bd51385c7ae0326472146792542305f0 100644 --- a/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java +++ b/core/src/main/java/jenkins/security/BasicHeaderRealPasswordAuthenticator.java @@ -15,6 +15,7 @@ package jenkins.security; import hudson.Extension; +import jenkins.util.SystemProperties; import jenkins.ExtensionFilter; import jenkins.model.Jenkins; import org.acegisecurity.Authentication; @@ -69,5 +70,5 @@ public class BasicHeaderRealPasswordAuthenticator extends BasicHeaderAuthenticat * Legacy property to disable the real password support. * Now that this is an extension, {@link ExtensionFilter} is a better way to control this. */ - public static boolean DISABLE = Boolean.getBoolean("jenkins.security.ignoreBasicAuth"); + public static boolean DISABLE = SystemProperties.getBoolean("jenkins.security.ignoreBasicAuth"); } diff --git a/core/src/main/java/jenkins/security/ChannelConfigurator.java b/core/src/main/java/jenkins/security/ChannelConfigurator.java index a371ae540126f44b785e42b2a65aac8d47045767..fd7c26e229e6f6fe44fe8f6a9ee8d4fb14b37c9d 100644 --- a/core/src/main/java/jenkins/security/ChannelConfigurator.java +++ b/core/src/main/java/jenkins/security/ChannelConfigurator.java @@ -30,7 +30,7 @@ public abstract class ChannelConfigurator implements ExtensionPoint { * *

*
{@link SlaveComputer} - *
When a channel is being established to talk to a slave. + *
When a channel is being established to talk to a agent. *
*/ public void onChannelBuilding(ChannelBuilder builder, @Nullable Object context) {} diff --git a/core/src/main/java/jenkins/security/ConfidentialKey.java b/core/src/main/java/jenkins/security/ConfidentialKey.java index a0167f478d680e5fe1b8931170cb8ca044384fea..a9ac452768dce7218e539bdcf13890670b84d63b 100644 --- a/core/src/main/java/jenkins/security/ConfidentialKey.java +++ b/core/src/main/java/jenkins/security/ConfidentialKey.java @@ -3,7 +3,6 @@ package jenkins.security; import hudson.scm.SCM; import hudson.tasks.Builder; import hudson.util.Secret; -import jenkins.slaves.JnlpSlaveAgentProtocol; import javax.annotation.CheckForNull; import java.io.IOException; diff --git a/core/src/main/java/jenkins/security/ConfidentialStore.java b/core/src/main/java/jenkins/security/ConfidentialStore.java index 9b3efdbec6956319f2b2f0eb26eea771789d6d47..9434035d2a53a5f61750ce0d7f9575e249225d90 100644 --- a/core/src/main/java/jenkins/security/ConfidentialStore.java +++ b/core/src/main/java/jenkins/security/ConfidentialStore.java @@ -2,7 +2,6 @@ package jenkins.security; import hudson.Extension; import hudson.Lookup; -import hudson.init.InitMilestone; import hudson.util.Secret; import hudson.util.Service; import jenkins.model.Jenkins; @@ -11,7 +10,6 @@ import org.kohsuke.MetaInfServices; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import java.io.IOException; -import java.security.SecureRandom; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -64,9 +62,6 @@ public abstract class ConfidentialStore { if (TEST!=null) return TEST.get(); Jenkins j = Jenkins.getInstance(); - if (j == null) { - throw new IllegalStateException("cannot initialize confidential key store until Jenkins has started"); - } Lookup lookup = j.lookup; ConfidentialStore cs = lookup.get(ConfidentialStore.class); if (cs==null) { diff --git a/core/src/main/java/jenkins/security/FrameOptionsPageDecorator.java b/core/src/main/java/jenkins/security/FrameOptionsPageDecorator.java index bc47e231b56c28effaf9e66c018500bb83377479..eaade662f435a341429f09926613e47416def289 100644 --- a/core/src/main/java/jenkins/security/FrameOptionsPageDecorator.java +++ b/core/src/main/java/jenkins/security/FrameOptionsPageDecorator.java @@ -1,7 +1,9 @@ package jenkins.security; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.model.PageDecorator; +import org.jenkinsci.Symbol; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; @@ -10,8 +12,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse; * * @since 1.581 */ -@Extension(ordinal = 1000) +@Extension(ordinal = 1000) @Symbol("frameOptions") public class FrameOptionsPageDecorator extends PageDecorator { @Restricted(NoExternalUse.class) - public static boolean enabled = Boolean.valueOf(System.getProperty(FrameOptionsPageDecorator.class.getName() + ".enabled", "true")); + public static boolean enabled = Boolean.valueOf(SystemProperties.getString(FrameOptionsPageDecorator.class.getName() + ".enabled", "true")); } diff --git a/core/src/main/java/jenkins/security/ImpersonatingUserDetailsService.java b/core/src/main/java/jenkins/security/ImpersonatingUserDetailsService.java index c1dbf8f69e29c7ac0bd414cd3057687a2c955b1d..5e3d62e49ad1b9fb13de4ef7eb8aff8edb0d5711 100644 --- a/core/src/main/java/jenkins/security/ImpersonatingUserDetailsService.java +++ b/core/src/main/java/jenkins/security/ImpersonatingUserDetailsService.java @@ -39,7 +39,7 @@ public class ImpersonatingUserDetailsService implements UserDetailsService { protected UserDetails attemptToImpersonate(String username, RuntimeException e) { // this backend cannot tell if the user name exists or not. so substitute by what we know - User u = User.get(username, false, emptyMap()); + User u = User.getById(username, false); if (u!=null) { LastGrantedAuthoritiesProperty p = u.getProperty(LastGrantedAuthoritiesProperty.class); if (p!=null) diff --git a/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java b/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java index 8fc7042d0c708f9fd6f3229497285c99d9b8ea14..0a2ec20625cf108b983d76c75b46f4d8714dcbf4 100644 --- a/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java +++ b/core/src/main/java/jenkins/security/LastGrantedAuthoritiesProperty.java @@ -12,6 +12,7 @@ import org.acegisecurity.Authentication; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.GrantedAuthorityImpl; import org.acegisecurity.userdetails.UserDetails; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; import javax.annotation.Nonnull; @@ -100,7 +101,9 @@ public class LastGrantedAuthoritiesProperty extends UserProperty { @Override protected void loggedIn(@Nonnull String username) { try { - User u = User.get(username); + // user should have been created but may not have been saved for some realms + // but as this is a callback of a successful login we can safely create the user. + User u = User.getById(username, true); LastGrantedAuthoritiesProperty o = u.getProperty(LastGrantedAuthoritiesProperty.class); if (o==null) u.addProperty(o=new LastGrantedAuthoritiesProperty()); @@ -132,7 +135,7 @@ public class LastGrantedAuthoritiesProperty extends UserProperty { */ // try { -// User u = User.get(username,false,Collections.emptyMap()); +// User u = User.getById(username,false); // LastGrantedAuthoritiesProperty o = u.getProperty(LastGrantedAuthoritiesProperty.class); // if (o!=null) // o.invalidate(); @@ -146,17 +149,13 @@ public class LastGrantedAuthoritiesProperty extends UserProperty { } } - @Extension + @Extension @Symbol("lastGrantedAuthorities") public static final class DescriptorImpl extends UserPropertyDescriptor { - public String getDisplayName() { - return null; // not visible - } - @Override - public LastGrantedAuthoritiesProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return new LastGrantedAuthoritiesProperty(); + public boolean isEnabled() { + return false; } - + public UserProperty newInstance(User user) { return null; } diff --git a/core/src/main/java/jenkins/security/MasterToSlaveCallable.java b/core/src/main/java/jenkins/security/MasterToSlaveCallable.java index 8be5b98305c1eed129da241c454a76ce49b3ce4e..e348ec1e4903d3fb75b03de9baecf802203be937 100644 --- a/core/src/main/java/jenkins/security/MasterToSlaveCallable.java +++ b/core/src/main/java/jenkins/security/MasterToSlaveCallable.java @@ -1,13 +1,11 @@ package jenkins.security; import hudson.remoting.Callable; -import org.jenkinsci.remoting.Role; import org.jenkinsci.remoting.RoleChecker; -import java.util.Collection; /** - * Convenient {@link Callable} meant to be run on slave. + * Convenient {@link Callable} meant to be run on agent. * * @author Kohsuke Kawaguchi * @since 1.THU diff --git a/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java b/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java index 05e00097c9bd3841171ed5c9572206ef1bc31569..03f609f16360b65c15326fdf78c7e5babe8cbbd4 100644 --- a/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java +++ b/core/src/main/java/jenkins/security/QueueItemAuthenticatorConfiguration.java @@ -1,17 +1,15 @@ package jenkins.security; -import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; -import hudson.model.AbstractProject; -import hudson.security.ACL; import hudson.util.DescribableList; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import net.sf.json.JSONObject; -import org.acegisecurity.Authentication; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.StaplerRequest; +import javax.annotation.Nonnull; import java.io.IOException; import java.util.List; @@ -21,7 +19,7 @@ import java.util.List; * @author Kohsuke Kawaguchi * @since 1.520 */ -@Extension +@Extension @Symbol("queueItemAuthenticator") public class QueueItemAuthenticatorConfiguration extends GlobalConfiguration { private final DescribableList authenticators = new DescribableList(this); @@ -61,7 +59,7 @@ public class QueueItemAuthenticatorConfiguration extends GlobalConfiguration { @Extension(ordinal = 100) public static class ProviderImpl extends QueueItemAuthenticatorProvider { - @NonNull + @Nonnull @Override public List getAuthenticators() { return get().getAuthenticators(); diff --git a/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java b/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java index bb43c58f8a125ec99551c884586fe631ecdbf369..dbdca64a1a96d430508b95e560d23d14c5750cf0 100644 --- a/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java +++ b/core/src/main/java/jenkins/security/QueueItemAuthenticatorProvider.java @@ -1,12 +1,11 @@ package jenkins.security; -import edu.umd.cs.findbugs.annotations.NonNull; import hudson.Extension; +import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; +import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; @@ -20,7 +19,7 @@ import java.util.NoSuchElementException; */ public abstract class QueueItemAuthenticatorProvider implements ExtensionPoint { - @NonNull + @Nonnull public abstract List getAuthenticators(); public static Iterable authenticators() { @@ -32,10 +31,7 @@ public abstract class QueueItemAuthenticatorProvider implements ExtensionPoint { private Iterator delegate = null; private IteratorImpl() { - final Jenkins jenkins = Jenkins.getInstance(); - providers = new ArrayList(jenkins == null - ? Collections.emptyList() - : jenkins.getExtensionList(QueueItemAuthenticatorProvider.class)).iterator(); + providers = ExtensionList.lookup(QueueItemAuthenticatorProvider.class).iterator(); } @Override diff --git a/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java b/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java index ea96951bcf4927f8ff6d4562b47a0e6a35d6c860..7b48e94a0c371ed69c3b68a548de24c7e613d74c 100644 --- a/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java +++ b/core/src/main/java/jenkins/security/RekeySecretAdminMonitor.java @@ -10,6 +10,7 @@ import hudson.util.VersionNumber; import jenkins.management.AsynchronousAdministrativeMonitor; import jenkins.model.Jenkins; import jenkins.util.io.FileBoolean; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.StaplerProxy; import org.kohsuke.stapler.StaplerRequest; @@ -28,7 +29,7 @@ import java.util.logging.Logger; * * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("rekeySecret") public class RekeySecretAdminMonitor extends AsynchronousAdministrativeMonitor implements StaplerProxy { /** @@ -113,13 +114,11 @@ public class RekeySecretAdminMonitor extends AsynchronousAdministrativeMonitor i @Initializer(fatal=false,after=InitMilestone.PLUGINS_STARTED,before=InitMilestone.EXTENSIONS_AUGMENTED) // as early as possible, but this needs to be late enough that the ConfidentialStore is available - public static void scanOnReboot() throws InterruptedException, IOException, GeneralSecurityException { - RekeySecretAdminMonitor m = new RekeySecretAdminMonitor(); // throw-away instance - - FileBoolean flag = m.scanOnBoot; + public void scanOnReboot() throws InterruptedException, IOException, GeneralSecurityException { + FileBoolean flag = scanOnBoot; if (flag.isOn()) { flag.off(); - m.start(false).join(); + start(false).join(); // block the boot until the rewrite process is complete // don't let the failure in RekeyThread block Jenkins boot. } diff --git a/core/src/main/java/jenkins/security/Roles.java b/core/src/main/java/jenkins/security/Roles.java index cca26873a5a69b972720d6aafc2bbbcc01a37ed9..ada2ca96c0899e331d573b32d4fbe944acab532f 100644 --- a/core/src/main/java/jenkins/security/Roles.java +++ b/core/src/main/java/jenkins/security/Roles.java @@ -7,7 +7,7 @@ import org.jenkinsci.remoting.Role; * *

* In Jenkins, there is really only one interesting role, which is the Jenkins master. - * Slaves, CLI, and Maven processes are all going to load classes from the master, + * Agents, CLI, and Maven processes are all going to load classes from the master, * which means it accepts anything that the master asks for, and thus they need * not have any role. * @@ -16,14 +16,14 @@ import org.jenkinsci.remoting.Role; */ public class Roles { /** - * Indicates that a callable runs on masters, requested by slaves/CLI/maven/whatever. + * Indicates that a callable runs on masters, requested by agents/CLI/maven/whatever. */ public static final Role MASTER = new Role("master"); /** - * Indicates that a callable is meant to run on slaves. + * Indicates that a callable is meant to run on agents. * - * This isn't used to reject callables to run on the slave, but rather to allow + * This isn't used to reject callables to run on the agent, but rather to allow * the master to promptly reject callables that are really not meant to be run on * the master (as opposed to ones that do not have that information, which gets * {@link Role#UNKNOWN}) diff --git a/core/src/main/java/jenkins/security/SecureRequester.java b/core/src/main/java/jenkins/security/SecureRequester.java index 42c6ac1dbb847954bb225d509fe8b32ca59da857..f13385cca723ca46c991c0eee3ab587a34eb0f59 100644 --- a/core/src/main/java/jenkins/security/SecureRequester.java +++ b/core/src/main/java/jenkins/security/SecureRequester.java @@ -2,6 +2,7 @@ package jenkins.security; import hudson.Extension; import hudson.ExtensionPoint; +import jenkins.util.SystemProperties; import hudson.model.Api; import java.util.logging.Logger; import jenkins.model.Jenkins; @@ -34,7 +35,7 @@ public interface SecureRequester extends ExtensionPoint { @Extension class Default implements SecureRequester { private static final String PROP = "hudson.model.Api.INSECURE"; - private static final boolean INSECURE = Boolean.getBoolean(PROP); + private static final boolean INSECURE = SystemProperties.getBoolean(PROP); static { if (INSECURE) { Logger.getLogger(SecureRequester.class.getName()).warning(PROP + " system property is deprecated; implement SecureRequester instead"); diff --git a/core/src/main/java/jenkins/security/SecurityListener.java b/core/src/main/java/jenkins/security/SecurityListener.java index 992b3bb0c1234a1928bd13e7268ffe458213b759..7cec8c0eea4afa72f446c03d781d80592c0a5443 100644 --- a/core/src/main/java/jenkins/security/SecurityListener.java +++ b/core/src/main/java/jenkins/security/SecurityListener.java @@ -33,7 +33,6 @@ import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nonnull; -import jenkins.model.Jenkins; import org.acegisecurity.GrantedAuthority; import org.acegisecurity.userdetails.UserDetails; diff --git a/core/src/main/java/jenkins/security/SlaveToMasterCallable.java b/core/src/main/java/jenkins/security/SlaveToMasterCallable.java index 61265cbdea54544055eaa09eaa91136258c73c8a..34b227c5bf847fe384b22c9688f096e78789cb1b 100644 --- a/core/src/main/java/jenkins/security/SlaveToMasterCallable.java +++ b/core/src/main/java/jenkins/security/SlaveToMasterCallable.java @@ -1,13 +1,11 @@ package jenkins.security; import hudson.remoting.Callable; -import org.jenkinsci.remoting.Role; import org.jenkinsci.remoting.RoleChecker; -import java.util.Collection; /** - * Convenient {@link Callable} that are meant to run on the master (sent by slave/CLI/etc). + * Convenient {@link Callable} that are meant to run on the master (sent by agent/CLI/etc). * * @author Kohsuke Kawaguchi * @since 1.THU diff --git a/core/src/main/java/jenkins/security/UserDetailsCache.java b/core/src/main/java/jenkins/security/UserDetailsCache.java new file mode 100644 index 0000000000000000000000000000000000000000..2ea4fe777aec13deaaaa1da3306f6de27dbbe118 --- /dev/null +++ b/core/src/main/java/jenkins/security/UserDetailsCache.java @@ -0,0 +1,189 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.security; + +import com.google.common.cache.Cache; +import com.google.common.util.concurrent.UncheckedExecutionException; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.security.UserMayOrMayNotExistException; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import org.acegisecurity.userdetails.UserDetails; +import org.acegisecurity.userdetails.UsernameNotFoundException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.springframework.dao.DataAccessException; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import static com.google.common.cache.CacheBuilder.newBuilder; + +/** + * Cache layer for {@link org.acegisecurity.userdetails.UserDetails} lookup. + * + * @since 2.15 + */ +@Extension +public final class UserDetailsCache { + + private static final String SYS_PROP_NAME = UserDetailsCache.class.getName() + ".EXPIRE_AFTER_WRITE_SEC"; + /** + * Nr of seconds before a value expires after being cached, note full GC will also clear the cache. + * Should be able to set this value in script and then reload from disk to change in runtime. + */ + private static /*not final*/ Integer EXPIRE_AFTER_WRITE_SEC = SystemProperties.getInteger(SYS_PROP_NAME, (int)TimeUnit.MINUTES.toSeconds(2)); + private final Cache detailsCache; + private final Cache existanceCache; + + /** + * Constructor intended to be instantiated by Jenkins only. + */ + @Restricted(NoExternalUse.class) + public UserDetailsCache() { + if (EXPIRE_AFTER_WRITE_SEC == null || EXPIRE_AFTER_WRITE_SEC <= 0) { + //just in case someone is trying to trick us + EXPIRE_AFTER_WRITE_SEC = SystemProperties.getInteger(SYS_PROP_NAME, (int)TimeUnit.MINUTES.toSeconds(2)); + if (EXPIRE_AFTER_WRITE_SEC <= 0) { + //The property could also be set to a negative value + EXPIRE_AFTER_WRITE_SEC = (int)TimeUnit.MINUTES.toSeconds(2); + } + } + detailsCache = newBuilder().softValues().expireAfterWrite(EXPIRE_AFTER_WRITE_SEC, TimeUnit.SECONDS).build(); + existanceCache = newBuilder().softValues().expireAfterWrite(EXPIRE_AFTER_WRITE_SEC, TimeUnit.SECONDS).build(); + } + + /** + * The singleton instance registered in Jenkins. + * @return the cache + */ + public static UserDetailsCache get() { + return ExtensionList.lookup(UserDetailsCache.class).get(UserDetailsCache.class); + } + + /** + * Gets the cached UserDetails for the given username. + * Similar to {@link #loadUserByUsername(String)} except it doesn't perform the actual lookup if there is a cache miss. + * + * @param idOrFullName the username + * + * @return {@code null} if the cache doesn't contain any data for the key or the user details cached for the key. + * @throws UsernameNotFoundException if a previous lookup resulted in the same + */ + @CheckForNull + public UserDetails getCached(String idOrFullName) throws UsernameNotFoundException { + Boolean exists = existanceCache.getIfPresent(idOrFullName); + if (exists != null && !exists) { + throw new UserMayOrMayNotExistException(String.format("\"%s\" does not exist", idOrFullName)); + } else { + return detailsCache.getIfPresent(idOrFullName); + } + } + + /** + * Locates the user based on the username, by first looking in the cache and then delegate to + * {@link hudson.security.SecurityRealm#loadUserByUsername(String)}. + * + * @param idOrFullName the username + * @return the details + * + * @throws UsernameNotFoundException (normally a {@link hudson.security.UserMayOrMayNotExistException}) + * if the user could not be found or the user has no GrantedAuthority + * @throws DataAccessException if user could not be found for a repository-specific reason + * @throws ExecutionException if anything else went wrong in the cache lookup/retrieval + */ + @Nonnull + public UserDetails loadUserByUsername(String idOrFullName) throws UsernameNotFoundException, DataAccessException, ExecutionException { + Boolean exists = existanceCache.getIfPresent(idOrFullName); + if(exists != null && !exists) { + throw new UsernameNotFoundException(String.format("\"%s\" does not exist", idOrFullName)); + } else { + try { + return detailsCache.get(idOrFullName, new Retriever(idOrFullName)); + } catch (ExecutionException | UncheckedExecutionException e) { + if (e.getCause() instanceof UsernameNotFoundException) { + throw ((UsernameNotFoundException)e.getCause()); + } else if (e.getCause() instanceof DataAccessException) { + throw ((DataAccessException)e.getCause()); + } else { + throw e; + } + } + } + } + + /** + * Discards all entries in the cache. + */ + public void invalidateAll() { + existanceCache.invalidateAll(); + detailsCache.invalidateAll(); + } + + /** + * Discards any cached value for key. + * @param idOrFullName the key + */ + public void invalidate(final String idOrFullName) { + existanceCache.invalidate(idOrFullName); + detailsCache.invalidate(idOrFullName); + } + + /** + * Callable that performs the actual lookup if there is a cache miss. + * @see #loadUserByUsername(String) + */ + private class Retriever implements Callable { + private final String idOrFullName; + + private Retriever(final String idOrFullName) { + this.idOrFullName = idOrFullName; + } + + @Override + public UserDetails call() throws Exception { + try { + Jenkins jenkins = Jenkins.getInstance(); + UserDetails userDetails = jenkins.getSecurityRealm().loadUserByUsername(idOrFullName); + if (userDetails == null) { + existanceCache.put(this.idOrFullName, Boolean.FALSE); + throw new NullPointerException("hudson.security.SecurityRealm should never return null. " + + jenkins.getSecurityRealm() + " returned null for idOrFullName='" + idOrFullName + "'"); + } + existanceCache.put(this.idOrFullName, Boolean.TRUE); + return userDetails; + } catch (UsernameNotFoundException e) { + existanceCache.put(this.idOrFullName, Boolean.FALSE); + throw e; + } catch (DataAccessException e) { + existanceCache.invalidate(this.idOrFullName); + throw e; + } + } + } +} diff --git a/core/src/main/java/jenkins/security/s2m/AdminCallableMonitor.java b/core/src/main/java/jenkins/security/s2m/AdminCallableMonitor.java index d6a483af767e80a09e322e495d6dc2dcf3218cdf..01eec3210274bb54bb592a0249adb05711fc0772 100644 --- a/core/src/main/java/jenkins/security/s2m/AdminCallableMonitor.java +++ b/core/src/main/java/jenkins/security/s2m/AdminCallableMonitor.java @@ -5,6 +5,7 @@ import hudson.FilePath; import hudson.model.AdministrativeMonitor; import hudson.remoting.Callable; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.HttpResponses; import org.kohsuke.stapler.QueryParameter; @@ -19,7 +20,7 @@ import java.io.IOException; * @since 1.THU * @author Kohsuke Kawaguchi */ -@Extension +@Extension @Symbol("slaveToMasterAccessControl") public class AdminCallableMonitor extends AdministrativeMonitor { @Inject Jenkins jenkins; @@ -38,7 +39,7 @@ public class AdminCallableMonitor extends AdministrativeMonitor { @Override public String getDisplayName() { - return "Slave \u2192 Master Access Control"; + return Messages.AdminCallableMonitor_DisplayName(); } // bind this to URL diff --git a/core/src/main/java/jenkins/security/s2m/AdminCallableWhitelist.java b/core/src/main/java/jenkins/security/s2m/AdminCallableWhitelist.java index a6bc100d3130f31e922acfaf62d614ea5165f6aa..2b448778ba71fcc048d81dc34d2e688de0b6cdb8 100644 --- a/core/src/main/java/jenkins/security/s2m/AdminCallableWhitelist.java +++ b/core/src/main/java/jenkins/security/s2m/AdminCallableWhitelist.java @@ -2,6 +2,7 @@ package jenkins.security.s2m; import hudson.Extension; import hudson.remoting.Callable; +import org.jenkinsci.Symbol; import org.jenkinsci.remoting.Role; import org.jenkinsci.remoting.RoleSensitive; @@ -19,7 +20,7 @@ import java.util.Collection; * * @author Kohsuke Kawaguchi */ -@Extension(ordinal=-100) +@Extension(ordinal=-100) @Symbol("admin") public class AdminCallableWhitelist extends CallableWhitelist { @Inject AdminWhitelistRule rule; diff --git a/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java b/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java index c9aabe56919f8e6e4342b752c7d3e299feb9390e..a05fd59e8ebc58c7ab1d112318f8a2f709144390 100644 --- a/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java +++ b/core/src/main/java/jenkins/security/s2m/AdminWhitelistRule.java @@ -109,14 +109,14 @@ public class AdminWhitelistRule implements StaplerProxy { private InputStream transformForWindows(InputStream src) throws IOException { BufferedReader r = new BufferedReader(new InputStreamReader(src)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintStream p = new PrintStream(out); - String line; - while ((line=r.readLine())!=null) { - if (!line.startsWith("#") && Functions.isWindows()) - line = line.replace("/","\\\\"); - p.println(line); + try (PrintStream p = new PrintStream(out)) { + String line; + while ((line = r.readLine()) != null) { + if (!line.startsWith("#") && Functions.isWindows()) + line = line.replace("/", "\\\\"); + p.println(line); + } } - p.close(); return new ByteArrayInputStream(out.toByteArray()); } diff --git a/core/src/main/java/jenkins/security/s2m/CallableDirectionChecker.java b/core/src/main/java/jenkins/security/s2m/CallableDirectionChecker.java index 706d17c0be7901b1ec7f71bb70460f0d7981a208..858375a8abcf29d52cb67ab031bfbd565e7ca1a8 100644 --- a/core/src/main/java/jenkins/security/s2m/CallableDirectionChecker.java +++ b/core/src/main/java/jenkins/security/s2m/CallableDirectionChecker.java @@ -1,6 +1,7 @@ package jenkins.security.s2m; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.remoting.Callable; import hudson.remoting.ChannelBuilder; import jenkins.security.ChannelConfigurator; @@ -38,7 +39,7 @@ public class CallableDirectionChecker extends RoleChecker { * This is an escape hatch in case the fix breaks something critical, to allow the user * to keep operation. */ - public static boolean BYPASS = Boolean.getBoolean(BYPASS_PROP); + public static boolean BYPASS = SystemProperties.getBoolean(BYPASS_PROP); private CallableDirectionChecker(Object context) { this.context = context; @@ -55,11 +56,11 @@ public class CallableDirectionChecker extends RoleChecker { if (isWhitelisted(subject,expected)) { // this subject is dubious, but we are letting it through as per whitelisting - LOGGER.log(Level.FINE, "Explicitly allowing {0} to be sent from slave to master", name); + LOGGER.log(Level.FINE, "Explicitly allowing {0} to be sent from agent to master", name); return; } - throw new SecurityException("Sending " + name + " from slave to master is prohibited.\nSee http://jenkins-ci.org/security-144 for more details"); + throw new SecurityException("Sending " + name + " from agent to master is prohibited.\nSee http://jenkins-ci.org/security-144 for more details"); } /** diff --git a/core/src/main/java/jenkins/security/s2m/DefaultFilePathFilter.java b/core/src/main/java/jenkins/security/s2m/DefaultFilePathFilter.java index 563d19269eb093fc5435d840b89b6523557d0fc4..a35bfbe814ead7e3fdf6821c3a579ff0778fc783 100644 --- a/core/src/main/java/jenkins/security/s2m/DefaultFilePathFilter.java +++ b/core/src/main/java/jenkins/security/s2m/DefaultFilePathFilter.java @@ -25,6 +25,7 @@ package jenkins.security.s2m; import hudson.Extension; +import jenkins.util.SystemProperties; import hudson.remoting.ChannelBuilder; import jenkins.ReflectiveFilePathFilter; import jenkins.security.ChannelConfigurator; @@ -36,7 +37,7 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - * Blocks slaves from writing to files on the master by default (and also provide the kill switch.) + * Blocks agents from writing to files on the master by default (and also provide the kill switch.) */ @Restricted(DoNotUse.class) // impl @Extension public class DefaultFilePathFilter extends ChannelConfigurator { @@ -44,7 +45,7 @@ import java.util.logging.Logger; /** * Escape hatch to disable this check completely. */ - public static boolean BYPASS = Boolean.getBoolean(DefaultFilePathFilter.class.getName()+".allow"); + public static boolean BYPASS = SystemProperties.getBoolean(DefaultFilePathFilter.class.getName()+".allow"); private static final Logger LOGGER = Logger.getLogger(DefaultFilePathFilter.class.getName()); @@ -53,7 +54,7 @@ import java.util.logging.Logger; new ReflectiveFilePathFilter() { protected boolean op(String op, File f) throws SecurityException { if (BYPASS) { - LOGGER.log(Level.FINE, "slave allowed to {0} {1}", new Object[] {op, f}); + LOGGER.log(Level.FINE, "agent allowed to {0} {1}", new Object[] {op, f}); return true; } else { return false; diff --git a/core/src/main/java/jenkins/security/s2m/MasterKillSwitchConfiguration.java b/core/src/main/java/jenkins/security/s2m/MasterKillSwitchConfiguration.java index d83d436f4bf09570711f8c3132fb44139c692295..69bb8e34bc1f71b455047939d3ffe2cbd928e2a4 100644 --- a/core/src/main/java/jenkins/security/s2m/MasterKillSwitchConfiguration.java +++ b/core/src/main/java/jenkins/security/s2m/MasterKillSwitchConfiguration.java @@ -1,14 +1,13 @@ package jenkins.security.s2m; import hudson.Extension; +import javax.inject.Inject; import jenkins.model.GlobalConfiguration; import jenkins.model.GlobalConfigurationCategory; import jenkins.model.Jenkins; import net.sf.json.JSONObject; import org.kohsuke.stapler.StaplerRequest; -import javax.inject.Inject; - /** * Exposes {@link AdminWhitelistRule#masterKillSwitch} to the admin. * @@ -47,9 +46,7 @@ public class MasterKillSwitchConfiguration extends GlobalConfiguration { * Unless this option is relevant, we don't let users choose this. */ public boolean isRelevant() { - return jenkins.getComputers().length>1 // if there's no slave, there's no point - && jenkins.isUseSecurity() // if security is off, likewise this is pointless - ; + return jenkins.hasPermission(Jenkins.RUN_SCRIPTS) && jenkins.isUseSecurity(); } } diff --git a/core/src/main/java/jenkins/security/s2m/MasterKillSwitchWarning.java b/core/src/main/java/jenkins/security/s2m/MasterKillSwitchWarning.java index 7a5df576f12b5fb292e49a85ca8ce5ea523ce724..bad34cc5405544ea63c3237522776229c2cc1a6c 100644 --- a/core/src/main/java/jenkins/security/s2m/MasterKillSwitchWarning.java +++ b/core/src/main/java/jenkins/security/s2m/MasterKillSwitchWarning.java @@ -28,6 +28,11 @@ public class MasterKillSwitchWarning extends AdministrativeMonitor { return rule.getMasterKillSwitch() && config.isRelevant(); } + @Override + public String getDisplayName() { + return Messages.MasterKillSwitchWarning_DisplayName(); + } + public HttpResponse doAct(@QueryParameter String dismiss) throws IOException { if(dismiss!=null) { disable(true); diff --git a/core/src/main/java/jenkins/security/s2m/package-info.java b/core/src/main/java/jenkins/security/s2m/package-info.java index 84875777f61b609dd531aaf9f3f6b450ad36b4b5..b0650138bc0c709dbde56454944c5407ab571f5e 100644 --- a/core/src/main/java/jenkins/security/s2m/package-info.java +++ b/core/src/main/java/jenkins/security/s2m/package-info.java @@ -1,4 +1,4 @@ /** - * Slave -> master security. + * Agent -> master security. */ package jenkins.security.s2m; diff --git a/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java b/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java index a52de1e391fbff0a21768e0743a1953e7b988865..4daf509cfbac43ed6354a133e3c054188deade2e 100644 --- a/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java +++ b/core/src/main/java/jenkins/slaves/DefaultJnlpSlaveReceiver.java @@ -1,23 +1,43 @@ package jenkins.slaves; +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.ClassicPluginStrategy; import hudson.Extension; import hudson.TcpSlaveAgentListener.ConnectionFromCurrentPeer; import hudson.Util; +import hudson.model.Computer; import hudson.model.Slave; import hudson.remoting.Channel; +import hudson.slaves.ComputerLauncher; +import hudson.slaves.ComputerLauncherFilter; +import hudson.slaves.DelegatingComputerLauncher; +import hudson.slaves.JNLPLauncher; import hudson.slaves.SlaveComputer; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import jenkins.model.Jenkins; +import jenkins.security.ChannelConfigurator; +import jenkins.util.SystemProperties; +import org.apache.commons.io.IOUtils; +import org.jenkinsci.remoting.engine.JnlpConnectionState; import java.io.IOException; import java.security.SecureRandom; -import java.util.Properties; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.logging.Level; import java.util.logging.Logger; +import org.jenkinsci.remoting.protocol.impl.ConnectionRefusalException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; /** - * Match the name against the slave name and route the incoming JNLP agent as {@link Slave}. + * Match the name against the agent name and route the incoming JNLP agent as {@link Slave}. * * @author Kohsuke Kawaguchi * @since 1.561 @@ -25,53 +45,170 @@ import java.util.logging.Logger; */ @Extension public class DefaultJnlpSlaveReceiver extends JnlpAgentReceiver { + + /** + * Disables strict verification of connections. Turn this on if you have plugins that incorrectly extend + * {@link ComputerLauncher} when then should have extended {@link DelegatingComputerLauncher} + * + * @since 2.28 + */ + @Restricted(NoExternalUse.class) + public static boolean disableStrictVerification = + SystemProperties.getBoolean(DefaultJnlpSlaveReceiver.class.getName() + ".disableStrictVerification"); + + @Override - public boolean handle(String nodeName, JnlpSlaveHandshake handshake) throws IOException, InterruptedException { - SlaveComputer computer = (SlaveComputer) Jenkins.getInstance().getComputer(nodeName); + public boolean owns(String clientName) { + Computer computer = Jenkins.getInstance().getComputer(clientName); + return computer != null; + } - if(computer==null) { - return false; + private static ComputerLauncher getDelegate(ComputerLauncher launcher) { + try { + Method getDelegate = launcher.getClass().getMethod("getDelegate"); + if (ComputerLauncher.class.isAssignableFrom(getDelegate.getReturnType())) { + return (ComputerLauncher) getDelegate.invoke(launcher); + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + // ignore + } + try { + Method getLauncher = launcher.getClass().getMethod("getLauncher"); + if (ComputerLauncher.class.isAssignableFrom(getLauncher.getReturnType())) { + return (ComputerLauncher) getLauncher.invoke(launcher); + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + // ignore } + return null; + } + @Override + public void afterProperties(@NonNull JnlpConnectionState event) { + String clientName = event.getProperty(JnlpConnectionState.CLIENT_NAME_KEY); + SlaveComputer computer = (SlaveComputer) Jenkins.getInstance().getComputer(clientName); + if (computer == null) { + event.reject(new ConnectionRefusalException(String.format("%s is not a JNLP agent", clientName))); + return; + } + ComputerLauncher launcher = computer.getLauncher(); + while (!(launcher instanceof JNLPLauncher)) { + ComputerLauncher l; + if (launcher instanceof DelegatingComputerLauncher) { + launcher = ((DelegatingComputerLauncher) launcher).getLauncher(); + } else if (launcher instanceof ComputerLauncherFilter) { + launcher = ((ComputerLauncherFilter) launcher).getCore(); + } else if (null != (l = getDelegate(launcher))) { // TODO remove when all plugins are fixed + LOGGER.log(Level.INFO, "Connecting {0} as a JNLP agent where the launcher {1} does not mark " + + "itself correctly as being a JNLP agent", + new Object[]{clientName, computer.getLauncher().getClass()}); + launcher = l; + } else { + if (disableStrictVerification) { + LOGGER.log(Level.WARNING, "Connecting {0} as a JNLP agent where the launcher {1} does not mark " + + "itself correctly as being a JNLP agent", + new Object[]{clientName, computer.getLauncher().getClass()}); + break; + } else { + LOGGER.log(Level.WARNING, "Rejecting connection to {0} from {1} as a JNLP agent as the launcher " + + "{2} does not extend JNLPLauncher or does not implement " + + "DelegatingComputerLauncher with a delegation chain leading to a JNLPLauncher. " + + "Set system property " + + "jenkins.slaves.DefaultJnlpSlaveReceiver.disableStrictVerification=true to allow" + + "connections until the plugin has been fixed.", + new Object[]{clientName, event.getSocket().getRemoteSocketAddress(), computer.getLauncher().getClass()}); + event.reject(new ConnectionRefusalException(String.format("%s is not a JNLP agent", clientName))); + return; + } + } + } Channel ch = computer.getChannel(); - if(ch !=null) { - String c = handshake.getRequestProperty("Cookie"); - if (c!=null && c.equals(ch.getProperty(COOKIE_NAME))) { + if (ch != null) { + String cookie = event.getProperty(JnlpConnectionState.COOKIE_KEY); + if (cookie != null && cookie.equals(ch.getProperty(COOKIE_NAME))) { // we think we are currently connected, but this request proves that it's from the party // we are supposed to be communicating to. so let the current one get disconnected - LOGGER.info("Disconnecting "+nodeName+" as we are reconnected from the current peer"); + LOGGER.log(Level.INFO, "Disconnecting {0} as we are reconnected from the current peer", clientName); try { computer.disconnect(new ConnectionFromCurrentPeer()).get(15, TimeUnit.SECONDS); - } catch (ExecutionException e) { - throw new IOException("Failed to disconnect the current client",e); - } catch (TimeoutException e) { - throw new IOException("Failed to disconnect the current client",e); + } catch (ExecutionException | TimeoutException | InterruptedException e) { + event.reject(new ConnectionRefusalException("Failed to disconnect the current client", e)); + return; } } else { - handshake.error(nodeName + " is already connected to this master. Rejecting this connection."); - return true; + event.reject(new ConnectionRefusalException(String.format( + "%s is already connected to this master. Rejecting this connection.", clientName))); + return; } } + event.approve(); + event.setStash(new State(computer)); + } + + @Override + public void beforeChannel(@NonNull JnlpConnectionState event) { + DefaultJnlpSlaveReceiver.State state = event.getStash(DefaultJnlpSlaveReceiver.State.class); + final SlaveComputer computer = state.getNode(); + final OutputStream log = computer.openLogFile(); + state.setLog(log); + PrintWriter logw = new PrintWriter(log, true); + logw.println("JNLP agent connected from " + event.getSocket().getInetAddress()); + for (ChannelConfigurator cc : ChannelConfigurator.all()) { + cc.onChannelBuilding(event.getChannelBuilder(), computer); + } + event.getChannelBuilder().withHeaderStream(log); + String cookie = event.getProperty(JnlpConnectionState.COOKIE_KEY); + if (cookie != null) { + event.getChannelBuilder().withProperty(COOKIE_NAME, cookie); + } + } + + @Override + public void afterChannel(@NonNull JnlpConnectionState event) { + DefaultJnlpSlaveReceiver.State state = event.getStash(DefaultJnlpSlaveReceiver.State.class); + final SlaveComputer computer = state.getNode(); + try { + computer.setChannel(event.getChannel(), state.getLog(), null); + } catch (IOException | InterruptedException e) { + PrintWriter logw = new PrintWriter(state.getLog(), true); + e.printStackTrace(logw); + IOUtils.closeQuietly(event.getChannel()); + } + } - Properties response = new Properties(); - String cookie = generateCookie(); - response.put("Cookie",cookie); - handshake.success(response); + @Override + public void channelClosed(@NonNull JnlpConnectionState event) { + final String nodeName = event.getProperty(JnlpConnectionState.CLIENT_NAME_KEY); + IOException cause = event.getCloseCause(); + if (cause != null) { + LOGGER.log(Level.WARNING, Thread.currentThread().getName() + " for " + nodeName + " terminated", + cause); + } + } - // this cast is leaking abstraction - JnlpSlaveAgentProtocol2.Handler handler = (JnlpSlaveAgentProtocol2.Handler)handshake; + private static class State implements JnlpConnectionState.ListenerState { + @Nonnull + private final SlaveComputer node; + @CheckForNull + private OutputStream log; - ch = handler.jnlpConnect(computer); + public State(@Nonnull SlaveComputer node) { + this.node = node; + } - ch.setProperty(COOKIE_NAME, cookie); + @Nonnull + public SlaveComputer getNode() { + return node; + } - return true; - } + @CheckForNull + public OutputStream getLog() { + return log; + } - private String generateCookie() { - byte[] cookie = new byte[32]; - new SecureRandom().nextBytes(cookie); - return Util.toHexString(cookie); + public void setLog(@Nonnull OutputStream log) { + this.log = log; + } } private static final Logger LOGGER = Logger.getLogger(DefaultJnlpSlaveReceiver.class.getName()); diff --git a/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java b/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java index dfdd5de7502d3309498c47c29495faaee2aa266c..feb11427a8f0dc6cc08d0efe1440f03b7b8af37a 100644 --- a/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java +++ b/core/src/main/java/jenkins/slaves/EncryptedSlaveAgentJnlpFile.java @@ -44,7 +44,7 @@ public class EncryptedSlaveAgentJnlpFile implements HttpResponse { */ private final String viewName; /** - * Name of the slave, which is used to determine secret HMAC code. + * Name of the agent, which is used to determine secret HMAC code. */ private final String slaveName; /** diff --git a/test/src/main/java/org/jvnet/hudson/test/SleepBuilder.java b/core/src/main/java/jenkins/slaves/IOHubProvider.java similarity index 54% rename from test/src/main/java/org/jvnet/hudson/test/SleepBuilder.java rename to core/src/main/java/jenkins/slaves/IOHubProvider.java index 9d2176aedecc8c1995b0f44d1274360b26236edb..dad9cf8398d46500f39f2a6bc8af6605ae37b3b1 100644 --- a/test/src/main/java/org/jvnet/hudson/test/SleepBuilder.java +++ b/core/src/main/java/jenkins/slaves/IOHubProvider.java @@ -1,18 +1,18 @@ /* * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * + * Copyright (c) 2016, CloudBees, Inc. + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,41 +21,51 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; +package jenkins.slaves; -import hudson.Launcher; import hudson.Extension; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.model.Descriptor; -import hudson.tasks.Builder; -import org.kohsuke.stapler.DataBoundConstructor; - +import hudson.init.Terminator; +import hudson.model.Computer; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.jenkinsci.remoting.protocol.IOHub; /** - * {@link Builder} that just sleeps for the specified amount of milli-seconds. - * - * @author Kohsuke Kawaguchi + * Singleton holder of {@link IOHub} + * + * @since 2.27 */ -public class SleepBuilder extends Builder { - public final long time; +@Extension +public class IOHubProvider { + /** + * Our logger. + */ + private static final Logger LOGGER = Logger.getLogger(IOHubProvider.class.getName()); + /** + * Our hub. + */ + private IOHub hub; - @DataBoundConstructor - public SleepBuilder(long time) { - this.time = time; + public IOHubProvider() { + try { + hub = IOHub.create(Computer.threadPoolForRemoting); + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Failed to launch IOHub", e); + this.hub = null; + } } - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - listener.getLogger().println("Sleeping "+time+"ms"); - Thread.sleep(time); - return true; + public IOHub getHub() { + return hub; } - @Extension - public static final class DescriptorImpl extends Descriptor { - public String getDisplayName() { - return "Sleep"; + @Terminator + public void cleanUp() throws IOException { + if (hub != null) { + hub.close(); + hub = null; } } + } diff --git a/core/src/main/java/jenkins/slaves/JnlpAgentReceiver.java b/core/src/main/java/jenkins/slaves/JnlpAgentReceiver.java index 914447332f66447e1ec8657d0956df1a8c81c33d..369bd122dc9cf22482b07487426f78fffd793270 100644 --- a/core/src/main/java/jenkins/slaves/JnlpAgentReceiver.java +++ b/core/src/main/java/jenkins/slaves/JnlpAgentReceiver.java @@ -2,14 +2,15 @@ package jenkins.slaves; import hudson.ExtensionList; import hudson.ExtensionPoint; +import hudson.Util; import hudson.model.Slave; -import jenkins.model.Jenkins; - -import java.io.IOException; -import java.util.Properties; +import java.security.SecureRandom; +import javax.annotation.Nonnull; +import org.jenkinsci.remoting.engine.JnlpClientDatabase; +import org.jenkinsci.remoting.engine.JnlpConnectionStateListener; /** - * Receives incoming slaves connecting through {@link JnlpSlaveAgentProtocol2}. + * Receives incoming agents connecting through {@link JnlpSlaveAgentProtocol2}, {@link JnlpSlaveAgentProtocol3}, {@link JnlpSlaveAgentProtocol4}. * *

* This is useful to establish the communication with other JVMs and use them @@ -18,47 +19,42 @@ import java.util.Properties; * @author Kohsuke Kawaguchi * @since 1.561 */ -public abstract class JnlpAgentReceiver implements ExtensionPoint { +public abstract class JnlpAgentReceiver extends JnlpConnectionStateListener implements ExtensionPoint { + + private static final SecureRandom secureRandom = new SecureRandom(); - /** - * Called after the client has connected. - * - *

- * The implementation must do the following in the order: - * - *

    - *
  1. Check if the implementation recognizes and claims the given name. - * If not, return false to let other {@link JnlpAgentReceiver} have a chance to - * take this connection. - * - *
  2. If you claim the name but the connection is refused, call - * {@link JnlpSlaveHandshake#error(String)} to refuse the client, and return true. - * The connection will be shut down and the client will report this error to the user. - * - *
  3. If you claim the name and the connection is OK, call - * {@link JnlpSlaveHandshake#success(Properties)} to accept the client. - * - *
  4. Proceed to build a channel with {@link JnlpSlaveHandshake#createChannelBuilder(String)} - * and return true - * - * @param name - * Name of the incoming JNLP agent. All {@link JnlpAgentReceiver} shares a single namespace - * of names. The implementation needs to be able to tell which name belongs to them. - * - * @param handshake - * Encapsulation of the interaction with the incoming JNLP agent. - * - * @return - * true if the name was claimed and the handshake was completed (either successfully or unsuccessfully) - * false if the name was not claimed. Other {@link JnlpAgentReceiver}s will be called to see if they - * take this connection. - * - * @throws Exception - * Any exception thrown from this method will fatally terminate the connection. - */ - public abstract boolean handle(String name, JnlpSlaveHandshake handshake) throws IOException, InterruptedException; + public static final JnlpClientDatabase DATABASE = new JnlpAgentDatabase(); public static ExtensionList all() { return ExtensionList.lookup(JnlpAgentReceiver.class); } + + public static boolean exists(String clientName) { + for (JnlpAgentReceiver receiver : all()) { + if (receiver.owns(clientName)) { + return true; + } + } + return false; + } + + protected abstract boolean owns(String clientName); + + public static String generateCookie() { + byte[] cookie = new byte[32]; + secureRandom.nextBytes(cookie); + return Util.toHexString(cookie); + } + + private static class JnlpAgentDatabase extends JnlpClientDatabase { + @Override + public boolean exists(String clientName) { + return JnlpAgentReceiver.exists(clientName); + } + + @Override + public String getSecretOf(@Nonnull String clientName) { + return JnlpSlaveAgentProtocol.SLAVE_SECRET.mac(clientName); + } + } } diff --git a/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol.java b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol.java index 06e54349f584cf9212ad1f1854bbe28722978d4e..e351b93945ed07ad94503def59eb75e7753a44a3 100644 --- a/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol.java +++ b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol.java @@ -1,49 +1,45 @@ package jenkins.slaves; -import hudson.AbortException; import hudson.Extension; -import hudson.remoting.Channel; -import hudson.remoting.Channel.Listener; -import hudson.remoting.ChannelBuilder; -import hudson.remoting.Engine; -import hudson.slaves.SlaveComputer; -import jenkins.AgentProtocol; -import jenkins.model.Jenkins; -import jenkins.security.HMACConfidentialKey; -import org.jenkinsci.remoting.nio.NioChannelHub; - -import javax.inject.Inject; -import java.io.BufferedWriter; -import java.io.DataInputStream; +import hudson.ExtensionList; +import hudson.Util; +import hudson.model.Computer; import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; import java.net.Socket; -import java.util.logging.Level; +import java.util.Collections; +import java.util.HashMap; import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.inject.Inject; +import jenkins.AgentProtocol; +import jenkins.model.Jenkins; +import jenkins.security.HMACConfidentialKey; +import org.jenkinsci.Symbol; +import org.jenkinsci.remoting.engine.JnlpClientDatabase; +import org.jenkinsci.remoting.engine.JnlpConnectionState; +import org.jenkinsci.remoting.engine.JnlpProtocol1Handler; /** - * {@link AgentProtocol} that accepts connection from slave agents. + * {@link AgentProtocol} that accepts connection from agents. * *

    Security

    *

    - * Once connected, remote slave agents can send in commands to be + * Once connected, remote agents can send in commands to be * executed on the master, so in a way this is like an rsh service. * Therefore, it is important that we reject connections from - * unauthorized remote slaves. + * unauthorized remote agents. * *

    - * We do this by computing HMAC of the slave name. - * This code is sent to the slave inside the .jnlp file + * We do this by computing HMAC of the agent name. + * This code is sent to the agent inside the .jnlp file * (this file itself is protected by HTTP form-based authentication that - * we use everywhere else in Jenkins), and the slave sends this + * we use everywhere else in Jenkins), and the agent sends this * token back when it connects to the master. - * Unauthorized slaves can't access the protected .jnlp file, - * so it can't impersonate a valid slave. + * Unauthorized agents can't access the protected .jnlp file, + * so it can't impersonate a valid agent. * *

    - * We don't want to force the JNLP slave agents to be restarted + * We don't want to force the JNLP agents to be restarted * whenever the server restarts, so right now this secret master key * is generated once and used forever, which makes this whole scheme * less secure. @@ -52,102 +48,65 @@ import java.util.logging.Logger; * @since 1.467 */ @Extension +@Symbol("jnlp") public class JnlpSlaveAgentProtocol extends AgentProtocol { + /** + * Our logger + */ + private static final Logger LOGGER = Logger.getLogger(JnlpSlaveAgentProtocol.class.getName()); + /** + * This secret value is used as a seed for agents. + */ + public static final HMACConfidentialKey SLAVE_SECRET = + new HMACConfidentialKey(JnlpSlaveAgentProtocol.class, "secret"); + + private NioChannelSelector hub; + + private JnlpProtocol1Handler handler; + @Inject - NioChannelSelector hub; + public void setHub(NioChannelSelector hub) { + this.hub = hub; + this.handler = new JnlpProtocol1Handler(JnlpAgentReceiver.DATABASE, Computer.threadPoolForRemoting, + hub.getHub(), true); + } + /** + * {@inheritDoc} + */ @Override - public String getName() { - return "JNLP-connect"; + public boolean isOptIn() { + return OPT_IN; } @Override - public void handle(Socket socket) throws IOException, InterruptedException { - new Handler(hub.getHub(),socket).run(); + public String getName() { + return handler.isEnabled() ? handler.getName() : null; } - protected static class Handler extends JnlpSlaveHandshake { - - /** - * @deprecated as of 1.559 - * Use {@link #Handler(NioChannelHub, Socket)} - */ - @Deprecated - public Handler(Socket socket) throws IOException { - this(null,socket); - } - - public Handler(NioChannelHub hub, Socket socket) throws IOException { - super(hub,socket, - new DataInputStream(socket.getInputStream()), - new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")),true)); - } - - protected void run() throws IOException, InterruptedException { - final String secret = in.readUTF(); - final String nodeName = in.readUTF(); - - if(!SLAVE_SECRET.mac(nodeName).equals(secret)) { - error("Unauthorized access"); - return; - } - - - SlaveComputer computer = (SlaveComputer) Jenkins.getInstance().getComputer(nodeName); - if(computer==null) { - error("No such slave: "+nodeName); - return; - } - - if(computer.getChannel()!=null) { - error(nodeName+" is already connected to this master. Rejecting this connection."); - return; - } - - out.println(Engine.GREETING_SUCCESS); - - jnlpConnect(computer); - } - - protected Channel jnlpConnect(SlaveComputer computer) throws InterruptedException, IOException { - final String nodeName = computer.getName(); - final OutputStream log = computer.openLogFile(); - PrintWriter logw = new PrintWriter(log,true); - logw.println("JNLP agent connected from "+ socket.getInetAddress()); - - try { - ChannelBuilder cb = createChannelBuilder(nodeName); + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return Messages.JnlpSlaveAgentProtocol_displayName(); + } - computer.setChannel(cb.withHeaderStream(log).build(socket), log, - new Listener() { - @Override - public void onClosed(Channel channel, IOException cause) { - if(cause!=null) - LOGGER.log(Level.WARNING, Thread.currentThread().getName() + " for " + nodeName + " terminated", cause); - try { - socket.close(); - } catch (IOException e) { - // ignore - } - } - }); - return computer.getChannel(); - } catch (AbortException e) { - logw.println(e.getMessage()); - logw.println("Failed to establish the connection with the slave"); - throw e; - } catch (IOException e) { - logw.println("Failed to establish the connection with the slave " + nodeName); - e.printStackTrace(logw); - throw e; - } - } + @Override + public void handle(Socket socket) throws IOException, InterruptedException { + handler.handle(socket, + Collections.singletonMap(JnlpConnectionState.COOKIE_KEY, JnlpAgentReceiver.generateCookie()), + ExtensionList.lookup(JnlpAgentReceiver.class)); } - private static final Logger LOGGER = Logger.getLogger(JnlpSlaveAgentProtocol.class.getName()); /** - * This secret value is used as a seed for slaves. + * A/B test turning off this protocol by default. */ - public static final HMACConfidentialKey SLAVE_SECRET = new HMACConfidentialKey(JnlpSlaveAgentProtocol.class,"secret"); + private static final boolean OPT_IN; + + static { + byte hash = Util.fromHexString(Jenkins.getInstance().getLegacyInstanceId())[0]; + OPT_IN = (hash % 10) == 0; + } } diff --git a/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol2.java b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol2.java index cee4b6cbad8568e0221366f8f01cbe9a0ce4fa34..66bc07dc9d72992701ab59889da570498f7002ea 100644 --- a/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol2.java +++ b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol2.java @@ -1,65 +1,71 @@ package jenkins.slaves; import hudson.Extension; -import org.jenkinsci.remoting.nio.NioChannelHub; - -import java.io.ByteArrayInputStream; +import hudson.ExtensionList; +import hudson.model.Computer; import java.io.IOException; import java.net.Socket; -import java.util.Properties; +import java.util.Collections; +import java.util.HashMap; +import javax.annotation.Nonnull; +import javax.inject.Inject; +import jenkins.AgentProtocol; +import org.jenkinsci.Symbol; +import org.jenkinsci.remoting.engine.JnlpClientDatabase; +import org.jenkinsci.remoting.engine.JnlpConnectionState; +import org.jenkinsci.remoting.engine.JnlpProtocol2Handler; /** * {@link JnlpSlaveAgentProtocol} Version 2. * *

    * This protocol extends the version 1 protocol by adding a per-client cookie, - * so that we can detect a reconnection from the slave and take appropriate action, + * so that we can detect a reconnection from the agent and take appropriate action, * when the connection disappeared without the master noticing. * * @author Kohsuke Kawaguchi * @since 1.467 */ @Extension -public class JnlpSlaveAgentProtocol2 extends JnlpSlaveAgentProtocol { +@Symbol("jnlp2") +public class JnlpSlaveAgentProtocol2 extends AgentProtocol { + private NioChannelSelector hub; + + private JnlpProtocol2Handler handler; + + @Inject + public void setHub(NioChannelSelector hub) { + this.hub = hub; + this.handler = new JnlpProtocol2Handler(JnlpAgentReceiver.DATABASE, Computer.threadPoolForRemoting, + hub.getHub(), true); + } + @Override public String getName() { - return "JNLP2-connect"; + return handler.isEnabled() ? handler.getName() : null; } + /** + * {@inheritDoc} + */ @Override - public void handle(Socket socket) throws IOException, InterruptedException { - new Handler2(hub.getHub(),socket).run(); + public boolean isOptIn() { + return false; } - protected static class Handler2 extends Handler { - /** - * @deprecated as of 1.559 - * Use {@link #Handler2(NioChannelHub, Socket)} - */ - @Deprecated - public Handler2(Socket socket) throws IOException { - super(socket); - } - - public Handler2(NioChannelHub hub, Socket socket) throws IOException { - super(hub, socket); - } - - /** - * Handles JNLP slave agent connection request (v2 protocol) - */ - @Override - protected void run() throws IOException, InterruptedException { - request.load(new ByteArrayInputStream(in.readUTF().getBytes("UTF-8"))); - - final String nodeName = request.getProperty("Node-Name"); - - for (JnlpAgentReceiver recv : JnlpAgentReceiver.all()) { - if (recv.handle(nodeName,this)) - return; - } + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return Messages.JnlpSlaveAgentProtocol2_displayName(); + } - error("Unrecognized name: "+nodeName); - } + @Override + public void handle(Socket socket) throws IOException, InterruptedException { + handler.handle(socket, + Collections.singletonMap(JnlpConnectionState.COOKIE_KEY, JnlpAgentReceiver.generateCookie()), + ExtensionList.lookup(JnlpAgentReceiver.class)); } + } diff --git a/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol3.java b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol3.java new file mode 100644 index 0000000000000000000000000000000000000000..50779ee9da4085bb1d527148f202ddfde90a2376 --- /dev/null +++ b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol3.java @@ -0,0 +1,97 @@ +package jenkins.slaves; + +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.Extension; +import hudson.ExtensionList; +import hudson.Util; +import hudson.model.Computer; +import java.io.IOException; +import java.net.Socket; +import java.util.Collections; +import java.util.HashMap; +import javax.annotation.Nonnull; +import javax.inject.Inject; +import jenkins.AgentProtocol; +import jenkins.model.Jenkins; +import jenkins.util.SystemProperties; +import org.jenkinsci.remoting.engine.JnlpClientDatabase; +import org.jenkinsci.remoting.engine.JnlpConnectionState; +import org.jenkinsci.remoting.engine.JnlpProtocol3Handler; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Master-side implementation for JNLP3-connect protocol. + * + *

    @see {@link org.jenkinsci.remoting.engine.JnlpProtocol3Handler} for more details. + * + * @since 1.XXX + */ +@Deprecated +@Extension +public class JnlpSlaveAgentProtocol3 extends AgentProtocol { + private NioChannelSelector hub; + + private JnlpProtocol3Handler handler; + + @Inject + public void setHub(NioChannelSelector hub) { + this.hub = hub; + this.handler = new JnlpProtocol3Handler(JnlpAgentReceiver.DATABASE, Computer.threadPoolForRemoting, + hub.getHub(), true); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isOptIn() { + return !ENABLED; + } + + @Override + public String getName() { + // we only want to force the protocol off for users that have explicitly banned it via system property + // everyone on the A/B test will just have the opt-in flag toggled + // TODO strip all this out and hardcode OptIn==TRUE once JENKINS-36871 is merged + return forceEnabled != Boolean.FALSE ? handler.getName() : null; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return Messages.JnlpSlaveAgentProtocol3_displayName(); + } + + @Override + public void handle(Socket socket) throws IOException, InterruptedException { + handler.handle(socket, + Collections.singletonMap(JnlpConnectionState.COOKIE_KEY, JnlpAgentReceiver.generateCookie()), + ExtensionList.lookup(JnlpAgentReceiver.class)); + } + + /** + * Flag to control the activation of JNLP3 protocol. + * + *

    + * Once this will be on by default, the flag and this field will disappear. The system property is + * an escape hatch for those who hit any issues and those who are trying this out. + */ + @Restricted(NoExternalUse.class) + @SuppressFBWarnings(value = "MS_SHOULD_BE_REFACTORED_TO_BE_FINAL", + justification = "Part of the administrative API for System Groovy scripts.") + public static boolean ENABLED; + private static final Boolean forceEnabled; + + static { + forceEnabled = SystemProperties.optBoolean(JnlpSlaveAgentProtocol3.class.getName() + ".enabled"); + if (forceEnabled != null) { + ENABLED = forceEnabled; + } else { + byte hash = Util.fromHexString(Jenkins.getActiveInstance().getLegacyInstanceId())[0]; + ENABLED = (hash % 10) == 0; + } + } +} diff --git a/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java new file mode 100644 index 0000000000000000000000000000000000000000..bcce1332f0568305286682cb7b6fe68af54ceb22 --- /dev/null +++ b/core/src/main/java/jenkins/slaves/JnlpSlaveAgentProtocol4.java @@ -0,0 +1,201 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.slaves; + +import hudson.Extension; +import hudson.ExtensionList; +import hudson.model.Computer; +import java.io.IOException; +import java.net.Socket; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.security.interfaces.RSAPrivateKey; +import java.util.Collections; +import java.util.HashMap; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.inject.Inject; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import jenkins.AgentProtocol; +import jenkins.model.identity.InstanceIdentityProvider; +import org.jenkinsci.remoting.engine.JnlpConnectionState; +import org.jenkinsci.remoting.engine.JnlpProtocol4Handler; +import org.jenkinsci.remoting.protocol.IOHub; +import org.jenkinsci.remoting.protocol.cert.PublicKeyMatchingX509ExtendedTrustManager; + +/** + * Master-side implementation for JNLP4-connect protocol. + * + *

    @see {@link org.jenkinsci.remoting.engine.JnlpProtocol4Handler} for more details. + * + * @since 2.27 + */ +@Extension +public class JnlpSlaveAgentProtocol4 extends AgentProtocol { + /** + * Our logger. + */ + private static final Logger LOGGER = Logger.getLogger(JnlpSlaveAgentProtocol4.class.getName()); + + /** + * Our keystore. + */ + private final KeyStore keyStore; + /** + * Our trust manager. + */ + private final TrustManager trustManager; + + /** + * The provider of our {@link IOHub} + */ + private IOHubProvider hub; + + /** + * Our handler. + */ + private JnlpProtocol4Handler handler; + /** + * Our SSL context. + */ + private SSLContext sslContext; + + /** + * Constructor. + * + * @throws KeyStoreException if things go wrong. + * @throws KeyManagementException if things go wrong. + * @throws IOException if things go wrong. + */ + public JnlpSlaveAgentProtocol4() throws KeyStoreException, KeyManagementException, IOException { + // prepare our local identity and certificate + X509Certificate identityCertificate = InstanceIdentityProvider.RSA.getCertificate(); + RSAPrivateKey privateKey = InstanceIdentityProvider.RSA.getPrivateKey(); + + // prepare our keyStore so we can provide our authentication + keyStore = KeyStore.getInstance("JKS"); + char[] password = "password".toCharArray(); + try { + keyStore.load(null, password); + } catch (IOException e) { + throw new IllegalStateException("Specification says this should not happen as we are not doing I/O", e); + } catch (NoSuchAlgorithmException | CertificateException e) { + throw new IllegalStateException("Specification says this should not happen as we are not loading keys", e); + } + keyStore.setKeyEntry("jenkins", privateKey, password, + new X509Certificate[]{identityCertificate}); + + // prepare our keyManagers to provide to the SSLContext + KeyManagerFactory kmf; + try { + kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + kmf.init(keyStore, password); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("Specification says the default algorithm should exist", e); + } catch (UnrecoverableKeyException e) { + throw new IllegalStateException("The key was just inserted with this exact password", e); + } + + // prepare our trustManagers + trustManager = new PublicKeyMatchingX509ExtendedTrustManager(false, true); + TrustManager[] trustManagers = {trustManager}; + + // prepare our SSLContext + try { + sslContext = SSLContext.getInstance("TLS"); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("Java runtime specification requires support for TLS algorithm", e); + } + sslContext.init(kmf.getKeyManagers(), trustManagers, null); + } + + /** + * Inject the {@link IOHubProvider} + * + * @param hub the hub provider. + */ + @Inject + public void setHub(IOHubProvider hub) { + this.hub = hub; + handler = new JnlpProtocol4Handler(JnlpAgentReceiver.DATABASE, Computer.threadPoolForRemoting, hub.getHub(), + sslContext, false, true); + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isOptIn() { + return true; + } + + /** + * {@inheritDoc} + */ + @Override + public String getDisplayName() { + return Messages.JnlpSlaveAgentProtocol4_displayName(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + return handler.getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public void handle(Socket socket) throws IOException, InterruptedException { + try { + X509Certificate certificate = (X509Certificate) keyStore.getCertificate("jenkins"); + if (certificate == null + || certificate.getNotAfter().getTime() < System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1)) { + LOGGER.log(Level.INFO, "Updating {0} TLS certificate to retain validity", getName()); + X509Certificate identityCertificate = InstanceIdentityProvider.RSA.getCertificate(); + RSAPrivateKey privateKey = InstanceIdentityProvider.RSA.getPrivateKey(); + char[] password = "password".toCharArray(); + keyStore.setKeyEntry("jenkins", privateKey, password, new X509Certificate[]{identityCertificate}); + } + } catch (KeyStoreException e) { + LOGGER.log(Level.FINEST, "Ignored", e); + } + handler.handle(socket, + Collections.singletonMap(JnlpConnectionState.COOKIE_KEY, JnlpAgentReceiver.generateCookie()), + ExtensionList.lookup(JnlpAgentReceiver.class)); + } + +} diff --git a/core/src/main/java/jenkins/slaves/JnlpSlaveHandshake.java b/core/src/main/java/jenkins/slaves/JnlpSlaveHandshake.java deleted file mode 100644 index b7c01a239e1aaa1ef4cebe77ab4a5175ccd2b8f5..0000000000000000000000000000000000000000 --- a/core/src/main/java/jenkins/slaves/JnlpSlaveHandshake.java +++ /dev/null @@ -1,118 +0,0 @@ -package jenkins.slaves; - -import hudson.model.Computer; -import hudson.remoting.Channel; -import hudson.remoting.ChannelBuilder; -import hudson.remoting.Engine; -import org.jenkinsci.remoting.nio.NioChannelHub; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.Socket; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Palette of objects to talk to the incoming JNLP slave connection. - * - * @author Kohsuke Kawaguchi - * @since 1.561 - */ -public class JnlpSlaveHandshake { - /** - * Useful for creating a {@link Channel} with NIO as the underlying transport. - */ - /*package*/ final NioChannelHub hub; - - /** - * Socket connection to the slave. - */ - /*package*/ final Socket socket; - - /** - * Wrapping Socket input stream. - */ - /*package*/ final DataInputStream in; - - /** - * For writing handshaking response. - * - * This is a poor design choice that we just carry forward for compatibility. - * For better protocol design, {@link DataOutputStream} is preferred for newer - * protocols. - */ - /*package*/ final PrintWriter out; - - /** - * Bag of properties the JNLP agent have sent us during the hand-shake. - */ - /*package*/ final Properties request = new Properties(); - - - /*package*/ JnlpSlaveHandshake(NioChannelHub hub, Socket socket, DataInputStream in, PrintWriter out) { - this.hub = hub; - this.socket = socket; - this.in = in; - this.out = out; - } - - public NioChannelHub getHub() { - return hub; - } - - public Socket getSocket() { - return socket; - } - - public DataInputStream getIn() { - return in; - } - - public PrintWriter getOut() { - return out; - } - - public Properties getRequestProperties() { - return request; - } - - public String getRequestProperty(String name) { - return request.getProperty(name); - } - - - /** - * Sends the error output and bail out. - */ - public void error(String msg) throws IOException { - out.println(msg); - LOGGER.log(Level.WARNING,Thread.currentThread().getName()+" is aborted: "+msg); - socket.close(); - } - - /** - * {@link JnlpAgentReceiver} calls this method to tell the client that the server - * is happy with the handshaking and is ready to move on to build a channel. - */ - public void success(Properties response) { - out.println(Engine.GREETING_SUCCESS); - for (Entry e : response.entrySet()) { - out.println(e.getKey()+": "+e.getValue()); - } - out.println(); // empty line to conclude the response header - } - - public ChannelBuilder createChannelBuilder(String nodeName) { - if (hub==null) - return new ChannelBuilder(nodeName, Computer.threadPoolForRemoting); - else - return hub.newChannelBuilder(nodeName, Computer.threadPoolForRemoting); - } - - - private static final Logger LOGGER = Logger.getLogger(JnlpSlaveHandshake.class.getName()); -} diff --git a/core/src/main/java/jenkins/slaves/NioChannelSelector.java b/core/src/main/java/jenkins/slaves/NioChannelSelector.java index 3aea28a1e32d84f6121abbe95fc8efd32be1476b..b8c086f80ab56cfff1e52d508dd9daec9453c8fc 100644 --- a/core/src/main/java/jenkins/slaves/NioChannelSelector.java +++ b/core/src/main/java/jenkins/slaves/NioChannelSelector.java @@ -1,6 +1,8 @@ package jenkins.slaves; import hudson.Extension; +import jenkins.util.SystemProperties; +import hudson.init.Terminator; import hudson.model.Computer; import org.jenkinsci.remoting.nio.NioChannelHub; @@ -34,10 +36,18 @@ public class NioChannelSelector { return hub; } + @Terminator + public void cleanUp() throws IOException { + if (hub!=null) { + hub.close(); + hub = null; + } + } + /** * Escape hatch to disable use of NIO. */ - public static boolean DISABLED = Boolean.getBoolean(NioChannelSelector.class.getName()+".disabled"); + public static boolean DISABLED = SystemProperties.getBoolean(NioChannelSelector.class.getName()+".disabled"); private static final Logger LOGGER = Logger.getLogger(NioChannelSelector.class.getName()); } diff --git a/core/src/main/java/jenkins/slaves/StandardOutputSwapper.java b/core/src/main/java/jenkins/slaves/StandardOutputSwapper.java index 794fc8626d5625ce47eb80193eecc7c9d7577dd1..89fedfd04ff52a602b547d70b8bb12acdbaafbc6 100644 --- a/core/src/main/java/jenkins/slaves/StandardOutputSwapper.java +++ b/core/src/main/java/jenkins/slaves/StandardOutputSwapper.java @@ -2,6 +2,7 @@ package jenkins.slaves; import hudson.Extension; import hudson.FilePath; +import jenkins.util.SystemProperties; import hudson.model.Computer; import hudson.model.TaskListener; import hudson.remoting.Channel; @@ -74,5 +75,5 @@ public class StandardOutputSwapper extends ComputerListener { } private static final Logger LOGGER = Logger.getLogger(StandardOutputSwapper.class.getName()); - public static boolean disabled = Boolean.getBoolean(StandardOutputSwapper.class.getName()+".disabled"); + public static boolean disabled = SystemProperties.getBoolean(StandardOutputSwapper.class.getName()+".disabled"); } diff --git a/core/src/main/java/jenkins/slaves/WorkspaceLocator.java b/core/src/main/java/jenkins/slaves/WorkspaceLocator.java index ff40093b6cbc7a1fc83ebd3b0c1727b64a6a4e69..7a99dce1c5a97c7c9cfabf785a3db9a5c7946ca9 100644 --- a/core/src/main/java/jenkins/slaves/WorkspaceLocator.java +++ b/core/src/main/java/jenkins/slaves/WorkspaceLocator.java @@ -5,11 +5,10 @@ import hudson.ExtensionPoint; import hudson.FilePath; import hudson.model.Node; import hudson.model.TopLevelItem; -import jenkins.model.Jenkins; /** * Allow extensions to override workspace locations - * on given slaves or projects. + * on given agents or projects. * * @author ryan.campbell@gmail.com * @since 1.501 @@ -18,11 +17,11 @@ public abstract class WorkspaceLocator implements ExtensionPoint { /** * Allows extensions to customize the workspace path. The first non-null response - * will determine the path to the workspace on that slave. + * will determine the path to the workspace on that agent. * * @param item The toplevel item - * @param node The slave node - * @return The absolute FilePath to the workspace on the slave. + * @param node The agent node + * @return The absolute FilePath to the workspace on the agent. * Will be created if it doesn't exist. * */ diff --git a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java index 61e21c4b182b895e49a91af6fc33c68d644d55fe..d30d6d2281867dce1c9bfe35844f029e444af4e2 100644 --- a/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java +++ b/core/src/main/java/jenkins/slaves/restarter/JnlpSlaveRestarterInstaller.java @@ -21,11 +21,11 @@ import static java.util.logging.Level.*; import jenkins.security.MasterToSlaveCallable; /** - * Actual slave restart logic. + * Actual agent restart logic. * *

    * Use {@link ComputerListener} to install {@link EngineListener}, which in turn gets executed when - * the slave gets disconnected. + * the agent gets disconnected. * * @author Kohsuke Kawaguchi */ @@ -73,15 +73,15 @@ public class JnlpSlaveRestarterInstaller extends ComputerListener implements Ser try { for (SlaveRestarter r : restarters) { try { - LOGGER.info("Restarting slave via "+r); + LOGGER.info("Restarting agent via "+r); r.restart(); } catch (Exception x) { - LOGGER.log(SEVERE, "Failed to restart slave with "+r, x); + LOGGER.log(SEVERE, "Failed to restart agent with "+r, x); } } } finally { // if we move on to the reconnection without restart, - // don't let the current implementations kick in when the slave loses connection again + // don't let the current implementations kick in when the agent loses connection again restarters.clear(); } } diff --git a/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java b/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java index e0c7c2f9124d81a47ab432b324b74e1ebcdecb8a..3484774e8ed9db736a971d15b7bded090de1f47b 100644 --- a/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java +++ b/core/src/main/java/jenkins/slaves/restarter/SlaveRestarter.java @@ -2,28 +2,27 @@ package jenkins.slaves.restarter; import hudson.ExtensionList; import hudson.ExtensionPoint; -import jenkins.model.Jenkins; import java.io.Serializable; import java.util.logging.Logger; /** - * Extension point to control how to restart JNLP slave when it loses the connection with the master. + * Extension point to control how to restart JNLP agent when it loses the connection with the master. * *

    - * Objects are instantiated on the master, then transfered to a slave via serialization. + * Objects are instantiated on the master, then transferred to an agent via serialization. * * @author Kohsuke Kawaguchi */ public abstract class SlaveRestarter implements ExtensionPoint, Serializable { /** - * Called on the slave to see if this restarter can work on this slave. + * Called on the agent to see if this restarter can work on this agent. */ public abstract boolean canWork(); /** * If {@link #canWork()} method returns true, this method is called later when - * the connection is lost to restart the slave. + * the connection is lost to restart the agent. * *

    * Note that by the time this method is called, classloader is no longer capable of @@ -33,8 +32,8 @@ public abstract class SlaveRestarter implements ExtensionPoint, Serializable { * *

    * This method is not expected to return, and the JVM should terminate before this call returns. - * If the method returns normally, the JNLP slave will move on to the reconnection without restart. - * If an exception is thrown, it is reported as an error and then the JNLP slave will move on to the + * If the method returns normally, the JNLP agent will move on to the reconnection without restart. + * If an exception is thrown, it is reported as an error and then the JNLP agent will move on to the * reconnection without restart. */ public abstract void restart() throws Exception; diff --git a/core/src/main/java/jenkins/slaves/systemInfo/ClassLoaderStatisticsSlaveInfo.java b/core/src/main/java/jenkins/slaves/systemInfo/ClassLoaderStatisticsSlaveInfo.java index 980d8468f7c6201b45428204d91d82a8ca91d927..28a3d3f85f5c1f907715c4cc31f0f7035fb3e0e0 100644 --- a/core/src/main/java/jenkins/slaves/systemInfo/ClassLoaderStatisticsSlaveInfo.java +++ b/core/src/main/java/jenkins/slaves/systemInfo/ClassLoaderStatisticsSlaveInfo.java @@ -1,11 +1,12 @@ package jenkins.slaves.systemInfo; import hudson.Extension; +import org.jenkinsci.Symbol; /** * @author Kohsuke Kawaguchi */ -@Extension(ordinal=0) +@Extension(ordinal=0) @Symbol("classLoaderStatistics") public class ClassLoaderStatisticsSlaveInfo extends SlaveSystemInfo { @Override public String getDisplayName() { diff --git a/core/src/main/java/jenkins/slaves/systemInfo/EnvVarsSlaveInfo.java b/core/src/main/java/jenkins/slaves/systemInfo/EnvVarsSlaveInfo.java index 4ded885092cce6301d8706bdd6ee2f0474f8e85d..6e1358c6f86aa65d11ee1460b2826a89dc1d3f38 100644 --- a/core/src/main/java/jenkins/slaves/systemInfo/EnvVarsSlaveInfo.java +++ b/core/src/main/java/jenkins/slaves/systemInfo/EnvVarsSlaveInfo.java @@ -1,11 +1,12 @@ package jenkins.slaves.systemInfo; import hudson.Extension; +import org.jenkinsci.Symbol; /** * @author Kohsuke Kawaguchi */ -@Extension(ordinal=2) +@Extension(ordinal=2) @Symbol("envVars") public class EnvVarsSlaveInfo extends SlaveSystemInfo { @Override public String getDisplayName() { diff --git a/core/src/main/java/jenkins/slaves/systemInfo/SlaveSystemInfo.java b/core/src/main/java/jenkins/slaves/systemInfo/SlaveSystemInfo.java index 6b39684f7552c2e4ed73ff491e043eb2e8f95cf0..16a5352d09aad470496420168cc9d4e267a1b79e 100644 --- a/core/src/main/java/jenkins/slaves/systemInfo/SlaveSystemInfo.java +++ b/core/src/main/java/jenkins/slaves/systemInfo/SlaveSystemInfo.java @@ -3,7 +3,6 @@ package jenkins.slaves.systemInfo; import hudson.ExtensionList; import hudson.ExtensionPoint; import hudson.model.Computer; -import jenkins.model.Jenkins; /** * Extension point that contributes to the system information page of {@link Computer}. diff --git a/core/src/main/java/jenkins/slaves/systemInfo/SystemPropertySlaveInfo.java b/core/src/main/java/jenkins/slaves/systemInfo/SystemPropertySlaveInfo.java index fe30064f241c20169e8d6eb771740ef3ac7767d4..553f69d8695a307bfe468cc1ad43ecb2b94a5638 100644 --- a/core/src/main/java/jenkins/slaves/systemInfo/SystemPropertySlaveInfo.java +++ b/core/src/main/java/jenkins/slaves/systemInfo/SystemPropertySlaveInfo.java @@ -1,11 +1,12 @@ package jenkins.slaves.systemInfo; import hudson.Extension; +import org.jenkinsci.Symbol; /** * @author Kohsuke Kawaguchi */ -@Extension(ordinal=3) +@Extension(ordinal=3) @Symbol("systemProperties") public class SystemPropertySlaveInfo extends SlaveSystemInfo { @Override public String getDisplayName() { diff --git a/core/src/main/java/jenkins/slaves/systemInfo/ThreadDumpSlaveInfo.java b/core/src/main/java/jenkins/slaves/systemInfo/ThreadDumpSlaveInfo.java index b0feabd0f8453e0f0d1d8c44c1d27cd7e9c4fa7d..b4a1a040e7827886b89eafc3f914a64936f9ad06 100644 --- a/core/src/main/java/jenkins/slaves/systemInfo/ThreadDumpSlaveInfo.java +++ b/core/src/main/java/jenkins/slaves/systemInfo/ThreadDumpSlaveInfo.java @@ -1,11 +1,12 @@ package jenkins.slaves.systemInfo; import hudson.Extension; +import org.jenkinsci.Symbol; /** * @author Kohsuke Kawaguchi */ -@Extension(ordinal=1) +@Extension(ordinal=1) @Symbol("threadDump") public class ThreadDumpSlaveInfo extends SlaveSystemInfo { @Override public String getDisplayName() { diff --git a/core/src/main/java/jenkins/tasks/SimpleBuildStep.java b/core/src/main/java/jenkins/tasks/SimpleBuildStep.java index 50b2fb8ca79951c9efd3af3f260276af890c5009..c99b15b71770242324b9d4224a8596d80898d1b0 100644 --- a/core/src/main/java/jenkins/tasks/SimpleBuildStep.java +++ b/core/src/main/java/jenkins/tasks/SimpleBuildStep.java @@ -28,19 +28,13 @@ import hudson.AbortException; import hudson.Extension; import hudson.FilePath; import hudson.Launcher; -import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Action; -import hudson.model.BuildListener; -import hudson.model.Computer; -import hudson.model.Executor; import hudson.model.InvisibleAction; import hudson.model.Job; import hudson.model.Run; import hudson.model.TaskListener; import hudson.tasks.BuildStep; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; import hudson.tasks.Builder; import hudson.tasks.Publisher; import java.io.IOException; @@ -81,18 +75,22 @@ public interface SimpleBuildStep extends BuildStep { * @throws InterruptedException if the step is interrupted * @throws IOException if something goes wrong; use {@link AbortException} for a polite error */ - void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, @Nonnull TaskListener listener) throws InterruptedException, IOException; + void perform(@Nonnull Run run, @Nonnull FilePath workspace, @Nonnull Launcher launcher, + @Nonnull TaskListener listener) throws InterruptedException, IOException; /** - * Marker for explicitly added build actions (as {@link Run#addAction}) which should imply a transient project action ({@link Job#getActions}) when present on the {@link Job#getLastSuccessfulBuild}. - * This can serve as a substitute for {@link BuildStep#getProjectActions} which does not assume that the project can enumerate the steps it would run before they are actually run. + * Marker for explicitly added build actions (as {@link Run#addAction}) which should imply a transient project + * action ({@link Job#getActions}) when present on the {@link Job#getLastSuccessfulBuild}. + * This can serve as a substitute for {@link BuildStep#getProjectActions} which does not assume that the project + * can enumerate the steps it would run before they are actually run. * (Use {@link InvisibleAction} as a base class if you do not need to show anything in the build itself.) */ interface LastBuildAction extends Action { /** * Optionally add some actions to the project owning this build. - * @return zero or more transient actions; if you need to know the {@link Job}, implement {@link RunAction2} and use {@link Run#getParent} + * @return zero or more transient actions; + * if you need to know the {@link Job}, implement {@link RunAction2} and use {@link Run#getParent} */ Collection getProjectActions(); @@ -100,14 +98,18 @@ public interface SimpleBuildStep extends BuildStep { @SuppressWarnings("rawtypes") @Restricted(DoNotUse.class) - @Extension public static final class LastBuildActionFactory extends TransientActionFactory { + @Extension + public static final class LastBuildActionFactory extends TransientActionFactory { - @Override public Class type() { + @Override + public Class type() { return Job.class; } - @Override public Collection createFor(Job j) { - List actions = new LinkedList(); + @Nonnull + @Override + public Collection createFor(@Nonnull Job j) { + List actions = new LinkedList<>(); Run r = j.getLastSuccessfulBuild(); if (r != null) { for (LastBuildAction a : r.getActions(LastBuildAction.class)) { @@ -115,7 +117,8 @@ public interface SimpleBuildStep extends BuildStep { } } // TODO should there be an option to check lastCompletedBuild even if it failed? - // Not useful for, say, TestResultAction, since if you have a build that fails before recording test results, the job would then have no TestResultProjectAction. + // Not useful for, say, TestResultAction, since if you have a build that fails before recording test + // results, the job would then have no TestResultProjectAction. return actions; } diff --git a/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java b/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java index e2da11b2bf9327a40b3111ee9d7ae1312e2d9384..df9ba97c96a097bacd2c1a7ea93ee6bd6ed06acc 100644 --- a/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java +++ b/core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java @@ -33,7 +33,6 @@ import hudson.model.AbstractBuild; import hudson.model.AbstractProject; import hudson.model.Action; import hudson.model.BuildListener; -import hudson.model.Computer; import hudson.model.Run; import hudson.model.TaskListener; import hudson.tasks.BuildWrapper; diff --git a/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java b/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java new file mode 100644 index 0000000000000000000000000000000000000000..209c4a1b72dc584747833d7c2689c862675fdd7c --- /dev/null +++ b/core/src/main/java/jenkins/tools/GlobalToolConfiguration.java @@ -0,0 +1,109 @@ +/* + * The MIT License + * + * Copyright (c) 2016 CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.tools; + +import com.google.common.base.Predicate; +import hudson.Extension; +import hudson.Functions; +import hudson.model.Descriptor; +import hudson.model.ManagementLink; +import hudson.security.Permission; +import hudson.util.FormApply; +import jenkins.model.GlobalConfigurationCategory; +import jenkins.model.Jenkins; +import net.sf.json.JSONObject; + +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Extension(ordinal = Integer.MAX_VALUE - 220) +@Restricted(NoExternalUse.class) +public class GlobalToolConfiguration extends ManagementLink { + + @Override + public String getIconFileName() { + return "setting.png"; + } + + @Override + public String getDisplayName() { + return jenkins.management.Messages.ConfigureTools_DisplayName(); + } + + @Override + public String getDescription() { + return jenkins.management.Messages.ConfigureTools_Description(); + } + + @Override + public String getUrlName() { + return "configureTools"; + } + + @Override + public Permission getRequiredPermission() { + return Jenkins.ADMINISTER; + } + + public synchronized void doConfigure(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, Descriptor.FormException { + boolean result = configure(req, req.getSubmittedForm()); + LOGGER.log(Level.FINE, "tools saved: "+result); + FormApply.success(req.getContextPath() + "/manage").generateResponse(req, rsp, null); + } + + private boolean configure(StaplerRequest req, JSONObject json) throws hudson.model.Descriptor.FormException, IOException { + Jenkins j = Jenkins.getInstance(); + j.checkPermission(Jenkins.ADMINISTER); + + boolean result = true; + for(Descriptor d : Functions.getSortedDescriptorsForGlobalConfig(FILTER)){ + result &= configureDescriptor(req, json, d); + } + j.save(); + + return result; + } + + private boolean configureDescriptor(StaplerRequest req, JSONObject json, Descriptor d) throws Descriptor.FormException { + String name = d.getJsonSafeClassName(); + JSONObject js = json.has(name) ? json.getJSONObject(name) : new JSONObject(); // if it doesn't have the property, the method returns invalid null object. + json.putAll(js); + return d.configure(req, js); + } + + public static Predicate FILTER = new Predicate() { + public boolean apply(GlobalConfigurationCategory input) { + return input instanceof ToolConfigurationCategory; + } + }; + + private static final Logger LOGGER = Logger.getLogger(GlobalToolConfiguration.class.getName()); +} diff --git a/core/src/main/java/jenkins/tools/ToolConfigurationCategory.java b/core/src/main/java/jenkins/tools/ToolConfigurationCategory.java new file mode 100644 index 0000000000000000000000000000000000000000..e785369556d1ec36ea0eaee5e30e080500c4f8d7 --- /dev/null +++ b/core/src/main/java/jenkins/tools/ToolConfigurationCategory.java @@ -0,0 +1,21 @@ +package jenkins.tools; + +import hudson.Extension; +import jenkins.model.GlobalConfigurationCategory; + +/** + * Global configuration of tool locations and installers. + * + * @since 2.0 + */ +@Extension +public class ToolConfigurationCategory extends GlobalConfigurationCategory { + @Override + public String getShortDescription() { + return jenkins.management.Messages.ConfigureTools_Description(); + } + + public String getDisplayName() { + return jenkins.management.Messages.ConfigureTools_DisplayName(); + } +} diff --git a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java index be6078eb51b9ec516243cfacebe462e9b2adc1d3..c9f432e6d1e7bdfef5cf6ebec2b907eff0b3d965 100644 --- a/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java +++ b/core/src/main/java/jenkins/triggers/ReverseBuildTrigger.java @@ -25,6 +25,7 @@ package jenkins.triggers; import hudson.Extension; +import hudson.ExtensionList; import hudson.Util; import hudson.console.ModelHyperlinkNote; import hudson.model.AbstractBuild; @@ -32,6 +33,7 @@ import hudson.model.AbstractProject; import hudson.model.Action; import hudson.model.AutoCompletionCandidates; import hudson.model.Cause; +import hudson.model.CauseAction; import hudson.model.DependencyGraph; import hudson.model.Item; import hudson.model.ItemGroup; @@ -45,6 +47,7 @@ import hudson.model.listeners.ItemListener; import hudson.model.listeners.RunListener; import hudson.model.queue.Tasks; import hudson.security.ACL; +import hudson.security.ACLContext; import hudson.tasks.BuildTrigger; import hudson.triggers.Trigger; import hudson.triggers.TriggerDescriptor; @@ -67,10 +70,13 @@ import org.acegisecurity.Authentication; import org.acegisecurity.context.SecurityContext; import org.acegisecurity.context.SecurityContextHolder; import org.apache.commons.lang.StringUtils; +import org.jenkinsci.Symbol; import org.kohsuke.stapler.AncestorInPath; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.QueryParameter; +import javax.annotation.Nonnull; + /** * Like {@link BuildTrigger} but defined on the downstream project. * Operates via {@link BuildTrigger#execute} and {@link DependencyGraph}, @@ -83,12 +89,12 @@ import org.kohsuke.stapler.QueryParameter; public final class ReverseBuildTrigger extends Trigger implements DependencyDeclarer { private static final Logger LOGGER = Logger.getLogger(ReverseBuildTrigger.class.getName()); - private static final Map> upstream2Trigger = new WeakHashMap>(); private String upstreamProjects; private final Result threshold; - @DataBoundConstructor public ReverseBuildTrigger(String upstreamProjects, Result threshold) { + @DataBoundConstructor + public ReverseBuildTrigger(String upstreamProjects, Result threshold) { this.upstreamProjects = upstreamProjects; this.threshold = threshold; } @@ -103,7 +109,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc private boolean shouldTrigger(Run upstreamBuild, TaskListener listener) { Jenkins jenkins = Jenkins.getInstance(); - if (jenkins == null) { + if (job == null) { return false; } // This checks Item.READ also on parent folders; note we are checking as the upstream auth currently: @@ -143,39 +149,18 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc } } - @Override public void start(Job project, boolean newInstance) { + @Override public void start(@Nonnull Job project, boolean newInstance) { super.start(project, newInstance); - SecurityContext orig = ACL.impersonate(ACL.SYSTEM); - try { - for (Job upstream : Items.fromNameList(project.getParent(), upstreamProjects, Job.class)) { - if (upstream instanceof AbstractProject && project instanceof AbstractProject) { - continue; // handled specially - } - synchronized (upstream2Trigger) { - Collection triggers = upstream2Trigger.get(upstream); - if (triggers == null) { - triggers = new LinkedList(); - upstream2Trigger.put(upstream, triggers); - } - triggers.remove(this); - triggers.add(this); - } - } - } finally { - SecurityContextHolder.setContext(orig); - } + RunListenerImpl.get().invalidateCache(); } @Override public void stop() { super.stop(); - synchronized (upstream2Trigger) { - for (Collection triggers : upstream2Trigger.values()) { - triggers.remove(this); - } - } + RunListenerImpl.get().invalidateCache(); } - @Extension public static final class DescriptorImpl extends TriggerDescriptor { + @Extension @Symbol("upstream") + public static final class DescriptorImpl extends TriggerDescriptor { @Override public String getDisplayName() { return Messages.ReverseBuildTrigger_build_after_other_projects_are_built(); @@ -198,11 +183,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc while(tokens.hasMoreTokens()) { String projectName = tokens.nextToken().trim(); if (StringUtils.isNotBlank(projectName)) { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins == null) { - return FormValidation.ok(); - } - Job item = jenkins.getItem(projectName, project, Job.class); + Job item = Jenkins.getInstance().getItem(projectName, project, Job.class); if (item == null) { Job nearest = Items.findNearest(Job.class, projectName, project.getParent()); String alternative = nearest != null ? nearest.getRelativeNameFrom(project) : "?"; @@ -221,14 +202,57 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc } @Extension public static final class RunListenerImpl extends RunListener { - @Override public void onCompleted(Run r, TaskListener listener) { + + static RunListenerImpl get() { + return ExtensionList.lookup(RunListener.class).get(RunListenerImpl.class); + } + + private Map> upstream2Trigger; + + synchronized void invalidateCache() { + upstream2Trigger = null; + } + + private Map> calculateCache() { + try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + final Map> result = new WeakHashMap<>(); + for (Job downstream : Jenkins.getInstance().getAllItems(Job.class)) { + ReverseBuildTrigger trigger = + ParameterizedJobMixIn.getTrigger(downstream, ReverseBuildTrigger.class); + if (trigger == null) { + continue; + } + List upstreams = + Items.fromNameList(downstream.getParent(), trigger.upstreamProjects, Job.class); + LOGGER.log(Level.FINE, "from {0} see upstreams {1}", new Object[]{downstream, upstreams}); + for (Job upstream : upstreams) { + if (upstream instanceof AbstractProject && downstream instanceof AbstractProject) { + continue; // handled specially + } + Collection triggers = result.get(upstream); + if (triggers == null) { + triggers = new LinkedList<>(); + result.put(upstream, triggers); + } + triggers.remove(trigger); + triggers.add(trigger); + } + } + return result; + } + } + + @Override public void onCompleted(@Nonnull Run r, @Nonnull TaskListener listener) { Collection triggers; - synchronized (upstream2Trigger) { + synchronized (this) { + if (upstream2Trigger == null) { + upstream2Trigger = calculateCache(); + } Collection _triggers = upstream2Trigger.get(r.getParent()); if (_triggers == null || _triggers.isEmpty()) { return; } - triggers = new ArrayList(_triggers); + triggers = new ArrayList<>(_triggers); } for (final ReverseBuildTrigger trigger : triggers) { if (trigger.shouldTrigger(r, listener)) { @@ -237,11 +261,7 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc continue; } String name = ModelHyperlinkNote.encodeTo(trigger.job) + " #" + trigger.job.getNextBuildNumber(); - if (new ParameterizedJobMixIn() { - @Override protected Job asJob() { - return trigger.job; - } - }.scheduleBuild(new Cause.UpstreamCause(r))) { + if (ParameterizedJobMixIn.scheduleBuild2(trigger.job, -1, new CauseAction(new Cause.UpstreamCause(r))) != null) { listener.getLogger().println(hudson.tasks.Messages.BuildTrigger_Triggering(name)); } else { listener.getLogger().println(hudson.tasks.Messages.BuildTrigger_InQueue(name)); @@ -251,23 +271,26 @@ public final class ReverseBuildTrigger extends Trigger implements Dependenc } } - @Extension public static class ItemListenerImpl extends ItemListener { - @Override public void onLocationChanged(Item item, String oldFullName, String newFullName) { - Jenkins jenkins = Jenkins.getInstance(); - if (jenkins == null) { - return; - } - for (ParameterizedJobMixIn.ParameterizedJob p : jenkins.getAllItems(ParameterizedJobMixIn.ParameterizedJob.class)) { - Trigger _t = p.getTriggers().get(jenkins.getDescriptorByType(DescriptorImpl.class)); - if (_t instanceof ReverseBuildTrigger) { - ReverseBuildTrigger t = (ReverseBuildTrigger) _t; - String revised = Items.computeRelativeNamesAfterRenaming(oldFullName, newFullName, t.upstreamProjects, p.getParent()); - if (!revised.equals(t.upstreamProjects)) { - t.upstreamProjects = revised; - try { - p.save(); - } catch (IOException e) { - LOGGER.log(Level.WARNING, "Failed to persist project setting during rename from " + oldFullName + " to " + newFullName, e); + @Extension + public static class ItemListenerImpl extends ItemListener { + @Override + public void onLocationChanged(Item item, final String oldFullName, final String newFullName) { + try (ACLContext _ = ACL.as(ACL.SYSTEM)) { + for (Job p : Jenkins.getInstance().getAllItems(Job.class)) { + ReverseBuildTrigger t = ParameterizedJobMixIn.getTrigger(p, ReverseBuildTrigger.class); + if (t != null) { + String revised = + Items.computeRelativeNamesAfterRenaming(oldFullName, newFullName, t.upstreamProjects, + p.getParent()); + if (!revised.equals(t.upstreamProjects)) { + t.upstreamProjects = revised; + try { + p.save(); + } catch (IOException e) { + LOGGER.log(Level.WARNING, + "Failed to persist project setting during rename from " + oldFullName + " to " + + newFullName, e); + } } } } diff --git a/core/src/main/java/jenkins/triggers/SCMTriggerItem.java b/core/src/main/java/jenkins/triggers/SCMTriggerItem.java index 1c916edf52cc6a9f5a1404427215c40d1e71ba69..7a1cb1db27d122ecd35a726a75207cab3e796087 100644 --- a/core/src/main/java/jenkins/triggers/SCMTriggerItem.java +++ b/core/src/main/java/jenkins/triggers/SCMTriggerItem.java @@ -40,6 +40,7 @@ import java.util.logging.Logger; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import jenkins.model.ParameterizedJobMixIn; +import jenkins.scm.SCMDecisionHandler; /** * The item type accepted by {@link SCMTrigger}. @@ -65,6 +66,9 @@ public interface SCMTriggerItem { *

    * The implementation is responsible for ensuring mutual exclusion between polling and builds * if necessary. + *

    + * The implementation is responsible for checking the {@link SCMDecisionHandler} before proceeding + * with the actual polling. */ @Nonnull PollingResult poll(@Nonnull TaskListener listener); @@ -116,6 +120,11 @@ public interface SCMTriggerItem { return delegate.asProject().scheduleBuild2(quietPeriod, null, actions); } @Override public PollingResult poll(TaskListener listener) { + SCMDecisionHandler veto = SCMDecisionHandler.firstShouldPollVeto(asItem()); + if (veto != null && !veto.shouldPoll(asItem())) { + listener.getLogger().println(Messages.SCMTriggerItem_PollingVetoed(veto)); + return PollingResult.NO_CHANGES; + } return delegate.poll(listener); } @Override public SCMTrigger getSCMTrigger() { diff --git a/core/src/main/java/jenkins/util/AntClassLoader.java b/core/src/main/java/jenkins/util/AntClassLoader.java index 16c7c374742507b66dcf8852ef89c28cfd6b33a0..baf7eb968ab6ddf6c19dc0382ce2c714988282c1 100644 --- a/core/src/main/java/jenkins/util/AntClassLoader.java +++ b/core/src/main/java/jenkins/util/AntClassLoader.java @@ -1352,31 +1352,25 @@ public class AntClassLoader extends ClassLoader implements SubBuildListener { throws ClassNotFoundException { // we need to search the components of the path to see if // we can find the class we want. - InputStream stream = null; String classFilename = getClassFilename(name); - try { - Enumeration e = pathComponents.elements(); - while (e.hasMoreElements()) { - File pathComponent = (File) e.nextElement(); - try { - stream = getResourceStream(pathComponent, classFilename); - if (stream != null) { - log("Loaded from " + pathComponent + " " - + classFilename, Project.MSG_DEBUG); - return getClassFromStream(stream, name, pathComponent); - } - } catch (SecurityException se) { - throw se; - } catch (IOException ioe) { - // ioe.printStackTrace(); - log("Exception reading component " + pathComponent + " (reason: " - + ioe.getMessage() + ")", Project.MSG_VERBOSE); + Enumeration e = pathComponents.elements(); + while (e.hasMoreElements()) { + File pathComponent = (File) e.nextElement(); + try (final InputStream stream = getResourceStream(pathComponent, classFilename)) { + if (stream != null) { + log("Loaded from " + pathComponent + " " + + classFilename, Project.MSG_DEBUG); + return getClassFromStream(stream, name, pathComponent); } + } catch (SecurityException se) { + throw se; + } catch (IOException ioe) { + // ioe.printStackTrace(); + log("Exception reading component " + pathComponent + " (reason: " + + ioe.getMessage() + ")", Project.MSG_VERBOSE); } - throw new ClassNotFoundException(name); - } finally { - FileUtils.close(stream); } + throw new ClassNotFoundException(name); } /** diff --git a/core/src/main/java/jenkins/util/HttpSessionListener.java b/core/src/main/java/jenkins/util/HttpSessionListener.java new file mode 100644 index 0000000000000000000000000000000000000000..7efbee9dd00b1e74f8c757538328436d39915c7d --- /dev/null +++ b/core/src/main/java/jenkins/util/HttpSessionListener.java @@ -0,0 +1,64 @@ +/* + * The MIT License + * + * Copyright (c) 2016, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.util; + + +import hudson.ExtensionList; +import hudson.ExtensionPoint; + +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionEvent; + +/** + * {@link javax.servlet.http.HttpSessionListener} {@link ExtensionPoint} for Jenkins. + *

    + * Allows plugins to listen to {@link HttpSession} lifecycle events. + * + * @author tom.fennelly@gmail.com + * @since 2.2 + */ +public abstract class HttpSessionListener implements ExtensionPoint, javax.servlet.http.HttpSessionListener { + + /** + * Get all of the {@link HttpSessionListener} implementations. + * @return All of the {@link HttpSessionListener} implementations. + */ + public static ExtensionList all() { + return ExtensionList.lookup(HttpSessionListener.class); + } + + /** + * {@inheritDoc} + */ + @Override + public void sessionCreated(HttpSessionEvent httpSessionEvent) { + } + + /** + * {@inheritDoc} + */ + @Override + public void sessionDestroyed(HttpSessionEvent httpSessionEvent) { + } +} diff --git a/core/src/main/java/jenkins/util/JSONSignatureValidator.java b/core/src/main/java/jenkins/util/JSONSignatureValidator.java index 76d422cd90743110d7279db0ecb926efc6d10acc..865a7b9917645791b056667ade8c85456373dc45 100644 --- a/core/src/main/java/jenkins/util/JSONSignatureValidator.java +++ b/core/src/main/java/jenkins/util/JSONSignatureValidator.java @@ -82,7 +82,11 @@ public class JSONSignatureValidator { // this is for computing a signature Signature sig = Signature.getInstance("SHA1withRSA"); - sig.initVerify(certs.get(0)); + if (certs.isEmpty()) { + return FormValidation.error("No certificate found in %s. Cannot verify the signature", name); + } else { + sig.initVerify(certs.get(0)); + } SignatureOutputStream sos = new SignatureOutputStream(sig); // until JENKINS-11110 fix, UC used to serve invalid digest (and therefore unverifiable signature) @@ -135,17 +139,13 @@ public class JSONSignatureValidator { // which isn't useful at all Set anchors = new HashSet(); // CertificateUtil.getDefaultRootCAs(); Jenkins j = Jenkins.getInstance(); - if (j == null) { - return anchors; - } for (String cert : (Set) j.servletContext.getResourcePaths("/WEB-INF/update-center-rootCAs")) { if (cert.endsWith("/") || cert.endsWith(".txt")) { continue; // skip directories also any text files that are meant to be documentation } - InputStream in = j.servletContext.getResourceAsStream(cert); - if (in == null) continue; // our test for paths ending in / should prevent this from happening Certificate certificate; - try { + try (InputStream in = j.servletContext.getResourceAsStream(cert)) { + if (in == null) continue; // our test for paths ending in / should prevent this from happening certificate = cf.generateCertificate(in); } catch (CertificateException e) { LOGGER.log(Level.WARNING, String.format("Webapp resources in /WEB-INF/update-center-rootCAs are " @@ -154,8 +154,6 @@ public class JSONSignatureValidator { + "resource for now.", cert), e); continue; - } finally { - in.close(); } try { TrustAnchor certificateAuthority = new TrustAnchor((X509Certificate) certificate, null); diff --git a/core/src/main/java/jenkins/util/JenkinsJVM.java b/core/src/main/java/jenkins/util/JenkinsJVM.java new file mode 100644 index 0000000000000000000000000000000000000000..f8e37a79a15cfa401fc3711a5ddef0adaa7d6dfb --- /dev/null +++ b/core/src/main/java/jenkins/util/JenkinsJVM.java @@ -0,0 +1,73 @@ +package jenkins.util; + +import hudson.WebAppMain; +import javax.servlet.ServletContextEvent; +import jenkins.model.Jenkins; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * A utility class to identify if the current JVM is the one that is running {@link Jenkins} + * + * @since 1.653 + */ +public class JenkinsJVM { + /** + * Flag to identify the JVM running {@link Jenkins}. + */ + private static boolean jenkinsJVM; + + /** + * Protect against people instantiating this class. + */ + @Restricted(NoExternalUse.class) + protected JenkinsJVM() { + throw new IllegalAccessError("Utility class"); + } + + /** + * Identify whether the classloader that loaded this class is the classloader from which {@link Jenkins} has been + * started. + * + * @return {@code true} if this is the classloader on the JVM that started {@link Jenkins} otherwise {@code false} + */ + public static boolean isJenkinsJVM() { + return jenkinsJVM; + } + + /** + * Verify that the classloader that loaded this class is the classloader from which {@link Jenkins} has been + * started. + * + * @throws IllegalStateException if this is not the classloader on the JVM that started {@link Jenkins}. + */ + public static void checkJenkinsJVM() { + if (!isJenkinsJVM()) { + throw new IllegalStateException("Not running on the Jenkins master JVM"); + } + } + + /** + * Verify that the classloader that loaded this class is not the classloader from which {@link Jenkins} has been + * started. + * + * @throws IllegalStateException if this is the classloader on the JVM that started {@link Jenkins}. + */ + public static void checkNotJenkinsJVM() { + if (isJenkinsJVM()) { + throw new IllegalStateException("Running on the Jenkins master JVM"); + } + } + + /** + * Used by {@link WebAppMain#contextInitialized(ServletContextEvent)} and + * {@link WebAppMain#contextDestroyed(ServletContextEvent)} to identify the classloader and JVM which started + * {@link Jenkins} + * + * @param jenkinsJVM {@code true} if and only if this is the classloader and JVM that started {@link Jenkins}. + */ + @Restricted(NoExternalUse.class) + protected static void setJenkinsJVM(boolean jenkinsJVM) { + JenkinsJVM.jenkinsJVM = jenkinsJVM; + } +} diff --git a/core/src/main/java/jenkins/util/ProgressiveRendering.java b/core/src/main/java/jenkins/util/ProgressiveRendering.java index 11cd35c0e28207fb55d52220b2b76a0047d2c82c..77582d74cef238479bce8f0dc445a33440448120 100644 --- a/core/src/main/java/jenkins/util/ProgressiveRendering.java +++ b/core/src/main/java/jenkins/util/ProgressiveRendering.java @@ -24,8 +24,7 @@ package jenkins.util; -import edu.umd.cs.findbugs.annotations.SuppressWarnings; -import hudson.model.AbstractItem; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; @@ -78,7 +77,7 @@ public abstract class ProgressiveRendering { private static final Logger LOG = Logger.getLogger(ProgressiveRendering.class.getName()); /** May be set to a number of milliseconds to sleep in {@link #canceled}, useful for watching what are normally fast computations. */ - private static final Long DEBUG_SLEEP = Long.getLong("jenkins.util.ProgressiveRendering.DEBUG_SLEEP"); + private static final Long DEBUG_SLEEP = SystemProperties.getLong("jenkins.util.ProgressiveRendering.DEBUG_SLEEP"); private static final int CANCELED = -1; private static final int ERROR = -2; diff --git a/core/src/main/java/jenkins/util/ResourceBundleUtil.java b/core/src/main/java/jenkins/util/ResourceBundleUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..b2eee336abc1a262fad51a1ea537c29f53d42e9c --- /dev/null +++ b/core/src/main/java/jenkins/util/ResourceBundleUtil.java @@ -0,0 +1,135 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.util; + +import net.sf.json.JSONObject; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import hudson.PluginWrapper; +import java.util.logging.Logger; +import java.util.Locale; +import java.util.Map; +import java.util.MissingResourceException; +import java.util.ResourceBundle; +import java.util.concurrent.ConcurrentHashMap; +import jenkins.model.Jenkins; + +/** + * Simple {@link java.util.ResourceBundle} utility class. + * @author tom.fennelly@gmail.com + * @since 2.0 + */ +@Restricted(NoExternalUse.class) +public class ResourceBundleUtil { + + private static final Logger logger = Logger.getLogger("jenkins.util.ResourceBundle"); + private static final Map bundles = new ConcurrentHashMap<>(); + + private ResourceBundleUtil() { + } + + /** + * Get a bundle JSON using the default Locale. + * @param baseName The bundle base name. + * @return The bundle JSON. + * @throws MissingResourceException Missing resource bundle. + */ + public static @Nonnull JSONObject getBundle(@Nonnull String baseName) throws MissingResourceException { + return getBundle(baseName, Locale.getDefault()); + } + + /** + * Get a bundle JSON using the supplied Locale. + * @param baseName The bundle base name. + * @param locale The Locale. + * @return The bundle JSON. + * @throws MissingResourceException Missing resource bundle. + */ + public static @Nonnull JSONObject getBundle(@Nonnull String baseName, @Nonnull Locale locale) throws MissingResourceException { + String bundleKey = baseName + ":" + locale.toString(); + JSONObject bundleJSON = bundles.get(bundleKey); + + if (bundleJSON != null) { + return bundleJSON; + } + + ResourceBundle bundle = getBundle(baseName, locale, Jenkins.class.getClassLoader()); + if (bundle == null) { + // Not in Jenkins core. Check the plugins. + Jenkins jenkins = Jenkins.getInstance(); // will never return null + if (jenkins != null) { + for (PluginWrapper plugin : jenkins.getPluginManager().getPlugins()) { + bundle = getBundle(baseName, locale, plugin.classLoader); + if (bundle != null) { + break; + } + } + } + } + if (bundle == null) { + throw new MissingResourceException("Can't find bundle for base name " + + baseName + ", locale " + locale, baseName + "_" + locale, ""); + } + + bundleJSON = toJSONObject(bundle); + bundles.put(bundleKey, bundleJSON); + + return bundleJSON; + } + + /** + * Get a plugin bundle using the supplied Locale and classLoader + * + * @param baseName The bundle base name. + * @param locale The Locale. + * @param classLoader The classLoader + * @return The bundle JSON. + */ + private static @CheckForNull ResourceBundle getBundle(@Nonnull String baseName, @Nonnull Locale locale, @Nonnull ClassLoader classLoader) { + try { + return ResourceBundle.getBundle(baseName, locale, classLoader); + } catch (MissingResourceException e) { + // fall through and return null. + logger.finer(e.getMessage()); + } + return null; + } + + /** + * Create a JSON representation of a resource bundle + * + * @param bundle The resource bundle. + * @return The bundle JSON. + */ + private static JSONObject toJSONObject(@Nonnull ResourceBundle bundle) { + JSONObject json = new JSONObject(); + for (String key : bundle.keySet()) { + json.put(key, bundle.getString(key)); + } + return json; + } +} diff --git a/core/src/main/java/jenkins/util/SystemProperties.java b/core/src/main/java/jenkins/util/SystemProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..464f347d4c22f9ce4e26b55d306d73ee8fa26b4e --- /dev/null +++ b/core/src/main/java/jenkins/util/SystemProperties.java @@ -0,0 +1,394 @@ +/* + * The MIT License + * + * Copyright 2015 Johannes Ernst http://upon2020.com/ + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.util; + +import edu.umd.cs.findbugs.annotations.CheckForNull; +import edu.umd.cs.findbugs.annotations.Nullable; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +import hudson.EnvVars; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import jenkins.util.io.OnMaster; +import org.apache.commons.lang.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +/** + * Centralizes calls to {@link System#getProperty()} and related calls. + * This allows us to get values not just from environment variables but also from + * the {@link ServletContext}, so properties like {@code hudson.DNSMultiCast.disabled} + * can be set in {@code context.xml} and the app server's boot script does not + * have to be changed. + * + *

    This should be used to obtain hudson/jenkins "app"-level parameters + * (e.g. {@code hudson.DNSMultiCast.disabled}), but not for system parameters + * (e.g. {@code os.name}). + * + *

    If you run multiple instances of Jenkins in the same virtual machine and wish + * to obtain properties from {@code context.xml}, make sure these Jenkins instances use + * different ClassLoaders. Tomcat, for example, does this automatically. If you do + * not use different ClassLoaders, the values of properties specified in + * {@code context.xml} is undefined. + * + *

    Property access is logged on {@link Level#CONFIG}. Note that some properties + * may be accessed by Jenkins before logging is configured properly, so early access to + * some properties may not be logged. + * + *

    While it looks like it on first glance, this cannot be mapped to {@link EnvVars}, + * because {@link EnvVars} is only for build variables, not Jenkins itself variables. + * + * @author Johannes Ernst + * @since 2.4 + */ +//TODO: Define a correct design of this engine later. Should be accessible in libs (remoting, stapler) and Jenkins modules too +@Restricted(NoExternalUse.class) +public class SystemProperties implements ServletContextListener, OnMaster { + // this class implements ServletContextListener and is declared in WEB-INF/web.xml + + /** + * The ServletContext to get the "init" parameters from. + */ + @CheckForNull + private static ServletContext theContext; + + /** + * Logger. + */ + private static final Logger LOGGER = Logger.getLogger(SystemProperties.class.getName()); + + /** + * Public for the servlet container. + */ + public SystemProperties() {} + + /** + * Called by the servlet container to initialize the {@link ServletContext}. + */ + @Override + @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", + justification = "Currently Jenkins instance may have one ond only one context") + public void contextInitialized(ServletContextEvent event) { + theContext = event.getServletContext(); + } + + /** + * Gets the system property indicated by the specified key. + * This behaves just like {@link System#getProperty(java.lang.String)}, except that it + * also consults the {@link ServletContext}'s "init" parameters. + * + * @param key the name of the system property. + * @return the string value of the system property, + * or {@code null} if there is no property with that key. + * + * @exception NullPointerException if {@code key} is {@code null}. + * @exception IllegalArgumentException if {@code key} is empty. + */ + @CheckForNull + public static String getString(String key) { + String value = System.getProperty(key); // keep passing on any exceptions + if (value != null) { + if (LOGGER.isLoggable(Level.CONFIG)) { + LOGGER.log(Level.CONFIG, "Property (system): {0} => {1}", new Object[] {key, value}); + } + return value; + } + + value = tryGetValueFromContext(key); + if (value != null) { + if (LOGGER.isLoggable(Level.CONFIG)) { + LOGGER.log(Level.CONFIG, "Property (context): {0} => {1}", new Object[]{key, value}); + } + return value; + } + + if (LOGGER.isLoggable(Level.CONFIG)) { + LOGGER.log(Level.CONFIG, "Property (not found): {0} => {1}", new Object[] {key, value}); + } + return null; + } + + /** + * Gets the system property indicated by the specified key, or a default value. + * This behaves just like {@link System#getProperty(java.lang.String, java.lang.String)}, except + * that it also consults the {@link ServletContext}'s "init" parameters. + * + * @param key the name of the system property. + * @param def a default value. + * @return the string value of the system property, + * or {@code null} if the the property is missing and the default value is {@code null}. + * + * @exception NullPointerException if {@code key} is {@code null}. + * @exception IllegalArgumentException if {@code key} is empty. + */ + public static String getString(String key, @CheckForNull String def) { + return getString(key, def, Level.CONFIG); + } + + /** + * Gets the system property indicated by the specified key, or a default value. + * This behaves just like {@link System#getProperty(java.lang.String, java.lang.String)}, except + * that it also consults the {@link ServletContext}'s "init" parameters. + * + * @param key the name of the system property. + * @param def a default value. + * @param logLevel the level of the log if the provided key is not found. + * @return the string value of the system property, + * or {@code null} if the the property is missing and the default value is {@code null}. + * + * @exception NullPointerException if {@code key} is {@code null}. + * @exception IllegalArgumentException if {@code key} is empty. + */ + public static String getString(String key, @CheckForNull String def, Level logLevel) { + String value = System.getProperty(key); // keep passing on any exceptions + if (value != null) { + if (LOGGER.isLoggable(logLevel)) { + LOGGER.log(logLevel, "Property (system): {0} => {1}", new Object[] {key, value}); + } + return value; + } + + value = tryGetValueFromContext(key); + if (value != null) { + if (LOGGER.isLoggable(logLevel)) { + LOGGER.log(logLevel, "Property (context): {0} => {1}", new Object[]{key, value}); + } + return value; + } + + value = def; + if (LOGGER.isLoggable(logLevel)) { + LOGGER.log(logLevel, "Property (default): {0} => {1}", new Object[] {key, value}); + } + return value; + } + + /** + * Returns {@code true} if the system property + * named by the argument exists and is equal to the string + * {@code "true"}. If the system property does not exist, return + * {@code "false"}. if a property by this name exists in the {@link ServletContext} + * and is equal to the string {@code "true"}. + * + * This behaves just like {@link Boolean#getBoolean(java.lang.String)}, except that it + * also consults the {@link ServletContext}'s "init" parameters. + * + * @param name the system property name. + * @return the {@code boolean} value of the system property. + */ + public static boolean getBoolean(String name) { + return getBoolean(name, false); + } + + /** + * Returns {@code true} if the system property + * named by the argument exists and is equal to the string + * {@code "true"}, or a default value. If the system property does not exist, return + * {@code "true"} if a property by this name exists in the {@link ServletContext} + * and is equal to the string {@code "true"}. If that property does not + * exist either, return the default value. + * + * This behaves just like {@link Boolean#getBoolean(java.lang.String)} with a default + * value, except that it also consults the {@link ServletContext}'s "init" parameters. + * + * @param name the system property name. + * @param def a default value. + * @return the {@code boolean} value of the system property. + */ + public static boolean getBoolean(String name, boolean def) { + String v = getString(name); + + if (v != null) { + return Boolean.parseBoolean(v); + } + return def; + } + + /** + * Returns {@link Boolean#TRUE} if the named system property exists and is equal to the string {@code "true} + * (ignoring case), returns {@link Boolean#FALSE} if the system property exists and doesn't equal {@code "true} + * otherwise returns {@code null} if the named system property does not exist. + * + * @param name the system property name. + * @return {@link Boolean#TRUE}, {@link Boolean#FALSE} or {@code null} + * @since 2.16 + */ + @CheckForNull + public static Boolean optBoolean(String name) { + String v = getString(name); + return v == null ? null : Boolean.parseBoolean(v); + } + + /** + * Determines the integer value of the system property with the + * specified name. + * + * This behaves just like {@link Integer#getInteger(java.lang.String)}, except that it + * also consults the {@link ServletContext}'s "init" parameters. + * + * @param name property name. + * @return the {@code Integer} value of the property. + */ + @CheckForNull + public static Integer getInteger(String name) { + return getInteger(name, null); + } + + /** + * Determines the integer value of the system property with the + * specified name, or a default value. + * + * This behaves just like Integer.getInteger(String,Integer), except that it + * also consults the ServletContext's "init" parameters. If neither exist, + * return the default value. + * + * @param name property name. + * @param def a default value. + * @return the {@code Integer} value of the property. + * If the property is missing, return the default value. + * Result may be {@code null} only if the default value is {@code null}. + */ + public static Integer getInteger(String name, Integer def) { + return getInteger(name, def, Level.CONFIG); + } + + /** + * Determines the integer value of the system property with the + * specified name, or a default value. + * + * This behaves just like Integer.getInteger(String,Integer), except that it + * also consults the ServletContext's "init" parameters. If neither exist, + * return the default value. + * + * @param name property name. + * @param def a default value. + * @param logLevel the level of the log if the provided system property name cannot be decoded into Integer. + * @return the {@code Integer} value of the property. + * If the property is missing, return the default value. + * Result may be {@code null} only if the default value is {@code null}. + */ + public static Integer getInteger(String name, Integer def, Level logLevel) { + String v = getString(name); + + if (v != null) { + try { + return Integer.decode(v); + } catch (NumberFormatException e) { + // Ignore, fallback to default + if (LOGGER.isLoggable(logLevel)) { + LOGGER.log(logLevel, "Property. Value is not integer: {0} => {1}", new Object[] {name, v}); + } + } + } + return def; + } + + /** + * Determines the long value of the system property with the + * specified name. + * + * This behaves just like {@link Long#getLong(java.lang.String)}, except that it + * also consults the {@link ServletContext}'s "init" parameters. + * + * @param name property name. + * @return the {@code Long} value of the property. + */ + @CheckForNull + public static Long getLong(String name) { + return getLong(name, null); + } + + /** + * Determines the integer value of the system property with the + * specified name, or a default value. + * + * This behaves just like Long.getLong(String,Long), except that it + * also consults the ServletContext's "init" parameters. If neither exist, + * return the default value. + * + * @param name property name. + * @param def a default value. + * @return the {@code Long} value of the property. + * If the property is missing, return the default value. + * Result may be {@code null} only if the default value is {@code null}. + */ + public static Long getLong(String name, Long def) { + return getLong(name, def, Level.CONFIG); + } + + /** + * Determines the integer value of the system property with the + * specified name, or a default value. + * + * This behaves just like Long.getLong(String,Long), except that it + * also consults the ServletContext's "init" parameters. If neither exist, + * return the default value. + * + * @param name property name. + * @param def a default value. + * @param logLevel the level of the log if the provided system property name cannot be decoded into Long. + * @return the {@code Long} value of the property. + * If the property is missing, return the default value. + * Result may be {@code null} only if the default value is {@code null}. + */ + public static Long getLong(String name, Long def, Level logLevel) { + String v = getString(name); + + if (v != null) { + try { + return Long.decode(v); + } catch (NumberFormatException e) { + // Ignore, fallback to default + if (LOGGER.isLoggable(logLevel)) { + LOGGER.log(logLevel, "Property. Value is not long: {0} => {1}", new Object[] {name, v}); + } + } + } + return def; + } + + @CheckForNull + private static String tryGetValueFromContext(String key) { + if (StringUtils.isNotBlank(key) && theContext != null) { + try { + String value = theContext.getInitParameter(key); + if (value != null) { + return value; + } + } catch (SecurityException ex) { + // Log exception and go on + LOGGER.log(Level.CONFIG, "Access to the property {0} is prohibited", key); + } + } + return null; + } + + @Override + public void contextDestroyed(ServletContextEvent event) { + // nothing to do + } +} diff --git a/core/src/main/java/jenkins/util/VirtualFile.java b/core/src/main/java/jenkins/util/VirtualFile.java index caf9bd0123a19cdda6d7d8303aaa78d18b7e6fec..f6f592cd5ff2afbd8aa1913062ea26a63fcbbf18 100644 --- a/core/src/main/java/jenkins/util/VirtualFile.java +++ b/core/src/main/java/jenkins/util/VirtualFile.java @@ -38,6 +38,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.net.URI; +import java.nio.file.InvalidPathException; +import java.nio.file.LinkOption; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; @@ -161,7 +163,7 @@ public abstract class VirtualFile implements Comparable, Serializab /** * Does case-insensitive comparison. - * @inheritDoc + * {@inheritDoc} */ @Override public final int compareTo(VirtualFile o) { return getName().compareToIgnoreCase(o.getName()); @@ -169,7 +171,7 @@ public abstract class VirtualFile implements Comparable, Serializab /** * Compares according to {@link #toURI}. - * @inheritDoc + * {@inheritDoc} */ @Override public final boolean equals(Object obj) { return obj instanceof VirtualFile && toURI().equals(((VirtualFile) obj).toURI()); @@ -177,7 +179,7 @@ public abstract class VirtualFile implements Comparable, Serializab /** * Hashes according to {@link #toURI}. - * @inheritDoc + * {@inheritDoc} */ @Override public final int hashCode() { return toURI().hashCode(); @@ -185,7 +187,7 @@ public abstract class VirtualFile implements Comparable, Serializab /** * Displays {@link #toURI}. - * @inheritDoc + * {@inheritDoc} */ @Override public final String toString() { return toURI().toString(); @@ -297,13 +299,16 @@ public abstract class VirtualFile implements Comparable, Serializab } private boolean isIllegalSymlink() { // TODO JENKINS-26838 try { - String myPath = f.getCanonicalPath(); - String rootPath = root.getCanonicalPath(); + String myPath = f.toPath().toRealPath(new LinkOption[0]).toString(); + String rootPath = root.toPath().toRealPath(new LinkOption[0]).toString(); if (!myPath.equals(rootPath) && !myPath.startsWith(rootPath + File.separatorChar)) { return true; } } catch (IOException x) { Logger.getLogger(VirtualFile.class.getName()).log(Level.FINE, "could not determine symlink status of " + f, x); + } catch (InvalidPathException x2) { + // if this cannot be converted to a path, it cannot be an illegal symlink, as it cannot exist + Logger.getLogger(VirtualFile.class.getName()).log(Level.FINE, "Could not convert " + f + " to path", x2); } return false; } diff --git a/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java b/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java index 8a946534fd0858e58bd637b8e89d3853287bb774..168f3d00a198a77f5e2e28735e83b42910b556ec 100644 --- a/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java +++ b/core/src/main/java/jenkins/util/groovy/GroovyHookScript.java @@ -3,8 +3,6 @@ package jenkins.util.groovy; import groovy.lang.Binding; import groovy.lang.GroovyCodeSource; import groovy.lang.GroovyShell; -import jenkins.model.Jenkins; - import java.io.File; import java.io.FileFilter; import java.io.IOException; @@ -12,9 +10,11 @@ import java.net.URL; import java.util.Arrays; import java.util.Set; import java.util.TreeSet; -import java.util.logging.Logger; - import static java.util.logging.Level.WARNING; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.servlet.ServletContext; +import jenkins.model.Jenkins; /** * A collection of Groovy scripts that are executed as various hooks. @@ -40,9 +40,24 @@ import static java.util.logging.Level.WARNING; public class GroovyHookScript { private final String hook; private final Binding bindings = new Binding(); + private final ServletContext servletContext; + private final File home; + private final ClassLoader loader; + @Deprecated public GroovyHookScript(String hook) { + this(hook, Jenkins.getActiveInstance()); + } + + private GroovyHookScript(String hook, Jenkins j) { + this(hook, j.servletContext, j.getRootDir(), j.getPluginManager().uberClassLoader); + } + + public GroovyHookScript(String hook, @Nonnull ServletContext servletContext, @Nonnull File home, @Nonnull ClassLoader loader) { this.hook = hook; + this.servletContext = servletContext; + this.home = home; + this.loader = loader; } public GroovyHookScript bind(String name, Object o) { @@ -55,23 +70,22 @@ public class GroovyHookScript { } public void run() { - Jenkins j = Jenkins.getInstance(); final String hookGroovy = hook+".groovy"; final String hookGroovyD = hook+".groovy.d"; try { - URL bundled = j.servletContext.getResource("/WEB-INF/"+ hookGroovy); + URL bundled = servletContext.getResource("/WEB-INF/"+ hookGroovy); execute(bundled); } catch (IOException e) { LOGGER.log(WARNING, "Failed to execute /WEB-INF/"+hookGroovy,e); } - Set resources = j.servletContext.getResourcePaths("/WEB-INF/"+ hookGroovyD +"/"); + Set resources = servletContext.getResourcePaths("/WEB-INF/"+ hookGroovyD +"/"); if (resources!=null) { // sort to execute them in a deterministic order for (String res : new TreeSet(resources)) { try { - URL bundled = j.servletContext.getResource(res); + URL bundled = servletContext.getResource(res); execute(bundled); } catch (IOException e) { LOGGER.log(WARNING, "Failed to execute " + res, e); @@ -79,10 +93,10 @@ public class GroovyHookScript { } } - File script = new File(j.getRootDir(), hookGroovy); + File script = new File(home, hookGroovy); execute(script); - File scriptD = new File(j.getRootDir(), hookGroovyD); + File scriptD = new File(home, hookGroovyD); if (scriptD.isDirectory()) { File[] scripts = scriptD.listFiles(new FileFilter() { public boolean accept(File f) { @@ -129,7 +143,7 @@ public class GroovyHookScript { * Can be used to customize the environment in which the script runs. */ protected GroovyShell createShell() { - return new GroovyShell(Jenkins.getInstance().getPluginManager().uberClassLoader, bindings); + return new GroovyShell(loader, bindings); } private static final Logger LOGGER = Logger.getLogger(GroovyHookScript.class.getName()); diff --git a/core/src/main/java/jenkins/util/io/OnMaster.java b/core/src/main/java/jenkins/util/io/OnMaster.java index ce84873df874626c18d307e2f69bb8fe61f30f57..e8006d6b890bd2d89478f67de875794f5e684255 100644 --- a/core/src/main/java/jenkins/util/io/OnMaster.java +++ b/core/src/main/java/jenkins/util/io/OnMaster.java @@ -2,12 +2,12 @@ package jenkins.util.io; /** * Marks the objects in Jenkins that only exist in the core - * and not on slaves. + * and not on agents. * *

    * This marker interface is for plugin developers to quickly * tell if they can take a specific object from a master to - * a slave. + * an agent. * * (Core developers, if you find classes/interfaces that extend * from this, please be encouraged to add them.) @@ -16,4 +16,36 @@ package jenkins.util.io; * @since 1.475 */ public interface OnMaster { +// TODO uncomment once we can have a delegating ClassFilter, also add SystemProperty to toggle feature +// @Extension +// @Restricted(NoExternalUse.class) +// class ChannelConfiguratorImpl extends ChannelConfigurator { +// @Override +// public void onChannelBuilding(ChannelBuilder builder, @Nullable Object context) { +// if (context instanceof SlaveComputer) { +// builder.withClassFilter(new ClassFilterImpl(builder.getClassFilter(), OnMaster.class.getName, ...)); +// } +// } +// } +// +// @Restricted(NoExternalUse.class) +// class ClassFilterImpl extends ClassFilter { +// private final ClassFilter delegate; +// private final Set blacklist; +// +// public ClassFilterImpl(ClassFilter delegate, String... blacklist) { +// this.blacklist = new HashSet<>(blacklist); +// this.delegate = delegate; +// } +// +// @Override +// protected boolean isBlacklisted(String name) { +// return blacklist.contains(name) || delegate.isBlacklisted(name); +// } +// +// @Override +// protected boolean isBlacklisted(Class c) { +// return c.getAnnotation(MasterJVMOnly.class) != null || delegate.isBlacklisted(c); +// } +// } } diff --git a/core/src/main/java/jenkins/util/xml/XMLUtils.java b/core/src/main/java/jenkins/util/xml/XMLUtils.java index 84e6f6151bf6feba4b8589cb3ee4a8bea4d4120d..f5929a38eb2dc24a9edf851d6530fb6121a94784 100644 --- a/core/src/main/java/jenkins/util/xml/XMLUtils.java +++ b/core/src/main/java/jenkins/util/xml/XMLUtils.java @@ -1,17 +1,29 @@ package jenkins.util.xml; +import jenkins.util.SystemProperties; +import org.apache.commons.io.IOUtils; import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.w3c.dom.Document; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; import javax.annotation.Nonnull; import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; @@ -19,6 +31,9 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; /** * Utilities useful when working with various XML types. @@ -29,6 +44,9 @@ public final class XMLUtils { private final static Logger LOGGER = LogManager.getLogManager().getLogger(XMLUtils.class.getName()); private final static String DISABLED_PROPERTY_NAME = XMLUtils.class.getName() + ".disableXXEPrevention"; + private static final String FEATURE_HTTP_XML_ORG_SAX_FEATURES_EXTERNAL_GENERAL_ENTITIES = "http://xml.org/sax/features/external-general-entities"; + private static final String FEATURE_HTTP_XML_ORG_SAX_FEATURES_EXTERNAL_PARAMETER_ENTITIES = "http://xml.org/sax/features/external-parameter-entities"; + /** * Transform the source to the output in a manner that is protected against XXE attacks. * If the transform can not be completed safely then an IOException is thrown. @@ -47,11 +65,11 @@ public final class XMLUtils { XMLReader xmlReader = XMLReaderFactory.createXMLReader(); try { - xmlReader.setFeature("http://xml.org/sax/features/external-general-entities", false); + xmlReader.setFeature(FEATURE_HTTP_XML_ORG_SAX_FEATURES_EXTERNAL_GENERAL_ENTITIES, false); } catch (SAXException ignored) { /* ignored */ } try { - xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + xmlReader.setFeature(FEATURE_HTTP_XML_ORG_SAX_FEATURES_EXTERNAL_PARAMETER_ENTITIES, false); } catch (SAXException ignored) { /* ignored */ } // defend against XXE @@ -66,7 +84,7 @@ public final class XMLUtils { // for some reason we could not convert source // this applies to DOMSource and StAXSource - and possibly 3rd party implementations... // a DOMSource can already be compromised as it is parsed by the time it gets to us. - if (Boolean.getBoolean(DISABLED_PROPERTY_NAME)) { + if (SystemProperties.getBoolean(DISABLED_PROPERTY_NAME)) { LOGGER.log(Level.WARNING, "XML external entity (XXE) prevention has been disabled by the system " + "property {0}=true Your system may be vulnerable to XXE attacks.", DISABLED_PROPERTY_NAME); if (LOGGER.isLoggable(Level.FINE)) { @@ -81,6 +99,106 @@ public final class XMLUtils { } } + /** + * Parse the supplied XML stream data to a {@link Document}. + *

    + * This function does not close the stream. + * + * @param stream The XML stream. + * @return The XML {@link Document}. + * @throws SAXException Error parsing the XML stream data e.g. badly formed XML. + * @throws IOException Error reading from the steam. + * @since 2.0 + */ + public static @Nonnull Document parse(@Nonnull Reader stream) throws SAXException, IOException { + DocumentBuilder docBuilder; + + try { + docBuilder = newDocumentBuilderFactory().newDocumentBuilder(); + docBuilder.setEntityResolver(RestrictiveEntityResolver.INSTANCE); + } catch (ParserConfigurationException e) { + throw new IllegalStateException("Unexpected error creating DocumentBuilder.", e); + } + + return docBuilder.parse(new InputSource(stream)); + } + + /** + * Parse the supplied XML file data to a {@link Document}. + * @param file The file to parse. + * @param encoding The encoding of the XML in the file. + * @return The parsed document. + * @throws SAXException Error parsing the XML file data e.g. badly formed XML. + * @throws IOException Error reading from the file. + * @since 2.0 + */ + public static @Nonnull Document parse(@Nonnull File file, @Nonnull String encoding) throws SAXException, IOException { + if (!file.exists() || !file.isFile()) { + throw new IllegalArgumentException(String.format("File %s does not exist or is not a 'normal' file.", file.getAbsolutePath())); + } + + FileInputStream fileInputStream = new FileInputStream(file); + try { + InputStreamReader fileReader = new InputStreamReader(fileInputStream, encoding); + try { + return parse(fileReader); + } finally { + IOUtils.closeQuietly(fileReader); + } + } finally { + IOUtils.closeQuietly(fileInputStream); + } + } + + /** + * The a "value" from an XML file using XPath. + *

    + * Uses the system encoding for reading the file. + * + * @param xpath The XPath expression to select the value. + * @param file The file to read. + * @return The data value. An empty {@link String} is returned when the expression does not evaluate + * to anything in the document. + * @throws IOException Error reading from the file. + * @throws SAXException Error parsing the XML file data e.g. badly formed XML. + * @throws XPathExpressionException Invalid XPath expression. + * @since 2.0 + */ + public static @Nonnull String getValue(@Nonnull String xpath, @Nonnull File file) throws IOException, SAXException, XPathExpressionException { + return getValue(xpath, file, Charset.defaultCharset().toString()); + } + + /** + * The a "value" from an XML file using XPath. + * @param xpath The XPath expression to select the value. + * @param file The file to read. + * @param fileDataEncoding The file data format. + * @return The data value. An empty {@link String} is returned when the expression does not evaluate + * to anything in the document. + * @throws IOException Error reading from the file. + * @throws SAXException Error parsing the XML file data e.g. badly formed XML. + * @throws XPathExpressionException Invalid XPath expression. + * @since 2.0 + */ + public static @Nonnull String getValue(@Nonnull String xpath, @Nonnull File file, @Nonnull String fileDataEncoding) throws IOException, SAXException, XPathExpressionException { + Document document = parse(file, fileDataEncoding); + return getValue(xpath, document); + } + + /** + * The a "value" from an XML file using XPath. + * @param xpath The XPath expression to select the value. + * @param document The document from which the value is to be extracted. + * @return The data value. An empty {@link String} is returned when the expression does not evaluate + * to anything in the document. + * @throws XPathExpressionException Invalid XPath expression. + * @since 2.0 + */ + public static String getValue(String xpath, Document document) throws XPathExpressionException { + XPath xPathProcessor = XPathFactory.newInstance().newXPath(); + return xPathProcessor.compile(xpath).evaluate(document); + } + /** * potentially unsafe XML transformation. * @param source The XML input to transform. @@ -96,4 +214,27 @@ public final class XMLUtils { t.transform(source, out); } + private static DocumentBuilderFactory newDocumentBuilderFactory() { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + // Set parser features to prevent against XXE etc. + // Note: setting only the external entity features on DocumentBuilderFactory instance + // (ala how safeTransform does it for SAXTransformerFactory) does seem to work (was still + // processing the entities - tried Oracle JDK 7 and 8 on OSX). Setting seems a bit extreme, + // but looks like there's no other choice. + documentBuilderFactory.setXIncludeAware(false); + documentBuilderFactory.setExpandEntityReferences(false); + setDocumentBuilderFactoryFeature(documentBuilderFactory, XMLConstants.FEATURE_SECURE_PROCESSING, true); + setDocumentBuilderFactoryFeature(documentBuilderFactory, FEATURE_HTTP_XML_ORG_SAX_FEATURES_EXTERNAL_GENERAL_ENTITIES, false); + setDocumentBuilderFactoryFeature(documentBuilderFactory, FEATURE_HTTP_XML_ORG_SAX_FEATURES_EXTERNAL_PARAMETER_ENTITIES, false); + setDocumentBuilderFactoryFeature(documentBuilderFactory, "http://apache.org/xml/features/disallow-doctype-decl", true); + + return documentBuilderFactory; + } + private static void setDocumentBuilderFactoryFeature(DocumentBuilderFactory documentBuilderFactory, String feature, boolean state) { + try { + documentBuilderFactory.setFeature(feature, state); + } catch (Exception e) { + LOGGER.log(Level.WARNING, String.format("Failed to set the XML Document Builder factory feature %s to %s", feature, state), e); + } + } } diff --git a/core/src/main/java/jenkins/util/xstream/CriticalXStreamException.java b/core/src/main/java/jenkins/util/xstream/CriticalXStreamException.java new file mode 100644 index 0000000000000000000000000000000000000000..4c098ff1e409e5bb11bbdf103dfed183e5a33844 --- /dev/null +++ b/core/src/main/java/jenkins/util/xstream/CriticalXStreamException.java @@ -0,0 +1,41 @@ +/* + * The MIT License + * + * Copyright (c) 2015 IKEDA Yasuyuki + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package jenkins.util.xstream; + +import com.thoughtworks.xstream.XStreamException; +import com.thoughtworks.xstream.converters.ConversionException; + +/** + * Wraps {@link XStreamException} to indicate it is critical for Jenkins. + * + * @since 1.625 + */ +public class CriticalXStreamException extends ConversionException { + private static final long serialVersionUID = 1L; + + public CriticalXStreamException(XStreamException cause) { + super(cause); + } +} diff --git a/core/src/main/java/jenkins/util/xstream/XStreamDOM.java b/core/src/main/java/jenkins/util/xstream/XStreamDOM.java index c5aad8c95c15d7fb62f4725954400deee707db40..41603b5179940306aa95fa40f4c970fc6dc698ca 100644 --- a/core/src/main/java/jenkins/util/xstream/XStreamDOM.java +++ b/core/src/main/java/jenkins/util/xstream/XStreamDOM.java @@ -35,17 +35,13 @@ import com.thoughtworks.xstream.io.xml.AbstractXmlReader; import com.thoughtworks.xstream.io.xml.AbstractXmlWriter; import com.thoughtworks.xstream.io.xml.DocumentReader; import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer; -import com.thoughtworks.xstream.io.xml.XppDriver; +import com.thoughtworks.xstream.io.xml.Xpp3Driver; import hudson.Util; import hudson.util.VariableResolver; -import hudson.util.XStream2; -import org.apache.commons.io.IOUtils; import java.io.InputStream; import java.io.OutputStream; import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; @@ -245,11 +241,11 @@ public class XStreamDOM { * Writes this {@link XStreamDOM} into {@link OutputStream}. */ public void writeTo(OutputStream os) { - writeTo(new XppDriver().createWriter(os)); + writeTo(new Xpp3Driver().createWriter(os)); } public void writeTo(Writer w) { - writeTo(new XppDriver().createWriter(w)); + writeTo(new Xpp3Driver().createWriter(w)); } public void writeTo(HierarchicalStreamWriter w) { @@ -266,11 +262,11 @@ public class XStreamDOM { } public static XStreamDOM from(InputStream in) { - return from(new XppDriver().createReader(in)); + return from(new Xpp3Driver().createReader(in)); } public static XStreamDOM from(Reader in) { - return from(new XppDriver().createReader(in)); + return from(new Xpp3Driver().createReader(in)); } public static XStreamDOM from(HierarchicalStreamReader in) { diff --git a/core/src/main/java/jenkins/widgets/BuildListTable.java b/core/src/main/java/jenkins/widgets/BuildListTable.java index ec8e60e368373ad98619d354729f8a6a33770984..7be989feaf37de8e533cf7ccfbca757b2b31fc58 100644 --- a/core/src/main/java/jenkins/widgets/BuildListTable.java +++ b/core/src/main/java/jenkins/widgets/BuildListTable.java @@ -25,9 +25,13 @@ package jenkins.widgets; import hudson.Functions; +import hudson.Util; import hudson.model.BallColor; import hudson.model.Run; import net.sf.json.JSONObject; + +import java.util.Date; + import org.kohsuke.accmod.Restricted; import org.kohsuke.accmod.restrictions.DoNotUse; @@ -45,6 +49,7 @@ public class BuildListTable extends RunListProgressiveRendering { element.put("displayName", build.getDisplayName()); element.put("timestampString", build.getTimestampString()); element.put("timestampString2", build.getTimestampString2()); + element.put("timestampString3", Util.XS_DATETIME_FORMATTER.format(new Date(build.getStartTimeInMillis()))); Run.Summary buildStatusSummary = build.getBuildStatusSummary(); element.put("buildStatusSummaryWorse", buildStatusSummary.isWorse); element.put("buildStatusSummaryMessage", buildStatusSummary.message); diff --git a/core/src/main/java/jenkins/widgets/BuildQueueWidget.java b/core/src/main/java/jenkins/widgets/BuildQueueWidget.java index 5fa694c926b75d729cf9fb7b9e17a2d79e4be6bf..93ba02163e6a45163ba60c831653b15a8c022258 100644 --- a/core/src/main/java/jenkins/widgets/BuildQueueWidget.java +++ b/core/src/main/java/jenkins/widgets/BuildQueueWidget.java @@ -3,6 +3,7 @@ package jenkins.widgets; import hudson.Extension; import hudson.widgets.Widget; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; /** * Show the default build queue. @@ -12,7 +13,7 @@ import jenkins.model.Jenkins; * @author Kohsuke Kawaguchi * @since 1.514 */ -@Extension(ordinal=200) // historically this was the top most widget +@Extension(ordinal=200) @Symbol("buildQueue") // historically this was the top most widget public class BuildQueueWidget extends Widget { } diff --git a/core/src/main/java/jenkins/widgets/ExecutorsWidget.java b/core/src/main/java/jenkins/widgets/ExecutorsWidget.java index 4dba7bd61bde9fa3c9ac5f63b090ed409a45d59a..a4eed237f41ab4c95f0dd06d105475b98becf18f 100644 --- a/core/src/main/java/jenkins/widgets/ExecutorsWidget.java +++ b/core/src/main/java/jenkins/widgets/ExecutorsWidget.java @@ -3,6 +3,7 @@ package jenkins.widgets; import hudson.Extension; import hudson.widgets.Widget; import jenkins.model.Jenkins; +import org.jenkinsci.Symbol; /** * The default executors widget. @@ -12,6 +13,6 @@ import jenkins.model.Jenkins; * @author Kohsuke Kawaguchi * @since 1.514 */ -@Extension(ordinal=100) // historically this was above normal widgets and below BuildQueueWidget +@Extension(ordinal=100) @Symbol("executors") // historically this was above normal widgets and below BuildQueueWidget public class ExecutorsWidget extends Widget { } diff --git a/core/src/main/java/jenkins/widgets/HistoryPageEntry.java b/core/src/main/java/jenkins/widgets/HistoryPageEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..b3aeaecedb8221aea3af1be4be4c2bacbb29344b --- /dev/null +++ b/core/src/main/java/jenkins/widgets/HistoryPageEntry.java @@ -0,0 +1,70 @@ +/* + * The MIT License + * + * Copyright (c) 2013-2014, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.widgets; + +import hudson.model.Queue; +import hudson.model.Run; + +import javax.annotation.Nonnull; + +/** + * Represents an entry used by the {@link HistoryPageFilter}. + * + *

    + * Wraps {@link Queue.Item} and {@link Run} instances from the build queue, normalizing + * access to the info required for pagination. + * + * + * @author tom.fennelly@gmail.com + */ +public class HistoryPageEntry { + + private final T entry; + + public HistoryPageEntry(T entry) { + this.entry = entry; + } + + public T getEntry() { + return entry; + } + + public long getEntryId() { + return getEntryId(entry); + } + + protected static long getEntryId(@Nonnull Object entry) { + if (entry instanceof Queue.Item) { + return ((Queue.Item) entry).getId(); + } else if (entry instanceof Run) { + Run run = (Run) entry; + return (Long.MIN_VALUE + run.getNumber()); + } else if (entry instanceof Number) { + // Used for testing purposes because of JENKINS-30899 and JENKINS-30909 + return (Long.MIN_VALUE + ((Number) entry).longValue()); + } else { + return Run.QUEUE_ID_UNKNOWN; + } + } +} diff --git a/core/src/main/java/jenkins/widgets/HistoryPageFilter.java b/core/src/main/java/jenkins/widgets/HistoryPageFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..04938ec9a666c1142d77089039f88f8a6e52ff58 --- /dev/null +++ b/core/src/main/java/jenkins/widgets/HistoryPageFilter.java @@ -0,0 +1,367 @@ +/* + * The MIT License + * + * Copyright (c) 2013-2014, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.widgets; + +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import hudson.model.Job; +import hudson.model.Queue; +import hudson.model.Run; +import hudson.widgets.HistoryWidget; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +/** + * History page filter. + * + * @author tom.fennelly@gmail.com + */ +public class HistoryPageFilter { + + private final int maxEntries; + private Long newerThan; + private Long olderThan; + private String searchString; + + // Need to use different Lists for Queue.Items and Runs because + // we need access to them separately in the jelly files for rendering. + public final List> queueItems = new ArrayList>(); + public final List> runs = new ArrayList>(); + + public boolean hasUpPage = false; // there are newer builds than on this page + public boolean hasDownPage = false; // there are older builds than on this page + public long nextBuildNumber; + public HistoryWidget widget; + + public long newestOnPage = Long.MIN_VALUE; // see updateNewestOldest() + public long oldestOnPage = Long.MAX_VALUE; // see updateNewestOldest() + + /** + * Create a history page filter instance. + * + * @param maxEntries The max number of entries allowed for the page. + */ + public HistoryPageFilter(int maxEntries) { + this.maxEntries = maxEntries; + } + + /** + * Set the 'newerThan' queue ID. + * @param newerThan Queue IDs newer/greater than this queue ID take precedence on this page. + */ + public void setNewerThan(Long newerThan) { + if (olderThan != null) { + throw new UnsupportedOperationException("Cannot set 'newerThan'. 'olderThan' already set."); + } + this.newerThan = newerThan; + } + + /** + * Set the 'olderThan' queue ID. + * @param olderThan Queue IDs older/less than this queue ID take precedence on this page. + */ + public void setOlderThan(Long olderThan) { + if (newerThan != null) { + throw new UnsupportedOperationException("Cannot set 'olderThan'. 'newerThan' already set."); + } + this.olderThan = olderThan; + } + + /** + * Set the search string used to narrow the filtered set of builds. + * @param searchString The search string. + */ + public void setSearchString(@Nonnull String searchString) { + this.searchString = searchString; + } + + /** + * Add build items to the History page. + * + * @param runItems The items to be added. Assumes the items are in descending queue ID order i.e. newest first. + * @deprecated Replaced by add(Iterable<T>) as of version 2.15 + */ + @Deprecated + public void add(@Nonnull List runItems) { + addInternal(runItems); + } + + /** + * Add build items to the History page. + * + * @param runItems The items to be added. Assumes the items are in descending queue ID order i.e. newest first. + * @since 2.17 + */ + public void add(@Nonnull Iterable runItems) { + addInternal(runItems); + } + + /** + * Add run items and queued items to the History page. + * + * @param runItems The items to be added. Assumes the items are in descending queue ID order i.e. newest first. + * @param queueItems The queue items to be added. Queue items do not need to be sorted. + * @since 2.17 + */ + public void add(@Nonnull Iterable runItems, @Nonnull List queueItems) { + sort(queueItems); + addInternal(Iterables.concat(queueItems, runItems)); + } + + /** + * Add items to the History page, internal implementation. + * @param items The items to be added. + * @param The type of items should either be T or Queue.Item. + */ + private void addInternal(@Nonnull Iterable items) { + // Note that items can be a large lazily evaluated collection, + // so this method is optimized to only iterate through it as much as needed. + + if (!items.iterator().hasNext()) { + return; + } + + nextBuildNumber = getNextBuildNumber(items.iterator().next()); + + if (newerThan == null && olderThan == null) { + // Just return the first page of entries (newest) + Iterator iter = items.iterator(); + while (iter.hasNext()) { + add(iter.next()); + if (isFull()) { + break; + } + } + hasDownPage = iter.hasNext(); + } else if (newerThan != null) { + int toFillCount = getFillCount(); + if (toFillCount > 0) { + // Walk through the items and keep track of the oldest + // 'toFillCount' items until we reach an item older than + // 'newerThan' or the end of the list. + LinkedList itemsToAdd = new LinkedList<>(); + Iterator iter = items.iterator(); + while (iter.hasNext()) { + ItemT item = iter.next(); + if (HistoryPageEntry.getEntryId(item) > newerThan) { + itemsToAdd.addLast(item); + + // Discard an item off the front of the list if we have + // to (which means we would be able to page up). + if (itemsToAdd.size() > toFillCount) { + itemsToAdd.removeFirst(); + hasUpPage = true; + } + } else { + break; + } + } + if (itemsToAdd.size() == 0) { + // All builds are older than newerThan ? + hasDownPage = true; + } else { + // If there's less than a full page of items newer than + // 'newerThan', then it's ok to fill the page with older items. + if (itemsToAdd.size() < toFillCount) { + // We have to restart the iterator and skip the items that we added (because + // we may have popped an extra item off the iterator that did not get added). + Iterator skippedIter = items.iterator(); + Iterators.skip(skippedIter, itemsToAdd.size()); + for (int i = itemsToAdd.size(); i < toFillCount && skippedIter.hasNext(); i++) { + ItemT item = skippedIter.next(); + itemsToAdd.addLast(item); + } + } + hasDownPage = iter.hasNext(); + for (Object item : itemsToAdd) { + add(item); + } + } + } + } else if (olderThan != null) { + Iterator iter = items.iterator(); + while (iter.hasNext()) { + Object item = iter.next(); + if (HistoryPageEntry.getEntryId(item) >= olderThan) { + hasUpPage = true; + } else { + add(item); + if (isFull()) { + hasDownPage = iter.hasNext(); + break; + } + } + } + } + } + + public int size() { + return queueItems.size() + runs.size(); + } + + private void sort(List items) { + // Queue items can start building out of order with how they got added to the queue. Sorting them + // before adding to the page. They'll still get displayed before the building items coz they end + // up in a different list in HistoryPageFilter. + Collections.sort(items, new Comparator() { + @Override + public int compare(Object o1, Object o2) { + long o1QID = HistoryPageEntry.getEntryId(o1); + long o2QID = HistoryPageEntry.getEntryId(o2); + + if (o1QID < o2QID) { + return 1; + } else if (o1QID == o2QID) { + return 0; + } else { + return -1; + } + } + }); + } + + private long getNextBuildNumber(@Nonnull Object entry) { + if (entry instanceof Queue.Item) { + Queue.Task task = ((Queue.Item) entry).task; + if (task instanceof Job) { + return ((Job) task).getNextBuildNumber(); + } + } else if (entry instanceof Run) { + return ((Run) entry).getParent().getNextBuildNumber(); + } + + // TODO maybe this should be an error? + return HistoryPageEntry.getEntryId(entry) + 1; + } + + private void addQueueItem(Queue.Item item) { + HistoryPageEntry entry = new HistoryPageEntry<>(item); + queueItems.add(entry); + updateNewestOldest(entry.getEntryId()); + } + + private void addRun(Run run) { + HistoryPageEntry entry = new HistoryPageEntry<>(run); + // Assert that runs have been added in descending order + if (runs.size() > 0) { + if (entry.getEntryId() > runs.get(runs.size() - 1).getEntryId()) { + throw new IllegalStateException("Runs were out of order"); + } + } + runs.add(entry); + updateNewestOldest(entry.getEntryId()); + } + + private void updateNewestOldest(long entryId) { + newestOnPage = Math.max(newestOnPage, entryId); + oldestOnPage = Math.min(oldestOnPage, entryId); + } + + private boolean add(Object entry) { + // Purposely not calling isFull(). May need to add a greater number of entries + // to the page initially, newerThan then cutting it back down to size using cutLeading() + if (entry instanceof Queue.Item) { + Queue.Item item = (Queue.Item) entry; + if (searchString != null && !fitsSearchParams(item)) { + return false; + } + addQueueItem(item); + return true; + } else if (entry instanceof Run) { + Run run = (Run) entry; + if (searchString != null && !fitsSearchParams(run)) { + return false; + } + addRun(run); + return true; + } + return false; + } + + private boolean isFull() { + return (size() >= maxEntries); + } + + /** + * Get the number of items required to fill the page. + * + * @return The number of items required to fill the page. + */ + private int getFillCount() { + return Math.max(0, (maxEntries - size())); + } + + private boolean fitsSearchParams(@Nonnull Queue.Item item) { + if (fitsSearchString(item.getDisplayName())) { + return true; + } else if (fitsSearchString(item.getId())) { + return true; + } + // Non of the fuzzy matches "liked" the search term. + return false; + } + + private boolean fitsSearchParams(@Nonnull Run run) { + if (searchString == null) { + return true; + } + + if (fitsSearchString(run.getDisplayName())) { + return true; + } else if (fitsSearchString(run.getDescription())) { + return true; + } else if (fitsSearchString(run.getNumber())) { + return true; + } else if (fitsSearchString(run.getQueueId())) { + return true; + } else if (fitsSearchString(run.getResult())) { + return true; + } + + // Non of the fuzzy matches "liked" the search term. + return false; + } + + private boolean fitsSearchString(Object data) { + if (searchString == null) { + return true; + } + + if (data != null) { + if (data instanceof Number) { + return data.toString().equals(searchString); + } else { + return data.toString().toLowerCase().contains(searchString); + } + } + + return false; + } +} diff --git a/core/src/main/resources/hudson/AboutJenkins/index.jelly b/core/src/main/resources/hudson/AboutJenkins/index.jelly index 259b52e9f1df84fc094ef5b610866af501ca207c..68e063af6d83d2bd9905a3adf8bf13a898876458 100644 --- a/core/src/main/resources/hudson/AboutJenkins/index.jelly +++ b/core/src/main/resources/hudson/AboutJenkins/index.jelly @@ -25,44 +25,53 @@ THE SOFTWARE. - - -

    ${%about(app.VERSION)}

    -

    - ${%blurb} -

    -

    - ${%dependencies} -

    - - - + + + +
    +
    +
    +

    ${%about(app.VERSION)}

    +

    ${%blurb}

    +

    ${%dependencies}

    +

    Mavenized dependencies

    + + + - + - - + +

    ${%No information recorded}

    -
    -
    -

    ${%plugin.dependencies}

    - + + +

    ${%static.dependencies}

    + +

    ${%plugin.dependencies}

    + +
    +
    +
    diff --git a/core/src/main/resources/hudson/AboutJenkins/index.properties b/core/src/main/resources/hudson/AboutJenkins/index.properties index 907fcc70eb21546675b1307eb1a734c100a41625..5bb26ae164d2524d950c4432aa8b4765c6911083 100644 --- a/core/src/main/resources/hudson/AboutJenkins/index.properties +++ b/core/src/main/resources/hudson/AboutJenkins/index.properties @@ -21,7 +21,8 @@ # THE SOFTWARE. about=About Jenkins {0} -blurb=Jenkins is a community-developed open-source continuous integration server. +blurb=Jenkins is a community-developed open-source automation server. -dependencies=Jenkins depends on the following 3rd party libraries. -plugin.dependencies=License and dependency information for plugins: +dependencies=Jenkins depends on the following 3rd party libraries +plugin.dependencies=License and dependency information for plugins +static.dependencies=Static resources diff --git a/core/src/main/resources/hudson/AboutJenkins/index_lt.properties b/core/src/main/resources/hudson/AboutJenkins/index_lt.properties index f599a675082b6220d2b9ae7e68a009cf7877095c..e99d3c32feffff31f032939f641196a23a129982 100644 --- a/core/src/main/resources/hudson/AboutJenkins/index_lt.properties +++ b/core/src/main/resources/hudson/AboutJenkins/index_lt.properties @@ -1,5 +1,6 @@ -# This file is under the MIT License by authors - about=Apie Jenkins {0} blurb=Jenkins - bendruomen\u0117s kuriamas atviro kodo pastovios integracijos (CIS) serveris. -dependencies=Jenkins priklauso nuo \u0161i\u0173 3-i\u0173j\u0173 \u0161ali\u0173 bibliotek\u0173. +dependencies=Jenkins priklauso nuo \u0161i\u0173 3-\u0173j\u0173 \u0161ali\u0173 bibliotek\u0173. +plugin.dependencies=Pried\u0173 licencijos ir priklausomybi\u0173 informacija +static.dependencies=Statiniai resursai + diff --git a/core/src/main/resources/hudson/AboutJenkins/index_pl.properties b/core/src/main/resources/hudson/AboutJenkins/index_pl.properties index 0b9e7c410c3528ccf77a48e1c649168527706004..41b9fec9383895e6ebe7c54f938c4f66a035f516 100644 --- a/core/src/main/resources/hudson/AboutJenkins/index_pl.properties +++ b/core/src/main/resources/hudson/AboutJenkins/index_pl.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors -about=O Jenkins''ie {0} +about=O Jenkinsie {0} blurb=Jenkins jest rozwijanym przez spo\u0142eczno\u015B\u0107 open-source serwerem Continuous Integration dependencies=Jenkins jest oparty na nast\u0119puj\u0105cych zewn\u0119trznych bibliotekach: plugin.dependencies=Informacja o licencji i zale\u017Cno\u015Bci plugin\u00F3w: diff --git a/core/src/main/resources/hudson/AboutJenkins/index_sr.properties b/core/src/main/resources/hudson/AboutJenkins/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c490046deb34d721b0738e763c7645cada148def --- /dev/null +++ b/core/src/main/resources/hudson/AboutJenkins/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +about=\u041E Jenkins-\u0443 {0} +blurb=Jenkins \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430 \u043A\u043E\u043D\u0442\u0438\u043D\u0443\u0438\u0440\u0430\u043D\u0443 \u0438\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0458\u0443 \u0441\u0430 \u043E\u0442\u0432\u043E\u0440\u0435\u043D\u0438\u043C \u0438\u0437\u0432\u043E\u0440\u043D\u0438\u043C \u043A\u043E\u0434\u043E\u043C. +dependencies=Jenkins \u0437\u0430\u0432\u0438\u0441\u0438 \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0438\u0445 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 +No\ information\ recorded=\u041D\u0435\u043C\u0430 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 +static.dependencies=\u0421\u0442\u0430\u0442\u0443\u0447\u043A\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0438 +plugin.dependencies=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u043B\u0438\u0446\u0435\u043D\u0446\u0438 \u0438 \u043C\u043E\u0434\u0443\u043B\u0438\u043C\u0430: diff --git a/core/src/main/resources/hudson/Messages.properties b/core/src/main/resources/hudson/Messages.properties index 2613298aff908330ce3b1b751a5832ef8c414d60..902cc4036d1fb91ef3eda4b44869e778297cbd0a 100644 --- a/core/src/main/resources/hudson/Messages.properties +++ b/core/src/main/resources/hudson/Messages.properties @@ -28,6 +28,7 @@ FilePath.validateAntFileMask.doesntMatchAndSuggest=\ FilePath.validateAntFileMask.portionMatchAndSuggest=\u2018{0}\u2019 doesn\u2019t match anything, although \u2018{1}\u2019 exists FilePath.validateAntFileMask.portionMatchButPreviousNotMatchAndSuggest=\u2018{0}\u2019 doesn\u2019t match anything: \u2018{1}\u2019 exists but not \u2018{2}\u2019 FilePath.validateAntFileMask.doesntMatchAnything=\u2018{0}\u2019 doesn\u2019t match anything +FilePath.validateAntFileMask.matchWithCaseInsensitive=\u2018{0}\u2019 doesn\u2019t match anything because it is treated case sensitively. You can deactivate case sensitivity to get matches FilePath.validateAntFileMask.doesntMatchAnythingAndSuggest=\u2018{0}\u2019 doesn\u2019t match anything: even \u2018{1}\u2019 doesn\u2019t exist FilePath.validateRelativePath.wildcardNotAllowed=Wildcard is not allowed here @@ -60,11 +61,28 @@ PluginManager.UploadPluginsPermission.Description=\ PluginManager.ConfigureUpdateCenterPermission.Description=\ The "configure update center" permission allows a user to \ configure update sites and proxy settings. +PluginManager.PluginCycleDependenciesMonitor.DisplayName=Cyclic Dependencies Detector +PluginManager.PluginUpdateMonitor.DisplayName=Invalid Plugin Configuration AboutJenkins.DisplayName=About Jenkins AboutJenkins.Description=See the version and license information. ProxyConfiguration.TestUrlRequired=Test URL is required. +ProxyConfiguration.MalformedTestUrl=Malformed Test URL {0}. ProxyConfiguration.FailedToConnectViaProxy=Failed to connect to {0}. ProxyConfiguration.FailedToConnect=Failed to connect to {0} (code {1}). -ProxyConfiguration.Success=Success \ No newline at end of file +ProxyConfiguration.Success=Success + +Functions.NoExceptionDetails=No Exception details + +PluginWrapper.missing={0} v{1} is missing. To fix, install v{1} or later. +PluginWrapper.failed_to_load_plugin={0} v{1} failed to load. +PluginWrapper.failed_to_load_dependency={0} v{1} failed to load. Fix this plugin first. +PluginWrapper.disabledAndObsolete={0} v{1} is disabled and older than required. To fix, install v{2} or later and enable it. +PluginWrapper.disabled={0} is disabled. To fix, enable it. +PluginWrapper.obsolete={0} v{1} is older than required. To fix, install v{2} or later. +PluginWrapper.obsoleteCore=You must update Jenkins from v{0} to v{1} or later to run this plugin. +PluginWrapper.PluginWrapperAdministrativeMonitor.DisplayName=Plugins Failed To Load + +TcpSlaveAgentListener.PingAgentProtocol.displayName=Ping protocol + diff --git a/core/src/main/resources/hudson/Messages_bg.properties b/core/src/main/resources/hudson/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..8791c38139914e2508d43dfdd623be1ba9a247cb --- /dev/null +++ b/core/src/main/resources/hudson/Messages_bg.properties @@ -0,0 +1,137 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +FilePath.did_not_manage_to_validate_may_be_too_sl=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u0442\u0430 \u043d\u0430 \u201e{0}\u201c \u043d\u0435 \u0435 \u0437\u0430\u0432\u044a\u0440\u0448\u0438\u043b\u0430, \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0435 \u043f\u0440\u0435\u043a\u0430\u043b\u0435\u043d\u043e \u0431\u0430\u0432\u0435\u043d. +FilePath.validateAntFileMask.whitespaceSeprator=\ + \u041f\u0440\u0430\u0437\u043d\u0438\u0442\u0435 \u0437\u043d\u0430\u0446\u0438 \u0432\u0435\u0447\u0435 \u043d\u0435 \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0437\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u0438. \u041f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u043f\u0435\u0442\u0430\u044f \u2014 \u201e,\u201c. +FilePath.validateAntFileMask.doesntMatchAndSuggest=\ + \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u043d\u0438\u0449\u043e, \u043d\u043e \u201e{1}\u201c \u0441\u044a\u0432\u043f\u0430\u0434\u0430. \u0422\u043e\u0432\u0430 \u043b\u0438 \u0438\u043c\u0430\u0445\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434? +FilePath.validateAntFileMask.portionMatchAndSuggest=\ + \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u043d\u0438\u0449\u043e, \u043d\u043e \u201e{1}\u201c \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430. +FilePath.validateAntFileMask.portionMatchButPreviousNotMatchAndSuggest=\ + \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u043d\u0438\u0449\u043e: \u201e{1}\u201c \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430, \u043d\u043e \u043d\u0435 \u0438 \u201e{1}\u201c. +FilePath.validateAntFileMask.doesntMatchAnything=\ + \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u043d\u0438\u0449\u043e. +FilePath.validateAntFileMask.matchWithCaseInsensitive=\ + \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u043d\u0438\u0449\u043e, \u0437\u0430\u0449\u043e\u0442\u043e \u043f\u0440\u0430\u0432\u0438 \u0440\u0430\u0437\u043b\u0438\u043a\u0430 \u043c\u0435\u0436\u0434\u0443 \u0433\u043b\u0430\u0432\u043d\u0438 \u0438 \u043c\u0430\u043b\u043a\u0438 \u0431\u0443\u043a\u0432\u0438.\ + \u041c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u0432\u0430\u043d\u0435\u0442\u043e, \u0437\u0430 \u0434\u0430 \u0438\u043c\u0430 \u0441\u044a\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f. +FilePath.validateAntFileMask.doesntMatchAnythingAndSuggest=\ + \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u043d\u0438\u0449\u043e, \u0434\u043e\u0440\u0438 \u0438 \u201e{1}\u201c \u043d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430. + +FilePath.validateRelativePath.wildcardNotAllowed=\ + \u0417\u043d\u0430\u043a\u044a\u0442 \u201e*\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430 +FilePath.validateRelativePath.notFile=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0444\u0430\u0439\u043b +FilePath.validateRelativePath.notDirectory=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f +FilePath.validateRelativePath.noSuchFile=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u0444\u0430\u0439\u043b \u201e{0}\u201c +FilePath.validateRelativePath.noSuchDirectory=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u201e{0}\u201c + +PluginManager.PluginDoesntSupportDynamicLoad.RestartRequired=\ + \u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u201e{0}\u201c \u043d\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u043d\u043e \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435. \u041f\u0440\u043e\u043c\u044f\u043d\u0430\u0442\u0430 \u043d\u0430\u043b\u0430\u0433\u0430\ + \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins. +PluginManager.PluginIsAlreadyInstalled.RestartRequired=\ + \u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u201e{0}\u201c \u0432\u0435\u0447\u0435 \u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0430. \u041f\u0440\u043e\u043c\u044f\u043d\u0430\u0442\u0430 \u043d\u0430\u043b\u0430\u0433\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins +Util.millisecond=\ + {0} {0,choice,0#\u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0438|1#\u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0430|1<\u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434\u0438} +Util.second=\ + {0} {0,choice,0#\u0441\u0435\u043a\u0443\u043d\u0434\u0438|1#\u0441\u0435\u043a\u0443\u043d\u0434\u0430|1\u0441\u0435\u043a\u0443\u043d\u0434\u0438} +Util.minute=\ + {0} {0,choice,0#\u043c\u0438\u043d\u0443\u0442\u0438|1#\u043c\u0438\u043d\u0443\u0442\u0430|1<\u043c\u0438\u043d\u0443\u0442\u0438} +Util.hour =\ + {0} {0,choice,0#\u0447\u0430\u0441\u0430|1#\u0447\u0430\u0441|1<\u0447\u0430\u0441\u0430} +Util.day =\ + {0} {0,choice,0#\u0434\u043d\u0438|1#\u0434\u0435\u043d|1<\u0434\u043d\u0438} +Util.month =\ + {0} {0,choice,0#\u043c\u0435\u0441\u0435\u0446\u0430|1#\u043c\u0435\u0441\u0435\u0446|1<\u043c\u0435\u0441\u0435\u0446\u0430} +Util.year =\ + {0} {0,choice,0#\u0433\u043e\u0434\u0438\u043d\u0438|1#\u0433\u043e\u0434\u0438\u043d\u0430|1<\u0433\u043e\u0434\u0438\u043d\u0438} + +# ideally it should be "{0} ago" but this saves more space +# another implication of this is that where we use this, +# we often want to add "ago" there +Util.pastTime=\ + {0} +FilePath.TildaDoesntWork=\ + \u201e~\u201c \u0441\u0435 \u043f\u043e\u0434\u0434\u044a\u0440\u0436\u0430 \u0441\u0430\u043c\u043e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u0442\u0435 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0438 \u043d\u0430 Unix \u0438 \u043d\u0438\u043a\u044a\u0434\u0435 \u0434\u0440\u0443\u0433\u0430\u0434\u0435. + +PluginManager.DisplayName=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 +PluginManager.PortNotANumber=\ + \u0421\u0442\u043e\u0439\u043d\u043e\u0441\u0442\u0442\u0430 \u0437\u0430 \u043f\u043e\u0440\u0442\u0430 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0447\u0438\u0441\u043b\u043e +PluginManager.PortNotInRange=\ + \u0421\u0442\u043e\u0439\u043d\u043e\u0441\u0442\u0442\u0430 \u0437\u0430 \u043f\u043e\u0440\u0442\u0430 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0432 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430 [{0}; {1}] +PluginManager.UploadPluginsPermission.Description=\ + \u041f\u0440\u0430\u0432\u043e\u0442\u043e \u0437\u0430 \u043a\u0430\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0434\u0430 \u043a\u0430\u0447\u0438\ + \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430. +PluginManager.ConfigureUpdateCenterPermission.Description=\ + \u041f\u0440\u0430\u0432\u043e\u0442\u043e \u0437\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0432\u0430\u043d\u0435 \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0434\u0430 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435\ + \u043d\u0430 \u0441\u0430\u0439\u0442\u043e\u0432\u0435\u0442\u0435 \u0438 \u0441\u044a\u0440\u0432\u044a\u0440\u0430-\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a. + +AboutJenkins.DisplayName=\ + \u041e\u0442\u043d\u043e\u0441\u043d\u043e Jenkins +AboutJenkins.Description=\ + \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u0438 \u043b\u0438\u0446\u0435\u043d\u0437\u0430. + +ProxyConfiguration.TestUrlRequired=\ + \u0418\u0437\u0438\u0441\u043a\u0432\u0430 \u0441\u0435 \u0430\u0434\u0440\u0435\u0441 \u0437\u0430 \u043f\u0440\u043e\u0431\u0430. +ProxyConfiguration.FailedToConnectViaProxy=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u201e{0}\u201c. +ProxyConfiguration.FailedToConnect=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u043a\u044a\u043c \u201e{0}\u201c (\u043a\u043e\u0434: {1}). +ProxyConfiguration.Success=\ + \u0423\u0441\u043f\u0435\u0445 + +Functions.NoExceptionDetails=\ + \u041d\u044f\u043c\u0430 \u0434\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u0442\u043e. +# Malformed Test URL {0}. +ProxyConfiguration.MalformedTestUrl=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0442\u0435\u0441\u0442\u043e\u0432 \u0430\u0434\u0440\u0435\u0441: \u201e{0}\u201c. +# {0} v{1} is missing. To fix, install v{1} or later. +PluginWrapper.missing=\ + \u201e{0}\u201c, \u0432\u0435\u0440\u0441\u0438\u044f {1} \u043b\u0438\u043f\u0441\u0432\u0430. \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u0439\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044f {1} \u0438\u043b\u0438 \u043f\u043e-\u043d\u043e\u0432\u0430. +# {0} v{1} is disabled and older than required. To fix, install v{2} or later and enable it. +PluginWrapper.disabledAndObsolete=\ + \u201e{0}\u201c, \u0432\u0435\u0440\u0441\u0438\u044f {1} \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0438\u043b\u0438 \u0435 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u0435 \u043f\u043e-\u0441\u0442\u0430\u0440\u0430 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0442\u043e.\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u0439\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044f {2} \u0438\u043b\u0438 \u043f\u043e-\u043d\u043e\u0432\u0430 \u0438 \u044f \u0432\u043a\u043b\u044e\u0447\u0435\u0442\u0435. +# {0} is disabled. To fix, enable it. +PluginWrapper.disabled=\ + \u201e{0}\u201c \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0430. \u0412\u043a\u043b\u044e\u0447\u0435\u0442\u0435 \u044f. +# Ping protocol +TcpSlaveAgentListener.PingAgentProtocol.displayName=\ + \u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u201eping\u201c +# {0} v{1} failed to load. Fix this plugin first. +PluginWrapper.failed_to_load_dependency=\ + \u201e{0}\u201c, \u0432\u0435\u0440\u0441\u0438\u044f {1} \u043d\u0435 \u0441\u0435 \u0437\u0430\u0440\u0435\u0434\u0438. \u041e\u043f\u0440\u0430\u0432\u0435\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430. +# You must update Jenkins from v{0} to v{1} or later to run this plugin. +PluginWrapper.obsoleteCore=\ + \u0417\u0430 \u0434\u0430 \u0440\u0430\u0431\u043e\u0442\u0438\u0442\u0435 \u0441 \u0442\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u043e\u0431\u043d\u043e\u0432\u0435\u0442\u0435 Jenkins \u043e\u0442 \u0432\u0435\u0440\u0441\u0438\u044f {0} \u043a\u044a\u043c {1} +# {0} v{1} is older than required. To fix, install v{2} or later. +PluginWrapper.obsolete=\ + \u201e{0}\u201c, \u0432\u0435\u0440\u0441\u0438\u044f {1} \u0435 \u043f\u043e-\u0441\u0442\u0430\u0440\u0430 \u043e\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0442\u043e. \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u0439\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044f {2} \u0438\u043b\u0438\ + \u043f\u043e-\u043d\u043e\u0432\u0430. +# {0} v{1} failed to load. +PluginWrapper.failed_to_load_plugin=\ + \u201e{0}\u201c, \u0432\u0435\u0440\u0441\u0438\u044f {1} \u043d\u0435 \u0441\u0435 \u0437\u0430\u0440\u0435\u0434\u0438. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pt_BR.properties b/core/src/main/resources/hudson/Messages_pl.properties similarity index 64% rename from core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pt_BR.properties rename to core/src/main/resources/hudson/Messages_pl.properties index c02b59dfae65567c2075aa4b800516dae3e53f24..268459378aee701589c2ab385e99a27a54c17b08 100644 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pt_BR.properties +++ b/core/src/main/resources/hudson/Messages_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva, Fernando Boaglio +# Copyright (c) 2016, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,15 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -body=Esta \u00e9 a central de funcionalidades do Jenkins. Ele construir\u00e1 seu projeto,e voc\u00ea pode combinar qualquer SCM com qualquer sistema de builds, e ele at\u00e9 mesmo pode ser usado para outras jobs diferentes de builds de software. +Util.millisecond={0} ms +Util.second={0} sek +Util.minute={0} min +Util.hour ={0} godz +Util.day ={0} {0,choice,0#dni|1#dzie\u0144|1 -
  5. +
  6. diff --git a/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message_bg.properties b/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..1deca421ad0adaeb42b5c55b2a2ac71265259376 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +PluginCycles=\ + \u0421\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0438 \u043f\u043e\u0440\u0430\u0434\u0438 \u0446\u0438\u043a\u043b\u0438\u0447\u043d\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u041d\u0430\u0439-\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0442\u043e\u0437\u0438\ + \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0449\u0435 \u0441\u0435 \u0440\u0435\u0448\u0438, \u043a\u043e\u0433\u0430\u0442\u043e \u0433\u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435. diff --git a/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message_sr.properties b/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a581c6ee19b3b6ef2cb49fab6f0e1ed43f25ecd0 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/PluginCycleDependenciesMonitor/message_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +PluginCycles=\u0421\u043B\u0435\u0434\u0435\u045B\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u0441\u0443 \u0438\u0441\u043A\u0459\u0443\u0447\u0435\u043D\u0438 \u0437\u0431\u043E\u0433 \u043A\u0440\u0443\u0436\u043D\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0442\u043D\u043E\u0441\u0442\u0438 \u0448\u0442\u043E \u0432\u0435\u0440\u043E\u0432\u0430\u043D\u0442\u043E \u043C\u043E\u0436\u0435\u0442\u0435 \u0440\u0435\u0448\u0438\u0442\u0438 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435\u043C \u043D\u0430 \u043D\u043E\u0432\u0438\u0458\u0443 \u0432\u0435\u0440\u0437\u0438\u0458\u0443. diff --git a/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message_bg.properties b/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..bc122f8ed3df8beecb84b3d5988b17dba52d30b3 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +RequiredPluginUpdates=\ + \u0421\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0438\u0437\u0438\u0441\u043a\u0432\u0430\u0442 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435. diff --git a/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message_sr.properties b/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..97296e7de6f3fe63a900bd6e71f92128bb1fa8b1 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/PluginUpdateMonitor/message_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +RequiredPluginUpdates=\u0421\u043B\u0435\u0434\u0435\u045B\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u0437\u0430\u0445\u0442\u0435\u0432\u0430\u0458\u0443 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435. diff --git a/core/src/main/resources/hudson/PluginManager/_api.jelly b/core/src/main/resources/hudson/PluginManager/_api.jelly index cd15d1398d45c8ea3fed2288644e1cc871a12566..8ef92ccf32d05e83b271f61eef04705ec6a631aa 100644 --- a/core/src/main/resources/hudson/PluginManager/_api.jelly +++ b/core/src/main/resources/hudson/PluginManager/_api.jelly @@ -31,7 +31,7 @@ THE SOFTWARE.

    Making sure all the needed plugins are installed

    - Jenkins uses an XML format for representing most of complex objects internally (such as slaves, views, jobs, and builds.) + Jenkins uses an XML format for representing most of complex objects internally (such as agents, views, jobs, and builds.) As such, it has various APIs that send/receive those XMLs. For example, you can create a new job by POSTing its XML representation. Starting 1.482, Jenkins annotates these XMLs with additional information indicating what plugins have been used in them. This improves the portability of those XML files. diff --git a/core/src/main/resources/hudson/PluginManager/_table.js b/core/src/main/resources/hudson/PluginManager/_table.js index b84bae0806cee2097d27cb03ae5fe719b336f315..417694036293526252eafc48b68286e33f207404 100644 --- a/core/src/main/resources/hudson/PluginManager/_table.js +++ b/core/src/main/resources/hudson/PluginManager/_table.js @@ -44,3 +44,357 @@ Behaviour.specify("#filter-box", '_table', 0, function(e) { e.onkeyup = applyFilter; }); + +/** + * Code for handling the enable/disable behavior based on plugin + * dependencies and dependants. + */ +(function(){ + function selectAll(selector, element) { + if (element) { + return $(element).select(selector); + } else { + return Element.select(undefined, selector); + } + } + function select(selector, element) { + var elementsBySelector = selectAll(selector, element); + if (elementsBySelector.length > 0) { + return elementsBySelector[0]; + } else { + return undefined; + } + } + + /** + * Wait for document onload. + */ + Element.observe(window, "load", function() { + var pluginsTable = select('#plugins'); + var pluginTRs = selectAll('.plugin', pluginsTable); + + if (!pluginTRs) { + return; + } + + var pluginI18n = select('.plugins.i18n'); + function i18n(messageId) { + return pluginI18n.getAttribute('data-' + messageId); + } + + // Create a map of the plugin rows, making it easy to index them. + var plugins = {}; + for (var i = 0; i < pluginTRs.length; i++) { + var pluginTR = pluginTRs[i]; + var pluginId = pluginTR.getAttribute('data-plugin-id'); + + plugins[pluginId] = pluginTR; + } + + function getPluginTR(pluginId) { + return plugins[pluginId]; + } + function getPluginName(pluginId) { + var pluginTR = getPluginTR(pluginId); + if (pluginTR) { + return pluginTR.getAttribute('data-plugin-name'); + } else { + return pluginId; + } + } + + function processSpanSet(spans) { + var ids = []; + for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + var pluginId = span.getAttribute('data-plugin-id'); + var pluginName = getPluginName(pluginId); + + span.update(pluginName); + ids.push(pluginId); + } + return ids; + } + + function markAllDependantsDisabled(pluginTR) { + var jenkinsPluginMetadata = pluginTR.jenkinsPluginMetadata; + var dependantIds = jenkinsPluginMetadata.dependantIds; + + if (dependantIds) { + // If the only dependant is jenkins-core (it's a bundle plugin), then lets + // treat it like all its dependants are disabled. We're really only interested in + // dependant plugins in this case. + // Note: This does not cover "implied" dependencies ala detached plugins. See https://goo.gl/lQHrUh + if (dependantIds.length === 1 && dependantIds[0] === 'jenkins-core') { + pluginTR.addClassName('all-dependants-disabled'); + return; + } + + for (var i = 0; i < dependantIds.length; i++) { + var dependantId = dependantIds[i]; + + if (dependantId === 'jenkins-core') { + // Jenkins core is always enabled. So, make sure it's not possible to disable/uninstall + // any plugins that it "depends" on. (we sill have bundled plugins) + pluginTR.removeClassName('all-dependants-disabled'); + return; + } + + // The dependant is a plugin.... + var dependantPluginTr = getPluginTR(dependantId); + if (dependantPluginTr && dependantPluginTr.jenkinsPluginMetadata.enableInput.checked) { + // One of the plugins that depend on this plugin, is marked as enabled. + pluginTR.removeClassName('all-dependants-disabled'); + return; + } + } + } + + pluginTR.addClassName('all-dependants-disabled'); + } + + function markHasDisabledDependencies(pluginTR) { + var jenkinsPluginMetadata = pluginTR.jenkinsPluginMetadata; + var dependencyIds = jenkinsPluginMetadata.dependencyIds; + + if (dependencyIds) { + for (var i = 0; i < dependencyIds.length; i++) { + var dependencyPluginTr = getPluginTR(dependencyIds[i]); + if (dependencyPluginTr && !dependencyPluginTr.jenkinsPluginMetadata.enableInput.checked) { + // One of the plugins that this plugin depend on, is marked as disabled. + pluginTR.addClassName('has-disabled-dependency'); + return; + } + } + } + + pluginTR.removeClassName('has-disabled-dependency'); + } + + function setEnableWidgetStates() { + for (var i = 0; i < pluginTRs.length; i++) { + var pluginMetadata = pluginTRs[i].jenkinsPluginMetadata; + if (pluginTRs[i].hasClassName('has-dependants-but-disabled')) { + if (pluginMetadata.enableInput.checked) { + pluginTRs[i].removeClassName('has-dependants-but-disabled'); + } + } + markAllDependantsDisabled(pluginTRs[i]); + markHasDisabledDependencies(pluginTRs[i]); + } + } + + function addDependencyInfoRow(pluginTR, infoTR) { + infoTR.addClassName('plugin-dependency-info'); + pluginTR.insert({ + after: infoTR + }); + } + function removeDependencyInfoRow(pluginTR) { + var nextRows = pluginTR.nextSiblings(); + if (nextRows && nextRows.length > 0) { + var nextRow = nextRows[0]; + if (nextRow.hasClassName('plugin-dependency-info')) { + nextRow.remove(); + } + } + } + + function populateEnableDisableInfo(pluginTR, infoContainer) { + var pluginMetadata = pluginTR.jenkinsPluginMetadata; + + // Remove all existing class info + infoContainer.removeAttribute('class'); + infoContainer.addClassName('enable-state-info'); + + if (pluginTR.hasClassName('has-disabled-dependency')) { + var dependenciesDiv = pluginMetadata.dependenciesDiv; + var dependencySpans = pluginMetadata.dependencies; + + infoContainer.update('

    ' + i18n('cannot-enable') + '
    ' + i18n('disabled-dependencies') + '.
    '); + + // Go through each dependency element. Show the spans where the dependency is + // disabled. Hide the others. + for (var i = 0; i < dependencySpans.length; i++) { + var dependencySpan = dependencySpans[i]; + var pluginId = dependencySpan.getAttribute('data-plugin-id'); + var depPluginTR = getPluginTR(pluginId); + var depPluginMetadata = depPluginTR.jenkinsPluginMetadata; + if (depPluginMetadata.enableInput.checked) { + // It's enabled ... hide the span + dependencySpan.setStyle({display: 'none'}); + } else { + // It's disabled ... show the span + dependencySpan.setStyle({display: 'inline-block'}); + } + } + + dependenciesDiv.setStyle({display: 'inherit'}); + infoContainer.appendChild(dependenciesDiv); + + return true; + } if (pluginTR.hasClassName('has-dependants')) { + if (!pluginTR.hasClassName('all-dependants-disabled')) { + var dependantIds = pluginMetadata.dependantIds; + + // If the only dependant is jenkins-core (it's a bundle plugin), then lets + // treat it like all its dependants are disabled. We're really only interested in + // dependant plugins in this case. + // Note: This does not cover "implied" dependencies ala detached plugins. See https://goo.gl/lQHrUh + if (dependantIds.length === 1 && dependantIds[0] === 'jenkins-core') { + pluginTR.addClassName('all-dependants-disabled'); + return false; + } + + var dependantsDiv = pluginMetadata.dependantsDiv; + var dependantSpans = pluginMetadata.dependants; + + infoContainer.update('
    ' + i18n('cannot-disable') + '
    ' + i18n('enabled-dependants') + '.
    '); + + // Go through each dependant element. Show the spans where the dependant is + // enabled. Hide the others. + for (var i = 0; i < dependantSpans.length; i++) { + var dependantSpan = dependantSpans[i]; + var dependantId = dependantSpan.getAttribute('data-plugin-id'); + + if (dependantId === 'jenkins-core') { + // show the span + dependantSpan.setStyle({display: 'inline-block'}); + } else { + var depPluginTR = getPluginTR(dependantId); + var depPluginMetadata = depPluginTR.jenkinsPluginMetadata; + if (depPluginMetadata.enableInput.checked) { + // It's enabled ... show the span + dependantSpan.setStyle({display: 'inline-block'}); + } else { + // It's disabled ... hide the span + dependantSpan.setStyle({display: 'none'}); + } + } + } + + dependantsDiv.setStyle({display: 'inherit'}); + infoContainer.appendChild(dependantsDiv); + + return true; + } + } + + return false; + } + + function populateUninstallInfo(pluginTR, infoContainer) { + // Remove all existing class info + infoContainer.removeAttribute('class'); + infoContainer.addClassName('uninstall-state-info'); + + if (pluginTR.hasClassName('has-dependants')) { + var pluginMetadata = pluginTR.jenkinsPluginMetadata; + var dependantsDiv = pluginMetadata.dependantsDiv; + var dependantSpans = pluginMetadata.dependants; + + infoContainer.update('
    ' + i18n('cannot-uninstall') + '
    ' + i18n('installed-dependants') + '.
    '); + + // Go through each dependant element. Show them all. + for (var i = 0; i < dependantSpans.length; i++) { + var dependantSpan = dependantSpans[i]; + dependantSpan.setStyle({display: 'inline-block'}); + } + + dependantsDiv.setStyle({display: 'inherit'}); + infoContainer.appendChild(dependantsDiv); + + return true; + } + + return false; + } + + function initPluginRowHandling(pluginTR) { + var enableInput = select('.enable input', pluginTR); + var dependenciesDiv = select('.dependency-list', pluginTR); + var dependantsDiv = select('.dependant-list', pluginTR); + var enableTD = select('td.enable', pluginTR); + var uninstallTD = select('td.uninstall', pluginTR); + + pluginTR.jenkinsPluginMetadata = { + enableInput: enableInput, + dependenciesDiv: dependenciesDiv, + dependantsDiv: dependantsDiv + }; + + if (dependenciesDiv) { + pluginTR.jenkinsPluginMetadata.dependencies = selectAll('span', dependenciesDiv); + pluginTR.jenkinsPluginMetadata.dependencyIds = processSpanSet(pluginTR.jenkinsPluginMetadata.dependencies); + } + if (dependantsDiv) { + pluginTR.jenkinsPluginMetadata.dependants = selectAll('span', dependantsDiv); + pluginTR.jenkinsPluginMetadata.dependantIds = processSpanSet(pluginTR.jenkinsPluginMetadata.dependants); + } + + // Setup event handlers... + + // Toggling of the enable/disable checkbox requires a check and possible + // change of visibility on the same checkbox on other plugins. + Element.observe(enableInput, 'click', function() { + setEnableWidgetStates(); + }); + + // + var infoTR = document.createElement("tr"); + var infoTD = document.createElement("td"); + var infoDiv = document.createElement("div"); + infoTR.appendChild(infoTD) + infoTD.appendChild(infoDiv) + infoTD.setAttribute('colspan', '6'); // This is the cell that all info will be added to. + infoDiv.setStyle({display: 'inherit'}); + + // We don't want the info row to appear immediately. We wait for e.g. 1 second and if the mouse + // is still in there (hasn't left the cell) then we show. The following code is for clearing the + // show timeout where the mouse has left before the timeout has fired. + var showInfoTimeout = undefined; + function clearShowInfoTimeout() { + if (showInfoTimeout) { + clearTimeout(showInfoTimeout); + } + showInfoTimeout = undefined; + } + + // Handle mouse in/out of the enable/disable cell (left most cell). + Element.observe(enableTD, 'mouseenter', function() { + showInfoTimeout = setTimeout(function() { + showInfoTimeout = undefined; + infoDiv.update(''); + if (populateEnableDisableInfo(pluginTR, infoDiv)) { + addDependencyInfoRow(pluginTR, infoTR); + } + }, 1000); + }); + Element.observe(enableTD, 'mouseleave', function() { + clearShowInfoTimeout(); + removeDependencyInfoRow(pluginTR); + }); + + // Handle mouse in/out of the uninstall cell (right most cell). + Element.observe(uninstallTD, 'mouseenter', function() { + showInfoTimeout = setTimeout(function() { + showInfoTimeout = undefined; + infoDiv.update(''); + if (populateUninstallInfo(pluginTR, infoDiv)) { + addDependencyInfoRow(pluginTR, infoTR); + } + }, 1000); + }); + Element.observe(uninstallTD, 'mouseleave', function() { + clearShowInfoTimeout(); + removeDependencyInfoRow(pluginTR); + }); + } + + for (var i = 0; i < pluginTRs.length; i++) { + initPluginRowHandling(pluginTRs[i]); + } + + setEnableWidgetStates(); + }); +}()); \ No newline at end of file diff --git a/core/src/main/resources/hudson/PluginManager/advanced_bg.properties b/core/src/main/resources/hudson/PluginManager/advanced_bg.properties index 21ede7a1563a13c07410ddc483d31b4b6ab50677..60ac6803dba9e50d0cc251ad6a7161c6e1173b2d 100644 --- a/core/src/main/resources/hudson/PluginManager/advanced_bg.properties +++ b/core/src/main/resources/hudson/PluginManager/advanced_bg.properties @@ -1,10 +1,42 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -File=\u0424\u0430\u0439\u043B -HTTP\ Proxy\ Configuration=\u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F \u043D\u0430 HTTP \u043F\u0440\u043E\u043A\u0441\u0438 -Submit=\u041F\u043E\u0442\u0432\u044A\u0440\u0434\u0438 -Update\ Site=\u041E\u0431\u043D\u043E\u0432\u0438 \u0441\u0430\u0439\u0442\u0430 -Upload=\u041A\u0430\u0447\u0438 -Upload\ Plugin=\u041A\u0430\u0447\u0438 \u043F\u043B\u044A\u0433\u0438\u043D -lastUpdated=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\u0442\u0430 \u0437\u0430 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u0431\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0441\u0432\u0430\u043B\u0435\u043D\u0430 \u043F\u0440\u0435\u0434\u0438 {0} -uploadtext=\u0411\u0438\u0445\u0442\u0435 \u043C\u043E\u0433\u043B\u0438 \u0434\u0430 \u043A\u0430\u0447\u0438\u0442\u0435 .hpi \u0444\u0430\u0439\u043B \u0438 \u043F\u043E \u0442\u043E\u0437\u0438 \u043D\u0430\u0447\u0438\u043D \u0434\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0442\u0435 \u043F\u043B\u044A\u0433\u0438\u043D \u0438\u0437\u0432\u044A\u043D \u043E\u0441\u043D\u043E\u0432\u043D\u0430\u0442\u0430 \u043F\u043B\u044A\u0433\u0438\u043D \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u044F. +File=\u0424\u0430\u0439\u043b +HTTP\ Proxy\ Configuration=\ + \u0421\u044a\u0440\u0432\u044a\u0440-\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u0437\u0430 HTTP +Submit=\ + \u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0430\u0432\u0430\u043d\u0435 +Update\ Site=\ + \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0430\u0439\u0442\u0430 +Upload=\ + \u041a\u0430\u0447\u0432\u0430\u043d\u0435 +Upload\ Plugin=\ + \u041a\u0430\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 +uploadtext=\ + \u041c\u043e\u0436\u0435 \u0434\u0430 \u043a\u0430\u0447\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 \u201e.hpi\u201c, \u0437\u0430 \u0434\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0438\u0437\u0432\u044a\u043d\ + \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u043d\u043e\u0442\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. +Other\ Sites=\ + \u0414\u0440\u0443\u0433\u0438 \u0441\u0430\u0439\u0442\u043e\u0432\u0435 +Update\ Center=\ + \u0421\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +URL=\ + \u0410\u0434\u0440\u0435\u0441 diff --git a/core/src/main/resources/hudson/PluginManager/advanced_sr.properties b/core/src/main/resources/hudson/PluginManager/advanced_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..99f4d1a1e12f373202f7ccda4f029501ddd896d6 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/advanced_sr.properties @@ -0,0 +1,20 @@ +# This file is under the MIT License by authors + +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +HTTP\ Proxy\ Configuration=\u041F\u043E\u0441\u0442\u0430\u0432\u0459\u0430\u045A\u0435 HTTP Proxy +Submit=\u041F\u043E\u0442\u0432\u0440\u0434\u0438 +Upload\ Plugin=\u041E\u0442\u043F\u0440\u0435\u043C\u0438 \u043C\u043E\u0434\u0443\u043B\u0443 +uploadtext=\u041C\u043E\u0436\u0435\u0442\u0435 \u043E\u0442\u043F\u0440\u0435\u043C\u0438\u0442\u0438 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 \u0443 \u0444\u043E\u0440\u043C\u0430\u0442\u0443 ".hpi", \u0434\u0430 \u0431\u0438\u0441\u0442\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043B\u0438 \u043C\u043E\u0434\u0443\u043B\u0443 \u0432\u0430\u043D\ +\u0446\u0435\u043D\u0442\u0440\u0430\u043B\u043D\u043E\u0433 \u0438\u0437\u0432\u043E\u0440\u0430 \u0437\u0430 \u043C\u043E\u0434\u0443\u043B\u0435. +File=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 +Upload=\u041E\u0442\u043F\u0440\u0435\u043C\u0438 +Update\ Site=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 \u0441\u0442\u0440\u0430\u043D\u0443 +URL=URL \u0430\u0434\u0440\u0435\u0441\u0430 +Other\ Sites=\u0414\u0440\u0443\u0433\u0435 \u0441\u0442\u0440\u0430\u043D\u0435 +lastUpdated=\u0417\u0430\u0434\u045A\u0435 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u043E: \u043F\u0440\u0435 {0} +Password=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 +Port=\u041F\u043E\u0440\u0442 +User\ name=\u041A\u043E\u0440\u0438\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 +Server=\u0421\u0435\u0440\u0432\u0435\u0440 +Proxy\ Needs\ Authorization=Proxy-\u0443 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0434\u043E\u0432\u043B\u0430\u0448\u045B\u0435\u045A\u0435 +No\ Proxy\ Host=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 Proxy Host diff --git a/core/src/main/resources/hudson/PluginManager/available_sr.properties b/core/src/main/resources/hudson/PluginManager/available_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..84c0685cfb83b4ff9ef87489f0833169bd4cd57d --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/available_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Updates=\u041D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0435 +Available=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0435 +Installed=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/PluginManager/checkUpdates_bg.properties b/core/src/main/resources/hudson/PluginManager/checkUpdates_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..2e06417a0b23e9298e1cfc813f36574b109260ba --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/checkUpdates_bg.properties @@ -0,0 +1,30 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Go\ back\ to\ update\ center=\ + \u041a\u044a\u043c \u0441\u0430\u0439\u0442\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Update\ Center=\ + \u0421\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Done=\ + \u0413\u043e\u0442\u043e\u0432\u043e +Checking\ Updates...=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u2026 diff --git a/core/src/main/resources/hudson/PluginManager/checkUpdates_sr.properties b/core/src/main/resources/hudson/PluginManager/checkUpdates_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c970a3513f1334ab5911c1c8dc6bb77d877b78cc --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/checkUpdates_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +Checking\ Updates...=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0430 +Done=\u0413\u043E\u0442\u043E\u0432\u043E +Go\ back\ to\ update\ center=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u0446\u0435\u043D\u0442\u0440\u0443 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 diff --git a/core/src/main/resources/hudson/PluginManager/check_bg.properties b/core/src/main/resources/hudson/PluginManager/check_bg.properties index 563165ac538f2f47384c18bca07fff661a4f86fb..f308d4fbed52506723d5f745f057644defe87c7a 100644 --- a/core/src/main/resources/hudson/PluginManager/check_bg.properties +++ b/core/src/main/resources/hudson/PluginManager/check_bg.properties @@ -1,3 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Check\ now=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 \u0441\u0435\u0433\u0430 +Check\ now=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u0435\u0433\u0430 +lastUpdated=\ + \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u0442\u0430 \u0435 \u043e\u0442 \u043f\u0440\u0435\u0434\u0438 {0} diff --git a/core/src/main/resources/hudson/PluginManager/check_pl.properties b/core/src/main/resources/hudson/PluginManager/check_pl.properties index 2003bf8df1cf47819c72fed4508d15fec566094d..579836ad90c039adcb03bdddd90640ac2a38e7e6 100644 --- a/core/src/main/resources/hudson/PluginManager/check_pl.properties +++ b/core/src/main/resources/hudson/PluginManager/check_pl.properties @@ -21,3 +21,4 @@ # THE SOFTWARE. Check\ now=Sprawd\u017A teraz +lastUpdated=Ostatnie sprawdzenie: {0} temu \ No newline at end of file diff --git a/core/src/main/resources/hudson/PluginManager/check_sr.properties b/core/src/main/resources/hudson/PluginManager/check_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..00cfe6bee196592907e255f3886709a1d21d76d3 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/check_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +lastUpdated=\ \u0417\u0430\u0434\u045A\u0435 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u043E: \u043F\u0440\u0435 {0} +Check\ now=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 \u0441\u0430\u0434\u0430 diff --git a/core/src/main/resources/hudson/PluginManager/index_bg.properties b/core/src/main/resources/hudson/PluginManager/index_bg.properties index 95c41881624f9e1b74e144b90f5168c8926756e2..91bf6b5e8bd38f34d972ccae942ad3de14d08273 100644 --- a/core/src/main/resources/hudson/PluginManager/index_bg.properties +++ b/core/src/main/resources/hudson/PluginManager/index_bg.properties @@ -1,6 +1,34 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -All=\u0412\u0441\u0438\u0447\u043A\u0438 -None=\u041D\u0438\u043A\u043E\u0438 -Select=\u0418\u0437\u0431\u0435\u0440\u0438 -UpdatePageDescription=\u0422\u0430\u0437\u0438 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u0432\u0438 \u043F\u043E\u043A\u0430\u0437\u0432\u0430 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u043D\u0430 \u0438\u0437\u043F\u043E\u043B\u0437\u0432\u0430\u043D\u0438\u0442\u0435 \u043F\u043B\u044A\u0433\u0438\u043D\u0438. +All=\ + \u0412\u0441\u0438\u0447\u043a\u0438 +None=\ + \u041d\u0438\u043a\u043e\u0438 +Select=\ + \u0418\u0437\u0431\u043e\u0440 +UpdatePageDescription=\ + \u041d\u0430\u043b\u0438\u0447\u043d\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438. +UpdatePageLegend=\ + \u0420\u0435\u0434\u043e\u0432\u0435\u0442\u0435, \u043a\u043e\u0438\u0442\u043e \u043d\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0431\u0435\u0440\u0430\u0442, \u0441\u0430 \u0437\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438\u0442\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u0438\u0442\u043e\ + \u0438\u0437\u0438\u0441\u043a\u0432\u0430\u0442 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins. \u041e\u0446\u0432\u0435\u0442\u0435\u043d\u0438\u0442\u0435 \u0440\u0435\u0434\u043e\u0432\u0435, \u043a\u043e\u0438\u0442\u043e \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435\ + \u0438\u0437\u0431\u0435\u0440\u0430\u0442, \u0441\u0430 \u0437\u0430 \u043f\u0440\u043e\u0442\u0438\u0447\u0430\u0449\u0438 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. diff --git a/core/src/main/resources/hudson/PluginManager/index_sr.properties b/core/src/main/resources/hudson/PluginManager/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c4d6e484813c5cd66e834f75df41e8d5d1c6881c --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Select=\u0418\u0437\u0430\u0431\u0435\u0440\u0438 +All=\u0421\u0432\u0435 +None=\u041D\u0438\u0458\u0435\u0434\u043D\u0443 +UpdatePageDescription=\u041C\u043E\u0434\u0443\u043B\u0435 \u0441\u043F\u0440\u0435\u043C\u0435 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435. +UpdatePageLegend=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0438 \u0440\u0435\u0434\u043E\u0432\u0438 \u0441\u0443 \u0432\u0435\u045B \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u0438 \u0438 \u0447\u0435\u043A\u0430\u0458\u0443 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435.\ + \u041E\u0431\u043E\u0458\u0435\u043D\u0438 (\u0430\u043B\u0438 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0430\u0447\u043D\u0438) \u0440\u0435\u0434\u043E\u0432\u0438 \u0441\u0443 \u0443 \u0442\u043E\u043A\u0443 \u0438\u043B\u0438 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0438. diff --git a/core/src/main/resources/hudson/PluginManager/installed.jelly b/core/src/main/resources/hudson/PluginManager/installed.jelly index 2d439b335e0597c54eee66207d29e3abd244435c..22ff5f7419877e6c10edb7be60b5121c39a789f5 100644 --- a/core/src/main/resources/hudson/PluginManager/installed.jelly +++ b/core/src/main/resources/hudson/PluginManager/installed.jelly @@ -35,10 +35,23 @@ THE SOFTWARE. ${%Filter}: + + +
    ${%Warning}: ${%requires.restart}
    +
    +
    - +
    +
    - + - - - diff --git a/core/src/main/resources/hudson/PluginManager/installed.properties b/core/src/main/resources/hudson/PluginManager/installed.properties index ad37e72885f246853d7a0041a17e0586c91cddb1..2fa0cafb8083f2b150ecd074aeb95ea0321dc2b7 100644 --- a/core/src/main/resources/hudson/PluginManager/installed.properties +++ b/core/src/main/resources/hudson/PluginManager/installed.properties @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. wiki.url=http://wiki.jenkins-ci.org/display/JENKINS/Pinned+Plugins -downgradeTo=Downgrade to {0} \ No newline at end of file +downgradeTo=Downgrade to {0} +requires.restart=This Jenkins instance requires a restart. Changing the state of plugins at this time is strongly discouraged. Restart Jenkins before proceeding. \ No newline at end of file diff --git a/core/src/main/resources/hudson/PluginManager/installed_bg.properties b/core/src/main/resources/hudson/PluginManager/installed_bg.properties index 8d62547e3d7d906b808c8d67b21d25fc4298baec..c950862a63b41df6b8dedcfffb431ff6a6e94386 100644 --- a/core/src/main/resources/hudson/PluginManager/installed_bg.properties +++ b/core/src/main/resources/hudson/PluginManager/installed_bg.properties @@ -1,13 +1,73 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Changes\ will\ take\ effect\ when\ you\ restart\ Jenkins=\u041F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0435 \u0449\u0435 \u0441\u0442\u0430\u043D\u0430\u0442 \u0430\u043A\u0442\u0438\u0432\u043D\u0438 \u0441\u043B\u0435\u0434 \u0440\u0435\u0441\u0442\u0430\u0440\u0442 \u043D\u0430 Jenkins -Enabled=\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043D -Name=\u0418\u043C\u0435 -Pinned=\u0417\u0430\u043B\u0435\u043F\u0435\u043D -Previously\ installed\ version=\u041F\u0440\u0435\u0434\u0438\u0448\u043D\u043E \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0430 \u0432\u0435\u0440\u0441\u0438\u044F -Restart\ Once\ No\ Jobs\ Are\ Running=\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439 \u0432 \u043C\u043E\u043C\u0435\u043D\u0442\u0430 \u0432 \u043A\u043E\u0439\u0442\u043E \u043D\u044F\u043C\u0430 \u043F\u043E\u0432\u0435\u0447\u0435 \u0440\u0430\u0431\u043E\u0442\u0435\u0449\u0438 \u0431\u0438\u043B\u0434\u043E\u0432\u0435. -Uncheck\ to\ disable\ the\ plugin=\u0418\u0437\u0447\u0438\u0441\u0442\u0435\u0442\u0435 \u0437\u0430 \u0434\u0430 \u0437\u0430\u0431\u0440\u0430\u043D\u0438\u0442\u0435 \u043F\u043B\u044A\u0433\u0438\u043D\u0430 -Uninstall=\u0414\u0435\u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0439 -Unpin=\u041E\u0442\u043B\u0435\u043F\u0438 -Version=\u0412\u0435\u0440\u0441\u0438\u044F -downgradeTo=\u0412\u044A\u0440\u043D\u0438 \u043A\u044A\u043C \u0432\u0435\u0440\u0441\u0438\u044F {0} +Changes\ will\ take\ effect\ when\ you\ restart\ Jenkins=\ + \u041f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u0449\u0435 \u0432\u043b\u044f\u0437\u0430\u0442 \u0432 \u0441\u0438\u043b\u0430 \u0441\u043b\u0435\u0434 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins +Enabled=\ + \u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d +Name=\ + \u0418\u043c\u0435 +Pinned=\ + \u0424\u0438\u043a\u0441\u0438\u0440\u0430\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f +Previously\ installed\ version=\ + \u041f\u0440\u0435\u0434\u0438\u0448\u043d\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f +Restart\ Once\ No\ Jobs\ Are\ Running=\ + \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435, \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0431\u0435\u0437 \u0442\u0435\u043a\u0443\u0449\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +Uncheck\ to\ disable\ the\ plugin=\ + \u041c\u0430\u0445\u043d\u0435\u0442\u0435 \u043e\u0442\u043c\u0435\u0442\u043a\u0430\u0442\u0430 \u0437\u0430 \u0437\u0430\u0431\u0440\u0430\u043d\u0430 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 +Uninstall=\ + \u0414\u0435\u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 +Unpin=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f +Version=\ + \u0412\u0435\u0440\u0441\u0438\u044f +downgradeTo=\ + \u041a\u044a\u043c \u0432\u0435\u0440\u0441\u0438\u044f {0} +No\ plugins\ installed.=\ + \u041d\u044f\u043c\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438. +Update\ Center=\ + \u0421\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Uninstallation\ pending=\ + \u041f\u0440\u0435\u0434\u0441\u0442\u043e\u0438 \u0434\u0435\u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 +Warning=\ + \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 +This\ plugin\ cannot\ be\ uninstalled=\ + \u0422\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0434\u0435\u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430 +It\ has\ one\ or\ more\ enabled\ dependants=\ + \u0418\u043c\u0430 \u043f\u043e\u043d\u0435 \u0435\u0434\u043d\u0430 \u0434\u0440\u0443\u0433\u0430 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u043a\u043e\u044f\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438 \u043e\u0442 \u043d\u0435\u044f +It\ has\ one\ or\ more\ disabled\ dependencies=\ + \u0418\u043c\u0430 \u043f\u043e\u043d\u0435 \u0435\u0434\u043d\u0430 \u0434\u0440\u0443\u0433\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u043a\u043e\u044f\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438 \u043e\u0442 \u043d\u0435\u044f +This\ plugin\ cannot\ be\ disabled=\ + \u0422\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0438 +This\ plugin\ cannot\ be\ enabled=\ + \u0422\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0432\u043a\u043b\u044e\u0447\u0438 +Filter=\ + \u0424\u0438\u043b\u0442\u0440\u0438\u0440\u0430\u043d\u0435 +wiki.url=\ + \u0422\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0438 +requires.restart=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 Jenkins, \u043f\u0440\u0435\u0434\u0438 \u0434\u0430 \u043f\u0440\u0430\u0432\u0438\u0442\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u043f\u043e\ + \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438\u0442\u0435. \u041e\u043f\u0430\u0441\u043d\u043e \u0435 \u0434\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435 \u0431\u0435\u0437 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435. +It\ has\ one\ or\ more\ installed\ dependants=\ + \u041a\u044a\u043c \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0430 \u043f\u043e\u043d\u0435 \u0435\u0434\u043d\u0430 \u0434\u0440\u0443\u0433\u0430 \u043a\u0430\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442. +No\ description\ available.=\ + \u0411\u0435\u0437 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 diff --git a/core/src/main/resources/hudson/PluginManager/installed_pl.properties b/core/src/main/resources/hudson/PluginManager/installed_pl.properties index 799c461da78217eaf58e3abb3ae4028910194ac0..9fd5654ff235cb56e7f8ea97cccb77a23422746f 100644 --- a/core/src/main/resources/hudson/PluginManager/installed_pl.properties +++ b/core/src/main/resources/hudson/PluginManager/installed_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-2016, Sun Microsystems, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -25,10 +25,17 @@ Enabled=W\u0142\u0105czone wtyczki Name=Nazwa Pinned=Przypi\u0119ta Previously\ installed\ version=Poprzednia zainstalowana wersja -Restart\ Once\ No\ Jobs\ Are\ Running=Zrestartuj gdy \u017Cadne zadania nie s\u0105 wykonywane +Restart\ Once\ No\ Jobs\ Are\ Running=Uruchom ponownie gdy \u017Cadne zadania nie s\u0105 wykonywane Uncheck\ to\ disable\ the\ plugin=Odznacz aby wy\u0142\u0105czy\u0107 wtyczk\u0119 Uninstall=Odinstaluj Unpin=Odepnij Version=Wersja downgradeTo=Powr\u00F3\u0107 do starszej wersji {0} -wiki.url=http://wiki.jenkins-ci.org/display/JENKINS/Pinned+Plugins +requires.restart=Wymagane jest ponowne uruchomienie Jenkinsa. Zmiany wtyczek w tym momencie s\u0105 bardzo niewskazane. Uruchom ponownie Jenkinsa, zanim wprowadzisz zmiany. +Uninstallation\ pending=Trwa odinstalowywanie +This\ plugin\ cannot\ be\ disabled=Ta wtyczka nie mo\u017Ce by\u0107 wy\u0142\u0105czona +No\ plugins\ installed.=Brak zainstalowanych wtyczek +This\ plugin\ cannot\ be\ enabled=Ta wtyczka nie mo\u017Ce by\u0107 wy\u0142\u0105czona +Update\ Center=Centrum aktualizacji +Filter=Filtruj +No\ description\ available.=Opis nie jest dost\u0119pny diff --git a/core/src/main/resources/hudson/PluginManager/installed_sr.properties b/core/src/main/resources/hudson/PluginManager/installed_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0adbdf655ecd9d685677c2438c07219c5d8b7917 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/installed_sr.properties @@ -0,0 +1,29 @@ +# This file is under the MIT License by authors + +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +Filter=\u041F\u0440\u043E\u0444\u0438\u043B\u0442\u0440\u0438\u0440\u0430\u0458 +Warning=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435 +requires.restart=\u041F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0458\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0438 Jenkins. \u041E\u043F\u0430\u0441\u043D\u043E \u0458\u0435 \u043C\u0435\u045A\u0430\u0442\u0438 \u043C\u043E\u0434\u0443\u043B\u0435 \u0443 \u043E\u0432\u043E \u0432\u0440\u0435\u043C\u0435 - \u043F\u043E\u043D\u043E\u0432\u043E Jenkins \u043F\u0440\u0435 \u043D\u0435\u0433\u043E \u0448\u0442\u043E \u0434\u0435\u043B\u0443\u0458\u0435\u0442\u0435 \u0434\u0430\u0459\u0435. +This\ plugin\ cannot\ be\ enabled=\u041E\u0432\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043E\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0430 +This\ plugin\ cannot\ be\ disabled=\u041E\u0432\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0430 +This\ plugin\ cannot\ be\ uninstalled=\u041E\u0432\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u043D\u0435\u043C\u043E\u0436\u0435 \u0432\u0438\u0442\u0438 \u0434\u0435\u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0430 +It\ has\ one\ or\ more\ disabled\ dependencies=\u041F\u043E\u0441\u0442\u043E\u0458\u0438 \u043D\u0430\u0458\u043C\u0430\u045A\u0435 \u0458\u0435\u0434\u043D\u0430 \u0438\u0441\u043A\u0459\u0443\u0447\u0435\u043D\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u043E\u0434 \u043A\u043E\u0458\u0435 \u043E\u0432\u0430 \u0437\u0430\u0432\u0438\u0441\u0438 +It\ has\ one\ or\ more\ enabled\ dependants=\u041F\u043E\u0441\u0442\u043E\u0458\u0438 \u043D\u0430\u0458\u043C\u0430\u045A\u0435 \u0458\u0435\u043D\u0434\u0430 \u0434\u0440\u0443\u0433\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u043A\u043E\u0458\u0430 \u0437\u0430\u0432\u0438\u0441\u0438 \u043E\u0434 \u045A\u0435 +It\ has\ one\ or\ more\ installed\ dependants=\u041F\u043E\u0441\u0442\u043E\u0458\u0438 \u043D\u0430\u0458\u043C\u0430\u045A\u0435 \u0458\u0435\u043D\u0434\u0430 \u0434\u0440\u0443\u0433\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u043A\u043E\u0458\u0430 \u0437\u0430\u0432\u0438\u0441\u0438 \u043E\u0434 \u045A\u0435 +No\ plugins\ installed.=\u041D\u0435\u043C\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430 +Uncheck\ to\ disable\ the\ plugin=\u0423\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u043A\u0432\u0430\u0447\u0438\u0446\u0443 \u0434\u0430 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0443 +Enabled=\u0410\u043A\u0442\u0438\u043D\u0432\u043E +Name=\u0418\u043C\u0435 +Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 +Previously\ installed\ version=\u041F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u043E \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 +Pinned=\u0424\u0438\u043A\u0441\u0438\u0440\u0430\u043D\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 +Uninstall=\u0414\u0435\u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 +No\ description\ available.=\u041D\u0435\u043C\u0430 \u043E\u043F\u0438\u0441\u0430 +downgradeTo=\u0412\u0440\u0430\u0442\u0438 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 \u043D\u0430\u0437\u0430\u0434 \u043D\u0430 {0} +Unpin=\u041E\u0434\u043C\u0440\u0437\u043D\u0438 +wiki.url=http://wiki.jenkins-ci.org/display/JENKINS/Pinned+Plugins +Uninstallation\ pending=\u0414\u0435\u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443 +Changes\ will\ take\ effect\ when\ you\ restart\ Jenkins=\u041F\u0440\u043E\u043C\u0435\u043D\u0435 \u045B\u0435 \u0441\u0442\u0443\u043F\u0438\u0442\u0438 \u043D\u0430\u043A\u043E\u043D \u043F\u043E\u043D\u043E\u0432\u043D\u043E\u0433 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 Jenkins +Restart\ Once\ No\ Jobs\ Are\ Running=\u041F\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0442\u0438 \u043A\u0430\u0434 \u043D\u0435 \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u043E \u0442\u0435\u043A\u0443\u045B\u0438\u0445 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. +New\ plugins\ will\ take\ effect\ once\ you\ restart\ Jenkins=\u041D\u043E\u0432\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u045B\u0435 \u0441\u0442\u0443\u043F\u0438\u0442\u0438 \u043D\u0430\u043A\u043E\u043D \u043F\u043E\u043D\u043E\u0432\u043E\u0433 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 +Restart\ Now=\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0438 \u0441\u0430\u0434\u0430 diff --git a/core/src/main/resources/hudson/PluginManager/sidepanel.groovy b/core/src/main/resources/hudson/PluginManager/sidepanel.groovy index 98aeab34702702834934e1499d9f20e3286ebd81..d129bd53c71afabdb533e5a7e679fad3906d656c 100644 --- a/core/src/main/resources/hudson/PluginManager/sidepanel.groovy +++ b/core/src/main/resources/hudson/PluginManager/sidepanel.groovy @@ -28,7 +28,7 @@ l.header() l.side_panel { l.tasks { l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard")) - l.task(icon:"icon-setting icon-md", href:"${rootURL}/manage", title:_("Manage Jenkins"), permission:app.ADMINISTER, it:app) + l.task(icon:"icon-gear2 icon-md", href:"${rootURL}/manage", title:_("Manage Jenkins"), permission:app.ADMINISTER, it:app) if (!app.updateCenter.jobs.isEmpty()) { l.task(icon:"icon-plugin icon-md", href:"${rootURL}/updateCenter/", title:_("Update Center")) } diff --git a/core/src/main/resources/hudson/PluginManager/sidepanel_bg.properties b/core/src/main/resources/hudson/PluginManager/sidepanel_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..18a142f1ce25170da4da6e000fa3b12385b7f7dd --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/sidepanel_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Back\ to\ Dashboard=\ + \u041a\u044a\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f \u0435\u043a\u0440\u0430\u043d +Manage\ Jenkins=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 Jenkins +Update\ Center=\ + \u0421\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_fr.properties b/core/src/main/resources/hudson/PluginManager/sidepanel_pl.properties similarity index 85% rename from core/src/main/resources/hudson/model/Slave/help-launcher_fr.properties rename to core/src/main/resources/hudson/PluginManager/sidepanel_pl.properties index bf302724067063e45a2b6019c5c3bb5a17085b97..cd9cfbdce1c1d2b016ae8aba04bfc322236240b0 100644 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_fr.properties +++ b/core/src/main/resources/hudson/PluginManager/sidepanel_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Alan Harder, Eric Lefevre-Ardant +# Copyright (c) 2004-2016, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Controls\ how\ Jenkins\ starts\ this\ slave.=Contrle la faon dont Jenkins dmarre l''esclave. +Back\ to\ Dashboard=Powr\u00F3t do tablicy +Manage\ Jenkins=Zarz\u0105dzaj Jenkinsem diff --git a/core/src/main/resources/hudson/PluginManager/sidepanel_sr.properties b/core/src/main/resources/hudson/PluginManager/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..baba7c569c30a788802dce6a9cf9ba11f431ebc2 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/sidepanel_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043A\u043E\u043D\u0442\u043E\u0440\u043B\u043D\u043E\u0458 \u043F\u0430\u043D\u0435\u043B\u0438 +Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Executor/causeOfDeath_zh_TW.properties b/core/src/main/resources/hudson/PluginManager/sites_bg.properties similarity index 75% rename from core/src/main/resources/hudson/model/Executor/causeOfDeath_zh_TW.properties rename to core/src/main/resources/hudson/PluginManager/sites_bg.properties index 1a5bca33768540002aa1bdf4524017799507650b..52e24f2840bb03b5e019691503113d20609ffb4a 100644 --- a/core/src/main/resources/hudson/model/Executor/causeOfDeath_zh_TW.properties +++ b/core/src/main/resources/hudson/PluginManager/sites_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back=\u8fd4\u56de -Thread\ is\ still\ alive=Thread \u904b\u4f5c\u4e2d -Thread\ has\ died=Thread \u5df2\u4e2d\u6b62 -more\ info=\u66f4\u591a\u8cc7\u8a0a -Restart\ this\ thread=\u91cd\u65b0\u555f\u52d5 Thread +Remove=\ + \u041f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435 +Add...=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435\u2026 +Update\ Center=\ + \u0421\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f + diff --git a/core/src/main/resources/hudson/PluginManager/sites_sr.properties b/core/src/main/resources/hudson/PluginManager/sites_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..008225b821ad3154447f184aeb3fba9c275af713 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/sites_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +Add...=\u0414\u043E\u0434\u0430\u0458... +Remove=\u0423\u043A\u043B\u043E\u043D\u0438 diff --git a/core/src/main/resources/hudson/PluginManager/tabBar_bg.properties b/core/src/main/resources/hudson/PluginManager/tabBar_bg.properties index 1c89e45f4ada87a2f6d3126feb2edf37133778b6..440d9b26d84a9a35acbda671965d6cc1173a06f7 100644 --- a/core/src/main/resources/hudson/PluginManager/tabBar_bg.properties +++ b/core/src/main/resources/hudson/PluginManager/tabBar_bg.properties @@ -1,6 +1,32 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Advanced=\u0420\u0430\u0437\u0448\u0438\u0440\u0435\u043D\u0438 -Available=\u041D\u0430\u043B\u0438\u0447\u043D\u0438 -Installed=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0438 -Updates=\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F +Advanced=\ + \u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 +Available=\ + \u041d\u0430\u043b\u0438\u0447\u043d\u0438 +Installed=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438 +Updates=\ + \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Sites=\ + \u0421\u0430\u0439\u0442\u043e\u0432\u0435 diff --git a/core/src/main/resources/hudson/PluginManager/tabBar_sr.properties b/core/src/main/resources/hudson/PluginManager/tabBar_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c7e4f8cb4bab6a7ffadb29e6a162a1da3633fb29 --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/tabBar_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Updates=\u041D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0435 +Available=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u043E +Installed=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u043E +Advanced=\u041D\u0430\u043F\u0440\u0435\u0434\u043D\u043E +Sites=\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0435 diff --git a/core/src/main/resources/hudson/PluginManager/table.properties b/core/src/main/resources/hudson/PluginManager/table.properties index 0a60d099892f5256e278c2fc3918e66846ad1d77..cc7af60893f49c7a3c8f67b61ab97099f922bf0b 100644 --- a/core/src/main/resources/hudson/PluginManager/table.properties +++ b/core/src/main/resources/hudson/PluginManager/table.properties @@ -27,10 +27,9 @@ coreWarning=\ Warning: This plugin is built for Jenkins {0} or newer. \ It may or may not work in your Jenkins. depCompatWarning=\ - Warning: This plugin requires dependent plugins be upgraded \ - and some of these dependent plugins are not compatible \ - with the current installed version. Jobs using these \ - dependent plugins may need to be reconfigured. + Warning: This plugin requires dependent plugins be upgraded and at least one of these dependent plugins claims to use a different settings format than the installed version. \ + Jobs using that plugin may need to be reconfigured, and/or you may not be able to cleanly revert to the prior version without manually restoring old settings. \ + Consult the plugin release notes for details. depCoreWarning=\ Warning: This plugin requires dependent plugins that are \ built for Jenkins {0} or newer. The dependent plugins may \ diff --git a/core/src/main/resources/hudson/PluginManager/table_bg.properties b/core/src/main/resources/hudson/PluginManager/table_bg.properties index 7f6814bcbdc28381d7b4b78009b3fb2735faa809..893174efce4dcc7ef700a68b8bbee745d59fe5e2 100644 --- a/core/src/main/resources/hudson/PluginManager/table_bg.properties +++ b/core/src/main/resources/hudson/PluginManager/table_bg.properties @@ -1,11 +1,63 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Check\ to\ install\ the\ plugin=\u041C\u0430\u0440\u043A\u0438\u0440\u0430\u0439\u0442\u0435 \u0437\u0430 \u0434\u0430 \u0441\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430 \u043F\u043B\u044A\u0433\u0438\u043D\u0430 -Download\ now\ and\ install\ after\ restart=\u0421\u0432\u0430\u043B\u044F\u043D\u0435 \u0441\u0435\u0433\u0430 \u0438 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 \u0441\u043B\u0435\u0434 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043D\u0435 -Filter=\u0424\u0438\u043B\u0442\u044A\u0440 -Install=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0439 -Install\ without\ restart=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 \u0431\u0435\u0437 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043D\u0435 -Installed=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D -Name=\u0418\u043C\u0435 -No\ updates=\u041D\u044F\u043C\u0430 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F -Version=\u0412\u0435\u0440\u0441\u0438\u044F +Check\ to\ install\ the\ plugin=\ + \u0418\u0437\u0431\u0435\u0440\u0435\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u0437\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 +Download\ now\ and\ install\ after\ restart=\ + \u0418\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u0441\u043b\u0435\u0434 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 +Filter=\ + \u0424\u0438\u043b\u0442\u0440\u0438\u0440\u0430\u043d\u0435 +Install=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 +Install\ without\ restart=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u0431\u0435\u0437 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 +Installed=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0430 +Name=\ + \u0418\u043c\u0435 +No\ updates=\ + \u041d\u044f\u043c\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Version=\ + \u0412\u0435\u0440\u0441\u0438\u044f +depCoreWarning=\ + \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u0442\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438, \u043a\u043e\u0438\u0442\u043e \u0441\u0430 \u0437\u0430 Jenkins \u0432\u0435\u0440\u0441\u0438\u044f\ + {0} \u0438\u043b\u0438 \u043f\u043e-\u043d\u043e\u0432\u0430. \u0418\u043c\u0430 \u0448\u0430\u043d\u0441 \u0442\u0435 \u0434\u0430 \u043d\u0435 \u0441\u0430 \u0441\u044a\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0438 \u0441 \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Jenkins,\ + \u0442.\u0435. \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u043c\u043e\u0436\u0435 \u0438 \u0434\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0438. +compatWarning=\ + \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u043d\u043e\u0432\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u0435\u043d \u0444\u043e\u0440\u043c\u0430\u0442 \u043d\u0430\ + \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0441\u043f\u0440\u044f\u043c\u043e \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f. \u0429\u0435 \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435, \u043a\u043e\u0438\u0442\u043e \u044f\ + \u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u2014 \u0438\u043c\u0430 \u0448\u0430\u043d\u0441 \u0434\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0441\u0435 \u0432\u044a\u0440\u043d\u0435\u0442\u0435 \u043a\u044a\u043c \u043f\u0440\u0435\u0434\u0438\u0448\u043d\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f, \u0431\u0435\u0437\ + \u043d\u0430\u043d\u043e\u0432\u043e \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u0433\u043b\u0435\u0434\u043d\u0435\u0442\u0435 \u0431\u0435\u043b\u0435\u0436\u043a\u0438\u0442\u0435 \u043a\u044a\u043c\ + \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430. +Inactive=\ + \u041d\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u0430 +Update\ Center=\ + \u0421\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Click\ this\ heading\ to\ sort\ by\ category=\ + \u041d\u0430\u0442\u0438\u0441\u043d\u0435\u0442\u0435 \u0437\u0430\u0433\u043b\u0430\u0432\u043d\u0430\u0442\u0430 \u043a\u043b\u0435\u0442\u043a\u0430 \u0437\u0430 \u043f\u043e\u0434\u0440\u0435\u0434\u0431\u0430 \u043f\u043e \u0442\u0430\u0437\u0438 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f +coreWarning=\ + \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u0442\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0437\u0430 Jenkins \u0432\u0435\u0440\u0441\u0438\u044f {0} \u0438\u043b\u0438\ + \u043f\u043e-\u043d\u043e\u0432\u0430, \u043c\u043e\u0436\u0435 \u0438 \u0434\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0438 \u0441 \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Jenkins. +depCompatWarning=\ + \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435: \u0442\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0435\u0449\u0438\u0442\u0435 \u043e\u0442 \u043d\u0435\u044f\ + \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438. \u0427\u0430\u0441\u0442 \u043e\u0442 \u0442\u044f\u0445 \u043d\u0435 \u0441\u0430 \u0441\u044a\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0438 \u0441 \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Jenkins. \u0429\u0435\ + \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435, \u043a\u043e\u0438\u0442\u043e \u0433\u0438 \u043f\u043e\u043b\u0437\u0432\u0430\u0442. diff --git a/core/src/main/resources/hudson/PluginManager/table_sr.properties b/core/src/main/resources/hudson/PluginManager/table_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1517b4aa23eb508e3e2824c240d96f5aa628c1f --- /dev/null +++ b/core/src/main/resources/hudson/PluginManager/table_sr.properties @@ -0,0 +1,19 @@ +# This file is under the MIT License by authors + +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +Filter=\u0424\u0438\u043B\u0442\u0440\u0438\u0440\u0430\u0458 +Check\ to\ install\ the\ plugin=\u0418\u0437\u0430\u0431\u0435\u0440\u0438\u0442\u0435 \u043A\u0432\u0430\u0447\u0438\u0446\u0443 \u0434\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0443 +Click\ this\ heading\ to\ sort\ by\ category=\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043E\u0432\u0430\u0458 \u043D\u0430\u0441\u043B\u043E\u0432 \u0434\u0430 \u0441\u043E\u0440\u0442\u0438\u0440\u0430\u0442\u0435 \u043F\u043E \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0458\u0438 +Install=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 +Name=\u0418\u043C\u0435 +Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 +Installed=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u043E +compatWarning=\ + \u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043D\u043E\u0432\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u0434\u0440\u0443\u0433\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u043D\u0430 \u043E\u0434\u043D\u043E\u0441\u0443 \u043D\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0435. \u0417\u0430\u0434\u0430\u0446\u0438 \u043A\u043E\u0458\u0438 \u043A\u043E\u0440\u0438\u0441\u0442\u0435 \u043E\u0432\u0443 \u043C\u043E\u0434\u0443\u043B\u0443 \u045B\u0435 \u043C\u043E\u0436\u0434\u0430 \u043C\u043E\u0440\u0430\u0442\u0438 \u0431\u0438\u0442\u0438 \u0434\u0440\u0443\u0433\u0430\u0447\u0438\u0458\u0435 \u043F\u043E\u0434\u0435\u0448\u0435\u043D\u0438, \u0438 \u043C\u043E\u0436\u0434\u0430 \u043D\u0435\u045B\u0435\u0442\u0435 \u043C\u043E\u045B\u0438 \u0432\u0440\u0430\u0442\u0438\u0442\u0438 \u043D\u0430 \u0441\u0442\u0430\u0440\u0438\u0458\u0443 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 \u0431\u0435\u0437 \u0440\u0443\u0447\u043D\u043E\u0433 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430. \u0417\u0430 \u0432\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430, \u043F\u043E\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0431\u0435\u043B\u0435\u0448\u043A\u0435 \u043E\u0432\u0435 \u043C\u043E\u0434\u0443\u043B\u0435. +coreWarning=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u041C\u043E\u0434\u0443\u043B\u0430 \u0458\u0435 \u043A\u043E\u043C\u043F\u0430\u0442\u0438\u0431\u0438\u043B\u043D\u0430 \u0441\u0430 Jenkins \u0432\u0435\u0440\u0437\u0438\u0458\u0435 {0} \u0438\u043B\u0438 \u043D\u043E\u0432\u0438\u0458\u0435. \u041C\u043E\u0436\u0434\u0430 \u045B\u0435 \u0440\u0430\u0434\u0438\u0442\u0438 \u0441\u0430 \u0432\u0430\u0448\u043E\u0458 \u0432\u0435\u0440\u0437\u0438\u0458\u0438. +depCompatWarning=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043E\u0432\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u0437\u0430\u0445\u0442\u0435\u0432\u0430 \u0438\u0441\u043F\u0440\u0430\u0432\u0435 \u043D\u0430\u0434 \u043C\u043E\u0434\u0443\u043B\u0438\u043C\u0430 \u043E\u0434 \u043A\u043E\u0458\u0435 \u043E\u0432\u0430 \u0437\u0430\u0432\u0438\u0441\u043D\u0438. \u041D\u0435\u043A\u0438 \u043E\u0434 \u045A\u0438\u0445 \u043D\u0438\u0441\u0443 \u043A\u043E\u043C\u043F\u0430\u0442\u0438\u0431\u0438\u043B\u043D\u0438 \u0441\u0430 \u0432\u0430\u0448\u043E\u043C \u0432\u0435\u0440\u0437\u0438\u0458\u043E\u043C Jenkins-\u0430. \u041C\u043E\u0440\u0430\u0442\u0435 \u0442\u0430\u043A\u043E\u0452\u0435 \u043F\u043E\u0434\u0435\u0441\u0438\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u043A\u043E\u0458\u0435 \u0438\u0445 \u043A\u043E\u0440\u0438\u0441\u0442\u0435. +depCoreWarning=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043E\u0432\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u0437\u0430\u0445\u0442\u0435\u0432\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430 \u043A\u043E\u0458\u0435 \u0441\u0443 \u0441\u0430\u043C\u043E \u0437\u0430 Jenkins \u0432\u0435\u0440\u0437\u0438\u0458\u0443 {0} \u0438\u043B\u0438 \u043D\u043E\u0432\u0438\u0458\u0435. \u041F\u043E\u0441\u0442\u043E\u0458\u0438 \u0448\u0430\u043D\u0441\u0430 \u0434\u0430 \u043E\u043D\u0438 \u043D\u0435\u045B\u0435 \u0440\u0430\u0434\u0438\u0442\u0438 \u0441\u0430 \u0432\u0430\u0448\u043E\u043C \u0432\u0435\u0440\u0437\u0438\u0458\u043E\u043C Jenkins-\u0430, \u0442\u0430\u043A\u043E\u0452\u0435 \u0438 \u043E\u0432\u0430. +Inactive=\u041D\u0435\u0430\u043A\u0442\u0438\u0432\u043D\u0435 +No\ updates=\u041D\u0435\u043C\u0430 \u043D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0430 +Install\ without\ restart=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 \u0431\u0435\u0437 \u043F\u043E\u043D\u043E\u0432\u043E\u0433 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 +Download\ now\ and\ install\ after\ restart=\u041F\u0440\u0435\u0443\u0437\u043C\u0438 \u0441\u0430\u0434\u0430 \u0438 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458\u0442\u0435 \u043D\u0430\u043A\u043E\u043D \u043F\u043E\u043D\u043E\u0432\u043E\u0433 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/PluginWrapper/PluginWrapperAdministrativeMonitor/message.jelly b/core/src/main/resources/hudson/PluginWrapper/PluginWrapperAdministrativeMonitor/message.jelly new file mode 100644 index 0000000000000000000000000000000000000000..54fe0726608696b7178c3f83eaea44c6230ab679 --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/PluginWrapperAdministrativeMonitor/message.jelly @@ -0,0 +1,22 @@ + + +
    +
    +
    + +
    + + There are dependency errors loading some plugins: +
      + +
    • ${plugin.longName} v${plugin.version} +
        + +
      • ${d}
      • +
        +
      +
    • +
      +
    +
    +
    diff --git a/core/src/main/resources/hudson/PluginWrapper/PluginWrapperAdministrativeMonitor/message_sr.properties b/core/src/main/resources/hudson/PluginWrapper/PluginWrapperAdministrativeMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..bca24ec7867558e5ef384bf7c5a8d354695636ab --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/PluginWrapperAdministrativeMonitor/message_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Correct=\u041F\u0440\u0430\u0432\u0438\u043B\u043D\u043E diff --git a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses.jelly b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses.jelly index 80fe21f1ec484be4acaf8245b9c51351cc029be2..acdbbb6b9e75ec89bde94f0aaa653e2c33bb017c 100644 --- a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses.jelly +++ b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses.jelly @@ -25,7 +25,7 @@ THE SOFTWARE. - +

    ${%about(it.longName+' '+it.version)}

    diff --git a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_bg.properties b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..884f05963cdd80ccbb5e92059f3f04bbb4b457ac --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +No\ information\ recorded=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f +3rd\ Party\ Dependencies=\ + \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u0438 \u043e\u0442 \u0442\u0440\u0435\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438 +about=\ + \u041e\u0442\u043d\u043e\u0441\u043d\u043e \u201e{0}\u201c diff --git a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_de.properties b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_de.properties index 187db016889c101b211396b3098f32b672639e72..84f1c402cef454d9d3e4353ae548f0dfd662a573 100644 --- a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_de.properties +++ b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_de.properties @@ -1,25 +1,25 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -about=\u00DCber {0} -No\ information\ recorded=Keine Informationen verf\u00FCgbar -3rd\ Party\ Dependencies=Dritthersteller-Abh\u00E4ngigkeiten +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +about=\u00DCber {0} +No\ information\ recorded=Keine Informationen verf\u00FCgbar +3rd\ Party\ Dependencies=Dritthersteller-Abh\u00E4ngigkeiten diff --git a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_lt.properties b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..d5e34dd4a8a81275a3decb58f5cc958c5a8611ad --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_lt.properties @@ -0,0 +1 @@ +about=Apie {0} diff --git a/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_sr.properties b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5790695505a246d8cde4defb633382888820a43a --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/thirdPartyLicenses_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +about=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0430 \u043E {0} +3rd\ Party\ Dependencies=\u0417\u0430\u0432\u0438\u0441\u043D\u043E\u0441\u0442\u0438 \u0441\u0430 \u0440\u0430\u0437\u043D\u0438\u0445 \u0441\u0442\u0440\u0430\u043D\u0430 +No\ information\ recorded=\u041D\u0438\u0458\u0435 \u043D\u0438\u0448\u0442\u0430 \u0437\u0430\u043F\u0438\u0441\u0430\u043D\u043E diff --git a/core/src/main/resources/hudson/PluginWrapper/uninstall.groovy b/core/src/main/resources/hudson/PluginWrapper/uninstall.groovy index a47356a1a5b650c852df453b810e65f3fea37939..b6e34756f017703e8b4c61d31b527b4c7e8881b7 100644 --- a/core/src/main/resources/hudson/PluginWrapper/uninstall.groovy +++ b/core/src/main/resources/hudson/PluginWrapper/uninstall.groovy @@ -1,9 +1,11 @@ package hudson.PluginWrapper +import jenkins.model.Jenkins + def l = namespace(lib.LayoutTagLib) def f = namespace(lib.FormTagLib) -l.layout { +l.layout(permission: Jenkins.ADMINISTER) { def title = _("title", my.shortName) l.header(title:title) l.main_panel { diff --git a/core/src/main/resources/hudson/PluginWrapper/uninstall_lt.properties b/core/src/main/resources/hudson/PluginWrapper/uninstall_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..80e7fec4e0832bbbca33cfca4f72c032f13aeb18 --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/uninstall_lt.properties @@ -0,0 +1,3 @@ +msg=J\u016bs tuoj i\u0161mesite pried\u0105 {0}. Priedo vykdomas kodas bus pa\u0161alintas i\u0161 j\u016bs\u0173 $JENKINS_HOME, \ + o priedo konfig\u016bravimo failai bus palikti nepaliesti. +title=I\u0161imamas priedas {0} diff --git a/core/src/main/resources/hudson/PluginWrapper/uninstall_pl.properties b/core/src/main/resources/hudson/PluginWrapper/uninstall_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..8ac4bef57538f34d8fd0b297e2e6fd3a86fe8cd0 --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/uninstall_pl.properties @@ -0,0 +1,3 @@ +msg=Czy na pewno chcesz usun\u0105\u0107 wtyczk\u0119 {0}? Ta operacja usunie wtyczk\u0119 z folderu $JENKINS_HOME, ale pozostawi pliki konfiguracyjne. +title=Odinstalowywanie wtyczki {0} +Yes=Tak \ No newline at end of file diff --git a/core/src/main/resources/hudson/PluginWrapper/uninstall_sr.properties b/core/src/main/resources/hudson/PluginWrapper/uninstall_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..cf1a20a90ef369030e3068895180f424207f6932 --- /dev/null +++ b/core/src/main/resources/hudson/PluginWrapper/uninstall_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +title=\u0414\u0435\u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 {0} +Yes=\u0414\u0430 +msg=\u0414\u0435\u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0442\u0438 \u045B\u0435 \u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0443 {0}, \u0448\u0442\u043E \u045B\u0435 \u0458\u0435 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u0442\u0438 \u0441\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0435 $JENKINS_HOME, \u0430\u043B\u0438 \u045B\u0435 \u043F\u0440\u0435\u043E\u0441\u0442\u0430\u0442\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 \u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0443. \ No newline at end of file diff --git a/core/src/main/resources/hudson/ProxyConfiguration/config_sr.properties b/core/src/main/resources/hudson/ProxyConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3e622e98adc7ed57d26735ae87559a3326c010ae --- /dev/null +++ b/core/src/main/resources/hudson/ProxyConfiguration/config_sr.properties @@ -0,0 +1,21 @@ +# This file is under the MIT License by authors + +Password=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 +User\ name=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 +Port=\u041F\u043E\u0440\u0442 +Server=\u0421\u0435\u0440\u0432\u0435\u0440 +No\ Proxy\ Host=\u041D\u0435\u043C\u0430 Proxy \u0425\u043E\u0441\u0442 +Validate\ Proxy=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 Proxy +Proxy\ Needs\ Authorization=\u041F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0430\u0443\u0442\u043E\u0440\u0438\u0437\u0430\u0446\u0438\u0458\u0430 \u0437\u0430 Proxy +No\ Proxy\ for=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 Proxy \u0437\u0430 +Check\ now=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 \u0441\u0430\u0434\u0430 +HTTP\ Proxy\ Configuration=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 HTTP Proxy +Submit=\u041F\u043E\u0434\u043D\u0435\u0441\u0438 +lastUpdated=\u0417\u0430\u0434\u045A\u0435 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u043E: \u043F\u0440\u0435 {0} +uploadtext=\u041C\u043E\u0436\u0435\u0442\u0435 \u043E\u0442\u043F\u0440\u0435\u043C\u0438\u0442\u0438 .hpi \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 \u0434\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0443 \u043A\u043E\u0458\u0430 \u0458\u0435 \u0432\u0430\u043D \u0433\u043B\u0430\u0432\u043D\u043E\u0433 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0430 \u0437\u0430 \u043C\u043E\u0434\u0443\u043B\u0435. +Test\ URL=URL \u0430\u0434\u0440\u0435\u0441\u0430 \u0437\u0430 \u0442\u0435\u0441\u0442\u0438\u0440\u0430\u045A\u0435 +Upload\ Plugin=\u041E\u0442\u043F\u0440\u0435\u043C\u0438 \u043C\u043E\u0434\u0443\u043B\u0443 +File=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 +Upload=\u041E\u0442\u043F\u0440\u0435\u043C\u0438 +URL=URL \u0430\u0434\u0440\u0435\u0441\u0430 +Update\ Site=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 \u0441\u0442\u0440\u0430\u043D\u0443 \ No newline at end of file diff --git a/core/src/main/resources/hudson/ProxyConfiguration/help-name.html b/core/src/main/resources/hudson/ProxyConfiguration/help-name.html index 858bf03249341805bd27bfe8e8b0a4b47d48e1a4..62f93846e9278825fc66fe9d07e005715fc74084 100644 --- a/core/src/main/resources/hudson/ProxyConfiguration/help-name.html +++ b/core/src/main/resources/hudson/ProxyConfiguration/help-name.html @@ -1,13 +1,13 @@
    If your Jenkins server sits behind a firewall and does not have the direct access to the internet, and if your server JVM is not configured appropriately - (See JDK networking properties for more details) + (See JDK networking properties for more details) to enable internet connection, you can specify the HTTP proxy server name in this field to allow Jenkins to install plugins on behalf of you. Note that Jenkins uses HTTPS to communicate with the update center to download plugins.

    - The value you submit here will be set as http.proxyHost system property. Leaving this field empty - causes this property to be unset, which means Jenkins will try to connect to the host directly. + Leaving this field empty + means Jenkins will try to connect to the internet directly.

    If you are unsure about the value, check the browser proxy configuration. diff --git a/core/src/main/resources/hudson/ProxyConfiguration/help-name_de.html b/core/src/main/resources/hudson/ProxyConfiguration/help-name_de.html index fb15d38b12778793c74f35569cf2f7e3dd45c06f..ebab2d935fd1e410f23fa0ce1623b83c9fe8fe0d 100644 --- a/core/src/main/resources/hudson/ProxyConfiguration/help-name_de.html +++ b/core/src/main/resources/hudson/ProxyConfiguration/help-name_de.html @@ -9,11 +9,9 @@ und Plugins herunterzuladen.

    - Der Wert, den Sie hier angeben, wird als Systemeigenschaft http.proxyHost - gesetzt. Wenn Sie dieses Feld freilassen, wird die Systemeigenschaft gelöscht. - Jenkins versucht dann, das Update-Center direkt zu kontaktieren. + Wenn Sie dieses Feld freilassen, versucht Jenkins, das Update-Center direkt zu kontaktieren.

    Wenn Sie sich nicht sicher sind, was Sie hier eintragen sollen, schauen Sie in der Proxy-Konfiguration Ihres Browsers nach. -

    \ No newline at end of file + diff --git a/core/src/main/resources/hudson/ProxyConfiguration/help-name_fr.html b/core/src/main/resources/hudson/ProxyConfiguration/help-name_fr.html index 7914a1700d3cdee5f2953f76135f9447c6d298cc..3c7b727592dfc5b4c826b8ca3226fd2513669e40 100644 --- a/core/src/main/resources/hudson/ProxyConfiguration/help-name_fr.html +++ b/core/src/main/resources/hudson/ProxyConfiguration/help-name_fr.html @@ -7,8 +7,7 @@ Notez que Jenkins utilise HTTPS pour communiquer avec le serveur de mise à jour pour télécharger les plugins.

    - La valeur placée ici sera positionnée dans la propriété système http.proxyHost. - Si ce champ est vide, la propriété ne sera pas positionnée; Jenkins tentera donc de se + Si ce champ est vide Jenkins tentera de se connecter directement au site.

    diff --git a/core/src/main/resources/hudson/ProxyConfiguration/help-name_pl.html b/core/src/main/resources/hudson/ProxyConfiguration/help-name_pl.html new file mode 100644 index 0000000000000000000000000000000000000000..d98aae01164fb77c8834cf1d0f128b7408a7e26b --- /dev/null +++ b/core/src/main/resources/hudson/ProxyConfiguration/help-name_pl.html @@ -0,0 +1,13 @@ +

    + Jeli Jenkins znajduje si za zapor sieciow i nie ma bezporedniego dostpu do Internetu, + a JVM nie jest skonfigurowana odpowiednio + (sprawd ustawienia sieciowe), + moesz udostpni Internet ustawiajc serwer proxy, aby Jenkins samodzielnie pobra i zainstalowa wtyczki. + Pamitaj, e Jenkins uywa poczenia https, aby pobra wtyczki z centrum aktualizacji. + +

    + Pozostaw to pole puste, aby Jenkins korzysta z bezporedniego poczenia z Internetem. + +

    + Jeli nie jeste pewny ustawie, sprawd ustawienia serwerw proxy w przegldarce. +

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/ProxyConfiguration/help-name_pt_BR.html b/core/src/main/resources/hudson/ProxyConfiguration/help-name_pt_BR.html index 2b4882af538af983c88786cbeb423bda1dcc0d48..41f744e14324e44f98c2f98eb22a3b691b7b7179 100644 --- a/core/src/main/resources/hudson/ProxyConfiguration/help-name_pt_BR.html +++ b/core/src/main/resources/hudson/ProxyConfiguration/help-name_pt_BR.html @@ -6,8 +6,8 @@ instalar plugins para você. Note que o Jenkins usa HTTPS para se comunicar com o centro de atualização para baixar os plugins.

    - O valor que você colocar aqui será atribuído a propriedade de sistema http.proxyHost. Deixar este campo vazio - deixa esta propriedade sem atribuição, o que significa que o Jenkins tentará conectar ao host externo diretamente. + Deixar este campo vazio + faz com que o Jenkins tente conectar à internet diretamente.

    Se você não está certo sobre o valor, cheque a configuração de proxy de seu browser. diff --git a/core/src/main/resources/hudson/ProxyConfiguration/help-name_tr.html b/core/src/main/resources/hudson/ProxyConfiguration/help-name_tr.html deleted file mode 100644 index 858bf03249341805bd27bfe8e8b0a4b47d48e1a4..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/ProxyConfiguration/help-name_tr.html +++ /dev/null @@ -1,14 +0,0 @@ -

    - If your Jenkins server sits behind a firewall and does not have the direct access to the internet, - and if your server JVM is not configured appropriately - (See JDK networking properties for more details) - to enable internet connection, you can specify the HTTP proxy server name in this field to allow Jenkins - to install plugins on behalf of you. Note that Jenkins uses HTTPS to communicate with the update center to download plugins. - -

    - The value you submit here will be set as http.proxyHost system property. Leaving this field empty - causes this property to be unset, which means Jenkins will try to connect to the host directly. - -

    - If you are unsure about the value, check the browser proxy configuration. -

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/TcpSlaveAgentListener/index.jelly b/core/src/main/resources/hudson/TcpSlaveAgentListener/index.jelly index 9e65250be24c2ba2ddbed7b2c3cc8abc0fd855b4..48854e95fb91e191db00c863ddc839defae840a0 100644 --- a/core/src/main/resources/hudson/TcpSlaveAgentListener/index.jelly +++ b/core/src/main/resources/hudson/TcpSlaveAgentListener/index.jelly @@ -23,17 +23,22 @@ THE SOFTWARE. --> - + + - - + + + + + + Jenkins diff --git a/core/src/main/resources/hudson/cli/CLIAction/command.jelly b/core/src/main/resources/hudson/cli/CLIAction/command.jelly index 3dcecdc1ffd01bc975e1b2fc65828032bcc702f0..02acaa65b4c4a46d9944018956d30d9bcac9ed3f 100644 --- a/core/src/main/resources/hudson/cli/CLIAction/command.jelly +++ b/core/src/main/resources/hudson/cli/CLIAction/command.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. - +

    diff --git a/core/src/main/resources/hudson/cli/CLIAction/index.jelly b/core/src/main/resources/hudson/cli/CLIAction/index.jelly index 816471090802d1d71daa8cb814a658d63851b44b..94ecddfb23b09d3c0a1525e6c712c57fd8fe64d3 100644 --- a/core/src/main/resources/hudson/cli/CLIAction/index.jelly +++ b/core/src/main/resources/hudson/cli/CLIAction/index.jelly @@ -24,7 +24,7 @@ THE SOFTWARE. - +

    diff --git a/core/src/main/resources/hudson/cli/CLIAction/index_sr.properties b/core/src/main/resources/hudson/cli/CLIAction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..704a2a0c3143c1d51d69ccd7e8c7646f96030fbe --- /dev/null +++ b/core/src/main/resources/hudson/cli/CLIAction/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Jenkins\ CLI=Jenkins \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 +blurb=\u041F\u043E\u043C\u043E\u045B\u0443 \u043A\u043E\u043D\u0437\u043E\u043B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 Jenkins \u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u043E\u0431\u0438\u0442\u0438 \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u0432\u0435\u043B\u0438\u043A\u043E\u043C \u0431\u0440\u043E\u0458\u0443 \u0444\u0443\u043D\u043A\u0446\u0438\u0458\u0430. \u0414\u0435\u0442\u0430\u0459\u043D\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u0441\u0435 \u043D\u0430\u043B\u0430\u0437\u0435 \u043D\u0430 \u0443 Jenkins \u0432\u0438\u043A\u0438. \u0423 \u0446\u0438\u0459\u0443 \u0434\u0430 \u043F\u043E\u0447\u043D\u0435\u0442\u0435 \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443, \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0458\u0435 \u0434\u0430 \u043F\u0440\u0435\u0443\u0437\u043C\u0435\u0442\u0435 jenkins-cli.jar, \u0438 \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 \u043F\u0430\u043A\u0435\u0442 \u043D\u0430 \u0441\u043B\u0435\u0434\u0435\u045B\u0438 \u043D\u0430\u0447\u0438\u043D: +Available\ Commands=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 diff --git a/core/src/main/resources/hudson/cli/CliProtocol/description.jelly b/core/src/main/resources/hudson/cli/CliProtocol/description.jelly new file mode 100644 index 0000000000000000000000000000000000000000..e24d56912900efe6607d1b434a1ec7cf61bdeee0 --- /dev/null +++ b/core/src/main/resources/hudson/cli/CliProtocol/description.jelly @@ -0,0 +1,4 @@ + + + ${%Accepts connections from CLI clients} + diff --git a/core/src/main/resources/hudson/cli/CliProtocol2/description.jelly b/core/src/main/resources/hudson/cli/CliProtocol2/description.jelly new file mode 100644 index 0000000000000000000000000000000000000000..66f27c511c1b651aa6ba9cb396d4140384750ae3 --- /dev/null +++ b/core/src/main/resources/hudson/cli/CliProtocol2/description.jelly @@ -0,0 +1,4 @@ + + + ${%Extends the version 1 protocol by adding transport encryption} + diff --git a/core/src/main/resources/hudson/cli/Messages.properties b/core/src/main/resources/hudson/cli/Messages.properties index 57c9299f81b6032667f2cc4efaa2150af0fb3f12..f2cf34d4d687eed873eed4a346af0363bca94282 100644 --- a/core/src/main/resources/hudson/cli/Messages.properties +++ b/core/src/main/resources/hudson/cli/Messages.properties @@ -21,7 +21,9 @@ CreateViewCommand.ShortDescription=\ DeleteBuildsCommand.ShortDescription=\ Deletes build record(s). DeleteViewCommand.ShortDescription=\ - Deletes view. + Deletes view(s). +DeleteJobCommand.ShortDescription=\ + Deletes job(s). GroovyCommand.ShortDescription=\ Executes the specified Groovy script. GroovyshCommand.ShortDescription=\ @@ -78,3 +80,19 @@ BuildCommand.CLICause.CannotBuildConfigNotSaved=\ Cannot build {0} because its configuration has not been saved. BuildCommand.CLICause.CannotBuildUnknownReasons=\ Cannot build {0} for unknown reasons. + +DeleteNodeCommand.ShortDescription=Deletes node(s) +ReloadJobCommand.ShortDescription=Reload job(s) +OnlineNodeCommand.ShortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command. +ClearQueueCommand.ShortDescription=Clears the build queue. +ReloadConfigurationCommand.ShortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk. +ConnectNodeCommand.ShortDescription=Reconnect to a node(s) +DisconnectNodeCommand.ShortDescription=Disconnects from a node. +QuietDownCommand.ShortDescription=Quiet down Jenkins, in preparation for a restart. Don\u2019t start any builds. +CancelQuietDownCommand.ShortDescription=Cancel the effect of the "quiet-down" command. +OfflineNodeCommand.ShortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command. +WaitNodeOnlineCommand.ShortDescription=Wait for a node to become online. +WaitNodeOfflineCommand.ShortDescription=Wait for a node to become offline. + +CliProtocol.displayName=Jenkins CLI Protocol/1 +CliProtocol2.displayName=Jenkins CLI Protocol/2 diff --git a/core/src/main/resources/hudson/cli/Messages_bg.properties b/core/src/main/resources/hudson/cli/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..3ce9a54d03d52307a3b3b8993c3b0965e43dabf7 --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_bg.properties @@ -0,0 +1,161 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +InstallPluginCommand.DidYouMean=\ + \u201e{0}\u201c \u0435 \u043a\u0440\u0430\u0442\u043a\u043e \u0438\u043c\u0435 \u0437\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430. \u201e{1}\u201c \u043b\u0438 \u0438\u043c\u0430\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434? +InstallPluginCommand.InstallingFromUpdateCenter=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 \u201e{0}\u201c \u043e\u0442 \u0441\u0430\u0439\u0442\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 +InstallPluginCommand.InstallingPluginFromLocalFile=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043e\u0442 \u043b\u043e\u043a\u0430\u043b\u0435\u043d \u0444\u0430\u0439\u043b \u201e{0}\u201c +InstallPluginCommand.InstallingPluginFromUrl=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043e\u0442 \u0430\u0434\u0440\u0435\u0441 \u201e{0}\u201c +InstallPluginCommand.NoUpdateCenterDefined=\ + \u041d\u0435 \u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u0430\u0439\u0442 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u0432 \u0442\u0430\u0437\u0438 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f \u043d\u0430 Jenkins. +InstallPluginCommand.NoUpdateDataRetrieved=\ + \u0412\u0441\u0435 \u043e\u0449\u0435 \u043d\u0435 \u0441\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438 \u043d\u0438\u043a\u0430\u043a\u0432\u0438 \u0434\u0430\u043d\u043d\u0438 \u043e\u0442 \u0446\u0435\u043d\u0442\u044a\u0440\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435: {0} +InstallPluginCommand.NotAValidSourceName=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u043d\u0438\u0442\u043e \u0444\u0430\u0439\u043b \u0441 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430, \u043d\u0438\u0442\u043e \u0430\u0434\u0440\u0435\u0441, \u043d\u0438\u0442\u043e \u0438\u043c\u0435 \u043d\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u043e\u0442 \u0441\u0430\u0439\u0442\u0430 \u0437\u0430\ + \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435. + +AddJobToViewCommand.ShortDescription=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u043a\u044a\u043c \u0438\u0437\u0433\u043b\u0435\u0434. +BuildCommand.ShortDescription=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0438 \u0438\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435\u0442\u043e \u045d (\u043f\u043e \u0438\u0437\u0431\u043e\u0440). +ConsoleCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0445\u043e\u0434\u0430 \u043e\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u043a\u044a\u043c \u043a\u043e\u043d\u0437\u043e\u043b\u0430\u0442\u0430. +CopyJobCommand.ShortDescription=\ + \u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +CreateJobCommand.ShortDescription=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u0431\u0430\u0437\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u043e\u0442\u043e \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0432\u044a\u0432\ + \u0444\u043e\u0440\u043c\u0430\u0442 XML. +CreateNodeCommand.ShortDescription=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0430 \u0431\u0430\u0437\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0447\u0435\u0442\u0435\u043d\u043e\u0442\u043e \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0432\u044a\u0432\ + \u0444\u043e\u0440\u043c\u0430\u0442 XML. +DeleteBuildsCommand.ShortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\u0442\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430. +DeleteViewCommand.ShortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434\u0438. +DeleteJobCommand.ShortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438. +GroovyCommand.ShortDescription=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 Groovy. +GroovyshCommand.ShortDescription=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u0435\u043d \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u043d\u0430 Groovy. +HelpCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0438 \u0438\u043b\u0438 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430. +InstallPluginCommand.ShortDescription=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043e\u0442 \u0444\u0430\u0439\u043b, \u0430\u0434\u0440\u0435\u0441 \u0438\u043b\u0438 \u0446\u0435\u043d\u0442\u044a\u0440\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435. +InstallToolCommand.ShortDescription=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0438 \u0438\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u043c\u0443 \u043d\u0430\ + \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0438\u0437\u0445\u043e\u0434. \u041c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u0438\u043a\u0432\u0430 \u0441\u0430\u043c\u043e \u043e\u0442 \u0437\u0430\u0434\u0430\u0447\u0430. +ListChangesCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0441 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u0437\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +ListJobsCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0438\u0437\u0433\u043b\u0435\u0434 \u0438\u043b\u0438 \u0433\u0440\u0443\u043f\u0430. +ListPluginsCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0441\u043f\u0438\u0441\u044a\u043a\u0430 \u0441 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438. +LoginCommand.ShortDescription=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0438 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f, \u0437\u0430 \u0434\u0430 \u043c\u043e\u0433\u0430\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0438\u0442\u0435\ + \u043a\u043e\u043c\u0430\u043d\u0434\u0438 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442, \u0431\u0435\u0437 \u0442\u0435\u0437\u0438 \u0434\u0430\u043d\u043d\u0438 \u0434\u0430 \u0441\u0435 \u0432\u044a\u0432\u0435\u0436\u0434\u0430\u0442 \u043d\u0430\u043d\u043e\u0432\u043e. +LogoutCommand.ShortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438\u0442\u0435 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f, \u0437\u0430\u043f\u0430\u0437\u0435\u043d\u0438 \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u0437\u0430 \u0432\u043b\u0438\u0437\u0430\u043d\u0435. +MailCommand.ShortDescription=\ + \u0418\u0437\u0447\u0438\u0442\u0430\u043d\u0435 \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0438 \u0438\u0437\u043f\u0440\u0430\u0449\u0430\u043d\u0435 \u043f\u043e \u0435-\u043f\u043e\u0449\u0430. +SetBuildDescriptionCommand.ShortDescription=\ + \u0417\u0430\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. +SetBuildParameterCommand.ShortDescription=\ + \u041f\u0440\u043e\u043c\u044f\u043d\u0430/\u0437\u0430\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0442\u0435 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. +SetBuildResultCommand.ShortDescription=\ + \u0417\u0430\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0430 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. \u041c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u0438\u043a\u0432\u0430 \u0441\u0430\u043c\u043e \u043e\u0442\ + \u0437\u0430\u0434\u0430\u0447\u0430. +RemoveJobFromViewCommand.ShortDescription=\ + \u0418\u0437\u0432\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0442 \u0438\u0437\u0433\u043b\u0435\u0434. +VersionCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 Jenkins. +GetJobCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u0438\u043d\u0438\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML \u043a\u044a\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0438\u0437\u0445\u043e\u0434. +GetNodeCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u0438\u043d\u0438\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML \u043a\u044a\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0438\u0437\u0445\u043e\u0434. +GetViewCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u0438\u043d\u0438\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434\u0430 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML \u043a\u044a\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0438\u0437\u0445\u043e\u0434. +SetBuildDisplayNameCommand.ShortDescription=\ + \u0417\u0430\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u043c\u0435\u0442\u043e (displayName) \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. +WhoAmICommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0434\u0430\u043d\u043d\u0438\u0442\u0435 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0438 \u043f\u0440\u0430\u0432\u0430\u0442\u0430. +UpdateJobCommand.ShortDescription=\ + \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u0438\u043d\u0438\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML.\ + \u041e\u0431\u0440\u0430\u0442\u043d\u043e\u0442\u043e \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eget-job\u201c. +UpdateNodeCommand.ShortDescription=\ + \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u0438\u043d\u0438\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML.\ + \u041e\u0431\u0440\u0430\u0442\u043d\u043e\u0442\u043e \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eget-node\u201c. +SessionIdCommand.ShortDescription=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043d\u0430 \u0441\u0435\u0441\u0438\u044f\u0442\u0430. \u0422\u043e\u0439 \u0441\u0435 \u0441\u043c\u0435\u043d\u044f \u043f\u0440\u0438 \u0432\u0441\u044f\u043a\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430\ + Jenkins. +UpdateViewCommand.ShortDescription=\ + \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u0435\u0444\u0438\u043d\u0438\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML.\ + \u041e\u0431\u0440\u0430\u0442\u043d\u043e\u0442\u043e \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eget-view\u201c. + +BuildCommand.CLICause.ShortDescription=\ + \u0417\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430 \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434 \u043e\u0442 \u201e{0}\u201c +BuildCommand.CLICause.CannotBuildDisabled=\ + \u0417\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u201e{0}\u201c \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438. +BuildCommand.CLICause.CannotBuildConfigNotSaved=\ + \u0417\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438, \u0437\u0430\u0449\u043e\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u045d \u043d\u0435 \u0441\u0430 \u0437\u0430\u043f\u0430\u0437\u0435\u043d\u0438. +BuildCommand.CLICause.CannotBuildUnknownReasons=\ + \u0417\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438 \u043f\u043e \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u0438. + +ClearQueueCommand.ShortDescription=\ + \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0441\u044a\u0441 \u0437\u0430\u0434\u0430\u0447\u0438. +DisconnectNodeCommand.ShortDescription=\ + \u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u0441 \u043c\u0430\u0448\u0438\u043d\u0430. +ReloadConfigurationCommand.ShortDescription=\ + \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u043c\u0435\u0442\u0442\u0430 \u0438 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u043e \u043e\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0430\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430.\ + \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e \u0434\u0438\u0441\u043a\u0430. +QuietDownCommand.ShortDescription=\ + \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043d\u0430 Jenkins \u0437\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435. \u0414\u0430 \u043d\u0435 \u0441\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +CancelQuietDownCommand.ShortDescription=\ + \u041e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430\u0442\u0430 \u0437\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u2014 \u0449\u0435 \u0441\u0435 \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +OfflineNodeCommand.ShortDescription=\ + \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u043a\u0430\u0442\u043e \u043d\u0435 \u0441\u0435\ + \u0432\u044a\u0432\u0435\u0434\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eonline-node\u201c. +WaitNodeOnlineCommand.ShortDescription=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u0430 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. +WaitNodeOfflineCommand.ShortDescription=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. +CreateViewCommand.ShortDescription=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432 \u0438\u0437\u0433\u043b\u0435\u0434 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0432\u0445\u043e\u0434 \u0432\u044a\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 XML. +OnlineNodeCommand.ShortDescription=\ + \u041e\u0442\u043d\u043e\u0432\u043e \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. \u0422\u043e\u0432\u0430 \u043e\u0442\u043c\u0435\u043d\u044f \u043f\u0440\u0435\u0434\u0438\u0448\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\ + \u201eoffline-node\u201c. +ReloadJobCommand.ShortDescription=\ + \u041f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 +DeleteNodeCommand.ShortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0438 +# Reconnect to a node(s) +ConnectNodeCommand.ShortDescription=\ + \u041d\u0430\u043d\u043e\u0432\u043e \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u043c\u0430\u0448\u0438\u043d\u0430 +# Jenkins CLI Protocol/2 +CliProtocol2.displayName=\ + \u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043d\u0430 Jenkins \u0437\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0435\u043d \u0440\u0435\u0434, \u0432\u0435\u0440\u0441\u0438\u044f 2 +# Jenkins CLI Protocol/1 +CliProtocol.displayName=\ + \u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u043d\u0430 Jenkins \u0437\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0435\u043d \u0440\u0435\u0434, \u0432\u0435\u0440\u0441\u0438\u044f 1 diff --git a/core/src/main/resources/hudson/cli/Messages_da.properties b/core/src/main/resources/hudson/cli/Messages_da.properties new file mode 100644 index 0000000000000000000000000000000000000000..bfd9e8d040cde189cc6c1c975d00299ccb0f36b8 --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_da.properties @@ -0,0 +1,12 @@ +DeleteNodeCommand.ShortDescription=Sletter en node +DeleteJobCommand.ShortDescription=Sletter et job +OnlineNodeCommand.ShortDescription=Genoptag brugen af en byggenode, for at annullere en tidligere udstedt "offline-node" kommando. +ClearQueueCommand.ShortDescription=Ryd byggek\u00f8en +ReloadConfigurationCommand.ShortDescription=Genindl\u00e6s alle data fra filsystemet. \ +Nyttigt hvis du har modificeret konfigurationsfiler direkte, udenom Jenkins. +DisconnectNodeCommand.ShortDescription=Afbryder forbindelsen til en node +ConnectNodeCommand.ShortDescription=Gentilslut en node +QuietDownCommand.ShortDescription=Forbereder nedlukning, starter ingen nye byg. +CancelQuietDownCommand.ShortDescription=Sl\u00e5 effekten af "quite-down" kommandoen fra. +OfflineNodeCommand.ShortDescription=Hold midlertidigt op med at bygge p\u00e5 en node, indtil n\u00e6ste "online-node" kommando. + diff --git a/core/src/main/resources/hudson/cli/Messages_de.properties b/core/src/main/resources/hudson/cli/Messages_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..287aeef5160e3994f2584ad5a287a5baf88cdc69 --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_de.properties @@ -0,0 +1,11 @@ +DeleteNodeCommand.ShortDescription=Knoten l\u00f6schen. +DeleteJobCommand.ShortDescription=Job l\u00f6schen. +OnlineNodeCommand.ShortDescription=Knoten wird wieder f\u00fcr neue Builds verwendet. Hebt ein vorausgegangenes "offline-node"-Kommando auf. +ClearQueueCommand.ShortDescription=Build-Warteschlange l\u00f6schen. +ReloadConfigurationCommand.ShortDescription=Alle Daten im Speicher verwerfen und Konfiguration neu von Festplatte laden. Dies ist n\u00fctzlich, wenn Sie \u00c4nderungen direkt im Dateisystem vorgenommen haben. +ConnectNodeCommand.ShortDescription=Erneut mit Knoten verbinden. +DisconnectNodeCommand.ShortDescription=Knoten trennen. +QuietDownCommand.ShortDescription=Jenkins' Aktivit\u00e4t reduzieren, z.B. zur Vorbereitung eines Neustarts. Es werden keine neuen Builds mehr gestartet. +CancelQuietDownCommand.ShortDescription=Wirkung des Befehls "quiet-down" wieder aufheben. +OfflineNodeCommand.ShortDescription=Knoten wird bis zum n\u00e4chsten "online-node"-Kommando f\u00fcr keine neuen Builds verwendet. + diff --git a/core/src/main/resources/hudson/cli/Messages_es.properties b/core/src/main/resources/hudson/cli/Messages_es.properties index 9f56ca37c0347dceaad00cd22a141f753fb64856..11525579ca6435b6433a4acfac31c4feecf6cd02 100644 --- a/core/src/main/resources/hudson/cli/Messages_es.properties +++ b/core/src/main/resources/hudson/cli/Messages_es.properties @@ -47,4 +47,16 @@ WhoAmICommand.ShortDescription=Muestra tus credenciales y permisos UpdateJobCommand.ShortDescription=Actualiza el fichero XML de la definicin de una tarea desde la entrada estndard. Es lo contrario al comando get-job. GroovyshCommand.ShortDescription=Ejecuta una shell interactiva de groovy. SetBuildDescriptionCommand.ShortDescription=Establece la descripcin de una ejecucin. +DeleteJobCommand.ShortDescription=Borrar una tarea +DeleteNodeCommand.ShortDescription=Borrar un nodo +OnlineNodeCommand.ShortDescription=Continuar usando un nodo y candelar el comando "offline-node" mas reciente. +ClearQueueCommand.ShortDescription=Limpiar la cola de trabajos +ReloadConfigurationCommand.ShortDescription=Descartar todos los datos presentes en memoria y recargar todo desde el disco duro. \u00datil cuando se han hecho modificaciones a mano en el disco duro. +ConnectNodeCommand.ShortDescription=Reconectarse con un nodo +DisconnectNodeCommand.ShortDescription=Desconectarse de un nodo +QuietDownCommand.ShortDescription=Poner Jenkins en modo quieto y estar preparado para un reinicio. No comenzar ninguna ejecuci\u00f3n. +CancelQuietDownCommand.ShortDescription=Cancelar el efecto del comando "quiet-down". +OfflineNodeCommand.ShortDescription=Dejar de utilizar un nodo temporalmente hasta que se ejecute el comando "online-node". +WaitNodeOnlineCommand.ShortDescription=Esperando hasta que el nodo est activado +WaitNodeOfflineCommand.ShortDescription=Esperando a que el nodo est desactivado diff --git a/core/src/main/resources/hudson/cli/Messages_it.properties b/core/src/main/resources/hudson/cli/Messages_it.properties new file mode 100644 index 0000000000000000000000000000000000000000..ca09f191dfc6093126030b35ec84e1f8dc37b0a4 --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_it.properties @@ -0,0 +1,10 @@ +DeleteNodeCommand.ShortDescription=Cancella un nodo +DeleteJobCommand.ShortDescription=Cancella un job +OnlineNodeCommand.ShortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command. +ClearQueueCommand.ShortDescription=Pulisce la coda di lavoro +ReloadConfigurationCommand.ShortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk. +ConnectNodeCommand.ShortDescription=Riconnettersi ad un nodo +OfflineNodeCommand.ShortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command. +WaitNodeOnlineCommand.ShortDescription=Attende che il nodo sia attivo +WaitNodeOfflineCommand.ShortDescription=Attende che un nodo sia disattivo + diff --git a/core/src/main/resources/hudson/cli/Messages_ja.properties b/core/src/main/resources/hudson/cli/Messages_ja.properties index 9399b7f78b733d69672f691addf780d04b1f0a97..fb1ddd68602381ccd617eed57b265caae0eacdd4 100644 --- a/core/src/main/resources/hudson/cli/Messages_ja.properties +++ b/core/src/main/resources/hudson/cli/Messages_ja.properties @@ -68,4 +68,17 @@ BuildCommand.CLICause.CannotBuildDisabled=\ BuildCommand.CLICause.CannotBuildConfigNotSaved=\ \u8a2d\u5b9a\u304c\u4fdd\u5b58\u3055\u308c\u3066\u3044\u306a\u3044\u306e\u3067{0}\u3092\u30d3\u30eb\u30c9\u3067\u304d\u307e\u305b\u3093\u3002 BuildCommand.CLICause.CannotBuildUnknownReasons=\ - \u30d3\u30eb\u30c9\u3067\u304d\u307e\u305b\u3093(\u539f\u56e0\u4e0d\u660e)\u3002 \ No newline at end of file + \u30d3\u30eb\u30c9\u3067\u304d\u307e\u305b\u3093(\u539f\u56e0\u4e0d\u660e)\u3002 +DeleteNodeCommand.ShortDescription=\u30ce\u30fc\u30c9\u3092\u524a\u9664\u3057\u307e\u3059\u3002 +DeleteJobCommand.ShortDescription=\u30b8\u30e7\u30d6\u3092\u524a\u9664\u3057\u307e\u3059\u3002 +OnlineNodeCommand.ShortDescription=\u76f4\u524d\u306b\u5b9f\u884c\u3057\u305f"online-node"\u30b3\u30de\u30f3\u30c9\u3092\u53d6\u308a\u6d88\u3057\u3001\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u30ce\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u518d\u958b\u3057\u307e\u3059\u3002 +ClearQueueCommand.ShortDescription=\u30d3\u30eb\u30c9\u30ad\u30e5\u30fc\u3092\u30af\u30ea\u30a2\u3057\u307e\u3059\u3002 +ReloadConfigurationCommand.ShortDescription=\u30e1\u30e2\u30ea\u306b\u3042\u308b\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u7834\u68c4\u3057\u3066\u3001\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u518d\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u76f4\u63a5\u4fee\u6b63\u3057\u305f\u5834\u5408\u306b\u5f79\u306b\u7acb\u3061\u307e\u3059\u3002 +ConnectNodeCommand.ShortDescription=\u30ce\u30fc\u30c9\u3068\u518d\u63a5\u7d9a\u3057\u307e\u3059\u3002 +DisconnectNodeCommand.ShortDescription=\u30ce\u30fc\u30c9\u3068\u306e\u63a5\u7d9a\u3092\u5207\u65ad\u3057\u307e\u3059\u3002 +QuietDownCommand.ShortDescription=Jenkins\u306f\u518d\u8d77\u52d5\u306b\u5411\u3051\u3066\u7d42\u4e86\u51e6\u7406\u3092\u5b9f\u65bd\u4e2d\u3067\u3059\u3002\u30d3\u30eb\u30c9\u3092\u958b\u59cb\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002 +CancelQuietDownCommand.ShortDescription="quiet-down"\u30b3\u30de\u30f3\u30c9\u306e\u51e6\u7406\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3059\u3002 +OfflineNodeCommand.ShortDescription="online-node"\u30b3\u30de\u30f3\u30c9\u304c\u5b9f\u884c\u3055\u308c\u308b\u307e\u3067\u3001\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u30ce\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u4e00\u6642\u7684\u306b\u505c\u6b62\u3057\u307e\u3059\u3002 +WaitNodeOnlineCommand.ShortDescription=\u30ce\u30fc\u30c9\u304c\u30aa\u30f3\u30e9\u30a4\u30f3\u306b\u306a\u308b\u306e\u3092\u5f85\u3061\u307e\u3059\u3002 +WaitNodeOfflineCommand.ShortDescription=\u30ce\u30fc\u30c9\u304c\u30aa\u30d5\u30e9\u30a4\u30f3\u306b\u306a\u308b\u306e\u3092\u5f85\u3061\u307e\u3059\u3002 + diff --git a/core/src/main/resources/hudson/cli/Messages_lt.properties b/core/src/main/resources/hudson/cli/Messages_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..f83756b5abb1eb4badd60e35e7d3d50f433ba0a3 --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_lt.properties @@ -0,0 +1,95 @@ +InstallPluginCommand.DidYouMean={0} pana\u0161us \u012f trump\u0105 priedo pavadinim\u0105. Gal tur\u0117jote omenyje \u201e{1}\u201c? +InstallPluginCommand.InstallingFromUpdateCenter={0} diegiamas i\u0161 atnaujinim\u0173 centro +InstallPluginCommand.InstallingPluginFromLocalFile=Priedas diegiamas i\u0161 vietinio failo: {0} +InstallPluginCommand.InstallingPluginFromUrl=Priedas diegiamas i\u0161 {0} +InstallPluginCommand.NoUpdateCenterDefined=Pasteb\u0117tina, kad \u0161iame Jenkinse n\u0117ra nurodytas nei vienas atnaujinimo centras. +InstallPluginCommand.NoUpdateDataRetrieved=Dar neatsi\u0173sta joki\u0173 atnaujinimo centro duomen\u0173 i\u0161: {0} +InstallPluginCommand.NotAValidSourceName={0} n\u0117ra nei tinkamas failas, nei URL, nei priedo rezultat\u0173 pavadinimas atnaujinimo centre + +AddJobToViewCommand.ShortDescription=\ + Prideda darbus \u012f rodin\u012f. +BuildCommand.ShortDescription=\ + Vykdo darb\u0105 ir, jei reikia, palaukia, kol vykdymas baigiamas. +ConsoleCommand.ShortDescription=I\u0161traukia vykdymo konsol\u0117s i\u0161vest\u012f. +CopyJobCommand.ShortDescription=Kopijuoja darb\u0105. +CreateJobCommand.ShortDescription=\ + Sukuria nauj\u0105 darb\u0105 skaitant stdin kaip konfig\u016bracin\u012f XML fail\u0105. +CreateNodeCommand.ShortDescription=\ + Sukuria nauja mazg\u0105 skaitant stdin kaip XML konfig\u016bracij\u0105. +CreateViewCommand.ShortDescription=\ + Creates a new view by reading stdin as a XML configuration. +DeleteBuildsCommand.ShortDescription=\ + I\u0161trina vykdymo \u012fra\u0161\u0105(-us). +DeleteViewCommand.ShortDescription=\ + I\u0161trina rodin\u012f(-ius). +DeleteJobCommand.ShortDescription=\ + I\u0161trina darb\u0105(-us). +GroovyCommand.ShortDescription=\ + Vykdo nurodyt\u0105 Groovy scenarij\u0173. +GroovyshCommand.ShortDescription=\ + Paleid\u017eia interaktyvi\u0105 groovy aplink\u0105. +HelpCommand.ShortDescription=\ + Rodo visas galima komandas arba detal\u0173 vienos komandos apra\u0161ym\u0105. +InstallPluginCommand.ShortDescription=\ + \u012ediegia prieda i\u0161 failo, URL arba i\u0161 atanaujinimo centro. +InstallToolCommand.ShortDescription=\ + Vykdo automatin\u012f \u012franki\u0173 diegim\u0105 ir spausdina jo viet\u0105 \u012f stdout. Gali b\u016bti kvie\u010diamas tik i\u0161 vykdymo vidaus. +ListChangesCommand.ShortDescription=\ + I\u0161krauna nurodyt\u0173 vykdym\u0173 pakeitim\u0173 s\u0105ra\u0161\u0105. +ListJobsCommand.ShortDescription=\ + Rodo visus darbus nurodytame rodinyje arba element\u0173 grup\u0117je. +ListPluginsCommand.ShortDescription=\ + Spausdina \u012fdiegt\u0173 pried\u0173 s\u0105ra\u0161\u0105. +LoginCommand.ShortDescription=\ + \u012era\u0161o dabartinius prisijungimo duomenis, kad ateityje komandas b\u016bt\u0173 galima vykdyti be i\u0161skirtin\u0117s prisijungimo duomen\u0173 informacijos. +LogoutCommand.ShortDescription=\ + I\u0161trina prisijungimo duomenis, \u012fra\u0161ytus su prisijungimo komanda. +MailCommand.ShortDescription=\ + Skaito stdin ir i\u0161siun\u010dia kaip e-pa\u0161t\u0105. +SetBuildDescriptionCommand.ShortDescription=\ + Nustato vykdymo apra\u0161ym\u0105. +SetBuildParameterCommand.ShortDescription=Keisti/nurodyti dabar vykdomo vykdymo parametr\u0105. +SetBuildResultCommand.ShortDescription=\ + Nurodo dabartinio vykdymo rezultat\u0105. Veikia tik paleidus vykdymo viduje. +RemoveJobFromViewCommand.ShortDescription=\ + I\u0161ima darbus i\u0161 rodinio. +VersionCommand.ShortDescription=\ + Spausdina dabartin\u0119 versij\u0105. +GetJobCommand.ShortDescription=\ + Spausdina darbo apra\u0161ymo XML \u012f stdout. +GetNodeCommand.ShortDescription=\ + Spausdina mazgo apra\u0161ymo XML \u012f stdout. +GetViewCommand.ShortDescription=\ + Spausdina rodinio apra\u0161ymo XML \u012f stdout. +SetBuildDisplayNameCommand.ShortDescription=\ + Nurodo vykdymo rodom\u0105 pavadinim\u0105. +WhoAmICommand.ShortDescription=\ + J\u016bs\u0173 prisijungimo duomen\u0173 ir teisi\u0173 ataskaita. +UpdateJobCommand.ShortDescription=\ + Atnaujina darbo apra\u0161ymo XML i\u0161 stdin. Prie\u0161ingas komandai \u201eget-job\u201c. +UpdateNodeCommand.ShortDescription=\ + Atnaujina mazgo apra\u0161ymo XML i\u0161 stdin. Prie\u0161ingas komandai \u201eget-node\u201c. +SessionIdCommand.ShortDescription=Spausdina sesijos ID, kuris pasikei\u010dia kiekvien\u0105 kart\u0105 i\u0161 naujo paleidus Jenkins'\u0105. +UpdateViewCommand.ShortDescription=\ + Atnaujina rodinio apra\u0161ymo XML i\u0161 stdin. Prie\u0161ingas komandai \u201eget-view\u201c. + +BuildCommand.CLICause.ShortDescription=I\u0161 komandin\u0117s eilut\u0117s paleido {0} +BuildCommand.CLICause.CannotBuildDisabled=\ +Negalima vykdyti {0}, nes jis i\u0161jungtas. +BuildCommand.CLICause.CannotBuildConfigNotSaved=\ +Negalima vykdyti {0}, nes jo konfig\u016bracija nebuvo \u012fra\u0161yta. +BuildCommand.CLICause.CannotBuildUnknownReasons=\ +Negalima vykdyti {0} d\u0117l ne\u017einom\u0173 prie\u017eas\u010di\u0173. + +DeleteNodeCommand.ShortDescription=Trina mazg\u0105(-us) +ReloadJobCommand.ShortDescription=I\u0161 naujo \u012fkelti darb\u0105(-us) +OnlineNodeCommand.ShortDescription=V\u0117l naudoti mazg\u0105 vykdymams, atjungiant ankstesn\u012f re\u017eim\u0105 \u201eatsijung\u0119s\u201c. +ClearQueueCommand.ShortDescription=Valo vykdymo eil\u0119. +ReloadConfigurationCommand.ShortDescription=I\u0161mesti visus atminties duomenis ir visk\u0105 \u012fkelti i\u0161 fail\u0173 sistemos. Naudinga, jei konfig\u016bracinius failus keit\u0117te tiesiai diske. +DisconnectNodeCommand.ShortDescription=Atsijungia nuo mazgo. +QuietDownCommand.ShortDescription=Tyliai nuleisti Jenkins\u0105, pasiruo\u0161iant paleidimui i\u0161 naujo. Neprad\u0117ti joki\u0173 vykdym\u0173. +CancelQuietDownCommand.ShortDescription=Nutraukti \u201etylaus i\u0161jungimo\u201c komandos efekt\u0105. +OfflineNodeCommand.ShortDescription=Laikinai nebenaudoti mazgo darb\u0173 vykdymui, kol bus \u012fvykdyta kita \u201emazgas \u012fjungtas\u201c komanda. +WaitNodeOnlineCommand.ShortDescription=Laukti, kol mazgas prisijungs. +WaitNodeOfflineCommand.ShortDescription=Laukti, kol mazgas atsijungs. + diff --git a/core/src/main/resources/hudson/cli/Messages_pt_BR.properties b/core/src/main/resources/hudson/cli/Messages_pt_BR.properties index 007038f34b8275742e361079a317f772816391a4..7965b0b7e10de3cc2f6bbdef93806efc09f65a28 100644 --- a/core/src/main/resources/hudson/cli/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/cli/Messages_pt_BR.properties @@ -110,3 +110,21 @@ SessionIdCommand.ShortDescription=Exibe o ID de sess\u00e3o, que muda toda vez q InstallPluginCommand.InstallingPluginFromUrl=Instalando um plugin de {0} # Installs a plugin either from a file, an URL, or from update center. InstallPluginCommand.ShortDescription=Instala um plugin a partir de um arquivo, uma URL, ou da central de atualiza\u00e7\u00f5es. + +# Deletes a node +CLI.delete-node.shortDescription=Remover o n\u00f3 +# Deletes a job +DeleteJobCommand.ShortDescription=Remover uma job(s) +ReloadJobCommand.ShortDescription=Recarrega job(s) do disco. +OnlineNodeCommand.ShortDescription=Continuar usando um n\u00f3 para realizar os builds +ClearQueueCommand.ShortDescription=Limpa a fila de builds +ReloadConfigurationCommand.ShortDescription=Descarta todo o conte\u00fado de mem\u00f3ria e recarrega novamente a partir do arquivo. \ +Indicado quando voc\u00ea modificou os arquivos diretamente no disco. +ConnectNodeCommand.ShortDescription=Reconectar ao n\u00f3 +DisconnectNodeCommand.ShortDescription=Desconectar do n\u00f3 +QuietDownCommand.ShortDescription=Desativar em modo silencioso, em prepara\u00e7\u00e3o para o rein\u00edcio. N\u00e3o come\u00e7e nenhum build. +CancelQuietDownCommand.ShortDescription=Cancela o comando "quiet-down" +OfflineNodeCommand.ShortDescription=Temporariamente n\u00e3o usando um n\u00f3 para os builds. Aguardando o pr\u00f3ximo comando de modo-online +WaitNodeOnlineCommand.ShortDescription=Aguarda por um n\u00f3 que se torne online +WaitNodeOfflineCommand.ShortDescription=Aguarde por um n\u00f3 ficar offline. + diff --git a/core/src/main/resources/hudson/cli/Messages_sr.properties b/core/src/main/resources/hudson/cli/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a504742d83a470fcfbe23593087db7f45f73ac03 --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_sr.properties @@ -0,0 +1,68 @@ +# This file is under the MIT License by authors + +InstallPluginCommand.DidYouMean={0} \u043B\u0438\u0447\u0438 \u043D\u0430 \u043A\u0440\u0430\u0442\u043A\u043E \u0438\u043C\u0435 \u0437\u0430 \u043C\u043E\u0434\u0443\u043B\u0443. \u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u043C\u0438\u0441\u043B\u0438\u043B\u0438 \u2018{1}\u2019? +InstallPluginCommand.InstallingFromUpdateCenter=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u045A\u0435 "{0}" \u0441\u0430 \u0446\u0435\u043D\u0442\u0440\u0430 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0430\u045A\u0430 +InstallPluginCommand.InstallingPluginFromLocalFile=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u0441\u0430 \u043B\u043E\u043A\u0430\u043B\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 "{0}" +InstallPluginCommand.InstallingPluginFromUrl=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u045A\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u0441\u0430 {0} +InstallPluginCommand.NoUpdateCenterDefined=\u041D\u0438\u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D \u0441\u0430\u0458\u0442 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 \u0443 \u043E\u0432\u043E\u0458 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0438 Jenkins. +InstallPluginCommand.NoUpdateDataRetrieved=\ \u041D\u0438\u0441\u0443 \u0458\u043E\u0448 \u043F\u0440\u0435\u0443\u0437\u0435\u0442\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 \u0438\u0437 \u0446\u0435\u043D\u0442\u0440\u0430 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435: {0} +InstallPluginCommand.NotAValidSourceName="{0}" \u043D\u0438\u0458\u0435 \u043D\u0438 \u0438\u043C\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435, URL \u0430\u0434\u0440\u0435\u0441\u0430, \u043D\u0438\u0442\u0438 \u0438\u043C\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043D\u0430 \u0446\u0435\u043D\u0442\u0440\u0443 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +AddJobToViewCommand.ShortDescription=\u041F\u0440\u0438\u043A\u0430\u0436\u0438 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0443 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0443 +BuildCommand.ShortDescription=\ \u041F\u043E\u043A\u0440\u0435\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 \u0438 \u043E\u043F\u0446\u0438\u043E\u043D\u043E \u0447\u0435\u043A\u0430 \u0437\u0430 \u045A\u0435\u0433\u043E\u0432 \u0437\u0430\u0432\u0440\u0448\u0435\u0442\u0430\u043A +ConsoleCommand.ShortDescription=\u041F\u0440\u0435\u0443\u0437\u043C\u0435 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +CopyJobCommand.ShortDescription=\u0418\u0441\u043A\u043E\u043F\u0438\u0440\u0430 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +CreateJobCommand.ShortDescription=\u041A\u0440\u0435\u0438\u0440\u0430 \u043D\u043E\u0432\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0447\u0438\u0442\u0430\u0458\u0443\u045B\u0438 stdin \u043A\u0430\u043E \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043E\u043D\u0443 XML \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 +CreateNodeCommand.ShortDescription=\u041A\u0440\u0435\u0438\u0440\u0430 \u043D\u043E\u0432\u0443 \u043C\u0430\u0448\u0438\u043D\u0443 \u0447\u0438\u0442\u0430\u0458\u0443\u045B\u0438 stdin \u043A\u0430\u043E \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043E\u043D\u0443 XML \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 +CreateViewCommand.ShortDescription=\u041A\u0440\u0435\u0438\u0440\u0430 \u043D\u043E\u0432\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 \u0447\u0438\u0442\u0430\u0458\u0443\u045B\u0438 stdin \u043A\u0430\u043E \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043E\u043D\u0443 XML \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 +DeleteBuildsCommand.ShortDescription=\u0418\u0437\u0431\u0440\u0438\u0448\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438 +DeleteViewCommand.ShortDescription=\u0418\u0437\u0431\u0440\u0438\u0448\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +DeleteJobCommand.ShortDescription=\u0418\u0437\u0431\u0440\u0438\u0448\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +GroovyCommand.ShortDescription=\u0418\u0437\u0432\u0440\u0448\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D Groovy \u043F\u0440\u043E\u0433\u0440\u0430\u043C +GroovyshCommand.ShortDescription=\u041F\u043E\u043A\u0440\u0435\u043D\u0435 \u0438\u043D\u0442\u0435\u0440\u0430\u043A\u0442\u0438\u0432\u0430\u043D \u0438\u043D\u0442\u0435\u0440\u043F\u0440\u0435\u0442\u0430\u0442\u043E\u0440 \u0437\u0430 Groovy +HelpCommand.ShortDescription=\u0418\u0441\u043F\u0438\u0448\u0435 \u0441\u0432\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \u0438\u043B\u0438 \u0434\u0435\u0442\u0430\u0459\u043D\u0438 \u043E\u043F\u0438\u0441 \u043E\u0434\u0440\u0435\u0452\u0435\u043D\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435. +InstallPluginCommand.ShortDescription=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430 \u043C\u043E\u0434\u0443\u043B\u0443 \u0441\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435, URL \u0430\u0434\u0440\u0435\u0441\u0435, \u0438\u043B\u0438 \u0446\u0435\u043D\u0442\u0440\u0430 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435. +InstallToolCommand.ShortDescription=\u0410\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430 \u0430\u043B\u0430\u0442 \u0438 \u043F\u0440\u0438\u043A\u0430\u0436\u0435 \u045A\u0435\u0433\u043E\u0432\u0443 \u043B\u043E\u043A\u0430\u0446\u0438\u0458\u0438 \u043D\u0430 stdout. \u041C\u043E\u0436\u0435 \u0441\u0430\u043C\u043E \u0431\u0438\u0442\u0438 \u043F\u043E\u0437\u0432\u0430\u043D \u0443\u043D\u0443\u0442\u0430\u0440 \u0437\u0430\u0434\u0430\u0442\u043A\u043E\u043C. +ListChangesCommand.ShortDescription=\u041F\u0440\u0438\u043A\u0430\u0436\u0435 \u0434\u043D\u0435\u0432\u043D\u0438\u043A \u0438\u0437\u043C\u0435\u043D\u0430 \u0437\u0430 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u045A\u0430. +ListJobsCommand.ShortDescription=\u041F\u0440\u0438\u043A\u0430\u0436\u0435 \u0441\u0432\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u043E\u0434\u0440\u0435\u0452\u0435\u043D\u0435 \u0432\u0440\u0441\u0442\u0435 \u0438\u043B\u0438 \u0433\u0440\u0443\u043F\u0435. +ListPluginsCommand.ShortDescription=\u041F\u0440\u0438\u043A\u0430\u0436\u0435 \u0441\u043F\u0438\u0441\u0430\u043A \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430. +LoginCommand.ShortDescription=\u0421\u0430\u0447\u0443\u0432\u0430 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0458\u0443, \u0434\u0430 \u0431\u0438 \u043D\u0430\u043A\u043D\u0430\u0434\u043D\u0438 \u0437\u0430\u0434\u0430\u0446\u0438 \u043C\u043E\u045B\u0438 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u0431\u0435\u0437 \u043F\u043E\u043D\u043E\u0432\u0443 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0458\u0443. +LogoutCommand.ShortDescription=\u0418\u0437\u0431\u0440\u0438\u0448\u0435 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0458\u0443 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u043E \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u043F\u0440\u0438\u0458\u0430\u0432\u0435. +MailCommand.ShortDescription=\u0418\u0437\u0447\u0438\u0442\u0430 stdin \u0438 \u043F\u043E\u0448\u0430\u0459\u0435 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u043F\u0440\u0435\u043A\u043E \u0435-\u043F\u043E\u0448\u0442\u0435. +SetBuildParameterCommand.ShortDescription=\u0423\u0440\u0435\u0452\u0438\u0432\u0430\u045A\u0435/\u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0430\u045A\u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440\u0430 \u043D\u0430 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438. +SetBuildDescriptionCommand.ShortDescription=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u043E\u043F\u0438\u0441 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +SetBuildResultCommand.ShortDescription=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442 \u043D\u0430 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443. \u041C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043F\u043E\u0437\u0432\u0430\u043D\u043E \u0441\u0430\u043C\u043E \u0443\u043D\u0443\u0442\u0430\u0440 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. +RemoveJobFromViewCommand.ShortDescription=\u0423\u043A\u043B\u043E\u043D\u0438 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0441\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 +VersionCommand.ShortDescription=\u041F\u0440\u0438\u043A\u0430\u0436\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 Jenkins. +GetJobCommand.ShortDescription=\u0418\u0441\u043F\u0438\u0448\u0435 \u0434\u0435\u0444\u0438\u043D\u0438\u0446\u0438\u0458\u0443 \u0437\u0430\u0434\u0430\u0442\u043A\u0430 \u0443 XML \u0444\u043E\u0440\u043C\u0430\u0442\u0443 \u043D\u0430 stdout. +GetNodeCommand.ShortDescription=\u0418\u0441\u043F\u0438\u0448\u0435 \u0434\u0435\u0444\u0438\u043D\u0438\u0446\u0438\u0458\u0443 \u043C\u0430\u0448\u0438\u043D\u0435 \u0443 XML \u0444\u043E\u0440\u043C\u0430\u0442\u0443 \u043D\u0430 stdout. +GetViewCommand.ShortDescription=\u0418\u0441\u043F\u0438\u0448\u0435 \u0434\u0435\u0444\u0438\u043D\u0438\u0446\u0438\u0458\u0443 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \u0443 XML \u0444\u043E\u0440\u043C\u0430\u0442\u0443 \u043D\u0430 stdout. +SetBuildDisplayNameCommand.ShortDescription=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u0438\u043C\u0435 (displayName) \u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438. +WhoAmICommand.ShortDescription=\u0418\u0437\u0432\u0435\u0448\u0442\u0430je \u0432\u0430\u0448\u0435 \u0430\u043A\u0440\u0435\u0434\u0438\u0442\u0438\u0432\u0435 \u0438 \u043F\u0440\u0430\u0432\u0430. +UpdateJobCommand.ShortDescription=\u0410\u0436\u0443\u0440\u0438\u0440\u0430 XML \u0434\u0435\u0444\u0438\u043D\u0438\u0446\u0438\u0458\u0443 \u0437\u0430\u0434\u0430\u0442\u043A\u0430 \u0438\u0437 stdin, \u0437\u0430 \u0440\u0430\u0437\u043B\u0438\u043A\u0443 \u043E\u0434 get-job \u043A\u043E\u043C\u0430\u043D\u0434\u0435. +UpdateNodeCommand.ShortDescription=\u0410\u0436\u0443\u0440\u0438\u0440\u0430 XML \u0434\u0435\u0444\u0438\u043D\u0438\u0446\u0438\u0458\u0443 \u043C\u0430\u0448\u0438\u043D\u0435 \u0438\u0437 stdin, \u0437\u0430 \u0440\u0430\u0437\u043B\u0438\u043A\u0443 \u043E\u0434 get-node \u043A\u043E\u043C\u0430\u043D\u0434\u0435. +SessionIdCommand.ShortDescription=\u0418\u0437\u0458\u0430\u0432\u0438 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u0430 \u0441\u0435\u0441\u0438\u0458\u0435, \u0448\u0442\u043E \u0441\u0435 \u043C\u0435\u045A\u0430 \u0441\u0432\u0430\u043A\u0438 \u043F\u0443\u0442 \u043A\u0430\u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 Jenkins. +UpdateViewCommand.ShortDescription=\u0410\u0436\u0443\u0440\u0438\u0440\u0430 XML \u0434\u0435\u0444\u0438\u043D\u0438\u0446\u0438\u0458\u0443 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \u0438\u0437 stdin, \u0437\u0430 \u0440\u0430\u0437\u043B\u0438\u043A\u0443 \u043E\u0434 get-view \u043A\u043E\u043C\u0430\u043D\u0434\u0435. +BuildCommand.CLICause.ShortDescription=\u0417\u0430\u0434\u0430\u0442\u0430\u043A \u0458\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u043F\u0440\u0435\u043A\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043E\u043C "{0}" +BuildCommand.CLICause.CannotBuildDisabled=\ +\u041D\u0435 \u043C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A "{0}" \u0437\u0430\u0448\u0442\u043E \u0458\u0435 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u043E. +BuildCommand.CLICause.CannotBuildConfigNotSaved=\ +\u041D\u0435 \u043C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A "{0}" \u0437\u0430\u0448\u0442\u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u043D\u0438\u0441\u0443 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0430. +BuildCommand.CLICause.CannotBuildUnknownReasons=\ +\u041D\u0435 \u043C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A "{0}" \u0437\u0431\u043E\u0433 \u043D\u0435\u043F\u043E\u0437\u043D\u0430\u0442\u043E\u0433 \u0440\u0430\u0437\u043B\u043E\u0433\u0430. +DeleteNodeCommand.ShortDescription=\ +\u0423\u043A\u043B\u043E\u043D\u0438 \u043C\u0430\u0448\u0438\u043D\u0443 +ReloadJobCommand.ShortDescription=\ +\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u0440\u0435\u0443\u0437\u043C\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 +OnlineNodeCommand.ShortDescription=\u041D\u0430\u0441\u0442\u0430\u0432\u0438 \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443, \u0448\u0442\u043E \u043F\u043E\u043D\u0438\u0448\u0442\u0430\u0432\u0430 \u043F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u0443 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 "offline-node". +ClearQueueCommand.ShortDescription=\u0418\u0437\u0431\u0440\u0438\u0448\u0435 \u0437\u0430\u043A\u0430\u0437\u0430\u043D\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0435. +ReloadConfigurationCommand.ShortDescription=\u041E\u0434\u0431\u0430\u0446\u0438 \u0441\u0432\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u0443 \u043C\u0435\u043C\u043E\u0440\u0438\u0458\u0438, \u0438 \u043F\u043E\u043D\u043E \u0443\u0447\u0438\u0442\u0430\u0458 \u0441\u0432\u0435 \u0438\u0437 \u0434\u0430\u0442\u043E\u0442\u0435\u0447\u043D\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430. \u041A\u043E\u0440\u0438\u0441\u043D\u043E \u043A\u0430\u0434 \u0441\u0442\u0435 \u043C\u0435\u045A\u0430\u043B\u0438 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043D\u043E. +ConnectNodeCommand.ShortDescription=\u041F\u043E\u043D\u043E\u0432\u043E \u0441\u0435 \u043F\u043E\u0432\u0435\u0436\u0438\u0442\u0435 \u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0443 +QuietDownCommand.ShortDescription=\u041F\u0440\u0438\u043F\u0440\u0435\u043C\u0438 Jenkins \u0437\u0430 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435. \u041D\u0438\u0441\u0443 \u0434\u043E\u0437\u0432\u043E\u0459\u0435\u043D\u0430 \u043D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430. +DisconnectNodeCommand.ShortDescription=\u041F\u0440\u0435\u043A\u0438\u043D\u0435 \u0432\u0435\u0437\u0443 \u0441\u0430 \u043C\u0430\u0448\u0438\u043D\u043E\u043C. +CancelQuietDownCommand.ShortDescription=\u041F\u043E\u043D\u0438\u0448\u0442\u0438 \u043C\u0435\u0440\u0435 \u043F\u043E\u0447\u0435\u0442\u0435 \u0437\u0430 \u043F\u0440\u0438\u043F\u0440\u0435\u043C\u0443 \u043F\u043E\u043D\u043E\u0432\u043E\u0433 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430. +OfflineNodeCommand.ShortDescription=\u0421\u0443\u0441\u043F\u0435\u043D\u0437\u0438\u0458\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0434\u043E \u0441\u043B\u0435\u0434\u0435\u045B\u0435 "online-node" \u043A\u043E\u043C\u0430\u043D\u0434\u0435. +WaitNodeOnlineCommand.ShortDescription=\u0421\u0430\u0447\u0435\u043A\u0430\u0458 \u0434\u043E\u043A \u043D\u0435\u043A\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0431\u0443\u0434\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430. +WaitNodeOfflineCommand.ShortDescription=\u0421\u0430\u0447\u0435\u043A\u0430\u0458 \u0434\u043E\u043A \u043D\u0435\u043A\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0431\u0443\u0434\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430. +CliProtocol.displayName=\u041F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u0437\u0430 Jenkins \u043F\u0440\u0435\u043A\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435, \u0432\u0435\u0440\u0437\u0438\u0458\u0430 1 +CliProtocol2.displayName=\u041F\u0440\u043E\u0442\u043E\u043A\u043E\u043B \u0437\u0430 Jenkins \u043F\u0440\u0435\u043A\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435, \u0432\u0435\u0440\u0437\u0438\u0458\u0430 2 +CLI.delete-node.shortDescription=\u0423\u043A\u043B\u043E\u043D\u0438 \u043C\u0430\u0448\u0438\u043D\u0443 \ No newline at end of file diff --git a/core/src/main/resources/hudson/cli/Messages_zh_CN.properties b/core/src/main/resources/hudson/cli/Messages_zh_CN.properties new file mode 100644 index 0000000000000000000000000000000000000000..c767020ed348c46f519a74942afe15d6028ea4cf --- /dev/null +++ b/core/src/main/resources/hudson/cli/Messages_zh_CN.properties @@ -0,0 +1,10 @@ +DeleteNodeCommand.ShortDescription=Deletes a node +DeleteJobCommand.ShortDescription=Deletes a job + +ClearQueueCommand.ShortDescription=Clears the build queue +ReloadConfigurationCommand.ShortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk. +ConnectNodeCommand.ShortDescription=Reconnect to a node +QuietDownCommand.ShortDescription=Quiet down Jenkins, in preparation for a restart. Don''t start any builds. +CancelQuietDownCommand.ShortDescription=Cancel the effect of the "quiet-down" command. +OfflineNodeCommand.ShortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command. + diff --git a/core/src/main/resources/hudson/cli/Messages_zh_TW.properties b/core/src/main/resources/hudson/cli/Messages_zh_TW.properties index 0cf6f8ec1827d85f589883432376fa19127a50fe..b2e5746b7a87145aea16f2d41b7c624102b6cae9 100644 --- a/core/src/main/resources/hudson/cli/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/cli/Messages_zh_TW.properties @@ -72,3 +72,16 @@ WhoAmICommand.ShortDescription=\ UpdateJobCommand.ShortDescription=\ \u7531 stdin \u66f4\u65b0\u4f5c\u696d\u5b9a\u7fa9 XML\u3002get-job \u6307\u4ee4\u7684\u76f8\u53cd BuildCommand.CLICause.ShortDescription=\u7531 {0} \u7684\u547d\u4ee4\u5217\u4ecb\u9762\u555f\u52d5 + +DeleteNodeCommand.ShortDescription=\u522a\u9664\u6307\u5b9a\u7bc0\u9ede\u3002 +DeleteJobCommand.ShortDescription=\u522a\u9664\u4f5c\u696d\u3002 +ClearQueueCommand.ShortDescription=\u6e05\u9664\u5efa\u7f6e\u4f47\u5217\u3002 +DisconnectNodeCommand.ShortDescription=\u4e2d\u65b7\u8207\u6307\u5b9a\u7bc0\u9ede\u7684\u9023\u7dda\u3002 +ReloadConfigurationCommand.ShortDescription=\u653e\u68c4\u6240\u6709\u8a18\u61b6\u9ad4\u88e1\u7684\u8cc7\u6599\uff0c\u7531\u6a94\u6848\u7cfb\u7d71\u4e2d\u91cd\u65b0\u8f09\u5165\u3002\u9069\u5408\u5728\u76f4\u63a5\u4fee\u6539\u8a2d\u5b9a\u6a94\u5f8c\u4f7f\u7528\u3002 +ConnectNodeCommand.ShortDescription=\u9023\u7dda\u5230\u6307\u5b9a\u7bc0\u9ede\u3002 +QuietDownCommand.ShortDescription=\u8b93 Jenkins \u6c89\u6fb1\u4e00\u4e0b\uff0c\u6e96\u5099\u91cd\u65b0\u555f\u52d5\u3002\u5148\u4e0d\u8981\u518d\u5efa\u7f6e\u4efb\u4f55\u4f5c\u696d\u3002 +CancelQuietDownCommand.ShortDescription=\u53d6\u6d88 "quiet-down" \u6307\u4ee4\u3002 +OfflineNodeCommand.ShortDescription=\u66ab\u6642\u4e0d\u4f7f\u7528\u6307\u5b9a\u7bc0\u9ede\u4f86\u5efa\u7f6e\uff0c\u76f4\u5230\u57f7\u884c "online-node" \u6307\u4ee4\u70ba\u6b62\u3002 +WaitNodeOnlineCommand.ShortDescription=\u7b49\u5019\u6307\u5b9a\u7bc0\u9ede\u4e0a\u7dda\u3002 +WaitNodeOfflineCommand.ShortDescription=\u7b49\u5019\u6307\u5b9a\u7bc0\u9ede\u96e2\u7dda\u3002 + diff --git a/core/src/main/resources/hudson/diagnosis/HudsonHomeDiskUsageMonitor/index_sr.properties b/core/src/main/resources/hudson/diagnosis/HudsonHomeDiskUsageMonitor/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2208ac4a5807e56b9579a9ea9fc8c6c990d6c6a7 --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/HudsonHomeDiskUsageMonitor/index_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +JENKINS_HOME\ is\ almost\ full=JENKINS_HOME \u0458\u0435 \u0441\u043A\u043E\u0440\u043E \u043F\u0440\u0435\u043F\u0443\u043D\u043E +blurb=JENKINS_HOME \u0458\u0435 \u0441\u043A\u043E\u0440\u043E \u043F\u0440\u0435\u043F\u0443\u043D\u043E +description.1=\ \u0412\u0430\u0448 JENKINS_HOME ({0}) \u0458\u0435 \u0441\u043A\u043E\u0440\u043E \u043F\u0440\u0435\u043F\u0443\u043D. \ + \u041A\u0430\u0434 \u0441\u0435 \u0441\u043A\u0440\u043E\u0437 \u043D\u0430\u043F\u0443\u043D\u0438 \u043E\u0432\u0430\u0458 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0443\u043C, Jenkins \u043D\u0435\u045B\u0435 \u043C\u043E\u045B\u0438 \u043F\u0438\u0441\u0430\u0442\u0438 \u0432\u0438\u0448\u0435 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430. +description.2=\u0414\u0430 \u0431\u0438 \u0441\u0435 \u0441\u043F\u0440\u0435\u0447\u0438\u043E \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0431\u043B\u0435\u043C, \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0458\u0435 \u0434\u0435\u043B\u043E\u0432\u0430\u0442\u0438 \u043E\u0434\u043C\u0430\u0445. +solution.1=\u041E\u0431\u0440\u0438\u0448\u0435\u0442\u0435 \u043D\u0435\u043A\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0441\u0430 \u043E\u0432\u0435 \u043F\u0430\u0440\u0442\u0438\u0446\u0438\u0458\u0435 \u0434\u0430 \u0431\u0438 \u0441\u0435 \u043E\u0441\u043B\u043E\u0431\u043E\u0434\u0438\u043B\u043E \u043C\u0435\u0441\u0442\u0430. +solution.2=\ +\u041F\u0440\u0435\u0431\u0430\u0446\u0438\u0442\u0435 <\u0422\u0422>JENKINS_HOME \u0432\u0435\u045B\u043E\u0458 \u043F\u0430\u0440\u0442\u0438\u0446\u0438\u0458\u0438.\ +\u041F\u043E\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 <\u0430 href="http://wiki.jenkins-ci.org/display/JENKINS/Administering+\u040F\u0435\u043D\u043A\u0438\u043D\u0441">\u0412\u0438\u043A\u0438 \u0442\u043E\u043C\u0435 \u043A\u0430\u043A\u043E \u0434\u0430 \u0442\u043E \u0443\u0440\u0430\u0434\u0438\u0442\u0438. +Dit= diff --git a/core/src/main/resources/hudson/diagnosis/HudsonHomeDiskUsageMonitor/message_sr.properties b/core/src/main/resources/hudson/diagnosis/HudsonHomeDiskUsageMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7f5e6eac953ef5209644aa251862868efe393500 --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/HudsonHomeDiskUsageMonitor/message_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Tell\ me\ more=\u041E\u0431\u0458\u0430\u0441\u043D\u0438 +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 +blurb=\u0412\u0430\u0448 Jenkins \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C "{0}" (<\u0422\u0422>JENKINS_HOME) \u0458\u0435 \u0441\u043A\u043E\u0440\u043E \u043F\u0440\u0435\u043F\u0443\u043D. \u0414\u0435\u043B\u0443\u0458\u0442\u0435 \u043F\u0440\u0435 \u043D\u0435\u0433\u043E \u0448\u0442\u043E \u0458\u0435 \u0441\u043A\u0440\u043E\u0437 \u043F\u0440\u0435\u043F\u0443\u043D. diff --git a/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index_sr.properties b/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1f7374f74686531c8b44e1bb9f92c0138aef1c27 --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/MemoryUsageMonitor/index_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +JVM\ Memory\ Usage=\u0423\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u043C\u0435\u043C\u043E\u0440\u0438\u0458\u0435 Java \u0432\u0438\u0440\u0442\u0443\u0435\u043B\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 +Timespan=\u0412\u0440\u0435\u043C\u0435 +Short=\u041A\u0440\u0430\u0442\u043A\u043E +Medium=\u0421\u0440\u0435\u0434\u045A\u0435 +Long=\u0414\u0443\u0433\u043E diff --git a/core/src/main/resources/hudson/diagnosis/Messages.properties b/core/src/main/resources/hudson/diagnosis/Messages.properties index b2e56afd7140e9854ac6dad38b3163939aad714b..06c38a572e012970f2403d6876b982d8ca9a618c 100644 --- a/core/src/main/resources/hudson/diagnosis/Messages.properties +++ b/core/src/main/resources/hudson/diagnosis/Messages.properties @@ -3,3 +3,7 @@ MemoryUsageMonitor.TOTAL=Total OldDataMonitor.Description=Scrub configuration files to remove remnants from old plugins and earlier versions. OldDataMonitor.DisplayName=Manage Old Data HudsonHomeDiskUsageMonitor.DisplayName=Disk Usage Monitor + +NullIdDescriptorMonitor.DisplayName=Missing Descriptor ID +ReverseProxySetupMonitor.DisplayName=Reverse Proxy Setup +TooManyJobsButNoView.DisplayName=Too Many Jobs Not Organized in Views diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ru.properties b/core/src/main/resources/hudson/diagnosis/Messages_bg.properties similarity index 51% rename from core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ru.properties rename to core/src/main/resources/hudson/diagnosis/Messages_bg.properties index 18216dc92a4f55190b4e43aa77240f98f49a7824..1a3ea6cfade1dc525ce73d04cc73991dbc9ed880 100644 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ru.properties +++ b/core/src/main/resources/hudson/diagnosis/Messages_bg.properties @@ -1,17 +1,17 @@ # The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Mike Salnikov -# +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -20,6 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -body=\u042d\u0442\u043e - \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u0437\u0430\u0434\u0430\u0447 \u0432 Jenkins. \ - Jenkins \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f \u043b\u044e\u0431\u0443\u044e SCM \u0441 \u043b\u044e\u0431\u043e\u0439 \u0441\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439. \ - \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447, \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 \u041f\u041e. +MemoryUsageMonitor.USED=\ + \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0438 +MemoryUsageMonitor.TOTAL=\ + \u041e\u0431\u0449\u043e +OldDataMonitor.Description=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0447\u0438\u0441\u0442\u044f\u0442 \u043e\u0441\u0442\u0430\u0442\u044a\u0446\u0438\u0442\u0435 \u043e\u0442 \u0441\u0442\u0430\u0440\u0438\ + \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0438 \u0432\u0435\u0440\u0441\u0438\u0438. +OldDataMonitor.DisplayName=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0442\u0430\u0440\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0438 +HudsonHomeDiskUsageMonitor.DisplayName=\ + \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u043e \u0434\u0438\u0441\u043a\u043e\u0432\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e diff --git a/core/src/main/resources/hudson/diagnosis/Messages_sr.properties b/core/src/main/resources/hudson/diagnosis/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b070f89027135acfd4e46480f60e8b2473811c3a --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/Messages_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authorsMemoryUsageMonitor.USED=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 + +MemoryUsageMonitor.TOTAL=\u0423\u043A\u0443\u043F\u043D\u043E +OldDataMonitor.Description=\u0418\u0437\u0431\u0440\u0438\u0448\u0438\u0442\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0434\u0430 \u0431\u0438\u0441\u0442\u0435 \u0443\u043A\u043B\u043E\u043D\u0438\u043B\u0438 \u0441\u0432\u0435 \u043E\u0441\u0442\u0430\u0442\u043A\u0435 \u043E\u0434 \u0441\u0442\u0430\u0440\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430 \u0438 \u0432\u0435\u0440\u0437\u0438\u0458\u0430. +OldDataMonitor.DisplayName=\u0423\u0440\u0435\u0434\u0438 \u0441\u0442\u0430\u0440\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/diagnosis/NullIdDescriptorMonitor/message_sr.properties b/core/src/main/resources/hudson/diagnosis/NullIdDescriptorMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..352d8fc5cf003dfb6a79aaba3a2c35fe0f3ea88a --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/NullIdDescriptorMonitor/message_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +blurb=\u0421\u043B\u0435\u0434\u0435\u045B\u0438 \u0434\u043E\u0434\u0430\u0446\u0438 \u043D\u0435\u043C\u0430\u0458\u0443 \u0418\u0414 \u0438 \u0442\u0430\u043A\u043E, \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E, \u0443\u0437\u0440\u043E\u043A \u043D\u0435\u043A\u043E\u0433 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u0458\u0442\u0435 \u043E\u0432\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u0430\u043A\u043E \u043D\u0438\u0441\u0443 \u043F\u043E\u0441\u043B\u0435\u0434\u045A\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0435. \u0410\u043A\u043E \u0432\u0435\u045B \u0458\u0435\u0441\u0443 \u043F\u043E\u0441\u043B\u0435\u0434\u045A\u0435, \u0434\u0430\u0458\u0442\u0435 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458 \u043E \u0433\u0440\u0435\u0448\u043A\u0430\u043C\u0430 \u0434\u0430 \u043C\u043E\u0436\u0435\u043C\u043E \u0434\u0430 \u0438\u0445 \u0438\u0441\u043F\u0440\u0430\u0432\u0438\u043C\u043E. +problem=\u0414\u0435\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0440 {0} \u0438\u0437 \u043C\u043E\u0434\u0443\u043B\u0435 {2} \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C {1} diff --git a/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_de.properties b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_de.properties index 9834cb21d567d8e20ad2696d53cb2445c00942d2..c180eae1c854ef762a824d28132ff56856ceb242 100644 --- a/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_de.properties +++ b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_de.properties @@ -1,66 +1,66 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Alan Harder, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Error=Fehler -Manage\ Old\ Data=Veraltete Daten verwalten -Name=Name -No\ old\ data\ was\ found.=Keine veralteten Daten gefunden. -Resave\ data\ files\ with\ structure\ changes\ no\ newer\ than\ Jenkins=\ - Aktualisiere Dateien mit Strukturnderungen nicht aktueller als Jenkins -Type=Typ -Unreadable\ Data=Nicht lesbare Daten -Discard\ Unreadable\ Data=Nicht lesbare Daten entfernen -Upgrade=Aktualisieren -Version=Version -blurb.1=\ - ndert sich die Struktur von Konfigurationsdateien, geht Jenkins folgendermaen vor: \ - Dateien werden beim Einlesen in den Speicher in das neue Datenformat migriert, aber \ - nicht automatisch auf Festplatte zurckgeschrieben. Die Konfigurationsdateien bleiben also \ - unverndert. Dies ermglicht bei Problemen ein Jenkins-Downgrade zu einer frheren \ - Version. Auf der anderen Seite knnen dadurch Dateien endlos in lngst veralteten \ - Formaten verbleiben. Die folgende Tabelle zeigt Dateien, die veraltete Strukturen verwenden, \ - sowie die Jenkins-Version(en), in denen die Datenstruktur verndert wurde. -blurb.2=\ - Beim Einlesen von Konfigurationsdateien knnen Fehler auftreten, z.B. wenn ein Plugin \ - Daten hinzufgt und spter deaktiviert wird, wenn kein Migrationscode fr Strukturnderungen \ - geschrieben wurde oder Jenkins auf eine ltere Version zurckgesetzt wird, nachdem die neuere \ - Version bereits Dateien mit einer neuen Struktur geschrieben hatte. Diese Fehler werden beim \ - Hochfahren von Jenkins zwar protokolliert, die nicht-lesbaren Daten werden aber einfach \ - bersprungen, damit Jenkins trotzdem starten und arbeiten kann. -blurb.3=\ - Mit der untenstehenden Funktion knnen Sie diese Datein im aktuellen Format neu abspeichern. \ - Damit entfllt die Mglichzeit, auf eine ltere als die ausgewhlte Jenkins-Version zurckzukehren. \ - Auch wenn Sie Konfigurationen bestehender Jobs ndern, werden diese Daten im neuen \ - Format gespeichert, was ein spteres Downgrade ausschliet. Nicht-lesbare Daten, die in der \ - Tabelle rechts dargestellt sind, werden bei der Aktualisierung dauerhaft entfernt. -blurb.4=\ - Langfristig wird Migrationscode zum Lesen veralteter Datenformate auch wieder entfernt werden. \ - Die Kompatibilitt wird mindestens 150 Releases nach nderung des Datenformates gewhrleistet. \ - Versionen, die noch lter sind, werden fett dargestellt. Es wird emfohlen, diese Dateien neu \ - abzuspeichern. -blurb.5=\ - (ein Downgrade bis zur ausgewhlten Version knnte immer noch mglich sein) -blurb.6=\ - Nicht-lesbare Daten stellen kein Problem dar, da Jenkins sie einfach ignoriert. \ - Um jedoch lange Protokolle mit zahlreichen Warnungen whrend des Hochfahrens von Jenkins zu \ - vermeiden, knnen Sie nicht-lesbare Daten dauerhaft entfernen, indem Sie diese ber die \ +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc., Alan Harder, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Error=Fehler +Manage\ Old\ Data=Veraltete Daten verwalten +Name=Name +No\ old\ data\ was\ found.=Keine veralteten Daten gefunden. +Resave\ data\ files\ with\ structure\ changes\ no\ newer\ than\ Jenkins=\ + Aktualisiere Dateien mit Strukturnderungen nicht aktueller als Jenkins +Type=Typ +Unreadable\ Data=Nicht lesbare Daten +Discard\ Unreadable\ Data=Nicht lesbare Daten entfernen +Upgrade=Aktualisieren +Version=Version +blurb.1=\ + ndert sich die Struktur von Konfigurationsdateien, geht Jenkins folgendermaen vor: \ + Dateien werden beim Einlesen in den Speicher in das neue Datenformat migriert, aber \ + nicht automatisch auf Festplatte zurckgeschrieben. Die Konfigurationsdateien bleiben also \ + unverndert. Dies ermglicht bei Problemen ein Jenkins-Downgrade zu einer frheren \ + Version. Auf der anderen Seite knnen dadurch Dateien endlos in lngst veralteten \ + Formaten verbleiben. Die folgende Tabelle zeigt Dateien, die veraltete Strukturen verwenden, \ + sowie die Jenkins-Version(en), in denen die Datenstruktur verndert wurde. +blurb.2=\ + Beim Einlesen von Konfigurationsdateien knnen Fehler auftreten, z.B. wenn ein Plugin \ + Daten hinzufgt und spter deaktiviert wird, wenn kein Migrationscode fr Strukturnderungen \ + geschrieben wurde oder Jenkins auf eine ltere Version zurckgesetzt wird, nachdem die neuere \ + Version bereits Dateien mit einer neuen Struktur geschrieben hatte. Diese Fehler werden beim \ + Hochfahren von Jenkins zwar protokolliert, die nicht-lesbaren Daten werden aber einfach \ + bersprungen, damit Jenkins trotzdem starten und arbeiten kann. +blurb.3=\ + Mit der untenstehenden Funktion knnen Sie diese Datein im aktuellen Format neu abspeichern. \ + Damit entfllt die Mglichzeit, auf eine ltere als die ausgewhlte Jenkins-Version zurckzukehren. \ + Auch wenn Sie Konfigurationen bestehender Jobs ndern, werden diese Daten im neuen \ + Format gespeichert, was ein spteres Downgrade ausschliet. Nicht-lesbare Daten, die in der \ + Tabelle rechts dargestellt sind, werden bei der Aktualisierung dauerhaft entfernt. +blurb.4=\ + Langfristig wird Migrationscode zum Lesen veralteter Datenformate auch wieder entfernt werden. \ + Die Kompatibilitt wird mindestens 150 Releases nach nderung des Datenformates gewhrleistet. \ + Versionen, die noch lter sind, werden fett dargestellt. Es wird emfohlen, diese Dateien neu \ + abzuspeichern. +blurb.5=\ + (ein Downgrade bis zur ausgewhlten Version knnte immer noch mglich sein) +blurb.6=\ + Nicht-lesbare Daten stellen kein Problem dar, da Jenkins sie einfach ignoriert. \ + Um jedoch lange Protokolle mit zahlreichen Warnungen whrend des Hochfahrens von Jenkins zu \ + vermeiden, knnen Sie nicht-lesbare Daten dauerhaft entfernen, indem Sie diese ber die \ untenstehende Funktion neu abspeichern lassen. \ No newline at end of file diff --git a/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_sr.properties b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..501dad149a2887ac1b77e2c4fef2dd701b5dbb88 --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/manage_sr.properties @@ -0,0 +1,18 @@ +# This file is under the MIT License by authors + +Manage\ Old\ Data=\u0423\u0440\u0435\u0434\u0438 \u0441\u0442\u0430\u0440\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 +blurb.1=\u041A\u0430\u0434\u0430 \u0438\u043C\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0435 \u0443 \u0442\u043E\u043C\u0435 \u043A\u0430\u043A\u043E \u0441y \u043F\u043E\u0434\u0430\u0446\u0438 \u0443\u0447\u0443\u0432\u0430\u043D\u0438 \u043D\u0430 \u0434\u0438\u0441\u043A\u0443, Jenkins \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u0441\u043B\u0435\u0434\u0435\u045B\u0443 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0458\u0443: \u043F\u043E\u0434\u0430\u0446\u0438 \u0441\u0443 \u043F\u0440\u0435\u043D\u0435\u0442\u0438 \u0443 \u043D\u043E\u0432\u0443 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0437 \u043A\u0430\u0434\u0430 \u0458\u0435 \u0443\u0447\u0438\u0442\u0430\u043D, \u0430\u043B\u0438 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043D\u0438\u0458\u0435 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0430 \u0443 \u043D\u043E\u0432\u043E\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0443. \u0422\u043E \u0432\u0430\u043C \u043E\u043C\u043E\u0433\u0443\u045B\u0430\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0432\u0440\u0430\u0442\u0438 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 Jenkins \u0430\u043A\u043E \u0431\u0443\u0434\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E. \u041C\u0435\u0452\u0443\u0442\u0438\u043C, \u043E\u043D \u0442\u0430\u043A\u043E\u0452\u0435 \u043C\u043E\u0436\u0435 \u043F\u0438\u0441\u0430\u0442\u0438 \u043D\u043E\u0432\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u043D\u0430 \u0434\u0438\u0441\u043A\u0443 \u0443 \u0441\u0442\u0430\u0440\u043E\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0443 \u043D\u0430 \u043D\u0435\u043E\u0434\u0440\u0435\u0452\u0435\u043D\u043E \u0432\u0440\u0435\u043C\u0435. \u0423 \u0442\u0430\u0431\u0435\u043B\u0438 \u0438\u0441\u043F\u043E\u0434 \u0458\u0435 \u0441\u043F\u0438\u0441\u0430\u043A \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043A\u043E\u0458\u0438 \u0441\u0430\u0434\u0440\u0436\u0435 \u0442\u0430\u043A\u0432\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435, \u0438 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 Jenkins, \u0433\u0434\u0435 \u0458\u0435 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u043F\u0440\u043E\u043C\u0435\u045A\u0435\u043D\u0430. +blurb.2=\u041F\u043E\u043D\u0435\u043A\u0430\u0434 \u0441\u0435 \u043F\u043E\u0458\u0430\u0432\u0435 \u0433\u0440\u0435\u0448\u043A\u0435 \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u0447\u0438\u0442\u0430\u045A\u0430 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430 (\u0430\u043A\u043E \u043D\u043F\u0440 \u043C\u043E\u0434\u0443\u043B\u0430 \u0431\u0443\u0434\u0435 \u043A\u0430\u0441\u043D\u0438\u0458\u0435 \u0438\u0441\u043A\u0459\u0443\u0447\u0435\u043D\u0430, \u043C\u0438\u0433\u0440\u0430\u0446\u0438\u043E\u043D\u0438 \u043A\u043E\u0434\u0435\u043A\u0441 \u043D\u0430\u043F\u0438\u0441\u0430\u043D \u043D\u0435 \u043F\u0440\u0435\u043F\u043E\u0437\u043D\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0435 \u0443 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0438, \u0438\u043B\u0438 \u0430\u043A\u043E \u0458\u0435 Jenkins \u0432\u0440\u0430\u045B\u0435\u043D \u043F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u043E\u0458 \u0432\u0435\u0440\u0437\u0438\u0458\u0438 \u043D\u0430\u043A\u043E\u043D \u0448\u0442\u043E \u0431\u0438 \u043D\u0435\u043A\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 \u043D\u0435\u0431\u0438 \u043C\u043E\u0433\u043B\u0438 \u0431\u0438\u0442\u0438 \u0443\u0447\u0438\u0442\u0430\u043D\u0438). \u041E\u0432\u0435 \u0433\u0440\u0435\u0448\u043A\u0435 \u0441\u0443 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0435, \u0430\u043B\u0438 \u043D\u0435\u043E\u0447\u0438\u0442\u0459\u0438\u0432\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 \u0441\u0435 \u043F\u0440\u0435\u0434\u0441\u043A\u0430\u0447\u0443. +Type=\u0422\u0438\u043F +Name=\u0418\u043C\u0435 +Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 +blurb.3=\u041F\u0440\u0430\u0442\u0435\u045B\u0438 \u0444\u043E\u0440\u043C\u0443\u043B\u0430\u0440 \u043C\u043E\u0436\u0435 \u0441\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u0430 \u043F\u043E\u043D\u043E\u0432\u043E \u0441\u0430\u0447\u0443\u0432\u0430\u045A\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0443 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0443, \u043A\u043E\u0458\u0438 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u0443\u0447\u0438\u0442\u0430\u043D \u0441\u0442\u0430\u0440\u0438\u0458\u0438\u043C \u0432\u0435\u0440\u0437\u0438\u0458\u0430\u043C\u0430 Jenkins. \u041D\u043E\u0440\u043C\u0430\u043B\u043D\u0430 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430 \u0442\u0430\u043A\u043E\u0452\u0435 \u043C\u043E\u0436\u0435 \u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u043A\u043E\u0458\u0435 \u043D\u0435\u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u0443\u0447\u0438\u0442\u0430\u043D\u0438 \u0441\u0442\u0430\u0440\u0438\u0458\u0438\u043C \u0432\u0435\u0440\u0437\u0438\u0458\u0430\u043C\u0430 Jenkins. \u0421\u0432\u0438 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u043F\u0440\u0435\u0431\u0430\u0447\u0435\u043D\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 \u045B\u0435 \u0431\u0438\u0442\u0438 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u043D\u0438 \u043D\u0430\u043A\u043E\u043D \u0441\u0430\u0447\u0443\u0432\u0430\u045A\u0430. +blurb.4=\ \u041E\u0432\u0430 \u0441\u043F\u043E\u0441\u043E\u0431\u043D\u043E\u0441\u0442 \u043C\u043E\u0436\u0435 \u0435\u0432\u0435\u043D\u0442\u0443\u0430\u043B\u043D\u043E \u0431\u0438\u0442\u0438 \u0443\u043A\u043B\u045A\u0435\u043D\u0430, \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043A\u043E\u043C\u043F\u0430\u0442\u0438\u0431\u0438\u043B\u043D\u043E\u0441\u0442 \u045B\u0435 \u0431\u0438\u0442\u0438 \u043E\u0434\u0440\u0436\u0430\u043D \u0434\u043E \u043D\u0430\u0458\u043C\u0430\u045A\u0435 150 \u0438\u0437\u0434\u0430\u045A\u0430 \u043F\u043E\u0441\u043B\u0435 \u0438\u043A\u0430\u043A\u0432\u0438\u0445 \u043F\u0440\u043E\u043C\u0435\u043D\u0430. \u0421\u0442\u0430\u0440\u0438\u0458\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0435 \u0441\u0443 \u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438 \u043C\u0430\u0441\u043D\u0438\u043C \u0441\u043B\u043E\u0432\u0438\u043C\u0430. \u041F\u0440\u0435\u043F\u043E\u0440\u0443\u0447\u0443\u0458\u0435 \u0441\u0435 \u0441\u0430\u0447\u0443\u0432\u0430\u045A\u0435 \u043E\u0432\u0438\u0445 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430. +Resave\ data\ files\ with\ structure\ changes\ no\ newer\ than\ Jenkins=\u041F\u043E\u043D\u043E\u0432\u043E \u0441\u0430\u0447\u0443\u0432\u0430\u0458 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0441\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0430\u043C\u0430 \u043A\u043E\u0458\u0435 \u043D\u0438\u0441\u0443 \u043D\u043E\u0432\u0438\u0458\u0430 \u043E\u0434 Jenkins +blurb.5=(\u0432\u0440\u0430\u045B\u0430\u045A\u0435 \u043D\u0430 \u043E\u0434\u0430\u0431\u0440\u0430\u043D\u0443 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 \u045B\u0435 \u0431\u0438\u0442\u0438 \u043C\u043E\u0433\u0443\u045B\u0435) +Upgrade=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 +No\ old\ data\ was\ found.=\u0417\u0430\u0441\u0442\u0430\u0440\u0435\u043B\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 \u043D\u0438\u0441\u0443 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u0438. +Unreadable\ Data=\u041D\u0435\u043E\u0447\u0438\u0442\u0459\u0438\u0432\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 +blurb.6=\u041C\u043E\u0436\u0435 \u0441\u0435 \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u043D\u0435\u0432\u0430\u0436\u0435\u045B\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u0443 \u043E\u0432\u0438\u043C \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430\u043C\u0430, \u0437\u0430\u0448\u0442\u043E Jenkins \u0438\u0445 \u043D\u0435 \u0437\u0430\u0431\u0435\u043B\u0435\u0436\u0438. \u041F\u043E\u043D\u043E\u0432\u043E \u0441\u0430\u0447\u0443\u0432\u0430\u0458\u0442\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u0434\u0430 \u0431\u0438\u0441\u0442\u0435 \u0438\u0437\u0431\u0435\u0433\u043B\u0438 \u0436\u0443\u0440\u043D\u0430\u043B \u043F\u043E\u0440\u0443\u043A\u0435 \u043D\u0430\u043A\u043E\u043D \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430. +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +Discard\ Unreadable\ Data=\u041E\u0434\u0431\u0430\u0446\u0438 \u043D\u0435\u0447\u0438\u0459\u0438\u0432\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 diff --git a/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_de.properties b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_de.properties index bb93c60a8e499878f2daf2e4ddd17bc6e3932d3d..6406a4c1145032aad50cf18a96d0ec69316345b2 100644 --- a/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_de.properties +++ b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_de.properties @@ -1,27 +1,27 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Alan Harder, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - - -Dismiss=Ignorieren -Manage=Verwalten -You\ have\ data\ stored\ in\ an\ older\ format\ and/or\ unreadable\ data.=\ +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc., Alan Harder, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +Dismiss=Ignorieren +Manage=Verwalten +You\ have\ data\ stored\ in\ an\ older\ format\ and/or\ unreadable\ data.=\ Es liegen Daten in einem veralteten Format und/oder nicht lesbare Daten vor. \ No newline at end of file diff --git a/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_sr.properties b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9575d0a32398524af4e5e9cfb0ddf13f6225f5ea --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/OldDataMonitor/message_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Manage=\u041F\u043E\u0434\u0435\u0441\u0438 +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 +You\ have\ data\ stored\ in\ an\ older\ format\ and/or\ unreadable\ data.=\u0418\u043C\u0430\u0442\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0435 \u043F\u043E \u0441\u0442\u0430\u0440\u0438\u0458\u0435\u043C \u0444\u043E\u0440\u043C\u0430\u0442\u0443, \u0438\u043B\u0438 \u043D\u0435\u0443\u0447\u0438\u0442\u0459\u0438\u0432\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435. diff --git a/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_bg.properties b/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_bg.properties index 11093616065ccf9159840bc468fcedb4edad01d0..52cd6bb32a7f6a98998cec84eedb07fea51a55e4 100644 --- a/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_bg.properties +++ b/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Dismiss=\u041F\u0440\u043E\u043F\u0443\u0441\u043D\u0438 -More\ Info=\u041F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F -blurb=\u0418\u0437\u0433\u043B\u0435\u0436\u0434\u0430, \u0447\u0435 \u0438\u043C\u0430\u0442\u0435 \u0433\u0440\u0435\u0448\u043A\u0430 \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0442\u0430 \u043D\u0430 \u0432\u0430\u0448\u0435\u0442\u043E reverse proxy. +Dismiss=\u041f\u0440\u043e\u043f\u0443\u0441\u043d\u0438 +More\ Info=\u041f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f +blurb=\u0418\u0437\u0433\u043b\u0435\u0436\u0434\u0430, \u0447\u0435 \u0438\u043c\u0430\u0442\u0435 \u0433\u0440\u0435\u0448\u043a\u0430 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0442\u0430 \u043d\u0430 \u0432\u0430\u0448\u0435\u0442\u043e reverse proxy. diff --git a/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_sr.properties b/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_sr.properties index e045957692c99db26648ad5063ef6bc9baf08a51..a61a9cb6dabd56a797d4f4169f527eba4a08f447 100644 --- a/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_sr.properties +++ b/core/src/main/resources/hudson/diagnosis/ReverseProxySetupMonitor/message_sr.properties @@ -1,3 +1,5 @@ # This file is under the MIT License by authors -More\ Info=Vi\u0161e Informacija +More\ Info=\u0412\u0438\u0448\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0430 +blurb=\u0418\u0437\u0433\u043B\u0435\u0434\u0430 \u0434\u0430 \u0438\u043C\u0435 \u0433\u0440\u0435\u0448\u043A\u0430 \u0443 \u0432\u0430\u0448\u043E\u0458 reverse proxy. +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 diff --git a/core/src/main/resources/hudson/diagnosis/TooManyJobsButNoView/message_sr.properties b/core/src/main/resources/hudson/diagnosis/TooManyJobsButNoView/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d025743f7361427539960955abd847745a702dd9 --- /dev/null +++ b/core/src/main/resources/hudson/diagnosis/TooManyJobsButNoView/message_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Create\ a\ view\ now=\u041A\u0440\u0435\u0438\u0440\u0430\u0458 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 \u0441\u0430\u0434\u0430 +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 +blurb=\u041F\u043E\u0441\u0442\u043E\u0458\u0438 \u0432\u0435\u043B\u0438\u043A\u0438 \u0431\u0440\u043E\u0458 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. \u0414\u0430 \u043B\u0438 \u0437\u043D\u0430\u0442\u0435 \u0434\u0430 \u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u043E\u0440\u0433\u0430\u043D\u0438\u0437\u0443\u0458\u0435\u0442\u0435 \u0432\u0430\u0448\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u043F\u043E \u0440\u0430\u0437\u043B\u0438\u0447\u0438\u0442\u0438\u043C \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0438\u043C\u0430? \u041F\u0440\u0438\u0442\u0438\u0441\u043D\u0435\u0442\u0435 " + " \u043D\u0430 \u043F\u043E\u0447\u0435\u0442\u043A\u0443 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u0431\u0438\u043B\u043E \u043A\u0430\u0434\u0430, \u0434\u0430 \u0434\u043E\u0434\u0430\u0442\u0435 \u043D\u043E\u0432\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434. diff --git a/core/src/main/resources/hudson/fsp/Messages_bg.properties b/core/src/main/resources/hudson/fsp/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..f51fe4ae7cd7cdc83643f2c992a868a722e77a7f --- /dev/null +++ b/core/src/main/resources/hudson/fsp/Messages_bg.properties @@ -0,0 +1,36 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +WorkspaceSnapshotSCM.NoSuchJob=\ + \u0417\u0430\u0434\u0430\u0447\u0430 \u0441 \u0438\u043c\u0435 \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430. \u201e{1}\u201c \u043b\u0438 \u0438\u043c\u0430\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434? +WorkspaceSnapshotSCM.IncorrectJobType=\ + \u0417\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u201e{0}\u201c \u043d\u044f\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. +WorkspaceSnapshotSCM.NoBuild=\ + \u041d\u0438\u043a\u043e\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0435 \u0441\u044a\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0430 \u043d\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u0442\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u201e{0}\u201c \u043a\u044a\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u0435\u043d\u043e\u0442\u043e\ + \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u201e{1}\u201c. +WorkspaceSnapshotSCM.NoSuchPermalink=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430\u0442\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u201e{0}\u201c \u043a\u044a\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u0435\u043d\u043e\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u201e{1}\u201c. +WorkspaceSnapshotSCM.NoWorkspace=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043a\u044a\u043c \u0437\u0430\u0434\u0430\u0447\u0430 {0} \u0441 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\ + {1}.\n\u041d\u0430\u0439-\u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0430\u0442\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0435, \u0447\u0435 \u043d\u0438\u043a\u043e\u044f \u0434\u0440\u0443\u0433\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435 \u0441\u0435 \u0435 \u043d\u0443\u0436\u0434\u0430\u0435\u043b\u0430 \u043e\u0442\ + \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u045d \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043f\u043e \u0432\u0440\u0435\u043c\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e.\n\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u043e\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 {0}, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0430\u0437\u0438 \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. diff --git a/core/src/main/resources/hudson/fsp/Messages_sr.properties b/core/src/main/resources/hudson/fsp/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b4e48fe8ec4a2a4a00d1170614473ef621b2bb0e --- /dev/null +++ b/core/src/main/resources/hudson/fsp/Messages_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +WorkspaceSnapshotSCM.NoSuchJob=\u0417\u0430\u0434\u0430\u0442\u0430\u043A \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C "{0}" \u043D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438. \u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u043C\u0438\u0441\u043B\u0438\u043B\u0438 "{1}"? \ No newline at end of file diff --git a/core/src/main/resources/hudson/init/impl/Messages_bg.properties b/core/src/main/resources/hudson/init/impl/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..daa25199de5d08bfab71df3dc52e605023c43abc --- /dev/null +++ b/core/src/main/resources/hudson/init/impl/Messages_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +GroovyInitScript.init=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u0449 \u0441\u043a\u0440\u0438\u043f\u0442 +InitialUserContent.init=\ + \u041f\u043e\u0434\u0433\u043e\u0442\u0432\u044f\u043d\u0435 \u043d\u0430 \u043f\u044a\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u043d\u043e\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 diff --git a/core/src/main/resources/hudson/init/impl/Messages_sr.properties b/core/src/main/resources/hudson/init/impl/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..643a509371dbcf932f18addaa6e74df0f73ec6a6 --- /dev/null +++ b/core/src/main/resources/hudson/init/impl/Messages_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +GroovyInitScript.init=\u0418\u0437\u0432\u0440\u0448\u045A\u0430 \u043F\u0440\u0438\u043B\u0430\u0433\u043E\u0452\u0435\u043D\u0438\u0445 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u043E\u043D\u0438 \u043F\u0440\u043E\u0433\u0440\u0430\u043C +InitialUserContent.init=\u041F\u0440\u0438\u043F\u0440\u0435\u043C\u0430\u045A\u0435 \u043E\u0441\u043D\u043E\u0432\u043D\u0438 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u0437\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/lifecycle/Messages.properties b/core/src/main/resources/hudson/lifecycle/Messages.properties index 76609f4b6113f9eeddd62d6f19b0382dc6e4af0f..0439ce0fca5e44c3b4286e48f79978a1a665f439 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages.properties @@ -22,7 +22,7 @@ WindowsInstallerLink.DisplayName=Install as Windows Service WindowsInstallerLink.Description=Installs Jenkins as a Windows service to this system, so that Jenkins starts automatically when the machine boots. -WindowsSlaveInstaller.ConfirmInstallation=This will install a slave agent as a Windows service, so that a Jenkins slave starts automatically when the machine boots. +WindowsSlaveInstaller.ConfirmInstallation=This will install an agent as a Windows service, so that a Jenkins agent starts automatically when the machine boots. WindowsSlaveInstaller.DotNetRequired=.NET Framework 2.0 or later is required for this feature WindowsSlaveInstaller.InstallationSuccessful=Installation was successful. Would you like to start the service now? -WindowsSlaveInstaller.RootFsDoesntExist=Slave root directory \u2018{0}\u2019 doesn\u2019t exist \ No newline at end of file +WindowsSlaveInstaller.RootFsDoesntExist=Agent root directory \u2018{0}\u2019 doesn\u2019t exist \ No newline at end of file diff --git a/core/src/main/resources/hudson/lifecycle/Messages_bg.properties b/core/src/main/resources/hudson/lifecycle/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..b8dae9036cbc1b9f12d493be8e96be724b6cf7a6 --- /dev/null +++ b/core/src/main/resources/hudson/lifecycle/Messages_bg.properties @@ -0,0 +1,37 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +WindowsInstallerLink.DisplayName=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043a\u0430\u0442\u043e \u0443\u0441\u043b\u0443\u0433\u0430 \u043d\u0430 Windows +WindowsInstallerLink.Description=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins \u043a\u0430\u0442\u043e \u0443\u0441\u043b\u0443\u0433\u0430 \u043d\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438\u044f \u043d\u0430 \u0442\u0430\u0437\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 Windows, \u0437\u0430\ + \u0434\u0430 \u043c\u043e\u0436\u0435 \u0442\u043e\u0439 \u0434\u0430 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0437\u0430\u0435\u0434\u043d\u043e \u0441 \u043c\u0430\u0448\u0438\u043d\u0430\u0442\u0430. +WindowsSlaveInstaller.DotNetRequired=\ + \u0417\u0430 \u0442\u043e\u0432\u0430 \u0441\u0435 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 .NET Framework, \u0432\u0435\u0440\u0441\u0438\u044f 2.0 \u0438\u043b\u0438 \u043f\u043e-\u0432\u0438\u0441\u043e\u043a\u0430 +WindowsSlaveInstaller.InstallationSuccessful=\ + \u0423\u0441\u043f\u0435\u0448\u043d\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f. \u0414\u0430 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u043b\u0438 \u0443\u0441\u043b\u0443\u0433\u0430\u0442\u0430? +WindowsSlaveInstaller.RootFsDoesntExist=\ + \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u0438\u044f \u0430\u0433\u0435\u043d\u0442 \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430. +# This will install an agent as a Windows service, so that a Jenkins agent starts automatically when the machine boots. +WindowsSlaveInstaller.ConfirmInstallation=\ + \u0422\u043e\u0432\u0430 \u0449\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430 \u0443\u0441\u043b\u0443\u0433\u0430 \u043d\u0430 Windows, \u0442\u0430\u043a\u0430 \u0447\u0435 Jenkins \u0449\u0435 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0437\u0430\u0435\u0434\u043d\u043e \u0441\ + \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430. diff --git a/core/src/main/resources/hudson/lifecycle/Messages_da.properties b/core/src/main/resources/hudson/lifecycle/Messages_da.properties index 6cb6cfec1ac7c0213d4b311c8eaf31bc29fa74c0..f6efe70ed1739e9bda9d0a7a4861b23321a3d15b 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages_da.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages_da.properties @@ -22,7 +22,5 @@ WindowsInstallerLink.DisplayName=Installer som Windows service WindowsSlaveInstaller.DotNetRequired=Denne feature kr\u00e6ver .NET framework 2.0 eller nyere -WindowsSlaveInstaller.RootFsDoesntExist=Slave roddirektorie ''{0}'' findes ikke WindowsSlaveInstaller.InstallationSuccessful=Installationen lykkedes. Vil du gerne starte service''en nu ? WindowsInstallerLink.Description=Installerer Jenkins som en Windows service p\u00e5 denne computer, s\u00e5 Jenkins starter automatisk n\u00e5r computeren starter op. -WindowsSlaveInstaller.ConfirmInstallation=Dette vil installere en Jenkins slave agent som en Windows service, s\u00e5 Jenkins slaven vil starte automatisk n\u00e5r computeren starter op. diff --git a/core/src/main/resources/hudson/lifecycle/Messages_de.properties b/core/src/main/resources/hudson/lifecycle/Messages_de.properties index 83960e0ee6f3db267c11b540567ac88e720fa945..76ac1a47765114aa967a0a1dbd1c97cb40ae812a 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages_de.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages_de.properties @@ -24,7 +24,5 @@ WindowsInstallerLink.DisplayName=Als Windows-Dienst installieren WindowsInstallerLink.Description=\ Installiert Jenkins als Windows-Dienst: Dadurch wird Jenkins \ automatisch nach einem Neustart des Rechners gestartet. -WindowsSlaveInstaller.ConfirmInstallation=Dies installiert einen Slave-Agent als Windows-Dienst. WindowsSlaveInstaller.DotNetRequired=.NET Framework 2.0 oder hher ist fr dieses Funktionsmerkmal erforderlich. WindowsSlaveInstaller.InstallationSuccessful=Installation erfolgreich. Mchten Sie den Dienst jetzt starten? -WindowsSlaveInstaller.RootFsDoesntExist=Stammverzeichnis ''{0}'' existiert auf dem Slave-Knoten nicht. \ No newline at end of file diff --git a/core/src/main/resources/hudson/lifecycle/Messages_es.properties b/core/src/main/resources/hudson/lifecycle/Messages_es.properties index e4618b85a45cc32a4eefa6267988fadc1d8b4999..2a1031893cc2bdc801d66c1cab66e0a38c836b41 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages_es.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages_es.properties @@ -22,7 +22,7 @@ WindowsInstallerLink.DisplayName=Instalar como un servicio de Windows WindowsInstallerLink.Description=Instalar Jenkins como un servicio de Windows en este sistema, de manera que Jenkins se inicie cuando el sistema arranque. -WindowsSlaveInstaller.ConfirmInstallation=Esto instalar el agente esclavo como un servicio de Windows. +WindowsSlaveInstaller.ConfirmInstallation=Esto instalar el agente como un servicio de Windows. WindowsSlaveInstaller.DotNetRequired=Es necesario tener instalado: .NET Framework 2.0 o posterior, para que esta caracterstica funcione. WindowsSlaveInstaller.InstallationSuccessful=La instalacin ha sido correcta. Quieres arrancar el servicio ahora? -WindowsSlaveInstaller.RootFsDoesntExist=El directorio raiz {0} en el esclavo no existe. +WindowsSlaveInstaller.RootFsDoesntExist=El directorio raiz {0} en el agente no existe. diff --git a/core/src/main/resources/hudson/lifecycle/Messages_ja.properties b/core/src/main/resources/hudson/lifecycle/Messages_ja.properties index e157bec5ef2b0858cda42a57a8741ef6f72fa6df..481cbd8d0e70d29bfaba4f18312cb059814eadd7 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages_ja.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages_ja.properties @@ -22,7 +22,6 @@ WindowsInstallerLink.DisplayName=Windows\u306E\u30B5\u30FC\u30D3\u30B9\u3068\u3057\u3066\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB WindowsInstallerLink.Description=\u30DE\u30B7\u30F3\u304C\u30D6\u30FC\u30C8\u3057\u305F\u3068\u304D\u306BJenkins\u304C\u81EA\u52D5\u7684\u306B\u958B\u59CB\u3059\u308B\u3088\u3046\u306B\u3001Windows\u306E\u30B5\u30FC\u30D3\u30B9\u3068\u3057\u3066Jenkins\u3092\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u307E\u3059\u3002 -WindowsSlaveInstaller.ConfirmInstallation=\u30B9\u30EC\u30FC\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092Windows\u306E\u30B5\u30FC\u30D3\u30B9\u3068\u3057\u3066\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u307E\u3059\u3002 WindowsSlaveInstaller.DotNetRequired=.NET Framework 2.0 \u4EE5\u964D\u304C\u5FC5\u8981\u3067\u3059\u3002 WindowsSlaveInstaller.InstallationSuccessful=\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u304C\u6210\u529F\u3057\u307E\u3057\u305F\u3002\u4ECA\u3059\u3050\u30B5\u30FC\u30D3\u30B9\u3092\u958B\u59CB\u3057\u307E\u3059\u304B? -WindowsSlaveInstaller.RootFsDoesntExist=\u30B9\u30EC\u30FC\u30D6\u306E\u30EB\u30FC\u30C8\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA ''{0}'' \u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002 \ No newline at end of file +WindowsSlaveInstaller.RootFsDoesntExist=\u30B9\u30EC\u30FC\u30D6\u306E\u30EB\u30FC\u30C8\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA ''{0}'' \u304C\u5B58\u5728\u3057\u307E\u305B\u3093\u3002 diff --git a/core/src/main/resources/hudson/lifecycle/Messages_pt_BR.properties b/core/src/main/resources/hudson/lifecycle/Messages_pt_BR.properties index a280eaee0c0b6bd21f98e20c704d6772aa125409..e2d80763ab85eafadce129aad85efde7f316bd17 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages_pt_BR.properties @@ -22,12 +22,8 @@ # Install as Windows Service WindowsInstallerLink.DisplayName=Instalar como um servi\u00e7o do Windows -# Slave root directory ''{0}'' doesn''t exist -WindowsSlaveInstaller.RootFsDoesntExist=Diret\u00f3rio slave ''{0}'' n\u00e3o existe # .NET Framework 2.0 or later is required for this feature WindowsSlaveInstaller.DotNetRequired=Framework .NET 2.0 ou superior \u00e9 necess\u00e1rio -# This will install a slave agent as a Windows service, so that a Jenkins slave starts automatically when the machine boots. -WindowsSlaveInstaller.ConfirmInstallation=Isso instalar\u00e1 o agente slave como um servi\u00e7o do Windows, portanto ser\u00e1 iniciado junto com o Sistema Operacional # Installation was successful. Would you like to start the service now? WindowsSlaveInstaller.InstallationSuccessful=Instala\u00e7\u00e3o efetuada com sucesso. Gostaria de iniciar o servi\u00e7o agora? # Installs Jenkins as a Windows service to this system, so that Jenkins starts automatically when the machine boots. diff --git a/core/src/main/resources/hudson/lifecycle/Messages_sr.properties b/core/src/main/resources/hudson/lifecycle/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8c6981247ca11c3c5eef36b5b78108be454418ff --- /dev/null +++ b/core/src/main/resources/hudson/lifecycle/Messages_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +WindowsInstallerLink.DisplayName=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 \u043A\u0430\u043E Windows \u0441\u0435\u0440\u0432\u0438\u0441 +WindowsInstallerLink.Description=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430 Jenkins \u043A\u0430\u043E Windows \u0441\u0435\u0440\u0432\u0438\u0441 \u043A\u043E\u0458\u0438 \u0441\u0435 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0435 \u043A\u0430\u0434\u0430 \u043F\u043E\u0447\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0430. +WindowsSlaveInstaller.ConfirmInstallation=\u041E\u043F\u0435\u0440\u0430\u0446\u0438\u0458\u0430 \u045B\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0442\u0438 \u0430\u0433\u0435\u043D\u0442 \u043A\u043E\u0458\u0438 \u0441\u0435 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0435 \u043A\u0430\u0434\u0430 \u043F\u043E\u0447\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0430. +WindowsSlaveInstaller.InstallationSuccessful=\u0423\u0441\u043F\u0435\u0448\u043D\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430. \u0414\u0430 \u0441\u0435 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0441\u0430\u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 \u0441\u0435\u0440\u0432\u0438\u0441? +WindowsSlaveInstaller.DotNetRequired=\u0417\u0430 \u0442\u043E \u043D\u0438\u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E .NET Framework 2.0 \u0438\u043B\u0438 \u043D\u043E\u0432\u0438\u0458\u0435 +WindowsSlaveInstaller.RootFsDoesntExist=\u041E\u0441\u043D\u043E\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0430\u0433\u0435\u043D\u0442\u0430 "{0}" \u043D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438. \ No newline at end of file diff --git a/core/src/main/resources/hudson/lifecycle/Messages_zh_TW.properties b/core/src/main/resources/hudson/lifecycle/Messages_zh_TW.properties index 261fc2d0f24bfe6deb662b5a01012d693aed7d61..6986de32c6e35b651e9c44cbfb79a607ff2c2123 100644 --- a/core/src/main/resources/hudson/lifecycle/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/lifecycle/Messages_zh_TW.properties @@ -22,7 +22,5 @@ WindowsInstallerLink.DisplayName=\u5b89\u88dd\u6210 Windows \u670d\u52d9 WindowsInstallerLink.Description=\u5c07 Jenkins \u5b89\u88dd\u6210 Windows \u670d\u52d9\uff0c\u958b\u6a5f\u5f8c Jenkins \u5c31\u6703\u81ea\u52d5\u555f\u52d5\u3002 -WindowsSlaveInstaller.ConfirmInstallation=\u5c07\u628a Slave \u4ee3\u7406\u7a0b\u5f0f\u5b89\u88dd\u6210 Windows \u670d\u52d9\uff0c\u958b\u6a5f\u5f8c Jenkins Slave \u5c31\u6703\u81ea\u52d5\u555f\u52d5\u3002 WindowsSlaveInstaller.DotNetRequired=\u672c\u529f\u80fd\u9700\u8981 .NET Framework 2.0 \u6216\u662f\u66f4\u65b0\u7684\u7248\u672c WindowsSlaveInstaller.InstallationSuccessful=\u5b89\u88dd\u5b8c\u6210\u3002\u60a8\u8981\u99ac\u4e0a\u555f\u52d5\u670d\u52d9\u55ce? -WindowsSlaveInstaller.RootFsDoesntExist=Slave \u6839\u76ee\u9304 ''{0}'' \u4e0d\u5b58\u5728 \ No newline at end of file diff --git a/core/src/main/resources/hudson/lifecycle/WindowsInstallerLink/_restart_sr.properties b/core/src/main/resources/hudson/lifecycle/WindowsInstallerLink/_restart_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3452bbb3e291656c810d56dc2c7be70a43033942 --- /dev/null +++ b/core/src/main/resources/hudson/lifecycle/WindowsInstallerLink/_restart_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Please\ wait\ while\ Jenkins\ is\ restarting=\u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u0441\u0430\u0447\u0435\u043A\u0430\u0458\u0442\u0435 \u0434\u043E\u043A \u0441\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0435 Jenkins +blurb=\u0411\u0438\u045B\u0435\u0442\u0435 \u043C\u043E\u043C\u0435\u043D\u0442\u0430\u043B\u043D\u043E \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u043D\u0430\u0432\u0435\u0441\u0442\u0438 \u043D\u0430 Jenkins.\ +\u0410\u043A\u043E \u0438\u0437 \u043D\u0435\u043A\u043E\u0433 \u0440\u0430\u0437\u043B\u043E\u0433\u0430 \u0441\u0435\u0440\u0432\u0438\u0441 \u043D\u0435 \u0440\u0430\u0434\u0438, \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 Windows \u0436\u0443\u0440\u043D\u0430\u043B \u0434\u043E\u0433\u0430\u0452\u0430\u0458\u0430 \u043D\u0430 \u0433\u0440\u0435\u0448\u043A\u0435 \u0438\u043B\u0438 \u0441\u0435 \u043E\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0412\u0438\u043A\u0438 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438 <\u0430 href="http://wiki.jenkins-ci.org/display/JENKINS/Jenkins+windows+service+fails+to+start"">\u0437\u0432\u0430\u043D\u0438\u0447\u043D\u043E\u0433 \u0412\u0438\u043A\u0438. diff --git a/core/src/main/resources/hudson/lifecycle/WindowsInstallerLink/index_sr.properties b/core/src/main/resources/hudson/lifecycle/WindowsInstallerLink/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b7283ad27b269e9b251f5f91541319708cfa10cb --- /dev/null +++ b/core/src/main/resources/hudson/lifecycle/WindowsInstallerLink/index_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +Install\ as\ Windows\ Service=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 \u043A\u0430\u043E Windows \u0441\u0435\u0440\u0432\u0438\u0441 +installBlurb=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 Jenkins \u043A\u0430\u043E Windows \u0441\u0435\u0440\u0432\u0438\u0441 \u0432\u0430\u043C \u043E\u043C\u043E\u0433\u0443\u045B\u0430\u0432\u0430 \u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 Jenkins \u043A\u0430\u0434\u0430 \u043F\u043E\u0447\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0430, \u0431\u0435\u0437 \u043E\u0431\u0437\u0438\u0440\u0430 \u043D\u0430\ +\u043A\u043E \u043A\u043E\u0440\u0438\u0441\u0442\u0438 Jenkins. +Installation\ Directory=\u0414\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0443\u043C \u0437\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0443 +Install=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 +Installation\ Complete=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u0433\u043E\u0442\u043E\u0432\u0430 +restartBlurb=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u0458\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0437\u0430\u0432\u0440\u0448\u0435\u043D\u0430. \u0414\u0430\u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0437\u0430\u0443\u0441\u0442\u0430\u0432\u0438\u0442\u0435 Jenkins \u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 \u043D\u043E\u0432\u043E-\u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0438 Windows \u0441\u0435\u0440\u0432\u0438\u0441? +Yes=\u0414\u0430 diff --git a/core/src/main/resources/hudson/logging/LogRecorder/configure_sr.properties b/core/src/main/resources/hudson/logging/LogRecorder/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..22db6a939b54de73261a31e3004f54e6d4d6dcf9 --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorder/configure_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Loggers=\u041F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0438 +List\ of\ loggers\ and\ the\ log\ levels\ to\ record=\u0421\u043F\u0438\u0441\u0430\u043A \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0430 \u0438 \u043D\u0438\u0432\u043E\u0438 \u0437\u0430 \u043F\u0438\u0441\u0430\u045A\u0430\u045A\u0435 \u0437 \u0436\u0443\u0440\u043D\u0430\u043B +Logger=\u041F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +Log\ level=\u041D\u0438\u0432\u043E \u0434\u0435\u0442\u0430\u0459\u0430 \u0436\u0443\u0440\u043D\u0430\u043B\u043E\u0432\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/logging/LogRecorder/delete_sr.properties b/core/src/main/resources/hudson/logging/LogRecorder/delete_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..79e28f491f4e32a7e4d63e7fab3bebb240742e85 --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorder/delete_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Are\ you\ sure\ about\ deleting\ this\ log\ recorder?=\u0414\u0430\u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u043E\u0432\u043E\u0433 \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0430? +Yes=\u0414\u0430 diff --git a/core/src/main/resources/hudson/logging/LogRecorder/index_sr.properties b/core/src/main/resources/hudson/logging/LogRecorder/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ab884fbbc937e48a851a21483d670459ee7afb64 --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorder/index_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Clear\ This\ Log=\u041F\u0440\u0435\u0431\u0440\u0438\u0448\u0438 \u0436\u0443\u0440\u043D\u0430\u043B diff --git a/core/src/main/resources/hudson/logging/LogRecorder/sidepanel.jelly b/core/src/main/resources/hudson/logging/LogRecorder/sidepanel.jelly index b9c8884ff21ad96e05352f921bef98515e4d34c3..686f05cf7e8daecfc4caed041b53b98f30b615aa 100644 --- a/core/src/main/resources/hudson/logging/LogRecorder/sidepanel.jelly +++ b/core/src/main/resources/hudson/logging/LogRecorder/sidepanel.jelly @@ -32,7 +32,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/logging/LogRecorder/sidepanel_sr.properties b/core/src/main/resources/hudson/logging/LogRecorder/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..056edbafdc7b5a359246825a417f74154eebf546 --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorder/sidepanel_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Back\ to\ Loggers=\u041D\u0430\u0437\u0430\u0434 \u043D\u0430 \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0435 +Log\ records=\u041D\u0438\u0432\u043E\u0438 \u0437\u0430 \u043F\u0438\u0441\u0430\u045A\u0435 \u0443 \u0436\u0443\u0440\u043D\u0430\u043B +Configure=\u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0438\u0448\u0438 +Delete=\u0423\u043A\u043B\u043E\u043D\u0438 diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/all_sr.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/all_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9e6ac59fabe5e1e6b2772f7b4a2823a9b427dd68 --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/all_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Jenkins\ Log=Jenkins \u0436\u0443\u0440\u043D\u0430\u043B +Level=\u041D\u0438\u0432\u043E +Logger\ Configuration=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0436\u0443\u0440\u043D\u0430\u043B\u0430 +Name=\u0418\u043C\u0435 +Submit=\u041F\u043E\u0434\u043D\u0435\u0441\u0438 diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/feeds_sr.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/feeds_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..89231883ddcc627e1f46e051f32bd761449b8d5c --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/feeds_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +All=\u0421\u0432\u0435 +>\ SEVERE=> \u0421\u0422\u0420\u041E\u0413\u041E +>\ WARNING=> \u0423\u041F\u041E\u0417\u041E\u0420\u0415\u040A\u0415 diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly b/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly index 7b6e2d677e00c6fb31d8039610c9d620c337147f..e188caed69553577930fd4b4221fcf6b38b2956b 100644 --- a/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/index.jelly @@ -59,7 +59,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/index_pl.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/index_pl.properties index abfa7767baa747643b650e0ef9049c2de0178a95..9557f45bddecd150d7e5e3a30152fe528982c832 100644 --- a/core/src/main/resources/hudson/logging/LogRecorderManager/index_pl.properties +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/index_pl.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors Add\ new\ log\ recorder=Dodaj nowy rejestrator log\u00F3w -All\ Jenkins\ Logs=Wszystkie login Jenkins +All\ Jenkins\ Logs=Wszystkie zdarzenia Jenkinsa Log\ Recorders=Rejestratory log\u00F3w Name=Nazwa diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/index_sr.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3ace1a3e186ea7f6bdffbb89c1bea555d8f81f5a --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/index_sr.properties @@ -0,0 +1,14 @@ +# This file is under the MIT License by authors + +Log=\u0416\u0443\u0440\u043D\u0430\u043B +Log\ Recorders=\u0416\u0443\u0440\u043D\u0430\u043B\u0438 +Name=\u0418\u043C\u0435 +Add\ new\ log\ recorder=\u0414\u043E\u0434\u0430\u0458 \u043D\u043E\u0432\u043E\u0433 \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0430 +All\ Jenkins\ Logs=\u0421\u0432\u0438 Jenkins \u0436\u0443\u0440\u043D\u0430\u043B\u0438 +Jenkins\ Log=Jenkins \u0436\u0443\u0440\u043D\u0430\u043B +Level=\u041D\u0438\u0432\u043E +Logger\ Configuration=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u0436\u0443\u0440\u043D\u0430\u043B\u0430 +Submit=\u041F\u043E\u0434\u043D\u0435\u0441\u0438 +All=\u0421\u0432\u0435 +>\ SEVERE=> \u0421\u0422\u0420\u041E\u0413\u041E +>\ WARNING=> \u0423\u041F\u041E\u0417\u041E\u0420\u0415\u040A\u0415 diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/levels_sr.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/levels_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2030984d1c49471debfbc62855580a908a0db997 --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/levels_sr.properties @@ -0,0 +1,9 @@ +# This file is under the MIT License by authors + +Logger\ Configuration=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0436\u0443\u0440\u043D\u0430\u043B\u043E\u0432\u0430\u045A\u0430 +url=http://wiki.jenkins-ci.org/display/JENKINS/Logger+Configuration +Name=\u0418\u043C\u0435 +Level=\u041D\u0438\u0432\u043E +defaultLoggerMsg=\u041F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447 \u0431\u0435\u0437 \u0438\u043C\u0435\u043D\u0430 \u0458\u0435 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438 \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447. \u0422\u0430\u0458 \u043D\u0438\u0432\u043E \u045B\u0435 \u0432\u0438\u0442\u0438 \u043D\u0430\u0441\u043B\u0435\u0452\u0435\u043D +Adjust\ Levels=\u041F\u043E\u0434\u0435\u0441\u0438 \u043D\u0438\u0432\u043E\u0435 +Submit=\u041F\u043E\u0434\u043D\u0435\u0441\u0438 \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_eo.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/new_sr.properties similarity index 62% rename from core/src/main/resources/hudson/model/Computer/sidepanel_eo.properties rename to core/src/main/resources/hudson/logging/LogRecorderManager/new_sr.properties index 0c86aa471d25f6cb19261ae83bcb542ae46ddd3a..2fbb8bde38001bf90e43c02d70be99315bd965fa 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_eo.properties +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/new_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Delete\ Slave=Nuligi sklavon +Name=\u0418\u043C\u0435 diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel.jelly b/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel.jelly index d3d6da993536e3889cafe5d1cd057441db22a5e1..c27d64b58a5c1897a88bad0dc51155e334c6d302 100644 --- a/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel.jelly +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel.jelly @@ -31,7 +31,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_pl.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_pl.properties index 4945181f2788b5468c8a3b852e3adb28e6f94d4c..7f6219d2cdf953321fd993fc6a59ca9566ac78c2 100644 --- a/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_pl.properties +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_pl.properties @@ -1,8 +1,8 @@ # This file is under the MIT License by authors All\ Logs=Wszystkie Logi -Back\ to\ Dashboard=Wr\u00F3\u0107 do Panelu -Log\ Levels=Poziom Logowania +Back\ to\ Dashboard=Powr\u00F3t do tablicy +Log\ Levels=Poziom logowania Logger\ List=Lista loger\u00F3w -Manage\ Jenkins=Zarz\u0105dzaj Jenkins''em +Manage\ Jenkins=Zarz\u0105dzaj Jenkinsem New\ Log\ Recorder=Nowe Nagrywanie Log\u00F3w diff --git a/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_sr.properties b/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..332bbec552ce0aaacb3eafcd91c95accfba9a67f --- /dev/null +++ b/core/src/main/resources/hudson/logging/LogRecorderManager/sidepanel_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 +Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C +Logger\ List=\u041F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0438 +New\ Log\ Recorder=\u041D\u043E\u0432\u0438 \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447 +Log\ Levels=\u041D\u0438\u0432\u043E\u0438 \u0436\u0443\u0440\u043D\u0430\u043B\u0430 +All\ Logs=\u0421\u0432\u0438 \u0436\u0443\u0440\u043D\u0430\u043B\u0438 diff --git a/core/src/main/resources/hudson/logging/Messages_bg.properties b/core/src/main/resources/hudson/logging/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..71b30e1d27a9255209ddf7c5d3e620dc35742b22 --- /dev/null +++ b/core/src/main/resources/hudson/logging/Messages_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +LogRecorderManager.init=\ + \u041f\u043e\u0434\u0433\u043e\u0442\u0432\u044f\u043d\u0435 \u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0442\u0435 +LogRecorderManager.DisplayName=\ + \u0436\u0443\u0440\u043d\u0430\u043b diff --git a/core/src/main/resources/hudson/logging/Messages_de.properties b/core/src/main/resources/hudson/logging/Messages_de.properties index f76b7ce7c4ea11b2a94abd23aed52abb7386a9c3..f62c7472e0d98069f2faaa29390368e3acc798f9 100644 --- a/core/src/main/resources/hudson/logging/Messages_de.properties +++ b/core/src/main/resources/hudson/logging/Messages_de.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + LogRecorderManager.init=Initialisiere Log-Rekorder \ No newline at end of file diff --git a/core/src/main/resources/hudson/logging/Messages_sr.properties b/core/src/main/resources/hudson/logging/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9cc510fd61a3da051f08748c68ec993cd7d09b5e --- /dev/null +++ b/core/src/main/resources/hudson/logging/Messages_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +LogRecorderManager.init=\u0418\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0458\u0430 \u043F\u0440\u0435\u043F\u0438\u0441\u0438\u0432\u0430\u0447\u0430 +LogRecorderManager.DisplayName=\u0436\u0443\u0440\u043D\u0430\u043B \ No newline at end of file diff --git a/core/src/main/resources/hudson/markup/EscapedMarkupFormatter/config_sr.properties b/core/src/main/resources/hudson/markup/EscapedMarkupFormatter/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b8caf9dd6b919119d9b9a200771920b2f8b66971 --- /dev/null +++ b/core/src/main/resources/hudson/markup/EscapedMarkupFormatter/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u0421\u043C\u0430\u0442\u0440\u0430 \u0441\u0432\u0435 \u043A\u0430\u043E \u043E\u0431\u0438\u0447\u0430\u043D \u0442\u0435\u043A\u0441\u0442. HTML \u0437\u043D\u0430\u0446\u0438 < \u0438 & \u0441\u0443 \u043F\u0440\u0435\u0442\u0432\u043E\u0440\u0435\u043D\u0438 \u0443 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430\u0458\u0443\u045B\u0435 \u0435\u043D\u0442\u0438\u0442\u0435\u0442\u0435. diff --git a/core/src/main/resources/hudson/markup/Messages.properties b/core/src/main/resources/hudson/markup/Messages.properties index 24c2921e9b0a2764ffc54dbaea53d6e091b1606a..9b79e845e2ba2445434b5cb934210ed960f11ed5 100644 --- a/core/src/main/resources/hudson/markup/Messages.properties +++ b/core/src/main/resources/hudson/markup/Messages.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -EscapedMarkupFormatter.DisplayName=Escaped HTML +EscapedMarkupFormatter.DisplayName=Plain text diff --git a/core/src/main/resources/hudson/markup/Messages_bg.properties b/core/src/main/resources/hudson/markup/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..c7a2206baae954d60c217fd1e0f7aadf3390b57e --- /dev/null +++ b/core/src/main/resources/hudson/markup/Messages_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +EscapedMarkupFormatter.DisplayName=\ + \u041e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d \u0442\u0435\u043a\u0441\u0442 diff --git a/core/src/main/resources/hudson/markup/Messages_pl.properties b/core/src/main/resources/hudson/markup/Messages_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..b706b9193cb98a2335610b5101f6ef2abcff6d8e --- /dev/null +++ b/core/src/main/resources/hudson/markup/Messages_pl.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +EscapedMarkupFormatter.DisplayName=Niesformatowany tekst diff --git a/core/src/main/resources/hudson/markup/Messages_sr.properties b/core/src/main/resources/hudson/markup/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5f8d6dcd1f7caccecd17093c567f1ca2450cd2fd --- /dev/null +++ b/core/src/main/resources/hudson/markup/Messages_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +EscapedMarkupFormatter.DisplayName=\u041E\u0431\u0438\u0447\u0430\u043D \u0442\u0435\u043A\u0441\u0442 \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly b/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly index 8b357557fff90a16869f5640f75582124a5a3c39..f030f796e3f2bc7c7c0b0379b5a96758713a4597 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly +++ b/core/src/main/resources/hudson/model/AbstractBuild/changes.jelly @@ -31,7 +31,17 @@ THE SOFTWARE. ${%Changes} - + + + + + + ${%Not yet determined} + + + ${%Failed to determine} (${%log}) + + diff --git a/core/src/main/resources/hudson/model/AbstractBuild/changes_bg.properties b/core/src/main/resources/hudson/model/AbstractBuild/changes_bg.properties index 377ea21e939b944bc24ab25d1acf2a6b7c00ecf7..8dc5346f7f959c6f25610d8d15a656743d694061 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/changes_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/changes_bg.properties @@ -1,3 +1,30 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0438 +Changes=\ + \u041f\u0440\u043e\u043c\u00e8\u043d\u0438 +Failed\ to\ determine=\ + \u0413\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 +log=\ + \u0436\u0443\u0440\u043d\u0430\u043b +Not\ yet\ determined=\ + \u041f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u043d\u0435 \u0441\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438 diff --git a/core/src/main/resources/hudson/model/AbstractBuild/changes_sr.properties b/core/src/main/resources/hudson/model/AbstractBuild/changes_sr.properties index 5d4ef6a979b40b25f6cb7345c1e9d529d43e2fad..0a8f87fa885e1dc8f805de2f905a5fe03e51ea45 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/changes_sr.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/changes_sr.properties @@ -1,3 +1,6 @@ # This file is under the MIT License by authors Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0435 +Not\ yet\ determined=\u0408\u043E\u0448 \u043D\u0438\u0458\u0435 \u043E\u0434\u0440\u0435\u0452\u0435\u043D\u043E +Failed\ to\ determine=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043E\u0434\u0440\u0435\u0434\u0438\u0442\u0438 +log=\u0436\u0443\u0440\u043D\u0430\u043B diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_bg.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_bg.properties index 07e67e8699b3680f642eae6dc3f02b9fdcd1d68c..25b57a73db29059454f62db1619048b04b225a05 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/index_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/index_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,31 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build=\u0438\u0437\u043F\u044A\u043B\u043D\u0435\u043D\u0438\u0435 -Build\ Artifacts=\u0430\u0440\u0442\u0438\u0444\u0430\u043A\u0442\u0438 \u043E\u0442 \u0438\u0437\u043F\u044A\u043B\u043D\u0435\u043D\u0438\u0435\u0442\u043E -Took=\u041E\u0442\u043D\u0435 -beingExecuted=\u0422\u043E\u0437\u0438 \u0431\u0438\u043B\u0434 \u0441\u0435 \u0438\u0437\u043F\u044A\u043B\u043D\u044F\u0432\u0430 \u0432\u0435\u0447\u0435 {0} -on=\u043D\u0430 -startedAgo=\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043D \u043F\u0440\u0435\u0434\u0438 {0} +Build=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Build\ Artifacts=\ + \u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +Took=\ + \u041e\u0442\u043d\u0435 +beingExecuted=\ + \u0422\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u0432\u0435\u0447\u0435 {0} +on=\ + \u043d\u0430 +startedAgo=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043f\u0440\u0435\u0434\u0438 {0} +Downstream\ Builds=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f, \u043e\u0442 \u043a\u043e\u0438\u0442\u043e \u0442\u043e\u0432\u0430 \u0437\u0430\u0432\u0438\u0441\u0438 +Changes\ in\ dependency=\ + \u041f\u0440\u043e\u043c\u0435\u043d\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u0442\u0435 +none=\ + \u043d\u044f\u043c\u0430 +Upstream\ Builds=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f, \u043a\u043e\u0438\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0442\u043e\u0432\u0430 +Not\ yet\ determined=\ + \u041f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u043e\u0449\u0435 \u043d\u0435 \u0441\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438 +Failed\ to\ determine=\ + \u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438 +log=\ + \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0441 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 +detail=\ + \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_en_GB.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_en_GB.properties index d5ed3717ab68d5c47638a34f93665190c38bd05f..d251b5168d2a48d98bdcbec98ec42645832ec454 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/index_en_GB.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/index_en_GB.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Build\ Artifacts=Build Artefacts +Build\ Artifacts=Build Artifacts diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_pl.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_pl.properties index 13a1635b6dabb27e2f3f2ffe04916c7f8a92797c..c2e7fc25608eceebe99a53ccefcde6600bea6b21 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/index_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/index_pl.properties @@ -20,13 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build=Buduj +Build=Zadanie Build\ Artifacts=Artefakty budowania Changes\ in\ dependency=Zmiany w zale\u017Cno\u015Bciach -Downstream\ Builds=Buildy podrz\u0119dne +Downstream\ Builds=Zadania podrz\u0119dne Not\ yet\ determined=Jeszcze nie ustalono Took=Trwa\u0142o -Upstream\ Builds=Buildy nadrz\u0119dne +Upstream\ Builds=Zadania nadrz\u0119dne beingExecuted=Zadanie jest wykonywane od {0} detail=Detale none=brak diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties index e601d09c8842e6b38dd72d7e18d6c01974388abf..83030bc367b49ab8c23bcad295881b14e6ff0f60 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_BR.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva, Fernando Boaglio +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Reginaldo L. Russinholi, Cleiber Silva, Fernando Boaglio, George Gastaldi # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -21,9 +21,9 @@ # THE SOFTWARE. startedAgo=Iniciado {0} atr\u00e1s -Build\ Artifacts=Artefatos da builds +Build\ Artifacts=Artefatos da build Changes\ in\ dependency=Mudan\u00E7as na depend\u00EAncia -beingExecuted=Tempo de execu\u00E7\u00E3o da builds {0} +beingExecuted=Tempo de execu\u00E7\u00E3o da build {0} detail=detalhe Not\ yet\ determined=Ainda n\u00e3o determinado Failed\ to\ determine=Falhou ao determinar @@ -32,5 +32,4 @@ Upstream\ Builds=builds pai Downstream\ Builds=builds filho none=nenhum Took=Demorou -on=no slave Build=Build diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties index cb85ec5b930365cab2c9f674b4f0a8b4f3775848..8a54bd9d030ae6c22d33a6b5ad8cf9affc54ac1a 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/index_pt_PT.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-2010, Sun Microsystems, Inc., George Gastaldi # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,8 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build=Contru\u00E7\u00E3o -Build\ Artifacts=Contru\u00E7\u00E3o de artefactos +Build=Constru\u00E7\u00E3o +Build\ Artifacts=Constru\u00E7\u00E3o de artefactos Took=Demorou beingExecuted=Compila\u00E7\u00E3o a ser executada h\u00E1 {0} on=em diff --git a/core/src/main/resources/hudson/model/AbstractBuild/index_sr.properties b/core/src/main/resources/hudson/model/AbstractBuild/index_sr.properties index 2a36f45d5710257f12faba03e618f9ee9a9bc13d..8015f80d9cec368ac71047a92437b94bcb08cd57 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/index_sr.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/index_sr.properties @@ -1,7 +1,16 @@ # This file is under the MIT License by authors -Build=Projekat +Build=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 Build\ Artifacts=Artifakti projekta -Took=Uzmi -on=na -startedAgo=Zapoceto pre {0} +Took=\u0422\u0440\u0430\u0458\u0430\u043B\u043E: +on=\u043D\u0430 +startedAgo=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043F\u0440\u0435 {0} +beingExecuted=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u0441\u0435 {0} +Changes\ in\ dependency=\u041F\u0440\u043E\u043C\u0435\u043D\u0435 \u0443 \u0437\u0430\u0432\u0438\u0441\u043D\u043E\u043C \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0443 +detail=\u0434\u0435\u0442\u0430\u0459\u043D\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 +Not\ yet\ determined=\u041D\u0438\u0458\u0435 \u0458\u043E\u0448 \u043E\u0434\u0440\u0435\u0452\u0435\u043D\u043E +Failed\ to\ determine=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u043B\u043E \u043E\u0434\u0440\u0435\u0434\u0438\u0442\u0438 +log=\u0436\u0443\u0440\u043D\u0430\u043B +Upstream\ Builds=Upstream \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Downstream\ Builds=Downstream \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +none=\u043D\u0438\u0458\u0435\u0434\u043D\u043E diff --git a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_bg.properties b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_bg.properties index f883b8e2c8875158942947c0d1af3e8c51ec9724..e543476a9f4ccc13f434d477911c65ba988549ac 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Next\ Build=\u0421\u043B\u0435\u0434\u0432\u0430\u0449 \u0431\u0438\u043B\u0434 -Previous\ Build=\u041F\u0440\u0435\u0434\u0438\u0448\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043D\u0435 +Next\ Build=\ + \u0421\u043b\u0435\u0434\u0432\u0430\u0449\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Previous\ Build=\ + \u041f\u0440\u0435\u0434\u0438\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pl.properties b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pl.properties index 1f6bd5f5e87466465e5fb04e94e47a2dfa96bdbf..aa0cc1a6f557a9b39347629d4bacb916410cbc98 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pl.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Next\ Build=Nast\u0119pna wersja +Next\ Build=Nast\u0119pne zadanie Previous\ Build=Poprzednie zadanie diff --git a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties index 70b25b6c110bed38804a5c559fe960458aa145ff..8695d88bf5bf29de187b7f09b606153f3599d723 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_pt_PT.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Next\ Build=Pr\u00F3xima builds -Previous\ Build=Prever/ver contru\u00E7\u00E3o +Next\ Build=Pr\u00F3xima build +Previous\ Build=Prever/ver constru\u00E7\u00E3o diff --git a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_sr.properties b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_sr.properties index effcb55a0a699b1231a9641eb357055fdac95197..639db57af036d9a8df13c2b554dcc1e036e26c45 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_sr.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/sidepanel_sr.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Next\ Build=Naredna Gradnja -Previous\ Build=Prethodno sklapoanje +Previous\ Build=\u041F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Next\ Build=\u0421\u043B\u0435\u0434\u0435\u045B\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/core/src/main/resources/hudson/model/AbstractBuild/tasks_bg.properties b/core/src/main/resources/hudson/model/AbstractBuild/tasks_bg.properties index 996ec2e34395db3577df0cf6fb0c7b2f726ba865..b32a0ed30a840ffd6086b4cdd3816ff25e705d92 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/tasks_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/tasks_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,11 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Project=\u041E\u0431\u0440\u0430\u0442\u043D\u043E \u043A\u044A\u043C \u043F\u0440\u043E\u0435\u043A\u0442\u0430 -Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0438 -Console\ Output=\u041A\u043E\u043D\u0437\u043E\u043B\u0435\u043D \u0442\u0435\u043A\u0441\u0442 -View\ Build\ Information=\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u0437\u0430 \u0438\u0437\u043F\u044A\u043B\u043D\u0435\u043D\u0438\u0435\u0442\u043E -View\ as\ plain\ text=\u0420\u0430\u0437\u0433\u043B\u0435\u0436\u0434\u0430\u043D\u0435 \u043A\u0430\u0442\u043E \u043E\u0431\u0438\u043A\u043D\u043E\u0432\u0435\u043D \u0442\u0435\u043A\u0441\u0442 -Edit\ Build\ Information=\u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u0430\u043D\u0435 \u043D\u0430 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\u0442\u0430 \u0437\u0430 \u0431\u0438\u043B\u0434\u0430 -Status=\u0421\u0442\u0430\u0442\u0443\u0441 -raw=\u043D\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0435\u043D +Back\ to\ Project=\ + \u041e\u0431\u0440\u0430\u0442\u043d\u043e \u043a\u044a\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0430 +Changes=\ + \u041f\u0440\u043e\u043c\u0450\u043d\u0438 +Edit\ Build\ Information=\ + \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +Status=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractBuild/tasks_pl.properties b/core/src/main/resources/hudson/model/AbstractBuild/tasks_pl.properties index 0d03d2fca9e97500d0692b0ff15c100b72238715..5272dc29dff522cd55da44485e97997e2a0ef8cd 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/tasks_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/tasks_pl.properties @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Project=Wr\u00F3\u0107 do projektu -Changes=Zmiany +Back\ to\ Project=Powr\u00F3t do projektu +Changes=Rejestr zmian Console\ Output=Logi konsoli -View\ as\ plain\ text=Otw\u00F3rz jako zwyk\u0142y tekst -Edit\ Build\ Information=Edytuj informacje o kompilacji -View\ Build\ Information=Poka\u017C Informacje o build''zie +View\ as\ plain\ text=Otw\u00F3rz jako niesformatowany tekst +Edit\ Build\ Information=Edytuj informacje o zadaniu +View\ Build\ Information=Poka\u017C informacje o zadaniu raw=surowe wyj\u015Bcie diff --git a/core/src/main/resources/hudson/model/AbstractBuild/tasks_pt_BR.properties b/core/src/main/resources/hudson/model/AbstractBuild/tasks_pt_BR.properties index 149bfe88fccf44a683ba7dc7b7280a8054717a39..49ae1e411c5f49d79982a291986902d68bddf8cc 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/tasks_pt_BR.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/tasks_pt_BR.properties @@ -24,48 +24,3 @@ Back\ to\ Project=Voltar ao projeto Changes=Altera\u00E7\u00F5es Edit\ Build\ Information=Editar informa\u00E7\u00F5es de compila\u00E7\u00E3o Status=Estado pessoal -Jenkins -\u2026 -Translation Assistance Plugin -License of contribution to Jenkins translation -Edit -Add -Page -Gliffy Diagram -Comment -Attachment -Tools -Attachments (0) -Page History -Restrictions -Edit in Word -Favourite -Watch -Info -Link to this Page\u2026 -View in Hierarchy -View Wiki Markup -Export to PDF -Export to Word -Import Word Document -Copy -Move - License of contribution to Jenkins translation -Added by Kohsuke Kawaguchi, last edited by Kohsuke Kawaguchi on Aug 29, 2011 -Jenkins -Home -Mailing lists -Source code -Bugtracker -Security Advisories -Donation -Commercial Support -Wiki Site Map -Documents -Meet Jenkins -Use Jenkins -Extend Jenkins -Plugins -Servlet Container Notes - This page is the landing page for the translation assistance plugin''s "contribute" link -When you check the "I contribute my translations to the Jenkins project" link, you acknowledge that your submission will be licensed under the MIT license (the same license that the rest of the Jenkins core uses) and you have the rights to release them under the said license. diff --git a/core/src/main/resources/hudson/model/AbstractBuild/tasks_sr.properties b/core/src/main/resources/hudson/model/AbstractBuild/tasks_sr.properties index 2505d1654cbe7eda1007153b52ad54d738497042..f980312c413e5a725b38ccfcfc14ca4a7b1658ce 100644 --- a/core/src/main/resources/hudson/model/AbstractBuild/tasks_sr.properties +++ b/core/src/main/resources/hudson/model/AbstractBuild/tasks_sr.properties @@ -1,9 +1,10 @@ # This file is under the MIT License by authors -Back\ to\ Project=Nazad na projekt -Changes=Promjene -Console\ Output=Ispis konzole -Edit\ Build\ Information=Izmeni informacije o sklapoanju -View\ Build\ Information=Pogledaj informacije u buildu -View\ as\ plain\ text=Pregledati kao cisti text -raw=sirov +Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0435 +Console\ Output=\u0418\u0441\u0445\u043E\u0434 \u0438\u0437 \u043A\u043E\u043D\u0437\u043E\u043B\u0435 +Edit\ Build\ Information=\u0423\u0440\u0435\u0434\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438 +View\ Build\ Information=\u041F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +View\ as\ plain\ text=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u043E\u0431\u0438\u0447\u043D\u043E\u0433 \u0442\u0435\u043A\u0441\u0442\u0430 +raw=\u043D\u0435\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0437\u043E\u0432\u0430\u043D \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +Status=\u0421\u0442\u0430\u045A\u0435 +Back\ to\ Project=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0443 diff --git a/core/src/main/resources/hudson/model/AbstractItem/delete_bg.properties b/core/src/main/resources/hudson/model/AbstractItem/delete_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..3a70a40083b0a340e8cb98885a11dd1e4871b950 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractItem/delete_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 {0} \u201e{1}\u201c? +Yes=\ + \u0414\u0430 diff --git a/core/src/main/resources/hudson/model/AbstractItem/delete_sr.properties b/core/src/main/resources/hudson/model/AbstractItem/delete_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4777801d8ff03b1d3c231fc3e038d90b10c66a27 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractItem/delete_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +blurb=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u0442\u0438 {0} "{1}"? +Yes=\u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ job?=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A? diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-displayNameOrNull_bg.html b/core/src/main/resources/hudson/model/AbstractItem/help-displayNameOrNull_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..26671940462ccbb39de77b132613c10b510bb077 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractItem/help-displayNameOrNull_bg.html @@ -0,0 +1,7 @@ +
    +Ако е зададено, незадължителното показвано име се използва за проекта в +интерфейса на Jenkins. Понеже се ползва чисто визуално, няма изискване за +уникалност на това име на проект.
    +Ако не е зададено показвано име, интерфейсът на Jenkins показва обичайното +име на проект. +
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity.html b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity.html index 02ca4366566f3649cbe97a5a902f0eb0d8890f53..61dd7332947f9f7d1385161b310c8fb15d50c33b 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity.html +++ b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity.html @@ -1,17 +1,15 @@
    - Sometimes a project can only be successfully built on a particular slave - (or master). If so, this option forces Jenkins to always build this project - on a specific computer. - - If there is a group of machines that the job can be built on, you can specify - that label as the node to tie on, which will cause Jenkins to build the - project on any of the machines with that label. - + By default, builds of this project may be executed on any build agents that + are available and configured to accept new builds.

    - Otherwise, uncheck the box so that Jenkins can schedule builds on available - nodes, which results in faster turn-around time. - + When this option is checked, you have the possibility to ensure that builds of + this project only occur on a certain agent, or set of agents.

    - This option is also useful when you'd like to make sure that a project can - be built on a particular node. -

    \ No newline at end of file + For example, if your project should only be built on a certain operating + system, or on machines that have a certain set of tools installed, or even one + specific machine, you can restrict this project to only execute on agents that + that meet those criteria. +

    + The help text for the Label Expression field, shown when this option is + checked, provides more detailed information on how to specify agent criteria. + diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_bg.html b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..277eda80998b783d5f1542ad463aea9824ff88ee --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_bg.html @@ -0,0 +1,15 @@ +

    + Стандартно, всеки наличен и настроен да приема нови изграждания агент може да + изгради проекта. +

    + Ако изберете тази опция може да осигурите изграждането на проекта да се + извършва от определена група от компютри (в частност — само един компютър). +

    + Например, ако проектът трябва да се изгражда само на определени + операционни системи или на компютри, на които са инсталирани специфични + интструменти, можете да укажете на проекта да се изгражда само на машини, + коитоy отговарят на интересуващите ви критерии. +

    + Помощният текст за полето Израз с етикети, което се показва, когато + сте избрали тази опция, съдържа повече информация, как се указват критерии. +

    diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_de.html b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_de.html.lang,slave_rename similarity index 74% rename from core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_de.html rename to core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_de.html.lang,slave_rename index c942b354be7474c54afc5d651405617251dd9ba9..50d612fa49db316a79ef9fbb913c0a9d2def118a 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_de.html +++ b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_de.html.lang,slave_rename @@ -1,15 +1,15 @@
    - Manchmal kann ein Projekt nur auf einem bestimmten Slave-Knoten (oder + Manchmal kann ein Projekt nur auf einem bestimmten Agent-Knoten (oder Master-Knoten) erfolgreich gebaut werden. - In diesem Fall sollte diese Option angewählt werden, so daß Jenkins + In diesem Fall sollte diese Option angewählt werden, so dass Jenkins das Projekt stets nur auf diesem bestimmten Knoten baut. - In allen anderen Fällen sollten Sie diese Option abwählen, so daß Jenkins + In allen anderen Fällen sollten Sie diese Option abwählen, so dass Jenkins Builds auf allen verfügbaren Knoten planen kann - was in kürzeren Durchlaufzeiten resultieren kann.

    Diese Option ist ebenfalls nützlich, wenn Sie gezielt testen möchten, ob ein Projekt auf einem bestimmten Knoten gebaut werden kann. -

    \ No newline at end of file + diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_pt_BR.html b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_pt_BR.html deleted file mode 100644 index d5af2f57af26feca24bac75ea34f2b3ecab07095..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_pt_BR.html +++ /dev/null @@ -1,12 +0,0 @@ -v> - Algumas vezes um projeto só pode ser construído com sucesso em um slave - (ou master) em particular. Se for assim, esta opção força o Jenkins a sempre construir este projeto - em um computadore específico. - - Caso contrário, desmarque a caixa e assim o Jenkins pode agendar construções nos nós - disponíveis, o que resulta em tempos de resposta mais rápidos. - -

    - Esta opção tamém é últil quando você quiser ter certeza que um projeto pode - ser construído em um nó particular. - diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_tr.html b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_tr.html deleted file mode 100644 index a5ea3ee54e22cd7a9b1125590f6a170e936ca795..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_tr.html +++ /dev/null @@ -1,11 +0,0 @@ -

    - Bazı projeler sadece belirli slave'lerde (master'da olabilir) başarı ile yapılandırılır, - bu tür durumlar için, bu seçenek projeyi daima belirli bir bilgisayarda yapılandırır. - - Aksi takdirde, kutucuğu seçili değil halde bırakırsanız, Jenkins yapılandırmayı, herhangi - bir nod üzerinde yürütür. - -

    - Bir projenin sadece belli bir nod üzerinde çalışmasını istiyorsanız bu seçenek işinize - yarayacaktır. -

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_zh_TW.html b/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_zh_TW.html deleted file mode 100644 index 1b6c7e06cd29aea47147e6bfa76655fd24bb15d5..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/AbstractItem/help-slaveAffinity_zh_TW.html +++ /dev/null @@ -1,12 +0,0 @@ -
    - 有時候專案只能在特定的 Slave (或 Master) 上才能成功建置。 - 如果有這個情形,請設定這個選項,強制 Jenkins 都只在特定電腦上建置這個專案。 - - 如果有一群主機可以建置這個專案,您可以用標籤限定要執行的節點,Jenkins 就會在有指定相同標籤的機器中挑一台來建置專案。 - -

    - 否則請不要啟用這個功能,讓 Jenkins 盡量利用有空的節點來建置,等候及執行的時間也會比較短。 - -

    - 透過這個選項,也可以讓您確認專案是否能在特定節點上建置。 -

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace.jelly b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace.jelly index 4882cfc5dae418c205ed25285302a8a65475ba71..6a93fc14b4a59c84b4e4d08f2ca93360bf2b18eb 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace.jelly +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace.jelly @@ -45,7 +45,7 @@ THE SOFTWARE. ${%The project was renamed recently and no build was done under the new name.}
  7. - ${%The slave this project has run on for the last time was removed.} + ${%The agent this project has run on for the last time was removed.}
  8. ${%li3(it.workspace)} diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_bg.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..fbec109035d7ab3bd4a47b47f985ddbdaed440cd --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_bg.properties @@ -0,0 +1,44 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0431\u0435 \u043f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u043d \u0441\u043a\u043e\u0440\u043e. \u0412\u0441\u0435 \u043e\u0449\u0435 \u043d\u044f\u043c\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u0441 \u0442\u043e\u0432\u0430 \u0438\u043c\u0435. +# The workspace directory ({0}) is removed outside Jenkins. +li3=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u201e{0}\u201c \u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u044f\u043d\u043e \u0438\u0437\u0432\u044a\u043d Jenkins. +There''s\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043d\u0430 \u0442\u043e\u0437\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u043b\u0438\u043f\u0441\u0432\u0430. \u0412\u044a\u0437\u043c\u043e\u0436\u043d\u0438 \u043f\u0440\u0438\u0447\u0438\u043d\u0438 \u0441\u0430: +text=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0438 Jenkins \u0449\u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. +Error\:\ no\ workspace=\ + \u0413\u0440\u0435\u0448\u043a\u0430: \u043b\u0438\u043f\u0441\u0432\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e +The\ workspace\ was\ wiped\ out\ and\ no\ build\ has\ been\ done\ since\ then.=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0435 \u0431\u0438\u043b\u043e \u0438\u0437\u0442\u0440\u0438\u0442\u043e \u0438 \u043e\u0442\u0442\u043e\u0433\u0430\u0432\u0430 \u043d\u044f\u043c\u0430 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +A\ project\ won''t\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ performed.=\ + \u0417\u0430 \u0434\u0430 \u0441\u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0435 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043d\u0430 \u0435\u0434\u0438\u043d \u043f\u0440\u043e\u0435\u043a\u0442, \u0442\u043e\u0439 \u0442\u0440\u044f\u0431\u0432\u0430 \u043f\u044a\u0440\u0432\u043e \u0434\u0430 \u0441\u0435\ + \u0438\u0437\u0433\u0440\u0430\u0434\u0438. +The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442, \u043d\u0430 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u0435 \u0431\u0438\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d, \u0435 \u0438\u0437\u0432\u0430\u0434\u0435\u043d \u043e\u0442\ + \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430. +The\ agent\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442, \u043d\u0430 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u0435 \u0431\u0438\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d, \u0435 \u0438\u0437\u0432\u0430\u0434\u0435\u043d \u043e\u0442\ + \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_da.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_da.properties index 3db6b4afeea54c42e668a32908ff232065a1e78d..38f08ccf26d7e09d41bbd9ccfb531123a2c02012 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_da.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_da.properties @@ -27,4 +27,3 @@ The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new Projektet er blevet omd\u00f8bt for nyligt og ingen byg er endnu udf\u00f8rt under det nye navn Error\:\ no\ workspace=Fejl: intet arbejdsomr\u00e5de text=K\u00f8r et byg for at f\u00e5 Jenkins til at lave et arbejdsomr\u00e5de. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=Slaven projektet sidst k\u00f8rte p\u00e5 er blevet fjernet. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_de.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_de.properties index 784afb23af17f2379dfde79e2f5440353fcd6024..7c56bb5ee4557a877576e144f29d5fd3465817ab 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_de.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_de.properties @@ -27,8 +27,6 @@ There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\ Es existiert kein Arbeitsbereich fr dieses Projekt. Mgliche Grnde sind: The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=\ Das Projekt wurde vor kurzem umbenannt und noch kein Build unter dem neuen Namen ausgefhrt. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\ - Der Slave, auf dem dieses Projekt das letzte Mal ausgefhrt wurde, wurde entfernt. li3=Das Arbeitsbereichsverzeichnis ({0}) wurde auerhalb von Jenkins entfernt. text=Starten Sie einen Build, um von Jenkins einen Arbeitsbereich anlegen zu lassen. The\ workspace\ was\ wiped\ out\ and\ no\ build\ has\ been\ done\ since\ then.=Der Arbeitsbereich wurde gel\u00F6scht und es wurde seitdem kein Build durchgef\u00FChrt. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_es.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_es.properties index fc9d13524e66602aafaf07f1ec29b13f3f5c6cd1..58f2750bb3423ae4b73a6327eab1a099bd0d372d 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_es.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_es.properties @@ -26,7 +26,7 @@ text=Lanzar una ejecuci There''s\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=No hay espacio de trabajo para este proyecto, las causas posibles son: The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=El proyecto se ha renombrado y no se a ejecutado desde entonces Error\:\ no\ workspace=Error, no hay espacio de trabajo -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=El nodo esclavo donde se ejecut la ltima vez se ha eliminado +The\ agent\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=El agente donde se ejecut la ltima vez se ha eliminado The\ workspace\ was\ wiped\ out\ and\ no\ build\ has\ been\ done\ since\ then.=El espacio de trabajo se ha borrado, y no se ha ejecutado la tarea desde entonces. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_fr.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_fr.properties index 70d43848b321293c94f0967270ec8b6bf6ba531a..09aa43473944061daadcc73d399df2f378103464 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_fr.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_fr.properties @@ -24,6 +24,5 @@ Error\:\ no\ workspace=Erreur : pas de workspace A\ project\ won't\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ performed.=Un projet n''a pas de workspace avant un premier build. There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=Il n''y a pas de workspace existant pour ce projet. Les raisons possibles sont : The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=Le projet a \u00e9t\u00e9 renomm\u00e9 r\u00e9cemment et aucun build n''a \u00e9t\u00e9 fait avec ce nouveau nom. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=La machine esclave sur laquelle ce projet a \u00e9t\u00e9 lanc\u00e9 pour la derni\u00e8re fois a \u00e9t\u00e9 retir\u00e9e. li3=Le r\u00e9pertoire de travail ({0}) a \u00e9t\u00e9 d\u00e9plac\u00e9 hors de Jenkins. text=Lancer un build afin de faire cr\u00e9er un workspace par Jenkins. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ja.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ja.properties index 6f2a4b51856d7332072df660c644f2c24b776ab4..f8332b3369bbc542debb7e139671d2d05e78fa65 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ja.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ja.properties @@ -27,8 +27,6 @@ There''s\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\ \u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002\u4ee5\u4e0b\u306e\u7406\u7531\u304c\u8003\u3048\u3089\u308c\u307e\u3059\u3002 The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=\ \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u65b0\u3057\u3044\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d\u306b\u5909\u66f4\u3055\u308c\u305f\u5f8c\u306b\u3001\u305d\u306e\u540d\u524d\u3067\u30d3\u30eb\u30c9\u304c\u5b9f\u884c\u3055\u308c\u3066\u3044\u306a\u3044\u3002 -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\ - \u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u6700\u5f8c\u306b\u5b9f\u884c\u3057\u305f\u30b9\u30ec\u30fc\u30d6\u304c\u3001\u5916\u3055\u308c\u305f\u3002 li3=\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\uff08{0}\uff09\u304cJenkins\u306e\u7ba1\u7406\u5916\u3078\u53d6\u308a\u9664\u304b\u308c\u305f\u3002 text=\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3092\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002 The\ workspace\ was\ wiped\ out\ and\ no\ build\ has\ been\ done\ since\ then.=\ diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_nl.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_nl.properties index a569ad31227a6de65809639d245cd787bedcc4f2..2e441f20407920f6ca523661a5090080378745a4 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_nl.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_nl.properties @@ -24,6 +24,5 @@ Error\:\ no\ workspace=Fout : geen werkplaats beschikbaar A\ project\ won't\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ performed.=Een project zal geen werkplaats hebben tot er op zijn mins \u00E9\u00E9n bouwpoging plaatsgevonden heeft. There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=Er is geen werkplaats beschikbaar voor dit project. Mogelijke redenen zijn : The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=Dit project werd hernoemd en heeft nog bouwpoging plaats gevonden onder de nieuwe naam. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=De slaafnode die dit project het laatst gebouwd heeft werd verwijderd. li3=Het pad naar de werkplaats ({0}) werd buiten Jenkins verwijderd. text=Lanceer een bouwpoging om Jenkins de werkplaats te laten cre\u00EBren. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_pt_BR.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_pt_BR.properties index a05b67754518ad6748b1f00e83303e81fd36f788..7abc0567057a2aa67bc5d65d2a67f8c8668e94fc 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_pt_BR.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_pt_BR.properties @@ -22,7 +22,6 @@ Error\:\ no\ workspace=Erro: nenhum workspace The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=O projeto foi renomeado recentemente e nenhum build foi feito com um novo nome. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=A m\u00e1quina slave onde esse projeto executou pela ultima vez foi removida. li3=O diret\u00f3rio de workspace ({0}) foi removido externamente ao Jenkins. text=Execute um build para que o Jenkins crie um workspace. There''s\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=N\u00e3o existe nenhum workspace dispon\u00edvel para esse projeto diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ru.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ru.properties index d3cd6ba59db1dbe734ef0373eff3549a37812ef6..ca520bc3dfdd51a0256f60c8d2c1822c9b321fcb 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ru.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_ru.properties @@ -27,7 +27,5 @@ There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\ \u0421\u0431\u043e\u0440\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b: The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=\ \u041f\u0440\u043e\u0435\u043a\u0442 \u0431\u044b\u043b \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d \u0438 \u0441\u0431\u043e\u0440\u043e\u043a \u043f\u043e\u0434 \u043d\u043e\u0432\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u0435\u0449\u0435 \u043d\u0435 \u0431\u044b\u043b\u043e. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\ - \u041f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0441\u044f \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0440\u0430\u0437, \u0431\u044b\u043b \u0443\u0434\u0430\u043b\u0435\u043d. li3=\u0421\u0431\u043e\u0440\u043e\u0447\u043d\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f ({0}) \u0431\u044b\u043b\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0430 \u0438\u0437 \u0440\u0430\u0431\u043e\u0447\u0435\u0433\u043e \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 Jenkins. text=\u0417\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u0441\u0431\u043E\u0440\u043A\u0443, \u0447\u0442\u043E\u0431\u044B \u043F\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u044C Jenkins \u0441\u043E\u0437\u0434\u0430\u0442\u044C \u0441\u0431\u043E\u0440\u043E\u0447\u043D\u0443\u044E \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u044E. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_sr.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7c8d5110c9a3b5178372ae471c316b880db75a70 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_sr.properties @@ -0,0 +1,14 @@ +# This file is under the MIT License by authors + +Error\:\ no\ workspace=\u0413\u0440\u0435\u0448\u043A\u0430: \u043D\u0435\u043C\u0430 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 +A\ project\ won't\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ performed.=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043D\u0435\u045B\u0435 \u0438\u043C\u0430\u0442\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 \u0434\u043E\u043A \u0441\u0435 \u043D\u0435 \u0438\u0437\u0432\u0440\u0448\u0438 \u0458\u0435\u0434\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. +There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\u041D\u0435\u043C\u0430 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 \u0437\u0430 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442. \u041C\u043E\u0433\u0443\u045B\u0435 \u0458\u0435: +The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0458\u0435 \u0441\u043A\u043E\u0440\u043E \u043F\u0440\u0435\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u043D, \u0438 \u0458\u043E\u0448 \u043D\u0435\u043C\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u043F\u043E \u043D\u043E\u0432\u0438\u043C \u0438\u043C\u0435\u043D\u043E\u043C. +The\ agent\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\u0410\u0433\u0435\u043D\u0442 \u043E\u0432\u043E\u043C \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0443 \u043D\u0430 \u043A\u043E\u043C \u0458\u0435 \u0437\u0430\u0434\u045A\u0435 \u0438\u0437\u0432\u0440\u0448\u0435\u043D\u043E \u0458\u0435 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u043D. +li3=\u0420\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 "{0}" \u0458\u0435 \u0438\u0437\u0431\u0430\u0447\u0435\u043D \u0438\u0437 Jenkins. +The\ workspace\ was\ wiped\ out\ and\ no\ build\ has\ been\ done\ since\ then.=\u041D\u0438\u0458\u0435 \u0431\u0438\u043B\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043E\u0442\u043A\u0430\u0434 \u0458\u0435 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u043D. +text=\u041F\u043E\u043A\u0440\u0435\u043D\u0438\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0438 Jenkins \u045B\u0435 \u0441\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440. +Error=\ no workspace=\u0413\u0440\u0435\u0448\u043A\u0430: \u043D\u0435\u043C\u0430 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430 +There''s\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\u041D\u0435\u043C\u0430 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430 \u0437\u0430 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442. \u041C\u043E\u0433\u0443\u045B\u0435 \u0458\u0435: +A\ project\ won''t\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ performed.=\u041F\u0440\u043E\u0458\u043A\u0442\u0438 \u043D\u0435\u045B\u0435 \u0438\u043C\u0430\u0442\u0438 \u0440\u0430\u0434\u043D\u0438\u0445 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430 \u0434\u043E\u043A \u0441\u0435 \u043D\u0435 \u0438\u0437\u0432\u0440\u0448\u0438 \u0458\u0435\u0434\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430. +The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\u041F\u043E\u043C\u043E\u045B\u043D\u0438\u043A \u043E\u0432\u043E\u043C \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0443 \u043D\u0430 \u043A\u043E\u043C \u0458\u0435 \u0437\u0430\u0434\u045A\u0435 \u0438\u0437\u0432\u0440\u0448\u0435\u043D\u043E \u0458\u0435 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u043D. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_tr.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_tr.properties index aa57c214494f22ee8d103a14c3b091187a290ce7..0696ad6f25a7fa52b16f4f59a5bd785acbdf810d 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_tr.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_tr.properties @@ -26,4 +26,3 @@ Error\:\ no\ workspace=Hata\:\ \u00c7al\u0131\u015fma Alan\u0131 mevcut de\u011f A\ project\ won't\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ performed.=Bir\ proje,\ en\ az\u0131ndan\ bir\ yap\u0131land\u0131rma\ \u00e7al\u0131\u015ft\u0131r\u0131lmadan\ bir\ \u00e7al\u0131\u015fma\ alan\u0131na\ sahip\ olamaz. There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=Bu\ projenin\ bir\ \u00e7al\u0131\u015fma\ alan\u0131\ yok.\ Muhtemel\ sebepler\: The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=Projenin\ ismi\ yeni\ de\u011fi\u015ftirildi\ ve\ yeni\ isim\ alt\u0131nda\ herhangi\ bir\ yap\u0131land\u0131rma\ \u00e7al\u0131\u015ft\u0131r\u0131lmad\u0131. -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=Bu projenin en son \u00fczerinde \u00e7al\u0131\u015ft\u0131\u011f\u0131 slave silinmi\u015f. diff --git a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_zh_TW.properties b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_zh_TW.properties index 3c4872742177c70104723c802e207eb23c62d492..c3b0d8184ad556edeaf54658fa1d83df2032c57c 100644 --- a/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_zh_TW.properties +++ b/core/src/main/resources/hudson/model/AbstractItem/noWorkspace_zh_TW.properties @@ -26,7 +26,6 @@ A\ project\ won't\ have\ any\ workspace\ until\ at\ least\ one\ build\ is\ perfo There's\ no\ workspace\ for\ this\ project.\ Possible\ reasons\ are\:=\ \u5c08\u6848\u6c92\u6709\u5de5\u4f5c\u5340\u3002\u53ef\u80fd\u7684\u539f\u56e0\u6709: The\ project\ was\ renamed\ recently\ and\ no\ build\ was\ done\ under\ the\ new\ name.=\u5C08\u6848\u6700\u8FD1\u6539\u540D\u4E86\uFF0C\u800C\u4E14\u6539\u540D\u5F8C\u9084\u6C92\u5EFA\u7F6E\u904E\u3002 -The\ slave\ this\ project\ has\ run\ on\ for\ the\ last\ time\ was\ removed.=\u6700\u5F8C\u4E00\u6B21\u5EFA\u7F6E\u672C\u5C08\u6848\u7684 Slave \u88AB\u79FB\u9664\u4E86\u3002 li3=\u5DE5\u4F5C\u5340\u76EE\u9304 ({0}) \u5728 Jenkins \u5916\u88AB\u522A\u9664\u4E86\u3002 The\ workspace\ was\ wiped\ out\ and\ no\ build\ has\ been\ done\ since\ then.=\u5DE5\u4F5C\u5340\u88AB\u6E05\u9664\uFF0C\u800C\u4E14\u5230\u76EE\u524D\u70BA\u6B62\u9084\u6C92\u6709\u5EFA\u7F6E\u904E\u3002 diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_bg.properties b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..ce43fb6569eea3c2acd240ef64ac449ff8e66ff5 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Submit=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_pl.properties b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..6b45cc35e76b5226861cda595dd82768eda1ef82 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_pl.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Submit=Zapisz diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_sr.properties b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c8e10fc8ec69e893059e2f2cc4ec087c5fc78321 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/descriptionForm_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Submit=\u041F\u043E\u0434\u043D\u0435\u0441\u0438 diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/editDescription.jelly b/core/src/main/resources/hudson/model/AbstractModelObject/editDescription.jelly index 2e211b6221287f49c065d8e7d40d580dc588c55c..91940efa8d4091a42d10887dea83310bc360ccbd 100644 --- a/core/src/main/resources/hudson/model/AbstractModelObject/editDescription.jelly +++ b/core/src/main/resources/hudson/model/AbstractModelObject/editDescription.jelly @@ -33,7 +33,9 @@ THE SOFTWARE.
  9. @@ -55,16 +68,16 @@ THE SOFTWARE. ${%Uninstall}
    + + @@ -106,16 +119,30 @@ THE SOFTWARE. +

    ${%Uninstallation pending}

    - -
    - -
    -
    + + +
    + + + +
    +
    + +
    + + + +
    +
    +
    + +
    +
    - +
    diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/editDescription_bg.properties b/core/src/main/resources/hudson/model/AbstractModelObject/editDescription_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..ce43fb6569eea3c2acd240ef64ac449ff8e66ff5 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/editDescription_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Submit=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/editDescription_sr.properties b/core/src/main/resources/hudson/model/AbstractModelObject/editDescription_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c8e10fc8ec69e893059e2f2cc4ec087c5fc78321 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/editDescription_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Submit=\u041F\u043E\u0434\u043D\u0435\u0441\u0438 diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/error_bg.properties b/core/src/main/resources/hudson/model/AbstractModelObject/error_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..1f47752c3f91182b436a8268afaf971d6d0f1d3c --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/error_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Error=\ + \u0413\u0440\u0435\u0448\u043a\u0430 +Detail...=\ + \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438\u2026 diff --git a/core/src/main/resources/hudson/model/AbstractModelObject/error_sr.properties b/core/src/main/resources/hudson/model/AbstractModelObject/error_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..29271bc5b99d5bb966a13a57ea99850aaea7ede9 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractModelObject/error_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +Detail...=\u0414\u0435\u0442\u0430\u0459\u0438... diff --git a/core/src/main/resources/hudson/model/AbstractProject/BecauseOfUpstreamBuildInProgress/summary_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/BecauseOfUpstreamBuildInProgress/summary_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..4e71e9115da409f5896d975e198253b7701c6712 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/BecauseOfUpstreamBuildInProgress/summary_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# note for translators: this message is referenced from st:structuredMessageFormat +description=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u201e{0}\u201c, \u043e\u0442 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u0437\u0430\u0432\u0438\u0441\u0438, \u0432\u0435\u0447\u0435 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430. diff --git a/core/src/main/resources/hudson/model/AbstractProject/BecauseOfUpstreamBuildInProgress/summary_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/BecauseOfUpstreamBuildInProgress/summary_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..99a47ce6730324724c44b97a4ad128969f91d078 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/BecauseOfUpstreamBuildInProgress/summary_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +description=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 "{0}", \u043E\u0434 \u043A\u043E\u0433\u0430 \u043E\u0432\u0430\u0458 \u0437\u0430\u0432\u0438\u0441\u0438, \u0441\u0435 \u0432\u0435\u045B \u0433\u0440\u0430\u0434\u0438. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/AbstractProject/changes_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/changes_bg.properties index 377ea21e939b944bc24ab25d1acf2a6b7c00ecf7..deadd5410fb77150aee70c57742049e92a35790d 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/changes_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/changes_bg.properties @@ -1,3 +1,32 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0438 +Changes=\ + \u041f\u0440\u043e\u043c\u0450\u043d\u0438 +to.label=\ + \u0434\u043e #{0} +from.label=\ + \u043e\u0442 #{0} +changes.title=\ + {0} \u043f\u0440\u043e\u043c\u0450\u043d\u0438 +range.label=\ + \u043e\u0442 #{0} \u0434\u043e #{1} diff --git a/core/src/main/resources/hudson/model/AbstractProject/changes_pl.properties b/core/src/main/resources/hudson/model/AbstractProject/changes_pl.properties index 339b5fab61e076c263ead8cb98335fe2cefcaed4..faba046523585529c486cf13f18811d90cec91ca 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/changes_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/changes_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Changes=Zmiany +Changes=Rejestr zmian diff --git a/core/src/main/resources/hudson/model/AbstractProject/changes_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/changes_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d12d7fda35cf8ae55f31caf453e39e6cb234c490 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/changes_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +changes.title={0} \u043F\u0440\u043E\u043C\u0435\u043D\u0435 +Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0435 +range.label=\ \u043E\u0434 #{0} \u0434\u043E #{1} +from.label=\ \u043E\u0434 #{0} +to.label=\ \u0434\u043E #{0} diff --git a/core/src/main/resources/hudson/model/AbstractProject/configure-common.jelly b/core/src/main/resources/hudson/model/AbstractProject/configure-common.jelly index 62b5bd176a96a8396245a275c6a4ba7b8c9d8fe2..806067f21095e0480a85f991f38c2137f1ce8bb3 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/configure-common.jelly +++ b/core/src/main/resources/hudson/model/AbstractProject/configure-common.jelly @@ -48,19 +48,17 @@ THE SOFTWARE. - - - - - - - - - - - - - + + + + + + + + + + + diff --git a/core/src/main/resources/hudson/model/AbstractProject/configure-common_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/configure-common_bg.properties index ad363cc302056d3e273ea1bf73de44dedb77cbf9..aab9d48983cc80e9f7338b17581bdfd35dd1f7e1 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/configure-common_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/configure-common_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Restrict\ where\ this\ project\ can\ be\ run=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0438 \u043A\u044A\u0434\u0435 \u0434\u0430 \u0441\u0435 \u043F\u0443\u0441\u043A\u0430 \u0442\u043E\u0437\u0438 \u043F\u0440\u043E\u0435\u043A\u0442 +Keep\ the\ build\ logs\ of\ dependencies=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0436\u0443\u0440\u043d\u0430\u043b\u0438\u0442\u0435 \u0441 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\u0442\u0435 +Advanced\ Project\ Options=\ + \u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 +JDK\ to\ be\ used\ for\ this\ project=\ + JDK \u0437\u0430 \u0442\u043e\u0437\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 +Display\ Name=\ + \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u043e \u0438\u043c\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractProject/configure-common_pl.properties b/core/src/main/resources/hudson/model/AbstractProject/configure-common_pl.properties index cda4b2957f2611a64936e7c186ec34b28ee2ee52..7f251d1bedfe2278528a5ade5167454af7505c67 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/configure-common_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/configure-common_pl.properties @@ -1,7 +1,24 @@ -# This file is under the MIT License by authors - -Advanced\ Project\ Options=Zaawansowane opcje projektu -Display\ Name=Nazwa wy\u015bwietlana -JDK\ to\ be\ used\ for\ this\ project=JDK u\u017cyte do budowy projektu -default.value=(Domy\u015blny) -Keep\ the\ build\ logs\ of\ dependencies=Trzymaj logi projekt\u00f3w zale\u017cnych +# The MIT License +# +# Copyright (c) 2004-2016, Sun Microsystems, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Display\ Name=Nazwa wy\u015Bwietlana +JDK\ to\ be\ used\ for\ this\ project=JDK u\u017Cyte do budowy projektu +Keep\ the\ build\ logs\ of\ dependencies=Trzymaj logi konsoli projekt\u00F3w zale\u017Cnych diff --git a/core/src/main/resources/hudson/model/AbstractProject/configure-common_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/configure-common_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6f82603f0a88896fe290621beaa731ae7e8446fc --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/configure-common_sr.properties @@ -0,0 +1,13 @@ +# This file is under the MIT License by authors + +JDK\ to\ be\ used\ for\ this\ project=JDK \u043A\u043E\u0458\u0438 \u045B\u0435 \u0441\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u0430 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +Display\ Name=\u0418\u043C\u0435 +Keep\ the\ build\ logs\ of\ dependencies=\u0417\u0430\u0434\u0440\u0436\u0438 \u0436\u0443\u0440\u043D\u0430\u043B \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u043E\u0434 \u0437\u0430\u0432\u0438\u0441\u043D\u0438\u0445 +Advanced\ Project\ Options=\u041D\u0430\u043F\u0440\u0435\u0434\u043D\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +default.value=(\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434) +Restrict\ where\ this\ project\ can\ be\ run=O\u0433\u0440\u0430\u043D\u0438\u0447\u0438 \u0433\u0434\u0435 \u0458\u0435 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u0438\u0437\u0432\u0440\u0448\u0435\u043D +Tie\ this\ project\ to\ a\ node=\u041F\u043E\u0432\u0435\u0436\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0441\u0430 \u043C\u0430\u0448\u0438\u043D\u043E\u043C +Node=\u041C\u0430\u0448\u0438\u043D\u0430 +Advanced\ Project\ Options\ configure-common=\u041D\u0430\u043F\u0440\u0435\u0434\u043D\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +title.concurrentbuilds=\u041E\u0431\u0430\u0432\u0459\u0430 \u043F\u0430\u0440\u0430\u043B\u0435\u043B\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0430\u043A\u043E \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u043E \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E +Label\ Expression=\u041D\u0430\u043F\u0440\u0435\u0434\u043D\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString.html b/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString.html deleted file mode 100644 index e854b1d17b1bd1daf57603c36a777f04b2d42643..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString.html +++ /dev/null @@ -1,52 +0,0 @@ -
    - If you want to always run this project on a specific node/slave, just specify its name. - This works well when you have a small number of nodes. - -

    - As the size of the cluster grows, it becomes useful not to tie projects to specific slaves, - as it hurts resource utilization when slaves may come and go. For such situation, assign labels - to slaves to classify their capabilities and characteristics, and specify a boolean expression - over those labels to decide where to run. - -

    Valid Operators

    -

    - The following operators are supported, in the order of precedence. -

    -
    (expr)
    -
    parenthesis
    - -
    !expr
    -
    negation
    - -
    expr&&expr
    -
    - and -
    - -
    expr||expr
    -
    - or -
    - -
    a -> b
    -
    - "implies" operator. Equivalent to !a|b. - For example, windows->x64 could be thought of as "if run on a Windows slave, - that slave must be 64bit." It still allows Jenkins to run this build on linux. -
    - -
    a <-> b
    -
    - "if and only if" operator. Equivalent to a&&b || !a&&!b. - For example, windows<->sfbay could be thought of as "if run on a Windows slave, - that slave must be in the SF bay area, but if not on Windows, it must not be in the bay area." -
    -
    -

    - All operators are left-associative (i.e., a->b->c <-> (a->b)->c ) - An expression can contain whitespace for better readability, and it'll be ignored. - -

    - Label names or slave names can be quoted if they contain unsafe characters. For example, - "jenkins-solaris (Solaris)" || "Windows 2008" -

    diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString_zh_TW.html b/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString_zh_TW.html deleted file mode 100644 index 22b9144733baba9127b86c78cc96f8c6cd6123a0..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/AbstractProject/help-assignedLabelString_zh_TW.html +++ /dev/null @@ -1,50 +0,0 @@ -
    - 如果您想只在特定的節點或 Slave 上建置這個專案,請直接輸入該節點的名稱。 - 在節點不多時這樣子就很好用了。 - -

    - 如果叢集越來越大,那最好不要將專案限定到某一台 Slave 上,因為 Slave 可能會來來去去,進而影響到資源利用率。 - 這種情況下,建議在 Slave 上面設定標籤,依照能力及特性分類,並設定標籤的布林表示式來決定要執行的節點。 - -

    有效的運算符號

    -

    - 支援下面這些運算符號,依照優先順序高到低排列。 -

    -
    (expr)
    -
    括號
    - -
    !expr
    -
    - -
    expr&&expr
    -
    - 且 -
    - -
    expr||expr
    -
    - 或 -
    - -
    a -> b
    -
    - 「蘊涵」運算符號 (若 a 則 b)。等價於 !a|b。 - 舉例來說,windows->x64 可以想成是「如果在 Windows Slave 上執行,一定要 64 位元的環境」。 - Jenkins 還是可以在 Linux 主機上面建置這個專案。 -
    - -
    a <-> b
    -
    - 「若且唯若」運算符號。等價於 a&&b || !a&&!b。 - 舉例來說,windows<->taipei 可以想成是「如果在 Windows Slave 上執行,該節點一定要在臺北; - 不過要是不在 Windows 上執行,就一定不能在臺北」。 -
    -
    -

    - 所有運算符號都是由左向右算的 (Left-Associative; 例如 a->b->c <-> (a->b)->c ) - 為了方便閱讀,表示式裡可以用半形空白,運算時會被忽略。 - -

    - 標籤名稱或 Slave 名稱中如果有不安全的字元,可以用半形括號括起來。例如: - "jenkins-solaris (Solaris)" || "Windows 2008" -

    diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild.html b/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild.html index 6c5752360af8f33906377d11de1fb972cc388262..7d2116b37a0a7d7b5b2f88d77caafede88ae2ea9 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild.html +++ b/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild.html @@ -1,24 +1,39 @@ -
    - If this option is checked, Jenkins will schedule and execute multiple builds concurrently (provided - that you have sufficient executors and incoming build requests.) This is useful on builds and test jobs that - take a long time, as each build will only contain a smaller number of changes, and the total turn-around - time decreases due to the shorter time a build request spends waiting for the previous build to complete. - It is also very useful with parameterized builds, whose individual executions are independent from each other. - -

    - For other kinds of jobs, allowing concurrent executions of multiple builds may be problematic, - for example if it assumes a monopoly on a certain resource, like database, or for jobs where you use Jenkins - as a cron replacement. -

    - If you use a custom workspace and enable this option, all your builds will run on the same workspace, - thus unless a care is taken by your side, it'll likely to collide with each other. - Otherwise, even when they are run on the same node, Jenkins will use different workspaces to keep - them isolated. - -

    - When Jenkins creates different workspaces for isolation, Jenkins appends "@num" to the - workspace directory name, e.g. "@2". The separator "@" can be configured by setting the system property - "hudson.slaves.WorkspaceList" to the desired separator string on the Jenkins command line. - E.g. "-Dhudson.slaves.WorkspaceList=-" will use a dash as separator. +

    + When this option is checked, multiple builds of this project may be executed + in parallel. +

    + By default, only a single build of a project is executed at a time — any + other requests to start building that project will remain in the build queue + until the first build is complete.
    + This is a safe default, as projects can often require exclusive access to + certain resources, such as a database, or a piece of hardware. +

    + But with this option enabled, if there are enough build executors available + that can handle this project, then multiple builds of this project will take + place in parallel. If there are not enough available executors at any point, + any further build requests will be held in the build queue as normal. +

    + Enabling concurrent builds is useful for projects that execute lengthy test + suites, as it allows each build to contain a smaller number of changes, while + the total turnaround time decreases as subsequent builds do not need to wait + for previous test runs to complete.
    + This feature is also useful for parameterised projects, whose individual build + executions — depending on the parameters used — can be + completely independent from one another. +

    + Each concurrently executed build occurs in its own build workspace, isolated + from any other builds. By default, Jenkins appends "@<num>" to + the workspace directory name, e.g. "@2".
    + The separator "@" can be changed by setting the + hudson.slaves.WorkspaceList Java system property when starting + Jenkins. For example, "hudson.slaves.WorkspaceList=-" would change + the separator to a hyphen.
    + For more information on setting system properties, see the wiki page. +

    + However, if you enable the Use custom workspace option, all builds will + be executed in the same workspace. Therefore caution is required, as multiple + builds may end up altering the same directory at the same time.

    diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild_bg.html b/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..191bee10f3c8a3df1118b492d171af1639359703 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/help-concurrentBuild_bg.html @@ -0,0 +1,42 @@ + +
    + Когато тази опция е избрана, паралелно може да се изпълняват множество + изграждания на този проект. +

    + Стандартно, в един момент се изпълнява максимум едно изграждане на отделен + проект — последващите заявки за изграждането на проекта се поставят в опашка + да изчакат завършването на текущото изграждане, преди да се продължи със + следващото.
    + Това е по-безопасният вариант, защото често проектите изискват достъпът до + определени ресурси да е поединично — например база от данни или някакво + хардуерно устройство. +

    + Ако изберете тази опция и в даден момент има достатъчно изграждащи машини, то + паралелно ще могат да се изпълняват множество изграждания на проекта. Ако в + определен момент няма достатъчно свободни машини, то заявките за изграждане ще + изчакват в опашка както обикновено. +

    + Включването на паралелните изграждание е полезно при проекти с дълги тестове, + защото това позволява отделното изграждане да съдържа сравнително малък на + брой промени, без това да увеличава прекомерно много времето за работа, защото + всяко ново изграждане няма нужда да изчаква завършването на всички предишни + изграждания.
    + Тази възможност е полезна и за параметризираните проекти, чиито изграждания + може да са напълно независими едно от друго — при определени стойности на + параметрите. +

    + Всяко Each concurrently executed build occurs in its own build workspace, isolated + from any other builds. By default, Jenkins appends "@<num>" to + the workspace directory name, e.g. "@2".
    + The separator "@" can be changed by setting the + hudson.slaves.WorkspaceList Java system property when starting + Jenkins. For example, "hudson.slaves.WorkspaceList=-" would change + the separator to a hyphen.
    + For more information on setting system properties, see the wiki page. +

    + However, if you enable the Use custom workspace option, all builds will + be executed in the same workspace. Therefore caution is required, as multiple + builds may end up altering the same directory at the same time. +

    diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-label.html b/core/src/main/resources/hudson/model/AbstractProject/help-label.html new file mode 100644 index 0000000000000000000000000000000000000000..df1b6a104aff00203bc4d64d16bd34980f602a24 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/help-label.html @@ -0,0 +1,128 @@ +
    + Defines a logical expression which determines which agents may execute builds + of this project. This expression, when tested against the name and labels of + each available agent, will be either true or false. If the + expression evaluates to true, then that agent will be allowed to + execute builds of this project. +

    + If this project should always be built on a specific agent, or on the Jenkins + master, then you can just enter the agent's name, or master, + respectively. +

    + However, you should generally avoid using the Name of an agent here, + preferring to target the Labels of an agent. As documented on the + configuration page for each agent, and the Configure System page for + the master, labels can be used to represent which operating system the agent + is running on, its CPU architecture, or any number of other characteristics. +
    + Using labels removes the need to re-configure the label expression entered + here each time that you add, remove, or rename agents. +

    + A label expression can be as simple as entering a single label or + agent name, for example android-builder, or + linux-machine-42.
    + You can also make use of various operators to create more complex + expressions. + +

    Supported operators

    + The following operators are supported, in descending order of precedence: +
    +
    (expression)
    +
    + parentheses — used to explicitly define the associativity of an expression +
    + +
    !expression
    +
    + NOT — negation; the result of expression must not be true +
    + +
    a && b
    +
    + AND — both of the expressions a and b must be + true +
    + +
    a || b
    +
    + OR — either of the expressions a or b may be + true +
    + +
    a -> b
    +
    + "implies" operator — equivalent to !a || b.
    + For example, windows -> x64 could be thought of as "if a Windows + agent is used, then that agent must be 64-bit", while still + allowing this project to be executed on any agents that do not have + the windows label, regardless of whether they have also have an + x64 label +
    + +
    a <-> b
    +
    + "if and only if" operator — equivalent to a && b || + !a && !b
    + For example, windows <-> dc2 could be thought of as "if a + Windows agent is used, then that agent must be in datacenter 2, but + if a non-Windows agent is used, then it must not be in datacenter + 2" +
    +
    + +

    Notes

    +
      +
    • + All operators are left-associative, i.e. a -> b -> c is + equivalent to (a -> b) -> c. +
    • +
    • + Labels or agent names can be surrounded with quotation marks if they + contain characters that would conflict with the operator syntax.
      + For example, "osx (10.11)" || "Windows Server". +
    • +
    • + Expressions can be written without whitespace, but including it is + recommended for readability; Jenkins will ignore whitespace when + evaluating expressions. +
    • +
    • + Matching labels or agent names with wildcards or regular expressions is + not supported. +
    • +
    • + An empty expression will always evaluate to true, matching all + agents. +
    • +
    + +

    Examples

    +
    +
    master
    +
    Builds of this project may be executed only on the Jenkins master
    + +
    linux-machine-42
    +
    + Builds of this project may be executed only on the agent with the name + linux-machine-42 (or on any machine that happens to have a label + called linux-machine-42) +
    + +
    windows && jdk9
    +
    + Builds of this project may be executed only on any Windows agent that has + version 9 of the Java Development Kit installed (assuming that agents + with JDK 9 installed have been given a jdk9 label) +
    + +
    postgres && !vm && (linux || freebsd)
    +
    + Builds of this project may be executed only any on Linux or FreeBSD agent, + so long as they are not a virtual machine, and they have PostgreSQL + installed (assuming that each agent has the appropriate labels — in + particular, each agent running in a virtual machine must have the + vm label in order for this example to work as expected) +
    + +
    +
    diff --git a/core/src/main/resources/hudson/model/AbstractProject/help-label_bg.html b/core/src/main/resources/hudson/model/AbstractProject/help-label_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..a47aa93409dca1acfc564b01904f72a41739f27e --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/help-label_bg.html @@ -0,0 +1,128 @@ +
    + Логически израз, който определя кои агенти могат да изграждат този проект. + Изразът ще се изчисли с всеки етикет и име на всеки наличен агент и резултатът + ще е или истина, или лъжа. Само когато изразът се изчисли като + истина, агенът ще може да изгражда този проект. +

    + Ако проектът трябва задължително да се изгражда на определен подчинен компютър + или на основния, въведете съответно името на компютъра или + master. +

    + Като цяло трябва да избягвате употребата на името на подчинения + компютър като вместо това използвате етикетите на компютрите. Както е + документирано на страницата за настройки на всеки агент и страницата за + Системни настройки на основния компютър, етикетите могат да се + използват за определяне на кои операционни системи върви Jenkins, каква е + архитектурата на процесора както и на всякакви други характеристики. +
    + Като използвате етикети елиминирате нуждата да преправяте етикетните изрази + всеки път като добавяте, махате или преименувате машини. +

    + Етикетният израз може да е съвсем прост, напр. единичен етикет или + име на машина като android-builder или + linux-machine-42.
    + Може да ползвате и някоиоператори, за да създавате по-сложни изрази. + +

    Поддържани оператори

    + Поддържат се следните оператори в намаляващ приоритет: +
    +
    (израз)
    +
    + скоби — за изрично указване на приоритета на операция +
    + +
    !израз
    +
    + НЕ — отрицание, стойността на израза трябва да не е + истина. +
    + +
    a && b
    +
    + И — и двата израза a и b трябва да са + истина. +
    + +
    a || b
    +
    + ИЛИ — някой от изразите a или b трябва да е + истина. +
    + +
    a -> b
    +
    + ИМПЛИКАЦИЯ — АКО - ТО, същото като !a || b.
    + Напр. windows -> x64 означава: „ако се ползва компютър под + Windows, той трябва да е 64-битов“, което също позволява проектът + да бъде изграждан на машини без етикета windows, без + значение дали имат или не етикетаx64. +
    + +
    a <-> b
    +
    + ЕКВИВАЛЕНТНОСТ — АКО И САМО АКО, същото като a && b || + !a && !b
    + Напр. windows <-> dc2 означава: „ако се ползва компютър под + Windows, той трябва да е в центъра за данни № 2, ако обаче се + ползва компютър, който не е под Windows, той не трябва да е в + центъра за данни № 2“. +
    +
    + +

    Бележки

    +
      +
    • + Асоциативността на всички оператори е лява, т. е. a -> b -> c + означава: (a -> b) -> c. +
    • +
    • + Етикетите или имената на компютрите може да са заградени в кавички, ако + съдържат знаци, които противоречат на синтаксиса на операторите.
      + Напр. "osx (10.11)" || "Windows Server". +
    • +
    • + Не е задължително да слагате интервали в изразите, но е добре да го + правите за четимост. Jenkins прескача празните знаци при изчисляването на + изразите. +
    • +
    • + Напасване на етикетите или имената на компютрите с шаблони или регуларни + изрази не се поддържа. +
    • +
    • + Празен израз се изчислява като истина и напасва всички машини. +
    • +
    + +

    Примери

    +
    +
    master
    +
    Изгражданията на този проект може да са само на основния компютър на + Jenkins. +
    + +
    linux-machine-42
    +
    + Проектът може да бъде изграден само на агент с име + linux-machine-42 (или на всяка машина, която има етикет на име + linux-machine-42). +
    + +
    windows && jdk9
    +
    + Изгражданията може да се извършат на всеки подчинен компютър, който е с + Windows и има версия 9 на комплекта за разработчици на Java (като + приемаме, че всеки компютър с инсталиран JDK 9 има етикета jdk9). +
    + +
    postgres && !vm && (linux || freebsd)
    +
    + Изгражданията на този проект може да са на всеки агент под Linux или + FreeBSD, стига да не са във във виртуала машина, и да е инсталирана + базата PostgreSQL (като приемаме, че на всяка машина са поставени + съответните етикети, напр. всяка виртуална машина е с етикет vm, + иначе примерът няма да сработи). +
    + +
    +
    diff --git a/core/src/main/resources/hudson/model/AbstractProject/main_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/main_bg.properties index 3173ac136b98ed0a6c3bee0b358bf70576a24821..3c18c1b18d00b071b9140ae3b37860d751971d1a 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/main_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/main_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,6 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Successful\ Artifacts=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438 \u0443\u0441\u043F\u0435\u0448\u043D\u0438 \u0430\u0440\u0442\u0438\u0444\u0430\u043A\u0442\u0438 -Recent\ Changes=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0438 \u043F\u0440\u043E\u043C\u0435\u043D\u0438 -Workspace=\u0420\u0430\u0431\u043E\u0442\u043D\u043E \u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u043E +Last\ Successful\ Artifacts=\ + \u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 \u043e\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +Recent\ Changes=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u043f\u0440\u043e\u043c\u0450\u043d\u0438 +Workspace=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e diff --git a/core/src/main/resources/hudson/model/AbstractProject/main_pl.properties b/core/src/main/resources/hudson/model/AbstractProject/main_pl.properties index db7ba5366759ed6e285397603e20c128974c82fd..55645387b97c4439959cdc1a7c948503c319d4a8 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/main_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/main_pl.properties @@ -21,5 +21,5 @@ # THE SOFTWARE. Last\ Successful\ Artifacts=Ostatnie Powiedzione Artefakty -Recent\ Changes=Ostatnie zmiany -Workspace=Obszar roboczy +Recent\ Changes=Rejestr zmian +Workspace=Przestrze\u0144 robocza diff --git a/core/src/main/resources/hudson/model/AbstractProject/main_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/main_sr.properties index 543c3b75fdd485f925fde4a5dc0f249a1d8daf14..9ae2b613dc4677f9751daaa0c49bb9ef7da65400 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/main_sr.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/main_sr.properties @@ -1,4 +1,6 @@ # This file is under the MIT License by authors -Last\ Successful\ Artifacts=Poslednji uspe\u0161ni artifakt -Recent\ Changes=Nedavne promene +Recent\ Changes=\u041D\u0435\u0434\u0430\u0432\u043D\u0435 \u043F\u0440\u043E\u043C\u0435\u043D\u0435 +Workspace=\u0420\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 +Last\ Successful\ Artifacts=\u041F\u043E\u0441\u043B\u0435\u0434\u045A\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u0438 Artifacts +Latest\ Console\ output=\u041F\u043E\u0441\u043B\u0435\u0434\u045A\u0438 \u0438\u0441\u0445\u043E\u0434 \u0438\u0437 \u043A\u043E\u043D\u0437\u043E\u043B\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_bg.properties index 3ed94ba3422985d18a603638db938881dfac902b..e7cae3eb5616730e7dba59caf33126a30e2bbfe9 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Project=\u0417\u0430\u0431\u0440\u0430\u043D\u0438 \u043F\u0440\u043E\u0435\u043A\u0442 +Disable\ Project=\ + \u0418\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 +Enable=\ + \u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 +This\ project\ is\ currently\ disabled=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d diff --git a/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ccf1bf9b675dcde44a00921ecd658a055194a05a --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/makeDisabled_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +This\ project\ is\ currently\ disabled=\u041E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0458\u0435 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D +Enable=\u041E\u043C\u043E\u0433\u0443\u045B\u0438 +Disable\ Project=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 diff --git a/core/src/main/resources/hudson/model/AbstractProject/sidepanel_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/sidepanel_bg.properties index 9f36e0f6908504d6591fcf83730314d070669314..d5845c54d551476f364cfa3abb7fc7436e5127d1 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/sidepanel_bg.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/sidepanel_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,17 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Dashboard=\u043a\u044a\u043c \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0442\u043e \u0422\u0430\u0431\u043b\u043e -Changes=\u041f\u0440\u043e\u043c\u0435\u043d\u0438 -Status=\u0421\u0442\u0430\u0442\u0443\u0441 -Wipe\ Out\ Workspace=\u0418\u0437\u0442\u0440\u0438\u0439 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043c\u044f\u0441\u0442\u043e -Workspace=\u0420\u0430\u0431\u043e\u0442\u043d\u043e \u043c\u044f\u0441\u0442\u043e -wipe.out.confirm=\u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e? +Back\ to\ Dashboard=\ + \u041a\u044a\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f \u0435\u043a\u0440\u0430\u043d +Changes=\ + \u041f\u0440\u043e\u043c\u0450\u043d\u0438 +Status=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 +Wipe\ Out\ Workspace=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e +Workspace=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e +wipe.out.confirm=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e? +Up=\ + \u041d\u0430\u0433\u043e\u0440\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractProject/sidepanel_pl.properties b/core/src/main/resources/hudson/model/AbstractProject/sidepanel_pl.properties index 5b8c2058925a4d54f35a4404bcf02b87c406fc14..9e14bfa982b6236f08adf8e7becf9d888f9ace29 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/sidepanel_pl.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/sidepanel_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Copyright (c) 2004-2016, Sun Microsystems, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,8 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Dashboard=Powr\u00f3t do Dashboard''u +Back\ to\ Dashboard=Powr\u00F3t do tablicy Changes=Rejestr zmian -Wipe\ Out\ Workspace=Wyczy\u015b\u0107 przestrze\u0144 robocz\u0105 +Wipe\ Out\ Workspace=Wyczy\u015B\u0107 przestrze\u0144 robocz\u0105 Workspace=Przestrze\u0144 robocza -wipe.out.confirm=Czy na pewno wyczy\u015bci\u0107 przestrze\u0144 robocz\u0105? +wipe.out.confirm=Czy na pewno wyczy\u015Bci\u0107 przestrze\u0144 robocz\u0105? +Status=Status +Up=Powr\u00F3t diff --git a/core/src/main/resources/hudson/model/AbstractProject/sidepanel_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/sidepanel_sr.properties index 2eebf4c9818f3b450ef086da52ccc91ee315a18e..ef47d9183d6395e97bcbad6d05b29db360c3ca9d 100644 --- a/core/src/main/resources/hudson/model/AbstractProject/sidepanel_sr.properties +++ b/core/src/main/resources/hudson/model/AbstractProject/sidepanel_sr.properties @@ -1,6 +1,10 @@ # This file is under the MIT License by authors -Back\ to\ Dashboard=Nazad na Tablu -Changes=Izmene -Wipe\ Out\ Workspace=Obrisi Workspace -wipe.out.confirm=Da li si siguran da \u017eeli\u0161 da poni\u0161ti\u0161 radni prostor +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 +Changes=\u041F\u0440\u043E\u043C\u0435\u043D\u0435 +Wipe\ Out\ Workspace=\u0418\u0437\u0431\u0440\u0438\u0448\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 +wipe.out.confirm=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043F\u043E\u043D\u0438\u0448\u0442\u0438\u0442\u0435 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440? +Up=\u041D\u0430\u0433\u043E\u0440\u0435 +Status=\u0421\u0442\u0430\u045A\u0435 +Workspace=\u0420\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 +View\ Configuration=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractProject/wipeOutWorkspaceBlocked_bg.properties b/core/src/main/resources/hudson/model/AbstractProject/wipeOutWorkspaceBlocked_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..0b71e014b2ed07d9b60ddf59ca51ae36f14f14bc --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/wipeOutWorkspaceBlocked_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +The\ SCM\ for\ this\ project\ has\ blocked\ this\ attempt\ to\ wipe\ out\ the\ project''s\ workspace.=\ + \u0421\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430\ + \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. +Error\:\ Wipe\ Out\ Workspace\ blocked\ by\ SCM=\ + \u0413\u0440\u0435\u0448\u043a\u0430: \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0435 \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0435\u043d\u043e \u043e\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430\ + \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 diff --git a/core/src/main/resources/hudson/model/AbstractProject/wipeOutWorkspaceBlocked_sr.properties b/core/src/main/resources/hudson/model/AbstractProject/wipeOutWorkspaceBlocked_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..239c6b464bdf65b99ac2e614ba385b9d037679d5 --- /dev/null +++ b/core/src/main/resources/hudson/model/AbstractProject/wipeOutWorkspaceBlocked_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Error\:\ Wipe\ Out\ Workspace\ blocked\ by\ SCM=\u0413\u0440\u0435\u0448\u043A\u0430: \u0431\u0440\u0438\u0441\u0430\u045A\u0435 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430 \u0458\u0435 \u0441\u043F\u0440\u0435\u0447\u0438\u0458\u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0430 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +The\ SCM\ for\ this\ project\ has\ blocked\ this\ attempt\ to\ wipe\ out\ the\ project's\ workspace.=\u0421\u0438\u0441\u0442\u0435\u043C \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0430 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \u0458\u0435 \u0441\u043F\u0440\u0435\u0447\u0438\u0458\u043E \u0431\u0440\u0438\u0441\u0430\u045A\u0435 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430. diff --git a/core/src/main/resources/hudson/model/AgentSlave/config_bg.properties b/core/src/main/resources/hudson/model/AgentSlave/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..168bbbcc0b876566dd986a207b4c1a5603637c56 --- /dev/null +++ b/core/src/main/resources/hudson/model/AgentSlave/config_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +launch\ command=\ + \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0437\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/AgentSlave/config_sr.properties b/core/src/main/resources/hudson/model/AgentSlave/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2b6b09af19408944c8d309288ac4c3704ec52515 --- /dev/null +++ b/core/src/main/resources/hudson/model/AgentSlave/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +launch\ command=\u043F\u043E\u043A\u0440\u0435\u0442\u043D\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0430 diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_de.properties b/core/src/main/resources/hudson/model/AllView/newViewDetail_bg.properties similarity index 78% rename from core/src/main/resources/hudson/slaves/CommandLauncher/help_de.properties rename to core/src/main/resources/hudson/model/AllView/newViewDetail_bg.properties index 68a036e25270b2545b4b51abb0deaabc2efedcdc..8dc4aeb4ba8e020e8d91e3c449b8899e97074925 100644 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help_de.properties +++ b/core/src/main/resources/hudson/model/AllView/newViewDetail_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +# This view shows all the jobs on Jenkins. blurb=\ - Startet einen Slave, indem Jenkins vom Master aus einen Befehl auf dem Slave ausfhrt. \ - Verwenden Sie diese Option, wenn Jenkins Befehle auf entfernten Slaves ausfhren \ - kann, z.B. ber ssh/rsh. + \u0422\u043e\u0432\u0430 \u0435 \u0438\u0437\u0433\u043b\u0435\u0434 \u0441 \u0432\u0441\u0438\u0447\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430 Jenkins. diff --git a/core/src/main/resources/hudson/model/AllView/newViewDetail_lt.properties b/core/src/main/resources/hudson/model/AllView/newViewDetail_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..3080ff7a0ba6b69f50ee45462f97fe1dfa48f737 --- /dev/null +++ b/core/src/main/resources/hudson/model/AllView/newViewDetail_lt.properties @@ -0,0 +1 @@ +blurb=\u0160is rodinys rodo visus Jenkinso darbus. diff --git a/core/src/main/resources/hudson/model/AllView/newViewDetail_sr.properties b/core/src/main/resources/hudson/model/AllView/newViewDetail_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6c827494b85e6092886eb9813474ed1a674d3b36 --- /dev/null +++ b/core/src/main/resources/hudson/model/AllView/newViewDetail_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u041E\u0432\u0430\u0458 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 \u043F\u0440\u0438\u043A\u0430\u0436\u0435 \u0441\u0432\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u043D\u0430 Jenkins. diff --git a/core/src/main/resources/hudson/model/AllView/noJob.jelly b/core/src/main/resources/hudson/model/AllView/noJob.jelly index 5a7469797809d9a0f3cdd11aa6a6bf08771d673c..0c9e0c26a9952ca50e361159bb699a6966a1f9c0 100644 --- a/core/src/main/resources/hudson/model/AllView/noJob.jelly +++ b/core/src/main/resources/hudson/model/AllView/noJob.jelly @@ -32,7 +32,7 @@ THE SOFTWARE. - +
    ${%newJob}
    diff --git a/core/src/main/resources/hudson/model/AllView/noJob_bg.properties b/core/src/main/resources/hudson/model/AllView/noJob_bg.properties index 81842ac0f7729fa9e4fac2032ddc227b041ae9e8..0284a752eb6a10ca77609228295ff917fba85358 100644 --- a/core/src/main/resources/hudson/model/AllView/noJob_bg.properties +++ b/core/src/main/resources/hudson/model/AllView/noJob_bg.properties @@ -1,5 +1,30 @@ -# This file is under the MIT License by authors - -Welcome\ to\ Jenkins!=\u0414\u043E\u0431\u0440\u0435 \u0434\u043E\u0448\u043B\u0438 \u0432 Jenkins! -newJob=\u041C\u043E\u043B\u044F \u0441\u044A\u0437\u0434\u0430\u0439\u0442\u0435 \u043D\u043E\u0432 job \u0437\u0430 \u0434\u0430 \u0437\u043F\u043E\u0447\u043D\u0435\u0442\u0435. +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Welcome\ to\ Jenkins!=\ + \u0414\u043e\u0431\u0440\u0435 \u0434\u043e\u0448\u043b\u0438 \u0432 Jenkins! +newJob=\ + \u0421\u044a\u0437\u0434\u0430\u0439\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0430, \u0437\u0430 \u0434\u0430 \u0437\u0430\u043f\u043e\u0447\u043d\u0435\u0442\u0435 \u0434\u0430 \u0433\u043e \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435. +login=\ + \u0412\u043f\u0438\u0448\u0435\u0442\u0435 \u0441\u0435, \u0437\u0430 \u0434\u0430 \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u0442\u0435 \u043d\u043e\u0432\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. +signup=\ + \u0410\u043a\u043e \u043d\u044f\u043c\u0430\u0442\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u0439\u0442\u0435 \u0441\u0435 \u0441\u0435\u0433\u0430. diff --git a/core/src/main/resources/hudson/model/AllView/noJob_es.properties b/core/src/main/resources/hudson/model/AllView/noJob_es.properties index 7b9fbb90aac32aae861a88f9ef9ed2cad5bf0781..064002b28d15ebc2be3d623199741b7f500b31ee 100644 --- a/core/src/main/resources/hudson/model/AllView/noJob_es.properties +++ b/core/src/main/resources/hudson/model/AllView/noJob_es.properties @@ -24,8 +24,7 @@ newJob=Por favor, crea una nueva tarea para empezar. login=Entra para crear nuevas tareas. -signup=Si no tienes una cuenta, puedes crear una ahora. -newJob=Por favor, crea una nueva tarea para empezar. -Welcome\ to\ Jenkins!=\u00A1Bienvenido a Jenkins! -signup=Registrarse - +# TODO pick one: +#signup=Si no tienes una cuenta, puedes crear una ahora. +#signup=Registrarse +Welcome\ to\ Jenkins!=\u00a1Bienvenido a Jenkins! diff --git a/core/src/main/resources/hudson/model/AllView/noJob_lt.properties b/core/src/main/resources/hudson/model/AllView/noJob_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..be9cc5dea23ed7e31a626dfe1200452b46552b11 --- /dev/null +++ b/core/src/main/resources/hudson/model/AllView/noJob_lt.properties @@ -0,0 +1,5 @@ +newJob=Pra\u0161ome sukurti nauj\u0105 darb\u0105, kad prad\u0117tum\u0117te. + +login=Prisijunkite, kad gal\u0117tumet kurti naujus darbus. + +signup=Jei dar neturite paskyros, galite dabar u\u017esiregistruoti. diff --git a/core/src/main/resources/hudson/model/AllView/noJob_sr.properties b/core/src/main/resources/hudson/model/AllView/noJob_sr.properties index a0d1ef95df8a978265f6f9a5b774dde63fcf622f..83ce33c5a5b13afa3682ec63113464ab380d382b 100644 --- a/core/src/main/resources/hudson/model/AllView/noJob_sr.properties +++ b/core/src/main/resources/hudson/model/AllView/noJob_sr.properties @@ -1,4 +1,6 @@ # This file is under the MIT License by authors -Welcome\ to\ Jenkins!=Dobrodo\u0161li u Jenkins! -newJob=Molimo napravite poslove da po\u010Dnete sa radom. +Welcome\ to\ Jenkins!=\u0414\u043E\u0431\u0440\u043E\u0434\u043E\u0448\u043B\u0438 \u0443 Jenkins! +newJob=\u041A\u0440\u0435\u0438\u0440\u0430\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0434\u0430 \u043F\u043E\u0447\u043D\u0435\u0442\u0435 \u0441\u0430 \u0440\u0430\u0434\u043E\u043C. +login=\ \u041F\u0440\u0438\u0458\u0430\u0432\u0438\u0442\u0435 \u0441\u0435, \u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 \u043D\u043E\u0432\u0438 \u0437\u0430\u0434\u0430\u0442\u043A\u0435. +signup=\u0410\u043A\u043E \u043D\u0435\u043C\u0430\u0442\u0435 \u043D\u0430\u043B\u043E\u0433, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443\u0458\u0442\u0435 \u0441\u0435 \u0441\u0430\u0434\u0430. diff --git a/core/src/main/resources/hudson/model/BooleanParameterDefinition/config_bg.properties b/core/src/main/resources/hudson/model/BooleanParameterDefinition/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..92f2cdb1c64c9b76ec50a5b982630f8675011fa8 --- /dev/null +++ b/core/src/main/resources/hudson/model/BooleanParameterDefinition/config_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Default\ Value=\ + \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 +Description=\ + \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +Name=\ + \u0418\u043c\u0435 diff --git a/core/src/main/resources/hudson/model/BooleanParameterDefinition/config_sr.properties b/core/src/main/resources/hudson/model/BooleanParameterDefinition/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..93b803761e8a11a2f0995c3e1d086d850afb7eee --- /dev/null +++ b/core/src/main/resources/hudson/model/BooleanParameterDefinition/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Default\ Value=\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0430 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442 +Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_bg.properties b/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..18d99e3ec743b6ad6befadaa9bf243a9279644fc --- /dev/null +++ b/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_bg.properties @@ -0,0 +1,35 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +e.g.,\ from\ scripts=\ + \u043d\u0430\u043f\u0440. \u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435 +Trigger\ builds\ remotely=\ + \u041e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Optionally\ append\ &cause\=Cause+Text\ to\ provide\ text\ that\ will\ be\ included\ in\ the\ recorded\ build\ cause.=\ + \u0410\u043a\u043e \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435 \u0442\u0435\u043a\u0441\u0442-\u043e\u0431\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0437\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e,\ + \u0434\u043e\u0431\u0430\u0432\u0435\u0442\u0435 &cause\=\u043e\u0431\u044f\u0441\u043d\u0435\u043d\u0438\u0435+\u0437\u0430+\u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0442\u0430 +Use\ the\ following\ URL\ to\ trigger\ build\ remotely\:=\ + \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441, \u0437\u0430 \u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e: +Authentication\ Token=\ + \u041d\u0438\u0437 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f +or=\ + \u0438\u043b\u0438 diff --git a/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_pl.properties b/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..f65ddfe8abc751f6b55bff9a37a62753ac6416d0 --- /dev/null +++ b/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_pl.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Optionally\ append\ &cause\=Cause+Text\ to\ provide\ text\ that\ will\ be\ included\ in\ the\ recorded\ build\ cause.=Opcjonalnie do\u0142\u0105cz &cause=Cause+Text, aby dostarczy\u0107 tekst, kt\u00F3y b\u0119dzie informowa\u0142 o \u017Ar\u00F3dle budowania. +Use\ the\ following\ URL\ to\ trigger\ build\ remotely\:=U\u017Cyj tego adresu URL, aby wyzwoli\u0107 budowanie zdalnie +Authentication\ Token=Token autentyfikacji +Trigger\ builds\ remotely=Wyzwalaj budowanie zdalnie +e.g.,\ from\ scripts=np. przez skrypt +or=lub +Use\ the\ following\ URL\ to\ trigger\ build\ remotely=U\u017Cyj tego adresu URL, aby wyzwoli\u0107 budowanie zdalnie diff --git a/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_sr.properties b/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b0b2e90cf53b5da55915fa4b7e01e3131afd6325 --- /dev/null +++ b/core/src/main/resources/hudson/model/BuildAuthorizationToken/config_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Trigger\ builds\ remotely=\u041F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0441\u0430 \u0434\u0430\u043B\u0435\u043A\u0430 +e.g.,\ from\ scripts=\u043D\u043F\u0440. \u043E\u0434 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0432\u0430 +Authentication\ Token=\u0422\u043E\u043A\u0435\u043D \u0437\u0430 \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0443 +Use\ the\ following\ URL\ to\ trigger\ build\ remotely\:=\u041A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u0441\u043B\u0435\u0434\u0435\u045B\u0443 \u0430\u0434\u0440\u0435\u0441\u0443 \u0434\u0430 \u0431\u0438 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u043B\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0441\u0430 \u0434\u0430\u043B\u0435\u043A\u0430: +or=\u0438\u043B\u0438 +Optionally\ append\ &cause\=Cause+Text\ to\ provide\ text\ that\ will\ be\ included\ in\ the\ recorded\ build\ cause.=\u041C\u043E\u0436\u0435\u0442\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438 \u043E\u0431\u0458\u0430\u0448\u045A\u0435\u045A\u0435 \u0437\u0430 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443, &cause\=\u043E\u0431\u0458\u0430\u0448\u045A\u0435\u045A\u0435+\u0437\u0430+\u0440\u0430\u0437\u043B\u043E\u0433 \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly b/core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly index f695275f06656ae91e35c41097263479810c7a56..a9efb2525b46622f9c4f34dbf445122b062ac070 100644 --- a/core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly +++ b/core/src/main/resources/hudson/model/BuildTimelineWidget/control.jelly @@ -41,35 +41,42 @@ THE SOFTWARE. var tz = ${(tz.rawOffset + tz.DSTSavings) / 3600000}; var tl = null; + var interval = 24*60*60*1000; +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +started_by_project_with_deleted_build=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u0437\u0430\u0440\u0430\u0434\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043e\u0442 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u0437\u0430\u0432\u0438\u0441\u0438:\ + {0}, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u2116\u200a{1} +caused_by=\ + \u043f\u044a\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043f\u043e\u0440\u0430\u0434\u0438: +started_by_project=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u0437\u0430\u0440\u0430\u0434\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043e\u0442 \u043a\u043e\u0439\u0442\u043e \u0442\u043e\u0437\u0438 \u0437\u0430\u0432\u0438\u0441\u0438:\ + {0}, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\ + \u2116\u200a{1} diff --git a/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..327dc4258303ca0aae6a1f1474ae4c0eba93792b --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/UpstreamCause/description_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +started_by_project=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0} \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {1} +started_by_project_with_deleted_build=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0} \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {1} +caused_by=\u043F\u0440\u0432\u043E\u0431\u0438\u0442\u043D\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u0437\u0431\u043E\u0433: diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_ja.properties b/core/src/main/resources/hudson/model/Cause/UserCause/description_bg.properties similarity index 84% rename from core/src/main/resources/hudson/model/Slave/help-launcher_ja.properties rename to core/src/main/resources/hudson/model/Cause/UserCause/description_bg.properties index 55ed67ea5f951c428c503835c795b48284322587..6d0361054072d95f025d3ff6d999acee0a59376f 100644 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_ja.properties +++ b/core/src/main/resources/hudson/model/Cause/UserCause/description_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Controls\ how\ Jenkins\ starts\ this\ slave.=\u3053\u306E\u30B9\u30EC\u30FC\u30D6\u306E\u8D77\u52D5\u65B9\u6CD5\u3092\u5236\u5FA1\u3057\u307E\u3059\u3002 +started_by_user=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f {1} diff --git a/core/src/main/resources/hudson/model/Cause/UserCause/description_sr.properties b/core/src/main/resources/hudson/model/Cause/UserCause/description_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..def7294073225d0fddeda01df2b6ccce316eeb83 --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/UserCause/description_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +started_by_user=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u043E\u0434 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 {0} diff --git a/core/src/main/resources/hudson/model/Cause/UserIdCause/description_bg.properties b/core/src/main/resources/hudson/model/Cause/UserIdCause/description_bg.properties index be2fa36d1d5345263a5d3cad28fe56ef322b36d7..044ce85447381eb3ff3a7232a830b9ed11f67d16 100644 --- a/core/src/main/resources/hudson/model/Cause/UserIdCause/description_bg.properties +++ b/core/src/main/resources/hudson/model/Cause/UserIdCause/description_bg.properties @@ -1,3 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -started_by_anonymous=\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043D \u043E\u0442 \u0430\u043D\u043E\u043D\u0438\u043C\u0435\u043D \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B +started_by_anonymous=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u0435\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b +started_by_user=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f {1} diff --git a/core/src/main/resources/hudson/model/Cause/UserIdCause/description_sr.properties b/core/src/main/resources/hudson/model/Cause/UserIdCause/description_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8b7e590e9fee90aa2e1204d33cb617751c40277a --- /dev/null +++ b/core/src/main/resources/hudson/model/Cause/UserIdCause/description_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +started_by_user=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u043E\u0434 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 {1} +started_by_anonymous=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438\u043C \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u043E\u043C diff --git a/core/src/main/resources/hudson/model/CauseAction/summary_bg.properties b/core/src/main/resources/hudson/model/CauseAction/summary_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..9dd0ef889054f53c323f5819adbb543de457f2c2 --- /dev/null +++ b/core/src/main/resources/hudson/model/CauseAction/summary_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# ({0} times) +Ntimes=\ + ({0} \u043f\u044a\u0442\u0438) diff --git a/core/src/main/resources/hudson/model/CauseAction/summary_sr.properties b/core/src/main/resources/hudson/model/CauseAction/summary_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..54014aff1e639d33a1e2a5788d3ca3a89ee36120 --- /dev/null +++ b/core/src/main/resources/hudson/model/CauseAction/summary_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Ntimes=({0} \u043F\u0443\u0442\u0430) diff --git a/core/src/main/resources/hudson/model/ChoiceParameterDefinition/config_bg.properties b/core/src/main/resources/hudson/model/ChoiceParameterDefinition/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..0a56a15f9b84a8525d1b1d4e0c46e8a26b4a3e22 --- /dev/null +++ b/core/src/main/resources/hudson/model/ChoiceParameterDefinition/config_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Choices=\ + \u0412\u0430\u0440\u0438\u0430\u043d\u0442\u0438 +Description=\ + \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +Name=\ + \u0418\u043c\u0435 diff --git a/core/src/main/resources/hudson/model/ChoiceParameterDefinition/config_sr.properties b/core/src/main/resources/hudson/model/ChoiceParameterDefinition/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..70ec444ad48f20f6a9bfb99e5ea77d66bc3f4c06 --- /dev/null +++ b/core/src/main/resources/hudson/model/ChoiceParameterDefinition/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Choices=\u0412\u0430\u0440\u0438\u0430\u043D\u0442\u0438 +Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/hudson/model/Computer/_script.jelly b/core/src/main/resources/hudson/model/Computer/_script.jelly index bcb7e1645ffa08c00573acadb25d1c746e725c4f..87fa923070a5507e5ea218133c0851becd8dc017 100644 --- a/core/src/main/resources/hudson/model/Computer/_script.jelly +++ b/core/src/main/resources/hudson/model/Computer/_script.jelly @@ -31,7 +31,7 @@ THE SOFTWARE.
    println System.getenv("PATH")
    println "uname -a".execute().text

    - ${%This execution happens in the slave agent JVM.} + ${%This execution happens in the agent JVM.}

    diff --git a/core/src/main/resources/hudson/model/Computer/_script_bg.properties b/core/src/main/resources/hudson/model/Computer/_script_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..bd54cfda1b312dfbae697d5ee0bb2cde21d74133 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/_script_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u0441\u0435 \u0432\u044a\u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u043d\u0430\u0442\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0430 Java \u043d\u0430 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440. +This\ execution\ happens\ in\ the\ agent\ JVM.=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u0441\u0435 \u0432\u044a\u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u043d\u0430\u0442\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u043d\u0430 Java \u043d\u0430 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440. diff --git a/core/src/main/resources/hudson/model/Computer/_script_de.properties b/core/src/main/resources/hudson/model/Computer/_script_de.properties deleted file mode 100644 index 1d42d76034e4c3f57202a71ab53be9042594d67c..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Computer/_script_de.properties +++ /dev/null @@ -1,2 +0,0 @@ -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=\ - Diese Ausfhrung findet in der JVM des Slave-Agenten statt. diff --git a/core/src/main/resources/hudson/model/Computer/_script_es.properties b/core/src/main/resources/hudson/model/Computer/_script_es.properties index acc45963cfaed4556f3498f5e43007083bf2da64..3c7710374db13f83b9b3f6b84683d79272ea8194 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_es.properties +++ b/core/src/main/resources/hudson/model/Computer/_script_es.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=Esta ejecucin se hace en el agente de la mquina virtual del esclavo. +This\ execution\ happens\ in\ the\ agent\ JVM.=Esta ejecucin se hace en la mquina virtual (JVM) del agente. diff --git a/core/src/main/resources/hudson/model/Computer/_script_ru.properties b/core/src/main/resources/hudson/model/Computer/_script_ru.properties deleted file mode 100644 index 04f38657ea4aa30dacb5d5a5c6e4c024d57d4014..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Computer/_script_ru.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u0432 JVM \u043f\u043e\u0434\u0447\u0438\u043d\u0451\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 diff --git a/core/src/main/resources/hudson/model/Computer/_script_sr.properties b/core/src/main/resources/hudson/model/Computer/_script_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..81b70f44fdd187f13922369845c03f4f858b984c --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/_script_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u0441\u0435 \u043D\u0430 Java \u0432\u0438\u0440\u0442\u0443\u0435\u043B\u043D\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438 \u043D\u0430 \u0434\u0440\u0443\u0433\u043E\u043C \u0440\u0430\u0447\u0443\u043D\u0430\u0440\u0443. +This\ execution\ happens\ in\ the\ agent\ JVM.=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u0441\u0435 \u043D\u0430 Java \u0432\u0438\u0440\u0442\u0443\u0435\u043B\u043D\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438 \u043D\u0430 \u0434\u0440\u0443\u0433\u043E\u043C \u0440\u0430\u0447\u0443\u043D\u0430\u0440\u0443. diff --git a/core/src/main/resources/hudson/model/Computer/builds_bg.properties b/core/src/main/resources/hudson/model/Computer/builds_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..28ed4cde648bdfffe20f1e2fcdc5e5c02ce6afd6 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/builds_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# Build History on {0} +title=\ + \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u043d\u0430 {0} diff --git a/core/src/main/resources/hudson/model/Computer/builds_sr.properties b/core/src/main/resources/hudson/model/Computer/builds_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2594501fed260f3f613d864844f0f0d35b2a8943 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/builds_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +title=\u0418\u0441\u0442\u043E\u0440\u0438\u0458\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0430 {0} diff --git a/core/src/main/resources/hudson/model/Computer/configure_bg.properties b/core/src/main/resources/hudson/model/Computer/configure_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..572a3657ce78a512e1714cd12281edebf17f45fa --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/configure_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Save=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 +title=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u201e{0}\u201c +Name=\ + \u0418\u043c\u0435 diff --git a/core/src/main/resources/hudson/model/Computer/configure_sr.properties b/core/src/main/resources/hudson/model/Computer/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..cf5adb2c26f21781bae048efc43443063ec12b8a --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/configure_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +title=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 "{0}" +Name=\u0418\u043C\u0435 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +Name\ is\ mandatory=\u0418\u043C\u0435 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E diff --git a/core/src/main/resources/hudson/model/Computer/custom-jnlp.jelly b/core/src/main/resources/hudson/model/Computer/custom-jnlp.jelly index df19f8cd2c62e0df2becfa0646855b350e3279b2..6f6cbfb2f33328c137b86b74360498a2bab80139 100644 --- a/core/src/main/resources/hudson/model/Computer/custom-jnlp.jelly +++ b/core/src/main/resources/hudson/model/Computer/custom-jnlp.jelly @@ -29,7 +29,7 @@ THE SOFTWARE.

    Tweak Launch Parameters

    - This page allows you to tweak the JVM parameters when launching JNLP slave agents. + This page allows you to tweak the JVM parameters when launching JNLP agents.

    diff --git a/core/src/main/resources/hudson/model/Computer/delete.jelly b/core/src/main/resources/hudson/model/Computer/delete.jelly index 2ae6fea1763d90a8ee7270fcf5e3b4dcb27fa1f3..2f88351c6a9f32423f3848ed154220e99587cd8a 100644 --- a/core/src/main/resources/hudson/model/Computer/delete.jelly +++ b/core/src/main/resources/hudson/model/Computer/delete.jelly @@ -28,7 +28,7 @@ THE SOFTWARE. - ${%Are you sure about deleting the slave?} + ${%Are you sure about deleting the agent?} diff --git a/core/src/main/resources/hudson/model/Computer/delete_bg.properties b/core/src/main/resources/hudson/model/Computer/delete_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..807612a8202264d9a089fee36efbcfab17130ba8 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/delete_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Are\ you\ sure\ about\ deleting\ the\ slave?=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0435\u0442\u0435 \u0442\u043e\u0437\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440? +Yes=\ + \u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ agent?=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u043f\u0440\u0435\u043c\u0430\u0445\u043d\u0435\u0442\u0435 \u0442\u043e\u0437\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440? diff --git a/core/src/main/resources/hudson/model/Computer/delete_da.properties b/core/src/main/resources/hudson/model/Computer/delete_da.properties index 41b74dfc8e5428083808525856ee593b4215e4ad..1d3dcce7bd165c780620dc79d7f71d735e15cde7 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_da.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_da.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Yes=Ja -Are\ you\ sure\ about\ deleting\ the\ slave?=Er du sikker p\u00e5 at du vil slette slaven? diff --git a/core/src/main/resources/hudson/model/Computer/delete_de.properties b/core/src/main/resources/hudson/model/Computer/delete_de.properties index 4e7fdd00369b60daa6bffd9755dca5ee5844326c..2593097cb45233343d8466bfc7d80e7b07cb9a0c 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_de.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_de.properties @@ -1,2 +1 @@ -Are\ you\ sure\ about\ deleting\ the\ slave?=Mchten Sie den Slave-Knoten wirklich lschen? Yes=Ja diff --git a/core/src/main/resources/hudson/model/Computer/delete_es.properties b/core/src/main/resources/hudson/model/Computer/delete_es.properties index 986f8ac8881a9ff2cb969a44082549ee07299afd..2bfd1f95b0a3d408cb0138ad1bcff7b0ec15848e 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_es.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_es.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ slave?=Ests seguro de querer borrar este esclavo? +Are\ you\ sure\ about\ deleting\ the\ agent?=Ests seguro de querer borrar este agente? Yes=S diff --git a/core/src/main/resources/hudson/model/Computer/delete_fr.properties b/core/src/main/resources/hudson/model/Computer/delete_fr.properties index f939cafb6a251d7d7888ff86d0d139ab53806a67..50339e156c2956396fda622fa20ee49b5fd91762 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_fr.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_fr.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ slave?=Etes-vous sr de vouloir supprimer cet esclave? Yes=Oui diff --git a/core/src/main/resources/hudson/model/Computer/delete_ja.properties b/core/src/main/resources/hudson/model/Computer/delete_ja.properties index 9eb4b9e52f78229e262b4d714c7cfc5109f67711..22f770e0f0f932796fd5cfe738d018fc9971d058 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_ja.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_ja.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Yes=\u306F\u3044 -Are\ you\ sure\ about\ deleting\ the\ slave?=\u30B9\u30EC\u30FC\u30D6\u3092\u524A\u9664\u3057\u3066\u3088\u308D\u3057\u3044\u3067\u3059\u304B? \ No newline at end of file +Yes=\u306F\u3044 \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties b/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties index d3a3105c4ad0b498a4f576027b326128e90b9a4f..60797521ae90f3cc089faab4538371fa0d75aacc 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_pt_BR.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Yes=Sim -Are\ you\ sure\ about\ deleting\ the\ slave?=Tem certeza que deseja remover esse slave? diff --git a/core/src/main/resources/hudson/model/Computer/delete_ru.properties b/core/src/main/resources/hudson/model/Computer/delete_ru.properties index 7259f6d977837aa6f4e5c4d5636fb47374f5ab0f..b7b2dfd7e23353da6409954a27d27644366ccd6b 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_ru.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_ru.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ slave?=\u0412\u044B \u0443\u0432\u0435\u0440\u0435\u043D\u044B, \u0447\u0442\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u043E\u0434\u0447\u0438\u043D\u0435\u043D\u043D\u044B\u0439 \u0443\u0437\u0435\u043B? Yes=\u0414\u0430 diff --git a/core/src/main/resources/hudson/model/Computer/delete_sr.properties b/core/src/main/resources/hudson/model/Computer/delete_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c6c8363f2ef8c53296f91ab9cd45aac8c3f17a81 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/delete_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Are\ you\ sure\ about\ deleting\ the\ agent?=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u0430\u0433\u0435\u043D\u0442\u0430? +Yes=\u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ slave?=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u043F\u043E\u043C\u043E\u045B\u043D\u0438\u043A\u0430? diff --git a/core/src/main/resources/hudson/model/Computer/delete_zh_TW.properties b/core/src/main/resources/hudson/model/Computer/delete_zh_TW.properties index caa065d636890f6507fae3834a68c58ec4247fe0..83db3cdbc32d831defe32ea7e6b496e6944da35b 100644 --- a/core/src/main/resources/hudson/model/Computer/delete_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Computer/delete_zh_TW.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ slave?=\u78ba\u5b9a\u8981\u522a\u9664 Slave? Yes=\u662f diff --git a/core/src/main/resources/hudson/model/Computer/index_bg.properties b/core/src/main/resources/hudson/model/Computer/index_bg.properties index df11dfbc832b520e5fe914013dcaf3519718f547..ef4c3adc9ca5362abe50d6ccb9b28b2b6b0faf48 100644 --- a/core/src/main/resources/hudson/model/Computer/index_bg.properties +++ b/core/src/main/resources/hudson/model/Computer/index_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,22 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Labels:=\u0415\u0442\u0438\u043A\u0435\u0442\u0438: -None=\u041D\u044F\u043C\u0430 -submit.not.temporarilyOffline=\u041C\u0430\u0440\u043A\u0438\u0440\u0430\u0439 \u0442\u0430\u0437\u0438 \u043C\u0430\u0448\u0438\u043D\u0430 \u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E \u043E\u0444\u043B\u0430\u0439\u043D -title.projects_tied_on=\u041F\u0440\u043E\u0435\u043A\u0442\u0438, \u0438\u0437\u043F\u044A\u043B\u043D\u044F\u0432\u0430\u043D\u0438 \u043D\u0430 {0} +None=\ + \u041d\u044f\u043c\u0430 +submit.not.temporarilyOffline=\ + \u041e\u0442\u0431\u0435\u043b\u044f\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430\u0442\u0430, \u0447\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f +title.projects_tied_on=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f, \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u043d\u0438 \u043d\u0430 \u201e{0}\u201c +Created\ by=\ + \u0421\u044a\u0437\u0434\u0430\u0434\u0435\u043d\u043e \u043e\u0442 +title.no_manual_launch=\ + \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u0442\u0430, \u043a\u043e\u0433\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u0434\u0430 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u0435: \u201e{0}\u201c. \u0422\u043e\u0432\u0430 \u043e\u0437\u043d\u0430\u0447\u0430\u0432\u0430, \u0447\u0435 \u0432\ + \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. +submit.updateOfflineCause=\ + \u041f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0442\u0430 \u0434\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f +submit.temporarilyOffline=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u0434\u0430 \u043c\u0438\u043d\u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f +Labels=\ + \u0415\u0442\u0438\u043a\u0435\u0442\u0438 +anonymous\ user=\ + \u0430\u043d\u043e\u043d\u0438\u043c\u0435\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b diff --git a/core/src/main/resources/hudson/model/Computer/index_sr.properties b/core/src/main/resources/hudson/model/Computer/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..461b7036554c530327db592bea1b666d27fbe8b1 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/index_sr.properties @@ -0,0 +1,13 @@ +# This file is under the MIT License by authors + +submit.temporarilyOffline=\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u0440\u0438\u043A\u043E\u043F\u0447\u0430\u0458 \u043C\u0430\u0448\u0438\u043D\u0443 +submit.updateOfflineCause=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 \u0440\u0430\u0437\u043B\u043E\u0433 \u043E\u0442\u043A\u043E\u043F\u0447\u0435\u045A\u0430 +submit.not.temporarilyOffline= +title.no_manual_launch=Availability policy \u0437\u0430 \u043C\u0430\u0448\u0438\u043D\u0443 \u0458\u0435: \u201C{0}\u201D, \u0448\u0442\u043E \u0438\u0437\u0438\u0441\u043A\u0430\u0432\u0430 \u0434\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0441\u0430\u0434\u0430 \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u0430 \u043D\u0435\u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0430. +Created\ by=\u041A\u0440\u0435\u0438\u0440\u0430\u043D\u043E \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 +anonymous\ user=\u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A +Labels=\u041B\u0430\u0431\u0435\u043B\u0435 +title.projects_tied_on=\u041F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \u0432\u0435\u0437\u0430\u043D\u0438 \u043D\u0430 {0} +None=\u041D\u0435\u043C\u0430 +Labels\=\u30E9\u30D9\u30EB= +Labels\:=\u041B\u0430\u0431\u0435\u043B\u0430: diff --git a/core/src/main/resources/hudson/model/Computer/markOffline_bg.properties b/core/src/main/resources/hudson/model/Computer/markOffline_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..5b2494762b809541c4a859483881753be29a867d --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/markOffline_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +title=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f +blurb=\ + \u041c\u043e\u0436\u0435 \u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u0430, \u0437\u0430\u0449\u043e \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f: +submit=\ + \u0422\u043e\u0437\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0434\u0430 \u0435 \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f diff --git a/core/src/main/resources/hudson/model/Computer/markOffline_sr.properties b/core/src/main/resources/hudson/model/Computer/markOffline_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2d2ee65ad86415d07fa16b4aca79f215f29c7691 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/markOffline_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +title=\u041E\u0442\u043A\u043E\u043F\u0447\u0430\u0432\u0430 {0} +blurb=\u041C\u043E\u0436\u0435\u0442\u0435 \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u0440\u0430\u0437\u043B\u043E\u0433 \u0437\u0430\u0448\u0442\u043E \u0458\u0435 \u0432\u0430\u0448 \u0440\u0430\u0447\u0443\u043D\u0430\u0440 \u0458\u0435 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u0432\u0430\u043D \u043C\u0440\u0435\u0436\u0435: +submit=\u041F\u0440\u0438\u0432\u0440\u0435\u043C\u0435\u043D\u043E \u043E\u0442\u043A\u043E\u043F\u0447\u0430\u0458 \u043E\u0432\u0443 \u043C\u0430\u0448\u0438\u043D\u0443 diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_de.properties b/core/src/main/resources/hudson/model/Computer/setOfflineCause_bg.properties similarity index 59% rename from core/src/main/resources/hudson/slaves/JNLPLauncher/help_de.properties rename to core/src/main/resources/hudson/model/Computer/setOfflineCause_bg.properties index 0481b8a47caa474674b1c03362a18ea7a63077a1..655f3526e643d1967542653e64daf49bf94dc08e 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_de.properties +++ b/core/src/main/resources/hudson/model/Computer/setOfflineCause_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +submit=\ + \u041f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0442\u0430 +title=\ + \u201e{0}\u201c \u0434\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f blurb=\ - Schaltet einen Slave ein, indem ein Agent ber \ - JNLP gestartet wird. \ - Da der Start in diesem Fall vom Slave aus initiiert wird, muss der Slave nicht \ - per IP-Adresse von Master aus erreichbar sein (z.B. wenn der Slave hinter einer \ - Firewall liegt). Es ist weiterhin mglich, den Slave ohne Benutzeroberflche \ - zu starten, z.B. als Windows Dienst. + \u041c\u043e\u0436\u0435 \u0434\u0430 \u0437\u0430\u0434\u0430\u0434\u0435\u0442\u0435 \u0438\u043b\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0442\u0430, \u0437\u0430\u0449\u043e \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u0435 \u043d\u0430\ + \u043b\u0438\u043d\u0438\u044f: diff --git a/core/src/main/resources/hudson/model/Computer/setOfflineCause_sr.properties b/core/src/main/resources/hudson/model/Computer/setOfflineCause_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9fdc2865e38d49f5be9a2061a6fc054776dbebc8 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/setOfflineCause_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +title=\u0420\u0430\u0437\u043B\u043E\u0433 \u043E\u0442\u043A\u043E\u043F\u0447\u0430\u045A\u0430 {0} +blurb=\u041C\u043E\u0436\u0435\u0442\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u0438\u043B\u0438 \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0438 \u0440\u0430\u0437\u043B\u043E\u0433 \u0437\u0430\u0448\u0442\u043E \u0458\u0435 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u043E\u0432\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0432\u0430\u043D \u043C\u0440\u0435\u0436\u0435: +submit=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 \u0440\u0430\u0437\u043B\u043E\u0433 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel.jelly b/core/src/main/resources/hudson/model/Computer/sidepanel.jelly index 2a74c154e76ab2050b44ae38808e9a37c0a71610..d3c30c47a19098ab1d8c9174c2895a7483064208 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/Computer/sidepanel.jelly @@ -32,7 +32,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_bg.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_bg.properties index d7d2c90921c8f792f516c5f12ac406dcc9c8f2cd..8f13b54328b5429f24d200dc6399f5c02b4b74a2 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_bg.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,19 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ List=\u041E\u0431\u0440\u0430\u0442\u043D\u043E \u043A\u044A\u043C \u0441\u043F\u0438\u0441\u044A\u043A\u0430 -Build\ History=\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u043D\u0430 \u0431\u0438\u043B\u0434\u0430 -Configure=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 -Delete\ Slave=\u0418\u0437\u0442\u0440\u0438\u0439 \u043C\u0430\u0448\u0438\u043D\u0430 -Load\ Statistics=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430 \u043D\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043D\u0438\u044F\u0442\u0430 -Script\ Console=\u041A\u043E\u043D\u0437\u043E\u043B\u0430 -Status=\u0421\u0442\u0430\u0442\u0443\u0441 +Back\ to\ List=\ + \u041a\u044a\u043c \u0441\u043f\u0438\u0441\u044a\u043a\u0430 +Build\ History=\ + \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +Configure=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +Delete\ Slave=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 +Load\ Statistics=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0430 \u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0432\u0430\u043d\u0435\u0442\u043e +Script\ Console=\ + \u041a\u043e\u043d\u0437\u043e\u043b\u0430 +Status=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 +Delete\ Agent=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_cs.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_cs.properties index 4facbaf7340b931362fcae2387fb084b4d9637fb..c4bb2a911cddd3e48f8752ab6345a239b017686d 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_cs.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_cs.properties @@ -23,7 +23,6 @@ Back\ to\ List=Zp\u011Bt na seznam Build\ History=Historie sestaven\u00ED Configure=Nastavit -Delete\ Slave=Vymazat server Load\ Statistics=Na\u010D\u00EDst statistiku Script\ Console=Konzole Status=Stav diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_da.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_da.properties index 62d0db6dbf8cbfe8f1b7abf3f7ae9bd32c9d6c10..44c72e343abdabe4770538c711500375625911b4 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_da.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_da.properties @@ -22,7 +22,6 @@ Configure=Konfigurer Status=Status -Delete\ Slave=Slet slave Build\ History=Byggehistorik Load\ Statistics=Belastningsstatistik Back\ to\ List=Tilbage til liste diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_de.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_de.properties index 2fa34e5fa037682237a1c3cbc78acdd00b70d2bb..b927f03b5a240023d135c210cdb8f666641a2f7f 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_de.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_de.properties @@ -24,6 +24,5 @@ Back\ to\ List=Zur Build\ History=Build-Verlauf Script\ Console=Script-Konsole Status=Status -Delete\ Slave=Slave lschen Configure=Konfigurieren Load\ Statistics=Auslastung diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_es.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_es.properties index d8b9a2d6d9b9a8fbd42721715922361ccfe0878c..c96d7bb82dbcdf925df9c9df452f849e940883a5 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_es.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_es.properties @@ -22,7 +22,7 @@ Back\ to\ List=Volver Status=Estado -Delete\ Slave=Borrar esclavo +Delete\ Agent=Borrar agente Configure=Configurar Build\ History=Historia de ejecuciones Load\ Statistics=Cargar estadsticas diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_fi.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_fi.properties index f3fb8825cca8b0286bcbd8ba1850d3ff4b91427b..9049275c327b664193437e569991abe23cccdfef 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_fi.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_fi.properties @@ -23,7 +23,6 @@ Back\ to\ List=Takaisin listaan Build\ History=K\u00E4\u00E4nn\u00F6shistoria Configure=Konfiguroi -Delete\ Slave=Poista suorittaja Load\ Statistics=Kuormatilastot Script\ Console=Skriptikonsoli Status=Tila diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_fr.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_fr.properties index 3c7a539c24b41b0e0aef83759b3e4c855d9edd6d..63d8626ee30c32ae6a1348108b628a513a11b0a6 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_fr.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_fr.properties @@ -24,7 +24,6 @@ Back\ to\ List=Retour Build\ History=Historique des constructions Script\ Console=Console de script Status=Statut -Delete\ Slave=Supprimer l\u2019esclave Configure=Configurer Load\ Statistics=Statistiques d\u2019utilisation diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_he.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_he.properties index 17436729ee1bac05b79311072d9d578a0ceba94f..992f7a1f6610afb25ded467d594bcbf5ee040ddc 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_he.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_he.properties @@ -23,7 +23,6 @@ Back\ to\ List=\u05D7\u05D6\u05E8\u05D4 \u05DC\u05E8\u05E9\u05D9\u05DE\u05D4 Build\ History=\u05D4\u05D9\u05E1\u05D8\u05D5\u05E8\u05D9\u05D9\u05EA \u05D1\u05E0\u05D9\u05D5\u05EA Configure=\u05E7\u05D1\u05D9\u05E2\u05EA \u05EA\u05E6\u05D5\u05E8\u05D4 -Delete\ Slave=\u05DE\u05D7\u05D9\u05E7\u05EA \u05EA\u05D7\u05E0\u05D4 Load\ Statistics=\u05E1\u05D8\u05D8\u05D9\u05E1\u05D8\u05D9\u05E7\u05D5\u05EA \u05D4\u05E2\u05D5\u05DE\u05E1 Script\ Console=\u05DE\u05E1\u05D5\u05E3 \u05D4\u05E1\u05E7\u05E8\u05D9\u05E4\u05D8\u05D9\u05DD Status=\u05E1\u05D8\u05D8\u05D5\u05E1 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_it.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_it.properties index 62bd6909dc7e17cdc9fb3d2345955120beced2ed..3e3dab4a4339b0272a1f114e218781df2d92c0b1 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_it.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_it.properties @@ -3,6 +3,5 @@ Back\ to\ List=Torna alla Lista Build\ History=Storia dei Build Configure=Configura -Delete\ Slave=Cancella Slave Load\ Statistics=Carica Statistiche Status=Stato diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_ja.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_ja.properties index 7ab2d427d60e99cefbc057a1709d0706110a3c28..ed49c9c3b96e8ec1131a2d4a250a947ee6a5cea6 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_ja.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_ja.properties @@ -22,7 +22,6 @@ Back\ to\ List=\u30EA\u30B9\u30C8\u3078\u623B\u308B Status=\u72B6\u614B -Delete\ Slave=\u30B9\u30EC\u30FC\u30D6\u524A\u9664 Configure=\u8A2D\u5B9A Build\ History=\u30D3\u30EB\u30C9\u5C65\u6B74 Load\ Statistics=\u8CA0\u8377\u7D71\u8A08 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_ko.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_ko.properties index 23a3838f62cd8dbd597ba6c5d962d7e584aa8dee..5c294876385fddf4a14508271f5f53e0a58f78d4 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_ko.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_ko.properties @@ -23,7 +23,6 @@ Back\ to\ List=\uBAA9\uB85D\uC73C\uB85C \uB3CC\uC544\uAC00\uAE30 Build\ History=\uBE4C\uB4DC \uAE30\uB85D Configure=\uC124\uC815 -Delete\ Slave=Slave \uC0AD\uC81C Load\ Statistics=\uD1B5\uACC4\uBCF4\uAE30 Script\ Console=\uC2A4\uD06C\uB9BD\uD2B8 \uCF58\uC194 Status=\uC0C1\uD0DC diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_lt.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_lt.properties index d06880df350b64ebce8ed66741b2e6fdddbc6b75..10e449ee00841e56f4935fac79104f1c656307fe 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_lt.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_lt.properties @@ -23,6 +23,5 @@ Back\ to\ List=Atgal \u012F s\u0105ra\u0161\u0105 Build\ History=Darb\u0173 istorija Configure=Nustatymai -Delete\ Slave=I\u0161trinti ''Slave'' Load\ Statistics=Kr\u016Bvio statistika Status=B\u016Bsena diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_lv.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_lv.properties index 2b1f18e7147fee448d521b079748da375a3e0185..8f90d430a69313ce87d29c02e2601e7a60633a29 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_lv.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_lv.properties @@ -23,7 +23,6 @@ Back\ to\ List=Atpaka\u013C pie saraksta Build\ History=B\u016Bv\u0113jumu v\u0113sture Configure=Konfigur\u0113t -Delete\ Slave=Dz\u0113st pak\u0101rtoto izpild\u012Btaju Load\ Statistics=Noslodzes statistika Script\ Console=Skriptu konsole Status=St\u0101voklis diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_nb_NO.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_nb_NO.properties index 0a9fcd4feca35674588b837f03910da68792de2f..8a56a4ddd5059a0f18014607cf3bbec7605c47f5 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_nb_NO.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_nb_NO.properties @@ -23,7 +23,6 @@ Back\ to\ List=Tilbake til listen Build\ History=Bygghistorikk Configure=Konfigur\u00E9r -Delete\ Slave=Slett slave Load\ Statistics=Laststatistikk Script\ Console=Skriptekonsoll Status=Status diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_nl.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_nl.properties index 8c6eea983d6254acd088f87d083b0549055c8421..654c2904d9ab56415bda3d602df072bfde242315 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_nl.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_nl.properties @@ -23,7 +23,6 @@ Back\ to\ List=Terug naar overzicht Build\ History=Bouwhistorie Configure=Configureren -Delete\ Slave=Verwijderen -Load\ Statistics=Belasting statistieken +Load\ Statistics=Belastings statistieken Script\ Console=Scriptconsole Status=Status diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_pl.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_pl.properties index bd34753cda0fb665e45ee053d7331e7eb4766f02..2ddc6acd17947398fbcc24aa32b0d9f01985825d 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_pl.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_pl.properties @@ -23,6 +23,5 @@ Back\ to\ List=Powr\u00F3t do listy Build\ History=Historia kompilacji Configure=Konfiguruj -Delete\ Slave=Usu\u0144 Slave Load\ Statistics=Statystyka obci\u0105\u017Cenia Script\ Console=Konsola skrypt\u00F3w diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_pt_BR.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_pt_BR.properties index b91be21c9d10875bd0f1a88e660ff3e90b1ddb38..20731bae6a613a581966220713a9715cbe9e8400 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_pt_BR.properties @@ -24,6 +24,5 @@ Back\ to\ List=Voltar para a lista Build\ History=Hist\u00f3rico de builds Configure=Configurar Status=Situa\u00e7\u00e3o -Delete\ Slave=Remover slave Load\ Statistics=Estat\u00edsticas de carga Script\ Console=Terminal de script diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_pt_PT.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_pt_PT.properties index 677b381cb6412ff8b1e5ce761741e637457cf939..7581da9c238ad81f679243345e1838173bf70df5 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_pt_PT.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_pt_PT.properties @@ -3,6 +3,5 @@ Back\ to\ List=Voltar para a Lista Build\ History=Hist\u00F3rico de Compila\u00E7\u00F5es Configure=Configurar -Delete\ Slave=Apagar Escravo Load\ Statistics=Carregar Estat\u00EDsticas Status=Estado diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_ru.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_ru.properties index b8be6235c752b0fad2682dff38969f0db96a22ec..269c911a88b6e20d18b0441f440cebc204406809 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_ru.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_ru.properties @@ -23,7 +23,6 @@ Back\ to\ List=\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043f\u0438\u0441\u043a\u0443 Build\ History=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u0441\u0431\u043e\u0440\u043e\u043a Configure=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c -Delete\ Slave=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b Load\ Statistics=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Script\ Console=\u041a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 Status=\u0421\u0442\u0430\u0442\u0443\u0441 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_sk.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_sk.properties index e79975c8931c7f531a9f0de12b5f0e801c43e7f8..3e9548696ee45ea9ea018e0cffc7f3405e8d4ac9 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_sk.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_sk.properties @@ -3,7 +3,6 @@ Back\ to\ List=Nasp\u00E4\u0165 na zoznam Build\ History=Hist\u00F3ria zostaven\u00ED Configure=Konfiguruj -Delete\ Slave=Vyma\u017E stroj Load\ Statistics=\u0160tatistiky vy\u0165a\u017Eenia Script\ Console=Skriptov\u00E1 konzola Status=Stav diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_sr.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f81eb73cd6d7db97aec679647f9059eb7324e545 --- /dev/null +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +Back\ to\ List=\u041D\u0430\u0437\u0430\u0434 +Status=\u0421\u0442\u0430\u045A\u0435 +Delete\ Agent=\u0423\u043A\u043B\u043E\u043D\u0438 \u0430\u0433\u0435\u043D\u0442 +Configure=\u041F\u043E\u0434\u0435\u0441\u0438 +Build\ History=\u0418\u0441\u0442\u043E\u0440\u0438\u0458\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Load\ Statistics=\u0423\u0447\u0438\u0442\u0430\u0458 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0443 +Script\ Console=\u041A\u043E\u043D\u0437\u043E\u043B\u0430 +Delete\ Slave=\u0423\u043A\u043B\u043E\u043D\u0438 \u043F\u043E\u043C\u043E\u045B\u043D\u0438\u043A\u0430 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_sv_SE.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_sv_SE.properties index 6d9abb2fd5dbfcb0b21c8fccf717be20d7146b84..c98df81fab37e6fe5614623def8c778a8443430d 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_sv_SE.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_sv_SE.properties @@ -23,7 +23,6 @@ Back\ to\ List=Tillbaka till nodlista Build\ History=Jobbhistorik Configure=Konfigurera -Delete\ Slave=Ta bort nod Load\ Statistics=Belastningstatistik Script\ Console=Skriptkonsoll Status=Status diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_tr.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_tr.properties index 300309ef652bc269f066378f1baa33ba9edb5b57..87af65f9c3b2eac0707704271943741f177ea238 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_tr.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_tr.properties @@ -23,7 +23,6 @@ Back\ to\ List=Listeye D\u00f6n Build\ History=Yap\u0131land\u0131rma Ge\u00e7mi\u015fi Configure=Yap\u0131land\u0131r -Delete\ Slave=Ba\u011F\u0131l\u0131(Slave) sil Load\ Statistics=Y\u00FCklenme istatistikleri Script\ Console=Script\ Konsolu Status=Durum diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_uk.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_uk.properties index c103c891447b9e5efeff9bc739a08fdda0c98b00..8917b1c57c6effab1ce775a819238a72cc0ff45c 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_uk.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_uk.properties @@ -3,7 +3,6 @@ Back\ to\ List=\u041F\u043E\u0432\u0435\u0440\u043D\u0443\u0442\u0438\u0441\u044C \u0434\u043E \u0441\u043F\u0438\u0441\u043A\u0443 Build\ History=\u0406\u0441\u0442\u043E\u0440\u0456\u044F \u043F\u043E\u0431\u0443\u0434\u043E\u0432 Configure=\u041D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F -Delete\ Slave=\u0412\u0438\u0434\u0430\u043B\u0438\u0442\u0438 Slave Load\ Statistics=\u0417\u0430\u0432\u0430\u043D\u0442\u0430\u0436\u0438\u0442\u0438 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0443 Script\ Console=\u0421\u043A\u0440\u0438\u043F\u0442\u043E\u0432\u0430 \u043A\u043E\u043D\u0441\u043E\u043B\u044C Status=\u0421\u0442\u0430\u0442\u0443\u0441 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_zh_CN.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_zh_CN.properties index 547bb7a6f479ff5295026cc11f745971fe23d700..0861540bb9d90ade7d7878db991e853dcf03ffcb 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_zh_CN.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_zh_CN.properties @@ -23,7 +23,6 @@ Back\ to\ List=\u8fd4\u56de\u5217\u8868 Build\ History=\u6784\u5efa\u5386\u53f2 Configure=\u914D\u7F6E\u4ECE\u8282\u70B9 -Delete\ Slave=\u5220\u9664\u5B50\u8282\u70B9 Load\ Statistics=\u8d1f\u8f7d\u7edf\u8ba1 Script\ Console=\u811a\u672c\u547d\u4ee4\u884c Status=\u72b6\u6001 diff --git a/core/src/main/resources/hudson/model/Computer/sidepanel_zh_TW.properties b/core/src/main/resources/hudson/model/Computer/sidepanel_zh_TW.properties index fdc17d9b149557af1141e811e931ba857c873c60..88ef844bb3eeba839c6937c988c73be9100c62f0 100644 --- a/core/src/main/resources/hudson/model/Computer/sidepanel_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Computer/sidepanel_zh_TW.properties @@ -22,7 +22,6 @@ Back\ to\ List=\u56DE\u5230\u6E05\u55AE Status=\u72C0\u614B -Delete\ Slave=\u522A\u9664 Slave Configure=\u8A2D\u5B9A Build\ History=\u5EFA\u69CB\u6B77\u53F2 Load\ Statistics=\u8CA0\u8F09\u7D71\u8A08 diff --git a/core/src/main/resources/hudson/model/ComputerSet/_new.jelly b/core/src/main/resources/hudson/model/ComputerSet/_new.jelly index cfbfa20d2d515aa27cabf159410ff8472975b07b..38e161a7478b5004b3a07f3871884f455731db65 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/_new.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/_new.jelly @@ -32,7 +32,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/ComputerSet/_new_bg.properties b/core/src/main/resources/hudson/model/ComputerSet/_new_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..7ee69405cd39eab4c4539ea1a917751e42d73a4d --- /dev/null +++ b/core/src/main/resources/hudson/model/ComputerSet/_new_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Name=\ + \u0418\u043c\u0435 +Name\ is\ mandatory=\ + \u0418\u043c\u0435\u0442\u043e \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e +Save=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/ComputerSet/_new_sr.properties b/core/src/main/resources/hudson/model/ComputerSet/_new_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6fddb66c363bd58f902815be3b32fd5733e18de3 --- /dev/null +++ b/core/src/main/resources/hudson/model/ComputerSet/_new_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Name\ is\ mandatory=\u0418\u043C\u0435 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 diff --git a/core/src/main/resources/hudson/model/ComputerSet/configure_bg.properties b/core/src/main/resources/hudson/model/ComputerSet/configure_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..f282e34e987781d501a05d62c1272b3ebd9f2d8b --- /dev/null +++ b/core/src/main/resources/hudson/model/ComputerSet/configure_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +OK=\ + \u0414\u043e\u0431\u0440\u0435 +Node\ Monitoring\ Configuration=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430 +Preventive\ Node\ Monitoring=\ + \u041d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430 diff --git a/core/src/main/resources/hudson/model/ComputerSet/configure_sr.properties b/core/src/main/resources/hudson/model/ComputerSet/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..00670084b522622e4f1c0467693daa619cd39331 --- /dev/null +++ b/core/src/main/resources/hudson/model/ComputerSet/configure_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Node\ Monitoring\ Configuration=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u045A\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 +Preventive\ Node\ Monitoring=\u041F\u0440\u0435\u0432\u0435\u043D\u0442\u0438\u0432\u043D\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u045A\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 +OK=\u0423\u0440\u0435\u0434\u0443 diff --git a/core/src/main/resources/hudson/model/ComputerSet/index.jelly b/core/src/main/resources/hudson/model/ComputerSet/index.jelly index 421865bd2c3183fb348b55ea55a728dcd29e2167..22a8f39e346985edade65512cd013924a33207df 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/index.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/index.jelly @@ -68,7 +68,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/ComputerSet/index_bg.properties b/core/src/main/resources/hudson/model/ComputerSet/index_bg.properties index 7b844145ade14f50fe591bc91d222cf56416a570..ee523f43f62d7a2465a4874904d3dcf7f098eaa9 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/index_bg.properties +++ b/core/src/main/resources/hudson/model/ComputerSet/index_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,6 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Configure=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 -Name=\u0418\u043C\u0435 -Refresh\ status=\u0421\u0442\u0430\u0442\u0443\u0441 \u043D\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043D\u0435\u0442\u043E +Configure=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +Name=\ + \u0418\u043c\u0435 +Refresh\ status=\ + \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 +Data\ obtained=\ + \u041a\u043e\u0433\u0430 +Nodes=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u0440\u0438 diff --git a/core/src/main/resources/hudson/model/ComputerSet/index_sr.properties b/core/src/main/resources/hudson/model/ComputerSet/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a0f680dcf532eb34bc98193cfad1fabf61accc97 --- /dev/null +++ b/core/src/main/resources/hudson/model/ComputerSet/index_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Nodes=\u041C\u0430\u0448\u0438\u043D\u0435 +Name=\u0418\u043C\u0435 +Configure=\u041F\u043E\u0434\u0435\u0441\u0438 +Data\ obtained=\u0423\u0447\u0438\u0442\u0430\u043D\u0438 \u043F\u043E\u0434\u0430\u0446\u0438 +Refresh\ status=\u0421\u0442\u0430\u045A\u0435 \u043E\u0441\u0432\u0435\u0436\u0438\u0432\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/model/ComputerSet/new.jelly b/core/src/main/resources/hudson/model/ComputerSet/new.jelly index 8f3b7076dec82c90f92ef86e9645752034f70b4c..403cf5d9ff8df8b2d9391de93d2e5d1699ed6a84 100644 --- a/core/src/main/resources/hudson/model/ComputerSet/new.jelly +++ b/core/src/main/resources/hudson/model/ComputerSet/new.jelly @@ -23,7 +23,7 @@ THE SOFTWARE. --> + + + ${j} + + + + + +
    diff --git a/core/src/main/resources/hudson/model/Fingerprint/index_sr.properties b/core/src/main/resources/hudson/model/Fingerprint/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d348edb2072288fab74fea9e4ca1e7fe2c47a076 --- /dev/null +++ b/core/src/main/resources/hudson/model/Fingerprint/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 +introduced=\u0418\u0437\u0458\u0430\u0432\u0459\u0435\u043D\u043E \u043F\u0440\u0435 {0} +outside\ Jenkins=\u0438\u0437\u0432\u0430\u043D Jenkins +Usage=\u0418\u0441\u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0435 +This\ file\ has\ not\ been\ used\ anywhere\ else.=\u041E\u0432\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043D\u0438\u0458\u0435 \u0434\u0440\u0443\u0433\u0434\u0435 \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u043D\u0430. +This\ file\ has\ been\ used\ in\ the\ following\ places=\u041E\u0432\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0441\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u043A\u043E\u0434: diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail.jelly b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail.jelly index 583f693ef4b8404f29909eb5f8c8062382d73114..f720e3e51379280369ad83b00a124087c9d6c9b5 100644 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail.jelly +++ b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail.jelly @@ -24,5 +24,5 @@ THE SOFTWARE.
    - ${%body} + ${it.description}
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ar.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ar.properties deleted file mode 100644 index 8d8fada25e2cef6f6d0e5a057a492458ff98c5ca..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ar.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=\u0647\u0630\u0647 \u0647\u064A \u0627\u0644\u0645\u064A\u0632\u0629 \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629 \u0641\u064A \u062C\u0646\u0643\u0646\u0632. \u062C\u0646\u0643\u0646\u0632 \u0633\u064A\u0628\u0646\u064A \u0644\u0643 \u0645\u0634\u0631\u0648\u0639\u0643\u060C \u064A\u0633\u062A\u062E\u062F\u0645 \u0623\u062F\u0648\u0627\u062A \u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0645\u0635\u062F\u0631 \u0627\u0644\u0628\u0631\u0645\u062C\u064A\u060C \u0648\u064A\u0645\u0643\u0646 \u062D\u062A\u0649 \u0627\u0633\u062A\u062E\u062F\u0627\u0645\u0647\u0627 \uFEF7\u0634\u064A\u0627\u0621 \u063A\u064A\u0631 \u0628\u0646\u0627\u0621 \u0627\u0644\u0645\u0634\u0631\u0648\u0639. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_bg.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_bg.properties deleted file mode 100644 index 6ea50ab22d167b786535f4b5ef57e3d6d03d41eb..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_bg.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=\u0422\u043E\u0432\u0430 \u0435 \u043E\u0441\u043D\u043E\u0432\u043D\u0430 \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u043D\u043E\u0441\u0442 \u0432 Jenkins. Jenkins \u043C\u043E\u0436\u0435 \u0434\u0430 \u0431\u0438\u043B\u0434\u043D\u0435 \u0432\u0430\u0448 \u043F\u0440\u043E\u0435\u043A\u0442 \u043A\u043E\u043C\u0431\u0438\u043D\u0438\u0440\u0430\u0439\u043A\u0438 \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u0435\u043D \u0441\u043E\u0440\u0441 \u043A\u043E\u043D\u0442\u0440\u043E\u043B \u0441 \u043F\u0440\u043E\u0438\u0437\u0432\u043E\u043B\u043D\u0430 \u0431\u0438\u043B\u0434 \u0441\u0438\u0441\u0442\u0435\u043C\u0430, \u043A\u0430\u0442\u043E \u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u043E\u0440\u0438 \u0434\u0430 \u0433\u043E \u043F\u043E\u043B\u0437\u0432\u0430\u0442\u0435 \u0438 \u0437\u0430 \u0434\u0440\u0443\u0433\u0438 \u0446\u0435\u043B\u0438 \u0440\u0430\u0437\u043B\u0438\u0447\u043D\u0438 \u043E\u0442 \u0431\u0438\u043B\u0434\u0432\u0430\u043D\u0435 \u043D\u0430 \u0441\u043E\u0444\u0442\u0443\u0435\u0440. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ca.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ca.properties deleted file mode 100644 index 0b991b6b821377b3d7aa5e0b0496a9c79c408c0c..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ca.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=Aquesta \u00E9s la funcionalitat principal de Jenkins. Jenkins far\u00E0 un build del vostre projecte combinant qualsevol SCM amb qualsevol sistema de build. Aix\u00F2 tamb\u00E9 es pot usar per tasques que no siguin un build de software diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_cs.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_cs.properties deleted file mode 100644 index 15a4df88a9c00e14f095b855222d4d9cf8fc1589..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_cs.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=Toto je hlavn\u00ED funkce Jenkins. Jenkins sestav\u00ED v\u00E1\u0161 projekt, spoj\u00ED jak\u00FDkoli syst\u00E9m pro spr\u00E1vu verz\u00ED se syst\u00E9mem pro sestaven\u00ED. Nemus\u00ED b\u00FDt pou\u017Eit jen pro sestaven\u00ED softwaru. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_da.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_da.properties deleted file mode 100644 index b4febcef138d3c3c3eff13bf79dfd3c081b34815..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_da.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=Dette er den centrale feature i Jenkins. Jenkins vil bygge dit projekt i enhver kombination af kildekodestyring (SCM) med ethvert byggesystem og dette kan bruges til meget andet end at bygge software. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_es.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_es.properties deleted file mode 100644 index ec45052877f332fc2552c81f0229bcb7e11e5df1..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_es.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:cactusman -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=\ - Esta es la caracterstica principal de Jenkins, la de ejecutar el proyecto combinando cualquier tipo \ - de repositorio de software (SCM) con cualquier modo de construccion o ejecucin (make, ant, mvn, rake, script ...). \ - Por tanto se podr tanto compilar y empaquetar software, como ejecutar cualquier proceso que requiera monitorizacin. - diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_et.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_et.properties deleted file mode 100644 index c3c69a972c6770ba4000c9b8e3fba79892938180..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_et.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=See on Jenkinsi p\u00F5hifunktsioon! Jenkins ehitab su projekti, kombineerides sinu versioonihalduse mistahes ehitusprotsessiga. Sa v\u00F5id seda kasutada ka muudeks asjadeks kui tarkvara ehitamine. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_fi.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_fi.properties deleted file mode 100644 index aca64302b7ef369d6fea57cc5c0fcfdec15ee6d7..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_fi.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=T\u00E4m\u00E4 on Jenkins t\u00E4rkein ominaisuus. Jenkins rakentaa projektisi k\u00E4ytt\u00E4en versionhallintaa ja buildij\u00E4rjestelmi\u00E4. Voit k\u00E4ytt\u00E4\u00E4 t\u00E4t\u00E4 my\u00F6s muuhun kuin ohjelmien k\u00E4\u00E4nt\u00E4miseen. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_fr.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_fr.properties deleted file mode 100644 index 441d616f50565bc22895f483bfe1ac5938cb50f4..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_fr.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=Ceci est la fonction principale de Jenkins qui sert \u00E0 builder (construire) votre projet.
    Vous pouvez int\u00E9grer tous les outils de gestion de version avec tous les syst\u00E8mes de build.
    Il est m\u00EAme possible d''utiliser Jenkins pour tout autre chose qu''un build logiciel. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_hi_IN.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_hi_IN.properties deleted file mode 100644 index f83456bd02fd08999f2c1c52522bfe9151a1e622..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_hi_IN.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=\u092F\u0939 \u091C\u0947\u0928\u0915\u0940\u0902\u0938 \u0915\u0940 \u0915\u0947\u0902\u0926\u094D\u0930\u0940\u092F \u0935\u093F\u0936\u0947\u0937\u0924\u093E \u0939\u0948\u0964 \u091C\u0947\u0928\u0915\u0940\u0902\u0938, \u0915\u093F\u0938\u0940 \u092D\u0940 \u0928\u093F\u0930\u094D\u092E\u093E\u0923 \u092A\u094D\u0930\u0923\u093E\u0932\u0940 \u0915\u0947 \u0938\u093E\u0925 \u0915\u093F\u0938\u0940 \u092D\u0940 \u0938\u0949\u092B\u094D\u091F\u0935\u0947\u092F\u0930 \u0935\u093F\u0928\u094D\u092F\u093E\u0938 \u092A\u094D\u0930\u092C\u0902\u0927\u0928 \u0915\u093E \u0938\u0902\u092F\u094B\u091C\u0928 \u0915\u0930\u0915\u0947 \u0906\u092A\u0915\u0940 \u092A\u0930\u093F\u092F\u094B\u091C\u0928\u093E \u0915\u093E \u0928\u093F\u0930\u094D\u092E\u093E\u0923 \u0915\u0930\u0947\u0917\u093E, \u0914\u0930 \u0907\u0938\u0915\u093E \u092A\u094D\u0930\u092F\u094B\u0917 \u0938\u0949\u092B\u094D\u091F\u0935\u0947\u092F\u0930 \u0915\u093E \u0928\u093F\u0930\u094D\u092E\u093E\u0923 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0905\u0932\u093E\u0935\u093E \u0905\u0928\u094D\u092F \u0915\u093E\u0930\u094D\u092F\u094B\u0902 \u0915\u0947 \u0932\u093F\u090F \u092D\u0940 \u0915\u093F\u092F\u093E \u091C\u093E \u0938\u0915\u0924\u093E \u0939\u0948. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_id.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_id.properties deleted file mode 100644 index 0bd7d5726c6dcb1b20bc2c18c0ba194f0d249220..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_id.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=Ini adalah fitur sentral dari Jenkins. Jenkins akan membangun proyek anda, mengkombinasikan SCM apa pun dengan sistem pembangunan, dan ini akan digunakan untuk sesuatu selain pembangunan piranti lunak. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_it.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_it.properties deleted file mode 100644 index 09ff3126d87be949f3470d6b9e970eb4c4677bce..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_it.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=Questa \u00E8 la funzione principale di Jenkins. Jenkins effettuer\u00E0 una compilazione del progetto, combinando qualsiasi SCM con qualsiasi sistema di compilazione e si pu\u00F2 usare anche per qualcosa di altro che non sia un programma di compilazione. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ja.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ja.properties deleted file mode 100644 index 35598f0d335cc40e9816c0974db0cef6f313f03a..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ja.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:cactusman -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=\ - \u3082\u3063\u3068\u3082\u6c4e\u7528\u6027\u306e\u9ad8\u3044Jenkins\u306e\u4e2d\u6838\u6a5f\u80fd\u3067\u3059\u3002\u4efb\u610f\u306eSCM\u304b\u3089\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u30c1\u30a7\u30c3\u30af\u30a2\u30a6\u30c8\u3057\u3001\ - \u4efb\u610f\u306e\u30d3\u30eb\u30c9\u30b7\u30b9\u30c6\u30e0\u3067\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u30d3\u30eb\u30c9\u3067\u304d\u307e\u3059\u3002\u5f80\u3005\u306b\u3057\u3066\u3001\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u30d3\u30eb\u30c9\u4ee5\u5916\u306b\u3082\ - \u69d8\u3005\u306a\u4ed5\u4e8b\u306e\u81ea\u52d5\u5316\u306b\u5229\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ko.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ko.properties deleted file mode 100644 index e75ffeb39a7c94599cef662e3cc3f4c8973d5029..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ko.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=\uC774\uAC83\uC740 Jenkins\uC758 \uC8FC\uC694 \uAE30\uB2A5\uC785\uB2C8\uB2E4. Jenkins\uC740 \uC5B4\uB290 \uBE4C\uB4DC \uC2DC\uC2A4\uD15C\uACFC \uC5B4\uB5A4 SCM(\uD615\uC0C1\uAD00\uB9AC)\uC73C\uB85C \uBB36\uC778 \uB2F9\uC2E0\uC758 \uD504\uB85C\uC81D\uD2B8\uB97C \uBE4C\uB4DC\uD560 \uAC83\uC774\uACE0, \uC18C\uD504\uD2B8\uC6E8\uC5B4 \uBE4C\uB4DC\uBCF4\uB2E4 \uB2E4\uB978 \uC5B4\uB5A4 \uAC83\uC5D0 \uC790\uC8FC \uC0AC\uC6A9\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_lt.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_lt.properties deleted file mode 100644 index 60ae6f7c9dec2efcebf870463f07af96241aaf6c..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_lt.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=Pagrindin\u0117 Jenkins funkcija. Jenkins sukonstruos j\u016Bs\u0173 projekt\u0105, sujungdamas betkok\u012F SCM su betkokia konstravimo sistema. \u0160is darbo tipas gali b\u016Bt pritaikytas ne tik program\u0173 konstravimui. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_nb_NO.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_nb_NO.properties deleted file mode 100644 index 1d8c467e71601d1d7b7b919b3a38b85c4055914d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_nb_NO.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=Dette er en sentral egenskap ved Jenkins. Jenkins bygger dine prosjekter, kombinerer SCM (Source Control Management - Kildekodekontrollsystem ) med forskjellige byggsystemer og denne kan ogs\u00E5 brukes til mer enn bare \u00E5 bygge applikasjoner. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pl.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pl.properties deleted file mode 100644 index 2e8e7fa70de756b4e58a2451d9fef3971033aaaa..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pl.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=To jest podstawowa funkcja Jenkinsa. Jenkins stworzy projekt \u0142\u0105cz\u0105cy dowolny SCM z dowolnym systemem buduj\u0105cym, mo\u017Ce to by\u0107 r\u00F3wnie\u017C wykorzystane do czego\u015B innego ni\u017C budowanie oprogramowania. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pt_PT.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pt_PT.properties deleted file mode 100644 index 769ad93de77caa8f54d3e87a9c10fe6516aea092..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_pt_PT.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=Isto \u00E9 uma caracter\u00EDstica central do Jenkins. Jenkins vai construir o seu projecto, combinando qualquer SCM com qualquer sistema de compila\u00E7\u00E3o e isto pode ser usado mesmo em qualquer outra compila\u00E7\u00E3o de software. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ro.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ro.properties deleted file mode 100644 index b9a2e8fb70a1d4da18bcbdc8fc7bbcafa5ba3893..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_ro.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=Aceasta este func\u021Bionalitatea principal\u0103 a lui Jenkins. Jenkins va construi proiectul dvs, combin\u00E2nd orice SCM cu orice sistem de build-uri, \u0219i aceasta poate fi folosit\u0103 chiar \u0219i la altceva dec\u00E2t build-uri de aplica\u021Bii. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_tr.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_tr.properties deleted file mode 100644 index ad96ac4f59e5f53b537fb87b304baf3b485b9e93..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_tr.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Oguz Dag -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=\ - Jenkins''\u0131n merkezi \u00f6zelli\u011fi, projelerinizi yap\u0131land\u0131rman\u0131za yard\u0131m etmesidir. Bu proje t\u00fcr\u00fcn\u00fc kullanarak, \ - herhangi bir yap\u0131land\u0131rma sistemini herhangi bir Kaynak Kodu Y\u00f6netimi arac\u0131 ile birle\u015ftirebilirsiniz,\ - ve hatta yaz\u0131l\u0131m yap\u0131land\u0131rman\u0131n d\u0131\u015f\u0131nda ba\u015fka t\u00fcr projeler i\u00e7in dahi kullanabilirsiniz. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_uk.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_uk.properties deleted file mode 100644 index 96cf9358046190997730bb82b2293bad099c2961..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_uk.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -body=\u0426\u0435 - \u043E\u0441\u043D\u043E\u0432\u043D\u0430 \u0432\u0456\u0434\u043C\u0456\u043D\u043D\u0456\u0441\u0442\u044C Jenkins. Jenkins \u043F\u043E\u0431\u0443\u0434\u0443\u0454 \u0432\u0430\u0448 \u043F\u0440\u043E\u0435\u043A\u0442, \u043A\u043E\u043C\u0431\u0456\u043D\u0443\u044E\u0447\u0438 \u0431\u0443\u0434\u044C-\u044F\u043A\u0456 \u0441\u0438\u0441\u0442\u0435\u043C\u0438 \u0443\u043F\u0440\u0430\u0432\u043B\u0456\u043D\u043D\u044F \u043A\u043E\u0434\u043E\u043C \u0437 \u0431\u0443\u0434\u044C-\u044F\u043A\u0438\u043C\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u0430\u043C\u0438 \u0437\u0431\u0456\u0440\u043A\u0438, \u0449\u043E \u043C\u043E\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u0430\u043D\u043E \u043D\u0430\u0432\u0456\u0442\u044C \u0434\u043B\u044F \u0446\u0456\u043B\u0435\u0439 \u0432\u0456\u0434\u043C\u0456\u043D\u043D\u0438\u0445 \u0432\u0456\u0434 \u0437\u0431\u0456\u0440\u043A\u0438 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043D\u043E\u0433\u043E \u0437\u0430\u0431\u0435\u0437\u043F\u0435\u0447\u0435\u043D\u043D\u044F. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_zh_CN.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_zh_CN.properties deleted file mode 100644 index 745188fb5c575c5fb2ddecd6aee90e2a9b2d9204..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_zh_CN.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:cactusman -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=\u8FD9\u662FJenkins\u7684\u4E3B\u8981\u529F\u80FD.Jenkins\u5C06\u4F1A\u7ED3\u5408\u4EFB\u4F55SCM\u548C\u4EFB\u4F55\u6784\u5EFA\u7CFB\u7EDF\u6765\u6784\u5EFA\u4F60\u7684\u9879\u76EE, \u751A\u81F3\u53EF\u4EE5\u6784\u5EFA\u8F6F\u4EF6\u4EE5\u5916\u7684\u7CFB\u7EDF. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_zh_TW.properties b/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_zh_TW.properties deleted file mode 100644 index 9f8acc78f3a2ee7ebc8c632542375d9f4e42d667..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_zh_TW.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2013, Sun Microsystems, Inc., Chunghwa Telecom Co., Ltd., -# and Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -body=\ - \u9019\u662f Jenkins \u7684\u4e3b\u8981\u529f\u80fd\u3002\ - Jenkins \u80fd\u642d\u914d\u5404\u5f0f\u7a0b\u5f0f\u78bc\u7ba1\u7406\u3001\u5efa\u7f6e\u7cfb\u7d71\u4f86\u5efa\u7f6e\u60a8\u7684\u5c08\u6848\uff0c\ - \u751a\u81f3\u9084\u80fd\u505a\u8edf\u9ad4\u5efa\u7f6e\u4ee5\u5916\u7684\u5176\u4ed6\u4e8b\u60c5\u3002 diff --git a/core/src/main/resources/hudson/model/JDK/config_de.properties b/core/src/main/resources/hudson/model/JDK/config_de.properties index 0e96f25f7f3bb7c2ea803c186f1b8f53470c666d..b8b8b76869a2c554bae1954611687369e8f7cea3 100644 --- a/core/src/main/resources/hudson/model/JDK/config_de.properties +++ b/core/src/main/resources/hudson/model/JDK/config_de.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Name=Name +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Name=Name diff --git a/core/src/main/resources/hudson/model/JDK/config_sr.properties b/core/src/main/resources/hudson/model/JDK/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2fbb8bde38001bf90e43c02d70be99315bd965fa --- /dev/null +++ b/core/src/main/resources/hudson/model/JDK/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 diff --git a/core/src/main/resources/hudson/model/JDK/config_zh_CN.properties b/core/src/main/resources/hudson/model/JDK/config_zh_CN.properties index 4396111bece6a438e0ca2baee04e7204064a906c..3259f3501578f656d94be94154deb240ffe2c189 100644 --- a/core/src/main/resources/hudson/model/JDK/config_zh_CN.properties +++ b/core/src/main/resources/hudson/model/JDK/config_zh_CN.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Name=\u522b\u540d +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Name=\u522b\u540d diff --git a/core/src/main/resources/hudson/model/Job/_api.jelly b/core/src/main/resources/hudson/model/Job/_api.jelly index 684e8cc9fe37bafe70fb54bfe89ccb3e048af949..f2ee7bcf00c8b92ff746d6c6fb07a60dc67002e4 100644 --- a/core/src/main/resources/hudson/model/Job/_api.jelly +++ b/core/src/main/resources/hudson/model/Job/_api.jelly @@ -27,6 +27,14 @@ THE SOFTWARE. +

    Retrieving all builds

    +

    + To prevent Jenkins from having to load all builds from disk when someone accesses the job API, the builds + tree only contains the 50 newest builds. If you really need to get all builds, access the allBuilds tree, + e.g. by fetching …/api/xml?tree=allBuilds[…]. Note that this may result in significant performance degradation + if you have a lot of builds in this job. +

    +

    Fetch/Update job description

    this URL diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly b/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly index e389beed31b9ee2b53af2ed68460f43303d481f5..ec951a785d62ecf273b76c75e7912c40bc9aae98 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend.jelly @@ -72,7 +72,7 @@ THE SOFTWARE. ${%Build} ${%Duration} - ${%Slave} + ${%Agent} diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_bg.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_bg.properties index 54483eb2313efbeb7da49e0fcaf4b555f4d3c5d5..0bd66c1a99cb33a100fbceedfae53d9931f1cf29 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_bg.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_bg.properties @@ -1,4 +1,37 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Build=\u0411\u0438\u043B\u0434 -Duration=\u041F\u0440\u043E\u0434\u044A\u043B\u0436\u0438\u0442\u0435\u043B\u043D\u043E\u0441\u0442 +Build=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Duration=\ + \u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442 +# {0} Build time trend +title=\ + \u0417\u0430\u0433\u043b\u0430\u0432\u0438\u0435 +Timeline=\ + \u0412\u0440\u0435\u043c\u0435 +Build\ Time\ Trend=\ + \u0422\u0440\u0435\u043d\u0434 \u0437\u0430 \u0432\u0440\u0435\u043c\u0435\u0442\u043e \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Slave=\ + \u041f\u043e\u0434\u0447\u0438\u043d\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 +Agent=\ + \u0410\u0433\u0435\u043d\u0442 diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_da.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_da.properties index 6f693622769a5d69d7c58ea34d0187cc15d7e161..f4829493c37242a079465fd8da696d62d4d9dd78 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_da.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_da.properties @@ -24,6 +24,5 @@ title={0} Byggetidstrend Duration=Varighed Build\ Time\ Trend=Byggetidstrend Build=Byg -Slave=Slave More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Mere end et byg er n\u00f8dvendigt for at danne en trendrapport. Timeline=Tidslinie diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_de.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_de.properties index 20a7fc3a15ccd9b1bc270d4e5e54824f3731d959..0466c6359256b603e43dae99514e0f25f2861c73 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_de.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_de.properties @@ -23,7 +23,6 @@ title={0} Build-Dauer Trend Build=Build Duration=Dauer -Slave=Slave More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Fr einen Trendbericht sind mindestens zwei Builds notwendig. Timeline=Zeitleiste -Build\ Time\ Trend=Entwicklung der Build-Dauer \ No newline at end of file +Build\ Time\ Trend=Entwicklung der Build-Dauer diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_es.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_es.properties index 52ed3ef570ad7f0778caca8f4e72234c2b973b58..b39198f441a25c52bb103e53e31c21354a8ffbbf 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_es.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_es.properties @@ -22,7 +22,6 @@ title={0} Tendencia del tiempo de proceso Build=Ejecucin -Slave=Esclavo Duration=Duracin More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Ms de 1 ejecucin son necesarias para generar el grfico Build\ Time\ Trend=Tendencia del tiempo de ejecucin diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_fr.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_fr.properties index 5d6efe07242addc808933156e89efca270fe3672..c5528b81b45593b2beefd4f40512187ba1cd518a 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_fr.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_fr.properties @@ -25,5 +25,4 @@ title={0} Courbe de tendance de la dur\u00e9e du build Build=Build Build\ Time\ Trend=Tendance des temps de construction Duration=Dur\u00e9e -Slave=Esclave More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Plus de 1 build est n\u00e9cessaire pour le rapport de tendance. diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_hu.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_hu.properties index 4464362e1c2b9b056ba47727a815bb63f7ab472c..e5d67816dc5edd853cf287859684bf9d2a0023ac 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_hu.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_hu.properties @@ -3,5 +3,4 @@ Build=\u00C9p\u00EDt\u00E9s Build\ Time\ Trend=\u00C9p\u00EDt\u00E9si id\u0151 tendencia Duration=Id\u0151 -Slave=Csom\u00F3pont Timeline=Id\u0151vonal diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_ja.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_ja.properties index c147732ca4688bf3f66b5993e091b8b4ea0f83a9..c9cac2cdbf59c6774802bcd592d5a78eadb0ca75 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_ja.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_ja.properties @@ -25,4 +25,3 @@ Timeline=\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3 Build=\u30d3\u30eb\u30c9 Build\ Time\ Trend=\u30d3\u30eb\u30c9\u6642\u9593\u306e\u63a8\u79fb Duration=\u6240\u8981\u6642\u9593 -Slave=\u30b9\u30ec\u30fc\u30d6 diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_ko.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_ko.properties index d9b3a8e6d1ed6afe244a94f21f41aa037d30f139..197acb71513fc2500a6984aaa4826177f1b8fa36 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_ko.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_ko.properties @@ -24,5 +24,4 @@ Build=\uBE4C\uB4DC Build\ Time\ Trend=\uBE4C\uB4DC \uC18C\uC694 \uC2DC\uAC04 \uACBD\uD5A5 Duration=\uC18C\uC694\uC2DC\uAC04 More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=\uACBD\uD5A5 \uBCF4\uACE0\uC11C\uB294 1\uAC1C \uC774\uC0C1\uC758 \uBE4C\uB4DC\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. -Slave=Slave Timeline=\uD0C0\uC784\uB77C\uC778 diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_lv.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_lv.properties index df8252d96f851e708425c8fceed2875bf0ddc71e..0685e66a1635ba212f03f74c8c0c94eaf672a0eb 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_lv.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_lv.properties @@ -24,5 +24,4 @@ Build=B\u016Bv\u0113jums Build\ Time\ Trend=B\u016Bv\u0113jumu laika tendence Duration=Ilgums More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Tendences atskaitei nepiecie\u0161ams vismaz 1 b\u016Bv\u0113jums. -Slave=Slave Timeline=Laika nogrieznis diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_nl.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_nl.properties index b9bfcb6ba4fc6c09b9a19f56d466ebf2f8196094..bac54ff829de3fdf9353b921588bc9fbdd82a7a3 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_nl.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_nl.properties @@ -25,5 +25,4 @@ title={0} Duurtrend van een bouwpoging Build=Bouwpoging Build\ Time\ Trend=Bouw tijd trend Duration=Duur -Slave=Slaaf More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Er dienen minsten 2 bouwpogingen plaatsgevonden te hebben, vooralleer een trendrapport kan opgesteld worden. diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_pl.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_pl.properties index 736dc2efb47604ff705320d8dc376ee379999d82..76f7eb5480f1e6b2e4246d2a3b213e68bf5b6f1c 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_pl.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_pl.properties @@ -20,7 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ Time\ Trend=Trend czasu budowania +Build\ Time\ Trend=Trend czasu trwania zada\u0144 +Build=Zadanie Duration=Czas trwania -More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Potrzeba wi\u0119cej ni\u017C 1 builda by przygotowa\u0107 raport trendu +More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=Potrzeba wi\u0119cej ni\u017C jednego zadania by przygotowa\u0107 raport trendu Timeline=Linia czasu diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties index c29d10ac5bccbb7ec80aec4143aac88abe1ee460..5379d3b3c988cd6c1a95501a1e09f1f3ab4e2565 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_pt_BR.properties @@ -22,7 +22,6 @@ title={0} Tend\u00eancia de tempo de builds Duration=Dura\u00e7\u00e3o -Slave=SlaveMore\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=\u00c9 necess\u00e1rio mais do que um build para criar o relat\u00f3rio de tend\u00eancia. Build\ Time\ Trend=Tend\u00eancia de tempo de Build Timeline=Linha do tempo Build=Build diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_ru.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_ru.properties index 4307789795626036609c186f1b7f2176ef8198be..d7aa531f3bd196fa9f152303a7d5b4eb3e097a11 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_ru.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_ru.properties @@ -25,5 +25,4 @@ title={0} \u0413\u0440\u0430\u0444\u0438\u043a \u0432\u0440\u0435\u043c\u0435\u0 Build=\u0421\u0431\u043e\u0440\u043a\u0430 Build\ Time\ Trend=\u0413\u0440\u0430\u0444\u0438\u043A \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0438 Duration=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c -Slave=\u041f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0439 More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=\u0414\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u043a\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043e\u0434\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435. diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_sk.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_sk.properties index 0f7dfd3cc590e4143e45a00cc435c5f141853e1d..efb2e3b01f258cc2ea5a2804e630d13595102b85 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_sk.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_sk.properties @@ -3,5 +3,4 @@ Build=Zostavenie Build\ Time\ Trend=Trend \u010Dasu zostavenia Duration=Trvanie -Slave=Stroj Timeline=\u010Casov\u00E1 os diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_sr.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7dae472f70b6192b35fe8c9c8a8031f77d3a8287 --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +title={0} \u0442\u0440\u0435\u043D\u0434 \u0432\u0440\u0435\u043C\u0435\u043D\u0443 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +Timeline=\u0412\u0440\u0435\u043C\u0435 +Build\ Time\ Trend=\u0422\u0440\u0435\u043D\u0434 \u0432\u0440\u0435\u043C\u0435\u043D\u0443 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +Build=\u0418\u0437\u0433\u0440\u0430\u0434\u0438 +Duration=\u0422\u0440\u0430\u0458\u0430\u045A\u0435 +Agent=\u0410\u0433\u0435\u043D\u0442 +Slave=\u041F\u043E\u043C\u043E\u045B\u043D\u0438\u043A +More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=\u0412\u0438\u0448\u0435 \u043E\u0434 \u0458\u0435\u0434\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0437\u0430 \u0440\u0435\u043F\u043E\u0440\u0442\u0430\u0436\u0443 \u0442\u0440\u0435\u043D\u0434\u0430. diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_sv_SE.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_sv_SE.properties index 6eeafd4ac61d4895b1b08b465e307d475a234b87..90db2f4eb348e33d4fe8edea5af43715835eb993 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_sv_SE.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_sv_SE.properties @@ -23,4 +23,3 @@ Build=Bygge Build\ Time\ Trend=Byggtidstrend Duration=Tid -Slave=Nod diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_tr.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_tr.properties index 2f7f9c8529694f84d6e281564afb4a2cb94cda31..fafae7ebf8e4c588200c61621df64481e9db7d1c 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_tr.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_tr.properties @@ -25,5 +25,4 @@ title={0} yap\u0131land\u0131rma zaman\u0131 e\u011filimi Build=Yap\u0131land\u0131rma Build\ Time\ Trend=\u0130n\u015Faa Zaman E\u011Filimi Duration=S\u00fcre -Slave=Slave More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=E\u011filim raporu i\u00e7in birden fazla yap\u0131land\u0131rman\u0131n olmas\u0131 gerekir. diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_uk.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_uk.properties index 89d951ea750afd11de2ed12df127b358d51d98f4..926e23bd1e66bdc16dc4bbcc6c5ff3a758cef802 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_uk.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_uk.properties @@ -3,5 +3,4 @@ Build=\u041F\u043E\u0431\u0443\u0434\u043E\u0432\u0430 Build\ Time\ Trend=\u0422\u0440\u0435\u043D\u0434 \u0447\u0430\u0441\u0443 \u0431\u0443\u0434\u0443\u0432\u0430\u043D\u043D\u044F Duration=\u0422\u0440\u0438\u0432\u0430\u043B\u0456\u0441\u0442\u044C -Slave=\u0412\u0438\u043A\u043E\u043D\u0430\u0432\u0435\u0446\u044C Timeline=\u0427\u0430\u0441 diff --git a/core/src/main/resources/hudson/model/Job/buildTimeTrend_zh_TW.properties b/core/src/main/resources/hudson/model/Job/buildTimeTrend_zh_TW.properties index 85e788544fa9fad3c17942314cfacf9fb74c1ef2..df0952eae586e10a9f48e492906fac22d4461781 100644 --- a/core/src/main/resources/hudson/model/Job/buildTimeTrend_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Job/buildTimeTrend_zh_TW.properties @@ -28,7 +28,6 @@ Timeline=\u6642\u9593\u8ef8 Build\ Time\ Trend=\u5efa\u7f6e\u6642\u9593\u8da8\u52e2 Build=\u5efa\u7f6e Duration=\u4f7f\u7528\u6642\u9593 -Slave=Slave More\ than\ 1\ builds\ are\ needed\ for\ the\ trend\ report.=\ \u81f3\u5c11\u8981\u6709\u5169\u6b21\u4ee5\u4e0a\u7684\u5efa\u7f6e\u8a18\u9304\u624d\u80fd\u7522\u51fa\u8da8\u52e2\u5831\u544a\u3002 diff --git a/core/src/main/resources/hudson/model/Job/configure.jelly b/core/src/main/resources/hudson/model/Job/configure.jelly index afe44da1bd374befb5c4130690570ccb5afc823f..ddf5467f8d092f54324356f616e56ffca36648ec 100644 --- a/core/src/main/resources/hudson/model/Job/configure.jelly +++ b/core/src/main/resources/hudson/model/Job/configure.jelly @@ -27,50 +27,51 @@ THE SOFTWARE. --> - - - + + + + + + -

    ${%LOADING}
    - - - +
    +
    +
    + +
    ${%LOADING}
    - - - - - - - - + + + - - - - - - + + + + + + + + - - + - - + + - - - - - - - - - - - + + + + + + + + + + + +
    +
    +
    diff --git a/core/src/main/resources/hudson/model/Job/configure.properties b/core/src/main/resources/hudson/model/Job/configure.properties index f6f01a21a9ffa4e453610dc7283007ec9bb0b323..ba7d95bb98c211ac5f8bb88f8952a5f221ba6c6f 100644 --- a/core/src/main/resources/hudson/model/Job/configure.properties +++ b/core/src/main/resources/hudson/model/Job/configure.properties @@ -20,4 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -name={0} name \ No newline at end of file +name={0} name +Save=Save +Apply=Apply \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Job/configure_bg.properties b/core/src/main/resources/hudson/model/Job/configure_bg.properties index 5d8f2e70290e730c5c17a2606ed3b2fb62d2f2b4..42c3cd7bcb58333d65bce243a9afae16a49f2730 100644 --- a/core/src/main/resources/hudson/model/Job/configure_bg.properties +++ b/core/src/main/resources/hudson/model/Job/configure_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,8 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 -Discard\ Old\ Builds=\u041F\u0440\u0435\u043D\u0435\u0431\u0440\u0435\u0433\u0432\u0430\u043D\u0435 \u043D\u0430 \u0441\u0442\u0430\u0440\u0438\u0442\u0435 \u0431\u0438\u043B\u0434\u043E\u0432\u0435 -LOADING=\u0417\u0430\u0440\u0435\u0436\u0434\u0430\u043D\u0435 -Save=\u0417\u0430\u043F\u0438\u0448\u0438 -name=\u0438\u043C\u0435 +Description=\ + \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +LOADING=\ + \u0417\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 +Save=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 +name=\u0438\u043c\u0435 +# Apply +Apply=\ + \u041f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/Job/configure_cs.properties b/core/src/main/resources/hudson/model/Job/configure_cs.properties index a3242e7567da4b4ce04638638af87a0938029a90..c898b2bb2828ae9fee62e4a304ac8ebe1fcb76e9 100644 --- a/core/src/main/resources/hudson/model/Job/configure_cs.properties +++ b/core/src/main/resources/hudson/model/Job/configure_cs.properties @@ -1,6 +1,5 @@ # This file is under the MIT License by authors Description=Popis -Discard\ Old\ Builds=Zahodit star\u00E9 sestaven\u00ED LOADING=Nahr\u00E1v\u00E1n\u00ED name=jm\u00E9no diff --git a/core/src/main/resources/hudson/model/Job/configure_da.properties b/core/src/main/resources/hudson/model/Job/configure_da.properties index fa65b1a3d76999aa0ba224b4709cffdc1bd37e2d..52acd6704606d304f2650dbc028811ea44293af5 100644 --- a/core/src/main/resources/hudson/model/Job/configure_da.properties +++ b/core/src/main/resources/hudson/model/Job/configure_da.properties @@ -22,7 +22,6 @@ Strategy=Strategi name={0} navn -Discard\ Old\ Builds=Fjern Gamle Byg Save=Gem LOADING=INDL\u00c6SER Description=Beskrivelse diff --git a/core/src/main/resources/hudson/model/Job/configure_de.properties b/core/src/main/resources/hudson/model/Job/configure_de.properties index 553598aa9f0cfc43250ddf7b12c67f8ab5677d7b..6112e05e9a298b36b2f12aa3372c77510b922461 100644 --- a/core/src/main/resources/hudson/model/Job/configure_de.properties +++ b/core/src/main/resources/hudson/model/Job/configure_de.properties @@ -23,6 +23,5 @@ Strategy=Strategie name={0}name Description=Beschreibung -Discard\ Old\ Builds=Alte Builds verwerfen Save=Speichern LOADING=LADE DATEN diff --git a/core/src/main/resources/hudson/model/Job/configure_es.properties b/core/src/main/resources/hudson/model/Job/configure_es.properties index fe6860662559eda2151fe0f0ab3cd89a631c2c11..6c3bdab63a43f000273e2dce4f0bb298469c533a 100644 --- a/core/src/main/resources/hudson/model/Job/configure_es.properties +++ b/core/src/main/resources/hudson/model/Job/configure_es.properties @@ -22,7 +22,6 @@ Strategy=Estrategia name={0} nombre -Discard\ Old\ Builds=Desechar ejecuciones antiguas Save=Guardar Description=Descripcin LOADING=CARGANDO diff --git a/core/src/main/resources/hudson/model/Job/configure_es_AR.properties b/core/src/main/resources/hudson/model/Job/configure_es_AR.properties index 48a45961759ca16ee1dd42e6c11e22c3576a236e..9f83c8326196542d97c8d719bc7c46e595792f0f 100644 --- a/core/src/main/resources/hudson/model/Job/configure_es_AR.properties +++ b/core/src/main/resources/hudson/model/Job/configure_es_AR.properties @@ -1,6 +1,5 @@ # This file is under the MIT License by authors Description=Descripci\u00F3n -Discard\ Old\ Builds=Descargar build antiguos LOADING=CARGANDO name={0} nombre diff --git a/core/src/main/resources/hudson/model/Job/configure_et.properties b/core/src/main/resources/hudson/model/Job/configure_et.properties index b128ff63ca5b08783f053b7f17d518cb83df9654..9014e9008a021c4afc3f99b1ffef908e89fb5f54 100644 --- a/core/src/main/resources/hudson/model/Job/configure_et.properties +++ b/core/src/main/resources/hudson/model/Job/configure_et.properties @@ -1,6 +1,5 @@ # This file is under the MIT License by authors Description=Kirjeldus -Discard\ Old\ Builds=Eemalda vanad bildid LOADING=Laen name={0} nimi diff --git a/core/src/main/resources/hudson/model/Job/configure_fi.properties b/core/src/main/resources/hudson/model/Job/configure_fi.properties index bfb65f20a1c5bf6bc6d90c95af1ed6231322c0d3..03769c1d17c4644ee2f20ec3b703c36d939176c0 100644 --- a/core/src/main/resources/hudson/model/Job/configure_fi.properties +++ b/core/src/main/resources/hudson/model/Job/configure_fi.properties @@ -21,5 +21,4 @@ # THE SOFTWARE. Description=Kuvaus -Discard\ Old\ Builds=H\u00E4vit\u00E4 vanhat k\u00E4\u00E4nn\u00F6kset Save=Tallenna diff --git a/core/src/main/resources/hudson/model/Job/configure_fr.properties b/core/src/main/resources/hudson/model/Job/configure_fr.properties index 264d85c33f4e01bc0f610bf8cd351bfb52682741..252a92d8af0280f5216132d7a3936b563b6e9ea3 100644 --- a/core/src/main/resources/hudson/model/Job/configure_fr.properties +++ b/core/src/main/resources/hudson/model/Job/configure_fr.properties @@ -22,7 +22,6 @@ name=Nom du {0} Description=Description -Discard\ Old\ Builds=Supprimer les anciens builds Save=Sauver LOADING=CHARGEMENT Strategy=Strat\u00E9gie diff --git a/core/src/main/resources/hudson/model/Job/configure_he.properties b/core/src/main/resources/hudson/model/Job/configure_he.properties index bf8a3c763b0727b8d9337f89b9b2d6dff41b2164..1f1a76f0de19ddcb9f5c6fe73086ebe9f1131ab9 100644 --- a/core/src/main/resources/hudson/model/Job/configure_he.properties +++ b/core/src/main/resources/hudson/model/Job/configure_he.properties @@ -1,6 +1,5 @@ # This file is under the MIT License by authors Description=\u05EA\u05D0\u05D5\u05E8 -Discard\ Old\ Builds=\u05D4\u05E9\u05DE\u05D3 \u05D1\u05E0\u05D9\u05D5\u05EA \u05D9\u05E9\u05E0\u05D5\u05EA LOADING=\u05D8\u05D5\u05E2\u05DF name=\u05E9\u05DD {0} diff --git a/core/src/main/resources/hudson/model/Job/configure_hu.properties b/core/src/main/resources/hudson/model/Job/configure_hu.properties index b8c94eb8719da7858f64d8170b17dd24f42a1ae9..885ae20793d853efa8e0052b027b690aed0a0e53 100644 --- a/core/src/main/resources/hudson/model/Job/configure_hu.properties +++ b/core/src/main/resources/hudson/model/Job/configure_hu.properties @@ -1,7 +1,6 @@ # This file is under the MIT License by authors Description=Le\u00EDr\u00E1s -Discard\ Old\ Builds=R\u00E9gi \u00E9p\u00EDt\u00E9sek t\u00F6rl\u00E9se LOADING=BET\u00D6LT\u00C9S Strategy=Strat\u00E9gia name={0} n\u00E9v diff --git a/core/src/main/resources/hudson/model/Job/configure_it.properties b/core/src/main/resources/hudson/model/Job/configure_it.properties index f60881e74bc20e3c3aa4ad0ade64ce78da556514..516070295cd0cab3c363d9a3e9bcf09b92fe29d6 100644 --- a/core/src/main/resources/hudson/model/Job/configure_it.properties +++ b/core/src/main/resources/hudson/model/Job/configure_it.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Description=Descrizione -Discard\ Old\ Builds=Elimina Build Precedenti LOADING=CARICAMENTO Save=Salva Strategy=Strategia diff --git a/core/src/main/resources/hudson/model/Job/configure_ja.properties b/core/src/main/resources/hudson/model/Job/configure_ja.properties index 6e5c2ee080959707df3b437b2f4447244d344072..8a94d9d2037b2f4d0efba71627bab41376b414f4 100644 --- a/core/src/main/resources/hudson/model/Job/configure_ja.properties +++ b/core/src/main/resources/hudson/model/Job/configure_ja.properties @@ -22,7 +22,6 @@ name={0}\u540d Description=\u8aac\u660e -Discard\ Old\ Builds=\u53e4\u3044\u30d3\u30eb\u30c9\u306e\u7834\u68c4 Save=\u4fdd\u5b58 LOADING=\u30ed\u30fc\u30c9\u4e2d... -Strategy=\u65b9\u91dd \ No newline at end of file +Strategy=\u65b9\u91dd diff --git a/core/src/main/resources/hudson/model/Job/configure_ko.properties b/core/src/main/resources/hudson/model/Job/configure_ko.properties index 6e4b97f731333666cf10f75ace4fe8163ea07d33..e232a25de0a816d751e443cb5ba184e706cb1c71 100644 --- a/core/src/main/resources/hudson/model/Job/configure_ko.properties +++ b/core/src/main/resources/hudson/model/Job/configure_ko.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Description=\uC124\uBA85 -Discard\ Old\ Builds=\uC624\uB798\uB41C \uBE4C\uB4DC \uC0AD\uC81C LOADING=\uBD88\uB7EC\uC624\uB294 \uC911 Save=\uC800\uC7A5 Strategy=\uC804\uB7B5 diff --git a/core/src/main/resources/hudson/model/Job/configure_lt.properties b/core/src/main/resources/hudson/model/Job/configure_lt.properties index b594bec592a19975fa64165b227ea0b5b6eb1a38..fa183c864c97f0a0fa70767b842fd2e481ae59f7 100644 --- a/core/src/main/resources/hudson/model/Job/configure_lt.properties +++ b/core/src/main/resources/hudson/model/Job/configure_lt.properties @@ -1,7 +1,6 @@ # This file is under the MIT License by authors Description=Apra\u0161ymas -Discard\ Old\ Builds=Pa\u0161alinti senus darbus LOADING=\u012EKELIAMA Save=\u012Era\u0161yti Strategy=Strategija diff --git a/core/src/main/resources/hudson/model/Job/configure_lv.properties b/core/src/main/resources/hudson/model/Job/configure_lv.properties index b5608a91ae718fbed3734f715477d19c07a31e11..130eafbf90a4a3e541965df980082cec9f7ae215 100644 --- a/core/src/main/resources/hudson/model/Job/configure_lv.properties +++ b/core/src/main/resources/hudson/model/Job/configure_lv.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Description=Apraksts -Discard\ Old\ Builds=Dz\u0113st vecos b\u016Bv\u0113jumus LOADING=IEL\u0100D\u0112 Save=Saglab\u0101t name={0} nosaukums diff --git a/core/src/main/resources/hudson/model/Job/configure_nb_NO.properties b/core/src/main/resources/hudson/model/Job/configure_nb_NO.properties index 06330e0c48b3b4a0eda2408dc48f776f9b3816aa..9b6ee83290bca22933766e5f3356ff156d89c683 100644 --- a/core/src/main/resources/hudson/model/Job/configure_nb_NO.properties +++ b/core/src/main/resources/hudson/model/Job/configure_nb_NO.properties @@ -21,6 +21,5 @@ # THE SOFTWARE. Description=Beskrivelse -Discard\ Old\ Builds=Slett gamle bygg LOADING=LASTER name={0} navn diff --git a/core/src/main/resources/hudson/model/Job/configure_nl.properties b/core/src/main/resources/hudson/model/Job/configure_nl.properties index 332107a25516863719d16b7d1e3297779ccfa74b..bdec1d286a9af2bf37edf0017154911e22242b1b 100644 --- a/core/src/main/resources/hudson/model/Job/configure_nl.properties +++ b/core/src/main/resources/hudson/model/Job/configure_nl.properties @@ -23,6 +23,5 @@ Strategy=Strategie name={0} naam Description=Omschrijving -Discard\ Old\ Builds=Oude builds automatisch verwijderen LOADING=LADEN Save=Opslaan diff --git a/core/src/main/resources/hudson/model/Job/configure_pl.properties b/core/src/main/resources/hudson/model/Job/configure_pl.properties index d71bd2df454f20248acca854916fdd3b84dccd10..ebd96c0e7e38d1068edde07287cd34c9d075ecc9 100644 --- a/core/src/main/resources/hudson/model/Job/configure_pl.properties +++ b/core/src/main/resources/hudson/model/Job/configure_pl.properties @@ -21,8 +21,8 @@ # THE SOFTWARE. Description=Opis -Discard\ Old\ Builds=Porzu\u0107 stare buildy LOADING=\u0141ADOWANIE Save=Zapisz +Apply=Zastosuj Strategy=Strategia name={0} nazwa diff --git a/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties b/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties index 32d486e561bf255ed4f13dbc29944e1d7ba43d53..19b04234431c27473cd3f5e97e525b8ea627a6f2 100644 --- a/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Job/configure_pt_BR.properties @@ -23,6 +23,5 @@ Strategy=Estrat\u00E9gia name=Nome do {0} Description=Descri\u00e7\u00e3o -Discard\ Old\ Builds=Descartar builds antigos Save=Salvar LOADING=CARREGANDO diff --git a/core/src/main/resources/hudson/model/Job/configure_pt_PT.properties b/core/src/main/resources/hudson/model/Job/configure_pt_PT.properties index 7de593bdf3fc754f74a53407bdf0d6066bf42597..2e2937ce6bacb52f32506022fdfe016cdf362560 100644 --- a/core/src/main/resources/hudson/model/Job/configure_pt_PT.properties +++ b/core/src/main/resources/hudson/model/Job/configure_pt_PT.properties @@ -1,6 +1,5 @@ # This file is under the MIT License by authors Description=Descri\u00E7\u00E3o -Discard\ Old\ Builds=Descartar compila\u00E7\u00F5es antigas LOADING=A CARREGAR name={0} nome diff --git a/core/src/main/resources/hudson/model/Job/configure_ro.properties b/core/src/main/resources/hudson/model/Job/configure_ro.properties index 2260b1a4b107f9fe7882fc3efeb7cc75f3433140..1168eebe56233d9ebae89f73d050777abbc95872 100644 --- a/core/src/main/resources/hudson/model/Job/configure_ro.properties +++ b/core/src/main/resources/hudson/model/Job/configure_ro.properties @@ -1,7 +1,6 @@ # This file is under the MIT License by authors Description=Descriere -Discard\ Old\ Builds=Anuleaza Build-urile vechi LOADING=SE INCARCA Strategy=Strategie name=numele {0} diff --git a/core/src/main/resources/hudson/model/Job/configure_ru.properties b/core/src/main/resources/hudson/model/Job/configure_ru.properties index 721111e40d7cd697b2511888ed91d57edb89db35..795374cdf8335098e90ff91f100687ccae38ab9c 100644 --- a/core/src/main/resources/hudson/model/Job/configure_ru.properties +++ b/core/src/main/resources/hudson/model/Job/configure_ru.properties @@ -23,6 +23,5 @@ Strategy=\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f name={0} Description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 -Discard\ Old\ Builds=\u0423\u0434\u0430\u043b\u044f\u0442\u044c \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 LOADING=\u0417\u0410\u0413\u0420\u0423\u0417\u041a\u0410 Save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c diff --git a/core/src/main/resources/hudson/model/Job/configure_sk.properties b/core/src/main/resources/hudson/model/Job/configure_sk.properties index a218d7afe5fa38161387c06266e10d0a2d2e6b42..b08d5e7931880b3b0da8c9c4bc0d20fddfdabad7 100644 --- a/core/src/main/resources/hudson/model/Job/configure_sk.properties +++ b/core/src/main/resources/hudson/model/Job/configure_sk.properties @@ -1,7 +1,6 @@ # This file is under the MIT License by authors Description=Popis -Discard\ Old\ Builds=Vymazanie star\u00FDch zostaven\u00ED LOADING=Nahr\u00E1vanie Strategy=Strat\u00E9gia name={0} meno diff --git a/core/src/main/resources/hudson/model/Job/configure_sr.properties b/core/src/main/resources/hudson/model/Job/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..67e427cfa16d728ea574aa9b32b321b30004dc43 --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/configure_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +LOADING=\u0423\u0447\u0438\u0442\u0430\u0432\u0430\u045A\u0435 +name={0} \u0438\u043C\u0435 +Description=\u041E\u043F\u0438\u0441 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +Apply=\u041F\u0440\u0438\u043C\u0435\u043D\u0438 +Strategy=\u0428\u0435\u043C\u0430 diff --git a/core/src/main/resources/hudson/model/Job/configure_sv_SE.properties b/core/src/main/resources/hudson/model/Job/configure_sv_SE.properties index 862e6868eade3e97a065cedfaca17e53fa9d097a..43f4e32f31f4175d0e8ad5efb9103b5e83186e0b 100644 --- a/core/src/main/resources/hudson/model/Job/configure_sv_SE.properties +++ b/core/src/main/resources/hudson/model/Job/configure_sv_SE.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Description=Beskrivning -Discard\ Old\ Builds=Ta bort gamla byggen LOADING=LADDAR Save=Spara Strategy=Strategi diff --git a/core/src/main/resources/hudson/model/Job/configure_tr.properties b/core/src/main/resources/hudson/model/Job/configure_tr.properties index a530c119d24354a90dd2c9fcfb78379858c6f1bf..f65678e2fefcbc4ac9013713b9df8a45e7389535 100644 --- a/core/src/main/resources/hudson/model/Job/configure_tr.properties +++ b/core/src/main/resources/hudson/model/Job/configure_tr.properties @@ -23,6 +23,5 @@ Strategy=Strateji name={0} isim Description=A\u00e7\u0131klama -Discard\ Old\ Builds=Eski Yap\u0131land\u0131rmalardan Kurtul LOADING=Y\u00DCKLEN\u0130YOR Save=Kaydet diff --git a/core/src/main/resources/hudson/model/Job/configure_uk.properties b/core/src/main/resources/hudson/model/Job/configure_uk.properties index afbf1a51cccc36b07fe2ecf0cae1002e18e3fe9c..293d8113074a98938573f04de32adc6219bd0425 100644 --- a/core/src/main/resources/hudson/model/Job/configure_uk.properties +++ b/core/src/main/resources/hudson/model/Job/configure_uk.properties @@ -1,7 +1,6 @@ # This file is under the MIT License by authors Description=\u041E\u043F\u0438\u0441 -Discard\ Old\ Builds=\u0421\u043A\u0430\u0441\u0443\u0432\u0430\u0442\u0438 \u0441\u0442\u0430\u0440\u0456 \u0431\u0456\u043B\u0434\u0438 LOADING=\u0417\u0410\u0412\u0410\u041D\u0422\u0410\u0416\u0423\u0404\u0422\u042C\u0421\u042F Save=\u0417\u0431\u0435\u0440\u0435\u0433\u0442\u0438 Strategy=\u0421\u0442\u0440\u0430\u0442\u0435\u0433\u0456\u044F diff --git a/core/src/main/resources/hudson/model/Job/configure_zh_CN.properties b/core/src/main/resources/hudson/model/Job/configure_zh_CN.properties index 68143f6235b60bc4779d18c105fc21260c0991b9..307ce3d03f7c87178f1fc13b8b241407d97f3405 100644 --- a/core/src/main/resources/hudson/model/Job/configure_zh_CN.properties +++ b/core/src/main/resources/hudson/model/Job/configure_zh_CN.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Description=\u63CF\u8FF0 -Discard\ Old\ Builds=\u4E22\u5F03\u65E7\u7684\u6784\u5EFA LOADING=\u52A0\u8F7D\u4E2D Save=\u4FDD\u5B58 Strategy=\u7B56\u7565 diff --git a/core/src/main/resources/hudson/model/Job/configure_zh_TW.properties b/core/src/main/resources/hudson/model/Job/configure_zh_TW.properties index 7f09adb310104dc97cab56e8b00b81e3dfe8ea64..44bf241205fd815a13f1e500c1ddae37e44c15da 100644 --- a/core/src/main/resources/hudson/model/Job/configure_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Job/configure_zh_TW.properties @@ -25,7 +25,6 @@ LOADING=\u8B80\u53D6\u4E2D name={0} \u540D\u7A31 Description=\u63CF\u8FF0 -Discard\ Old\ Builds=\u5FFD\u7565\u820ABuilds Strategy=\u7b56\u7565 Save=\u5132\u5b58 diff --git a/core/src/main/resources/hudson/model/Job/index_bg.properties b/core/src/main/resources/hudson/model/Job/index_bg.properties index 08a72fc21a54d163c5c3cb318c8647cd4f7dc8fe..36a90de191695b7d970ba1ba5fce0d1429837c6f 100644 --- a/core/src/main/resources/hudson/model/Job/index_bg.properties +++ b/core/src/main/resources/hudson/model/Job/index_bg.properties @@ -1,3 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Project\ name=\u0418\u043C\u0435 \u043D\u0430 \u043F\u0440\u043E\u0435\u043A\u0442 +Project\ name=\ + \u0418\u043c\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 +Full\ project\ name=\ + \u041f\u044a\u043b\u043d\u043e \u0438\u043c\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 diff --git a/core/src/main/resources/hudson/model/Job/index_sr.properties b/core/src/main/resources/hudson/model/Job/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0d0ed0e2e702cd8da2cd134f5a52835727a47825 --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/index_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +Full\ project\ name=\u041F\u0443\u043D\u043E \u0438\u043C\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 +Project\ name=\u0418\u043C\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 +Disable\ Project=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +Enable=\u041E\u043C\u043E\u0433\u0443\u045B\u0443 +This\ project\ is\ currently\ disabled=\u041E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0458\u0435 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D +Permalinks=\u0422\u0440\u0430\u0458\u043D\u0438 \u043B\u0438\u043D\u043A\u043E\u0432\u0438 +Last\ build=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Last\ stable\ build=\u0417\u0430\u0434\u045A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Last\ successful\ build=\u0417\u0430\u0434\u045A\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Last\ failed\ build=\u0417\u0430\u0434\u045A\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/core/src/main/resources/hudson/model/Job/permalinks_bg.properties b/core/src/main/resources/hudson/model/Job/permalinks_bg.properties index 2c37fa3b8a50437a667985d89c3f5920848159e8..b9dd991b1704533e45706093a301e0135d339967 100644 --- a/core/src/main/resources/hudson/model/Job/permalinks_bg.properties +++ b/core/src/main/resources/hudson/model/Job/permalinks_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Permalinks=\u0421\u0442\u0430\u0442\u0438\u0447\u043D\u0438 \u0432\u0440\u044A\u0437\u043A\u0438 +Permalinks=\ + \u0421\u0442\u0430\u0442\u0438\u0447\u043d\u0438 \u0432\u0440\u044a\u0437\u043a\u0438 diff --git a/core/src/main/resources/hudson/model/Job/permalinks_pl.properties b/core/src/main/resources/hudson/model/Job/permalinks_pl.properties index f5ff9bd483199b1fa40443a30574ab97bc50e350..ce59813bf36d95ebb56041f523722ed9f3750089 100644 --- a/core/src/main/resources/hudson/model/Job/permalinks_pl.properties +++ b/core/src/main/resources/hudson/model/Job/permalinks_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Permalinks=Odno\u015Bniki permanentne +Permalinks=Odno\u015Bniki niezmienne diff --git a/core/src/main/resources/hudson/model/Job/permalinks_sr.properties b/core/src/main/resources/hudson/model/Job/permalinks_sr.properties index 875957e4c1ffb67801d2e76af4e67a6164ecd8c1..32c60f83c199b7f7217be42e2f27c87c02927876 100644 --- a/core/src/main/resources/hudson/model/Job/permalinks_sr.properties +++ b/core/src/main/resources/hudson/model/Job/permalinks_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Permalinks=Linkovi +Permalinks=\u0422\u0440\u0430\u0458\u043D\u0438 \u043B\u0438\u043D\u043A\u043E\u0432\u0438 diff --git a/core/src/main/resources/hudson/model/Job/rename_bg.properties b/core/src/main/resources/hudson/model/Job/rename_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..cdc08c0d849d4f017d2e42f583fd53156df983ed --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/rename_bg.properties @@ -0,0 +1,37 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# The name {0} is already in use. +newNameInUse=\ + \u0418\u043c\u0435\u0442\u043e \u201e{0}\u201c \u0435 \u0437\u0430\u0435\u0442\u043e. +# Yes +Yes=\ + \u0414\u0430 +# Unable to rename a job while it is building. +noRenameWhileBuilding=\ + \u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u043f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u043e \u0432\u0440\u0435\u043c\u0435 \u043d\u0430 \u043d\u0435\u0439\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 . +# All other configuration options were saved. +configWasSaved=\ + \u0412\u0441\u0438\u0447\u043a\u0438 \u0434\u0440\u0443\u0433\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0430 \u0437\u0430\u043f\u0430\u0437\u0435\u043d\u0438. +# Are you sure about renaming {0} to {1}? +description=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u043f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0435 \u201e{0}\u201c \u043d\u0430 \u201e{1}\u201c? diff --git a/core/src/main/resources/hudson/model/Job/rename_sr.properties b/core/src/main/resources/hudson/model/Job/rename_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..531c0a42259c88d77b6499db587c656fefe01946 --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/rename_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +noRenameWhileBuilding=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043F\u0440\u0435\u0438\u043C\u0435\u043D\u043E\u0432\u0430\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0434\u043E\u043A \u0441\u0435 \u0433\u0440\u0430\u0434\u0438. +configWasSaved=\u0421\u0432\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0443 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0430. +newNameInUse=\u0418\u043C\u0435 {0} \u0458\u0435 \u0437\u0430\u0443\u0437\u0435\u0442\u043E. +description=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043F\u0440\u0435\u0438\u043C\u0435\u043D\u0443\u0458\u0435\u0442\u0435 "{0}" \u0443 "{1}"? +Yes=\u0414\u0430 +No=\u041D\u0435 diff --git a/core/src/main/resources/hudson/model/Job/requirePOST_bg.properties b/core/src/main/resources/hudson/model/Job/requirePOST_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..f4894f5267d9f879ac4f24d80688d138562b0a2c --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/requirePOST_bg.properties @@ -0,0 +1,36 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Proceed=\ + \u041f\u0440\u043e\u0434\u044a\u043b\u0436\u0430\u0432\u0430\u043d\u0435 +Form\ post\ required=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043f\u043e\u0434\u0430\u0434\u0435\u0442\u0435 \u0444\u043e\u0440\u043c\u0443\u043b\u044f\u0440\u0430 \u0447\u0440\u0435\u0437 \u201ePOST\u201c. +# \ +# You must use POST method to trigger builds. \ +# (From scripts you may instead pass a per-project authentication token, or authenticate with your API token.) \ +# If you see this page, it may be because a plugin offered a GET link; file a bug report for that plugin. +use_post=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u201ePOST\u201c, \u0437\u0430 \u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. (\u0417\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435\ + \u043c\u043e\u0436\u0435 \u0434\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0436\u0435\u0442\u043e\u043d \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043a\u044a\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0438\u043b\u0438 \u0434\u0430 \u0441\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0430\u0442\u0435 \u0441 \ + \u0436\u0435\u0442\u043e\u043d\u0430 \u0441\u0438 \u0437\u0430 API.) \u0410\u043a\u043e \u0432\u0438\u0436\u0434\u0430\u0442\u0435 \u0442\u0430\u0437\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u0430\u0442\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0435, \u0447\u0435\ + \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u0432\u0438 \u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u0437\u0430 \u201eGET\u201c. \u041c\u043e\u043b\u0438\u043c \u043f\u043e\u0434\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u043b\u0430\u0434 \u0437\u0430\ + \u0433\u0440\u0435\u0448\u043a\u0430 \u0437\u0430 \u0442\u0430\u0437\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430. diff --git a/core/src/main/resources/hudson/model/Job/requirePOST_sr.properties b/core/src/main/resources/hudson/model/Job/requirePOST_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d1f040363ec472aab221fd4b3ed112564820c5e2 --- /dev/null +++ b/core/src/main/resources/hudson/model/Job/requirePOST_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Form\ post\ required=\u0422\u0440\u0435\u0431\u0430\u043B\u043E \u0431\u0438 \u043F\u043E\u0434\u043D\u0435\u0442\u0438 \u043E\u0431\u0440\u0430\u0437\u0430\u0446 \u043F\u0440\u0435\u043A\u043E "POST". +use_post=\u041C\u043E\u0440\u0430\u0442\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0438 \u043C\u0435\u0442\u043E\u0434 POST \u0434\u0430 \u0438\u0437\u0430\u0437\u043E\u0432\u0435\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435.\ +\u0410\u043A\u043E \u0432\u0430\u043C \u0458\u0435 \u043E\u0432\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u043F\u0440\u0438\u043A\u0430\u0437\u0430\u043D\u0430, \u043C\u043E\u0433\u0443\u045B\u0435 \u0458\u0435 \u0434\u0430 \u0458\u0435 \u043D\u0435\u043A\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 \u0438\u0437\u043F\u0443\u0441\u0442\u0438\u043B\u0430 GET \u0437\u0430\u0445\u0442\u0435\u0432, \u0443 \u043A\u043E\u043C \u0441\u043B\u0443\u0447\u0430\u0458\u0443 \u043F\u043E\u0434\u043D\u0435\u0441\u0438\u0442\u0435 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458 \u043E \u0433\u0440\u0435\u0448\u0446\u0438 \u0437\u0430 \u0442\u0443 \u043C\u043E\u0434\u0443\u043B\u0443. +Proceed=\u041D\u0430\u0441\u0442\u0430\u0432\u0438 diff --git a/core/src/main/resources/hudson/model/Label/index.jelly b/core/src/main/resources/hudson/model/Label/index.jelly index 931d7932df5ea14edb7af58d0489b008281bb565..10b239fd63cb4ad07a3edf8b70724107ef034151 100644 --- a/core/src/main/resources/hudson/model/Label/index.jelly +++ b/core/src/main/resources/hudson/model/Label/index.jelly @@ -36,7 +36,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/Label/index_sr.properties b/core/src/main/resources/hudson/model/Label/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..51a766a551e9051475371bb86a308067e6a3569e --- /dev/null +++ b/core/src/main/resources/hudson/model/Label/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Nodes=\u041C\u0430\u0448\u0438\u043D\u0435 +Projects=\u041F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 +None=\u041D\u0435\u043C\u0430 diff --git a/core/src/main/resources/hudson/model/Label/sidepanel.jelly b/core/src/main/resources/hudson/model/Label/sidepanel.jelly index 734a5c53dd6f58f74ab00e4e0238e59b7d5ae929..7d662a0a4564a076e43350878c6f95e4ee65806e 100644 --- a/core/src/main/resources/hudson/model/Label/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/Label/sidepanel.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/Label/sidepanel_sr.properties b/core/src/main/resources/hudson/model/Label/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..adab3fbf79fd9310b0f5899281c7fd47cbd063d6 --- /dev/null +++ b/core/src/main/resources/hudson/model/Label/sidepanel_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Overview=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 +Configure=\u041F\u043E\u0434\u0435\u0441\u0438 +Load\ Statistics=\u0423\u0447\u0438\u0442\u0430\u0458 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435 +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 diff --git a/core/src/main/resources/hudson/model/ListView/configure-entries_sr.properties b/core/src/main/resources/hudson/model/ListView/configure-entries_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..04cba4a19b8a02999efa39012bb63013f8217a67 --- /dev/null +++ b/core/src/main/resources/hudson/model/ListView/configure-entries_sr.properties @@ -0,0 +1,14 @@ +# This file is under the MIT License by authors + +Job\ Filters=\u0424\u0438\u043B\u0442\u0435\u0440\u0438 \u043D\u0430 \u0437\u0430\u0434\u0430\u0446\u0438\u043C\u0430 +Status\ Filter= +All\ selected\ jobs=\u0421\u0432\u0435 \u0438\u0437\u0430\u0431\u0440\u0430\u043D\u0438 \u0437\u0430\u0434\u0430\u0446\u0438 +Enabled\ jobs\ only=\u0421\u0430\u043C\u043E \u043E\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0438 \u0437\u0430\u0434\u0430\u0446\u0438 +Disabled\ jobs\ only=\u0421\u0430\u043C\u043E \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0438 \u0437\u0430\u0434\u0430\u0446\u0438 +Recurse\ in\ subfolders= +Jobs=\u0417\u0430\u0434\u0430\u0446\u0438 +Use\ a\ regular\ expression\ to\ include\ jobs\ into\ the\ view= +Regular\ expression=\u0420\u0435\u0433\u0443\u043B\u0430\u0440\u043D\u0438 \u0438\u0437\u0440\u0430\u0437 +Add\ Job\ Filter= +Columns=\u041A\u043E\u043B\u043E\u043D\u0435 +Add\ column=\u0414\u043E\u0434\u0430\u0458 \u043A\u043E\u043B\u043E\u043D\u0443 diff --git a/core/src/main/resources/hudson/model/ListView/newJobButtonBar.jelly b/core/src/main/resources/hudson/model/ListView/newJobButtonBar.jelly new file mode 100644 index 0000000000000000000000000000000000000000..c7af6102595074fc682a6cadc184704c8bf5d1c4 --- /dev/null +++ b/core/src/main/resources/hudson/model/ListView/newJobButtonBar.jelly @@ -0,0 +1,29 @@ + + + + + + + diff --git a/core/src/main/resources/hudson/model/ListView/newJobButtonBar_sr.properties b/core/src/main/resources/hudson/model/ListView/newJobButtonBar_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ff4f4a4f27400d0e8216673f666e641f0fec32eb --- /dev/null +++ b/core/src/main/resources/hudson/model/ListView/newJobButtonBar_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Add\ to\ current\ view=\u0414\u043E\u0434\u0430\u0458 \u043D\u0430 \u043E\u0432\u0430\u0458 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/hudson/model/ListView/newViewDetail_sr.properties b/core/src/main/resources/hudson/model/ListView/newViewDetail_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..93393667152bbf4ce1ec503c4e9c18ab861b21b8 --- /dev/null +++ b/core/src/main/resources/hudson/model/ListView/newViewDetail_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u041F\u043E\u043A\u0430\u0437\u0443\u0458\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0443 \u043E\u0431\u043B\u0438\u043A\u0443 \u043E\u0431\u0438\u0447\u043D\u0435 \u043B\u0438\u0441\u0442\u0435. \u041C\u043E\u0436\u0435\u0442\u0435 \u043E\u0434\u0430\u0431\u0440\u0430\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0437\u0430 \u043F\u0440\u0438\u043A\u0430\u0437\u0438\u0432\u0430\u045A\u0435 \u0443 \u043D\u0435\u043A\u043E\u043C \u043F\u0440\u0438\u043A\u0430\u0437\u0443. diff --git a/core/src/main/resources/hudson/model/LoadStatistics/main.properties b/core/src/main/resources/hudson/model/LoadStatistics/main.properties index 8bd2d4096749f28ac79ba5df8278ab42c71fd432..f8e8787faf131375a267996ccb760c5533976ad5 100644 --- a/core/src/main/resources/hudson/model/LoadStatistics/main.properties +++ b/core/src/main/resources/hudson/model/LoadStatistics/main.properties @@ -31,7 +31,7 @@ blurb=\ For a label: this is the sum of all executors across all online computers in this label.
    \ For the entire Jenkins: this is the sum of all executors across all online computers in this Jenkins \ installation.
    \ - Other than configuration changes, this value can also change when slaves go offline. \ + Other than configuration changes, this value can also change when agents go offline. \ \
    Number of busy executors
    \
    \ @@ -57,8 +57,8 @@ blurb=\ adding more computers.\
    \ \ -

    Note:The number of busy executors and the number of available executors need not \ - necessarily be equal to the number of online executors as executors can be suspended from\ +

    Note: The number of busy executors and the number of available executors need not \ + necessarily be equal to the number of online executors as executors can be suspended from \ accepting builds and thus be neither busy nor available.

    \

    The graph is an exponential moving average of periodically collected data values. \ 3 timespans are updated every 10 seconds, 1 minute and 1 hour respectively.

    diff --git a/core/src/main/resources/hudson/model/LoadStatistics/main_bg.properties b/core/src/main/resources/hudson/model/LoadStatistics/main_bg.properties index 4901c0926cc0b30ad1a8a296d359195f7e4876a8..b1a4f086134aba915802f41154937cd5c7e8bbda 100644 --- a/core/src/main/resources/hudson/model/LoadStatistics/main_bg.properties +++ b/core/src/main/resources/hudson/model/LoadStatistics/main_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,58 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Long=\u0414\u044A\u043B\u044A\u0433 -Medium=\u0421\u0440\u0435\u0434\u0435\u043D -Short=\u041A\u0440\u0430\u0442\u044A\u043A -title=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430 \u043D\u0430 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043D\u0435\u0442\u043E: {0} +Long=\ + \u0414\u044a\u043b\u044a\u0433 +Medium=\ + \u0421\u0440\u0435\u0434\u0435\u043d +Short=\ + \u041a\u0440\u0430\u0442\u044a\u043a +title=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0430 \u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0432\u0430\u043d\u0435\u0442\u043e: {0} +Load\ statistics\ graph=\ + \u0413\u0440\u0430\u0444\u0438\u043a\u0430 \u043d\u0430 \u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0432\u0430\u043d\u0435\u0442\u043e +Timespan=\ + \u0412\u0440\u0435\u043c\u0435\u0432\u0438 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d +blurb=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430\u0442\u0430 \u043d\u0430 \u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0432\u0430\u043d\u0435\u0442\u043e \u043f\u0440\u043e\u0441\u043b\u0435\u0434\u044f\u0432\u0430 \u0447\u0435\u0442\u0438\u0440\u0438 \u043a\u043b\u044e\u0447\u043e\u0432\u0438 \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u043d\u0430\ + \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0438:\ +
    \ +
    \u0411\u0440\u043e\u0439 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f (\u0432\u0441\u0438\u0447\u043a\u0438)
    \ +
    \ + \u0417\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440: \u0430\u043a\u043e \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u0442\u043e\u0432\u0430 \u0435 \u0431\u0440\u043e\u044f\u0442 \u043d\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438\u0442\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0438\ + \u043d\u0430 \u043d\u0435\u0433\u043e. \u0410\u043a\u043e \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u0447\u0438\u0441\u043b\u043e\u0442\u043e \u0435 0.
    \ + \u0417\u0430 \u0435\u0442\u0438\u043a\u0435\u0442: \u0442\u043e\u0432\u0430 \u0435 \u0441\u0431\u043e\u0440\u044a\u0442 \u043e\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u043e\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u0440\u0438 \u043d\u0430\ + \u043b\u0438\u043d\u0438\u044f \u0441 \u0442\u043e\u0437\u0438 \u0435\u0442\u0438\u043a\u0435\u0442.
    \ + \u0417\u0430 \u0446\u0435\u043b\u0438\u044f \u043a\u043b\u044a\u0441\u0442\u044a\u0440 \u043d\u0430 Jenkins: \u0442\u043e\u0432\u0430 \u0435 \u0441\u0431\u043e\u0440\u044a\u0442 \u043e\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u043e\u0442\ + \u0432\u0441\u0438\u0447\u043a\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u0440\u0438 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f \u0432 \u0442\u0430\u0437\u0438 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f \u043d\u0430 Jenkins.
    \ + \u0422\u0430\u0437\u0438 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0441\u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u044f \u043f\u0440\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0438 \u043f\u0440\u0438 \u0438\u0437\u043b\u0438\u0437\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u0440\u0438\ + \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f.\ +
    \ +
    \u0411\u0440\u043e\u0439 \u0437\u0430\u0435\u0442\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438
    \ +
    \ + \u0422\u043e\u0437\u0438 \u0431\u0440\u043e\u0439 \u043e\u0442\u0440\u0430\u0437\u044f\u0432\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0438\u0442\u0435 (\u0438\u0437\u043c\u0435\u0436\u0434\u0443 \u0432\u0441\u0438\u0447\u043a\u0438), \u043a\u043e\u0438\u0442\u043e \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u0442. \u041e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0442\u043e\u0437\u0438 \u0431\u0440\u043e\u0439 \u043a\u044a\u043c \u0433\u043e\u0440\u043d\u0438\u044f \u0434\u0430\u0432\u0430 \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u044f\u0442\u0430 \u043d\u0430\ + \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0438\u0442\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0438. \u0410\u043a\u043e \u0432\u0441\u0438\u0447\u043a\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u0441\u0430 \u0437\u0430\u0435\u0442\u0438 \u043f\u0440\u0435\u043a\u0430\u043b\u0435\u043d\u043e \u0447\u0435\u0441\u0442\u043e,\ + \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435 \u043e\u0449\u0435 \u043c\u0430\u0448\u0438\u043d\u0438 \u043a\u044a\u043c \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430 \u043d\u0430 Jenkins.\ +
    \ +
    \u0411\u0440\u043e\u0439 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438
    \ +
    \ + \u0422\u043e\u0437\u0438 \u0431\u0440\u043e\u0439 \u043e\u0442\u0440\u0430\u0437\u044f\u0432\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0438\u0442\u0435 (\u0438\u0437\u043c\u0435\u0436\u0434\u0443 \u0432\u0441\u0438\u0447\u043a\u0438), \u043a\u043e\u0438\u0442\u043e \u0441\u0430 \u0432 \u0441\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u0430\ + \u0437\u0430\u043f\u043e\u0447\u043d\u0430\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. \u041e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0442\u043e\u0437\u0438 \u0431\u0440\u043e\u0439 \u043a\u044a\u043c \u0433\u043e\u0440\u043d\u0438\u044f \u0434\u0430\u0432\u0430 \u043f\u0440\u043e\u043f\u043e\u0440\u0446\u0438\u044f\u0442\u0430 \u043d\u0430\ + \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0438. \u0410\u043a\u043e \u043d\u044f\u043c\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0438 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u043f\u0440\u0435\u043a\u0430\u043b\u0435\u043d\u043e \u0447\u0435\u0441\u0442\u043e,\ + \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435 \u043e\u0449\u0435 \u043c\u0430\u0448\u0438\u043d\u0438 \u043a\u044a\u043c \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430 \u043d\u0430 Jenkins.\ +
    \ +
    \u0414\u044a\u043b\u0436\u0438\u043d\u0430 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430
    \ +
    \ + \u0422\u043e\u0432\u0430 \u0435 \u0431\u0440\u043e\u044f\u0442 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435 \u0432 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u043a\u043e\u0438\u0442\u043e \u0438\u0437\u0447\u0430\u043a\u0432\u0430\u0442 \u0441\u0432\u043e\u0431\u043e\u0434\u0435\u043d\ + \u043f\u0440\u043e\u0446\u0435\u0441 (\u043d\u0430 \u0442\u043e\u0437\u0438 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u0438\u043b\u0438 \u0441 \u0442\u043e\u0437\u0438 \u0435\u0442\u0438\u043a\u0435\u0442, \u0438\u043b\u0438 \u043a\u044a\u0434\u0435\u0442\u043e \u0438 \u0434\u0430 \u0435 \u0432 \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430 \u043d\u0430\ + Jenkins). \u0422\u043e\u0432\u0430 \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0432\u0430 \u0437\u0430\u0434\u0430\u0447\u0438, \u043a\u043e\u0438\u0442\u043e \u0441\u0430 \u0432 \u0442\u0438\u0445 \u043f\u0435\u0440\u0438\u043e\u0434, \u043a\u0430\u043a\u0442\u043e \u0438 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435,\ + \u043a\u043e\u0438\u0442\u043e \u0441\u0430 \u0432 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430, \u0437\u0430\u0449\u043e\u0442\u043e \u0438\u0437\u0447\u0430\u043a\u0432\u0430\u0442 \u043f\u0440\u0435\u0434\u0438\u0448\u043d\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. \u0410\u043a\u043e \u0431\u0440\u043e\u044f\u0442 \u043d\u0430\u0434\u0432\u0438\u0448\u0438\ + 0, Jenkins \u0449\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0437\u0430\u0434\u0430\u0447\u0438, \u0430\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u0435 \u043e\u0449\u0435 \u043c\u0430\u0448\u0438\u043d\u0438 \u043a\u044a\u043c \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430.\ +
    \ +
    \ +

    \u0411\u0435\u043b\u0435\u0436\u043a\u0430: \u0421\u0431\u043e\u0440\u044a\u0442 \u043d\u0430 \u0437\u0430\u0435\u0442\u0438\u0442\u0435 \u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0438\u0442\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u043d\u0435 \u0432\u0438\u043d\u0430\u0433\u0438 \u0435 \u0440\u0430\u0432\u0435\u043d \u043d\u0430\ + \u0431\u0440\u043e\u044f \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u043d\u0438\u0442\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0438, \u0437\u0430\u0449\u043e\u0442\u043e \u043d\u044f\u043a\u043e\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438 \u043c\u043e\u0436\u0435 \u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u0435\u043c\u0430\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0437\u0430\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0438 \u0434\u0430 \u043d\u0435 \u0441\u0435 \u0431\u0440\u043e\u044f\u0442 \u043d\u0438\u0442\u043e \u0437\u0430\u0435\u0442\u0438, \u043d\u0438\u0442\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0438.

    \ +

    \u0413\u0440\u0430\u0444\u0438\u043a\u0430\u0442\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043f\u0440\u043e\u0437\u043e\u0440\u0435\u0446 \u0441 \u0435\u043a\u0441\u043f\u043e\u043d\u0435\u043d\u0446\u0438\u0430\u043b\u043d\u043e \u0437\u0430\u0433\u043b\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e\ + \u0441\u044a\u0431\u0438\u0440\u0430\u043d\u0438\u0442\u0435 \u0434\u0430\u043d\u043d\u0438. \u041e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0438\u044f\u0442\u0430 \u0441\u0430 \u043d\u0430 \u0432\u0441\u0435\u043a\u0438 10 \u0441\u0435\u043a\u0443\u043d\u0434\u0438, 1 \u043c\u0438\u043d\u0443\u0442\u0430 \u0438 1 \u0447\u0430\u0441.

    diff --git a/core/src/main/resources/hudson/model/LoadStatistics/main_sr.properties b/core/src/main/resources/hudson/model/LoadStatistics/main_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..de74c71dd496be326fa49b1f6577e732c78ce597 --- /dev/null +++ b/core/src/main/resources/hudson/model/LoadStatistics/main_sr.properties @@ -0,0 +1,48 @@ +# This file is under the MIT License by authors + +title=\u0423\u0447\u0438\u0442\u0430\u0458 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435: {0} +Timespan=\u0412\u0440\u0435\u043C\u0435 +Short=\u041A\u0440\u0430\u0442\u043A\u043E +Medium=\u0421\u0440\u0435\u0434\u045A\u0435 +Long=\u0414\u0443\u0433\u043E +Load\ statistics\ graph=\u0423\u0447\u0438\u0442\u0430\u0458 \u0433\u0440\u0430\u0444\u0438\u043A\u043E\u043D \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430 +blurb=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435 \u043E\u043F\u0442\u0435\u0440\u0435\u045B\u0435\u045A\u0430 \u043F\u0440\u0430\u0442\u0435 \u0447\u0435\u0442\u0438\u0440\u0438 \u0433\u043B\u0430\u0432\u043D\u0435 \u043C\u0435\u0442\u0440\u0438\u043A\u0435 \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430: \ +
    \ +
    \u0411\u0440\u043E\u0458 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430
    \ +
    \ + \u0417\u0430 \u043C\u0430\u0448\u0438\u043D\u0443: \u0430\u043A\u043E \u0458\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0430 \u043E\u043D\u0434\u0430 \u0458\u0435 \u043E\u0432\u043E \u0432\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \ + \u0442\u0430\u0458 \u0440\u0430\u0447\u0443\u043D\u0430\u0440 \u0438\u043C\u0430; \u0430\u043A\u043E \u043D\u0438\u0458\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u043D \u043E\u043D\u0434\u0430 \u0458\u0435 \u0437\u0431\u0438\u0440 \u043D\u0443\u043B\u0430.
    \ + \u0417\u0430 \u043B\u0430\u0431\u0435\u043B\u0443: \u0437\u0431\u0438\u0440 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u043D\u0430 \u0441\u0432\u0438\u043C \u0440\u0430\u0447\u0443\u043D\u0430\u0440\u0438\u043C\u0430 \u0441\u0430 \u043E\u0432\u043E\u043C \u043B\u0430\u0431\u0435\u043B\u043E\u043C.
    \ + \u0417\u0430 \u0446\u0435\u043E Jenkins: \u0437\u0431\u0438\u0440 \u0441\u0432\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u043D\u0430 \u043E\u0432\u043E\u0458 \u0438\u043D\u0441\u0442\u0430\u043D\u0446\u0438 Jenkins-\u0430.
    \ + \u041E\u0441\u0438\u043C \u043F\u0440\u043E\u043C\u0435\u043D\u0430 \u0443 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0443, \u043E\u0432\u0430 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442 \u043C\u043E\u0436\u0435 \u0441\u0435 \u043C\u0435\u045A\u0430\u0442\u0438 \u043A\u0430\u0434 \u0430\u0433\u0435\u043D\u0442\u0438 \u043F\u0440\u0435\u043A\u0438\u043D\u0443 \u0432\u0435\u0437\u0443. \ +
    \ +
    \u0411\u0440\u043E\u0458 \u0437\u0430\u0443\u0437\u0435\u0442\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430
    \ +
    \ + \u041E\u0437\u043D\u0430\u0447\u0430\u0432\u0430 \u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 (me\u0452\u0443 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u0438\u0437\u043D\u0430\u0434) \ + \u043A\u043E\u0458\u0438 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u0458\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. \u041E\u0434\u043D\u043E\u0441 \u043E\u0432\u0435 \u0446\u0438\u0444\u0440\u0435 \u043F\u0440\u0435\u043C\u0430 \u0431\u0440\u043E\u0458\u0443 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \ + \u0434\u0430\u0458\u0435 \u0432\u0430\u043C \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0410\u043A\u043E \u0441\u0443 \u0441\u0432\u0438 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0438 \u0437\u0430\u0443\u0437\u0435\u0442\u0438 \ + \u0437\u0430 \u0434\u0443\u0436\u0435 \u0432\u0440\u0435\u043C\u0435, \u043C\u043E\u0436\u0434\u0430 \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043B\u043E \u0434\u043E\u0434\u0430\u0442\u0438 \u0432\u0438\u0448\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u0443 \u0432\u0430\u0448\u0443 Jenkins \u0433\u0440\u0443\u043F\u0443.\ +
    \ +
    \u0411\u0440\u043E\u0458 \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430
    \ +
    \ + \u041E\u0437\u043D\u0430\u0447\u0430\u0432\u0430 \u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 (me\u0452\u0443 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u0438\u0437\u043D\u0430\u0434) \ + \u043A\u043E\u0458\u0438 \u043C\u043E\u0433\u0443 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. \u041E\u0434\u043D\u043E\u0441 \u043E\u0432\u0435 \u0446\u0438\u0444\u0440\u0435 \u043F\u0440\u0435\u043C\u0430 \u0431\u0440\u043E\u0458 \u0441\u0432\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \ + \u0434\u0430\u0458\u0435 \u0432\u0430\u043C \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0410\u043A\u043E \u043D\u0438\u0458\u0435\u0434\u0430\u043D \u043E\u0434 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u043D\u0438\u0458\u0435 \u0441\u043B\u043E\u0431\u043E\u0434\u0430\u043D \ + \u0437\u0430 \u0434\u0443\u0436\u0435 \u0432\u0440\u0435\u043C\u0435, \u043C\u043E\u0436\u0434\u0430 \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043B\u043E \u0434\u043E\u0434\u0430\u0442\u0438 \u0432\u0438\u0448\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u0443 \u0432\u0430\u0448\u0443 Jenkins \u0433\u0440\u0443\u043F\u0443.\ +
    \ +
    \u0414\u0443\u0436\u0438\u043D\u0430 \u0440\u0435\u0434\u0430
    \ +
    \ + \u0411\u0440\u043E\u0458 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 \u043A\u043E\u0458\u0438 \u0441\u0435 \u043D\u0430\u043B\u0430\u0437\u0435 \u0443 \u0440\u0435\u0434\u0443 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443, \u0447\u0435\u043A\u0430\u0458\u0443\u045B\u0438 \ + \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u043E\u0433 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 (\u043D\u0430 \u043E\u0432\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438, \u0441\u0430 \u043E\u0432\u043E\u043C \u043B\u0430\u0431\u0435\u043B\u043E\u043C, \u0446\u0435\u043B\u0438\u043C Jenkins-\u043E\u043C) \ + \u0426\u0438\u0444\u0440\u0430 \u043D\u0435 \u0443\u043A\u0459\u0443\u0447\u0443\u0458\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u043F\u043E\u0434 \u0442\u0438\u0445\u0438\u043C \u0440\u0435\u0436\u0438\u043C\u043E\u043C, \u043D\u0438\u0442\u0438 \ + \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u043A\u043E\u0458\u0438 \u0441\u0443 \u0443 \u0440\u0435\u0434\u0443 \u0437\u0430\u0448\u0442\u043E \u043F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0441\u0443 \u0458\u043E\u0448 \u0443\u0432\u0435\u043A \u0443 \u0442\u043E\u043A\u0443. \ + \u0410\u043A\u043E \u0431\u0440\u043E\u0458 \u043F\u0440\u0435\u0452\u0435 \u043F\u0440\u0435\u043A\u043E 0, Jenkins \u045B\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0442\u0430\u043A\u043E \u0448\u0442\u043E \u045B\u0435 \u0434\u043E\u0434\u0430\u0442\u0438 \u0458\u043E\u0448 \u043C\u0430\u0448\u0438\u043D\u0430. \ +
    \ +
    \ +

    \u0411\u0435\u043B\u0435\u0448\u043A\u0430: \u0411\u0440\u043E\u0458 \u0437\u0430\u0443\u0437\u0435\u0442\u0438\u0445 \u0438 \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u043D\u0435\u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \ + \u0458\u0435\u0434\u043D\u0430\u043A \u0431\u0440\u043E\u0458\u0443 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0438\u0445 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430, \u0437\u0430\u0448\u0442\u043E \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0438 \u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u0441\u0443\u0441\u043F\u0435\u043D\u0434\u043E\u0432\u0430\u043D\u0438 \ + \u0438 \u043F\u0440\u0435\u043C\u0430 \u0442\u043E\u043C\u0435 \u043D\u0438\u0442\u0438 \u0437\u0430\u0443\u0437\u0435\u0442\u0438\u0430 \u043D\u0438 \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u0438\u0430.

    \ +

    \u0413\u0440\u0430\u0444\u0438\u043A\u043E\u043D \u0458\u0435 \u0435\u043A\u0441\u043F\u043E\u043D\u0435\u043D\u0446\u0438\u0430\u043B\u043D\u0438 \u043F\u043E\u043A\u0440\u0435\u0442\u043D\u0438 \u043F\u0440\u0435\u0441\u0435\u043A \u043E\u0434 \u043F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u043E \u043F\u0440\u0438\u043A\u0443\u043F\u0459\u0435\u043D\u0435 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442\u0438. \ + 3 \u0440\u0430\u0441\u043F\u043E\u043D\u0430 \u0441\u0443 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u0430 \u0441\u0432\u0430\u043A\u0438\u0445 10 \u0441\u0435\u043A\u0443\u043D\u0434\u0438, 1 \u043C\u0438\u043D\u0443\u0442\u0430 \u0438 1 \u0447\u0430\u0441\u0430.

    + diff --git a/core/src/main/resources/hudson/model/Messages.properties b/core/src/main/resources/hudson/model/Messages.properties index c9b024bca3d3a8367f7655fa6560eb7141e4a8a4..70bba990cf77ff7df505ccff77b989b217ee8df9 100644 --- a/core/src/main/resources/hudson/model/Messages.properties +++ b/core/src/main/resources/hudson/model/Messages.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2012, Sun Microsystems, Inc., Kohsuke Kawaguchi, +# Copyright (c) 2004-2015, Sun Microsystems, Inc., Kohsuke Kawaguchi, # Eric Lefevre-Ardant, Erik Ramfelt, Seiji Sogabe, id:cactusman, # Manufacture Francaise des Pneumatiques Michelin, Romain Seguy # @@ -29,26 +29,24 @@ AbstractBuild.BuildingInWorkspace=\ in workspace {0} AbstractBuild.KeptBecause=This build is kept because of {0}. AbstractItem.NoSuchJobExists=No such job \u2018{0}\u2019 exists. Perhaps you meant \u2018{1}\u2019? +AbstractItem.NoSuchJobExistsWithoutSuggestion=No such job \u2018{0}\u2019 exists. AbstractItem.Pronoun=Item -AbstractProject.AssignedLabelString_NoMatch_DidYouMean=There\u2019s no slave/cloud that matches this assignment. Did you mean \u2018{1}\u2019 instead of \u2018{0}\u2019? +AbstractProject.AssignedLabelString_NoMatch_DidYouMean=There\u2019s no agent/cloud that matches this assignment. Did you mean \u2018{1}\u2019 instead of \u2018{0}\u2019? AbstractProject.NewBuildForWorkspace=Scheduling a new build to get a workspace. AbstractProject.AwaitingBuildForWorkspace=Awaiting build to get a workspace. AbstractProject.AwaitingWorkspaceToComeOnline=We need to schedule a new build to get a workspace, but deferring {0}ms in the hope that one will become available soon AbstractProject.Pronoun=Project AbstractProject.Aborted=Aborted -AbstractProject.BuildInProgress=Build #{0} is already in progress{1} -AbstractProject.BuildNow=Build Now -AbstractProject.build_with_parameters=Build with Parameters AbstractProject.UpstreamBuildInProgress=Upstream project {0} is already building. AbstractProject.DownstreamBuildInProgress=Downstream project {0} is already building. AbstractProject.Disabled=Build disabled -AbstractProject.ETA=\ (ETA:{0}) AbstractProject.NoBuilds=No existing build. Scheduling a new one. AbstractProject.NoSCM=No SCM AbstractProject.NoWorkspace=No workspace is available, so can\u2019t check for updates. AbstractProject.WorkspaceTitle=Workspace of {0} AbstractProject.WorkspaceTitleOnComputer=Workspace of {0} on {1} AbstractProject.PollingABorted=SCM polling aborted +AbstractProject.PollingVetoed=SCM polling vetoed by {0} AbstractProject.ScmAborted=SCM check out aborted AbstractProject.WorkspaceOffline=Workspace is offline. AbstractProject.BuildPermission.Description=\ @@ -75,9 +73,9 @@ AbstractProject.CancelPermission.Description=\ AbstractProject.AssignedLabelString.InvalidBooleanExpression=\ Invalid boolean expression: {0} AbstractProject.AssignedLabelString.NoMatch=\ - There's no slave/cloud that matches this assignment + There's no agent/cloud that matches this assignment AbstractProject.CustomWorkspaceEmpty=Custom workspace is empty. -AbstractProject.LabelLink=Slaves in label: {2} +AbstractProject.LabelLink=Label {1} is serviced by {3,choice,0#no nodes|1#1 node|1<{3} nodes}{4,choice,0#|1# and 1 cloud|1< and {4} clouds} Api.MultipleMatch=XPath "{0}" matched {1} nodes. \ Create XPath that only matches one, or use the "wrapper" query parameter to wrap them all under a root element. @@ -94,40 +92,36 @@ BallColor.Unstable=Unstable Build.post_build_steps_failed=Post-build steps failed CLI.clear-queue.shortDescription=Clears the build queue. -CLI.delete-job.shortDescription=Deletes a job. -CLI.reload-job.shortDescription=Reloads this job from disk. CLI.disable-job.shortDescription=Disables a job. CLI.enable-job.shortDescription=Enables a job. -CLI.delete-node.shortDescription=Deletes a node. -CLI.disconnect-node.shortDescription=Disconnects from a node. -CLI.connect-node.shortDescription=Reconnect to a node. CLI.online-node.shortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command. -CLI.offline-node.shortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command. -CLI.wait-node-online.shortDescription=Wait for a node to become online. -CLI.wait-node-offline.shortDescription=Wait for a node to become offline. - -Computer.Caption=Slave {0} -Computer.NoSuchSlaveExists=No such slave "{0}" exists. Did you mean "{1}"? -Computer.Permissions.Title=Slave -Computer.ExtendedReadPermission.Description=This permission allows users to read slave configuration. -Computer.ConfigurePermission.Description=This permission allows users to configure slaves. -Computer.DeletePermission.Description=This permission allows users to delete existing slaves. -Computer.CreatePermission.Description=This permission allows users to create slaves. -Computer.ConnectPermission.Description=This permission allows users to connect slaves or mark slaves as online. -Computer.DisconnectPermission.Description=This permission allows users to disconnect slaves or mark slaves as temporarily offline. -Computer.BuildPermission.Description=This permission allows users to run jobs as them on slaves. -Computer.BadChannel=Slave node offline or not a remote channel (such as master node). - -ComputerSet.NoSuchSlave=No such slave: {0} -ComputerSet.SlaveAlreadyExists=Slave called \u2018{0}\u2019 already exists -ComputerSet.SpecifySlaveToCopy=Specify which slave to copy -ComputerSet.DisplayName=nodes + +Computer.Caption=Agent {0} +Computer.NoSuchSlaveExists=No such agent "{0}" exists. Did you mean "{1}"? +Computer.NoSuchSlaveExistsWithoutAdvice=No such agent "{0}" exists. +Computer.Permissions.Title=Agent +Computer.ExtendedReadPermission.Description=This permission allows users to read agent configuration. +Computer.ConfigurePermission.Description=This permission allows users to configure agents. +Computer.DeletePermission.Description=This permission allows users to delete existing agents. +Computer.CreatePermission.Description=This permission allows users to create agents. +Computer.ConnectPermission.Description=This permission allows users to connect agents or mark agents as online. +Computer.DisconnectPermission.Description=This permission allows users to disconnect agents or mark agents as temporarily offline. +Computer.BuildPermission.Description=This permission allows users to run jobs as them on agents. +Computer.BadChannel=Agent node offline or not a remote channel (such as master node). + +ComputerSet.NoSuchSlave=No such agent: {0} +ComputerSet.SlaveAlreadyExists=Agent called \u2018{0}\u2019 already exists +ComputerSet.SpecifySlaveToCopy=Specify which agent to copy +ComputerSet.DisplayName=Nodes Descriptor.From=(from {0}) Executor.NotAvailable=N/A FreeStyleProject.DisplayName=Freestyle project +FreeStyleProject.Description=\ + This is the central feature of Jenkins. Jenkins will build your project, combining any SCM with any build system, \ + and this can be even used for something other than software build. HealthReport.EmptyString= @@ -175,7 +169,7 @@ Item.CREATE.description=Create a new job. Item.DELETE.description=Delete a job. Item.CONFIGURE.description=Change the configuration of a job. Item.READ.description=See a job. (You may deny this permission but allow Discover to force an anonymous user to log in to see the job.) - +ItemGroupMixIn.may_not_copy_as_it_contains_secrets_and_=May not copy {0} as it contains secrets and {1} has {2}/{3} but not /{4} Job.AllRecentBuildFailed=All recent builds failed. Job.BuildStability=Build stability: {0} Job.NOfMFailed={0} out of the last {1} builds failed. @@ -200,6 +194,8 @@ Queue.Unknown=??? Queue.WaitingForNextAvailableExecutor=Waiting for next available executor Queue.WaitingForNextAvailableExecutorOn=Waiting for next available executor on {0} Queue.init=Restoring the build queue +Queue.node_has_been_removed_from_configuration={0} has been removed from configuration +Queue.executor_slot_already_in_use=Executor slot already in use ResultTrend.Aborted=Aborted ResultTrend.Failure=Failure @@ -239,19 +235,19 @@ Run.Summary.BrokenSinceThisBuild=broken since this build Run.Summary.BrokenSince=broken since build {0} Run.Summary.Unknown=? -Slave.InvalidConfig.Executors=Invalid slave configuration for {0}. Invalid # of executors. -Slave.InvalidConfig.NoName=Invalid slave configuration. Name is empty -Slave.InvalidConfig.NoRemoteDir=Invalid slave configuration for {0}. No remote directory given -Slave.Launching={0} Launching slave agent +Slave.InvalidConfig.Executors=Invalid agent configuration for {0}. Invalid # of executors. +Slave.InvalidConfig.NoName=Invalid agent configuration. Name is empty +Slave.InvalidConfig.NoRemoteDir=Invalid agent configuration for {0}. No remote directory given +Slave.Launching={0} Launching agent Slave.Network.Mounted.File.System.Warning=Are you sure you want to use network mounted file system for FS root? Note that this directory does not need to be visible to the master. Slave.Remote.Director.Mandatory=Remote directory is mandatory -Slave.Terminated={0} slave agent was terminated +Slave.Terminated={0} agent was terminated Slave.Remote.Relative.Path.Warning=Are you sure you want to use a relative path for the FS root? Note that relative \ paths require that you can assure that the selected launcher provides a consistent current working directory. Using \ an absolute path is highly recommended. -Slave.UnableToLaunch=Unable to launch the slave agent for {0}{1} -Slave.UnixSlave=This is a Unix slave -Slave.WindowsSlave=This is a Windows slave +Slave.UnableToLaunch=Unable to launch the agent for {0}{1} +Slave.UnixSlave=This is a Unix agent +Slave.WindowsSlave=This is a Windows agent TopLevelItemDescriptor.NotApplicableIn={0} items are not applicable within {1} @@ -267,6 +263,8 @@ View.ConfigurePermission.Description=\ View.ReadPermission.Description=\ This permission allows users to see views (implied by generic read access). View.MissingMode=No view type is specified +View.DisplayNameNotUniqueWarning=The display name, "{0}", is already in use by another view and \ + could cause confusion and delay. UpdateCenter.Status.CheckingInternet=Checking internet connectivity UpdateCenter.Status.CheckingJavaNet=Checking update center connectivity @@ -278,25 +276,44 @@ UpdateCenter.Status.ConnectionFailed=\ Failed to connect to {0}. \ Perhaps you need to configure HTTP proxy? UpdateCenter.init=Initialing update center +UpdateCenter.CoreUpdateMonitor.DisplayName=Jenkins Update Notification + +UpdateCenter.PluginCategory.android=Android Development UpdateCenter.PluginCategory.builder=Build Tools UpdateCenter.PluginCategory.buildwrapper=Build Wrappers UpdateCenter.PluginCategory.cli=Command Line Interface +UpdateCenter.PluginCategory.cloud=Cloud Providers UpdateCenter.PluginCategory.cluster=Cluster Management and Distributed Build +UpdateCenter.PluginCategory.database=Database +UpdateCenter.PluginCategory.deployment=Deployment +UpdateCenter.PluginCategory.devops=DevOps +UpdateCenter.PluginCategory.dotnet=.NET Development UpdateCenter.PluginCategory.external=External Site/Tool Integrations +UpdateCenter.PluginCategory.groovy-related=Groovy-related +UpdateCenter.PluginCategory.ios=iOS Development +UpdateCenter.PluginCategory.library=Library plugins (for use by other plugins) UpdateCenter.PluginCategory.listview-column=List view columns UpdateCenter.PluginCategory.maven=Maven UpdateCenter.PluginCategory.misc=Miscellaneous UpdateCenter.PluginCategory.notifier=Build Notifiers UpdateCenter.PluginCategory.page-decorator=Page Decorators +UpdateCenter.PluginCategory.parameter=Build Parameters UpdateCenter.PluginCategory.post-build=Other Post-Build Actions +UpdateCenter.PluginCategory.python=Python Development UpdateCenter.PluginCategory.report=Build Reports +UpdateCenter.PluginCategory.ruby=Ruby Development +UpdateCenter.PluginCategory.runcondition=RunConditions for use by the Run Condition plugin +UpdateCenter.PluginCategory.scala=Scala Development UpdateCenter.PluginCategory.scm=Source Code Management UpdateCenter.PluginCategory.scm-related=Source Code Management related -UpdateCenter.PluginCategory.slaves=Slave Launchers and Controllers +UpdateCenter.PluginCategory.security=Security +UpdateCenter.PluginCategory.slaves=Agent Launchers and Controllers +UpdateCenter.PluginCategory.test=Testing UpdateCenter.PluginCategory.trigger=Build Triggers UpdateCenter.PluginCategory.ui=User Interface UpdateCenter.PluginCategory.upload=Artifact Uploaders UpdateCenter.PluginCategory.user=Authentication and User Management +UpdateCenter.PluginCategory.view=Views UpdateCenter.PluginCategory.must-be-labeled=Uncategorized UpdateCenter.PluginCategory.unrecognized=Misc ({0}) @@ -306,11 +323,12 @@ Permalink.LastUnstableBuild=Last unstable build Permalink.LastUnsuccessfulBuild=Last unsuccessful build Permalink.LastSuccessfulBuild=Last successful build Permalink.LastFailedBuild=Last failed build +Permalink.LastCompletedBuild=Last completed build ParameterAction.DisplayName=Parameters -ParametersDefinitionProperty.DisplayName=Parameters +ParametersDefinitionProperty.DisplayName=This project is parameterized StringParameterDefinition.DisplayName=String Parameter -TextParameterDefinition.DisplayName=Text Parameter +TextParameterDefinition.DisplayName=Multi-line String Parameter FileParameterDefinition.DisplayName=File Parameter BooleanParameterDefinition.DisplayName=Boolean Parameter ChoiceParameterDefinition.DisplayName=Choice Parameter @@ -321,9 +339,9 @@ PasswordParameterDefinition.DisplayName=Password Parameter Node.BecauseNodeIsReserved={0} is reserved for jobs with matching label expression Node.BecauseNodeIsNotAcceptingTasks={0} is not accepting tasks Node.LabelMissing={0} doesn\u2019t have label {1} -Node.LackingBuildPermission={0} doesn\u2019t have a permission to run on {1} -Node.Mode.NORMAL=Utilize this node as much as possible -Node.Mode.EXCLUSIVE=Only build jobs with label restrictions matching this node +Node.LackingBuildPermission={0} lacks permission to run on {1} +Node.Mode.NORMAL=Use this node as much as possible +Node.Mode.EXCLUSIVE=Only build jobs with label expressions matching this node ListView.DisplayName=List View @@ -357,9 +375,6 @@ MyViewsProperty.ViewExistsCheck.AlreadyExists=A view with name {0} already exist CLI.restart.shortDescription=Restart Jenkins CLI.safe-restart.shortDescription=Safely restart Jenkins CLI.keep-build.shortDescription=Mark the build to keep the build forever. -CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don\u2019t start any builds. -CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command. -CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk. BuildAuthorizationToken.InvalidTokenProvided=Invalid token provided. @@ -371,3 +386,5 @@ Jenkins.IsRestarting=Jenkins is restarting User.IllegalUsername="{0}" is prohibited as a username for security reasons. User.IllegalFullname="{0}" is prohibited as a full name for security reasons. + +Hudson.NoParamsSpecified=No Parameters are specified for this parameterized build diff --git a/core/src/main/resources/hudson/model/Messages_ar.properties b/core/src/main/resources/hudson/model/Messages_ar.properties new file mode 100644 index 0000000000000000000000000000000000000000..6ff7b6edcf98b3863f0c4568061d98b7bb7833d8 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_ar.properties @@ -0,0 +1 @@ +FreeStyleProject.Description=\u0647\u0630\u0647 \u0647\u064A \u0627\u0644\u0645\u064A\u0632\u0629 \u0627\u0644\u0631\u0626\u064A\u0633\u064A\u0629 \u0641\u064A \u062C\u0646\u0643\u0646\u0632. \u062C\u0646\u0643\u0646\u0632 \u0633\u064A\u0628\u0646\u064A \u0644\u0643 \u0645\u0634\u0631\u0648\u0639\u0643\u060C \u064A\u0633\u062A\u062E\u062F\u0645 \u0623\u062F\u0648\u0627\u062A \u0645\u0631\u0627\u0642\u0628\u0629 \u0627\u0644\u0645\u0635\u062F\u0631 \u0627\u0644\u0628\u0631\u0645\u062C\u064A\u060C \u0648\u064A\u0645\u0643\u0646 \u062D\u062A\u0649 \u0627\u0633\u062A\u062E\u062F\u0627\u0645\u0647\u0627 \uFEF7\u0634\u064A\u0627\u0621 \u063A\u064A\u0631 \u0628\u0646\u0627\u0621 \u0627\u0644\u0645\u0634\u0631\u0648\u0639. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_bg.properties b/core/src/main/resources/hudson/model/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..ce334d720b5728d79786ebd635f682874baecc6c --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_bg.properties @@ -0,0 +1,712 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +AbstractBuild.BuildingRemotely=\ + \u041e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0432\u044a\u0440\u0445\u0443 \u201e{0}\u201c +AbstractBuild.BuildingOnMaster=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0432\u044a\u0440\u0445\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f \u0441\u044a\u0440\u0432\u044a\u0440 +AbstractBuild_Building=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +AbstractBuild.BuildingInWorkspace=\ + \ \u0432 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u201e{0}\u201c +AbstractBuild.KeptBecause=\ + \u0422\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0441\u0435 \u043f\u0430\u0437\u0438, \u0437\u0430\u0440\u0430\u0434\u0438 \u201e{0}\u201c. + +AbstractItem.NoSuchJobExists=\ + \u041d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u0438\u043c\u0435 \u201e{0}\u201c. \u201e{1}\u201c \u043b\u0438 \u0438\u043c\u0430\u0445\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434? +AbstractItem.NoSuchJobExistsWithoutSuggestion=\ + \u041d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u0438\u043c\u0435 \u201e{0}\u201c. +AbstractItem.Pronoun=\ + \u0415\u043b\u0435\u043c\u0435\u043d\u0442 +AbstractProject.NewBuildForWorkspace=\ + \u041d\u0430\u0441\u0440\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043b\u0443\u0447\u0438 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. +AbstractProject.AwaitingBuildForWorkspace=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043b\u0443\u0447\u0438 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. +AbstractProject.AwaitingWorkspaceToComeOnline=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u043d\u0430\u0441\u0440\u043e\u0447\u0438 \u043d\u043e\u0432\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0437\u0430 \u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0438 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e.\ + \u0417\u0430\u0431\u0430\u0432\u044f\u043d\u0435 \u043e\u0442 {0}\u200ams \u0441 \u043d\u0430\u0434\u0435\u0436\u0434\u0430 \u0434\u0430 \u0441\u0435 \u043e\u0441\u0432\u043e\u0431\u043e\u0434\u0438 \u043d\u044f\u043a\u043e\u0435 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e +AbstractProject.Pronoun=\ + \u041f\u0440\u043e\u0435\u043a\u0442 +AbstractProject.Aborted=\ + \u041f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d +AbstractProject.UpstreamBuildInProgress=\ + \u201e{0}\u201c \u2014 \u0437\u0430\u0434\u0430\u0447\u0430, \u043e\u0442 \u043a\u043e\u044f\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438 \u0442\u0435\u043a\u0443\u0449\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0432\u0435\u0447\u0435 \u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430. +AbstractProject.DownstreamBuildInProgress=\ + \u201e{0}\u201c \u2014 \u0437\u0430\u0434\u0430\u0447\u0430, \u043a\u043e\u044f\u0442\u043e \u0437\u0430\u0432\u0438\u0441\u0438 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0432\u0435\u0447\u0435 \u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430. +AbstractProject.Disabled=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u043e +AbstractProject.NoBuilds=\ + \u041d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. \u041d\u0430\u0441\u0440\u043e\u0447\u0432\u0430 \u0441\u0435 \u043d\u043e\u0432\u043e. +AbstractProject.NoSCM=\ + \u041d\u044f\u043c\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 +AbstractProject.NoWorkspace=\ + \u041d\u044f\u043c\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. +AbstractProject.WorkspaceTitle=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u201e{0}\u201c +AbstractProject.WorkspaceTitleOnComputer=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u201e{0}\u201c \u043d\u0430 \u201e{1}\u201c +AbstractProject.PollingABorted=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430\u0442\u0430 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0438\u0442\u0435 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0435 \u043f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u0430 +AbstractProject.ScmAborted=\ + \u0418\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435\u0442\u043e \u043e\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0438\u0442\u0435 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0435 \u043f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e +AbstractProject.WorkspaceOffline=\ + \u0420\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043d\u0435 \u0435 \u043d\u0430\u043b\u0438\u0447\u043d\u043e. +AbstractProject.BuildPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e\u0442\u043e \u0437\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. +AbstractProject.WorkspacePermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430 \u0441\u0435 \u0440\u0430\u0437\u0433\u043b\u0435\u0436\u0434\u0430 \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043f\u0440\u0438\ + \u0438\u0437\u0432\u044a\u0440\u0448\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u043e\u0442 Jenkins. \u041e\u0442\u043d\u0435\u043c\u0435\u0442\u0435 \u0433\u043e, \u0430\u043a\u043e \u043d\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\ + \u0434\u0430 \u0434\u043e\u0441\u0442\u044a\u043f\u0432\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0432 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e (\u043d\u0430\u043f\u0440. \u0438\u0437\u0445\u043e\u0434\u043d\u0438\u044f \u043a\u043e\u0434, \u0438\u0437\u0442\u0435\u0433\u043b\u0435\u043d\ + \u043e\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0438\u0442\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043f\u0440\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e). +AbstractProject.ExtendedReadPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u0437\u0430 \u0447\u0435\u0442\u0435\u043d\u0435 \u0438 \u043c\u043e\u0436\u0435 \u0434\u0430\ + \u0434\u043e\u0432\u0435\u0434\u0435 \u0434\u043e \u0440\u0430\u0437\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u0430\u0439\u043d\u0438, \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u2014 \u043a\u0430\u0442\u043e \u043f\u0430\u0440\u043e\u043b\u0438\ + \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u0438 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435. +AbstractProject.DiscoverPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u043e\u0442\u043a\u0440\u0438\u0432\u0430\u043d\u0435 \u0438 \u0438\u0437\u0431\u0440\u043e\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435. \u041f\u0440\u0430\u0432\u043e\u0442\u043e \u0435 \u043f\u043e-\u0441\u043b\u0430\u0431\u043e \u043e\u0442\ + \u0434\u043e\u0441\u0442\u044a\u043f\u0430 \u0434\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u0437\u0430 \u0447\u0435\u0442\u0435\u043d\u0435, \u043d\u043e \u0432\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430 \u0434\u0430 \u043f\u0440\u0435\u043d\u0430\u0441\u043e\u0447\u0438\u0442\u0435\ + \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0438\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u043a\u044a\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f, \u043a\u043e\u0433\u0430\u0442\u043e \u0441\u0435 \u043e\u043f\u0438\u0442\u0430\u0442 \u0434\u0430\ + \u043e\u0442\u0432\u043e\u0440\u044f\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u043d\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. \u0410\u043a\u043e \u043f\u0440\u0430\u0432\u043e\u0442\u043e \u043d\u0435 \u0435 \u0434\u0430\u0434\u0435\u043d\u043e, \u043e\u0442\u0433\u043e\u0432\u043e\u0440\u044a\u0442\ + \u043d\u0430 \u0437\u0430\u044f\u0432\u043a\u0438\u0442\u0435 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0438\u0442\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435 \u0449\u0435 \u0435 \u0433\u0440\u0435\u0448\u043a\u0430 404 \u0438 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0438\u0442\u0435\ + \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u043d\u044f\u043c\u0430 \u0434\u0430 \u043d\u0430\u0443\u0447\u0430\u0432\u0430\u0442 \u0438\u043c\u0435\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0442\u0435. +# hudson.security.WipeOutPermission is set to true +AbstractProject.WipeOutPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0446\u044f\u043b\u043e\u0442\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430\u043d\u0438\u0435 \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e. +AbstractProject.CancelPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u043e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u0437\u0430\u043f\u043b\u0430\u043d\u0443\u0432\u0430\u043d\u043e \u0438 \u0441\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. +AbstractProject.AssignedLabelString.InvalidBooleanExpression=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0431\u0443\u043b\u0435\u0432 \u0438\u0437\u0440\u0430\u0437: {0} +AbstractProject.CustomWorkspaceEmpty=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0435 \u043f\u0440\u0430\u0437\u043d\u043e. +AbstractProject.LabelLink=\ + \u0415\u0442\u0438\u043a\u0435\u0442\u044a\u0442 {1} \u0441\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0432\u0430 \u043e\u0442\ + {3,choice,0#0 \u043c\u0430\u0448\u0438\u043d\u0438|1#1 \u043c\u0430\u0448\u0438\u043d\u0430|1<{3} \u043c\u0430\u0448\u0438\u043d\u0438}{4,choice,0#|1# \u0438 1 \u043e\u0431\u043b\u0430\u043a|1< \u0438 {4} \u043e\u0431\u043b\u0430\u043a\u0430} + +Api.MultipleMatch=\ + \u0418\u0437\u0440\u0430\u0437\u044a\u0442 \u0447\u0440\u0435\u0437 XPath \u201e{0}\u201c \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f \u043d\u0430 {1} \u043c\u0430\u0448\u0438\u043d\u0438. \u0417\u0430\u0434\u0430\u0439\u0442\u0435 \u0438\u0437\u0440\u0430\u0437, \u043a\u043e\u0439\u0442\u043e \u0434\u0430 + \u043d\u0430\u043f\u0430\u0441\u0432\u0430 \u0441\u0430\u043c\u043e \u0435\u0434\u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0438\u043b\u0438 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440\u0430 \u201ewrapper\u201c, \u0437\u0430 \u0434\u0430 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\ + \u0432\u0441\u0438\u0447\u043a\u0438 \u0442\u0435\u0437\u0438 \u043c\u0430\u0448\u0438\u043d\u0438 \u0432 \u043e\u0431\u0449 \u0435\u043b\u0435\u043c\u0435\u043d\u0442. +Api.NoXPathMatch=\ + \u0418\u0437\u0440\u0430\u0437\u044a\u0442 \u0447\u0440\u0435\u0437 XPath \u201e{0}\u201c \u043d\u0435 \u043d\u0430\u043f\u0430\u0441\u0432\u0430 \u0441 \u043d\u0438\u043a\u043e\u044f \u043c\u0430\u0448\u0438\u043d\u0430. + +BallColor.Aborted=\ + \u041e\u0442\u043c\u0435\u043d\u0435\u043d\u043e +BallColor.Disabled=\ + \u0418\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u043e +BallColor.Failed=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e +BallColor.InProgress=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 +BallColor.NotBuilt=\ + \u041d\u0435\u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u043e +BallColor.Pending=\ + \u041f\u0440\u0435\u0434\u0441\u0442\u043e\u0438 +BallColor.Success=\ + \u0423\u0441\u043f\u0435\u0448\u043d\u043e +BallColor.Unstable=\ + \u041d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e + +Build.post_build_steps_failed=\ + \u0421\u0442\u044a\u043f\u043a\u0438\u0442\u0435 \u0441\u043b\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0441\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438 +CLI.delete-job.shortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +CLI.reload-job.shortDescription=\ + \u041f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u043e\u0442 \u0434\u0438\u0441\u043a\u0430. +CLI.clear-queue.shortDescription=\ + \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0441\u044a\u0441 \u0437\u0430\u0434\u0430\u0447\u0438. +CLI.disable-job.shortDescription=\ + \u0418\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +CLI.enable-job.shortDescription=\ + \u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +CLI.delete-node.shortDescription=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430. +CLI.online-node.shortDescription=\ + \u041e\u0442\u043d\u043e\u0432\u043e \u0434\u0430 \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. \u041e\u0442\u043c\u0435\u043d\u044f\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u0445\u043e\u0434\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\ + \u201eoffline-node\u201c. +CLI.disconnect-node.shortDescription=\ + \u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u0441 \u043c\u0430\u0448\u0438\u043d\u0430. +CLI.connect-node.shortDescription=\ + \u0421\u0432\u044a\u0440\u0437\u0432\u0430\u043d\u0435 \u043a\u044a\u043c \u043c\u0430\u0448\u0438\u043d\u0430. +CLI.offline-node.shortDescription=\ + \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u0434\u043e\u043a\u0430\u0442\u043e \u043d\u0435 \u0441\u0435\ + \u0432\u044a\u0432\u0435\u0434\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eonline-node\u201c. +CLI.wait-node-online.shortDescription=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u0430 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. +CLI.wait-node-offline.shortDescription=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. + +ComputerSet.DisplayName=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u0440\u0438 + +Descriptor.From=\ + (\u043e\u0442 {0}) + +Executor.NotAvailable=\ + \u041b\u0438\u043f\u0441\u0432\u0430 + +FreeStyleProject.DisplayName=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 +FreeStyleProject.Description=\ + \u0422\u043e\u0432\u0430 \u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043d\u043e\u0441\u0442 \u0432 Jenkins. Jenkins \u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u0430\u0442\u043e\ + \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0441 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442. \u0422\u043e\u0432\u0430 \u0432\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430 \u0434\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 Jenkins \u0438 \u0437\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u0438 \u043e\u0442\ + \u043e\u0441\u0442\u043d\u043e\u0432\u043d\u0430\u0442\u0430 \u043c\u0443 \u0446\u0435\u043b\u0438. + + +Hudson.BadPortNumber=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u043d\u043e\u043c\u0435\u0440 \u043d\u0430 \u043f\u043e\u0440\u0442 \u201e{0}\u201c +Hudson.Computer.Caption=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0449 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 +Hudson.Computer.DisplayName=\ + \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0449 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 +Hudson.ControlCodeNotAllowed=\ + \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043d\u0438 \u0437\u043d\u0430\u0446\u0438 \u043d\u0435 \u0441\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0435\u043d\u0438: {0} +Hudson.DisplayName=\ + Jenkins +Hudson.JobAlreadyExists=\ + \u0412\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u0438\u043c\u0435 \u201e{0}\u201c. +Hudson.NoJavaInPath=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0438\u043c\u0438\u044f\u0442 \u0444\u0430\u0439\u043b \u201ejava\u201c \u043d\u0435 \u0435 \u0432 \u043f\u044a\u0442\u0438\u0449\u0430\u0442\u0430, \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438 \u0432 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0430\u0442\u0430 \u043d\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430\ + \u201ePATH\u201c. \u041f\u0440\u043e\u0431\u0432\u0430\u0439\u0442\u0435 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430\ + \u043d\u0430 Java (JDK). +Hudson.NoName=\ + \u041d\u0435 \u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0438\u043c\u0435. +Hudson.NoSuchDirectory=\ + \u041d\u044f\u043c\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0438\u043c\u0435 \u201e{0}\u201c +Hudson.NodeBeingRemoved=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430 \u0441\u0435 \u0438\u0437\u0432\u0430\u0436\u0434\u0430 \u043e\u0442 \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430 +Hudson.NotAPlugin=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430 \u043d\u0430 Jenkins. +Hudson.NotJDKDir=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043d\u0430 Java (JDK). +Hudson.Permissions.Title=\ + \u041e\u0431\u0449\u043e +Hudson.USER_CONTENT_README=\ + \u0424\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0432 \u0442\u0430\u0437\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0449\u0435 \u0441\u0430 \u0434\u043e\u0441\u0442\u044a\u043f\u043d\u0438 \u043f\u0440\u0435\u0437 \u0430\u0434\u0440\u0435\u0441\u0430 \ + \u201ehttp://server/jenkins/userContent/\u201c. +Hudson.UnsafeChar=\ + \u041e\u043f\u0430\u0441\u043d\u043e \u0435 \u0434\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0437\u043d\u0430\u043a\u0430 \u201e{0}\u201c. +Hudson.ViewAlreadyExists=\ + \u0412\u0435\u0447\u0435 \u0438\u043c\u0430 \u0438\u0437\u0433\u043b\u0435\u0434 \u0441 \u0438\u043c\u0435 \u201e{0}\u201c. +Hudson.ViewName=\ + \u0412\u0441\u0438\u0447\u043a\u0438 +Hudson.NotANumber=\ + \u041d\u0435 \u0435 \u0447\u0438\u0441\u043b\u043e. +Hudson.NotAPositiveNumber=\ + \u041d\u0435 \u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u043d\u043e \u0447\u0438\u0441\u043b\u043e. +Hudson.NotANonNegativeNumber=\ + \u0427\u0438\u0441\u043b\u043e\u0442\u043e \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0435 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u043d\u043e. +Hudson.NotANegativeNumber=\ + \u0427\u0438\u0441\u043b\u043e\u0442\u043e \u043d\u0435 \u0435 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u043d\u043e. +Hudson.NotUsesUTF8ToDecodeURL=\ + \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044a\u0442 \u0437\u0430 \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438 \u043d\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 UTF-8 \u0437\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u0438. \u0417\u043d\u0430\u0446\u0438\ + \u0438\u0437\u0432\u044a\u043d ASCII \u0432 \u0438\u043c\u0435\u043d\u0430\u0442\u0430 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u0434\u0440. \u0449\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044f\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435\ + \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u0433\u043b\u0435\u0434\u043d\u0435\u0442\u0435\ + \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0438\ + \u0438\ + \ + \u0418\u043d\u0442\u0435\u0440\u043d\u0430\u0446\u0438\u043e\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 Tomcat. +Hudson.AdministerPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u0430\u043a\u0442\u043e \u0438 \u043f\u044a\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e\ + \u043b\u043e\u043a\u0430\u043b\u043d\u0430\u0442\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 \u0440\u0430\u043c\u043a\u0438\u0442\u0435 \u043d\u0430 \u043f\u0440\u0430\u0432\u0430\u0442\u0430 \u0441\u043f\u043e\u0440\u0435\u0434 \u0440\u0430\u0431\u043e\u0442\u0435\u0449\u0430\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\ + \u0441\u0438\u0441\u0442\u0435\u043c\u0430. +Hudson.ReadPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0440\u0430\u0437\u0433\u043b\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0438\u0447\u043a\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0438 \u043d\u0430 Jenkins. \u0410\u043a\u043e \u043d\u0435\ + \u0438\u0441\u043a\u0430\u0442\u0435 \u043d\u0435\u043f\u043e\u0437\u043d\u0430\u0442\u0438\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0434\u0430 \u0432\u0438\u0436\u0434\u0430\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0438\u0442\u0435 \u043d\u0430 Jenkins, \u043e\u0442\u043d\u0435\u043c\u0435\u0442\u0435 \u0442\u043e\u0432\u0430\ + \u043f\u0440\u0430\u0432\u043e \u043d\u0430 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b (\u201eanonymous\u201c) \u0438 \u0433\u043e \u0434\u0430\u0439\u0442\u0435 \u043d\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0430\u043b\u0438\u0442\u0435 \u0441\u0435\ + \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 (\u201eauthenticated\u201c). +Hudson.RunScriptsPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435 \u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0430 \u043d\u0430 \u043f\u0440\u0435\u0437 \u043a\u043e\u043d\u0437\u043e\u043b\u0430\u0442\u0430 \u043d\u0430\ + Groovy \u0438\u043b\u0438 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438\u0442\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434. +Hudson.NodeDescription=\ + \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0449\u0438\u044f\u0442 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u043d\u0430 Jenkins + +Item.Permissions.Title=\ + \u0417\u0430\u0434\u0430\u0447\u0430 +Item.CREATE.description=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +Item.DELETE.description=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +Item.CONFIGURE.description=\ + \u041f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. +Item.READ.description=\ + \u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430. (\u041c\u043e\u0436\u0435 \u0434\u0430 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u0435 \u0442\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e, \u043d\u043e \u0447\u0440\u0435\u0437 \u043f\u0440\u0430\u0432\u043e\u0442\u043e \u0437\u0430 \u043e\u0442\u043a\u0440\u0438\u0432\u0430\u043d\u0435\ + \u0434\u0430 \u043d\u0430\u043a\u0430\u0440\u0430\u0442\u0435 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0438\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0434\u0430 \u0441\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0430\u0442, \u0437\u0430 \u0434\u0430 \u0432\u0438\u0434\u044f\u0442 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430.) + +Job.AllRecentBuildFailed=\ + \u0412\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u0441\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438. +Job.BuildStability=\ + \u0421\u0442\u0430\u0431\u0438\u043b\u043d\u043e\u0441\u0442 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430: {0} +Job.NOfMFailed=\ + {0} \u043e\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f {1} \u0441\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438. +Job.NoRecentBuildFailed=\ + \u0421\u043a\u043e\u0440\u043e \u043d\u0435 \u0435 \u0438\u043c\u0430\u043b\u043e \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +Job.Pronoun=\ + \u041f\u0440\u043e\u0435\u043a\u0442 +Job.minutes=\ + \u043c\u0438\u043d. + +Job.you_must_use_the_save_button_if_you_wish=\ + \u0417\u0430 \u0434\u0430 \u043f\u0440\u0435\u0438\u043c\u0435\u043d\u0443\u0432\u0430\u0442\u0435 \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430\u0442\u0438\u0441\u043d\u0435\u0442\u0435 \u0431\u0443\u0442\u043e\u043d\u0430 \u201e\u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435\u201c. +Label.GroupOf=\ + \u0433\u0440\u0443\u043f\u0430\u0442\u0430 \u043d\u0430 {0} +Label.InvalidLabel=\ + \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0435\u0442\u0438\u043a\u0435\u0442 +Label.ProvisionedFrom=\ + \u041d\u0430\u0431\u0430\u0432\u0435\u043d\u0430 \u043e\u0442 {0} +ManageJenkinsAction.DisplayName=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 Jenkins +Queue.AllNodesOffline=\ + \u041d\u0438\u043a\u043e\u044f \u043c\u0430\u0448\u0438\u043d\u0430 \u0441 \u0435\u0442\u0438\u043a\u0435\u0442 \u201e{0}\u201c \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. +Queue.LabelHasNoNodes=\ + \u041d\u044f\u043c\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0441 \u0435\u0442\u0438\u043a\u0435\u0442 \u201e{0}\u201c. +Queue.BlockedBy=\ + \u0411\u043b\u043e\u043a\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u201e{0}\u201c. +Queue.HudsonIsAboutToShutDown=\ + Jenkins \u0449\u0435 \u0441\u0435 \u0441\u043f\u0440\u0435. +Queue.InProgress=\ + \u0418\u0437\u0432\u044a\u0440\u0448\u0432\u0430 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. +Queue.InQuietPeriod=\ + \u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0442\u0438\u0448\u0438\u043d\u0430, \u0438\u0437\u0442\u0438\u0447\u0430 \u0441\u043b\u0435\u0434 {0} +Queue.NodeOffline=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f. +Queue.Unknown=\ + \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e +Queue.WaitingForNextAvailableExecutor=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0438\u044f \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440. +Queue.WaitingForNextAvailableExecutorOn=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0438\u044f \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u0437\u0430 \u201e{0}\u201c. +Queue.init=\ + \u0412\u044a\u0437\u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 \u0441 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. + +ResultTrend.Aborted=\ + \u041f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e +ResultTrend.Failure=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e +ResultTrend.Fixed=\ + \u041e\u043f\u0440\u0430\u0432\u0435\u043d\u043e +ResultTrend.NotBuilt=\ + \u041d\u0435\u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u043e +ResultTrend.NowUnstable=\ + \u041d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e +ResultTrend.StillFailing=\ + \u0412\u0441\u0435 \u043e\u0449\u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e +ResultTrend.StillUnstable=\ + \u0412\u0441\u0435 \u043e\u0449\u0435 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e +ResultTrend.Success=\ + \u0423\u0441\u043f\u0435\u0448\u043d\u043e +ResultTrend.Unstable=\ + \u041d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e +Run._is_waiting_for_a_checkpoint_on_=\ + {0} \u0438\u0437\u0447\u0430\u043a\u0432\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u043d\u0438\u044f \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430 {1} +Run.BuildAborted=\ + \u041f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Run.MarkedExplicitly=\ + \u0422\u043e\u0437\u0438 \u0437\u0430\u043f\u0438\u0441 \u0435 \u043e\u0442\u0431\u0435\u043b\u044f\u0437\u0430\u043d \u0437\u0430 \u0441\u044a\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435. +Run.Permissions.Title=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 +Run.running_as_=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043a\u0430\u0442\u043e \u201e{0}\u201c +Run.UnableToDelete=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c: {1} +Run.DeletePermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u043e\u0441\u043e\u0447\u0435\u043d\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u043e\u0442 \u0438\u0441\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u043d\u0430\ + \u0437\u0430\u0434\u0430\u0447\u0438\u0442\u0435. +Run.UpdatePermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430\u0442\u0430 \u043d\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\u0442\u043e \u0438 \u0434\u0440\u0443\u0433\u0438\u0442\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435.\ + \u0422\u0430\u043a\u0430 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u0442 \u043f\u0440\u0438\u0447\u0438\u043d\u0438\u0442\u0435 \u0437\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440. +Run.ArtifactsPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438\u0442\u0435, \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430. \u041d\u0435\ + \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e, \u0430\u043a\u043e \u0438\u0441\u043a\u0430\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u043d\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0438\u0437\u0442\u0435\u0433\u043b\u044f\u0442\ + \u0438\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e\u0442\u043e. +Run.InProgressDuration=\ + {0} \u0438 \u0440\u0430\u0441\u0442\u0435 +Run.NotStartedYet=\ + \u041e\u0449\u0435 \u043d\u0435 \u0435 \u0437\u0430\u043f\u043e\u0447\u043d\u0430\u043b\u043e +Run.ArtifactsBrowserTitle=\ + \u0410\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 \u043d\u0430 {0} {1} + +Run.Summary.Stable=\ + \u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e +Run.Summary.Unstable=\ + \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e +Run.Summary.Aborted=\ + \u043f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e +Run.Summary.NotBuilt=\ + \u043d\u0435\u0438\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e +Run.Summary.BackToNormal=\ + \u043d\u043e\u0440\u043c\u0430\u043b\u043d\u043e +Run.Summary.BrokenForALongTime=\ + \u0441\u0447\u0443\u043f\u0435\u043d\u043e \u043e\u0442 \u043c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435 +Run.Summary.BrokenSinceThisBuild=\ + \u0441\u0447\u0443\u043f\u0435\u043d\u043e \u043e\u0442 \u0442\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Run.Summary.BrokenSince=\ + \u0441\u0447\u0443\u043f\u0435\u043d\u043e \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u2116\u200a{0} +Run.Summary.Unknown=\ + \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e + +Slave.Network.Mounted.File.System.Warning=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0441\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043c\u043e\u043d\u0442\u0438\u0440\u0430\u043d\u0430 \u043f\u043e\ + \u043c\u0440\u0435\u0436\u0430\u0442\u0430, \u043a\u0430\u0442\u043e \u043a\u043e\u0440\u0435\u043d\u043e\u0432\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f? \u041d\u044f\u043c\u0430 \u043d\u0443\u0436\u0434\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u0442\u0430 \u0434\u0430 \u0441\u0435 \u0432\u0438\u0436\u0434\u0430 \u043e\u0442\ + \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0449\u0438\u044f \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440. +Slave.Remote.Director.Mandatory=\ + \u041e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0430\u0442\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u0430. +Slave.Remote.Relative.Path.Warning=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0441\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u0435\u043d \u043f\u044a\u0442 \u043a\u0430\u0442\u043e \u043a\u043e\u0440\u0435\u043d\u043e\u0432\u0430\ + \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f? \u041f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0434\u0430\u043b\u0438 \u0438\u0437\u0431\u0440\u0430\u043d\u0438\u044f\u0442 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0449 \u043f\u0440\u043e\u0446\u0435\u0441 \u043e\u0441\u0438\u0433\u0443\u0440\u044f\u0432\u0430 \u043a\u043e\u043d\u0441\u0438\u0441\u0442\u0435\u043d\u0442\u043d\u043e\u0441\u0442\ + \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f. \u041f\u0440\u0435\u043f\u043e\u0440\u044a\u0447\u0438\u0442\u0435\u043b\u043d\u043e \u0435 \u0434\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u0435\u043d \u043f\u044a\u0442. + +TopLevelItemDescriptor.NotApplicableIn=\ + {0} \u0435\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0430\u0442 \u0432 {1} + +UpdateCenter.DownloadButNotActivated=\ + \u0423\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435. \u0429\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0438 \u0441\u043b\u0435\u0434 \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u043e\u0442\u043e \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435. +UpdateCenter.n_a=\ + \u041b\u0438\u043f\u0441\u0432\u0430 +View.Permissions.Title=\ + \u0418\u0437\u0433\u043b\u0435\u0434 +View.CreatePermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u043b\u0435\u0434\u0438. +View.DeletePermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0449\u0438 \u0438\u0437\u0433\u043b\u0435\u0434\u0438. +View.ConfigurePermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434\u0438\u0442\u0435. +View.ReadPermission.Description=\ + \u0422\u043e\u0432\u0430 \u0434\u0430\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0437\u0430 \u0432\u0438\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434\u0438\u0442\u0435 (\u043f\u043e\u0434\u0440\u0430\u0437\u0431\u0438\u0440\u0430 \u0441\u0435 \u043f\u0440\u0438 \u043e\u0431\u0449\u043e \u043f\u0440\u0430\u0432\u043e \u0437\u0430\ + \u0434\u043e\u0441\u0442\u044a\u043f). +View.MissingMode=\ + \u0412\u0438\u0434\u044a\u0442 \u043d\u0430 \u0438\u0437\u0433\u043b\u0435\u0434\u0430 \u043d\u0435 \u0435 \u0438\u0437\u0431\u0440\u0430\u043d. + +UpdateCenter.Status.CheckingInternet=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u043a\u044a\u043c \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 +UpdateCenter.Status.CheckingJavaNet=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u043a\u044a\u043c \u0446\u0435\u043d\u0442\u044a\u0440\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 +UpdateCenter.Status.Success=\ + \u0423\u0441\u043f\u0435\u0445 +UpdateCenter.Status.UnknownHostException=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 \u201e{0}\u201c.\ + \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435\ + \u0441\u044a\u0440\u0432\u044a\u0440-\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u0437\u0430 HTTP. +UpdateCenter.Status.ConnectionFailed=\ + \u0412\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435\ + \u0441\u044a\u0440\u0432\u044a\u0440-\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u0437\u0430 HTTP. +UpdateCenter.init=\ + \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0446\u0435\u043d\u0442\u044a\u0440\u0430 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 +UpdateCenter.PluginCategory.android=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 Android +UpdateCenter.PluginCategory.builder=\ + \u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +UpdateCenter.PluginCategory.buildwrapper=\ + \u0421\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435, \u043e\u0431\u0432\u0438\u0432\u0430\u0449\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438\u0442\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +UpdateCenter.PluginCategory.cli=\ + \u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434 +UpdateCenter.PluginCategory.cloud=\ + \u0414\u043e\u0441\u0442\u0430\u0432\u0447\u0438\u0446\u0438 \u043d\u0430 \u043e\u0431\u043b\u0430\u0447\u043d\u0438 \u0443\u0441\u043b\u0443\u0433\u0438 +UpdateCenter.PluginCategory.cluster=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043b\u044a\u0441\u0442\u044a\u0440\u0430 \u0438 \u0440\u0430\u0437\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +UpdateCenter.PluginCategory.database=\ + \u0411\u0430\u0437\u0438 \u043e\u0442 \u0434\u0430\u043d\u043d\u0438 +UpdateCenter.PluginCategory.deployment=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 +UpdateCenter.PluginCategory.devops=\ + DevOps +UpdateCenter.PluginCategory.dotnet=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 .NET +UpdateCenter.PluginCategory.external=\ + \u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441\u044a\u0441 \u0441\u0430\u0439\u0442\u043e\u0432\u0435 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 +UpdateCenter.PluginCategory.groovy-related=\ + \u0421\u0432\u044a\u0440\u0437\u0430\u043d\u0438 \u0441 Groovy +UpdateCenter.PluginCategory.ios=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u0437\u0430 iOS +UpdateCenter.PluginCategory.library=\ + \u041f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 (\u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442 \u0441\u0435 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438) +UpdateCenter.PluginCategory.listview-column=\ + \u041a\u043e\u043b\u043e\u043d\u0438 \u0432 \u0441\u043f\u0438\u0441\u044a\u0447\u043d\u0438\u044f \u0438\u0437\u0433\u043b\u0435\u0434 +UpdateCenter.PluginCategory.maven=\ + Maven +UpdateCenter.PluginCategory.misc=\ + \u0420\u0430\u0437\u043d\u0438 +UpdateCenter.PluginCategory.notifier=\ + \u0418\u0437\u0432\u0435\u0441\u0442\u044f\u0432\u0430\u043d\u0435 \u043f\u0440\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +UpdateCenter.PluginCategory.page-decorator=\ + \u0414\u0435\u043a\u043e\u0440\u0430\u0446\u0438\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0438\u0442\u0435 +UpdateCenter.PluginCategory.parameter=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +UpdateCenter.PluginCategory.post-build=\ + \u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043b\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +UpdateCenter.PluginCategory.python=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Python +UpdateCenter.PluginCategory.report=\ + \u041e\u0442\u0447\u0435\u0442\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 +UpdateCenter.PluginCategory.ruby=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Ruby +UpdateCenter.PluginCategory.runcondition=\ + \u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 (\u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0441\u0435 \u043e\u0442 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0430\u0442\u0430 RunConditions) +UpdateCenter.PluginCategory.scala=\ + \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Scala +UpdateCenter.PluginCategory.scm=\ + \u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 +UpdateCenter.PluginCategory.scm-related=\ + \u041e\u0449\u0435 \u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 +UpdateCenter.PluginCategory.security=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442 +UpdateCenter.PluginCategory.test=\ + \u0422\u0435\u0441\u0442\u0432\u0430\u043d\u0435 +UpdateCenter.PluginCategory.trigger=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +UpdateCenter.PluginCategory.ui=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 +UpdateCenter.PluginCategory.upload=\ + \u041a\u0430\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 +UpdateCenter.PluginCategory.user=\ + \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 +UpdateCenter.PluginCategory.view=\ + \u0418\u0437\u0433\u043b\u0435\u0434\u0438 +UpdateCenter.PluginCategory.must-be-labeled=\ + \u0411\u0435\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f +UpdateCenter.PluginCategory.unrecognized=\ + \u0420\u0430\u0437\u043d\u0438 ({0}) + +Permalink.LastBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Permalink.LastStableBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Permalink.LastUnstableBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Permalink.LastUnsuccessfulBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Permalink.LastSuccessfulBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Permalink.LastFailedBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Permalink.LastCompletedBuild=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0437\u0430\u0432\u044a\u0440\u0448\u0435\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 + +ParameterAction.DisplayName=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 +ParametersDefinitionProperty.DisplayName=\ + \u0422\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0435 \u043f\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 +StringParameterDefinition.DisplayName=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440-\u043d\u0438\u0437 +TextParameterDefinition.DisplayName=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440-\u0442\u0435\u043a\u0441\u0442 +FileParameterDefinition.DisplayName=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440-\u0444\u0430\u0439\u043b +BooleanParameterDefinition.DisplayName=\ + \u0411\u0443\u043b\u0435\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440 +ChoiceParameterDefinition.DisplayName=\ + \u0421\u043f\u0438\u0441\u044a\u0447\u0435\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440 +ChoiceParameterDefinition.MissingChoices=\ + \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0435 \u0441\u043f\u0438\u0441\u044a\u043a \u043e\u0442 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442\u0438. +RunParameterDefinition.DisplayName=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440 \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 +PasswordParameterDefinition.DisplayName=\ + \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440-\u043f\u0430\u0440\u043e\u043b\u0430 + +Node.BecauseNodeIsReserved=\ + \u201e{0}\u201c \u0435 \u0437\u0430\u043f\u0430\u0437\u0435\u043d\u0430 \u0437\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f\u0449 \u0435\u0442\u0438\u043a\u0435\u0442. +Node.BecauseNodeIsNotAcceptingTasks=\ + \u201e{0}\u201c \u043d\u0435 \u043f\u0440\u0438\u0435\u043c\u0430 \u0437\u0430\u0434\u0430\u0447\u0438. +Node.LabelMissing=\ + \u201e{0}\u201c \u043d\u044f\u043c\u0430 \u0435\u0442\u0438\u043a\u0435\u0442\u0430 \u201e{1}\u201c. +Node.LackingBuildPermission=\ + \u201e{0}\u201c \u043d\u044f\u043c\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u043e\u0442 \u201e{1}\u201c. +Node.Mode.NORMAL=\ + \u0422\u0430\u0437\u0438 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u0435 \u0441\u0435 \u043f\u043e\u043b\u0437\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439-\u043c\u043d\u043e\u0433\u043e. +Node.Mode.EXCLUSIVE=\ + \u0414\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u0441 \u0435\u0442\u0438\u043a\u0435\u0442\u0438 \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f\u0449\u0438 \u043d\u0430 \u0442\u0430\u0437\u0438 \u043c\u0430\u0448\u0438\u043d\u0430. + +ListView.DisplayName=\ + \u0421\u043f\u0438\u0441\u044a\u0447\u0435\u043d \u0438\u0437\u0433\u043b\u0435\u0434 + +MyView.DisplayName=\ + \u041c\u043e\u044f\u0442 \u0438\u0437\u0433\u043b\u0435\u0434 + +LoadStatistics.Legends.DefinedExecutors=\ + \u0414\u0435\u0444\u0438\u043d\u0438\u0440\u0430\u043d\u0438 \u043c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 +LoadStatistics.Legends.OnlineExecutors=\ + \u041c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f +LoadStatistics.Legends.ConnectingExecutors=\ + \u0421\u0432\u044a\u0440\u0437\u0430\u043d\u0438 \u043c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 +LoadStatistics.Legends.TotalExecutors=\ + \u041e\u0431\u0449\u043e \u043c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 +LoadStatistics.Legends.BusyExecutors=\ + \u0417\u0430\u0435\u0442\u0438 \u043c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 +LoadStatistics.Legends.IdleExecutors=\ + \u0421\u0432\u043e\u0431\u043e\u0434\u043d\u0438 \u043c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 +LoadStatistics.Legends.AvailableExecutors=\ + \u041d\u0430\u043b\u0438\u0447\u043d\u0438 \u043c\u0430\u0448\u0438\u043d\u0438-\u0438\u0437\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u0438 +LoadStatistics.Legends.QueueLength=\ + \u0414\u044a\u043b\u0436\u0438\u043d\u0430 \u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 + +Cause.LegacyCodeCause.ShortDescription=\ + \u0421\u0442\u0430\u0440 \u043a\u043e\u0434 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0442\u0430\u0437\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 \u2014 \u043b\u0438\u043f\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0442\u0430. +Cause.UpstreamCause.ShortDescription=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430 \u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u201e{0}\u201c, \u043e\u0442 \u043a\u043e\u0439\u0442\u043e \u0442\u044f \u0437\u0430\u0432\u0438\u0441\u0438, \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u2116\u200a{1} +Cause.UpstreamCause.CausedBy=\ + \u043f\u044a\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u043d\u043e \u043f\u043e\u0440\u0430\u0434\u0438: +Cause.UserCause.ShortDescription=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430 \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b: \u201e{0}\u201c +Cause.UserIdCause.ShortDescription=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0430 \u043e\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b: \u201e{0}\u201c +Cause.RemoteCause.ShortDescription=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430: \u201e{0}\u201c +Cause.RemoteCause.ShortDescriptionWithNote=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430: \u201e{0}\u201c \u0441\u044a\u0441 \u0441\u043b\u0435\u0434\u043d\u0430\u0442\u0430 \u0431\u0435\u043b\u0435\u0436\u043a\u0430: \u201e{1}\u201c + +ProxyView.NoSuchViewExists=\ + \u0413\u043b\u043e\u0431\u0430\u043b\u043d\u0438\u044f\u0442 \u0438\u0437\u0433\u043b\u0435\u0434 \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 +ProxyView.DisplayName=\ + \u0412\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0433\u043b\u043e\u0431\u0430\u043b\u0435\u043d \u0438\u0437\u0433\u043b\u0435\u0434 + +MyViewsProperty.DisplayName=\ + \u041c\u043e\u0438\u0442\u0435 \u0438\u0437\u0433\u043b\u0435\u0434\u0438 +MyViewsProperty.GlobalAction.DisplayName=\ + \u041c\u043e\u0438\u0442\u0435 \u0438\u0437\u0433\u043b\u0435\u0434\u0438 +MyViewsProperty.ViewExistsCheck.NotExist=\ + \u0418\u0437\u0433\u043b\u0435\u0434 \u0441 \u0438\u043c\u0435 \u201e{0}\u201c \u043d\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 +MyViewsProperty.ViewExistsCheck.AlreadyExists=\ + \u0418\u0437\u0433\u043b\u0435\u0434 \u0441 \u0438\u043c\u0435 \u201e{0}\u201c \u0432\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 + +CLI.restart.shortDescription=\ + \u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins +CLI.safe-restart.shortDescription=\ + \u0411\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 Jenkins +CLI.keep-build.shortDescription=\ + \u041e\u0442\u0431\u0435\u043b\u044f\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0434\u0430 \u0441\u0435 \u0437\u0430\u043f\u0430\u0437\u0438 \u0437\u0430\u0432\u0438\u043d\u0430\u0433\u0438. + +BuildAuthorizationToken.InvalidTokenProvided=\ + \u0417\u0430\u0434\u0430\u0434\u0435\u043d \u0435 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0436\u0435\u0442\u043e\u043d \u0437\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442. + +Jenkins.CheckDisplayName.NameNotUniqueWarning=\ + \u0418\u043c\u0435\u0442\u043e \u201e{0}\u201c \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0438 \u0437\u0430 \u0437\u0430\u0434\u0430\u0447\u0430, \u043a\u043e\u0435\u0442\u043e \u043c\u043e\u0436\u0435 \u0434\u0430 \u0434\u043e\u0432\u0435\u0434\u0435 \u0434\u043e \u043e\u0431\u044a\u0440\u043a\u0432\u0430\u043d\u0435 \u043f\u0440\u0438\ + \u0442\u044a\u0440\u0441\u0435\u043d\u0435. +Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=\ + \u0418\u043c\u0435\u0442\u043e \u201e{0}\u201c \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u0437\u0430 \u0434\u0440\u0443\u0433\u0430 \u0437\u0430\u0434\u0430\u0447\u0430, \u043a\u043e\u0435\u0442\u043e \u043c\u043e\u0436\u0435 \u0434\u0430 \u0434\u043e\u0432\u0435\u0434\u0435 \u0434\u043e \u0437\u0430\u0431\u0430\u0432\u044f\u043d\u0435 \u0438\ + \u043e\u0431\u044a\u0440\u043a\u0432\u0430\u043d\u0435 \u043f\u0440\u0438 \u0442\u044a\u0440\u0441\u0435\u043d\u0435. + +Jenkins.NotAllowedName=\ + \u041d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0438\u043c\u0435\u0442\u043e \u201e{0}\u201c +Jenkins.IsRestarting=\ + Jenkins \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 + +User.IllegalUsername=\ + \u041d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u201e{0}\u201c \u0437\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e \u0438\u043c\u0435 \u0437\u0430\u0440\u0430\u0434\u0438 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430. +User.IllegalFullname=\ + \u041d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u201e{0}\u201c \u0437\u0430 \u043f\u044a\u043b\u043d\u043e \u0438\u043c\u0435 \u0437\u0430\u0440\u0430\u0434\u0438 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430. +# No such agent "{0}" exists. Did you mean "{1}"? +Computer.NoSuchSlaveExists=\ + \u041d\u044f\u043c\u0430 \u0430\u0433\u0435\u043d\u0442 \u201e{0}\u201c. \u201e{1}\u201c \u043b\u0438 \u0438\u043c\u0430\u0445\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434? +# There\u2019s no agent/cloud that matches this assignment. Did you mean \u2018{1}\u2019 instead of \u2018{0}\u2019? +AbstractProject.AssignedLabelString_NoMatch_DidYouMean=\ + \u041d\u044f\u043c\u0430 \u0442\u0430\u043a\u044a\u0432 \u0430\u0433\u0435\u043d\u0442/\u043e\u0431\u043b\u0430\u043a. \u201e{1}\u201c \u043b\u0438 \u0438\u043c\u0430\u0445\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434 \u0432\u043c\u0435\u0441\u0442\u043e \u201e{0}\u201c? +# Agent called \u2018{0}\u2019 already exists +ComputerSet.SlaveAlreadyExists=\ + \u0412\u0435\u0447\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430 \u0430\u0433\u0435\u043d\u0442 \u0441 \u0438\u043c\u0435 \u201e{0}\u201c +# Agent node offline or not a remote channel (such as master node). +Computer.BadChannel=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0430 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f \u0438\u043b\u0438 \u043b\u0438\u043f\u0441\u0432\u0430 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d \u043a\u0430\u043d\u0430\u043b (\u043a\u0430\u043a\u0442\u043e \u043f\u0440\u0438\ + \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0449 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440). +# This permission allows users to disconnect agents or mark agents as temporarily offline. +Computer.DisconnectPermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u043f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u0442\u0435 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u043a\u044a\u043c \u0430\u0433\u0435\u043d\u0442\u0438 \u0438\u043b\u0438 \u0434\u0430 \u0433\u0438\ + \u043e\u0431\u044f\u0432\u044f\u0432\u0430\u0442\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f. +# Unable to launch the agent for {0}{1} +Slave.UnableToLaunch=\ + \u0410\u0433\u0435\u043d\u0442\u044a\u0442 \u0437\u0430 {0}{1} \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 +# This permission allows users to run jobs as them on agents. +Computer.BuildPermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0438\u0442\u0435\ + \u043e\u0442 \u0441\u0432\u043e\u0435 \u0438\u043c\u0435. +# Specify which agent to copy +ComputerSet.SpecifySlaveToCopy=\ + \u0423\u043a\u0430\u0436\u0435\u0442\u0435 \u0430\u0433\u0435\u043d\u0442\u0430 \u0437\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 +# Invalid agent configuration for {0}. No remote directory given +Slave.InvalidConfig.NoRemoteDir=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u0430\u0433\u0435\u043d\u0442 \u0437\u0430 {0}. \u041d\u0435 \u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f. +# This is a Windows agent +Slave.WindowsSlave=\ + \u0422\u043e\u0432\u0430 \u0435 \u0430\u0433\u0435\u043d\u0442 \u0437\u0430 Windows +# Agent Launchers and Controllers +UpdateCenter.PluginCategory.slaves=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0438 +MultiStageTimeSeries.EMPTY_STRING=\ + +# Invalid agent configuration for {0}. Invalid # of executors. +Slave.InvalidConfig.Executors=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0430 \u0437\u0430 {0}. \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0438. +# This permission allows users to create agents. +Computer.CreatePermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u0441\u0435 \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u0442 \u0430\u0433\u0435\u043d\u0442\u0438. +# This permission allows users to configure agents. +Computer.ConfigurePermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0432\u0430\u0442 \u0430\u0433\u0435\u043d\u0442\u0438. +# Agent {0} +Computer.Caption=\ + \u0410\u0433\u0435\u043d\u0442 \u201e{0}\u201c +# \ +# There's no agent/cloud that matches this assignment +AbstractProject.AssignedLabelString.NoMatch=\ + \u041d\u044f\u043c\u0430 \u0430\u0433\u0435\u043d\u0442, \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f\u0449 \u043d\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0435\u0442\u043e +# Invalid agent configuration. Name is empty +Slave.InvalidConfig.NoName=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442 \u2014 \u0438\u043c\u0435\u0442\u043e \u0435 \u043f\u0440\u0430\u0437\u043d\u043e. +# No such agent "{0}" exists. +Computer.NoSuchSlaveExistsWithoutAdvice=\ + \u041d\u044f\u043c\u0430 \u0430\u0433\u0435\u043d\u0442 \u201e{0}\u201c +# This permission allows users to connect agents or mark agents as online. +Computer.ConnectPermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u0441\u0432\u044a\u0440\u0437\u0432\u0430\u0442\u0435 \u043d\u043e\u0432\u0438 \u0430\u0433\u0435\u043d\u0442\u0438 \u0438\u043b\u0438 \u0434\u0430 \u043e\u0431\u044f\u0432\u044f\u0432\u0430\u0442\u0435, \u0447\u0435 \u0441\u0430 \u043d\u0430\ + \u043b\u0438\u043d\u0438\u044f. +# {0} agent was terminated +Slave.Terminated=\ + \u0410\u0433\u0435\u043d\u0442\u044a\u0442 \u201e{0}\u201c \u0435 \u0438\u0437\u0442\u0440\u0438\u0442 +# No such agent: {0} +ComputerSet.NoSuchSlave=\ + \u041d\u044f\u043c\u0430 \u0430\u0433\u0435\u043d\u0442 \u201e{0}\u201c +# This permission allows users to read agent configuration. +Computer.ExtendedReadPermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u0432\u0438\u0434\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0430. +HealthReport.EmptyString=\ + +# May not copy {0} as it contains secrets and {1} has {2}/{3} but not /{4} +ItemGroupMixIn.may_not_copy_as_it_contains_secrets_and_=\ + \u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u043a\u043e\u043f\u0438\u0440\u0430\u0442\u0435 \u201e{0}\u201c, \u0437\u0430\u0449\u043e\u0442\u043e \u043d\u0430 \u043d\u0435\u0433\u043e \u0438\u043c\u0430 \u043f\u0430\u0440\u043e\u043b\u0438, \u0430 \u201e{1}\u201c \u0438\u043c\u0430 {2}/{3}, \u043d\u043e\ + \u043d\u0435 \u0438 /{4} +# This permission allows users to delete existing agents. +Computer.DeletePermission.Description=\ + \u0422\u043e\u0432\u0430 \u043f\u0440\u0430\u0432\u043e \u0432\u0438 \u0434\u0430\u0432\u0430 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u0442\u0435 \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\u0449\u0438 \u0430\u0433\u0435\u043d\u0442\u0438. +# Agent +Computer.Permissions.Title=\ + \u0410\u0433\u0435\u043d\u0442 +# {0} Launching agent +Slave.Launching=\ + TODO +# This is a Unix agent +Slave.UnixSlave=\ + \u0422\u043e\u0432\u0430 \u0435 \u0430\u0433\u0435\u043d\u0442 \u0437\u0430 Unix +# SCM polling vetoed by {0} +AbstractProject.PollingVetoed=\ + \u0417\u0430\u044f\u0432\u043a\u0438\u0442\u0435 \u043a\u044a\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0441\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u043f\u0440\u0435\u043d\u0438 \u043e\u0442 {0}. +# No Parameters are specified for this parameterized build +Hudson.NoParamsSpecified=\ + \u041b\u0438\u043f\u0441\u0432\u0430\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 \u0437\u0430 \u0442\u043e\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u0438\u0440\u0430\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435. diff --git a/core/src/main/resources/hudson/model/Messages_ca.properties b/core/src/main/resources/hudson/model/Messages_ca.properties index 0f88dbec7e946d33d0d0a7509a1a95738a14d19c..0a5f3a512e4d9f48efcdf062336f526381e54f0e 100644 --- a/core/src/main/resources/hudson/model/Messages_ca.properties +++ b/core/src/main/resources/hudson/model/Messages_ca.properties @@ -1,2 +1,3 @@ -AbstractProject.BuildNow=Construir Ara ManageJenkinsAction.DisplayName=Configuraci\u00F3 de Jenkins + +FreeStyleProject.Description=Aquesta \u00E9s la funcionalitat principal de Jenkins. Jenkins far\u00E0 un build del vostre projecte combinant qualsevol SCM amb qualsevol sistema de build. Aix\u00F2 tamb\u00E9 es pot usar per tasques que no siguin un build de software diff --git a/core/src/main/resources/hudson/model/Messages_cs.properties b/core/src/main/resources/hudson/model/Messages_cs.properties index c294dbd242625f69c86a66d49d8604941448d24b..11de8e6c7a69c45e201f29b093e4dc9ac42a6b3f 100644 --- a/core/src/main/resources/hudson/model/Messages_cs.properties +++ b/core/src/main/resources/hudson/model/Messages_cs.properties @@ -1 +1,3 @@ ManageJenkinsAction.DisplayName=Administrace + +FreeStyleProject.Description=Toto je hlavn\u00ED funkce Jenkins. Jenkins sestav\u00ED v\u00E1\u0161 projekt, spoj\u00ED jak\u00FDkoli syst\u00E9m pro spr\u00E1vu verz\u00ED se syst\u00E9mem pro sestaven\u00ED. Nemus\u00ED b\u00FDt pou\u017Eit jen pro sestaven\u00ED softwaru. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_da.properties b/core/src/main/resources/hudson/model/Messages_da.properties index f17335347aff67bf5bd2371dd056fa0a712ea3f1..6cd683c17aece5abe194eb83e69820d33e56fd3d 100644 --- a/core/src/main/resources/hudson/model/Messages_da.properties +++ b/core/src/main/resources/hudson/model/Messages_da.properties @@ -38,7 +38,6 @@ Denne tilladelse g\u00f8r det muligt for brugeren at opdatere beskrivelsen og an for eksempel for at skrive en besked om hvorfor et byg fejler. StringParameterDefinition.DisplayName=Strengparameter Node.Mode.NORMAL=Benyt denne slave s\u00e5 meget som overhovedet muligt -Computer.Caption=Slave {0} ProxyView.NoSuchViewExists=Global visning {0} findes ikke UpdateCenter.PluginCategory.external=Eksternt site/ v\u00e6rkt\u00f8jsintegration BallColor.Pending=I k\u00f8 @@ -55,23 +54,21 @@ UpdateCenter.Status.Success=Succes ParameterAction.DisplayName=Parametre UpdateCenter.init=Initialiserer opdateringscenteret ComputerSet.DisplayName=noder -CLI.connect-node.shortDescription=Gentilslut en node Run.DeletePermission.Description=Denne tilladelse g\u00f8r det muligt for brugerne at slette specifikke byg i byggehistorikken. Run.Summary.BrokenForALongTime=fejlet l\u00e6nge CLI.safe-restart.shortDescription=Sikker genstart af Jenkins -CLI.quiet-down.shortDescription=Forbereder nedlukning, starter ingen nye byg. + FreeStyleProject.DisplayName=Byg et free-style projekt +FreeStyleProject.Description=Dette er den centrale feature i Jenkins. Jenkins vil bygge dit projekt i enhver kombination af kildekodestyring (SCM) med ethvert byggesystem og dette kan bruges til meget andet end at bygge software. + ProxyView.DisplayName=Inkluder en global visning -ComputerSet.SpecifySlaveToCopy=Angiv hvilken slave der skal kopieres Run.Permissions.Title=K\u00f8r Hudson.DisplayName=Jenkins Hudson.NotANonNegativeNumber=V\u00e6rdien m\u00e5 ikke v\u00e6re negativ -Slave.Launching={0} Starter slave agent BallColor.InProgress=I gang AbstractProject.NoBuilds=Ingen eksisterende byg. Skedulerer et nyt. Run.BuildAborted=Byg afbrudt BallColor.Aborted=Afbrudt -Slave.InvalidConfig.NoRemoteDir=Ugyldig slavekonfiguration for {0}. Intet fjerndirektorie angivet. ListView.DisplayName=Listevisning UpdateCenter.PluginCategory.page-decorator=Sidedekorat\u00f8rer Cause.LegacyCodeCause.ShortDescription=Legacy kode startede dette job. Ingen startbegrundelse tilg\u00e6ngelig. @@ -80,16 +77,13 @@ UpdateCenter.PluginCategory.post-build=Andre postbyg handlinger Cause.UpstreamCause.ShortDescription=Startet af upstreamprojektet "{0}" byg nummer {1} UpdateCenter.PluginCategory.cli=Kommandolinieinterface UpdateCenter.PluginCategory.builder=Byggev\u00e6rkt\u00f8jer -Slave.UnixSlave=Dette er en Unix slave FileParameterDefinition.DisplayName=Filparametre -CLI.delete-job.shortDescription=Sletter et job Run.Summary.Unstable=Ustabil CLI.reload-configuration.shortDescription=Genindl\u00e6s alle data fra filsystemet. \ Nyttigt hvis du har modificeret konfigurationsfiler direkte, udenom Jenkins. ComputerSet.NoSuchSlave=Ingen slave ved navn: {0} ComputerSet.SlaveAlreadyExists=En slave ved navn ''{0}'' eksisterer allerede Executor.NotAvailable=N/A -Slave.Terminated={0} slave agenten blev tilintetgjort Item.Permissions.Title=Job AbstractProject.NoWorkspace=Intet arbejdsomr\u00e5de tilg\u00e6ngeligt, kan ikke checke for opdateringer. CLI.disable-job.shortDescription=Sl\u00e5r et job fra @@ -98,20 +92,17 @@ Slave.Remote.Director.Mandatory=Fjerndirektorie er obligatorisk BallColor.Disabled=Sl\u00e5et fra Run.InProgressDuration={0} og t\u00e6ller UpdateCenter.Status.UnknownHostException=Ukendt v\u00e6rt undtagelse -Hudson.NotUsesUTF8ToDecodeURL=\ -Din container bruger ikke UTF-8 til at afkode URLer. Hvis du bruger ikke-ASCII tegn i jobnavne etc, \ +Hudson.NotUsesUTF8ToDecodeURL=\ +Din container bruger ikke UTF-8 til at afkode URLer. Hvis du bruger ikke-ASCII tegn i jobnavne etc, \ vil dette skabe problemer. UpdateCenter.Status.CheckingInternet=Checker internet forbindelse -View.DeletePermission.Description=\ +View.DeletePermission.Description=\ Denne rettighed tillader brugerne at slette eksisterende visninger. UpdateCenter.Status.CheckingJavaNet=Checker jenkins-ci.org forbindelse UpdateCenter.PluginCategory.user=Authentificering og brugerh\u00e5ndtering MyView.DisplayName=Min visning Hudson.USER_CONTENT_README=Filer i dette direktorie vil blive serveret under http://server/hudson/userContent/ UpdateCenter.PluginCategory.scm-related=Kildekodestyring (SCM) relateret -CLI.cancel-quiet-down.shortDescription=Sl\u00e5 effekten af "quite-down" kommandoen fra. -CLI.clear-queue.shortDescription=Ryd byggek\u00f8en -Slave.InvalidConfig.Executors=Ugyldig slavekonfiguration for {0}. Ugyldigt # afviklere. Api.NoXPathMatch=XPath {0} matcher ikke Run.MarkedExplicitly=Eksplicit markeret til at blive gemt Hudson.Permissions.Title=Overordnet @@ -119,7 +110,6 @@ AbstractProject.UpstreamBuildInProgress=Upstreamprojektet {0} bygger allerede. Permalink.LastBuild=Seneste Byg MyViewsProperty.ViewExistsCheck.NotExist=En visning ved navn {0} findes ikke AbstractItem.NoSuchJobExists=Intet job ved navn ''{0}'' eksisterer. M\u00e5ske mener du ''{1}''? -Slave.InvalidConfig.NoName=Ugyldig slavekonfiguration. Navnet er tomt. Run.Summary.BackToNormal=tilbage p\u00e5 sporet BooleanParameterDefinition.DisplayName=Boolesk V\u00e6rdi Permalink.LastSuccessfulBuild=Seneste succesfulde byg @@ -128,7 +118,7 @@ UpdateCenter.PluginCategory.buildwrapper=Byggeomslag Hudson.ReadPermission.Description=\ L\u00e6serettigheden er n\u00f8dvendig for at se n\u00e6sten alle sider i Jenkins. \ Denne rettighed kan bruges n\u00e5r du ikke vil have uauthentificerede brugere til at \ -se Jenkins sider — tilbagekald denne rettighed fra den anonyme bruger, tilf\u00f8j \ +se Jenkins sider — tilbagekald denne rettighed fra den anonyme bruger, tilf\u00f8j \ derefter en "authentificeret" pseudo-bruger og giv denne l\u00e6serettigheder. Hudson.NodeBeingRemoved=Node bliver fjernet Hudson.ViewAlreadyExists=En visning ved navn "{0}" findes allerede @@ -137,14 +127,12 @@ UpdateCenter.PluginCategory.notifier=Bygge Notifikatorer Label.ProvisionedFrom=Provisioneret fra {0} Run.Summary.Aborted=afbrudt UpdateCenter.PluginCategory.report=Bygge Rapporter -Computer.ConfigurePermission.Description=Denne rettighed tillader brugere at konfigurere slaver. View.Permissions.Title=Visninger Permalink.LastFailedBuild=Seneste fejlede byg UpdateCenter.PluginCategory.scm=Kildekodestyring (SCM) View.ConfigurePermission.Description=Denne rettighed tillader brugere at \u00e6ndre konfigurationen af visninger. AbstractProject.NewBuildForWorkspace=Skedulerer et nyt byg for at f\u00e5 et arbejdsomr\u00e5de Node.LabelMissing={0} har ikke etiket {1} -CLI.delete-node.shortDescription=Sletter en node Queue.BlockedBy=Blokeret af {0} Node.BecauseNodeIsReserved={0} er reserveret til jobs bundet(tied) til den Job.minutes=min @@ -154,36 +142,30 @@ UpdateCenter.PluginCategory.cluster=Klyngestyring og distribuerede byg AbstractBuild.KeptBecause=beholdt pga. {0} Hudson.NotADirectory={0} er ikke et direktorie Cause.RemoteCause.ShortDescription=Startet af fjernv\u00e6rt {0} -Slave.WindowsSlave=Dette er en Windows slave -Run.ArtifactsPermission.Description=\ -Denne rettighed g\u00f8r det muligt at hente byggeartifakter. \ +Run.ArtifactsPermission.Description=\ +Denne rettighed g\u00f8r det muligt at hente byggeartifakter. \ Hvis du ikke vil have at en bruger skal kunne tilg\u00e5 byggeartifakter kan \ du fratage vedkommende denne rettighed. -Computer.BadChannel=Slave node offline eller ikke en fjernkanal (f.eks. en masternode). AbstractProject.Aborted=Afbrudt Queue.init=Genopretter byggek\u00f8en Hudson.NodeDescription=master Jenkins noden -AbstractProject.BuildInProgress=Byg #{0} er allerede i gang {1} Job.NoRecentBuildFailed=Ingen byg har fejlet for nyligt. Permalink.LastUnsuccessfulBuild=Seneste fejlede byg RunParameterDefinition.DisplayName=K\u00f8rselsparameter Hudson.JobAlreadyExists=Et job eksisterer allerede med navnet ''{0}'' -CLI.offline-node.shortDescription=Hold midlertidigt op med at bygge p\u00e5 en node, indtil n\u00e6ste "online-node" kommando. MyViewsProperty.DisplayName=Mine visninger UpdateCenter.PluginCategory.must-be-labeled=Ukatagoriserede AbstractProject.Disabled=Byg sl\u00e5et fra MyViewsProperty.ViewExistsCheck.AlreadyExists=En visning ved navn {0} eksisterer allerede -Hudson.AdministerPermission.Description=\ -Denne rettighed g\u00f8r det muligt at lave konfigurations\u00e6ndringer p\u00e5 tv\u00e6rs af hele systemet, \ -s\u00e5vel som at k\u00f8re yderst f\u00f8lsomme operationer der effektivt svarer til fuld lokal system adgang \ +Hudson.AdministerPermission.Description=\ +Denne rettighed g\u00f8r det muligt at lave konfigurations\u00e6ndringer p\u00e5 tv\u00e6rs af hele systemet, \ +s\u00e5vel som at k\u00f8re yderst f\u00f8lsomme operationer der effektivt svarer til fuld lokal system adgang \ (indenfor rettighedsrammerne af det underliggende operativsystem.) Hudson.NotJDKDir={0} ligner ikke et JDK direktorie AbstractProject.WorkspaceOffline=Arbejdsomr\u00e5det er offline. Queue.HudsonIsAboutToShutDown=Jenkins skal til at lukke ned -UpdateCenter.PluginCategory.slaves=Slavestartere og kontroll\u00f8rer Api.MultipleMatch=XPath "{0}" matcher {1} noder. \ Lav en XPath der kun matcher en, eller brug en "omslags" foresp\u00f8rgselsparameter til at samle dem alle under et rodelement. -Slave.UnableToLaunch=Kan ikke starte en slave agent for {0}{1} Queue.Unknown=??? BallColor.Unstable=Ustabil Job.AllRecentBuildFailed=Alle de seneste byg er fejlet. @@ -202,7 +184,6 @@ LoadStatistics.Legends.QueueLength=K\u00f8 l\u00e6ngde Hudson.ViewName=Alle Job.BuildStability=Bygge stabilitet: {0} Job.Pronoun=Projekt -CLI.disconnect-node.shortDescription=Afbryder forbindelsen til en node CLI.restart.shortDescription=Genstart Jenkins Permalink.LastStableBuild=Sidste stabile byg Hudson.NoJavaInPath=Java er ikke i din sti. M\u00e5ske mangler du at konfigurere JDK? @@ -216,17 +197,13 @@ Queue.WaitingForNextAvailableExecutorOn=Venter p\u00e5 n\u00e6ste ledige afvikle Hudson.NotANegativeNumber=Ikke en negativ v\u00e6rdi UpdateCenter.PluginCategory.misc=Diverse Queue.InProgress=Et byg er allerede i gang -Computer.DeletePermission.Description=Denne rettighed tillader brugere at slette eksisterende slaver. UpdateCenter.Status.ConnectionFailed= UpdateCenter.PluginCategory.maven=Maven -CLI.online-node.shortDescription=Genoptag brugen af en byggenode, for at annullere en tidligere udstedt "offline-node" kommando. -Computer.Permissions.Title=Slave BallColor.Success=Succes UpdateCenter.PluginCategory.upload=Artifaktsendere Permalink.LastUnstableBuild=Seneste ustabile byg CLI.enable-job.shortDescription=Sl\u00e5r et job til Run.Summary.Unknown=? -ParametersDefinitionProperty.DisplayName=Parametre AbstractProject.BuildPermission.Description=\ Denne rettighed giver mulighed for at starte et nyt byg. Job.NOfMFailed={0} af de seneste {1} byg fejlede. @@ -235,10 +212,9 @@ Note: direktoriet beh\u00f8ver ikke v\u00e6re synlig for master noden. Label.GroupOf=Gruppe af {0} Queue.InQuietPeriod=I en stilleperiode. udl\u00f8ber om {0} Queue.AllNodesOffline=Alle noder med etiket ''{0}'' er offline -AbstractProject.ETA=(ETA:{0}) Hudson.NoSuchDirectory=Intet direktorie ved navn: {0} LoadStatistics.Legends.BusyExecutors=Optagede afviklere HealthReport.EmptyString= MultiStageTimeSeries.EMPTY_STRING= -AbstractProject.BuildNow=Byg nu ManageJenkinsAction.DisplayName=Bestyr Jenkins +ParametersDefinitionProperty.DisplayName=Dette byg er parameteriseret diff --git a/core/src/main/resources/hudson/model/Messages_de.properties b/core/src/main/resources/hudson/model/Messages_de.properties index 90cc3429225b2c4edba4f905627469d7b57cb67e..24789d48a8022ba20d5fb33c52496c9d358a11f6 100644 --- a/core/src/main/resources/hudson/model/Messages_de.properties +++ b/core/src/main/resources/hudson/model/Messages_de.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# Copyright (c) 2004-2015, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -AbstractBuild.BuildingRemotely=Baue auf Slave {0} AbstractBuild.BuildingOnMaster=Baue auf Master AbstractBuild_Building=Baue AbstractBuild.BuildingInWorkspace=\ in Arbeitsbereich {0} @@ -31,13 +30,9 @@ AbstractItem.Pronoun=Element AbstractProject.NewBuildForWorkspace=Plane einen neuen Build, um einen Arbeitsbereich anzulegen. AbstractProject.Pronoun=Projekt AbstractProject.Aborted=Abgebrochen -AbstractProject.BuildInProgress=Build #{0} ist bereits in Arbeit{1} -AbstractProject.BuildNow=Jetzt bauen -AbstractProject.build_with_parameters=Bauen mit Parametern AbstractProject.UpstreamBuildInProgress=Vorgelagertes Projekt {0} ist bereits in Arbeit. AbstractProject.DownstreamBuildInProgress=Nachgelagertes Projekt {0} ist bereits in Arbeit. AbstractProject.Disabled=Build deaktiviert -AbstractProject.ETA=\ (ETA:{0}) AbstractProject.NoSCM=Kein SCM AbstractProject.NoBuilds=Es existiert kein Build. Starte neuen Build. AbstractProject.NoWorkspace=Kein Arbeitsbereich verf\u00fcgbar, daher kann nicht auf Aktualisierungen \u00fcberpr\u00fcft werden. @@ -79,38 +74,22 @@ BallColor.Unstable=Instabil CLI.restart.shortDescription=Jenkins neu starten. CLI.keep-build.shortDescription=Build f\u00fcr immer aufbewahren. -CLI.quiet-down.shortDescription=Jenkins' Aktivit\u00e4t reduzieren, z.B. zur Vorbereitung eines Neustarts. Es werden keine neuen Builds mehr gestartet. -CLI.cancel-quiet-down.shortDescription=Wirkung des Befehls "quiet-down" wieder aufheben. CLI.reload-configuration.shortDescription=Alle Daten im Speicher verwerfen und Konfiguration neu von Festplatte laden. Dies ist n\u00fctzlich, wenn Sie \u00c4nderungen direkt im Dateisystem vorgenommen haben. CLI.clear-queue.shortDescription=Build-Warteschlange l\u00f6schen. -CLI.delete-job.shortDescription=Job l\u00f6schen. CLI.disable-job.shortDescription=Job deaktivieren. CLI.enable-job.shortDescription=Job aktivieren. -CLI.connect-node.shortDescription=Erneut mit Knoten verbinden. CLI.disconnect-node.shortDescription=Knoten trennen. -CLI.delete-node.shortDescription=Knoten l\u00f6schen. -CLI.offline-node.shortDescription=Knoten wird bis zum n\u00e4chsten "online-node"-Kommando f\u00fcr keine neuen Builds verwendet. -CLI.online-node.shortDescription=Knoten wird wieder f\u00fcr neue Builds verwendet. Hebt ein vorausgegangenes "offline-node"-Kommando auf. CLI.safe-restart.shortDescription=Startet Jenkins neu. -MyViewsProperty.GlobalAction.DisplayName=Meine Ansichten Queue.init=Build-Warteschlange neu initialisieren -Computer.Caption=Slave {0} -Computer.Permissions.Title=Slave -Computer.ConfigurePermission.Description=Dieses Recht erlaubt, Slaves zu konfigurieren. -Computer.DeletePermission.Description=Dieses Recht erlaubt, bestehende Slaves zu l\u00f6schen. -Computer.CreatePermission.Description=Dieses Recht erlaubt, neue Slaves zu erstellen. -Computer.ConnectPermission.Description=Dieses Recht erlaubt, Slaves zu verbinden oder als verf\u00fcgbar zu markieren. -Computer.DisconnectPermission.Description=Dieses Recht erlaubt, bestehende Slaves zu entfernen oder als vor\u00fcbergehend nicht verf\u00fcgbar zu markieren. -ComputerSet.NoSuchSlave=Slave ''{0}'' existiert nicht. -ComputerSet.SlaveAlreadyExists=Ein Slave mit Namen ''{0}'' existiert bereits. -ComputerSet.SpecifySlaveToCopy=Geben Sie an, welcher Slave kopiert werden soll +ComputerSet.DisplayName=Knoten Executor.NotAvailable=nicht verf\u00fcgbar FreeStyleProject.DisplayName="Free Style"-Softwareprojekt bauen +FreeStyleProject.Description=Dieses Profil ist das meistgenutzte in Jenkins. Jenkins baut Ihr Projekt, wobei Sie universell jedes SCM System mit jedem Build-Verfahren kombinieren k\u00F6nnen. Dieses Profil ist nicht nur auf das Bauen von Software beschr\u00E4nkt, sondern kann dar\u00FCber hinaus auch f\u00FCr weitere Anwendungsgebiete verwendet werden. HealthReport.EmptyString= @@ -216,22 +195,14 @@ Run.Summary.BrokenSinceThisBuild=Defekt seit diesem Build. Run.Summary.BrokenSince=Defekt seit Build {0} Run.Summary.Unknown=Ergebnis unbekannt -Slave.InvalidConfig.Executors=Ung\u00fcltige Slave-Einstellungen f\u00fcr {0}. Ung\u00fcltige Anzahl von Build-Prozessoren. -Slave.InvalidConfig.NoName=Ung\u00fcltige Slave-Einstellungen. Name ist leer. -Slave.InvalidConfig.NoRemoteDir=Ung\u00fcltige Slave-Einstellungen f\u00fcr {0}. Kein entferntes Verzeichnis angegeben. -Slave.Launching={0} Starte Slave-Agent Slave.Network.Mounted.File.System.Warning=\ - Sind Sie sicher, da\u00df Sie ein Netzlaufwerk als Stammverzeichnis verwenden m\u00f6chen? \ - Hinweis: Dieses Verzeichnis mu\u00df nicht vom Master-Knoten aus sichtbar sein. + Sind Sie sicher, dass Sie ein Netzlaufwerk als Stammverzeichnis verwenden m\u00f6chen? \ + Hinweis: Dieses Verzeichnis muss nicht vom Master-Knoten aus sichtbar sein. Slave.Remote.Director.Mandatory=Ein Stammverzeichnis muss angegeben werden. -Slave.Terminated={0} Slave-Agent wurde beendet -Slave.UnableToLaunch=Kann keinen Slave-Agenten starten f\u00fcr {0}{1} -Slave.UnixSlave=Dies ist ein UNIX-Slave -Slave.WindowsSlave=Dies ist ein Windows-Slave UpdateCenter.DownloadButNotActivated=Erfolgreich heruntergeladen. Wird beim n\u00e4chsten Neustart aktiviert. UpdateCenter.n_a=(nicht verf\u00fcgbar) -View.MissingMode=Ein Ansichtstyp mu\u00df angegeben werden. +View.MissingMode=Ein Ansichtstyp muss angegeben werden. View.Permissions.Title=Ansichten View.CreatePermission.Description=\ Dieses Recht erlaubt, neue Ansichten anzulegen. @@ -265,7 +236,6 @@ UpdateCenter.PluginCategory.post-build=Post-Build-Aktionen UpdateCenter.PluginCategory.report=Build-Berichte UpdateCenter.PluginCategory.scm=Versionsverwaltung UpdateCenter.PluginCategory.scm-related=Versionsverwaltung (weiteres Umfeld) -UpdateCenter.PluginCategory.slaves=Slave-Knoten Management UpdateCenter.PluginCategory.trigger=Build-Ausl\u00f6ser UpdateCenter.PluginCategory.ui=Benutzeroberfl\u00e4che UpdateCenter.PluginCategory.upload=Distribution von Artefakten @@ -281,7 +251,6 @@ Permalink.LastUnstableBuild=Letzter instabiler Build Permalink.LastUnsuccessfulBuild=Letzter erfolgloser Build ParameterAction.DisplayName=Parameter -ParametersDefinitionProperty.DisplayName=Parameter StringParameterDefinition.DisplayName=Text-Parameter TextParameterDefinition.DisplayName=Textbox-Parameter FileParameterDefinition.DisplayName=Datei-Parameter @@ -309,3 +278,4 @@ Cause.RemoteCause.ShortDescription=Gestartet durch entfernten Rechner {0} Cause.RemoteCause.ShortDescriptionWithNote=Gestartet durch entfernten Rechner {0} mit Hinweis: {1} ManageJenkinsAction.DisplayName=Jenkins verwalten +ParametersDefinitionProperty.DisplayName=Dieser Build ist parametrisiert. diff --git a/core/src/main/resources/hudson/model/Messages_en_GB.properties b/core/src/main/resources/hudson/model/Messages_en_GB.properties new file mode 100644 index 0000000000000000000000000000000000000000..b9d3954d76a701cd1a29dcb7b4d24e9ac27f2b8c --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_en_GB.properties @@ -0,0 +1 @@ +ParametersDefinitionProperty.DisplayName=This project is parameterised diff --git a/core/src/main/resources/hudson/model/Messages_es.properties b/core/src/main/resources/hudson/model/Messages_es.properties index 02b9081a433a15de7a8d1162ecb95a433e64ada6..d1f693619dd5c4e2f27a45e77361d81d06aea643 100644 --- a/core/src/main/resources/hudson/model/Messages_es.properties +++ b/core/src/main/resources/hudson/model/Messages_es.properties @@ -28,10 +28,8 @@ AbstractItem.NoSuchJobExists=La tarea ''{0}'' no existe. \u00bfQuiz\u00e1s quier AbstractProject.NewBuildForWorkspace=Lanzando una nueva ejecuci\u00f3n para crear el espacio de trabajo. AbstractProject.Pronoun=Proyecto AbstractProject.Aborted=Cancelado -AbstractProject.BuildInProgress=La ejecuci\u00f3n #{0} ya est\u00e1 en progreso {1} AbstractProject.UpstreamBuildInProgress=El proyecto padre {0} ya se est\u00e1 ejecutando. AbstractProject.Disabled=Ejecuci\u00f3n desactivada -AbstractProject.ETA= (ETA:{0}) AbstractProject.NoSCM=Sin SCM AbstractProject.NoWorkspace=No hay espacio de trabajo, por tanto no se puede comprobar las actualizaciones. AbstractProject.PollingABorted=Peticiones SCM abortadas @@ -58,15 +56,9 @@ BallColor.Pending=Pendiente BallColor.Success=Correcto BallColor.Unstable=Inestable -CLI.clear-queue.shortDescription=Limpiar la cola de trabajos -CLI.delete-job.shortDescription=Borrar una tarea CLI.disable-job.shortDescription=Desactivar una tarea CLI.enable-job.shortDescription=Activar una tarea -CLI.delete-node.shortDescription=Borrar un nodo -CLI.disconnect-node.shortDescription=Desconectarse de un nodo -CLI.connect-node.shortDescription=Reconectarse con un nodo CLI.online-node.shortDescription=Continuar usando un nodo y candelar el comando "offline-node" mas reciente. -CLI.offline-node.shortDescription=Dejar de utilizar un nodo temporalmente hasta que se ejecute el comando "online-node". Computer.Caption=Remoto {0} Computer.Permissions.Title=Nodo @@ -80,7 +72,7 @@ Executor.NotAvailable=N/D FreeStyleProject.DisplayName=Crear un proyecto de estilo libre - +FreeStyleProject.Description=Esta es la caracter\u00EDstica principal de Jenkins, la de ejecutar el proyecto combinando cualquier tipo de repositorio de software (SCM) con cualquier modo de construcci\u00F3n o ejecuci\u00F3n (make, ant, mvn, rake, script ...). Por tanto se podr\u00E1 tanto compilar y empaquetar software, como ejecutar cualquier proceso que requiera monitorizaci\u00F3n. Hudson.BadPortNumber=N\u00famero err\u00f3neo de puerto {0} Hudson.Computer.Caption=Principal @@ -218,7 +210,6 @@ Permalink.LastSuccessfulBuild=\u00daltima ejecuci\u00f3n correcta Permalink.LastFailedBuild=\u00daltima ejecuci\u00f3n fallida ParameterAction.DisplayName=Par\u00e1metros -ParametersDefinitionProperty.DisplayName=Par\u00e1metros StringParameterDefinition.DisplayName=Par\u00e1metro de cadena FileParameterDefinition.DisplayName=Par\u00e1metro de fichero BooleanParameterDefinition.DisplayName=Valor booleano @@ -254,9 +245,6 @@ MyViewsProperty.ViewExistsCheck.AlreadyExists=Una vista con el nombre {0} ya exi CLI.restart.shortDescription=Reiniciar Jenkins CLI.safe-restart.shortDescription=Reiniciar Jenkins de manera segura CLI.keep-build.shortDescription=Marcar la ejecuci\u00f3n para ser guardada para siempre. -CLI.quiet-down.shortDescription=Poner Jenkins en modo quieto y estar preparado para un reinicio. No comenzar ninguna ejecuci\u00f3n. -CLI.cancel-quiet-down.shortDescription=Cancelar el efecto del comando "quiet-down". -CLI.reload-configuration.shortDescription=Descartar todos los datos presentes en memoria y recargar todo desde el disco duro. \u00datil cuando se han hecho modificaciones a mano en el disco duro. View.MissingMode=No se ha especificado el tipo para la vista AbstractProject.NoBuilds=No existen ejecuciones. Lanzando una nueva. @@ -281,7 +269,6 @@ AbstractProject.AwaitingBuildForWorkspace=El trabajo est\u00e1 esperando para te Run.ArtifactsPermission.Description=\ Este permiso sirve para poder utilizar los artefactos producidos en los proyectos. AbstractProject.AssignedLabelString.InvalidBooleanExpression=Expresi\u00f3n booleana incorrecta: {0} -AbstractProject.BuildNow=Construir ahora ManageJenkinsAction.DisplayName=Administrar Jenkins Computer.NoSuchSlaveExists=El nodo {0} no existe. Quizs se est refiriendo a {1}? ResultTrend.StillFailing=Todava falla @@ -297,8 +284,6 @@ ResultTrend.Aborted=Cancelado TextParameterDefinition.DisplayName=Parmetro de texto AbstractProject.AssignedLabelString_NoMatch_DidYouMean=No hay ningn nodo que cumpla esta asignacin. Quizs se refiera a ''{1}'' en lugar de ''{0}''? ResultTrend.Success=Correcto -CLI.wait-node-online.shortDescription=Esperando hasta que el nodo est activado -CLI.wait-node-offline.shortDescription=Esperando a que el nodo est desactivado AbstractProject.CancelPermission.Description=Este permiso permite que se pueda cancelar un trabajo. Run.Summary.NotBuilt=no se ha ejecutado AbstractProject.DiscoverPermission.Description=Este permiso garantiza que se pueda descubrir tareas. \ @@ -316,3 +301,4 @@ UpdateCenter.DownloadButNotActivated=Descarga correcta. Se activar Computer.ConnectPermission.Description=Este permiso permite que los usuarios puedan conectar nodos o marcarlos como activos. BallColor.NotBuilt=Sin ejecutar. AbstractBuild_Building=Ejecutando. +ParametersDefinitionProperty.DisplayName=Esta ejecucin debe parametrizarse diff --git a/core/src/main/resources/hudson/model/Messages_et.properties b/core/src/main/resources/hudson/model/Messages_et.properties new file mode 100644 index 0000000000000000000000000000000000000000..ff3d7fc8bdde0b4f70664f1c3ed9426a41a19542 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_et.properties @@ -0,0 +1 @@ +FreeStyleProject.Description=See on Jenkinsi p\u00F5hifunktsioon! Jenkins ehitab su projekti, kombineerides sinu versioonihalduse mistahes ehitusprotsessiga. Sa v\u00F5id seda kasutada ka muudeks asjadeks kui tarkvara ehitamine. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_fi.properties b/core/src/main/resources/hudson/model/Messages_fi.properties index a5937f2baf73e1fd215188eaff1bb4fd10741675..cc62c20834f3c90b6e76e04f955f2b92a7efc694 100644 --- a/core/src/main/resources/hudson/model/Messages_fi.properties +++ b/core/src/main/resources/hudson/model/Messages_fi.properties @@ -1,2 +1,3 @@ -AbstractProject.BuildNow=K\u00E4\u00E4nn\u00E4 nyt ManageJenkinsAction.DisplayName=Hallitse Jenkinsia + +FreeStyleProject.Description=T\u00E4m\u00E4 on Jenkins t\u00E4rkein ominaisuus. Jenkins rakentaa projektisi k\u00E4ytt\u00E4en versionhallintaa ja buildij\u00E4rjestelmi\u00E4. Voit k\u00E4ytt\u00E4\u00E4 t\u00E4t\u00E4 my\u00F6s muuhun kuin ohjelmien k\u00E4\u00E4nt\u00E4miseen. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_fr.properties b/core/src/main/resources/hudson/model/Messages_fr.properties index 82d0d98072736e273db4887efba567fb8b2f2172..30e1b2e65b3fafd738d675c6a91472458018807a 100644 --- a/core/src/main/resources/hudson/model/Messages_fr.properties +++ b/core/src/main/resources/hudson/model/Messages_fr.properties @@ -1,17 +1,17 @@ # The MIT License -# +# # Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant, Damien Finck -# +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: -# +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. -# +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,9 +26,7 @@ AbstractBuild.KeptBecause=conserv\u00e9 \u00e0 cause de {0} AbstractProject.NewBuildForWorkspace=Demande d''un nouveau build afin d''avoir un r\u00e9pertoire de travail AbstractProject.Pronoun=Projet AbstractProject.Aborted=Annul\u00e9 -AbstractProject.BuildInProgress=Le build #{0} est d\u00e9j\u00e0 en cours {1} AbstractProject.Disabled=Build d\u00e9sactiv\u00e9 -AbstractProject.ETA=\ (fin pr\u00e9vue \u00e0: {0}) AbstractProject.NoSCM=Pas d''outil de gestion de version AbstractProject.NoWorkspace=Pas r\u00e9pertoire de travail disponible, donc impossible de r\u00e9cup\u00e9rer les mises \u00e0 jour. AbstractProject.PollingABorted=Scrutation de l''outil de gestion de version annul\u00e9e @@ -52,18 +50,12 @@ BallColor.Pending=En attente BallColor.Success=Succ\u00e8s BallColor.Unstable=Instable -Computer.Caption=Esclave {0} -Computer.Permissions.Title=Esclave -Computer.ConfigurePermission.Description=Ce droit permet aux utilisateurs de configurer les esclaves. -Computer.DeletePermission.Description=Ce droit permet aux utilisateurs de supprimer les esclaves. -ComputerSet.NoSuchSlave=Cet esclave n''existe pas : {0} -ComputerSet.SlaveAlreadyExists=L''esclave appel\u00e9 ''{0}'' existe d\u00e9j\u00e0 -ComputerSet.SpecifySlaveToCopy=Sp\u00e9cifiez l''esclave \u00e0 copier Executor.NotAvailable=N/A FreeStyleProject.DisplayName=Construire un projet free-style +FreeStyleProject.Description=Ceci est la fonction principale de Jenkins qui sert \u00E0 builder (construire) votre projet. Vous pouvez int\u00E9grer tous les outils de gestion de version avec tous les syst\u00E8mes de build. Il est m\u00EAme possible d''utiliser Jenkins pour tout autre chose qu''un build logiciel. Hudson.BadPortNumber=Num\u00e9ro de port incorrect {0} Hudson.Computer.Caption=Ma\u00eetre @@ -128,14 +120,6 @@ Run.UpdatePermission.Description=\ Cette option permet aux utilisateurs de mettre \u00e0 jour la description et d''autres propri\u00e9t\u00e9s d''un build, \ par exemple pour laisser des notes sur la cause d''\u00e9chec d''un build. -Slave.InvalidConfig.Executors=Configuration esclave invalide pour {0}. Nombre d''ex\u00e9cuteurs invalide. -Slave.InvalidConfig.NoName=Configuration esclave invalide. Le nom est vide. -Slave.InvalidConfig.NoRemoteDir=Configuration esclave invalide pour {0}. Pas de r\u00e9pertoire distant fourni -Slave.Launching={0} Lancement de l''agent esclave -Slave.Terminated={0} l''agent esclave a \u00e9t\u00e9 termin\u00e9 -Slave.UnableToLaunch=Impossible de lancer l''agent esclave pour {0} {1} -Slave.UnixSlave=Ceci est un esclave Unix -Slave.WindowsSlave=Ceci est un esclave Windows View.Permissions.Title=Vues View.CreatePermission.Description=\ @@ -163,7 +147,6 @@ Permalink.LastSuccessfulBuild=Dernier build avec succ\u00e8s Permalink.LastFailedBuild=Dernier build en \u00e9chec ParameterAction.DisplayName=Param\u00e8tres -ParametersDefinitionProperty.DisplayName=Param\u00e8tres StringParameterDefinition.DisplayName=Param\u00e8tre String TextParameterDefinition.DisplayName=Param\u00e8tre texte FileParameterDefinition.DisplayName=Param\u00e8tre fichier @@ -193,5 +176,5 @@ Cause.RemoteCause.ShortDescription=D\u00e9marr\u00e9 \u00e0 distance par {0} MyViewsProperty.DisplayName=Mes vues MyViewsProperty.GlobalAction.DisplayName=Mes vues -AbstractProject.BuildNow=Lancer un build ManageJenkinsAction.DisplayName=Administrer Jenkins +ParametersDefinitionProperty.DisplayName=Ce build a des paramtres diff --git a/core/src/main/resources/hudson/model/Messages_he.properties b/core/src/main/resources/hudson/model/Messages_he.properties new file mode 100644 index 0000000000000000000000000000000000000000..749fbe732d68257317835ddb25e4af01a620271c --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_he.properties @@ -0,0 +1 @@ +ParametersDefinitionProperty.DisplayName=\u05D1\u05E0\u05D9\u05D4 \u05DE\u05DB\u05D9\u05DC\u05D4 \u05DE\u05E9\u05EA\u05E0\u05D9\u05DD diff --git a/core/src/main/resources/hudson/model/Messages_hi_IN.properties b/core/src/main/resources/hudson/model/Messages_hi_IN.properties new file mode 100644 index 0000000000000000000000000000000000000000..58a16a05dd59427bb29ab5e14d6b9bd83e0f66e9 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_hi_IN.properties @@ -0,0 +1 @@ +FreeStyleProject.Description=\u092F\u0939 \u091C\u0947\u0928\u0915\u0940\u0902\u0938 \u0915\u0940 \u0915\u0947\u0902\u0926\u094D\u0930\u0940\u092F \u0935\u093F\u0936\u0947\u0937\u0924\u093E \u0939\u0948\u0964 \u091C\u0947\u0928\u0915\u0940\u0902\u0938, \u0915\u093F\u0938\u0940 \u092D\u0940 \u0928\u093F\u0930\u094D\u092E\u093E\u0923 \u092A\u094D\u0930\u0923\u093E\u0932\u0940 \u0915\u0947 \u0938\u093E\u0925 \u0915\u093F\u0938\u0940 \u092D\u0940 \u0938\u0949\u092B\u094D\u091F\u0935\u0947\u092F\u0930 \u0935\u093F\u0928\u094D\u092F\u093E\u0938 \u092A\u094D\u0930\u092C\u0902\u0927\u0928 \u0915\u093E \u0938\u0902\u092F\u094B\u091C\u0928 \u0915\u0930\u0915\u0947 \u0906\u092A\u0915\u0940 \u092A\u0930\u093F\u092F\u094B\u091C\u0928\u093E \u0915\u093E \u0928\u093F\u0930\u094D\u092E\u093E\u0923 \u0915\u0930\u0947\u0917\u093E, \u0914\u0930 \u0907\u0938\u0915\u093E \u092A\u094D\u0930\u092F\u094B\u0917 \u0938\u0949\u092B\u094D\u091F\u0935\u0947\u092F\u0930 \u0915\u093E \u0928\u093F\u0930\u094D\u092E\u093E\u0923 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0905\u0932\u093E\u0935\u093E \u0905\u0928\u094D\u092F \u0915\u093E\u0930\u094D\u092F\u094B\u0902 \u0915\u0947 \u0932\u093F\u090F \u092D\u0940 \u0915\u093F\u092F\u093E \u091C\u093E \u0938\u0915\u0924\u093E \u0939\u0948. diff --git a/core/src/main/resources/hudson/model/Messages_hu.properties b/core/src/main/resources/hudson/model/Messages_hu.properties index cbad071927f6add017668d5edb34a95fc1d0bce1..949132eb7f5dadd39bd24b1054c24d5985d730d6 100644 --- a/core/src/main/resources/hudson/model/Messages_hu.properties +++ b/core/src/main/resources/hudson/model/Messages_hu.properties @@ -1,2 +1,2 @@ -AbstractProject.BuildNow=\u00C9p\u00EDt\u00E9s Most ManageJenkinsAction.DisplayName=Jenkins Kezel\u00E9se +ParametersDefinitionProperty.DisplayName=Hozz\u00E1ad diff --git a/core/src/main/resources/hudson/model/Messages_id.properties b/core/src/main/resources/hudson/model/Messages_id.properties new file mode 100644 index 0000000000000000000000000000000000000000..fbb242f35c4f9735014141e62b9c36c07d040eb2 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_id.properties @@ -0,0 +1 @@ +FreeStyleProject.Description=Ini adalah fitur sentral dari Jenkins. Jenkins akan membangun proyek anda, mengkombinasikan SCM apa pun dengan sistem pembangunan, dan ini akan digunakan untuk sesuatu selain pembangunan piranti lunak. diff --git a/core/src/main/resources/hudson/model/Messages_it.properties b/core/src/main/resources/hudson/model/Messages_it.properties index e8b51dcaa4ec98123475babc1034887f5a34f71f..8458a59a89565bda36b45c14a24878a60b3ac82d 100644 --- a/core/src/main/resources/hudson/model/Messages_it.properties +++ b/core/src/main/resources/hudson/model/Messages_it.properties @@ -28,17 +28,13 @@ AbstractBuild.KeptBecause=kept because of {0} AbstractItem.NoSuchJobExists=Nessun job di nome ''{0}'' esiste. Intendevi forse ''{1}''? AbstractItem.Pronoun=Job -AbstractProject.AssignedLabelString_NoMatch_DidYouMean=There''s no slave/cloud that matches this assignment. Did you mean ''{1}'' instead of ''{0}''? AbstractProject.NewBuildForWorkspace=Scheduling a new build to get a workspace. AbstractProject.AwaitingBuildForWorkspace=Awaiting build to get a workspace. AbstractProject.Pronoun=Progetto AbstractProject.Aborted=Interrotta -AbstractProject.BuildInProgress=Build #{0} is already in progress{1} -AbstractProject.BuildNow=Effettua build AbstractProject.UpstreamBuildInProgress=Upstream project {0} is already building. AbstractProject.DownstreamBuildInProgress=Downstream project {0} is already building. AbstractProject.Disabled=Build disabled -AbstractProject.ETA=\ (ETA:{0}) AbstractProject.NoBuilds=No existing build. Scheduling a new one. AbstractProject.NoSCM=No SCM AbstractProject.NoWorkspace=No workspace is available, so can''t check for updates. @@ -59,8 +55,6 @@ AbstractProject.WipeOutPermission.Description=\ This permission grants the ability to wipe out the contents of a workspace. AbstractProject.AssignedLabelString.InvalidBooleanExpression=\ Espressione booleana non valida: {0} -AbstractProject.AssignedLabelString.NoMatch=\ - There's no slave/cloud that matches this assignment Api.MultipleMatch=XPath "{0}" corrisponde a {1} nodi. \ Creare un XPath che corrisponde ad un solo valore, oppure utilizzare una query "wrapper" \ @@ -76,36 +70,15 @@ BallColor.Pending=In attesa BallColor.Success=Successo BallColor.Unstable=Instabile -CLI.clear-queue.shortDescription=Pulisce la coda di lavoro -CLI.delete-job.shortDescription=Cancella un job CLI.disable-job.shortDescription=Disabilita un job CLI.enable-job.shortDescription=Abilita un job -CLI.delete-node.shortDescription=Cancella un nodo -CLI.disconnect-node.shortDescription=Disconnects from a node -CLI.connect-node.shortDescription=Riconnettersi ad un nodo CLI.online-node.shortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command. -CLI.offline-node.shortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command. -CLI.wait-node-online.shortDescription=Attende che il nodo sia attivo -CLI.wait-node-offline.shortDescription=Attende che un nodo sia disattivo -Computer.Caption=Slave {0} -Computer.NoSuchSlaveExists=No such slave "{0}" exists. Did you mean "{1}"? -Computer.Permissions.Title=Slave -Computer.ConfigurePermission.Description=This permission allows users to configure slaves. -Computer.DeletePermission.Description=This permission allows users to delete existing slaves. -Computer.CreatePermission.Description=This permission allows users to create slaves. -Computer.ConnectPermission.Description=This permission allows users to connect slaves or mark slaves as online. -Computer.DisconnectPermission.Description=This permission allows users to disconnect slaves or mark slaves as temporarily offline. -Computer.BadChannel=Slave node offline or not a remote channel (such as master node). - -ComputerSet.NoSuchSlave=No such slave: {0} -ComputerSet.SlaveAlreadyExists=Slave called ''{0}'' already exists -ComputerSet.SpecifySlaveToCopy=Specify which slave to copy ComputerSet.DisplayName=nodes Executor.NotAvailable=N/A - FreeStyleProject.DisplayName=Configura una build di tipo generico +FreeStyleProject.Description=Questa \u00E8 la funzione principale di Jenkins. Jenkins effettuer\u00E0 una compilazione del progetto, combinando qualsiasi SCM con qualsiasi sistema di compilazione e si pu\u00F2 usare anche per qualcosa di altro che non sia un programma di compilazione. HealthReport.EmptyString= @@ -211,16 +184,8 @@ Run.Summary.BrokenSinceThisBuild=broken since this build Run.Summary.BrokenSince=broken since build {0} Run.Summary.Unknown=? -Slave.InvalidConfig.Executors=Invalid slave configuration for {0}. Invalid # of executors. -Slave.InvalidConfig.NoName=Invalid slave configuration. Name is empty -Slave.InvalidConfig.NoRemoteDir=Invalid slave configuration for {0}. No remote directory given -Slave.Launching={0} Launching slave agent Slave.Network.Mounted.File.System.Warning=Are you sure you want to use network mounted file system for FS root? Note that this directory does not need to be visible to the master. Slave.Remote.Director.Mandatory=Remote directory is mandatory -Slave.Terminated={0} slave agent was terminated -Slave.UnableToLaunch=Unable to launch the slave agent for {0}{1} -Slave.UnixSlave=This is a Unix slave -Slave.WindowsSlave=This is a Windows slave UpdateCenter.DownloadButNotActivated=Downloaded Successfully. Will be activated during the next boot View.Permissions.Title=View @@ -256,7 +221,6 @@ UpdateCenter.PluginCategory.post-build=Other Post-Build Actions UpdateCenter.PluginCategory.report=Build Reports UpdateCenter.PluginCategory.scm=Source Code Management UpdateCenter.PluginCategory.scm-related=Source Code Management related -UpdateCenter.PluginCategory.slaves=Slave Launchers and Controllers UpdateCenter.PluginCategory.trigger=Build Triggers UpdateCenter.PluginCategory.ui=User Interface UpdateCenter.PluginCategory.upload=Artifact Uploaders @@ -272,16 +236,15 @@ Permalink.LastSuccessfulBuild=Last successful build Permalink.LastFailedBuild=Last failed build ParameterAction.DisplayName=Parameters -ParametersDefinitionProperty.DisplayName=Parameters StringParameterDefinition.DisplayName=String Parameter -TextParameterDefinition.DisplayName=Text Parameter +TextParameterDefinition.DisplayName=Multi-line String Parameter FileParameterDefinition.DisplayName=File Parameter BooleanParameterDefinition.DisplayName=Boolean Value ChoiceParameterDefinition.DisplayName=Choice RunParameterDefinition.DisplayName=Run Parameter PasswordParameterDefinition.DisplayName=Password Parameter -Node.Mode.NORMAL=Utilize this slave as much as possible +Node.Mode.NORMAL=Utilize this agent as much as possible Node.Mode.EXCLUSIVE=Leave this machine for tied jobs only ListView.DisplayName=List View @@ -310,8 +273,6 @@ MyViewsProperty.ViewExistsCheck.AlreadyExists=A view with name {0} already exist CLI.restart.shortDescription=Riavvia Jenkins CLI.safe-restart.shortDescription=Riavvio sicuro Jenkins CLI.keep-build.shortDescription=Mark the build to keep the build forever. -CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don''t start any builds. -CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command. -CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk. BuildAuthorizationToken.InvalidTokenProvided=Invalid token provided. +ParametersDefinitionProperty.DisplayName=Questa build \u00E8 parametrizzata diff --git a/core/src/main/resources/hudson/model/Messages_ja.properties b/core/src/main/resources/hudson/model/Messages_ja.properties index f47d7cb6859bf894c0ff368b92bc7a88d7431f11..3d51ee20c7170e3d7a519c978e0a26637f468ce6 100644 --- a/core/src/main/resources/hudson/model/Messages_ja.properties +++ b/core/src/main/resources/hudson/model/Messages_ja.properties @@ -28,19 +28,13 @@ AbstractBuild.KeptBecause={0}\u306e\u305f\u3081\u3001\u4fdd\u5b58\u3057\u307e\u3 AbstractItem.NoSuchJobExists=\u30b8\u30e7\u30d6''{0}''\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002''{1}''\u3067\u3059\u304b? AbstractItem.Pronoun=\u30b8\u30e7\u30d6 -AbstractProject.AssignedLabelString_NoMatch_DidYouMean=\ - \u8a72\u5f53\u3059\u308b\u30b9\u30ec\u30fc\u30d6\u3084\u30ce\u30fc\u30c9\u306f\u3042\u308a\u307e\u305b\u3093\u3002''{0}''\u3067\u306f\u306a\u304f\u3066''{1}''\u306e\u3053\u3068\u3067\u3059\u304b? AbstractProject.NewBuildForWorkspace=\u65b0\u898f\u306e\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3001\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3092\u4f5c\u6210\u3057\u3066\u304f\u3060\u3055\u3044\u3002 AbstractProject.AwaitingBuildForWorkspace=\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u304c\u7528\u610f\u3067\u304d\u308b\u307e\u3067\u30d3\u30eb\u30c9\u3092\u4fdd\u7559\u3057\u307e\u3059\u3002 AbstractProject.Pronoun=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 AbstractProject.Aborted=\u4e2d\u6b62 -AbstractProject.BuildInProgress=\u30d3\u30eb\u30c9 #{0} \u306f\u65e2\u306b\u5b9f\u884c\u4e2d\u3067\u3059\u3002{1} -AbstractProject.BuildNow=\u30d3\u30eb\u30c9\u5b9f\u884c -AbstractProject.build_with_parameters=\u30d1\u30e9\u30e1\u30fc\u30bf\u4ed8\u304d\u30d3\u30eb\u30c9 AbstractProject.UpstreamBuildInProgress=\u4e0a\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 {0} \u306f\u3059\u3067\u306b\u30d3\u30eb\u30c9\u4e2d\u3067\u3059\u3002 AbstractProject.DownstreamBuildInProgress=\u4e0b\u6d41\u30d7\u30ed\u30b8\u30a7\u30af\u30c8 {0} \u304c\u307e\u3060\u30d3\u30eb\u30c9\u4e2d\u3067\u3059\u3002 AbstractProject.Disabled=\u30d3\u30eb\u30c9\u306f\u7121\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002 -AbstractProject.ETA=\ (\u4e88\u5b9a\u6642\u9593:{0}) AbstractProject.NoBuilds=\u30d3\u30eb\u30c9\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u65b0\u3057\u3044\u30d3\u30eb\u30c9\u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3057\u307e\u3059\u3002 AbstractProject.NoSCM=SCM\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 AbstractProject.NoWorkspace=\u5229\u7528\u53ef\u80fd\u306a\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u304c\u306a\u3044\u306e\u3067\u3001\u66f4\u65b0\u3092\u30c1\u30a7\u30c3\u30af\u3067\u304d\u307e\u305b\u3093\u3002 @@ -64,7 +58,6 @@ AbstractProject.CancelPermission.Description=\ \u30d3\u30eb\u30c9\u306e\u30ad\u30e3\u30f3\u30bb\u30eb\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 AbstractProject.AssignedLabelString.InvalidBooleanExpression=\ \u30e9\u30d9\u30eb\u5f0f\u306b\u9593\u9055\u3044\u304c\u3042\u308a\u307e\u3059\u3002: {0} -AbstractProject.AssignedLabelString.NoMatch=\ \u8a72\u5f53\u3059\u308b\u30b9\u30ec\u30fc\u30d6\u3082\u3057\u304f\u306f\u30af\u30e9\u30a6\u30c9\u306f\u3042\u308a\u307e\u305b\u3093\u3002 AbstractProject.CustomWorkspaceEmpty=\u30ab\u30b9\u30bf\u30e0\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u304c\u5165\u529b\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 @@ -81,21 +74,7 @@ BallColor.Pending=\u672a\u6c7a\u5b9a BallColor.Success=\u6210\u529f BallColor.Unstable=\u4e0d\u5b89\u5b9a -Computer.Caption=\u30b9\u30ec\u30fc\u30d6 {0} -Computer.NoSuchSlaveExists="{0}"\u3068\u3044\u3046\u30b9\u30ec\u30fc\u30d6\u306f\u5b58\u5728\u3057\u307e\u305b\u3093\u3002"{1}"\u306e\u3053\u3068\u3067\u3059\u304b? -Computer.Permissions.Title=\u30b9\u30ec\u30fc\u30d6 -Computer.ExtendedReadPermission.Description=\u30b9\u30ec\u30fc\u30d6\u306e\u8a2d\u5b9a\u306e\u53c2\u7167\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.ConfigurePermission.Description=\u30b9\u30ec\u30fc\u30d6\u306e\u8a2d\u5b9a\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.DeletePermission.Description=\u30b9\u30ec\u30fc\u30d6\u306e\u524a\u9664\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.CreatePermission.Description=\u30b9\u30ec\u30fc\u30d6\u306e\u4f5c\u6210\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.ConnectPermission.Description=\u30b9\u30ec\u30fc\u30d6\u3078\u306e\u63a5\u7d9a\u3068\u30aa\u30f3\u30e9\u30a4\u30f3\u5316\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.DisconnectPermission.Description=\u30b9\u30ec\u30fc\u30d6\u306e\u5207\u65ad\u3068\u4e00\u6642\u7684\u306a\u30aa\u30d5\u30e9\u30a4\u30f3\u5316\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.BuildPermission.Description=\u30b9\u30ec\u30fc\u30d6\u4e0a\u3067\u306e\u30b8\u30e7\u30d6\u306e\u8d77\u52d5\u3092\u8a31\u53ef\u3057\u307e\u3059\u3002 -Computer.BadChannel=\u30b9\u30ec\u30fc\u30d6\u30ce\u30fc\u30c9\u304c\u30aa\u30d5\u30e9\u30a4\u30f3\u304b\u30ea\u30e2\u30fc\u30c8\u30c1\u30e3\u30cd\u30eb\u3067\u3059(\u30de\u30b9\u30bf\u30fc\u30ce\u30fc\u30c9\u306a\u3069)\u3002 - -ComputerSet.NoSuchSlave=\u30b9\u30ec\u30fc\u30d6\u304c\u5b58\u5728\u3057\u307e\u305b\u3093: {0} -ComputerSet.SlaveAlreadyExists=''{0}''\u306f\u3059\u3067\u306b\u5b58\u5728\u3057\u307e\u3059 -ComputerSet.SpecifySlaveToCopy=\u30b3\u30d4\u30fc\u3059\u308b\u30b9\u30ec\u30fc\u30d6\u3092\u6307\u5b9a\u3057\u3066\u304f\u3060\u3055\u3044\u3002 + ComputerSet.DisplayName=\u30ce\u30fc\u30c9 Descriptor.From=(from {0}) @@ -104,6 +83,10 @@ Executor.NotAvailable=N/A FreeStyleProject.DisplayName=\u30d5\u30ea\u30fc\u30b9\u30bf\u30a4\u30eb\u30fb\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u30d3\u30eb\u30c9 +FreeStyleProject.Description=\ + \u3082\u3063\u3068\u3082\u6c4e\u7528\u6027\u306e\u9ad8\u3044Jenkins\u306e\u4e2d\u6838\u6a5f\u80fd\u3067\u3059\u3002\u4efb\u610f\u306eSCM\u304b\u3089\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u30c1\u30a7\u30c3\u30af\u30a2\u30a6\u30c8\u3057\u3001\ + \u4efb\u610f\u306e\u30d3\u30eb\u30c9\u30b7\u30b9\u30c6\u30e0\u3067\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u30d3\u30eb\u30c9\u3067\u304d\u307e\u3059\u3002\u5f80\u3005\u306b\u3057\u3066\u3001\u30bd\u30d5\u30c8\u30a6\u30a7\u30a2\u306e\u30d3\u30eb\u30c9\u4ee5\u5916\u306b\u3082\ + \u69d8\u3005\u306a\u4ed5\u4e8b\u306e\u81ea\u52d5\u5316\u306b\u5229\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002 HealthReport.EmptyString= @@ -208,17 +191,9 @@ Run.Summary.BrokenSinceThisBuild=\u3053\u306e\u30d3\u30eb\u30c9\u304b\u3089\u654 Run.Summary.BrokenSince=\u30d3\u30eb\u30c9{0}\u304b\u3089\u6545\u969c Run.Summary.Unknown=? -Slave.InvalidConfig.Executors=\u30b9\u30ec\u30fc\u30d6 {0} \u306e\u8a2d\u5b9a\u306b\u8aa4\u308a\u304c\u3042\u308a\u307e\u3059\u3002\u540c\u6642\u5b9f\u884c\u6570\u304c\u4e0d\u6b63\u3067\u3059\u3002 -Slave.InvalidConfig.NoName=\u30b9\u30ec\u30fc\u30d6\u306e\u8a2d\u5b9a\u306b\u8aa4\u308a\u304c\u3042\u308a\u307e\u3059\u3002\u540d\u524d\u304c\u672a\u8a2d\u5b9a\u3067\u3059\u3002 -Slave.InvalidConfig.NoRemoteDir=\u30b9\u30ec\u30fc\u30d6 {0} \u306e\u8a2d\u5b9a\u306b\u8aa4\u308a\u304c\u3042\u308a\u307e\u3059\u3002\u30ea\u30e2\u30fc\u30c8FS\u30eb\u30fc\u30c8\u304c\u672a\u8a2d\u5b9a\u3067\u3059\u3002 -Slave.Launching=\u30b9\u30ec\u30fc\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u8d77\u52d5\u3057\u307e\u3057\u305f\u3002{0} Slave.Network.Mounted.File.System.Warning=\u672c\u5f53\u306bFS\u30eb\u30fc\u30c8\u3068\u3057\u3066\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30de\u30a6\u30f3\u30c8\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u30b7\u30b9\u30c6\u30e0\u3092\u4f7f\u7528\u3057\u305f\u3044\u3067\u3059\u304b\uff1f \u3053\u306e\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306f\u30de\u30b9\u30bf\u30fc\u306b\u898b\u3048\u308b\u5fc5\u8981\u306f\u7121\u3044\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002 Slave.Remote.Director.Mandatory=\u30ea\u30e2\u30fc\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306f\u5fc5\u9808\u3067\u3059\u3002 -Slave.Terminated=\u30b9\u30ec\u30fc\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u7d42\u4e86\u3057\u307e\u3057\u305f\u3002{0} Slave.the_remote_root_must_be_an_absolute_path=\u30ea\u30e2\u30fc\u30c9\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306f\u7d76\u5bfe\u30d1\u30b9\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002 -Slave.UnableToLaunch=\u30b9\u30ec\u30fc\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8 {0} \u3092\u8d77\u52d5\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002{1} -Slave.UnixSlave=\u3053\u308c\u306fUnix\u306e\u30b9\u30ec\u30fc\u30d6\u3067\u3059\u3002 -Slave.WindowsSlave=\u3053\u308c\u306fWindows\u306e\u30b9\u30ec\u30fc\u30d6\u3067\u3059\u3002 UpdateCenter.DownloadButNotActivated=\u6b63\u5e38\u306b\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3057\u307e\u3057\u305f\u3002\u6b21\u306e\u30d6\u30fc\u30c8\u6642\u306b\u6709\u52b9\u306b\u306a\u308a\u307e\u3059\u3002 UpdateCenter.n_a=N/A @@ -258,7 +233,6 @@ UpdateCenter.PluginCategory.post-build=\u30d3\u30eb\u30c9\u5f8c\u306e\u30a2\u30a UpdateCenter.PluginCategory.report=\u30d3\u30eb\u30c9\u30ec\u30dd\u30fc\u30c8 UpdateCenter.PluginCategory.scm=\u30bd\u30fc\u30b9\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0 UpdateCenter.PluginCategory.scm-related=\u30bd\u30fc\u30b9\u7ba1\u7406\u30b7\u30b9\u30c6\u30e0\u95a2\u9023 -UpdateCenter.PluginCategory.slaves=\u30b9\u30ec\u30fc\u30d6\u306e\u8d77\u52d5\u3068\u7ba1\u7406 UpdateCenter.PluginCategory.trigger=\u30d3\u30eb\u30c9\u30c8\u30ea\u30ac UpdateCenter.PluginCategory.ui=\u30e6\u30fc\u30b6\u30fc\u30a4\u30f3\u30bf\u30d5\u30a7\u30fc\u30b9 UpdateCenter.PluginCategory.upload=\u6210\u679c\u7269\u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9 @@ -272,10 +246,10 @@ Permalink.LastUnstableBuild=\u6700\u65b0\u306e\u4e0d\u5b89\u5b9a\u30d3\u30eb\u30 Permalink.LastUnsuccessfulBuild=\u6700\u65b0\u306e\u4e0d\u6210\u529f\u30d3\u30eb\u30c9 Permalink.LastSuccessfulBuild=\u6700\u65b0\u306e\u6210\u529f\u30d3\u30eb\u30c9 Permalink.LastFailedBuild=\u6700\u65b0\u306e\u5931\u6557\u30d3\u30eb\u30c9 +Permalink.LastCompletedBuild=\u6700\u65b0\u306e\u5b8c\u4e86\u30d3\u30eb\u30c9 ParameterAction.DisplayName=\u30d1\u30e9\u30e1\u30fc\u30bf -ParametersDefinitionProperty.DisplayName=\u30d1\u30e9\u30e1\u30fc\u30bf StringParameterDefinition.DisplayName=\u6587\u5b57\u5217 TextParameterDefinition.DisplayName=\u30c6\u30ad\u30b9\u30c8 FileParameterDefinition.DisplayName=\u30d5\u30a1\u30a4\u30eb @@ -316,20 +290,11 @@ MyViewsProperty.ViewExistsCheck.AlreadyExists="{0}"\u3068\u3044\u3046\u30d3\u30e CLI.restart.shortDescription=Jenkins\u3092\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002 CLI.safe-restart.shortDescription=Jenkins\u3092\u5b89\u5168\u306b\u518d\u8d77\u52d5\u3057\u307e\u3059\u3002 CLI.keep-build.shortDescription=\u30d3\u30eb\u30c9\u3092\u4fdd\u5b58\u3059\u308b\u3088\u3046\u306b\u30de\u30fc\u30af\u3057\u307e\u3059\u3002 -CLI.quiet-down.shortDescription=Jenkins\u306f\u518d\u8d77\u52d5\u306b\u5411\u3051\u3066\u7d42\u4e86\u51e6\u7406\u3092\u5b9f\u65bd\u4e2d\u3067\u3059\u3002\u30d3\u30eb\u30c9\u3092\u958b\u59cb\u3057\u306a\u3044\u3067\u304f\u3060\u3055\u3044\u3002 -CLI.cancel-quiet-down.shortDescription="quite-down"\u30b3\u30de\u30f3\u30c9\u306e\u51e6\u7406\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3059\u3002 CLI.reload-configuration.shortDescription=\u30e1\u30e2\u30ea\u306b\u3042\u308b\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u7834\u68c4\u3057\u3066\u3001\u30d5\u30a1\u30a4\u30eb\u304b\u3089\u518d\u30ed\u30fc\u30c9\u3057\u307e\u3059\u3002\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u3092\u76f4\u63a5\u4fee\u6b63\u3057\u305f\u5834\u5408\u306b\u5f79\u306b\u7acb\u3061\u307e\u3059\u3002 CLI.clear-queue.shortDescription=\u30d3\u30eb\u30c9\u30ad\u30e5\u30fc\u3092\u30af\u30ea\u30a2\u3057\u307e\u3059\u3002 -CLI.delete-job.shortDescription=\u30b8\u30e7\u30d6\u3092\u524a\u9664\u3057\u307e\u3059\u3002 CLI.disable-job.shortDescription=\u30b8\u30e7\u30d6\u3092\u7121\u52b9\u5316\u3057\u307e\u3059\u3002 CLI.enable-job.shortDescription=\u30b8\u30e7\u30d6\u3092\u6709\u52b9\u5316\u3057\u307e\u3059\u3002 -CLI.delete-node.shortDescription=\u30ce\u30fc\u30c9\u3092\u524a\u9664\u3057\u307e\u3059\u3002 -CLI.disconnect-node.shortDescription=\u30ce\u30fc\u30c9\u3068\u306e\u63a5\u7d9a\u3092\u5207\u65ad\u3057\u307e\u3059\u3002 -CLI.connect-node.shortDescription=\u30ce\u30fc\u30c9\u3068\u518d\u63a5\u7d9a\u3057\u307e\u3059\u3002 CLI.online-node.shortDescription=\u76f4\u524d\u306b\u5b9f\u884c\u3057\u305f"online-node"\u30b3\u30de\u30f3\u30c9\u3092\u53d6\u308a\u6d88\u3057\u3001\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u30ce\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u518d\u958b\u3057\u307e\u3059\u3002 -CLI.offline-node.shortDescription="online-node"\u30b3\u30de\u30f3\u30c9\u304c\u5b9f\u884c\u3055\u308c\u308b\u307e\u3067\u3001\u30d3\u30eb\u30c9\u3092\u5b9f\u884c\u3059\u308b\u30ce\u30fc\u30c9\u306e\u4f7f\u7528\u3092\u4e00\u6642\u7684\u306b\u505c\u6b62\u3057\u307e\u3059\u3002 -CLI.wait-node-online.shortDescription=\u30ce\u30fc\u30c9\u304c\u30aa\u30f3\u30e9\u30a4\u30f3\u306b\u306a\u308b\u306e\u3092\u5f85\u3061\u307e\u3059\u3002 -CLI.wait-node-offline.shortDescription=\u30ce\u30fc\u30c9\u304c\u30aa\u30d5\u30e9\u30a4\u30f3\u306b\u306a\u308b\u306e\u3092\u5f85\u3061\u307e\u3059\u3002 BuildAuthorizationToken.InvalidTokenProvided=\u8a8d\u8a3c\u30c8\u30fc\u30af\u30f3\u304c\u9593\u9055\u3063\u3066\u3044\u307e\u3059\u3002 ManageJenkinsAction.DisplayName=Jenkins\u306e\u7ba1\u7406 @@ -338,3 +303,4 @@ Jenkins.CheckDisplayName.NameNotUniqueWarning=\u8868\u793a\u7528\u30d7\u30ed\u30 Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=\u8868\u793a\u7528\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d "{0}" \u306f\u4ed6\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001 \u533a\u5225\u3067\u304d\u306a\u3044\u3053\u3068\u304c\u3042\u308a\u307e\u3059\u3002 Jenkins.NotAllowedName="{0}" \u306f\u8a31\u53ef\u3055\u308c\u306a\u3044\u540d\u524d\u3067\u3059\u3002 +ParametersDefinitionProperty.DisplayName=\u30d3\u30eb\u30c9\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u5316 diff --git a/core/src/main/resources/hudson/model/Messages_ko.properties b/core/src/main/resources/hudson/model/Messages_ko.properties index a19ef38f9960cafa1f2054cfc4ac8dec681117b7..02b6a1d0ae76854beb671d7b3e237c36d85d2151 100644 --- a/core/src/main/resources/hudson/model/Messages_ko.properties +++ b/core/src/main/resources/hudson/model/Messages_ko.properties @@ -1 +1,4 @@ ManageJenkinsAction.DisplayName=Jenkins \uAD00\uB9AC +ParametersDefinitionProperty.DisplayName=\uC774 \uBE4C\uB4DC\uB294 \uB9E4\uAC1C\uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 + +FreeStyleProject.Description=\uC774\uAC83\uC740 Jenkins\uC758 \uC8FC\uC694 \uAE30\uB2A5\uC785\uB2C8\uB2E4. Jenkins\uC740 \uC5B4\uB290 \uBE4C\uB4DC \uC2DC\uC2A4\uD15C\uACFC \uC5B4\uB5A4 SCM(\uD615\uC0C1\uAD00\uB9AC)\uC73C\uB85C \uBB36\uC778 \uB2F9\uC2E0\uC758 \uD504\uB85C\uC81D\uD2B8\uB97C \uBE4C\uB4DC\uD560 \uAC83\uC774\uACE0, \uC18C\uD504\uD2B8\uC6E8\uC5B4 \uBE4C\uB4DC\uBCF4\uB2E4 \uB2E4\uB978 \uC5B4\uB5A4 \uAC83\uC5D0 \uC790\uC8FC \uC0AC\uC6A9\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_lt.properties b/core/src/main/resources/hudson/model/Messages_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..6be646658f3caa9280547d43bb742e7cd4427f68 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_lt.properties @@ -0,0 +1,357 @@ +AbstractBuild.BuildingRemotely=Nutol\u0119s vykdymas ma\u0161inoje {0} +AbstractBuild.BuildingOnMaster=Vykdoma pagrindin\u0117je ma\u0161inoje +AbstractBuild_Building=Vykdomas +AbstractBuild.BuildingInWorkspace=\ darbalaukyje {0} +AbstractBuild.KeptBecause=Vykdymas u\u017elaikytas d\u0117l {0}. + +AbstractItem.NoSuchJobExists=N\u0117ra tokio darbo \u201e{0}\u201c. Gal tur\u0117jote omenyje \u201e{1}\u201c? +AbstractItem.NoSuchJobExistsWithoutSuggestion=N\u0117ra tokio darbo \u201e{0}\u201c. +AbstractItem.Pronoun=Elementas +AbstractProject.AssignedLabelString_NoMatch_DidYouMean=N\u0117ra agento/debesies, atitinkan\u010dio \u0161\u012f argument\u0105. Ar tur\u0117jote omenyje \u201e{1}\u201c, o ne \u201e{0}\u201c? +AbstractProject.NewBuildForWorkspace=Planuojamas naujas vykdymas, kad b\u016bt\u0173 gautas darbalaukis. +AbstractProject.AwaitingBuildForWorkspace=Laukiama, kol vykdymas gaus darbalauk\u012f. +AbstractProject.AwaitingWorkspaceToComeOnline=Mums reikia suplanuoti nauj\u0105 vykdym\u0105, kad gautume darbalauk\u012f, bet laukiame {0}ms, tik\u0117damiesi, kad kuris nors greitai atsilaisvins +AbstractProject.Pronoun=Projektas +AbstractProject.Aborted=Nutrauktas +AbstractProject.UpstreamBuildInProgress=Auk\u0161tesnis projektas {0} jau vykdomas. +AbstractProject.DownstreamBuildInProgress=\u017demesnis projektas {0} jau vykdomas. +AbstractProject.Disabled=Vykdymas i\u0161jungtas +AbstractProject.NoBuilds=N\u0117ra egzistuojan\u010dio vykdymo. Kuriamas naujas. +AbstractProject.NoSCM=Be SCM +AbstractProject.NoWorkspace=N\u0117ra prieinam\u0173 darbalauki\u0173, tai negalima patikrinti atnaujinim\u0173. +AbstractProject.WorkspaceTitle={0} darbalaukis +AbstractProject.WorkspaceTitleOnComputer={0} darbalaukis, esantis {1} +AbstractProject.PollingABorted=SCM traukimas nutrauktas +AbstractProject.ScmAborted=SCM i\u0161traukimas nutrauktas +AbstractProject.WorkspaceOffline=Darbalaukis atjungtas. +AbstractProject.BuildPermission.Description=\ + \u0160i teis\u0117 leid\u017eia prad\u0117ti nauj\u0105 vykdym\u0105. +AbstractProject.WorkspacePermission.Description=\ + \u0160i teis\u0117 leid\u017eia i\u0161traukti darbalaukio turin\u012f, kur\u012f \ + Jenkinsas i\u0161trauk\u0117 vykdymo metu. Jei nenorite kad naudotojas prieit\u0173 prie \ + darbalaukio fail\u0173 (pvz. prie i\u0161eities kodo paimto i\u0161 SCM arba tarpini\u0173 k\u016brimo \ + rezultat\u0173) per darbalaukio nar\u0161ykl\u0119, atimkite \u0161i\u0105 teis\u0119. +AbstractProject.ExtendedReadPermission.Description=\ + \u0160i teis\u0117 leid\u017eia tik-skaitymo pri\u0117jim\u0105 prie projekto konfig\u016bracijos. \u017dinokite, \ + kad jautri vykdymo informacija, tokia kaip slapta\u017eod\u017eiai, bus \ + matoma pla\u010diai auditorijai, jei suteiksite \u0161ias teises. +AbstractProject.DiscoverPermission.Description=\ + \u0160i teis\u0117 duoda darb\u0173 tyrimo galimyb\u0119. Ma\u017eiau nei skaitymo teis\u0117, ji leid\u017eia jums \ + persi\u0173sti anoniminius naudotojus \u012f prisijungimo puslap\u012f, kai jie bando jungtis prie darbo url. \ + Be jo, jie tiesiog gaut\u0173 404 klaid\u0105 ir negal\u0117t\u0173 su\u017einoti projekt\u0173 pavadinim\u0173. +# WipeOutPermission is only visible in the security configuration if the system property +# hudson.security.WipeOutPermission is set to true +AbstractProject.WipeOutPermission.Description=\ + \u0160i teis\u0117 leid\u017eia panaikinti darbalaukio turin\u012f. +AbstractProject.CancelPermission.Description=\ + \u0160i teis\u0117 leid\u017eia panaikinti suplanuot\u0105 arba nutraukti vykdom\u0105 darb\u0105. +AbstractProject.AssignedLabelString.InvalidBooleanExpression=\ + Netinkama login\u0117 i\u0161rai\u0161ka: {0} +AbstractProject.AssignedLabelString.NoMatch=\ + N\u0117ra \u0161io priskyrimo atitinkan\u010dio agento/debesies +AbstractProject.CustomWorkspaceEmpty=Savas darbalaukis tu\u0161\u010dias. +AbstractProject.LabelLink=Etiket\u0119 {1} aptarnauja {3,choice,0#no nodes|1#1 node|1<{3} nodes}{4,choice,0#|1# and 1 cloud|1< and {4} clouds} + +Api.MultipleMatch=XPath "{0}" atitiko {1} mazgus. \ + Sukurkite XPath, kuris atitinka tik vien\u0105 mazg\u0105 arba naudokite \u201eapgaubiant\u012f\u201c u\u017eklausos parametr\u0105, kuris visus juos apgaubt\u0173 po \u0161akniniu elementu. +Api.NoXPathMatch=XPath {0} neatitiko + +BallColor.Aborted=Nutrauktas +BallColor.Disabled=I\u0161jungtas +BallColor.Failed=Nepavyko +BallColor.InProgress=Vykdomas +BallColor.NotBuilt=Nekurtas +BallColor.Pending=Laukia +BallColor.Success=S\u0117km\u0117 +BallColor.Unstable=Nestabilus + +Build.post_build_steps_failed=\u017dingsniai po k\u016brimo nepavyko +CLI.clear-queue.shortDescription=I\u0161valo vykdymo eil\u0119. +CLI.disable-job.shortDescription=I\u0161jungia darb\u0105. +CLI.enable-job.shortDescription=\u012ejungia darb\u0105. +CLI.disconnect-node.shortDescription=Atsijungia nuo mazgo. + +Computer.Caption=Agentas {0} +Computer.NoSuchSlaveExists=N\u0117ra tokio agento \u201e{0}\u201c. Ar tur\u0117jote omeny \u201e{1}\u201c? +Computer.Permissions.Title=Agentas +Computer.ExtendedReadPermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams skaityti agento konfig\u016bracij\u0105. +Computer.ConfigurePermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams konfig\u016bruoti agentus. +Computer.DeletePermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams trinti esamus agentus. +Computer.CreatePermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams kurti agentus. +Computer.ConnectPermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams prijungti agentus arba pa\u017eym\u0117ti juos prisijungusiais. +Computer.DisconnectPermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams atjungti agentus arba pa\u017eym\u0117ti juos atsijungusiais. +Computer.BuildPermission.Description=\u0160i teis\u0117 leid\u017eia naudotojams paleisti darbus agentuose savo vardu. +Computer.BadChannel=Agento mazgas atsijuntg\u0119s arba n\u0117ra nutol\u0119s kanalas (pvz. valdantis mazgas). + +ComputerSet.NoSuchSlave=N\u0117ra tokio agento: {0} +ComputerSet.SlaveAlreadyExists=Agentas pavadintas \u201e{0}\u201c jau yra +ComputerSet.SpecifySlaveToCopy=Nurodykite, kur\u012f agent\u0105 kopijuoti +ComputerSet.DisplayName=Mazgai + +Descriptor.From=(i\u0161 {0}) + +Executor.NotAvailable=N\u0117ra + +FreeStyleProject.DisplayName=Laisvo stiliaus projektas +FreeStyleProject.Description=\ + Pagrindin\u0117 Jenkinso funkcija. Jenkinsas sukurs j\u016bs\u0173 projekt\u0105, kombinuojant bet koki\u0105 SCM su bet kokia k\u016brimo sistema, \ + ir visa tai galima naudoti neb\u016btinai program\u0173 k\u016brimui. + +HealthReport.EmptyString= + +Hudson.BadPortNumber=Blogas prievado numeris {0} +Hudson.Computer.Caption=\u0160eimininkas +Hudson.Computer.DisplayName=\u0161eimininkas +Hudson.ControlCodeNotAllowed=Kontrolinis kodas neleid\u017eiamas: {0} +Hudson.DisplayName=Jenkins +Hudson.JobAlreadyExists=Jau yra darbas pavadintas \u201e{0}\u201c +Hudson.NoJavaInPath=java nerasta j\u016bs\u0173 PATH. Gal jums reikia sukonfig\u016bruoti JDKs? +Hudson.NoName=Nenurodytas pavadinimas +Hudson.NoSuchDirectory=N\u0117ra tokio aplanko: {0} +Hudson.NodeBeingRemoved=Mazgas yra \u0161alinamas +Hudson.NotAPlugin={0} n\u0117ra Jenkinso priedas +Hudson.NotJDKDir={0} nepana\u0161us \u012f JDK aplank\u0105 +Hudson.Permissions.Title=Bendras +Hudson.USER_CONTENT_README=\u0160io aplanko failas bus pasiekiami nuoroda http://server/jenkins/userContent/ +Hudson.UnsafeChar=\u201e{0}\u201c yra nesaugus simbolis +Hudson.ViewAlreadyExists=Jau yra rodinys pavadinimu \u201e{0}\u201c +Hudson.ViewName=Visi +Hudson.NotANumber=Ne skai\u010dius +Hudson.NotAPositiveNumber=Ne teigiamas skai\u010dius +Hudson.NotANonNegativeNumber=Skai\u010dius negali b\u016bti neigiamas +Hudson.NotANegativeNumber=Ne neigiamas skai\u010dius +Hudson.NotUsesUTF8ToDecodeURL=\ + J\u016bs\u0173 konteineris nenaudoja UTF-8 nuorod\u0173 dekodavimui. Jei j\u016bs naudojate ne-ASCII simbolius darb\u0173 pavadinimams ir pan., \ + tai sukels problem\u0173. \ + Daugiau informacijos apie Konteinerius ir \ + Tomcat i18n. +Hudson.AdministerPermission.Description=\ + \u0160i teis\u0117 duoda galimyb\u0119 daryti sistemos lygio konfig\u016bracijos pakeitimus, \ + taip pat vykdyti labai jautrius veiksmus, \u012fskaitant piln\u0105 prieig\u0105 prie sistemos \ + (tiek, kiek leid\u017eia operacin\u0117 sistema.) +Hudson.ReadPermission.Description=\ + Skaitymo teis\u0117s yra b\u016btinos, norint \u017ei\u016br\u0117ti daugum\u0105 Jenkinso puslapi\u0173. \ + \u0160ios teis\u0117s naudingos, jei j\u016bs nenorite, kad neautentikuoti naudotojai matyt\u0173 \ + Jenkinso puslapius: atimkite \u0161ias teises i\u0161 anoniminio naudotojo, tada \ + prid\u0117kite pseaudo-naudotoj\u0105 \u201eauthenticated\u201c ir duokite jam skaitymo teises. +Hudson.RunScriptsPermission.Description=\ + Reikia skript\u0173 paleidim\u0173 Jenkinso procese, pavyzd\u017eiui per Groovy konsol\u0119 arba Groovy CLI komand\u0105. +Hudson.NodeDescription=Pagrindinis Jenkinso mazgas + +Item.Permissions.Title=Darbas +Item.CREATE.description=Kurti nauj\u0105 darb\u0105. +Item.DELETE.description=Trinti darb\u0105. +Item.CONFIGURE.description=Keisti darbo konfig\u016bracij\u0105. +Item.READ.description=Pa\u017ei\u016br\u0117ti darb\u0105. (Galite u\u017edrausti \u0161i\u0105 teis\u0119 bet leisti Tyrin\u0117jim\u0105, kad priverstum\u0117te anonimin\u012f naudotoj\u0105 prisijungti.) + +Job.AllRecentBuildFailed=Visi paskutiniai vykdymai nepavyko. +Job.BuildStability=Vykdymo stabilumas: {0} +Job.NOfMFailed={0} i\u0161 paskutini\u0173 {1} vykdym\u0173 nepavyko. +Job.NoRecentBuildFailed=Pavyko visi paskutiniai vykdymai. +Job.Pronoun=Projektas +Job.minutes=minut\u0117s + +Job.you_must_use_the_save_button_if_you_wish=J\u016bs privalote naudoti Save mygtuk\u0105, jei norite pervadinti darb\u0105. +Label.GroupOf=grup\u0117 i\u0161 {0} +Label.InvalidLabel=netinkama etiket\u0117 +Label.ProvisionedFrom=Apr\u016bpinta i\u0161 {0} +ManageJenkinsAction.DisplayName=Tvarkyti Jenkins\u0105 +MultiStageTimeSeries.EMPTY_STRING= +Queue.AllNodesOffline=Visi etiket\u0117s \u201e{0}\u201c mazgai yra atsijung\u0119 +Queue.LabelHasNoNodes=N\u0117ra mazg\u0173 su etikete \u201e{0}\u201c +Queue.BlockedBy=Blokuotojas: {0} +Queue.HudsonIsAboutToShutDown=Jenkinsas ruo\u0161iasi i\u0161sijungti +Queue.InProgress=Jau vyksta vykdymas +Queue.InQuietPeriod=Tyliame periode. Baigsis po {0} +Queue.NodeOffline={0} yra atsijung\u0119s +Queue.Unknown=??? +Queue.WaitingForNextAvailableExecutor=Laukiama kito prieinamo vykdytojo +Queue.WaitingForNextAvailableExecutorOn=Laukiama kito prieinamo vykdytojo, esan\u010dio {0} +Queue.init=Atstatoma vykdymo eil\u0117 + +ResultTrend.Aborted=Nutraukta +ResultTrend.Failure=Nes\u0117km\u0117 +ResultTrend.Fixed=Pataisyta +ResultTrend.NotBuilt=Nevykdyta +ResultTrend.NowUnstable=Dabar nestabilus +ResultTrend.StillFailing=Vis dar nepavyksta +ResultTrend.StillUnstable=Vis dar nestabilus +ResultTrend.Success=S\u0117km\u0117 +ResultTrend.Unstable=Nestabilus +Run._is_waiting_for_a_checkpoint_on_={0} laukia tikrinimom ta\u0161ko {1} +Run.BuildAborted=Vykdymas buvo nutrauktas +Run.MarkedExplicitly=\u0160is \u012fra\u0161as buvo konkre\u010diai pa\u017eym\u0117tas i\u0161saugojimui. +Run.Permissions.Title=Vykdyti +Run.running_as_=Vykdomas kaip {0} +Run.UnableToDelete=Nepavyksta i\u0161trinti {0}: {1} +Run.DeletePermission.Description=\ + \u0160i teis\u0117 leid\u017eia naudotojams rankiniu b\u016bdu i\u0161trinti konkre\u010dius vykdymus i\u0161 vykdym\u0173 istorijos. +Run.UpdatePermission.Description=\ + \u0160i teis\u0117 leid\u017eia naudotojams atnaujinti vykdymo apra\u0161ym\u0105 ir kitas savybes, \ + pavyzd\u017eiui palikti pastabas apie nes\u0117km\u0117s prie\u017eastis. +Run.ArtifactsPermission.Description=\ + \u0160i teis\u0117 duoda galimyb\u0119 i\u0161traukti rezultatus, sukurtus vykdymo metu. \ + Jei nenorite, kad naudotojas prieit\u0173 prie rezultat\u0173, galite t\u0105 padaryti \ + at\u0161aukdami \u0161i\u0105 teis\u0119. +Run.InProgressDuration={0} ir vis dar vyksta +Run.NotStartedYet=Dar neprad\u0117tas +Run.ArtifactsBrowserTitle=Rezultatai i\u0161 {0} {1} + +Run.Summary.Stable=stabilus +Run.Summary.Unstable=nestabilus +Run.Summary.Aborted=nutrauktas +Run.Summary.NotBuilt=nevykdytas +Run.Summary.BackToNormal=v\u0117l normalu +Run.Summary.BrokenForALongTime=sul\u016b\u017e\u0119s jau ilg\u0105 laik\u0105 +Run.Summary.BrokenSinceThisBuild=sul\u016b\u017e\u0119s nuo \u0161io vykdymo +Run.Summary.BrokenSince=sul\u016b\u017e\u0119s nuo vykdymo {0} +Run.Summary.Unknown=? + +Slave.InvalidConfig.Executors=Netinkama agento {0} konfig\u016bracija. Netinkamas vykdytoj\u0173 skai\u010dius. +Slave.InvalidConfig.NoName=Netinkama agento konfig\u016bracija. Tu\u0161\u010dias pavadinimas +Slave.InvalidConfig.NoRemoteDir=Netinkama agento {0} konfig\u016bracija. Nenurodytas nutol\u0119s aplankas +Slave.Launching={0} Paleid\u017eiamas agentas +Slave.Network.Mounted.File.System.Warning=Ar tikrai norite naudoti per tinkl\u0105 prijungt\u0105 fail\u0173 sistem\u0105 kaip FS \u0161ank\u012f? Pasteb\u0117tina, kad \u0161is aplankas neb\u016btinai turi b\u016bti matomas pagrindiniam mazgui. +Slave.Remote.Director.Mandatory=Nutol\u0119s aplankas yra privalomas +Slave.Terminated={0} agentas buvo nutrauktas +Slave.Remote.Relative.Path.Warning=Ar tikrai norite naudoti santykin\u012f keli\u0105, kaip FS \u0161akn\u012f? Pasteb\u0117tina, kad santykiniams \ + keliams reikia, kad j\u016bs u\u017etikrintum\u0117te, kad parinktas paleid\u0117jas u\u017etikrina pastov\u0173 einam\u0105j\u012f darbin\u012f aplank\u0105. Primygtinai \ + rekomenduojame naudoti absoliut\u0173 keli\u0105. +Slave.UnableToLaunch=Nepavyksta paleisti agento skirto {0}{1} +Slave.UnixSlave=Tai Unix agentas +Slave.WindowsSlave=Tai Windows agentas + +TopLevelItemDescriptor.NotApplicableIn={0} elementas nepritaikomi {1} r\u0117muose + +UpdateCenter.DownloadButNotActivated=S\u0117kmingai atsi\u0173stas. Bus aktyvuotas per kit\u0105 paleidim\u0105 +UpdateCenter.n_a=N\u0117ra +View.Permissions.Title=Rodinys +View.CreatePermission.Description=\ + \u0160i teis\u0117 leid\u017eia naudotojams kurti rodinius. +View.DeletePermission.Description=\ + \u0160i teis\u0117 leid\u017eia naudotojams trinti esamus rodinius. +View.ConfigurePermission.Description=\ + \u0160i teis\u0117 leid\u017eia naudotojams keisti rodini\u0173 konfig\u016bracij\u0105. +View.ReadPermission.Description=\ + \u0160i teis\u0117 leid\u017eia naudotojams \u017ei\u016br\u0117ti rodinius (rei\u0161kia bendr\u0105 skaitymo prieig\u0105). +View.MissingMode=Nenurodytas rodinio tipas + +UpdateCenter.Status.CheckingInternet=Tikrinamas prisijungimas prie interneto +UpdateCenter.Status.CheckingJavaNet=Tikrinamas prisijungimas prie atnaujinim\u0173 centro +UpdateCenter.Status.Success=S\u0117km\u0117 +UpdateCenter.Status.UnknownHostException=\ + Nepavyko i\u0161spr\u0119sti stoties pavadinimo {0}. \ + Gal jums reikia sukonfig\u016bruoti HTTP \u0161liuz\u0105? +UpdateCenter.Status.ConnectionFailed=\ + Nepavyko prisijungti prie {0}. \ + Gal jums reikia sukonfig\u016bruoti HTTP \u0161liuz\u0105? +UpdateCenter.init=Inicializuojamas atnaujinim\u0173 centras +UpdateCenter.PluginCategory.android=Android k\u016brimas +UpdateCenter.PluginCategory.builder=K\u016brimo \u012frankiai +UpdateCenter.PluginCategory.buildwrapper=K\u016brimo aplankas +UpdateCenter.PluginCategory.cli=Komandin\u0117s eilut\u0117s s\u0105saja +UpdateCenter.PluginCategory.cloud=Debes\u0173 tiek\u0117jai +UpdateCenter.PluginCategory.cluster=Klasterio valdymas ir paskirstytas vykdymas +UpdateCenter.PluginCategory.database=Duombaz\u0117 +UpdateCenter.PluginCategory.deployment=K\u016brimas +UpdateCenter.PluginCategory.devops=DevOps +UpdateCenter.PluginCategory.dotnet=.NET k\u016brimas +UpdateCenter.PluginCategory.external=I\u0161orin\u0117 svetain\u0117/\u012franki\u0173 integracija +UpdateCenter.PluginCategory.groovy-related=Groovy-susij\u0119s +UpdateCenter.PluginCategory.ios=iOS k\u016brimas +UpdateCenter.PluginCategory.library=Bibliotek\u0173 priedai (naudojami kit\u0173 pried\u0173) +UpdateCenter.PluginCategory.listview-column=Rodinio s\u0105ra\u0161o stulpeliai +UpdateCenter.PluginCategory.maven=Maven +UpdateCenter.PluginCategory.misc=\u012evair\u016bs +UpdateCenter.PluginCategory.notifier=Vykdymo prane\u0161ikliai +UpdateCenter.PluginCategory.page-decorator=Puslapi\u0173 dekoratoriai +UpdateCenter.PluginCategory.parameter=Vykdymo parametrai +UpdateCenter.PluginCategory.post-build=Kiti veiksmo po vykdymo +UpdateCenter.PluginCategory.python=Python k\u016brimas +UpdateCenter.PluginCategory.report=Vykdymo ataskaitos +UpdateCenter.PluginCategory.ruby=Ruby k\u016brimas +UpdateCenter.PluginCategory.runcondition=Vykdymo s\u0105lygos, kurias naudoja Vykdymo s\u0105lyg\u0173 priedas +UpdateCenter.PluginCategory.scala=Scala k\u016brimas +UpdateCenter.PluginCategory.scm=I\u0161eities kodo valdymas +UpdateCenter.PluginCategory.scm-related=Susij\u0119 su i\u0161eities kodo valdymu +UpdateCenter.PluginCategory.security=Saugumas +UpdateCenter.PluginCategory.slaves=Agent\u0173 paleid\u0117jai ir valdytojai +UpdateCenter.PluginCategory.test=Testavimas +UpdateCenter.PluginCategory.trigger=Vykdymo trigeriai +UpdateCenter.PluginCategory.ui=Naudotojo s\u0105saja +UpdateCenter.PluginCategory.upload=Rezultat\u0173 \u012fk\u0117l\u0117jai +UpdateCenter.PluginCategory.user=Autentikacija ir naudotoj\u0173 valdymas +UpdateCenter.PluginCategory.view=Rodiniai +UpdateCenter.PluginCategory.must-be-labeled=Nekategorizuoti +UpdateCenter.PluginCategory.unrecognized=\u012evair\u016bs ({0}) + +Permalink.LastBuild=Paskutinis vykdymas +Permalink.LastStableBuild=Paskutinis stabilus vykdymas +Permalink.LastUnstableBuild=Paskutinis nestabilus vykdymas +Permalink.LastUnsuccessfulBuild=Paskutinis nes\u0117kmingas vykdymas +Permalink.LastSuccessfulBuild=Paskutinis s\u0117kmingas vykdymas +Permalink.LastFailedBuild=Paskutinis nepavyk\u0119s vykdymas +Permalink.LastCompletedBuild=Paskutinis baigtas vykdymas + +ParameterAction.DisplayName=Parametrai +ParametersDefinitionProperty.DisplayName=\u0160is projektas yra parametrizuotas +StringParameterDefinition.DisplayName=Eilut\u0117s parametras +TextParameterDefinition.DisplayName=Keli\u0173 eilu\u010di\u0173 parametras +FileParameterDefinition.DisplayName=Failo parametras +BooleanParameterDefinition.DisplayName=Loginis parametras +ChoiceParameterDefinition.DisplayName=Pasirinkimo parametras +ChoiceParameterDefinition.MissingChoices=Reikalauja pasirinkim\u0173. +RunParameterDefinition.DisplayName=Paleidimo parametras +PasswordParameterDefinition.DisplayName=Slapta\u017eod\u017eio parametras + +Node.BecauseNodeIsReserved={0} yra rezervuotas darbams su atitinkan\u010dia etiket\u0117s i\u0161rai\u0161ka +Node.BecauseNodeIsNotAcceptingTasks={0} nepriima u\u017eduo\u010di\u0173 +Node.LabelMissing={0} neturi etiket\u0117s {1} +Node.LackingBuildPermission={0} neturi teis\u0117s b\u016bti paleistas {1} +Node.Mode.NORMAL=Naudoti \u0161\u012f mazg\u0105 kiek tik galima +Node.Mode.EXCLUSIVE=Vykdyti tik darbus su \u0161\u012f mazg\u0105 atitinkan\u010dia etikete + +ListView.DisplayName=S\u0105ra\u0161o rodinys + +MyView.DisplayName=Mano rodinys + +LoadStatistics.Legends.DefinedExecutors=Nurodyti vykdytojai +LoadStatistics.Legends.OnlineExecutors=Prisijung\u0119 vykdytojai +LoadStatistics.Legends.ConnectingExecutors=Prisijungiantys vykdytojai +LoadStatistics.Legends.TotalExecutors=Viso vykdytoj\u0173 +LoadStatistics.Legends.BusyExecutors=U\u017eimt\u0173 vykdytoj\u0173 +LoadStatistics.Legends.IdleExecutors=Neu\u017eimt\u0173 vykdytoj\u0173 +LoadStatistics.Legends.AvailableExecutors=Prieinam\u0173 vykdytoj\u0173 +LoadStatistics.Legends.QueueLength=Eil\u0117s ilgis + +Cause.LegacyCodeCause.ShortDescription=\u0160\u012f darb\u0105 prad\u0117jo senas kodas. N\u0117ra prie\u017easties informacijos +Cause.UpstreamCause.ShortDescription=Prad\u0117ta i\u0161 auk\u0161tesnio projekto \u201e{0}\u201c vykdymo numerio {1} +Cause.UpstreamCause.CausedBy=originali prie\u017eastis: +Cause.UserCause.ShortDescription=Prad\u0117jo naudotojas {0} +Cause.UserIdCause.ShortDescription=Prad\u0117jo naudotojas {0} +Cause.RemoteCause.ShortDescription=Prad\u0117jo nutol\u0119s mazgas {0} +Cause.RemoteCause.ShortDescriptionWithNote=Prad\u0117jo nutol\u0119s mazgas {0} su pastaba: {1} + +ProxyView.NoSuchViewExists=Neegzistuoja globalus rodinys {0} +ProxyView.DisplayName=\u012etraukti global\u0173 rodin\u012f + +MyViewsProperty.DisplayName=Mano rodiniai +MyViewsProperty.GlobalAction.DisplayName=Mano rodiniai +MyViewsProperty.ViewExistsCheck.NotExist=N\u0117ra rodinio pavadinimu {0} +MyViewsProperty.ViewExistsCheck.AlreadyExists=Rodinys pavadinimu {0} jau yra + +CLI.restart.shortDescription=I\u0161 naujo paleisti Jenkins\u0105 +CLI.safe-restart.shortDescription=Saugiai i\u0161 naujo paleisti Jenkins\u0105 +CLI.keep-build.shortDescription=Pa\u017eym\u0117ti vykdym\u0105 am\u017einam saugojimui. +CLI.reload-configuration.shortDescription=I\u0161mesti vius \u012f atmint\u012f \u012fkeltus duomenis ir i\u0161 naujo visk\u0105 \u012fkelti i\u0161 fail\u0173 sistemos. Naudinga, jei pakeit\u0117te konfig\u016bracijos failus tiesiai diske. + +BuildAuthorizationToken.InvalidTokenProvided=Pateikta neteisinga \u017eyma. + +Jenkins.CheckDisplayName.NameNotUniqueWarning=Rodomas pavadinimas \u201e{0}\u201c naudojamas kaip darbo pavadinimas ir gali b\u016bti keist\u0173 paie\u0161kos rezultat\u0173 prie\u017eastis. +Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=Rodomas pavadinimas \u201e{0}\u201c jau naudojamas kitame darbe tod\u0117l gali sukelti u\u017edelsim\u0105 ir sumai\u0161t\u012f. + +Jenkins.NotAllowedName=\u201e{0}\u201c - neleid\u017eiamas pavadinimas +Jenkins.IsRestarting=Jenkinsas paleid\u017eiamas i\u0161 naujo + +User.IllegalUsername=\u201e{0}\u201c neleid\u017eiamas kaip naudotojo pavadinimas d\u0117l saugumo sumetim\u0173. +User.IllegalFullname=\u201e{0}\u201c neleid\u017eiamas kaip pilnas vardas d\u0117l saugumo sumetim\u0173. diff --git a/core/src/main/resources/hudson/model/Messages_nb_NO.properties b/core/src/main/resources/hudson/model/Messages_nb_NO.properties index 02c96d98304627acf6b57ee6e4684d224370d4c1..d1098629e62d3ce266b72b25dea42ac1f6dac149 100644 --- a/core/src/main/resources/hudson/model/Messages_nb_NO.properties +++ b/core/src/main/resources/hudson/model/Messages_nb_NO.properties @@ -1,2 +1,4 @@ ManageJenkinsAction.DisplayName=Konfigurer Jenkins -ManageJenkinsAction.DisplayName=Konfigurer Jenkins +ParametersDefinitionProperty.DisplayName=Denne build har parametre + +FreeStyleProject.Description=Dette er en sentral egenskap ved Jenkins. Jenkins bygger dine prosjekter, kombinerer SCM (Source Control Management - Kildekodekontrollsystem ) med forskjellige byggsystemer og denne kan ogs\u00E5 brukes til mer enn bare \u00E5 bygge applikasjoner. diff --git a/core/src/main/resources/hudson/model/Messages_nl.properties b/core/src/main/resources/hudson/model/Messages_nl.properties index 88b53d8f21584d8764007afd43313048e59fe31e..3db4e11f0b59c048932e9fb29611a3a349127d01 100644 --- a/core/src/main/resources/hudson/model/Messages_nl.properties +++ b/core/src/main/resources/hudson/model/Messages_nl.properties @@ -26,9 +26,7 @@ AbstractBuild.KeptBecause=Weerhouden omwille van {0} AbstractProject.NewBuildForWorkspace=Om een werkplaats te krijgen wordt een nieuwe bouwpoging gepland. AbstractProject.Pronoun=Project AbstractProject.Aborted=Afgebroken -AbstractProject.BuildInProgress=Bouwpoging #{0} is reeds actief {1} AbstractProject.Disabled=Bouwen gedeactiveerd -AbstractProject.ETA= (einde voorzien op:{0}) AbstractProject.NoSCM=Geen versiebeheersysteem beschikbaar AbstractProject.NoWorkspace=Er is geen werkplaats beschikbaar. Ophalen van wijzigingen is dus onmogelijk. AbstractProject.PollingABorted=Contact met versiebeheersysteem werd afgebroken. @@ -46,12 +44,12 @@ BallColor.Pending=In afwachting BallColor.Success=Succes BallColor.Unstable=Onstabiel -Computer.Caption=Slaaf {0} Executor.NotAvailable=Niet beschikbaar FreeStyleProject.DisplayName=Bouw een vrije stijl type software project +FreeStyleProject.Description=Dit is de basisfunctionaliteit van Jenkins. Bij dit type project kun je gebruik maken van een willekeurige combinatie van versiebeheer- en bouwsysteem. Je zou Jenkins zelfs kunnen gebruiken voor andere zaken dan het bouwen van software. Hudson.BadPortNumber=Verkeerd poortnummer {0} Hudson.Computer.Caption=Hoofdnode @@ -88,19 +86,11 @@ Run.MarkedExplicitly=Expliciet gemarkeerd ter opbouw van historiek Run.Permissions.Title=Starten Run.UnableToDelete=Kan {0} niet verwijderen: {1} -Slave.InvalidConfig.Executors=Ongeldige configuratie voor slaaf {0}: Ongeldig aantal uitvoerders. -Slave.InvalidConfig.NoName=Ongeldige configuratie voor slaaf. Geen naam gespecificeerd. -Slave.InvalidConfig.NoRemoteDir=Ongeldige configuratie voor slaaf {0}. Geen pad op afstand opgegeven. -Slave.Launching={0} Slaaf node wordt gestart. -Slave.Terminated={0} Slaaf node werd be\u00ebindigd -Slave.UnableToLaunch=Kon de slaaf node niet starten voor {0} {1} -Slave.UnixSlave=Dit is een Unix slaaf node -Slave.WindowsSlave=Dit is een Windows slaaf node View.Permissions.Title=Tonen Permalink.LastBuild=Laatste bouwpoging Permalink.LastStableBuild=Laatste stabiele bouwpoging Permalink.LastSuccessfulBuild=Laatste succesvolle bouwpoging Permalink.LastFailedBuild=Laatst gefaalde bouwpoging -AbstractProject.BuildNow=Start nu een bouwpoging ManageJenkinsAction.DisplayName=Beheer Jenkins +ParametersDefinitionProperty.DisplayName=Deze bouwpoging is geparametriseerd diff --git a/core/src/main/resources/hudson/model/Messages_pl.properties b/core/src/main/resources/hudson/model/Messages_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..705ca647da36318a8238728c629fb7cda74c47f6 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_pl.properties @@ -0,0 +1,81 @@ +# The MIT License +# +# Copyright (c) 2004-2016, Sun Microsystems, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ParametersDefinitionProperty.DisplayName=To zadanie jest sparametryzowane +StringParameterDefinition.DisplayName=Tekst +TextParameterDefinition.DisplayName=Tekst wielolinijkowy +FileParameterDefinition.DisplayName=Plik +BooleanParameterDefinition.DisplayName=Warto\u015B\u0107 logiczna +ChoiceParameterDefinition.DisplayName=Lista wyboru +ChoiceParameterDefinition.MissingChoices=Nie podano warto\u015Bci +PasswordParameterDefinition.DisplayName=Has\u0142o + +ManageJenkinsAction.DisplayName=Zarz\u0105dzaj Jenkinsem + +Job.AllRecentBuildFailed=Wszystkie ostatnie zadania nie powiod\u0142y si\u0119. +Job.BuildStability=Stabilno\u015B\u0107 zada\u0144: {0} +Job.NOfMFailed={0} spo\u015Br\u00F3d {1} ostatnich zada\u0144 nie powiod\u0142o si\u0119. +Job.NoRecentBuildFailed=Brak ostatnich zada\u0144 zako\u0144czonych niepowodzeniem. +AbstractProject.Pronoun=Projekt +AbstractItem.Pronoun=Projekt + +AbstractProject.WorkspaceTitle=Przestrze\u0144 robocza {0} +AbstractProject.WorkspaceTitleOnComputer=Przestrze\u0144 robocza {0} na {1} + +BallColor.Aborted=Przerwany +BallColor.Disabled=Zablokowany +BallColor.Failed=Nie powi\u00F3d\u0142 si\u0119 +BallColor.InProgress=W trakcie +BallColor.NotBuilt=Brak uruchomie\u0144 +BallColor.Pending=W oczekiwaniu +BallColor.Success=Sukces +BallColor.Unstable=Niestabilny + +Permalink.LastBuild=Ostatnie zadanie +Permalink.LastStableBuild=Ostatnie stabilne zadanie +Permalink.LastUnstableBuild=Ostatnie niestabilne zadanie +Permalink.LastUnsuccessfulBuild=Ostatnie niepomy\u015Blne zadanie +Permalink.LastSuccessfulBuild=Ostatnie pomy\u015Blne zadanie +Permalink.LastFailedBuild=Ostatnie niepomy\u015Blne zadanie +Permalink.LastCompletedBuild=Ostatnie zako\u0144czone zadanie + +Run.Summary.Stable=stabilny +Run.Summary.Unstable=niestabilny +Run.Summary.Aborted=przerwany +Run.Summary.NotBuilt=brak zada\u0144 +Run.Summary.BackToNormal=ponownie stabilny +Run.Summary.BrokenForALongTime=nieudany od dawna +Run.Summary.BrokenSinceThisBuild=nieudany od tego zadania +Run.Summary.BrokenSince=nieudany od zadania {0} +Run.Summary.Unknown=? + +UpdateCenter.DownloadButNotActivated=Pobrana pomy\u015Blnie. Zostanie w\u0142\u0105czona podczas ponownego uruchomienia Jenkinsa +UpdateCenter.Status.CheckingInternet=Sprawdzanie po\u0142\u0105czenia z Internetem +UpdateCenter.Status.CheckingJavaNet=Sprawdzanie po\u0142\u0105czenia z centrum aktualizacji +UpdateCenter.Status.Success=Zako\u0144czono pomy\u015Blnie + +MyViewsProperty.DisplayName=Moje widoki +MyViewsProperty.GlobalAction.DisplayName=Moje widoki + +FreeStyleProject.Description=To jest podstawowa funkcja Jenkinsa. Jenkins stworzy projekt \u0142\u0105cz\u0105cy dowolny SCM z dowolnym systemem buduj\u0105cym, mo\u017Ce to by\u0107 r\u00F3wnie\u017C wykorzystane do czego\u015B innego ni\u017C budowanie oprogramowania. +# Freestyle project +FreeStyleProject.DisplayName=Og\u00F3lny projekt diff --git a/core/src/main/resources/hudson/model/Messages_pt_BR.properties b/core/src/main/resources/hudson/model/Messages_pt_BR.properties index b84852a2be0804f8e3423f22bb672045b23769c9..4ed07299f1ed91f75daa52fd131ca2bcbbc322d2 100644 --- a/core/src/main/resources/hudson/model/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/model/Messages_pt_BR.properties @@ -25,9 +25,7 @@ AbstractBuild.KeptBecause=mantido por causa de {0} AbstractProject.Pronoun=Projeto AbstractProject.Aborted=Abortado -AbstractProject.BuildInProgress=A builds #{0} j\u00e1 est\u00e1 em progresso{1} AbstractProject.Disabled=builds desabilitada -AbstractProject.ETA=\ (ETA:{0}) AbstractProject.NoSCM=Nenhum SCM AbstractProject.NoWorkspace=Nenhum workspace est\u00e1 dispon\u00edvel, assim n\u00e3o pode checar por atualiza\u00e7\u00f5es. AbstractProject.PollingABorted=Pesquisa SCM abortada @@ -46,12 +44,12 @@ BallColor.Pending=Pendente BallColor.Success=Sucesso BallColor.Unstable=Inst\u00e1vel -Computer.Caption=Slave {0} Executor.NotAvailable=N/D FreeStyleProject.DisplayName=Construir um projeto de software free-style +FreeStyleProject.Description=Esta \u00e9 a central de funcionalidades do Jenkins. Ele construir\u00e1 seu projeto,e voc\u00ea pode combinar qualquer SCM com qualquer sistema de builds, e ele at\u00e9 mesmo pode ser usado para outras jobs diferentes de builds de software. Hudson.BadPortNumber=N\u00famero de porta ruim {0} Hudson.Computer.Caption=Master @@ -87,14 +85,6 @@ Run.MarkedExplicitly=Explicitamente marcada para manter o registro Run.Permissions.Title=Executar Run.UnableToDelete=N\u00e3o foi poss\u00edvel excluir {0}: {1} -Slave.InvalidConfig.Executors=Configura\u00e7\u00e3o de slave inv\u00e1lida para {0}. Inv\u00e1lido # de executores. -Slave.InvalidConfig.NoName=Configura\u00e7\u00e3o de slave inv\u00e1lida. O nome est\u00e1 vazio -Slave.InvalidConfig.NoRemoteDir=Configura\u00e7\u00e3o de slave inv\u00e1lida para {0}. Nenhum diret\u00f3rio remoto foi informado -Slave.Launching={0} Iniciando agente slave -Slave.Terminated={0} Agente slave foi encerrado -Slave.UnableToLaunch=N\u00e3o foi poss\u00edvel iniciar o agente slave para {0}{1} -Slave.UnixSlave=Este \u00e9 um slave Unix -Slave.WindowsSlave=Este \u00e9 um slave Windows View.Permissions.Title=Vis\u00e3o Permalink.LastBuild=\u00daltimo build @@ -125,8 +115,6 @@ MyViewsProperty.GlobalAction.DisplayName= Minhas views Run.UpdatePermission.Description=Essa permiss\u00e3o permite aos usu\u00e1rios atualizarem a descri\u00e7\u00e3o e outras propriedades do build # String Parameter StringParameterDefinition.DisplayName=Par\u00e2metro string -# Utilize this slave as much as possible -Node.Mode.NORMAL=Utilize este slave, tanto quanto poss\u00edvel # Global view {0} does not exist ProxyView.NoSuchViewExists= Vis\u00e3o global {0} n\u00e3o existe # External Site/Tool Integrations @@ -147,8 +135,6 @@ UpdateCenter.Status.Success=Sucesso UpdateCenter.init=Iniciando o Update Center # Parameters ParameterAction.DisplayName=Par\u00e2metros -# Reconnect to a node -CLI.connect-node.shortDescription=Reconectar ao n\u00f3 # nodes ComputerSet.DisplayName=N\u00f3s # \ @@ -158,12 +144,8 @@ Run.DeletePermission.Description=Apagar builds espec\u00edficos do hist\u00f3rio Run.Summary.BrokenForALongTime=Quebrado h muito tempo # Safely restart Jenkins CLI.safe-restart.shortDescription=Seguro reiniciar o Jenkins -# Quiet down Jenkins, in preparation for a restart. Don''t start any builds. -CLI.quiet-down.shortDescription=Desativar em modo silencioso, em prepara\u00e7\u00e3o para o rein\u00edcio. N\u00e3o come\u00e7e nenhum build. # Include a global view ProxyView.DisplayName=Incluir uma vis\u00e3o global -# Specify which slave to copy -ComputerSet.SpecifySlaveToCopy=Especifica para qual slave copiar # Number may not be negative Hudson.NotANonNegativeNumber=N\u00famero n\u00e3o pode ser negativo # No existing build. Scheduling a new one. @@ -187,12 +169,10 @@ UpdateCenter.PluginCategory.builder=Ferramentas de build # File Parameter FileParameterDefinition.DisplayName=Par\u00e2metros de arquivo # {0} {0,choice,0#tests are|1#test is|1Failed to connect to {0}. \ # Perhaps you need to configure HTTP proxy? UpdateCenter.Status.ConnectionFailed=Erro ao conectar {0} / # Maven UpdateCenter.PluginCategory.maven=Maven -# Slave -Computer.Permissions.Title=Slave -# Resume using a node for performing builds, to cancel out the earlier "offline-node" command. -CLI.online-node.shortDescription=Continuar usando um n\u00f3 para realizar os builds # Artifact Uploaders UpdateCenter.PluginCategory.upload=Carregadores de artefatos # Last unstable build @@ -374,7 +329,6 @@ CLI.enable-job.shortDescription=Habilita um job # ? Run.Summary.Unknown=? # Parameters -ParametersDefinitionProperty.DisplayName=Par\u00e2metros # \ # This permission grants the ability to start a new build. AbstractProject.BuildPermission.Description=Permiss\u00e3o para iniciar um novo build @@ -386,7 +340,6 @@ Label.GroupOf=Grupo de {0} Queue.AllNodesOffline=Todos os rotulos ''{0}'' est\u00e3o offline. # Busy executors LoadStatistics.Legends.BusyExecutors=Executores ocupados. -AbstractProject.BuildNow=Construir agora ManageJenkinsAction.DisplayName=Gerenciar Jenkins # Workspace of {0} AbstractProject.WorkspaceTitle=Workspace de {0} @@ -394,8 +347,6 @@ AbstractProject.WorkspaceTitle=Workspace de {0} UpdateCenter.PluginCategory.listview-column=Lista as colunas da view # {0} is waiting for a checkpoint on {1} Run._is_waiting_for_a_checkpoint_on_={0} est\u00e1 aguardando por um checkpoint em {1} -# Wait for a node to become offline. -CLI.wait-node-offline.shortDescription=Aguarde por um n\u00f3 ficar offline. # \ in workspace {0} AbstractBuild.BuildingInWorkspace=\ no workspace {0} # Jenkins is restarting @@ -412,10 +363,6 @@ AbstractBuild_Building=Construindo Item.CREATE.description=Cria um novo job. # The remote root must be an absolute path. Slave.the_remote_root_must_be_an_absolute_path=A raiz remota deve ser um caminho absoluto. -# This permission allows users to disconnect slaves or mark slaves as temporarily offline. -Computer.DisconnectPermission.Description=Esta permiss\u00e3o deixa que usu\u00e1rios desconectem slaves ou os marque como temporariamente offline. -# This permission allows users to create slaves. -Computer.CreatePermission.Description=Exta permiss\u00e3o deixa usu\u00e1rios criarem slaves. # See a job. (You may deny this permission but allow Discover to force an anonymous user to log in to see the job.) Item.READ.description=Ver um job. (Voc\u00ea pode impedir essa permiss\u00e3o mas permitir Discover para forcar um usu\u00e1rio an\u00f4nimo a logar para ver o job) # This permission grants the ability to retrieve the artifacts produced by \ @@ -426,8 +373,6 @@ Run.ArtifactsPermission.Description=Esta permiss\u00e3o permite a habilidade de revogar esta permiss\u00e3o. # Invalid boolean expression: {0} AbstractProject.AssignedLabelString.InvalidBooleanExpression=Espress\u00e3o booleana inv\u00e1lida: {0} -# This permission allows users to connect slaves or mark slaves as online. -Computer.ConnectPermission.Description=Esta permiss\u00e3o deixa que usu\u00e1rios conectem slaves ou os marque como online. # originally caused by: Cause.UpstreamCause.CausedBy=originalmente causado por: # Invalid token provided. @@ -436,12 +381,8 @@ BuildAuthorizationToken.InvalidTokenProvided=Token inv\u00e1lido fornecido. TextParameterDefinition.DisplayName=Par\u00e2metro de texto # Downloaded Successfully. Will be activated during the next boot UpdateCenter.DownloadButNotActivated=Download finalizado com sucesso. Ser\u00e1 ativado no pr\u00f3ximo boot -# There\u2019s no slave/cloud that matches this assignment. Did you mean \u2018{1}\u2019 instead of \u2018{0}\u2019? -AbstractProject.AssignedLabelString_NoMatch_DidYouMean=N\u00e3o h\u00e1 um slave ou n\u00favem que combine com esta atribui\u00e7\u00e3o. Voc\u00ea quis dizer \u2018{1}\u2019 ao inv\u00e9s de \u2018{0}\u2019? # {0} doesn\u2019t have a permission to run on {1} Node.LackingBuildPermission={0} n\u00e3o tem permiss\u00e3o para executar em {1} -# This permission allows users to read slave configuration. -Computer.ExtendedReadPermission.Description=Esta permiss\u00e3o deixa usu\u00e1rios lerem as configura\u00e7\u00f5es dos slaves. # Not built ResultTrend.NotBuilt=N\u00e3o constru\u00eddo # There are no nodes with the label \u2018{0}\u2019 @@ -482,20 +423,12 @@ ResultTrend.Failure=Falha AbstractProject.WipeOutPermission.Description=Esta permiss\u00e3o deixa que seja eleminado o conte\u00fado de um workspace. # Requires Choices. ChoiceParameterDefinition.MissingChoices=Exige escolhas. -# This permission allows users to run jobs as them on slaves. -Computer.BuildPermission.Description=Esta permiss\u00e3o deixa que usu\u00e1rios executem jobs em slaves. -# Reloads this job from disk. -CLI.reload-job.shortDescription=Recarrega este job do disco. -# No such slave "{0}" exists. Did you mean "{1}"? -Computer.NoSuchSlaveExists=N\u00e3o existe o slave {0}. Voc\u00ea quis dizer "{1}"? # Aborted ResultTrend.Aborted=Abortado # This permission allows users to see views (implied by generic read access). View.ReadPermission.Description=Esta permiss\u00e3o deixa que usu\u00e1rios vejam views (inpl\u00edcito pela permiss\u00e3o gen\u00e9rica de leitura). # "{0}" is not allowed name Jenkins.NotAllowedName="{0}" n\u00e3o \u00e9 um nome permitido -# There's no slave/cloud that matches this assignment -AbstractProject.AssignedLabelString.NoMatch=N\u00e3o h\u00e1 um slave/n\u00favem que combine com esta atribui\u00e7\u00e3o # Workspace of {0} on {1} AbstractProject.WorkspaceTitleOnComputer=Workspace {0} em {1} # This permission grants the ability to cancel a scheduled, or abort a running, build. @@ -504,14 +437,9 @@ AbstractProject.CancelPermission.Description=Esta permiss\u00e3o deixa que seja Jenkins.CheckDisplayName.NameNotUniqueWarning=O nome de exibi\u00e7\u00e3o "{0}", \u00e9 usado por um job e pode causar confus\u00e3o nos resultados da pesquisa. # Custom workspace is empty. AbstractProject.CustomWorkspaceEmpty=O workspace customizado est\u00e1 vazio. -# Wait for a node to become online. -CLI.wait-node-online.shortDescription=Aguarda por um n\u00f3 que se torne online -# Slaves in label: {2} -AbstractProject.LabelLink=Slaves em label: {2} # Artifacts of {0} {1} Run.ArtifactsBrowserTitle=Artefatos de {0} {1} # Build with Parameters -AbstractProject.build_with_parameters=Construir com par\u00e2metros # Still unstable ResultTrend.StillUnstable=Ainda inst\u00e1vel # Running as {0} @@ -524,3 +452,4 @@ Item.CONFIGURE.description=Mudar a configura\u00e7\u00e3o de um job. Item.DELETE.description=Excuir um job. HealthReport.EmptyString= MultiStageTimeSeries.EMPTY_STRING= +ParametersDefinitionProperty.DisplayName=Este build \u00E9 parametrizado diff --git a/core/src/main/resources/hudson/model/Messages_pt_PT.properties b/core/src/main/resources/hudson/model/Messages_pt_PT.properties index e022d96cef477241f4cd6de990be865feada13da..be8cf4950ca99d13ff6e9292d05f90793a99a795 100644 --- a/core/src/main/resources/hudson/model/Messages_pt_PT.properties +++ b/core/src/main/resources/hudson/model/Messages_pt_PT.properties @@ -1 +1,3 @@ ManageJenkinsAction.DisplayName=Gerir o Jenkins + +FreeStyleProject.Description=Isto \u00E9 uma caracter\u00EDstica central do Jenkins. Jenkins vai construir o seu projecto, combinando qualquer SCM com qualquer sistema de compila\u00E7\u00E3o e isto pode ser usado mesmo em qualquer outra compila\u00E7\u00E3o de software. diff --git a/core/src/main/resources/hudson/model/Messages_ro.properties b/core/src/main/resources/hudson/model/Messages_ro.properties new file mode 100644 index 0000000000000000000000000000000000000000..8a8fa99a17cdb54bfdba317fa3e45a952db6d6d5 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_ro.properties @@ -0,0 +1,3 @@ +ParametersDefinitionProperty.DisplayName=Acest build este parametrizat + +FreeStyleProject.Description=Aceasta este func\u021Bionalitatea principal\u0103 a lui Jenkins. Jenkins va construi proiectul dvs, combin\u00E2nd orice SCM cu orice sistem de build-uri, \u0219i aceasta poate fi folosit\u0103 chiar \u0219i la altceva dec\u00E2t build-uri de aplica\u021Bii. diff --git a/core/src/main/resources/hudson/model/Messages_ru.properties b/core/src/main/resources/hudson/model/Messages_ru.properties index c0be7aa273b0a8f8c13fea50fe32e8e25abd2d54..2b0130c8fd51be5fe0757d2681c901643a9e9713 100644 --- a/core/src/main/resources/hudson/model/Messages_ru.properties +++ b/core/src/main/resources/hudson/model/Messages_ru.properties @@ -25,9 +25,7 @@ AbstractBuild.KeptBecause=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e AbstractProject.Pronoun=\u041f\u0440\u043e\u0435\u043a\u0442 AbstractProject.Aborted=\u041f\u0440\u0435\u0440\u0432\u0430\u043d\u043e -AbstractProject.BuildInProgress=\u0421\u0431\u043e\u0440\u043a\u0430 #{0} \u0443\u0436\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 {1} AbstractProject.Disabled=\u0421\u0431\u043e\u0440\u043a\u0430 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430 -AbstractProject.ETA=\ (\u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c:{0}) AbstractProject.NoSCM=\u041d\u0435\u0442 \u0421\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0439 AbstractProject.NoWorkspace=\u0421\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043d\u0435\u0442, \u043d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. AbstractProject.PollingABorted=\u041e\u043f\u0440\u043e\u0441 SCM \u043f\u0440\u0435\u0440\u0432\u0430\u043d @@ -46,12 +44,15 @@ BallColor.Pending=\u041e\u0436\u0438\u0434\u0430\u0435\u0442 BallColor.Success=\u0423\u0441\u043f\u0435\u0448\u043d\u043e BallColor.Unstable=\u041D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u044B\u0439 -Computer.Caption=\u041f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0439 \u0443\u0437\u0435\u043b {0} Executor.NotAvailable=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e FreeStyleProject.DisplayName=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0441\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 +FreeStyleProject.Description=\ + \u042d\u0442\u043e - \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0438 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u0437\u0430\u0434\u0430\u0447 \u0432 Jenkins. \ + Jenkins \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u044f \u043b\u044e\u0431\u0443\u044e SCM \u0441 \u043b\u044e\u0431\u043e\u0439 \u0441\u0431\u043e\u0440\u043e\u0447\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439. \ + \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u0447, \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 \u041f\u041e. Hudson.BadPortNumber=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430: {0} Hudson.Computer.Caption=\u041c\u0430\u0441\u0442\u0435\u0440 @@ -88,19 +89,11 @@ Run.MarkedExplicitly=\u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043e \u0434\u04 Run.Permissions.Title=\u0417\u0430\u043f\u0443\u0441\u043a Run.UnableToDelete=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c {0}: {1} -Slave.InvalidConfig.Executors=\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 {0}. \u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432. -Slave.InvalidConfig.NoName=\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430. \u0418\u043c\u044f \u0443\u0437\u043b\u0430 \u043f\u0443\u0441\u0442\u043e. -Slave.InvalidConfig.NoRemoteDir=\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 {0}. \u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f. -Slave.Launching={0} \u0417\u0430\u043f\u0443\u0441\u043a \u0430\u0433\u0435\u043d\u0442\u0430 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 -Slave.Terminated={0} \u0410\u0433\u0435\u043d\u0442 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d -Slave.UnableToLaunch= \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0437\u043b\u0430 {0} {1} -Slave.UnixSlave=\u0423\u0437\u0435\u043b \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c Unix -Slave.WindowsSlave=\u0423\u0437\u0435\u043b \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c Windows View.Permissions.Title=\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 Permalink.LastBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0441\u0431\u043e\u0440\u043a\u0430 Permalink.LastStableBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430 Permalink.LastSuccessfulBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430 Permalink.LastFailedBuild=\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u0441\u0431\u043e\u0440\u043a\u0430 -AbstractProject.BuildNow=\u0421\u043E\u0431\u0440\u0430\u0442\u044C \u0441\u0435\u0439\u0447\u0430\u0441 ManageJenkinsAction.DisplayName=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Jenkins +ParametersDefinitionProperty.DisplayName=\u042d\u0442\u043e - \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430 diff --git a/core/src/main/resources/hudson/model/Messages_sk.properties b/core/src/main/resources/hudson/model/Messages_sk.properties new file mode 100644 index 0000000000000000000000000000000000000000..d3cf7721e0e164ad7bf7a545fe62165e1a786cc2 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_sk.properties @@ -0,0 +1 @@ +ParametersDefinitionProperty.DisplayName=Toto zostavenie je parametrizovan\u00E9 diff --git a/core/src/main/resources/hudson/model/Messages_sl.properties b/core/src/main/resources/hudson/model/Messages_sl.properties index a9fc958501caf4cf0407d8d5a0757fc2fec9373b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/core/src/main/resources/hudson/model/Messages_sl.properties +++ b/core/src/main/resources/hudson/model/Messages_sl.properties @@ -1 +0,0 @@ -AbstractProject.BuildNow=Prevedi takoj diff --git a/core/src/main/resources/hudson/model/Messages_sr.properties b/core/src/main/resources/hudson/model/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..01085a0393f626c844e38882c00ee6b39810d8ca --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_sr.properties @@ -0,0 +1,292 @@ +# This file is under the MIT License by authors + +AbstractBuild.BuildingRemotely=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0441\u0430 \u0434\u0430\u043B\u0435\u043A\u0430 \u043D\u0430 "{0}" +AbstractBuild.BuildingOnMaster=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u043E\u043C \u0441\u0435\u0440\u0432\u0435\u0440\u0443 +AbstractBuild_Building=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +AbstractBuild.BuildingInWorkspace=\u043D\u0430 \u0440\u0430\u0434\u043D\u043E\u043C \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0443 "{0}" +AbstractBuild.KeptBecause=\u041E\u0432\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0458\u0435 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u043E \u0437\u0431\u043E\u0433 {0}. +AbstractItem.NoSuchJobExists=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A "{0}". \u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0438\u043C\u0430\u043B\u0438 "{1}"? +AbstractItem.NoSuchJobExistsWithoutSuggestion=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C "{0}". +AbstractItem.Pronoun=\u043E\u0431\u0458\u0435\u043A\u0430\u0442 +AbstractProject.AssignedLabelString_NoMatch_DidYouMean=\u041D\u0435\u043C\u0430 \u0442\u0430\u043A\u0432\u043E\u0433 \u0430\u0433\u0435\u043D\u0442\u0430/cloud. \u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u043C\u0438\u0441\u043B\u0438\u043B\u0438 "{1}" \u043D\u0430 \u0443\u043C\u0443 \u0443\u043C\u0435\u0441\u0442\u043E "{0}"? +AbstractProject.NewBuildForWorkspace=\u0417\u0430\u043A\u0430\u0437\u0438\u0432\u0430\u045A\u0435 \u043D\u043E\u0432\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0434\u0430 \u0431\u0438 \u0441\u0435 \u0434\u043E\u0431\u0438\u043E \u043D\u043E\u0432\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440. +AbstractProject.Pronoun=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +AbstractProject.AwaitingWorkspaceToComeOnline=\u041F\u043E\u043A\u0440\u0435\u043D\u0438\u0442\u0435 \u043D\u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0434\u0430 \u0431\u0438 \u0441\u0442\u0435 \u0434\u043E\u0431\u0438\u043B\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440. \u0427\u0435\u043A\u0430\u045A\u0435 {0}ms \u0441\u0430 \u043D\u0430\u0434\u043E\u043C \u0434\u0430 \u045B\u0435 \u0458\u0435\u043D\u0430\u043D \u0431\u0438\u0442\u0438 \u043E\u0441\u043B\u043E\u0431\u043E\u0452\u0435\u043D. +AbstractProject.AwaitingBuildForWorkspace=\u0427\u0435\u043A\u0430\u045A\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443, \u0434\u0430 \u0431\u0438 \u0441\u0435 \u0434\u043E\u0431\u0438\u043E \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440. +AbstractProject.Aborted=\u041F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u043E +AbstractProject.UpstreamBuildInProgress=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0}, \u043E\u0434 \u043A\u043E\u0433\u0430 \u0437\u0430\u0432\u0438\u0441\u0438 \u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430, \u0458\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442. +AbstractProject.DownstreamBuildInProgress=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 {0}, \u043A\u043E\u0458\u0438 \u0437\u0430\u0432\u0438\u0441\u0438 \u043D\u0430 \u043E\u0432\u043E\u043C, \u0458\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0430. +AbstractProject.Disabled=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0430 +AbstractProject.NoBuilds=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u043D\u0438 \u0458\u0435\u0434\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430. \u0417\u0430\u043A\u0430\u0437\u0438\u0432\u0430\u045A\u0435 \u043D\u043E\u0432\u0435 \u0443 \u0442\u043E\u043A\u0443. +AbstractProject.NoSCM=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u0441\u0438\u0441\u0442\u0435\u043C \u0437\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u0443 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +AbstractProject.NoWorkspace=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u043B\u043E \u0443\u0447\u0438\u0442\u0430\u0442\u0438 \u043D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0430 \u0437\u0430\u0448\u0442\u043E \u043D\u0435\u043C\u0430 \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u043E\u0433 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430. +UpdateCenter.PluginCategory.devops=DevOps +UpdateCenter.PluginCategory.dotnet=.NET \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.database=\u0411\u0430\u0437\u0430 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430 +UpdateCenter.PluginCategory.deployment=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 +UpdateCenter.PluginCategory.external=\u0418\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0458\u0430 \u0435\u043A\u0441\u0442\u0435\u0440\u043D\u0438\u043C \u0441\u0435\u0440\u0432\u0438\u0441\u0438\u043C\u0430 \u0438 \u0430\u043B\u0430\u0442\u0438\u043C\u0430 +UpdateCenter.PluginCategory.groovy-related=\u0423 \u0432\u0435\u0437\u0438 \u0441\u0430 Groovy +UpdateCenter.PluginCategory.ios=iOS \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.library=\u0411\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0435 \u0437\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 (\u0443 \u043A\u043E\u0440\u0438\u0441\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430) +UpdateCenter.PluginCategory.maven=Maven +UpdateCenter.PluginCategory.cluster=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 \u0438 \u0440\u0430\u0441\u043F\u043E\u0434\u0435\u0459\u0435\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +UpdateCenter.PluginCategory.android=Android \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.python=Python \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.report=\u0418\u0437\u0432\u0435\u0448\u0442\u0430\u0458\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +UpdateCenter.PluginCategory.ruby=Ruby \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.scm=\u0421\u0438\u0441\u0442\u0435\u043C \u0437\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +UpdateCenter.PluginCategory.scala=Scala \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.scm-related=\u0412\u0435\u0437\u0430\u043D\u043E \u0441\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u043C \u0437\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +UpdateCenter.PluginCategory.security=\u0411\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442 +UpdateCenter.PluginCategory.slaves=\u041F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0438 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0430\u0442\u0430 +UpdateCenter.PluginCategory.test=\u0422\u0435\u0441\u0442\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.trigger=\u0410\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u0441\u0442\u0430\u0440\u0442 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +\u043D\u0430\u043F\u0430\u0441\u0432\u0430= +AbstractProject.WorkspaceTitle=\u0420\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 \u043E\u0434 {0} +AbstractProject.WorkspaceTitleOnComputer=\u0420\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 {0} \u043D\u0430 {1} +AbstractProject.PollingABorted=\u041F\u0440\u043E\u0432\u0435\u0440\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \u0458\u0435 \u0443\u043A\u0438\u043D\u0443\u0442\u043E +AbstractProject.PollingVetoed=\u0417\u0430\u0445\u0442\u0435\u0432\u0438 \u043F\u0440\u0435\u043C\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0430 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \u0441\u0443 \u043F\u0440\u0438\u0432\u0440\u0435\u043C\u0435\u043D\u043E \u0441\u0443\u0441\u043F\u0435\u043D\u0434\u043E\u0432\u0430\u043D\u0438 \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 {0}. +AbstractProject.ScmAborted=\u0423\u0447\u0438\u0442\u0430\u0432\u0430\u045A\u0435 \u043E\u0434 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \u0458\u0435 \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u043E +AbstractProject.WorkspaceOffline=\u0420\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 \u0458\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0430\u043D +AbstractProject.BuildPermission.Description=\u041E\u0432\u0430 \u0434\u043E\u0437\u0432\u043E\u043B\u0430 \u043F\u0440\u0443\u0436\u0438 \u043C\u043E\u0433\u0443\u045B\u043D\u043E\u0441\u0442 \u0434\u0430 \u0441\u0435 \u0437\u0430\u043F\u043E\u0447\u043D\u0435 \u043D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430. +AbstractProject.WorkspacePermission.Description=\u041E\u0432\u0430 \u0434\u043E\u0437\u0432\u043E\u043B\u0430 \u043F\u0440\u0443\u0436\u0438 \u043C\u043E\u0433\u0443\u045B\u043D\u043E\u0441\u0442 \u0434\u0430 \u0441\u0435 \u0443\u0447\u0438\u0442\u0430 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430. +Computer.Caption=\u0410\u0433\u0435\u043D\u0442 {0} +Computer.NoSuchSlaveExists=\u041D\u043C\u0435\u0430 \u0430\u0433\u0435\u043D\u0442\u0430 "{0}". \u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u043C\u0438\u0441\u043B\u0438\u043B\u0438 "{1}" \u0443 \u0432\u0438\u0434\u0443? +AbstractProject.ExtendedReadPermission.Description=\u041E\u0432\u043E \u043F\u0440\u0430\u0432\u043E \u0434\u0430\u0458\u0435 \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u043D\u0430 \u0447\u0438\u0442\u0430\u045A\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u045A\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442\u0430, \u0430 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0434\u043E\u0432\u0435\u0434\u0435 \u0434\u043E \u0448\u0438\u0440\u0435\u045A\u0435 \u0442\u0430\u0458\u043D\u0438 \u043A\u043E\u0458\u0435 \u0441\u0435 \u043D\u0430\u043B\u0430\u0437\u0435 \u043F\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438 \u043A\u0430\u043E, \u043D\u0430 \u043F\u0440\u0438\u043C\u0435\u0440, \u043B\u043E\u0437\u0438\u043D\u043A\u0435. +AbstractProject.DiscoverPermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043D\u0430 \u043E\u0442\u043A\u0440\u0438\u0432\u0430\u045A\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430, \u043A\u043E\u0458\u0438 \u043E\u043C\u043E\u0433\u0443\u045B\u0430\u0432\u0430 \u043F\u0440\u0435\u0443\u0441\u043C\u0435\u0440\u0430\u0432\u0430\u045A\u0435 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0435 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0437\u0430 \u043F\u0440\u0438\u0458\u0430\u0432\u0443 \u043A\u0430\u0434\u0430 \u0431\u0443\u0434\u0443 \u043F\u043E\u043A\u0443\u0448\u0430\u0432\u0430\u043B\u0438 \u0434\u0430 \u043E\u0442\u0432\u043E\u0440\u0435 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043E\u0434\u0440\u0435\u0452\u0435\u043D\u043E\u0433 \u0437\u0430\u0434\u0430\u0442\u043A\u0430. \u0410\u043A\u043E \u043D\u0435\u043C\u0430\u0458\u0443 \u0434\u043E\u0432\u043B\u0430\u045B\u0435\u045A\u0435 \u043E\u043D\u0438 \u045B\u0435 \u0431\u0438\u0442\u0438 \u043F\u0440\u0435\u0443\u0441\u043C\u0435\u0440\u0435\u043D\u0438 \u0433\u0440\u0435\u0448\u0446\u0438 404 \u0438 \u043D\u0435\u045B\u0435 \u043C\u043E\u045B\u0438 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0438\u0442\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u043E\u043C. +AbstractProject.WipeOutPermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u0441\u0430\u0432 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430. +AbstractProject.CancelPermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043E\u0442\u043A\u0430\u0436\u0435\u0442\u0435 \u043F\u043B\u0430\u043D\u0438\u0440\u0430\u043D\u0435 \u0438 \u0437\u0430\u0443\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. +AbstractProject.AssignedLabelString.NoMatch=\u041D\u0435\u043C\u0430 \u0430\u0433\u0435\u043D\u0442/cloud \u0437\u0430\u0434\u0443\u0436\u0435\u043D \u043E\u0432\u0438\u043C \u0437\u0430\u0434\u0430\u0442\u043A\u043E\u043C +AbstractProject.AssignedLabelString.InvalidBooleanExpression=\u041F\u043E\u0433\u0440\u0435\u0448\u043D\u0438 \u0431\u0443\u043B\u043E\u0432 \u0438\u0437\u0440\u0430\u0437: {0} +AbstractProject.CustomWorkspaceEmpty=\u041F\u0440\u0438\u043B\u0430\u0433\u043E\u0452\u0435\u043D\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 \u0458\u0435 \u043F\u0440\u0430\u0437\u0430\u043D. +AbstractProject.LabelLink=\u041B\u0430\u0431\u0435\u043B\u0430 {1} \u0458\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0438\u0440\u0430\u043D\u0430 {3,choice,0#\u043D\u0435\u043C\u0430 \u043C\u0430\u0448\u0438\u043D\u0430|1#1 \u043C\u0430\u0448\u0438\u043D\u0430|1<{3} \u043C\u0430\u0448\u0438\u043D\u0430\u043C\u0430}{4,choice,0#|1# \u0438 1 cloud|1< \u0438 {4} clouds} +Api.MultipleMatch=\u0418\u0437\u0440\u0430\u0437 \u043A\u0440\u043E\u0437 XPath "{0}" \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430 \u043C\u0430\u0448\u0438\u043D\u0438 {1}. \u0423\u043D\u0435\u0441\u0438\u0442\u0435 \u0438\u0437\u0440\u0430\u0437 \u0438\u043B\u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 "wrapper", \u0434\u0430 \u0438\u0445 \u0441\u0432\u0435 \u043F\u043E\u043A\u0440\u0438\u0458\u0435 \u0433\u043B\u0430\u0432\u043D\u0438 \u0435\u043B\u0435\u043C\u0435\u043D\u0442. +Api.NoXPathMatch=\u0418\u0437\u0440\u0430\u0437 \u043A\u0440\u043E\u0437 XPath "{0}" \u043D\u0438\u0458\u0435 \u043D\u0430\u0448\u0430\u043E \u043D\u0438 \u0458\u0435\u0434\u043D\u0443 \u043C\u0430\u0448\u0438\u043D\u0443. +BallColor.Aborted=\u041E\u0442\u043A\u0430\u0437\u0430\u043D\u043E +BallColor.Disabled=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u043E +BallColor.Failed=\u041D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E +BallColor.InProgress=\u0423 \u0442\u043E\u043A\u0443 +BallColor.NotBuilt=\u041D\u0435\u0438\u0437\u0433\u0440\u0430\u0452\u0435\u043D\u043E +BallColor.Pending=\u041E\u0447\u0435\u043A\u0443\u0458\u0435 +BallColor.Success=\u0423\u0441\u043F\u0435\u0448\u043D\u043E +BallColor.Unstable=\u041D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E +Build.post_build_steps_failed=\u041A\u043E\u0440\u0430\u0446\u0438 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u043D\u0438\u0441\u0443 \u0443\u0441\u043F\u0435\u043B\u0435 +CLI.clear-queue.shortDescription=\u0418\u0437\u045B\u0438\u0441\u0442\u0438 \u0440\u0435\u0434 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 +CLI.disable-job.shortDescription=\u041F\u043E\u043D\u0438\u0448\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +CLI.enable-job.shortDescription=\u0423\u043A\u0459\u0443\u0447\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +CLI.online-node.shortDescription=\u041D\u0430\u0441\u0442\u0430\u0432\u0438 \u043A\u043E\u0440\u0438\u0441\u0442\u0435\u045B\u0438 \u043C\u0430\u0448\u0438\u043D\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0434\u0430 \u0431\u0438 \u0441\u0442\u0435 \u043F\u043E\u043D\u0438\u0448\u0442\u0438\u043B\u0438 \u043F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u0443 \u043A\u043E\u043C\u0430\u043D\u0434\u0443\ +"offline-node". +Computer.Permissions.Title=\u0410\u0433\u0435\u043D\u0442 +Computer.NoSuchSlaveExistsWithoutAdvice=\ \u041D\u0435\u043C\u0430 \u0430\u0433\u0435\u043D\u0442\u0430 {0} +Computer.ExtendedReadPermission.Description=\u041E\u0432\u043E \u0434\u043E\u0437\u0432\u043E\u0459\u0430\u0432\u0430 \u0434\u0430 \u043A\u043E\u0440\u0438\u043D\u0438\u0446\u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0443 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0430\u0433\u0435\u043D\u0430\u0442\u0430. +Computer.ConfigurePermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043F\u043E\u0441\u0442\u0430\u0432\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0430\u0433\u0435\u043D\u0430\u0442\u0430. +Computer.DeletePermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u0431\u0440\u0438\u0448\u0443 \u0430\u0433\u0435\u043D\u0442\u0435. +Computer.CreatePermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043F\u043E\u0441\u0442\u0430\u0432\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0430\u0433\u0435\u043D\u0430\u0442\u0430. +Computer.ConnectPermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043F\u043E\u0432\u0435\u0436\u0443 \u0430\u0433\u0435\u043D\u0442\u0435 \u0438\u043B\u0438 \u0438\u0445 \u043E\u0437\u043D\u0430\u0447\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0438\u043C. +Computer.DisconnectPermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043E\u0442\u043A\u043E\u043F\u0447\u0430\u0458\u0443 \u0430\u0433\u0435\u043D\u0442\u0435 \u0438\u043B\u0438 \u043E\u0437\u043D\u0430\u0447\u0435 \u043F\u0440\u0438\u0432\u0440\u0435\u043C\u0435\u043C\u043E \u043D\u0435\u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0438\u043C. +Computer.BuildPermission.Description=\u041E\u0432\u043E \u0434\u0430\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0443 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0441\u0430 \u0441\u0432\u043E\u0458\u0438\u043C \u0438\u043C\u0435\u043D\u0438\u043C\u0430. +ComputerSet.NoSuchSlave=\u041D\u0435\u043C\u0430 \u0430\u0433\u0435\u043D\u0442\u0430 {0} +Computer.BadChannel=\u041C\u0430\u0448\u0438\u043D\u0430 \u0430\u0433\u0435\u043D\u0442\u0430 \u043D\u0438\u0458\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0430 \u0438\u043B\u0438 \u043D\u0438\u0458\u0435 \u0434\u0430\u0459\u0438\u043D\u0441\u043A\u0438 \u043A\u0430\u043D\u0430\u043B (\u043A\u0430\u043E \u043D\u0430 \u043F\u0440\u0438\u043C\u0435\u0440 \u0448\u0442\u043E \u0458\u0435 \u0433\u043B\u0430\u0432\u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0430) +ComputerSet.SlaveAlreadyExists=\u0412\u0435\u045B \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u0430\u0433\u0435\u043D\u0442 \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C {0} +ComputerSet.SpecifySlaveToCopy=\u041E\u0434\u0440\u0435\u0434\u0438\u0442\u0435 \u0430\u0433\u0435\u043D\u0442 \u0437\u0430 \u043A\u043E\u043F\u0438\u0440\u0430\u045A\u0435 +ComputerSet.DisplayName=\u0420\u0430\u0447\u0443\u043D\u0430\u0440\u0438 +Descriptor.From=(\u043E\u0434 {0}) +Executor.NotAvailable=\u041D/\u0414 +FreeStyleProject.DisplayName=\u041D\u0435\u0437\u0430\u0432\u0438\u0441\u043D\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +FreeStyleProject.Description=\u041E\u0432\u043E \u0458\u0435 \u043E\u0441\u043D\u043E\u0432\u043D\u0430 \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u043D\u043E\u0441\u0442 Jenkins-\u0430. Jenkins \u043C\u043E\u0436\u0435 \u0434\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043A\u043E\u0440\u0438\u0441\u0442\u0435\u045B\u0438 \u0431\u0438\u043B\u043E \u043A\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u043D\u0438\u043C \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u043C. \u0422\u0430\u043A\u043E \u043C\u043E\u0436\u0435\u0442\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 Jenkins \u0437\u0430 \u0440\u0430\u0437\u043B\u0438\u0447\u0438\u0442\u0435 \u0441\u0432\u0440\u0445\u0435. +HealthReport.EmptyString= +Hudson.BadPortNumber=\u041F\u043E\u0433\u0440\u0435\u0448\u0430\u043D \u0431\u0440\u043E\u0458 \u043F\u043E\u0440\u0442\u0430 {0} +Hudson.Computer.Caption=\u0413\u043B\u0430\u0432\u043D\u0430 +Hudson.Computer.DisplayName=\u0433\u043B\u0430\u0432\u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 +Hudson.ControlCodeNotAllowed=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0438 \u043A\u043E\u0434 \u043D\u0438\u0458\u0435 \u0434\u043E\u0437\u0432\u043E\u0459\u0435\u043D: {0} +Hudson.JobAlreadyExists=\u0412\u0435\u045B \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C \u2018{0}\u2019 +Hudson.DisplayName=Jenkins +Hudson.NoJavaInPath=java \u043D\u0438\u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D \u0443 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0430 PATH-\u0430. \u041C\u043E\u0436\u0434\u0430 \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043B\u0438 \u0434\u0430 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0435 JDK? +Hudson.NoName=\u041D\u0438\u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E \u0438\u043C\u0435. +Hudson.NoSuchDirectory=\u041D\u0435\u043C\u0430 \u0434\u0438\u0440\u0435\u0434\u043A\u043E\u0440\u0438\u0458\u0443\u043C\u0430 \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C {0} +Hudson.NodeBeingRemoved=\u041C\u0430\u0448\u0438\u043D\u0430 \u0441\u0435 \u0431\u0440\u0438\u0448\u0435 +Hudson.NotAPlugin={0} \u043D\u0438\u0458\u0435 \u0432\u0440\u0441\u0442\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 \u0437\u0430 Jenkins +Hudson.NotJDKDir={0} \u043D\u0438\u0458\u0435 JDK \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C +Hudson.USER_CONTENT_README=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0443 \u0443 \u043E\u0432\u043E\u043C \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0443 \u045B\u0435 \u0431\u0438\u0442\u0438 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0438 \u043F\u0443\u0442\u0435\u043C \u0430\u0434\u0440\u0435\u0441\u0438 http://server/jenkins/userContent/ +Hudson.Permissions.Title=\u041E\u043F\u0448\u0442\u0435 +Hudson.UnsafeChar=\u041E\u043F\u0430\u0441\u043D\u043E \u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0438 \u0437\u043D\u0430\u043A \u2018{0}\u2019 +Hudson.ViewAlreadyExists=\u0412\u0435\u045B \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C "{0}" +Hudson.ViewName=\u0421\u0432\u0435 +Hudson.NotANumber=\u041D\u0438\u0458\u0435 \u0431\u0440\u043E\u0458\u043A\u0430 +Hudson.NotAPositiveNumber=\u041D\u0438\u0458\u0435 \u043F\u043E\u0437\u0438\u0442\u0438\u0432\u0430\u043D \u0431\u0440\u043E\u0458. +Hudson.NotANonNegativeNumber=\u0411\u0440\u043E\u0458 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043D\u0435\u0433\u0430\u0442\u0438\u0432\u0430\u043D. +Hudson.NotANegativeNumber=\u041D\u0438\u0458\u0435 \u043D\u0435\u0433\u0430\u0442\u0438\u0432\u0430\u043D \u0431\u0440\u043E\u0458. +Hudson.NotUsesUTF8ToDecodeURL=URL \u0430\u0434\u0440\u0435\u0441\u0435 \u0432\u0430\u0448\u0435\u0433 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0430 \u043D\u0438\u0441\u0443 \u0443\u043D\u0435\u0448\u0435\u043D\u0438 \u043F\u043E \u0444\u043E\u0440\u043C\u0430\u0442\u0443 UTF-8. \u0418\u043C\u0435\u043D\u0430 \u0441\u0430 \u0437\u043D\u0430\u0446\u0438\u043C\u0430 \u0438\u0437\u0432\u0430\u043D ASCII \u043C\u043E\u0433\u0443 \u0438\u0437\u0430\u0437\u0432\u0430\u0442\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0435. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 Containers \u0438 \ + Tomcat i18n. +Hudson.AdministerPermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043C\u0435\u045A\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0430, \u043A\u0430\u043E \u0438 \u043A\u043E\u043C\u043F\u043B\u0435\u0442\u0430\u043D \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u043B\u043E\u043A\u0430\u043B\u043D\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0443 \u0458\u0435\u0434\u043D\u0430\u043A\u0435 \u043F\u043E \u043E\u043A\u0432\u0438\u0440\u0443 \u043F\u0440\u0430\u0432\u0430 \u0443 \u0441\u043A\u043B\u0430\u0434\u0443 \u0441\u0430 \u043E\u043F\u0435\u0440\u0430\u0442\u0438\u0432\u043D\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u043C. +Hudson.ReadPermission.Description= +Hudson.RunScriptsPermission.Description=\u041E\u0431\u0430\u0432\u0435\u0437\u043D\u043E \u0437\u0430 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u0441\u043A\u0440\u0438\u043F\u0442\u0430 \u0443\u043D\u0443\u0442\u0430\u0440 Jenkins \u043F\u0440\u043E\u0446\u0435\u0441\u0430, \u043A\u0430\u043E \u043D\u0430 \u043F\u0440\u0438\u043C\u0435\u0440 \u043F\u0440\u0435\u043A\u043E Groovy \u043A\u043E\u043D\u0441\u043E\u043B\u0435 \u0438\u043B\u0438 \u043A\u043E\u043C\u0430\u043D\u0434\u0435. +Hudson.NodeDescription=\u0433\u043B\u0430\u0432\u043D\u0430 Jenkins \u043C\u0430\u0448\u0438\u043D\u0430 +Item.CREATE.description=\u041A\u0440\u0435\u0438\u0440\u0430\u0458 \u043D\u043E\u0432\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +Item.Permissions.Title=\u0417\u0430\u0434\u0430\u0442\u0430\u043A +Item.DELETE.description=\u0423\u043A\u043B\u043E\u043D\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +Item.CONFIGURE.description=\u041F\u0440\u043E\u043C\u0435\u043D\u0438 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0430 +Item.READ.description=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0437\u0430\u0434\u0430\u0442\u043A\u0430 (\u043C\u043E\u0436\u0435\u0442\u0435 \u0438\u0441\u0442\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u043E\u043C \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0438 \u043E\u0432\u043E \u043F\u0440\u0430\u0432\u043E \u0438 \u0434\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u0438 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438\u043C \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0443 \u0434\u0430 \u0441\u0435 \u043F\u0440\u0438\u0458\u0430\u0432\u0438 \u0434\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \u0437\u0430\u0434\u0430\u0442\u0430\u043A) +ItemGroupMixIn.may_not_copy_as_it_contains_secrets_and_=\u041D\u0435\u043C\u043E\u0436\u0435 \u0441\u0435 \u043A\u043E\u043F\u0438\u0440\u0430\u0442\u0438 {0} \u043F\u043E\u0448\u0442\u043E \u0441\u0430\u0434\u0440\u0436\u0438 \u0442\u0430\u0458\u043D\u0435 \u0438 {1} \u0438\u043C\u0430 {2}/{3} \u0430 \u043D\u0435 /{4} +Job.AllRecentBuildFailed=\u0421\u0432\u0430 \u043D\u0435\u0434\u0430\u0432\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0441\u0443 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430 +Job.BuildStability=\u0421\u0442\u0430\u0431\u0438\u043B\u043D\u043E\u0441\u0442 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435: {0} +Job.NOfMFailed={0} \u043E\u0434 \u043F\u043E\u0441\u043B\u0435\u0434\u045A\u0438\u0445 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 {1} \u0441\u0437 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430. +Job.NoRecentBuildFailed=\u0418\u0437\u043C\u0435\u045B\u0443 \u043D\u0430\u0458\u043D\u043E\u0432\u0438\u0458\u0438\u0445 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u043C\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0438\u0445. +Job.Pronoun=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +Job.minutes=\u043C\u0438\u043D. +Job.you_must_use_the_save_button_if_you_wish=\u0414\u0430 \u043F\u0440\u0435\u0438\u043C\u0435\u043D\u0443\u0458\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A, \u043A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 \u0434\u0443\u0433\u043C\u0435 "\u0421\u0430\u0447\u0443\u0432\u0430\u0458". +Label.GroupOf=\u0433\u0440\u0443\u043F\u0430 {0} +Label.InvalidLabel=\u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u043D\u0430 \u043B\u0430\u0431\u0435\u043B\u0430 +Label.ProvisionedFrom=\u041D\u0430\u0431\u0430\u0432\u0459\u0435\u043D\u043E \u043E\u0434 {0} +ManageJenkinsAction.DisplayName=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C +MultiStageTimeSeries.EMPTY_STRING= +Queue.AllNodesOffline=\u0421\u0432\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 \u0441\u0430 \u043B\u0430\u0431\u0435\u043B\u043E\u043C \u2018{0}\u2019 \u0441\u0443 \u0432\u0430\u043D \u043C\u0440\u0435\u0436\u0435 +Queue.LabelHasNoNodes=\u041D\u0435\u043C\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0441\u0430 \u043B\u0430\u0431\u0435\u043B\u043E\u043C \u2018{0}\u2019 +Queue.BlockedBy=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u043D\u043E \u043E\u0434 {0} +Queue.HudsonIsAboutToShutDown=Jenkins \u0441\u0435 \u0443\u0441\u043A\u043E\u0440\u043E \u0433\u0430\u0441\u0438 +Queue.InProgress=\u0412\u0435\u045B \u0441\u0435 \u0432\u0440\u0448\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Queue.InQuietPeriod=\ \u0418\u043D\u0442\u0435\u0440\u0432\u0430\u043B \u0442\u0438\u0448\u0438\u043De, \u0438\u0437\u0442\u0438\u0447e \u0437\u0430 {0} +Queue.NodeOffline={0} \u0458\u0435 \u0432\u0430\u043D \u043C\u0440\u0435\u0436\u0435 +Queue.Unknown=\u041D/\u0414 +Queue.WaitingForNextAvailableExecutor=\u0427\u0435\u043A\u0430\u045A\u0435 \u043D\u0430 \u0441\u043B\u0435\u0434\u0435\u045B\u0443 \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u0443 \u043C\u0430\u0448\u0438\u043D\u0443. +Queue.WaitingForNextAvailableExecutorOn=\u0427\u0435\u043A\u0430\u045A\u0435 \u043D\u0430 \u0441\u043B\u0435\u0434\u0435\u045B\u0443 \u0441\u043B\u043E\u0431\u043E\u0434\u043D\u0443 \u043C\u0430\u0448\u0438\u043D\u0443 \u043D\u0430 {0} +Queue.init=\u0412\u0440\u0430\u045B\u0430\u045A\u0435 \u0440\u0435\u0434\u0443 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443. +ResultTrend.Aborted=\u041E\u0434\u0443\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E +ResultTrend.Failure=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E +ResultTrend.Fixed=\u041F\u043E\u043F\u0440\u0430\u0432\u0459\u0435\u043D\u043E +ResultTrend.NotBuilt=\u041D\u0435\u0438\u0437\u0433\u0440\u0430\u0452\u0435\u043D\u043E +ResultTrend.NowUnstable=\u041D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E +ResultTrend.StillFailing=\u0408\u043E\u0448 \u0458\u0435 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E +ResultTrend.StillUnstable=\u0408\u043E\u0448 \u0458\u0435 \u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E +ResultTrend.Success=\u0423\u0441\u043F\u0435\u0448\u043D\u043E +ResultTrend.Unstable=\u041D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E +Run.BuildAborted=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043E\u0434\u0443\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u0430 +Run.MarkedExplicitly=\u041E\u0432\u0430\u0458 \u0440\u0435\u043A\u043E\u0440\u0434 \u0458\u0435 \u043E\u0431\u0435\u043B\u0435\u0436\u0435\u043D \u0437\u0430 \u0447\u0443\u0432\u0430\u045A\u0435. +Run._is_waiting_for_a_checkpoint_on_={0} \u0447\u0435\u043A\u0430 \u0442\u0440\u0435\u043D\u0443\u0442\u0430\u043A \u0437\u0430 {1} +Run.Permissions.Title=\u0418\u0437\u0432\u0440\u0448\u0438 +Run.running_as_=\u0418\u0437\u0432\u0440\u0448\u0430\u045A\u0435 \u043A\u0430\u043E {0} +Run.UnableToDelete=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0438 {0}: {1} +Run.DeletePermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043D\u0430 \u0431\u0440\u0438\u0441\u0430\u045A\u0435 \u0438\u0437\u0430\u0431\u0440\u0430\u043D\u0438\u0445 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0441\u0430 \u0438\u0441\u0442\u043E\u0440\u0438\u0458\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. +Run.UpdatePermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \u043F\u0440\u043E\u043C\u0435\u043D\u0435 \u043E\u043F\u0438\u0441 \u0438 \u0434\u0440\u0443\u0433\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0441\u0430 \u0438\u0441\u0442\u043E\u0440\u0438\u0458\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. \u041C\u043E\u0436\u0435 \u0441\u0435, \u043D\u0430 \u043F\u0440\u0438\u043C\u0435\u0440, \u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u043F\u043E\u0440\u0443\u043A\u0430 \u043A\u043E\u0458\u0430 \u043E\u043F\u0438\u0441\u0443\u0458\u0435 \u0440\u0430\u0437\u043B\u043E\u0433 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. +Run.ArtifactsPermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0443 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0435 \u043F\u0440\u043E\u0438\u0437\u0432\u0435\u0434\u0435\u043D\u0438 \u043E\u0434 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. \u041D\u0435\u043C\u043E\u0458 \u0442\u0435 \u0434\u0430\u0442\u0438 \u043E\u0432\u043E \u043F\u0440\u0430\u0432\u043E \u0430\u043A\u043E \u043D\u0435 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \u0434\u043E\u0441\u0442\u0443\u043F\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438\u043C\u0430. +Run.InProgressDuration={0} \u0438 \u0440\u0430\u0441\u0442\u0435 +Run.NotStartedYet=\u041D\u0438\u0458\u0435 \u0458\u043E\u0448 \u043F\u043E\u0447\u0435\u043B\u043E +Run.ArtifactsBrowserTitle=\u0410\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 \u043D\u0430 {0} {1} +Run.Summary.Stable=\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E +Run.Summary.Unstable=\u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E +Run.Summary.NotBuilt=\u043D\u0435\u0438\u0437\u0433\u0440\u0430\u0452\u0435\u043D\u043E +Run.Summary.Aborted=\u043E\u0434\u0443\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E +Run.Summary.BackToNormal=\u043D\u043E\u0440\u043C\u0430\u043B\u043D\u043E +Run.Summary.BrokenForALongTime=\u0434\u0443\u0436\u0435 \u0432\u0440\u0435\u043C\u0435 \u0441\u043B\u043E\u043C\u0459\u0435\u043D\u043E +Run.Summary.BrokenSinceThisBuild=\u0441\u043B\u043E\u043C\u0459\u0435\u043D\u043E \u043E\u0434 \u043E\u0432\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Run.Summary.BrokenSince=\u0441\u043B\u043E\u043C\u0459\u0435\u043D\u043E \u043E\u0434 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {0} +Run.Summary.Unknown=\u041D/\u0414 +Slave.InvalidConfig.Executors=\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u043D\u0430 \u0430\u0433\u0435\u043D\u0442\u0443 \u0437\u0430 {0}. \u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u0430\u043D \u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430. +Slave.InvalidConfig.NoName=\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u043D\u0430 \u0430\u0433\u0435\u043D\u0442\u0443 \u2014 \u0438\u043C\u0435 \u0458\u0435 \u043F\u0440\u0430\u0437\u043D\u043E. +Slave.InvalidConfig.NoRemoteDir=\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u043D\u0430 \u0430\u0433\u0435\u043D\u0442\u0443 \u2014 \u043D\u0438\u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E \u0443\u0434\u0430\u0459\u0435\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C. +Slave.Launching={0} \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0442\u043E\u043C +Slave.Network.Mounted.File.System.Warning=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043C\u0440\u0435\u0436\u043D\u0438 \u0441\u0438\u0441\u0442\u0435\u043C \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0437\u0430 \u043A\u043E\u0440\u0435\u043D \u0442\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430. \u0414\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u043D\u0435\u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u0432\u0438\u0434\u0459\u0438\u0432 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0443. +Slave.Remote.Director.Mandatory=\u041E\u0431\u0430\u0432\u0435\u0437\u043D\u043E \u0458\u0435 \u0438\u043C\u0430\u0442\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u043D\u0430 \u0434\u0430\u0459\u0438\u043D\u0438 +Slave.Terminated=\u0410\u0433\u0435\u043D\u0442 {0} \u0458\u0435 \u0443\u043A\u043B\u043E\u045A\u0435\u043D +Slave.Remote.Relative.Path.Warning=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u0440\u0435\u043B\u0430\u0442\u0438\u0432\u043D\u0430 \u043F\u0443\u0442\u0435\u0432\u0430 \u0437\u0430 \u043A\u043E\u0440\u0435\u043D \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430. \u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u0434\u0430 \u0438\u0437\u0430\u0431\u0440\u0430\u043D\u0438 \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 \u043E\u0431\u0435\u0437\u0431\u0435\u0452\u0443\u0458\u0435 \u043A\u043E\u043D\u0441\u0438\u0441\u0442\u0435\u043D\u0442\u043D\u043E\u0433 \u0440\u0430\u0434\u043D\u043E\u0433 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0430. \u041F\u0440\u0435\u043F\u043E\u0440\u0443\u0447\u0443\u0458\u0435 \u0441\u0435 \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u0430\u043F\u0441\u043E\u043B\u0443\u0442\u043D\u0430 \u043F\u0443\u0442\u0435\u0432\u0430. +Slave.UnableToLaunch=\u0410\u0433\u0435\u043D\u0430\u0442 \u0437\u0430 {0}{1} \u043D\u0435 \u043C\u043E\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0435 +Slave.UnixSlave=\u041E\u0432\u043E \u0458\u0435 \u0430\u0433\u0435\u043D\u0442 \u0437\u0430 Unix +TopLevelItemDescriptor.NotApplicableIn={0} \u0435\u043B\u0435\u043C\u0435\u043D\u0442\u0430 \u043D\u0435 \u043C\u043E\u0433\u0443 \u0441\u0435 \u043F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u0438 \u0443 {1} +Slave.WindowsSlave=\u041E\u0432\u043E \u0458\u0435 \u0430\u0433\u0435\u043D\u0442 \u0437\u0430 Windows +UpdateCenter.DownloadButNotActivated=\u0423\u0441\u043F\u0435\u0448\u043D\u043E \u043F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u045A\u0435. \u041F\u043E\u0447\u0435\u045B\u0435 \u0434\u0430 \u0440\u0430\u0434\u0438 \u043F\u043E\u0441\u043B\u0435 \u0441\u043B\u0435\u0434\u0435\u045B\u0435\u0433 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430. +UpdateCenter.n_a=\u041D\u0435\u043C\u0430 +View.Permissions.Title=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 +View.CreatePermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043A\u043E\u0440\u0438\u043D\u0438\u0446\u0438\u043C\u0430 \u0434\u0430 \u043A\u0440\u0435\u0438\u0440\u0430\u0458\u0443 \u043D\u043E\u0432\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430. +View.DeletePermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043A\u043E\u0440\u0438\u043D\u0438\u0446\u0438\u043C\u0430 \u0434\u0430 \u0431\u0440\u0438\u0448\u0443 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0435. +View.ConfigurePermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043A\u043E\u0440\u0438\u043D\u0438\u0446\u0438\u043C\u0430 \u0434\u0430 \u043C\u0435\u045A\u0430\u0458\u0443 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430. +View.ReadPermission.Description=\u0414\u0430\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043A\u043E\u0440\u0438\u043D\u0438\u0446\u0438\u043C\u0430 \u0434\u0430 \u0434\u043E\u0441\u0442\u0443\u043F\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0438\u043C\u0430. +View.MissingMode=\u0412\u0440\u0441\u0442\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \u043D\u0438\u0458\u0435 \u0438\u0437\u0430\u0431\u0440\u0430\u043D\u043E +UpdateCenter.Status.CheckingInternet=\u041F\u0440\u043E\u0432\u0435\u0440\u0430 \u0432\u0435\u0437\u043E\u043C \u0441\u0430 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043E\u043C +UpdateCenter.Status.CheckingJavaNet=\u041F\u0440\u043E\u0432\u0435\u0440\u0430 \u0432\u0435\u0437\u043E\u043C \u0441\u0430 \u0446\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 a\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.Status.Success=\u0423\u0441\u043F\u0435\u0445 +UpdateCenter.Status.UnknownHostException=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u0430 \u0430\u0434\u0440\u0435\u0441\u0435 {0}. \ +\u041C\u043E\u0436\u0434\u0430 \u043C\u043E\u0440\u0430\u0442\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 HTTP proxy? +UpdateCenter.Status.ConnectionFailed=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u043F\u043E\u0432\u0435\u0437\u0438\u0432\u0430\u045A\u0435 \u0441\u0430 {0}. \ +\u041C\u043E\u0436\u0434\u0430 \u043C\u043E\u0440\u0430\u0442\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 HTTP proxy? +UpdateCenter.init=\u0418\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0458\u0430 \u0446\u0435\u043D\u0442\u0440\u0430 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +UpdateCenter.PluginCategory.builder=\u0410\u043B\u0430\u0442\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +UpdateCenter.PluginCategory.buildwrapper=\u0421\u043A\u0440\u0438\u043F\u0442 \u043E\u043C\u043E\u0442\u0430\u0447\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +UpdateCenter.PluginCategory.cli=\u0418\u043D\u0442\u0435\u0440\u0444\u0435\u0458\u0441 \u043D\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u043E\u0458 \u043B\u0438\u043D\u0438\u0458\u0438 +UpdateCenter.PluginCategory.cloud=\u041F\u0440\u043E\u0432\u0430\u0458\u0434\u0435\u0440\u0438 cloud \u0441\u0435\u0440\u0432\u0438\u0441\u0435 +UpdateCenter.PluginCategory.listview-column=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0441\u043F\u0438\u0441\u0430\u043A\u0430 \u043F\u043E \u043A\u043E\u043B\u043E\u043D\u0438\u043C\u0430 +UpdateCenter.PluginCategory.misc=\u0420\u0430\u0437\u043D\u043E +UpdateCenter.PluginCategory.notifier=\u041E\u0431\u0430\u0432\u0435\u0448\u0442\u0435\u045A\u0430 \u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438 +UpdateCenter.PluginCategory.page-decorator=\u0414\u0435\u043A\u043E\u0440\u0430\u0446\u0438\u0458\u0430 \u0437\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 +UpdateCenter.PluginCategory.parameter=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +UpdateCenter.PluginCategory.post-build=\u0414\u043E\u0434\u0430\u0442\u043D\u0435 \u0430\u043A\u0446\u0438\u0458\u0435 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +UpdateCenter.PluginCategory.runcondition=\u0423\u0441\u043B\u043E\u0432\u0438 \u0437\u0430 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 +UpdateCenter.PluginCategory.ui=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u0438 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0458\u0441 +UpdateCenter.PluginCategory.upload=\u041F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u045A\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 +UpdateCenter.PluginCategory.user=\u0410\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0430 \u0438 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 +UpdateCenter.PluginCategory.view=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0438 +UpdateCenter.PluginCategory.must-be-labeled=\u0431\u0435\u0437 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0458\u0435 +UpdateCenter.PluginCategory.unrecognized=\u0420\u0430\u0437\u043D\u043E ({0}) +Permalink.LastBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Permalink.LastStableBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Permalink.LastUnstableBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Permalink.LastUnsuccessfulBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Permalink.LastSuccessfulBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Permalink.LastFailedBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Permalink.LastCompletedBuild=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0437\u0430\u0432\u0440\u0448\u0435\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +ParameterAction.DisplayName=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 +ParametersDefinitionProperty.DisplayName=\u041E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0438\u043C\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 +StringParameterDefinition.DisplayName=\u041D\u0438\u0437 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 +TextParameterDefinition.DisplayName=\u0422\u0435\u043A\u0441\u0442 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 +FileParameterDefinition.DisplayName=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 +BooleanParameterDefinition.DisplayName=\u0411\u0437\u043B\u043E\u0432 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 +ChoiceParameterDefinition.DisplayName=\u0421\u043F\u0438\u0441\u0430\u043A \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 +ChoiceParameterDefinition.MissingChoices=\u041F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0458\u0435 \u0443\u043D\u0435\u0442\u0438 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442\u0438. +PasswordParameterDefinition.DisplayName=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 +RunParameterDefinition.DisplayName=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 \u0437\u0430 \u0438\u0437\u0432\u0440\u0448\u0435\u045A\u0435 +Node.BecauseNodeIsReserved={0} \u0458\u0435 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u0430\u043D\u043E \u0437\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0441\u0430 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430\u0458\u0443\u045B\u043E\u0458 \u043B\u0430\u0431\u0435\u043B\u0438 +Node.BecauseNodeIsNotAcceptingTasks={0} \u043D\u0435 \u043F\u0440\u0438\u043C\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 +Node.LabelMissing={0} \u043D\u0435\u043C\u0430 \u043B\u0430\u0431\u0435\u043B\u0443 {1} +Node.LackingBuildPermission={0} \u043D\u0435\u043C\u0430 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u043D\u0430 {1} +Node.Mode.EXCLUSIVE=\u0418\u0437\u0433\u0440\u0430\u0434\u0438 \u0441\u0430\u043C\u043E \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0441\u0430 \u043B\u0430\u0431\u0435\u043B\u043E\u043C \u043A\u043E\u0458\u0430 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430 \u043E\u0432\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438 +Node.Mode.NORMAL=\u041A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043E\u0432\u0443 \u043C\u0430\u0448\u0438\u043D\u0443 \u043A\u043E\u043B\u0438\u043A\u043E \u0433\u043E\u0434 \u043C\u043E\u0436\u0435\u0442\u0435 +ListView.DisplayName=\u0421\u043F\u0438\u0441\u0447\u0435\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +MyView.DisplayName=\u041C\u043E\u0458 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +LoadStatistics.Legends.DefinedExecutors=\u0414\u0435\u0444\u043D\u0438\u0441\u0430\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0438 +LoadStatistics.Legends.ConnectingExecutors=\u041F\u043E\u0432\u0435\u0437\u0443\u0458\u0435 \u043C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0435 +LoadStatistics.Legends.OnlineExecutors=\u041C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0438 \u043D\u0430 \u043C\u0440\u0435\u0436\u0438 +LoadStatistics.Legends.TotalExecutors=\u0423\u043A\u0443\u043F\u043D\u043E \u043C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0430 +LoadStatistics.Legends.BusyExecutors=\u0417\u0430\u0443\u0437\u0435\u0442\u0435 \u043C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0438 +LoadStatistics.Legends.IdleExecutors=\u0421\u043B\u043E\u0431\u043E\u0434\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0438 +LoadStatistics.Legends.AvailableExecutors=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435-\u0438\u0437\u0432\u043E\u0452\u0430\u0447\u0438 +LoadStatistics.Legends.QueueLength=\u0414\u0443\u0436\u0438\u043D\u0430 \u0440\u0435\u0434\u0430 +Cause.LegacyCodeCause.ShortDescription=\u0421\u0442\u0430\u0440\u0438 \u043A\u043E\u0434 \u0458\u0435 \u0437\u0430\u043F\u043E\u0447\u0435\u043E \u043E\u0432\u0430\u0458 \u0437\u0430\u0434\u0430\u0442\u0430\u043A - \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u0458\u0435 \u0440\u0430\u0437\u043B\u043E\u0433. +Cause.UpstreamCause.ShortDescription=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u043E\u043C "{0}" \u0438\u0437\u0433\u0440\u0430\u0434\u043D\u0438 \u0431\u0440\u043E\u0458 {1} +Cause.UpstreamCause.CausedBy=\u043F\u0440\u0432\u043E\u0431\u0438\u0442\u043D\u043E \u0437\u0431\u043E\u0433: +Cause.UserCause.ShortDescription=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u043E\u043C {0} +Cause.UserIdCause.ShortDescription=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u043E\u043C {0} +Cause.RemoteCause.ShortDescription=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u0443\u0434\u0430\u0459\u0435\u043D\u043E\u043C \u043C\u0430\u0448\u0438\u043D\u043E\u043C {0} +Cause.RemoteCause.ShortDescriptionWithNote=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u0443\u0434\u0430\u0459\u0435\u043D\u043E\u043C \u043C\u0430\u0448\u0438\u043D\u043E\u043C {0} \u0441\u0430 \u0431\u0435\u043B\u0435\u0448\u043A\u043E\u043C: {0} +ProxyView.NoSuchViewExists=\u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 {0} \u043D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 +ProxyView.DisplayName=\u0423\u043A\u0459\u0443\u0447\u0438 \u0433\u043B\u043E\u0431\u0430\u043B\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +MyViewsProperty.DisplayName=\u041C\u043E\u0458\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0438 +MyViewsProperty.GlobalAction.DisplayName=\u041C\u043E\u0458\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0438 +MyViewsProperty.ViewExistsCheck.NotExist=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C {0} \u043D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 +MyViewsProperty.ViewExistsCheck.AlreadyExists=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0441\u0430 \u0438\u043C\u0435\u043D\u043E\u043C {0} \u0432\u0435\u045B \u043F\u043E\u0441\u0442\u043E\u0458\u0438 +CLI.restart.shortDescription=\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0438 Jenkins +CLI.safe-restart.shortDescription=\u0411\u0435\u0437\u0431\u0435\u0434\u043D\u043E \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0438 Jenkins +CLI.keep-build.shortDescription=\u041E\u0437\u043D\u0430\u0447\u0438\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0434\u0430 \u0458\u0435 \u0434\u0443\u0433\u043E\u0442\u0440\u0430\u0458\u043D\u043E \u0441\u0430\u0447\u0443\u0432\u0430\u0442\u0435 +BuildAuthorizationToken.InvalidTokenProvided=\u0417\u0430\u0434\u0430\u0442\u0438 \u0442\u043E\u043A\u0435\u043D \u0458\u0435 \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u0430\u043D +Jenkins.CheckDisplayName.NameNotUniqueWarning=\u0418\u043C\u0435 "{0}", \u0441\u0435 \u0432\u0435\u045B \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u043A\u0430\u043E \u0438\u043C\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430, \u0448\u0442\u043E \u043C\u043E\u0436\u0435 \u0434\u043E\u0432\u0435\u0441\u0442\u0438 \u0434\u043E \u0437\u0431\u0443\u045A\u0443\u0458\u0443\u045B\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u043F\u0440\u0435\u0433\u0440\u0430\u0442\u0435. +Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=\u0418\u043C\u0435 "{0}", \u0441\u0435 \u0432\u0435\u045B \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u0434\u0440\u0443\u0433\u0438\u043C \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u043E\u043C, \u0448\u0442\u043E \u043C\u043E\u0436\u0435 \u0434\u043E\u0432\u0435\u0441\u0442\u0438 \u0434\u043E \u0437\u0431\u0443\u045A\u0443\u0458\u0443\u045B\u0430 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 \u043F\u0440\u0435\u0433\u0440\u0430\u0442\u0435. +Jenkins.NotAllowedName="{0}" \u0458\u0435 \u043D\u0435\u0434\u043E\u0437\u0432\u043E\u0459\u0435\u043D\u043E \u0438\u043C\u0435 +Jenkins.IsRestarting=Jenkins \u0441\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u045B\u0435 +User.IllegalUsername=\u041D\u0435 \u043C\u043E\u0436\u0435\u0442\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0438 "{0}" \u0437\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 \u0438\u0437 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u043D\u0438\u0445 \u0440\u0430\u0437\u043B\u043E\u0433\u0430. +User.IllegalFullname=\u041D\u0435 \u043C\u043E\u0436\u0435\u0442\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0438 "{0}" \u0437\u0430 \u043F\u0443\u043D\u043E \u0438\u043C\u0435 \u0438\u0437 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u043D\u0438\u0445 \u0440\u0430\u0437\u043B\u043E\u0433\u0430. +Hudson.NoParamsSpecified=\u041D\u0438\u0441\u0443 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 \u0437\u0430 \u043E\u0432\u0430\u0458 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438\u0437\u043E\u0432\u0430\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +CLI.delete-job.shortDescription=\u0423\u043A\u043B\u043E\u043D\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +CLI.reload-job.shortDescription=\u041F\u043E\u043D\u043E\u0432\u043E \u0443\u0447\u0438\u0442\u0430\u0458 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0438\u0437 \u0434\u0438\u0441\u043A\u0430 +CLI.delete-node.shortDescription=\u0423\u043A\u043B\u043E\u043D\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +CLI.disconnect-node.shortDescription=\u041F\u0440\u0435\u043A\u0438\u043D\u0438 \u0432\u0435\u0437\u0443 \u0441\u0430 \u043C\u0430\u0448\u0438\u043D\u043E\u043C +CLI.connect-node.shortDescription=\u041F\u043E\u0432\u0435\u0436\u0438 \u0441\u0430 \u043C\u0430\u0448\u0438\u043D\u043E\u043C +CLI.offline-node.shortDescription= +Hudson.NotADirectory={0} \u043D\u0438\u0458\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_sv_SE.properties b/core/src/main/resources/hudson/model/Messages_sv_SE.properties index 7c0ec4d60adb1b6cd0dc1ea1aff1545791ae073e..6376d4e09d876cc5c917d79d13cb5af28b376c7b 100644 --- a/core/src/main/resources/hudson/model/Messages_sv_SE.properties +++ b/core/src/main/resources/hudson/model/Messages_sv_SE.properties @@ -1,7 +1,9 @@ AbstractProject.Pronoun=Projekt -AbstractProject.BuildNow=Starta bygge nu Job.Pronoun=Projekt ManageJenkinsAction.DisplayName=Hantera Jenkins +ParametersDefinitionProperty.DisplayName=Detta bygge \u00E4r parametriserat + +FreeStyleProject.Description=Detta \u00E4r en central del i Jenkins. Jenkins kommer att bygga ditt projekt med valfri versionshanterare och med vilket byggsystem som helst, och detta kan \u00E4ven anv\u00E4ndas f\u00F6r n\u00E5got annat \u00E4n mjukvarubyggen. diff --git a/core/src/main/resources/hudson/model/Messages_tr.properties b/core/src/main/resources/hudson/model/Messages_tr.properties index 3ea32148cadfcfa2925ae4cd974445bc53238d39..ee48426b3bbec1890f26ac3613be1ace4a187e21 100644 --- a/core/src/main/resources/hudson/model/Messages_tr.properties +++ b/core/src/main/resources/hudson/model/Messages_tr.properties @@ -26,9 +26,7 @@ AbstractBuild.KeptBecause={0} y\u00fcz\u00fcnden tutulmu\u015f AbstractProject.NewBuildForWorkspace=\u00c7al\u0131\u015fma alan\u0131 olu\u015fturmak i\u00e7in bir yap\u0131land\u0131rma planlan\u0131yor AbstractProject.Pronoun=Proje AbstractProject.Aborted=Durduruldu -AbstractProject.BuildInProgress=Yap\u0131land\u0131rma #{0} zaten i\u015flemde {1} AbstractProject.Disabled=Yap\u0131land\u0131rma devre d\u0131\u015f\u0131 b\u0131rak\u0131ld\u0131 -AbstractProject.ETA=\ (ETA:{0}) AbstractProject.NoSCM=SCM yok AbstractProject.NoWorkspace=Herhangi bir \u00e7al\u0131\u015fma alan\u0131 bulunmad\u0131\u011f\u0131ndan g\u00fcncellemeler kontrol edilemiyor. AbstractProject.PollingABorted=SCM kontrol\u00fc durduruldu @@ -47,12 +45,16 @@ BallColor.Pending=Bekliyor BallColor.Success=Ba\u015far\u0131l\u0131 BallColor.Unstable=Dengesiz -Computer.Caption=Slave {0} Executor.NotAvailable=Mevcut De\u011fil FreeStyleProject.DisplayName=Serbest-stil yaz\u0131l\u0131m projesi yap\u0131land\u0131r +FreeStyleProject.Description=\ + Jenkins''\u0131n merkezi \u00f6zelli\u011fi, projelerinizi yap\u0131land\u0131rman\u0131za yard\u0131m etmesidir. Bu proje t\u00fcr\u00fcn\u00fc kullanarak, \ + herhangi bir yap\u0131land\u0131rma sistemini herhangi bir Kaynak Kodu Y\u00f6netimi arac\u0131 ile birle\u015ftirebilirsiniz,\ + ve hatta yaz\u0131l\u0131m yap\u0131land\u0131rman\u0131n d\u0131\u015f\u0131nda ba\u015fka t\u00fcr projeler i\u00e7in dahi kullanabilirsiniz. + Hudson.BadPortNumber=Yanl\u0131\u015f Port Numaras\u0131 {0} Hudson.Computer.Caption=Master @@ -89,19 +91,11 @@ Run.MarkedExplicitly=kayd\u0131 tutmak i\u00e7in d\u0131\u015far\u0131dan i\u015 Run.Permissions.Title=\u00c7al\u0131\u015ft\u0131r Run.UnableToDelete={0} silinemiyor: {1} -Slave.InvalidConfig.Executors={0} i\u00e7in ge\u00e7ersiz slave konfig\u00fcrasyonu. Ge\u00e7ersiz yap\u0131land\u0131r\u0131c\u0131 say\u0131s\u0131. -Slave.InvalidConfig.NoName=Ge\u00e7ersiz slave konfig\u00fcrasyonu. \u0130sim bo\u015f. -Slave.InvalidConfig.NoRemoteDir={0} i\u00e7in ge\u00e7ersiz slave konfig\u00fcrasyonu. Uzak dizin verilmedi. -Slave.Launching={0} slave ajan\u0131 \u00e7al\u0131\u015ft\u0131r\u0131yor -Slave.Terminated={0} slave ajan\u0131 sonland\u0131r\u0131ld\u0131 -Slave.UnableToLaunch={0} y\u00fcz\u00fcnden slave ajan\u0131 \u00e7al\u0131\u015ft\u0131r\u0131lamad\u0131 {1} -Slave.UnixSlave=Bu bir unix slave -Slave.WindowsSlave=Bu bir windows slave View.Permissions.Title=G\u00f6r\u00fcnt\u00fc Permalink.LastBuild=Son yap\u0131land\u0131rma Permalink.LastStableBuild=Son stabil yap\u0131land\u0131rma Permalink.LastSuccessfulBuild=Son ba\u015far\u0131l\u0131 yap\u0131land\u0131rma Permalink.LastFailedBuild=Son ba\u015far\u0131s\u0131z yap\u0131land\u0131rma -AbstractProject.BuildNow=\u015eimdi Yap\u0131land\u0131r ManageJenkinsAction.DisplayName=Jenkins''\u0131 Y\u00f6net +ParametersDefinitionProperty.DisplayName=Bu yap\u0131land\u0131rma parametrele\u015ftirilmi\u015ftir. diff --git a/core/src/main/resources/hudson/model/Messages_uk.properties b/core/src/main/resources/hudson/model/Messages_uk.properties new file mode 100644 index 0000000000000000000000000000000000000000..59c4b0bc962ac56b0e70d244425579486770e7d7 --- /dev/null +++ b/core/src/main/resources/hudson/model/Messages_uk.properties @@ -0,0 +1,3 @@ +ParametersDefinitionProperty.DisplayName=\u0426\u044F \u0431\u0443\u0434\u043E\u0432\u0430 \u043C\u0430\u0454 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 + +FreeStyleProject.Description=\u0426\u0435 - \u043E\u0441\u043D\u043E\u0432\u043D\u0430 \u0432\u0456\u0434\u043C\u0456\u043D\u043D\u0456\u0441\u0442\u044C Jenkins. Jenkins \u043F\u043E\u0431\u0443\u0434\u0443\u0454 \u0432\u0430\u0448 \u043F\u0440\u043E\u0435\u043A\u0442, \u043A\u043E\u043C\u0431\u0456\u043D\u0443\u044E\u0447\u0438 \u0431\u0443\u0434\u044C-\u044F\u043A\u0456 \u0441\u0438\u0441\u0442\u0435\u043C\u0438 \u0443\u043F\u0440\u0430\u0432\u043B\u0456\u043D\u043D\u044F \u043A\u043E\u0434\u043E\u043C \u0437 \u0431\u0443\u0434\u044C-\u044F\u043A\u0438\u043C\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u0430\u043C\u0438 \u0437\u0431\u0456\u0440\u043A\u0438, \u0449\u043E \u043C\u043E\u0436\u0435 \u0431\u0443\u0442\u0438 \u0432\u0438\u043A\u043E\u0440\u0438\u0441\u0442\u0430\u043D\u043E \u043D\u0430\u0432\u0456\u0442\u044C \u0434\u043B\u044F \u0446\u0456\u043B\u0435\u0439 \u0432\u0456\u0434\u043C\u0456\u043D\u043D\u0438\u0445 \u0432\u0456\u0434 \u0437\u0431\u0456\u0440\u043A\u0438 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043D\u043E\u0433\u043E \u0437\u0430\u0431\u0435\u0437\u043F\u0435\u0447\u0435\u043D\u043D\u044F. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Messages_zh_CN.properties b/core/src/main/resources/hudson/model/Messages_zh_CN.properties index 68850858d4c57e50d28625d88b15d23f351eba6a..1d07150da1dd3b8f0f677bcd3ca39a6bde929c19 100644 --- a/core/src/main/resources/hudson/model/Messages_zh_CN.properties +++ b/core/src/main/resources/hudson/model/Messages_zh_CN.properties @@ -29,10 +29,8 @@ AbstractItem.NoSuchJobExists=No such job ''{0}'' exists. Perhaps you meant ''{1} AbstractProject.NewBuildForWorkspace=Scheduling a new build to get a workspace. AbstractProject.Pronoun=Project AbstractProject.Aborted=Aborted -AbstractProject.BuildInProgress=Build #{0} is already in progress{1} AbstractProject.UpstreamBuildInProgress=Upstream project {0} is already building. AbstractProject.Disabled=Build disabled -AbstractProject.ETA=\ (ETA:{0}) AbstractProject.NoBuilds=No existing build. Scheduling a new one. AbstractProject.NoSCM=No SCM AbstractProject.NoWorkspace=No workspace is available, so can''t check for updates. @@ -62,30 +60,18 @@ BallColor.Pending=Pending BallColor.Success=Success BallColor.Unstable=Unstable -CLI.clear-queue.shortDescription=Clears the build queue -CLI.delete-job.shortDescription=Deletes a job CLI.disable-job.shortDescription=Disables a job CLI.enable-job.shortDescription=Enables a job -CLI.delete-node.shortDescription=Deletes a node CLI.disconnect-node.shortDescription=Disconnects from a node -CLI.connect-node.shortDescription=Reconnect to a node CLI.online-node.shortDescription=Resume using a node for performing builds, to cancel out the earlier "offline-node" command. -CLI.offline-node.shortDescription=Stop using a node for performing builds temporarily, until the next "online-node" command. -Computer.Caption=Slave {0} -Computer.Permissions.Title=Slave -Computer.ConfigurePermission.Description=This permission allows users to configure slaves. -Computer.DeletePermission.Description=This permission allows users to delete existing slaves. -Computer.BadChannel=Slave node offline or not a remote channel (such as master node). -ComputerSet.NoSuchSlave=No such slave: {0} -ComputerSet.SlaveAlreadyExists=Slave called ''{0}'' already exists -ComputerSet.SpecifySlaveToCopy=Specify which slave to copy ComputerSet.DisplayName=nodes Executor.NotAvailable=N/A FreeStyleProject.DisplayName=\u6784\u5efa\u4e00\u4e2a\u81ea\u7531\u98ce\u683c\u7684\u8f6f\u4ef6\u9879\u76ee +FreeStyleProject.Description=\u8FD9\u662FJenkins\u7684\u4E3B\u8981\u529F\u80FD.Jenkins\u5C06\u4F1A\u7ED3\u5408\u4EFB\u4F55SCM\u548C\u4EFB\u4F55\u6784\u5EFA\u7CFB\u7EDF\u6765\u6784\u5EFA\u4F60\u7684\u9879\u76EE, \u751A\u81F3\u53EF\u4EE5\u6784\u5EFA\u8F6F\u4EF6\u4EE5\u5916\u7684\u7CFB\u7EDF. HealthReport.EmptyString= @@ -173,16 +159,8 @@ Run.Summary.BrokenSinceThisBuild=broken since this build Run.Summary.BrokenSince=broken since build {0} Run.Summary.Unknown=? -Slave.InvalidConfig.Executors=Invalid slave configuration for {0}. Invalid # of executors. -Slave.InvalidConfig.NoName=Invalid slave configuration. Name is empty -Slave.InvalidConfig.NoRemoteDir=Invalid slave configuration for {0}. No remote directory given -Slave.Launching={0} Launching slave agent Slave.Network.Mounted.File.System.Warning=Are you sure you want to use network mounted file system for FS root? Note that this directory does not need to be visible to the master. Slave.Remote.Director.Mandatory=Remote directory is mandatory -Slave.Terminated={0} slave agent was terminated -Slave.UnableToLaunch=Unable to launch the slave agent for {0}{1} -Slave.UnixSlave=This is a Unix slave -Slave.WindowsSlave=This is a Windows slave View.Permissions.Title=View View.CreatePermission.Description=\ @@ -216,7 +194,6 @@ UpdateCenter.PluginCategory.post-build=Other Post-Build Actions UpdateCenter.PluginCategory.report=Build Reports UpdateCenter.PluginCategory.scm=Source Code Management UpdateCenter.PluginCategory.scm-related=Source Code Management related -UpdateCenter.PluginCategory.slaves=Slave Launchers and Controllers UpdateCenter.PluginCategory.trigger=Build Triggers UpdateCenter.PluginCategory.ui=User Interface UpdateCenter.PluginCategory.upload=Artifact Uploaders @@ -232,7 +209,6 @@ Permalink.LastSuccessfulBuild=Last successful build Permalink.LastFailedBuild=Last failed build ParameterAction.DisplayName=Parameters -ParametersDefinitionProperty.DisplayName=Parameters StringParameterDefinition.DisplayName=String Parameter FileParameterDefinition.DisplayName=File Parameter BooleanParameterDefinition.DisplayName=Boolean Value @@ -269,8 +245,5 @@ MyViewsProperty.ViewExistsCheck.AlreadyExists=A view with name {0} already exist CLI.restart.shortDescription=Restart Jenkins CLI.safe-restart.shortDescription=Safely restart Jenkins CLI.keep-build.shortDescription=Mark the build to keep the build forever. -CLI.quiet-down.shortDescription=Quiet down Jenkins, in preparation for a restart. Don''t start any builds. -CLI.cancel-quiet-down.shortDescription=Cancel the effect of the "quiet-down" command. -CLI.reload-configuration.shortDescription=Discard all the loaded data in memory and reload everything from file system. Useful when you modified config files directly on disk. -AbstractProject.BuildNow=\u7acb\u5373\u6784\u5efa ManageJenkinsAction.DisplayName=\u7cfb\u7edf\u7ba1\u7406 +ParametersDefinitionProperty.DisplayName=\u53C2\u6570\u5316\u6784\u5EFA\u8FC7\u7A0B diff --git a/core/src/main/resources/hudson/model/Messages_zh_TW.properties b/core/src/main/resources/hudson/model/Messages_zh_TW.properties index b6fd160a90b76490cf48314d44446af7124ecad6..2ffc39e21fd0b0d66b8dc09af5da1b6a4e8da174 100644 --- a/core/src/main/resources/hudson/model/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/model/Messages_zh_TW.properties @@ -29,17 +29,13 @@ AbstractBuild.KeptBecause=\u56e0\u70ba {0} \u800c\u4fdd\u7559 AbstractItem.NoSuchJobExists=\u6c92\u6709 ''{0}'' \u4f5c\u696d\u3002\u60a8\u6307\u7684\u662f ''{1}'' \u55ce? AbstractItem.Pronoun=\u4f5c\u696d -AbstractProject.AssignedLabelString_NoMatch_DidYouMean=\u6c92\u6709\u7b26\u5408\u7684\u7bc0\u9ede\u3002\u60a8\u60f3\u7684\u8a72\u4e0d\u6703\u662f ''{1}''\uff0c\u800c\u4e0d\u662f ''{0}'' \u5427? AbstractProject.NewBuildForWorkspace=\u6311\u500b\u6642\u9593\u5efa\u7f6e\uff0c\u5c31\u80fd\u7522\u751f\u5de5\u4f5c\u5340\u3002 AbstractProject.AwaitingBuildForWorkspace=\u7b49\u5019\u5efa\u7f6e\u7522\u51fa\u5de5\u4f5c\u5340\u3002 AbstractProject.Pronoun=\u5c08\u6848 AbstractProject.Aborted=\u4e2d\u65b7 -AbstractProject.BuildInProgress=\u5efa\u7f6e #{0} \u57f7\u884c\u4e2d{1} -AbstractProject.BuildNow=\u99ac\u4e0a\u5efa\u7f6e AbstractProject.UpstreamBuildInProgress=\u4e0a\u6e38\u5c08\u6848 {0} \u5efa\u7f6e\u4e2d\u3002 AbstractProject.DownstreamBuildInProgress=\u4e0b\u6e38\u5c08\u6848 {0} \u5efa\u7f6e\u4e2d\u3002 AbstractProject.Disabled=\u5efa\u7f6e\u505c\u7528 -AbstractProject.ETA=\ (\u9810\u4f30\u6642\u9593:{0}) AbstractProject.NoBuilds=\u6c92\u6709\u5efa\u7f6e\u8a18\u9304\u3002\u99ac\u4e0a\u5efa\u7f6e\u4e00\u6b21\u5427\u3002 AbstractProject.NoSCM=\u7121 SCM AbstractProject.NoWorkspace=\u6c92\u6709\u5de5\u4f5c\u5340\uff0c\u7121\u6cd5\u6aa2\u67e5\u66f4\u65b0\u3002 @@ -64,7 +60,6 @@ AbstractProject.CancelPermission.Description=\ \u6388\u8207\u53d6\u6d88\u5efa\u7f6e\u7684\u80fd\u529b\u3002 AbstractProject.AssignedLabelString.InvalidBooleanExpression=\ \u7121\u6548\u7684\u5e03\u6797\u8868\u793a\u5f0f: {0} -AbstractProject.AssignedLabelString.NoMatch=\ \u6c92\u6709\u7b26\u5408\u7684\u7bc0\u9ede AbstractProject.CustomWorkspaceEmpty=\u81ea\u8a02\u5de5\u4f5c\u5340\u662f\u7a7a\u7684\u3002 @@ -81,39 +76,22 @@ BallColor.Pending=\u64f1\u7f6e BallColor.Success=\u6210\u529f BallColor.Unstable=\u4e0d\u7a69\u5b9a -CLI.clear-queue.shortDescription=\u6e05\u9664\u5efa\u7f6e\u4f47\u5217\u3002 -CLI.delete-job.shortDescription=\u522a\u9664\u4f5c\u696d\u3002 CLI.disable-job.shortDescription=\u505c\u7528\u4f5c\u696d\u3002 CLI.enable-job.shortDescription=\u555f\u7528\u4f5c\u696d\u3002 -CLI.delete-node.shortDescription=\u522a\u9664\u6307\u5b9a\u7bc0\u9ede\u3002 CLI.disconnect-node.shortDescription=\u4e2d\u65b7\u8207\u6307\u5b9a\u7bc0\u9ede\u7684\u9023\u7dda\u3002 -CLI.connect-node.shortDescription=\u9023\u7dda\u5230\u6307\u5b9a\u7bc0\u9ede\u3002 CLI.online-node.shortDescription=\u7e7c\u7e8c\u4f7f\u7528\u6307\u5b9a\u7bc0\u9ede\u4f86\u5efa\u7f6e\uff0c\u53d6\u6d88\u5148\u524d\u7684 "offline-node" \u6307\u4ee4\u3002 -CLI.offline-node.shortDescription=\u66ab\u6642\u4e0d\u4f7f\u7528\u6307\u5b9a\u7bc0\u9ede\u4f86\u5efa\u7f6e\uff0c\u76f4\u5230\u57f7\u884c "online-node" \u6307\u4ee4\u70ba\u6b62\u3002 -CLI.wait-node-online.shortDescription=\u7b49\u5019\u6307\u5b9a\u7bc0\u9ede\u4e0a\u7dda\u3002 -CLI.wait-node-offline.shortDescription=\u7b49\u5019\u6307\u5b9a\u7bc0\u9ede\u96e2\u7dda\u3002 - -Computer.Caption=Slave {0} -Computer.NoSuchSlaveExists=\u6c92\u6709 Slave "{0}"\u3002\u60a8\u6307\u7684\u662f "{1}" \u55ce? -Computer.Permissions.Title=Slave -Computer.ConfigurePermission.Description=\u6388\u8207\u8a2d\u5b9a Slave \u7684\u6b0a\u9650\u3002 -Computer.DeletePermission.Description=\u6388\u8207\u522a\u9664\u65e2\u6709 Slave \u7684\u6b0a\u9650\u3002 -Computer.CreatePermission.Description=\u6388\u8207\u4f7f\u7528\u8005\u5efa\u7acb Slave \u7684\u6b0a\u9650\u3002 -Computer.ConnectPermission.Description=\u6388\u8207\u4f7f\u7528\u8005\u9023\u7dda\u5230 Slave \u6216\u662f\u5c07\u5176\u8a2d\u70ba\u4e0a\u7dda\u7684\u6b0a\u9650\u3002 -Computer.DisconnectPermission.Description=\u6388\u8207\u4f7f\u7528\u8005\u4e2d\u65b7 Slave \u9023\u7dda\uff0c\u6216\u5c07\u5176\u6a19\u793a\u70ba\u66ab\u6642\u96e2\u7dda\u3002 -Computer.BadChannel=Slave \u7bc0\u9ede\u96e2\u7dda\u6216\u4e0d\u662f\u9060\u7aef\u901a\u9053 (\u4f8b\u5982 Master \u7bc0\u9ede)\u3002 - -ComputerSet.NoSuchSlave=\u6c92\u6709 Slave: {0} -ComputerSet.SlaveAlreadyExists=\u5df2\u7d93\u6709\u53eb\u505a ''{0}'' \u7684 Slave \u4e86 -ComputerSet.SpecifySlaveToCopy=\u6307\u5b9a\u8981\u8907\u88fd\u7684 Slave + ComputerSet.DisplayName=\u7bc0\u9ede Descriptor.From=(from {0}) Executor.NotAvailable=N/A - FreeStyleProject.DisplayName=\u5efa\u7f6e Free-Style \u8edf\u9ad4\u5c08\u6848 +FreeStyleProject.Description=\ + \u9019\u662f Jenkins \u7684\u4e3b\u8981\u529f\u80fd\u3002\ + Jenkins \u80fd\u642d\u914d\u5404\u5f0f\u7a0b\u5f0f\u78bc\u7ba1\u7406\u3001\u5efa\u7f6e\u7cfb\u7d71\u4f86\u5efa\u7f6e\u60a8\u7684\u5c08\u6848\uff0c\ + \u751a\u81f3\u9084\u80fd\u505a\u8edf\u9ad4\u5efa\u7f6e\u4ee5\u5916\u7684\u5176\u4ed6\u4e8b\u60c5\u3002 Hudson.BadPortNumber=\u9023\u63a5\u57e0\u865f {0} \u7121\u6548 Hudson.Computer.Caption=Master @@ -217,16 +195,8 @@ Run.Summary.BrokenSinceThisBuild=\u5f9e\u9019\u6b21\u5efa\u7f6e\u958b\u59cb\u721 Run.Summary.BrokenSince=\u5f9e {0} \u6b21\u5efa\u7f6e\u958b\u59cb\u721b\u4e86 Run.Summary.Unknown=? -Slave.InvalidConfig.Executors=Slave {0} \u8a2d\u5b9a\u932f\u8aa4\u3002\u57f7\u884c\u7a0b\u5f0f\u6578\u7121\u6548\u3002 -Slave.InvalidConfig.NoName=Slave \u8a2d\u5b9a\u932f\u8aa4\u3002\u6c92\u6709\u6307\u5b9a\u540d\u7a31\u3002 -Slave.InvalidConfig.NoRemoteDir=Slave {0} \u8a2d\u5b9a\u932f\u8aa4\u3002\u6c92\u6709\u6307\u5b9a\u9060\u7aef\u76ee\u9304\u3002 -Slave.Launching={0} \u555f\u52d5 Slave \u4ee3\u7406\u7a0b\u5f0f Slave.Network.Mounted.File.System.Warning=\u60a8\u78ba\u5b9a\u8981\u4f7f\u7528\u7db2\u8def\u639b\u8f09\u7684\u6a94\u6848\u7cfb\u7d71\u505a\u70ba\u6839\u76ee\u9304\u55ce? \u9019\u500b\u76ee\u9304 Master \u4e0d\u9700\u8981\u8b93\u76f4\u63a5\u5b58\u53d6\u5594\u3002 Slave.Remote.Director.Mandatory=\u4e00\u5b9a\u8981\u6307\u5b9a\u9060\u7aef\u76ee\u9304 -Slave.Terminated={0} Slave \u4ee3\u7406\u7a0b\u5f0f\u5df2\u7d50\u675f -Slave.UnableToLaunch=\u7121\u6cd5\u555f\u52d5 Slave {0} \u7684\u4ee3\u7406\u7a0b\u5f0f{1} -Slave.UnixSlave=\u9019\u662f Unix slave -Slave.WindowsSlave=\u9019\u662f Windows slave View.Permissions.Title=\u8996\u666f View.CreatePermission.Description=\ @@ -265,7 +235,6 @@ UpdateCenter.PluginCategory.post-build=\u5176\u4ed6\u5efa\u7f6e\u5f8c\u52d5\u4f5 UpdateCenter.PluginCategory.report=\u5efa\u7f6e\u5831\u8868 UpdateCenter.PluginCategory.scm=\u539f\u59cb\u78bc\u7ba1\u7406 UpdateCenter.PluginCategory.scm-related=\u539f\u59cb\u78bc\u7ba1\u7406\u76f8\u95dc -UpdateCenter.PluginCategory.slaves=Slave \u555f\u52d5\u53ca\u63a7\u5236\u7a0b\u5f0f UpdateCenter.PluginCategory.trigger=\u5efa\u7f6e\u89f8\u767c\u7a0b\u5e8f UpdateCenter.PluginCategory.ui=\u4f7f\u7528\u8005\u4ecb\u9762 UpdateCenter.PluginCategory.upload=\u6210\u54c1\u4e0a\u50b3 @@ -281,7 +250,6 @@ Permalink.LastSuccessfulBuild=\u6700\u65b0\u6210\u529f\u5efa\u7f6e Permalink.LastFailedBuild=\u6700\u65b0\u5931\u6557\u5efa\u7f6e ParameterAction.DisplayName=\u53c3\u6578 -ParametersDefinitionProperty.DisplayName=\u53c3\u6578 StringParameterDefinition.DisplayName=\u5b57\u4e32\u53c3\u6578 TextParameterDefinition.DisplayName=\u6587\u5b57\u53c3\u6578 FileParameterDefinition.DisplayName=\u6a94\u6848\u53c3\u6578 @@ -320,9 +288,6 @@ MyViewsProperty.ViewExistsCheck.AlreadyExists=\u5df2\u7d93\u6709\u53eb\u505a "{0 CLI.restart.shortDescription=\u91cd\u65b0\u555f\u52d5 Jenkins CLI.safe-restart.shortDescription=\u5b89\u5168\u7684\u91cd\u65b0\u555f\u52d5 Jenkins CLI.keep-build.shortDescription=\u6c38\u4e45\u4fdd\u5b58\u9019\u6b21\u5efa\u7f6e\u3002 -CLI.quiet-down.shortDescription=\u8b93 Jenkins \u6c89\u6fb1\u4e00\u4e0b\uff0c\u6e96\u5099\u91cd\u65b0\u555f\u52d5\u3002\u5148\u4e0d\u8981\u518d\u5efa\u7f6e\u4efb\u4f55\u4f5c\u696d\u3002 -CLI.cancel-quiet-down.shortDescription=\u53d6\u6d88 "quiet-down" \u6307\u4ee4\u3002 -CLI.reload-configuration.shortDescription=\u653e\u68c4\u6240\u6709\u8a18\u61b6\u9ad4\u88e1\u7684\u8cc7\u6599\uff0c\u7531\u6a94\u6848\u7cfb\u7d71\u4e2d\u91cd\u65b0\u8f09\u5165\u3002\u9069\u5408\u5728\u76f4\u63a5\u4fee\u6539\u8a2d\u5b9a\u6a94\u5f8c\u4f7f\u7528\u3002 BuildAuthorizationToken.InvalidTokenProvided=\u63d0\u4f9b\u7684 Token \u7121\u6548\u3002 @@ -330,3 +295,4 @@ Jenkins.CheckDisplayName.NameNotUniqueWarning=\u5df2\u7d93\u6709\u4f5c\u696d\u53 Jenkins.CheckDisplayName.DisplayNameNotUniqueWarning=\u5df2\u7d93\u6709\u4f5c\u696d\u7684\u986f\u793a\u540d\u7a31\u662f "{0}"\uff0c\u53ef\u80fd\u6703\u9020\u6210\u6df7\u6dc6\u53ca\u5ef6\u9072\u3002 Jenkins.NotAllowedName="{0}" \u4e26\u4e0d\u662f\u53ef\u4ee5\u4f7f\u7528\u7684\u540d\u7a31 +ParametersDefinitionProperty.DisplayName=\u53c3\u6578\u5316\u5efa\u7f6e diff --git a/core/src/main/resources/hudson/model/MyView/newViewDetail_pl.properties b/core/src/main/resources/hudson/model/MyView/newViewDetail_pl.properties index ce3d5d1c9e159b478ce137233457384321a7c371..ceda1f8b13781375e38f065f2f38c2948b024c8e 100644 --- a/core/src/main/resources/hudson/model/MyView/newViewDetail_pl.properties +++ b/core/src/main/resources/hudson/model/MyView/newViewDetail_pl.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -blurb=Widok ten, automatycznie wy\u015Bwietla wszystkie prace do kt\u00F3rych aktualnie zalogowany u\u017Cytkownik ma dost\u0119p. +blurb=Widok ten automatycznie wy\u015Bwietla wszystkie zadania do kt\u00F3rych aktualnie zalogowany u\u017Cytkownik ma dost\u0119p. diff --git a/core/src/main/resources/hudson/model/MyView/newViewDetail_sr.properties b/core/src/main/resources/hudson/model/MyView/newViewDetail_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f0a62a8baabe166d1008f93a6f0359b73902f12a --- /dev/null +++ b/core/src/main/resources/hudson/model/MyView/newViewDetail_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u041E\u0432\u0430 \u043F\u0440\u0435\u0437\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0430 \u045B\u0435 \u0441\u0435 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u043F\u0440\u0438\u043A\u0430\u0437\u0438\u0432\u0430\u0442\u0438 \u0437\u0430 \u0441\u0432\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \u0437\u0430 \u043A\u043E\u0458\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A \u0438\u043C\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F. diff --git a/core/src/main/resources/hudson/model/MyView/noJob_sr.properties b/core/src/main/resources/hudson/model/MyView/noJob_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..bad4b3bbeff533b1ff600fe653e0d290bf947730 --- /dev/null +++ b/core/src/main/resources/hudson/model/MyView/noJob_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u041E\u0432\u0430\u0458 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 \u043D\u0435\u043C\u0430 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. diff --git a/core/src/main/resources/hudson/model/MyViewsProperty/config_de.properties b/core/src/main/resources/hudson/model/MyViewsProperty/config_de.properties index 27f8470a90c7e662a9f347fad15599760d1b0572..c1696ffbf7785727846160b899c4e82ddfdbffe4 100644 --- a/core/src/main/resources/hudson/model/MyViewsProperty/config_de.properties +++ b/core/src/main/resources/hudson/model/MyViewsProperty/config_de.properties @@ -1,24 +1,24 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Default\ View=Standardansicht +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Default\ View=Standardansicht description=Die Ansicht wird als Vorgabe ausgewhlt, wenn der Anwender seine privaten Ansichten ffnet. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/MyViewsProperty/config_pl.properties b/core/src/main/resources/hudson/model/MyViewsProperty/config_pl.properties index 807824ceee04381d548674ee27e5ea62d0f4ae88..df58035e37b344ad77e02b2bafd24b4fc30f543f 100644 --- a/core/src/main/resources/hudson/model/MyViewsProperty/config_pl.properties +++ b/core/src/main/resources/hudson/model/MyViewsProperty/config_pl.properties @@ -1,3 +1,4 @@ # This file is under the MIT License by authors description=Domy\u015Blny widok po przej\u015Bciu do strony ''''Moje widoki'''' +Default\ View=Domy\u015Blny widok diff --git a/core/src/main/resources/hudson/model/MyViewsProperty/config_sr.properties b/core/src/main/resources/hudson/model/MyViewsProperty/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0d21018daff85ed8610104ac00e1efd2fd05ddca --- /dev/null +++ b/core/src/main/resources/hudson/model/MyViewsProperty/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Default\ View=\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +description=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0458\u0435 \u0438\u0437\u0430\u0431\u0440\u0430\u043D \u043A\u0430\u0434\u0430 \u0441\u0435 \u0438\u0434\u0435 \u043D\u0430 \u043F\u0440\u0438\u0432\u0430\u0442\u043D\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 diff --git a/core/src/main/resources/hudson/model/MyViewsProperty/newView_de.properties b/core/src/main/resources/hudson/model/MyViewsProperty/newView_de.properties index 5b3a61d6aee418e2300842f5c9e1d02bb948721a..6784ce2341ea7f47fd07437b864074cb4484cc3f 100644 --- a/core/src/main/resources/hudson/model/MyViewsProperty/newView_de.properties +++ b/core/src/main/resources/hudson/model/MyViewsProperty/newView_de.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -View\ name=Name der Ansicht +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +View\ name=Name der Ansicht diff --git a/core/src/main/resources/hudson/model/MyViewsProperty/newView_sr.properties b/core/src/main/resources/hudson/model/MyViewsProperty/newView_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..14b8d5c30fff08a52195fd985618cb6c187405d4 --- /dev/null +++ b/core/src/main/resources/hudson/model/MyViewsProperty/newView_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +View\ name=\u0418\u043C\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 diff --git a/core/src/main/resources/hudson/model/NoFingerprintMatch/index_sr.properties b/core/src/main/resources/hudson/model/NoFingerprintMatch/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..fadf596940065e95a461869063e751d3b72dabbf --- /dev/null +++ b/core/src/main/resources/hudson/model/NoFingerprintMatch/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +No\ matching\ record\ found=\u041D\u0435 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430 \u043D\u0438 \u0458\u0435\u0434\u043D\u043E\u043C \u043E\u0434 \u0437\u0430\u0431\u0435\u043B\u0435\u0436\u0435\u043D\u0438\u0445 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430. +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043D\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 +description=\u041E\u0442\u0438\u0441\u0430\u043A {0} \u043D\u0435 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430 \u043D\u0438 \u0458\u0435\u0434\u043D\u043E\u043C \u043E\u0434 \u0437\u0430\u0431\u0435\u043B\u0435\u0436\u0435\u043D\u0438\u0445 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430. +cause.1=\u041C\u043E\u0433\u0443\u045B\u0435 \u0458\u0435 \u0434\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043D\u0438\u0458\u0435 \u043D\u0430\u043F\u0440\u0430\u0432\u0459\u0435\u043D\u0430 \u0443 Jenkins.\ +\u041C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u0434\u0430 \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0452\u0435\u043D\u043E \u043D\u0430 \u043B\u043E\u043A\u0430\u043B\u043D\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438 \u043D\u0435\u043A\u043E\u0433 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430. +cause.2=\u041C\u043E\u0436\u0434\u0430 \u043D\u0438\u0441\u0443 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \u0434\u043E\u0431\u0440\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u0438, \u0437\u0431\u043E\u0433 \u0447\u0435\u0433\u0430 \u043E\u0442\u0438\u0441\u0446\u0438 \u043D\u0435\u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0438. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430. diff --git a/core/src/main/resources/hudson/model/Node/help-labelString.html b/core/src/main/resources/hudson/model/Node/help-labelString.html index d6951e220f117011aa14746a18c203bdd4796fd2..a7cfc252c15fa86f8be421ec77a6e795a10721fd 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString.html @@ -1,11 +1,23 @@
    - Labels (AKA tags) are used for grouping multiple slaves into one logical group. - Use spaces between each label. For instance 'regression java6' will assign a - node the labels 'regression' and 'java6'. - -

    - For example, if you have multiple Windows slaves and you have jobs that require - Windows, then you can configure all your Windows slaves to have the label 'windows', - then tie the job to the 'windows' label. This allows your job to run on any - of your Windows slaves but not on anywhere else. -

    \ No newline at end of file + Labels (or tags) are used to group multiple agents into one logical group. +

    + For example, if you have multiple Windows agents and you have a job that + must run on Windows, then you could configure all your Windows agents to have + the label windows, and then tie that job to this label. +
    + This would ensure that your job runs on one of your Windows agents, but not on + any agents without this label. +

    + Labels do not necessarily have to represent the operating system on the agent; + you can also use labels to note the CPU architecture, or that a certain tool + is installed on the agent. +

    + Multiple labels must be separated by a space. For example, + windows docker would assign two labels to the agent: windows + and docker. +

    + Labels may contain any non-space characters, but you should avoid special + characters such as any of these: !&|<>(), as other Jenkins + features allow for defining label expressions, where these characters may be + used. +

    diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_de.html b/core/src/main/resources/hudson/model/Node/help-labelString_de.html deleted file mode 100644 index 10fc53a877cdefe9c074c35e709b33ddba86158b..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-labelString_de.html +++ /dev/null @@ -1,11 +0,0 @@ -
    - Gruppen (auch: Labels oder Tags) werden benutzt, um mehrere Slave-Knoten in eine - logische Gruppe zusammenzufassen. Die Angabe 'regression java6' ordnet beispielsweise - einen Knoten den Gruppen 'regression' und 'java6' zu. -

    - Beispiel: Sie haben mehrere Slave-Knoten unter Windows und einen Job, der Windows - erfordert. Sie können dann alle Ihre Windows-Slave-Knoten unter der Gruppe - "windows" zusammenfassen und den Job an die Gruppe "windows" binden. - Dadurch kann Ihr Job jedem der Windows-Slave-Knoten zugewiesen werden - aber - keinem anderen Slave-Knoten sonst. -

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_pt_BR.html b/core/src/main/resources/hudson/model/Node/help-labelString_pt_BR.html deleted file mode 100644 index 685874ebc99440da22c0b8026ed9cbe4935b1ada..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-labelString_pt_BR.html +++ /dev/null @@ -1,9 +0,0 @@ -
    - Marcações também são usadas para agrupar múltiplos slaves em um grupo lógico. - -

    - Por exemplo, se você tem múltiplos slaves Windows e você tem tarefas que requerem - Windows, então você pode configurar todos seus slaves Windows para ter a marcação 'windows', - então amarre a tarefa à marcação 'windows'. Isto permite que sua tarefa executar apenas - nos seus slaves Windows. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_ru.html b/core/src/main/resources/hudson/model/Node/help-labelString_ru.html index af406c385c39c605e7f0d589996d72f73acd3d75..9d6a2098fef3eee398cd7a0e8eb41a201ea9ff6c 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString_ru.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString_ru.html @@ -1,11 +1,20 @@ 
    - Метки (ярлыки) используются для группирования нескольких узлов в одну - логическую группу. - -

    - Например, если у вас есть несколько узлов под управлением ОС Windows и проекты, требующие - для сборки эту ОС, вы можете присвоить таким узлам метку 'windows', - и затем связать проект с этой меткой. Теперь ваши сборки будут выполняться только на - узлах с меткой 'windows'. Это позволяет добавлять и удалять узлы из сборочного пула, - не переконфигурируя каждый из проектов, использующих эти узлы. + Метки (ярлыки) используются для группирования нескольких узлов в одну логическую группу. +

    + Например, если у вас есть несколько узлов под управлением ОС Windows и проекты, требующие + для сборки эту ОС, вы можете присвоить таким узлам метку windows, + и затем связать проект с этой меткой. +
    + Это гарантирует сборку проекта на одном из узлов под управлением ОС Windows, а не на + других узлах, не помеченных ярлыком 'windows'. +

    + Метки не обязательно описывают ОС узла: они могут также использоваться для обозначения + архитектуры CPU или наличия определённого ПО. +

    + Метки разделяются пробелами. Например, строка windows docker пометит узел двумя + метками: windows и docker. +

    + Метки могут содержать любые непробельные знаки, однако, следует избегать следующих + специальных символов: !&|<>(), так как они могут быть некорректно + обработаны в других местах.

    diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_tr.html b/core/src/main/resources/hudson/model/Node/help-labelString_tr.html deleted file mode 100644 index bdd2019e65e00d14e2f1dded0283e30bee4f0ee6..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-labelString_tr.html +++ /dev/null @@ -1,11 +0,0 @@ -
    - Etiketler (diğer adıyla tag'ler) birden fazla slave'i mantıklı bir grup içinde birleştirmek - için kullanılır. - -

    - Mesela, birden fazla Windows slave'iniz varsa ve bazı işlerinizin Windows üzerinde çalışması - gerekiyorsa, bu durumda Windows slave'lerini 'windows' etiketi ile birleştirip, çalıştırmak - istediğiniz işe, çalışacağı yer olarak 'windows' etiketini vermeniz yeterli olacaktır. - Ayarlarınızı bu şekilde yaparsanız, istediğiniz işler, windows slave'lerinden başka yerde - çalıştırılmayacaktır. -

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_zh_CN.html b/core/src/main/resources/hudson/model/Node/help-labelString_zh_CN.html index e45d74fc00db4a5c525ed9bdad4c9d1bc30d31df..63e825a3b3a60c4fd93663e36920ea06ad83e469 100644 --- a/core/src/main/resources/hudson/model/Node/help-labelString_zh_CN.html +++ b/core/src/main/resources/hudson/model/Node/help-labelString_zh_CN.html @@ -1,7 +1,7 @@ -
    - 标记(又叫做标签)用来对多节点分组,标记之间用空格分隔.例如'refression java6'将会把一个节点标记上'regression'和'java6'. - -

    - 举例来说,如果你有多个Windows系统的构建节点并且你的Job也需要在Windows系统上运行,那么你可以配置所有的Windows系统节点都标记为'windows', - 然后把Job也标记为'windows'.这样的话你的Job就不会运行在除了Windows节点以外的其它节点之上了. +

    + 标记(又叫做标签)用来对多节点分组,标记之间用空格分隔.例如'refression java6'将会把一个节点标记上'regression'和'java6'. + +

    + 举例来说,如果你有多个Windows系统的构建节点并且你的Job也需要在Windows系统上运行,那么你可以配置所有的Windows系统节点都标记为'windows', + 然后把Job也标记为'windows'.这样的话你的Job就不会运行在除了Windows节点以外的其它节点之上了.

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Node/help-labelString_zh_TW.html b/core/src/main/resources/hudson/model/Node/help-labelString_zh_TW.html deleted file mode 100644 index 0e3a303930bb2aa0fa0f05ff589b914da50ec54d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-labelString_zh_TW.html +++ /dev/null @@ -1,9 +0,0 @@ -
    - 標籤可以將多個 Slave 進行邏輯分類。 - 不同的標籤之間請以空格隔開。例如 'regression java6' 代表將節點貼上 'regression' 跟 'java6' 兩個標籤。 - -

    - 舉例來說,如果您有多部 Windows 的 Slave,而且有只能在 Windows 平台上跑的作業, - 那麼就可以把這些 Windows Slave 標上 'windows' 標籤,並將作業限定成只能在 'windows' 標籤上跑。 - 這麼一來,您的作業就只能在 Windows 的 Slave 上面跑。 -

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/Node/help-name.html b/core/src/main/resources/hudson/model/Node/help-name.html index dd66b5aa64b6166858281d0e74bd4a4c2ee78353..aa412606d46e11ed27736da2963bc32fab6784df 100644 --- a/core/src/main/resources/hudson/model/Node/help-name.html +++ b/core/src/main/resources/hudson/model/Node/help-name.html @@ -1,7 +1,10 @@
    - Name that uniquely identifies a slave within this Jenkins installation. - + Name that uniquely identifies an agent within this Jenkins installation.

    - This value could be any string, and doesn't have to be the same as the slave host name, - but it's often convenient to make them the same. + This does not have to be the same as the agent hostname (where applicable), + but it is often convenient to make them the same. +

    + The name may not contain any characters from this list: + ?*/\%!@#$^&|<>[]:; +

    diff --git a/core/src/main/resources/hudson/model/Node/help-name_de.html b/core/src/main/resources/hudson/model/Node/help-name_de.html deleted file mode 100644 index ce4e888b20a7af203bf15ea21fd2d6475c90dce8..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-name_de.html +++ /dev/null @@ -1,8 +0,0 @@ -
    - Name, der einen Slave-Knoten eindeutig innerhalb dieser Jenkins-Installation identifiziert. - -

    - Dieser Wert kann zwar beliebig gewählt werden und muß nicht zwingend mit dem Rechnernamen - des Slave-Knoten übereinstimmen - aber in vielen Fällen ist diese einfache Konvention - sehr praktisch. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-name_pt_BR.html b/core/src/main/resources/hudson/model/Node/help-name_pt_BR.html deleted file mode 100644 index 3be3f19567fde8a1bd8cedec4c0e582ef132e133..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-name_pt_BR.html +++ /dev/null @@ -1,7 +0,0 @@ -
    - Nome que identifica unicamente um slave dentro deste instalação do Jenkins. - -

    - Este valor poderia ser qualquer string, e não tem que ser o mesmo nome do host slave, - mas é conveniente mantê-los iguais. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-name_ru.html b/core/src/main/resources/hudson/model/Node/help-name_ru.html index 0cedb6cab30aeb8a688d4630148fffb81e8987d9..c789319f388d59c3803969bf10d53ea2c3d67289 100644 --- a/core/src/main/resources/hudson/model/Node/help-name_ru.html +++ b/core/src/main/resources/hudson/model/Node/help-name_ru.html @@ -1,7 +1,10 @@ 
    - Имя которое уникальным образом определяет узел в данной инсталляции Jenkins. - + Имя, уникальным образом определяющее узел в данной инсталляции Jenkins.

    - Значением может быть любая строка и необязательно совпадающая с именем хоста, который - присвоен узлу, но обычно принято делать их одинаковыми. + Значением может быть любая строка и необязательно совпадающая с именем хоста, который + присвоен узлу, но обычно принято делать их одинаковыми. +

    + Имя не может содержать следующие символы: + ?*/\%!@#$^&|<>[]:; +

    diff --git a/core/src/main/resources/hudson/model/Node/help-name_tr.html b/core/src/main/resources/hudson/model/Node/help-name_tr.html deleted file mode 100644 index 7aff93778fadc0e279176c7b7a63524596becf64..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-name_tr.html +++ /dev/null @@ -1,7 +0,0 @@ -
    - İsim, slave'e içerisinde bulunduğu Jenkins'da belirleyici bir tanım verir. - -

    - Bu değer bir string olabilir, ve host ismi ile aynı olmak zorunda değildir, ama anlamlı - olması için aynı vermek bazen uygun olabilir. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-name_zh_TW.html b/core/src/main/resources/hudson/model/Node/help-name_zh_TW.html deleted file mode 100644 index 3952c09cdb40e7c34c02b8d89600eeb964000147..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-name_zh_TW.html +++ /dev/null @@ -1,6 +0,0 @@ -
    - 在 Jenkins 中能亳無疑問識別出這個 Slave 的名稱。 - -

    - 名稱可以隨便您取。雖然不一定要是 Slave 的主機名稱,但是設成跟主機名稱一樣會比較方便。 -

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors.html b/core/src/main/resources/hudson/model/Node/help-numExecutors.html index f8dd8a46a925443f4fcc9154f2dc983287df03d7..6e23a37a77c4a499d7a65b12283dfd5bd65c01d1 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors.html @@ -1,15 +1,18 @@
    - This controls the number of concurrent builds that Jenkins can perform. So the value - affects the overall system load Jenkins may incur. - A good value to start with would be the number of processors on your system. - + The maximum number of concurrent builds that Jenkins may perform on this + agent.

    - Increasing this value beyond that would cause each build to take longer, but it could increase - the overall throughput, because it allows CPU to build one project while another build is waiting - for I/O. - + A good value to start with would be the number of CPU cores on the machine. + Setting a higher value would cause each build to take longer, but could + increase the overall throughput. For example, one build might be CPU-bound, + while a second build running at the same time might be I/O-bound — so + the second build could take advantage of the spare I/O capacity at that + moment.

    - When using Jenkins in the master/slave mode, setting this value to 0 would prevent the master - from doing any building on its own. Slaves may not have zero executors, but may be - temporarily disabled using the button on the slave's status page. + Agents must have at least one executor. To temporarily prevent any builds from + being executed on an agent, use the Mark this node temporarily offline + button on the agent's page. +

    + This does not apply to the Jenkins master — setting the number of + executors to zero will prevent any builds from being executed on the master.

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_de.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_de.html deleted file mode 100644 index f9427704b5a625d4d799bcb597ed529696fe89ae..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_de.html +++ /dev/null @@ -1,19 +0,0 @@ -
    - Diese Einstellung legt die Anzahl gleichzeitiger Build-Prozesse in Jenkins fest. - Sie beeinflusst daher die Gesamtlast, die Jenkins auf einem System erzeugen kann. - Ein guter Ausgangspunkt wäre die Anzahl der CPUs Ihres Systems. - -

    - - Eine Erhöhung der Anzahl über diesen Wert hinaus würde zunächst die einzelnen Builds - verlängern, könnte aber insgesamt den Durchsatz erhöhen, weil es den CPUs erlaubt, - an einem Build zu rechnen, während ein anderer Build wegen Ein-/Ausgabeoperationen - wartet. - -

    - - Falls Jenkins im Master/Slave-Modus betrieben wird, legt ein Wert von 0 auf dem Master - fest, daß ausschließlich auf den Slaves Build-Prozesse durchgeführt werden, nie aber - auf dem Master selbst. Slaves müssen mindestens 1 Build-Prozessor bereitstellen, können - aber temporär durch eine Schaltfläche auf der Statusseite des Slaves deaktiviert werden. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html index 2ff14c73c1b01984ffda6174f9f80ff9c87e5ac3..4f454f4841f3917e3a6b034c837e4f5cb7f57466 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors_fr.html @@ -1,16 +1,16 @@
    - Ceci contrle le nombre de builds simultans que Jenkins peut excuter. - Cette valeur impacte donc la charge gnrale du systme. + Ceci contrôle le nombre de builds simultanés que Jenkins peut exécuter. + Cette valeur impacte donc la charge générale du système. Une bonne valeur pour commencer serait le nombre de processeurs sur - votre systme. + votre systéme.

    - Un nombre de builds simultans suprieur cette valeur augmentera la - dure individuelle de chaque build. Nanmoins, la capacit globale - peut tre suprieure, puisqu'un processeur peut se charger d'un build - pendant qu'un autre build est en attente sur les entres/sorties. + Un nombre de builds simultanés supérieur à cette valeur augmentera la + durée individuelle de chaque build. Néanmoins, la capacité globale + peut être supérieure, puisqu'un processeur peut se charger d'un build + pendant qu'un autre build est en attente sur les entrées/sorties.

    - En mode matre/esclave, une valeur de 0 garantit que le matre ne fera - pas lui-mme de build. + En mode maître/esclave, une valeur de 0 garantit que le maître ne fera + pas lui-même de build.

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_pt_BR.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_pt_BR.html deleted file mode 100644 index 01b4537b2f44444dcab5406f675a9489da2ccae6..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_pt_BR.html +++ /dev/null @@ -1,13 +0,0 @@ -
    - Isto controla o número de construções concorrentes que o Jenkins pode executar. Assim o valor - afeta toda a carga do sistema que o Jenkins pode sustentar. - Um bom valor para iniciar seria o número de processadores em seu sistema. - - Aumentando este valor além disso pode causar lentidão na construção, mas também pode aumentar - a capacidade total, porque permite a CPU construir um projeto enquanto uma outra construção - está aguardando por operação de E/S. - -

    - Quando usando o Jenkins no modo master/slave, atribuir este valor a 0 evitará que o master - faça qualquer construção nele mesmo. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_ru.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_ru.html index c743a9ff4ce43cda1aecee3f7459cbc10004c1e4..37e8012ac5723f904764aa78bd01009e81dda341 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_ru.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors_ru.html @@ -1,15 +1,17 @@ 
    Эта опция контролирует количество одновременных сборок, которые может производить Jenkins. - Таким образом, значение определяет результирующую нагрузку на сервер, которую может - вызвать. Для начала установите это значение равным количеству процессоров в вашей системе. -

    - Увеличивая это значение далее, вы можете заметить увеличение продолжительности каждой - сборки, однако результирующая пропускная способность увеличитcя, так как это позволит - процессору выполнять одну из сборок в то время как другая сборка ожидает - окончания операции ввода-вывода. - + Таким образом, значение определяет результирующую нагрузку на сервер, которую может + вызвать. Для начала установите это значение равным количеству процессоров в вашей системе. + Увеличивая это значение далее, вы можете заметить увеличение продолжительности каждой + сборки, однако результирующая пропускная способность увеличитcя, так как это позволит + процессору выполнять одну из сборок в то время как другая сборка ожидает + окончания операции ввода-вывода.

    - Используя Jenkins в режиме мастер/рабочий, установка значения в 0 запретит мастеру - выполнять сборки самостоятельно. + Узлы должны иметь минимум один сборщик. Чтобы временно приостановить выполнение сборок + на узле, используйте кнопку Пометить данный узел как временно недоступный на + странице настройки узла. +

    + Это не применимо для мастер-узла — установка значения в 0 запретит мастеру + выполнять сборки самостоятельно.

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_tr.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_tr.html deleted file mode 100644 index cef65e409c70cadcb7ddf5d56dc602e036f6066e..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_tr.html +++ /dev/null @@ -1,14 +0,0 @@ -
    - Jenkins'ın bu slave üzerinde eş zamanlı kaç tane yapılandırma yürütebileceğini kontrol eder. - Yani, buraya girilecek değer, Jenkins'ın ne kadar yüke maruz kalacağını belirler. - Başlangıç için, işlemci sayısı iyi bir rakam olabilir. - -

    - Bu sayıyı artırmak, yapılandırmaların daha uzun sürmesine yol açsa da, toplam üretim kapasitesinde bir - artış sağlayacaktır, çünkü bu durum, bir yapılandırma I/O için beklerken, CPU'nun başka bir yapılandırma - ile uğraşmasına yol açacaktır. - -

    - Bu değeri 0 yapmak, Jenkins'ın, konfigürasyonunu kaybetmeden, devre dışı bırakılmış bir slave'i - silmesine olanak tanır. -

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_CN.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_CN.html index 9f66f26bc6aa0ecff6dacd8e55a1cbc789c0b95a..a77b70de8eb835d77998532dca26d010a7f7795e 100644 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_CN.html +++ b/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_CN.html @@ -1,11 +1,11 @@ -
    - 这个值控制着Jenkins并发构建的数量. - 因此这个值会影响Jenkins系统的负载压力. - 使用处理器个数作为其值会是比较好的选择. - -

    - 增大这个值会使每个构建的运行时间更长,但是这能够增大整体的构建数量,因为当一个项目在等待I/O时它允许CPU去构建另一个项目. - -

    - 设置这个值为0对于从Jenkins移除一个失效的从节点非常有用,并且不会丢失配置信息。 -

    +
    + 这个值控制着Jenkins并发构建的数量. + 因此这个值会影响Jenkins系统的负载压力. + 使用处理器个数作为其值会是比较好的选择. + +

    + 增大这个值会使每个构建的运行时间更长,但是这能够增大整体的构建数量,因为当一个项目在等待I/O时它允许CPU去构建另一个项目. + +

    + 设置这个值为0对于从Jenkins移除一个失效的从节点非常有用,并且不会丢失配置信息。 +

    diff --git a/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_TW.html b/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_TW.html deleted file mode 100644 index fd7b2ade67ed7352d48633998f6f25a0cdbc48db..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Node/help-numExecutors_zh_TW.html +++ /dev/null @@ -1,12 +0,0 @@ -
    - 控制 Jenkins 可以同時執行的建置數,可能會對 Jenkins 整體負載造成影響。 - 如果不知道該怎麼調整,建議您先設成跟系統處理器數目一樣的值。 - -

    - 增加這個值可能會讓每一次建置都變慢,但是可以增加整體處理效率。 - 因為專案在等候 I/O 時,CPU 還是能建置其他專案。 - -

    - 以 Master/Slave 模式使用 Jenkins 時,設定成 0 可以讓 Master 不要自己建置專案。 - Slave 應該不會半個執行程式都沒有,如果您想要暫時停用該 Slave 的話,可以透過它狀態頁中的按鈕達成。 -

    diff --git a/core/src/main/resources/hudson/model/ParametersAction/index.jelly b/core/src/main/resources/hudson/model/ParametersAction/index.jelly index 2c25579adcd2ace3e9f8c02960e87f95ac57fa94..72ed664c447665a08eaea60229fc43f8c5ff69dd 100644 --- a/core/src/main/resources/hudson/model/ParametersAction/index.jelly +++ b/core/src/main/resources/hudson/model/ParametersAction/index.jelly @@ -35,12 +35,21 @@ THE SOFTWARE.

    ${%Build} ${build.displayName}

    - - - - - +
    +
    +
    ${%Parameters}
    +
    + + + + + + +
    +
    +
    +
    diff --git a/core/src/main/resources/hudson/model/ParametersAction/index_sr.properties b/core/src/main/resources/hudson/model/ParametersAction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4063f794159a272a09e208265fcc14e06032caaf --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersAction/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Build=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Parameters=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details.jelly b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details.jelly new file mode 100644 index 0000000000000000000000000000000000000000..a2d545e0d3f0874c32f33f8e500d4edecfd8bf1c --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details.jelly @@ -0,0 +1,30 @@ + + + + + + + + diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_bg.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..c800c695876638ff007395af77d58bfe6aaa8ad6 --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add\ Parameter=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u044a\u0440 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ca.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ca.properties similarity index 100% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ca.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ca.properties diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_da.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_da.properties similarity index 95% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_da.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_da.properties index f18767a9ff2521145a3c3cf0b7b40623373b18b3..3b313b6542412539fabd6bc0486ebe7cfe586f59 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_da.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_da.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Add\ Parameter=Tilf\u00f8j Parametre -This\ build\ is\ parameterized=Dette byg er parameteriseret diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_de.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..315117f2c31c2abf02e15581fcc8617b063c5bd5 --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_de.properties @@ -0,0 +1 @@ +Add\ Parameter=Parameter hinzufgen diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_es.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_es.properties similarity index 94% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_es.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_es.properties index 29bf30e7594c0a25da45da0ef2a45bf299f4cdfc..dbfed3fa2544887e54505fecf30442e83f2ef935 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_es.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_es.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ build\ is\ parameterized=Esta ejecucin debe parametrizarse Add\ Parameter=Aadir un parmetro diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_fi.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_fi.properties similarity index 100% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_fi.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_fi.properties diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_fr.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_fr.properties similarity index 95% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_fr.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_fr.properties index 6c9fe1823c0ea9509d174f71614c2327bb57b5b3..bab6b2cbeabdb71d2be6228a79abb2c1e706c5ea 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_fr.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_fr.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ build\ is\ parameterized=Ce build a des paramtres Add\ Parameter=Ajouter un paramtre diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_he.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_he.properties new file mode 100644 index 0000000000000000000000000000000000000000..3ffb627eec0d0fb383684947dc25905e88ed7bdd --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_he.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Add\ Parameter=\u05D4\u05D5\u05E1\u05E3 \u05DE\u05E9\u05EA\u05E0\u05D4 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_hu.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_hu.properties similarity index 69% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_hu.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_hu.properties index 7eb7f4cee30b553b75d22221e648ea17aad70143..265e1c7a5cb0744c562212a23e59e9024842e764 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_hu.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_hu.properties @@ -1,4 +1,3 @@ # This file is under the MIT License by authors Add\ Parameter=Param\u00E9ter hozz\u00E1ad\u00E1sa -This\ build\ is\ parameterized=Hozz\u00E1ad diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_it.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_it.properties similarity index 94% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_it.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_it.properties index df1251f2fd0713259d30df1a3c0f95ef92f6b9da..a362612239e9fc6da39e225cf2a75870a65b6edc 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_it.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_it.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Add\ Parameter=Aggiungi Parametro -This\ build\ is\ parameterized=Questa build \u00E8 parametrizzata diff --git a/core/src/main/resources/hudson/model/Computer/_script_fr.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ja.properties similarity index 88% rename from core/src/main/resources/hudson/model/Computer/_script_fr.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ja.properties index 78ac8fcafca9d5dcfc5f59b613721cc7c68871fa..c4fabe7ca95ee646be1499fadbea9d7d70c44f9f 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_fr.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ja.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=Cette excution a lieu sur la JVM de l''agent Jenkins sur l''esclave. +Add\ Parameter=\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u8ffd\u52a0 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ko.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ko.properties new file mode 100644 index 0000000000000000000000000000000000000000..6ebd2a13ecaa81ebe1be68754ef059a684b244a0 --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ko.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Add\ Parameter=\uB9E4\uAC1C\uBCC0\uC218 \uCD94\uAC00 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_lt.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_lt.properties similarity index 57% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_lt.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_lt.properties index 4c66949799af17a1dc2bac0f338fbbaf624350a6..d1aace2dae62c9969a870e18d686bc30e2ffa854 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_lt.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_lt.properties @@ -1,4 +1,3 @@ # This file is under the MIT License by authors Add\ Parameter=Prid\u0117ti parametr\u0105 -This\ build\ is\ parameterized=\u0160is darbas yra parametrizuotas diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_lv.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_lv.properties similarity index 100% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_lv.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_lv.properties diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_nb_NO.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_nb_NO.properties similarity index 95% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_nb_NO.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_nb_NO.properties index 7a09188ef889f25bf028f84af446b36ad468ca48..0e081ccb9fb5b8e2c0724e1459398a7726eb0c73 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_nb_NO.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_nb_NO.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Add\ Parameter=Legg til parameter -This\ build\ is\ parameterized=Denne build har parametre diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_nl.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_nl.properties similarity index 55% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_nl.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_nl.properties index 7b7fe50685655e2144d8016278afee46e00bef6f..dcdd5a5287d8b0179d9546c9be92963399ce81dd 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_nl.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_nl.properties @@ -1,4 +1,3 @@ # This file is under the MIT License by authors Add\ Parameter=Instelling toevoegen -This\ build\ is\ parameterized=Deze bouwpoging is geparametriseerd diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_pl.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_pl.properties similarity index 94% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_pl.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_pl.properties index 3fccb98d7ae1053fe32cfb44ca31765aecf57ad0..e929a96a2ccaa7dac993a9c969d9dcc422d94d7b 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_pl.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_pl.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Add\ Parameter=Dodaj parametr -This\ build\ is\ parameterized=Ten build jest sparametryzowany diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_pt_BR.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_pt_BR.properties similarity index 95% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_pt_BR.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_pt_BR.properties index 602308ba2224dd17f4231f14ef66ecbcd12f65de..0f269cfdd6894eb3d4d48e9a1855644616f962a9 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_pt_BR.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_pt_BR.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ build\ is\ parameterized=Este build \u00E9 parametrizado Add\ Parameter=Adicionar par\u00e2metro diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ro.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ro.properties similarity index 57% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ro.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ro.properties index 1f84c50491177cb89cf4465993fd21cc2797c430..bda5b182eb53f3df4045c723d79c8b1d55fe84d8 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ro.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ro.properties @@ -1,4 +1,3 @@ # This file is under the MIT License by authors Add\ Parameter=Adauga Parametru -This\ build\ is\ parameterized=Acest build este parametrizat diff --git a/core/src/main/resources/hudson/model/Computer/_script_sv_SE.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ru.properties similarity index 90% rename from core/src/main/resources/hudson/model/Computer/_script_sv_SE.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ru.properties index e1d01dd5a88f31098d9e468a82953a8d735f5c86..af02f213e56ae8d96930b12c680ee2a21d8ffbca 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_sv_SE.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_ru.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=Detta utf\u00F6rs p\u00E5 nodens JVM. +Add\ Parameter=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_sk.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sk.properties similarity index 53% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_sk.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sk.properties index bcc1f6c9c4f998b7a4febc6650393c037d1675a8..2dbb26fa0301e89a9c58ca410944aceb410b3723 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_sk.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sk.properties @@ -1,4 +1,3 @@ # This file is under the MIT License by authors Add\ Parameter=Pridaj parameter -This\ build\ is\ parameterized=Toto zostavenie je parametrizovan\u00E9 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sr.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a85431294b30cb99b5f73f704d08363cebac4c4a --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Add\ Parameter=\u0414\u043E\u0434\u0430\u0458 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0430\u0440 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_sv_SE.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sv_SE.properties similarity index 94% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_sv_SE.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sv_SE.properties index d2cac0e4bbf5e1f1863cae84b7da1452f0203ee0..9c8d2bc11650417404a4e4744c1d79de5d734f70 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_sv_SE.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_sv_SE.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Add\ Parameter=L\u00E4gg till parameter -This\ build\ is\ parameterized=Detta bygge \u00E4r parametriserat diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_tr.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_tr.properties similarity index 92% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_tr.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_tr.properties index 269e5de81bbe610c7b59dab2a25c551a9c5672c4..3ce3029f744969f02a419e6044308f29825a13f5 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_tr.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_tr.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ build\ is\ parameterized=Bu yap\u0131land\u0131rma parametrele\u015ftirilmi\u015ftir. Add\ Parameter=Parametre ekle diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_uk.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_uk.properties new file mode 100644 index 0000000000000000000000000000000000000000..0c6b712511d6cacec9b6039c953373965886a0ff --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_uk.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Add\ Parameter=\u0414\u043E\u0434\u0430\u0442\u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_zh_CN.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_zh_CN.properties similarity index 94% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_zh_CN.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_zh_CN.properties index b760379d98691b2ff8007b461d0795ff6b70b225..572578efad90ad55c3f899f7c4afaed0022fba93 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_zh_CN.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_zh_CN.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. Add\ Parameter=\u6DFB\u52A0\u53C2\u6570 -This\ build\ is\ parameterized=\u53C2\u6570\u5316\u6784\u5EFA\u8FC7\u7A0B diff --git a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_zh_TW.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_zh_TW.properties similarity index 96% rename from test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_zh_TW.properties rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_zh_TW.properties index 16bed198fe4e0b226bb759221326742ca560e783..1ba5e442e094b6dbf4eda8b6a88c0ef98b5be8f1 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_zh_TW.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config-details_zh_TW.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Save=\u5132\u5b58 +Add\ Parameter=\u65B0\u589E\u53C3\u6578 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly deleted file mode 100644 index b2a1f6ba1016621432632f0264d1f5e55f4a5325..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_bg.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_bg.properties deleted file mode 100644 index de74757cf3f2dddf32bf796284d3e344d6aba49d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_bg.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Add\ Parameter=\u0414\u043E\u0431\u0430\u0432\u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u044A\u0440 -This\ build\ is\ parameterized=\u0422\u043E\u0437\u0438 \u0431\u0438\u043B\u0434 \u0435 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438\u0437\u0438\u0440\u0430\u043D diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_de.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_de.properties deleted file mode 100644 index b095c4e88032cdaa819b7a9594421360171311c3..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_de.properties +++ /dev/null @@ -1,2 +0,0 @@ -This\ build\ is\ parameterized=Dieser Build ist parametrisiert. -Add\ Parameter=Parameter hinzufgen diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_en_GB.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_en_GB.properties deleted file mode 100644 index 76261e71cdeee54d5bfc7947de95a60c00ee56b7..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_en_GB.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -This\ build\ is\ parameterized=This build is parameterised diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_he.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_he.properties deleted file mode 100644 index 9417ad6eeff56b805a2ce93a8acdffb5feaa65f5..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_he.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Add\ Parameter=\u05D4\u05D5\u05E1\u05E3 \u05DE\u05E9\u05EA\u05E0\u05D4 -This\ build\ is\ parameterized=\u05D1\u05E0\u05D9\u05D4 \u05DE\u05DB\u05D9\u05DC\u05D4 \u05DE\u05E9\u05EA\u05E0\u05D9\u05DD diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ko.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ko.properties deleted file mode 100644 index daaae005f86b6f519cf1d9e9aaf3d540c6a8128a..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ko.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Add\ Parameter=\uB9E4\uAC1C\uBCC0\uC218 \uCD94\uAC00 -This\ build\ is\ parameterized=\uC774 \uBE4C\uB4DC\uB294 \uB9E4\uAC1C\uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ru.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ru.properties deleted file mode 100644 index 52c610189d77dd70fc7b325acc9d6a79485ddea9..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ru.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Add\ Parameter=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 -This\ build\ is\ parameterized=\u042d\u0442\u043e - \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0431\u043e\u0440\u043a\u0430 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_uk.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_uk.properties deleted file mode 100644 index a0875e36a55d944a3f1f38449747ef9cd1e7ec24..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_uk.properties +++ /dev/null @@ -1,4 +0,0 @@ -# This file is under the MIT License by authors - -Add\ Parameter=\u0414\u043E\u0434\u0430\u0442\u0438 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440 -This\ build\ is\ parameterized=\u0426\u044F \u0431\u0443\u0434\u043E\u0432\u0430 \u043C\u0430\u0454 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_zh_TW.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_zh_TW.properties deleted file mode 100644 index 2e4dc6bccab125f1c36558c610e91718313135c7..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_zh_TW.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -This\ build\ is\ parameterized=\u53c3\u6578\u5316\u5efa\u7f6e -Add\ Parameter=\u65B0\u589E\u53C3\u6578 diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html new file mode 100644 index 0000000000000000000000000000000000000000..496799b63e62ff907c1283bc4b2c2b0a3bd16de3 --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help.html @@ -0,0 +1,36 @@ +
    + Parameters allow you to prompt users for one or more inputs that will be + passed into a build. For example, you might have a project that runs tests on + demand by allowing users to upload a zip file with binaries to be tested. + This could be done by adding a File Parameter here. +
    + Or you might have a project that releases some software, and you want users to + enter release notes that will be uploaded along with the software. This could + be done by adding a Multi-line String Parameter here. +

    + Each parameter has a Name and some sort of Value, depending on + the parameter type. These name-value pairs will be exported as environment + variables when the build starts, allowing subsequent parts of the build + configuration (such as build steps) to access those values, e.g. by using the + ${PARAMETER_NAME} syntax (or %PARAMETER_NAME% on Windows). +
    + This also implies that each parameter defined here should have a unique + Name. +

    + When a project is parameterized, the usual Build Now link will be + replaced with a Build with Parameters link, where users will be + prompted to specify values for each of the defined parameters. If they choose + not to enter anything, the build will start with the default value for each + parameter. +

    + If a build is started automatically, for example if started by an SCM trigger, + the default values for each parameter will be used. +

    + When a parameterized build is in the queue, attempting to start another build + of the same project will only succeed if the parameter values are different, + or if the Execute concurrent builds if necessary option is enabled. +

    + See the Parameterized Builds wiki page for more information about + this feature. +

    diff --git a/war/src/main/webapp/help/project-config/parameterized-build_de.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_de.html similarity index 100% rename from war/src/main/webapp/help/project-config/parameterized-build_de.html rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_de.html diff --git a/war/src/main/webapp/help/project-config/parameterized-build_fr.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_fr.html similarity index 100% rename from war/src/main/webapp/help/project-config/parameterized-build_fr.html rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_fr.html diff --git a/war/src/main/webapp/help/project-config/parameterized-build_ja.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_ja.html similarity index 100% rename from war/src/main/webapp/help/project-config/parameterized-build_ja.html rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_ja.html diff --git a/war/src/main/webapp/help/project-config/parameterized-build.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_tr.html similarity index 100% rename from war/src/main/webapp/help/project-config/parameterized-build.html rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_tr.html diff --git a/war/src/main/webapp/help/project-config/parameterized-build_zh_TW.html b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_zh_TW.html similarity index 100% rename from war/src/main/webapp/help/project-config/parameterized-build_zh_TW.html rename to core/src/main/resources/hudson/model/ParametersDefinitionProperty/help_zh_TW.html diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_pl.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_pl.properties index 0df95d4606d5d3960098608eaa7d53f1a174266c..188cbcaf55f842b1e80e39846ea2bca61866fe70 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_pl.properties +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_pl.properties @@ -22,4 +22,4 @@ Build=Buduj LOADING=\u0141ADOWANIE -description=To budowanie wymaga parametr\u00F3w: +description=To zadanie wymaga parametr\u00F3w: diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_sr.properties b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a8a3c1a60a6826dac2ccb86612edfc68166af9f3 --- /dev/null +++ b/core/src/main/resources/hudson/model/ParametersDefinitionProperty/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +LOADING=\u0423\u0427\u0418\u0422\u0410\u0412\u0410\u040A\u0415 +description=\u041E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0437\u0430\u0445\u0442\u0435\u0432\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0435: +Build=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/core/src/main/resources/hudson/model/PasswordParameterDefinition/config_sr.properties b/core/src/main/resources/hudson/model/PasswordParameterDefinition/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9d202ad38b4ee7215971ef685c426eac55ac5c1c --- /dev/null +++ b/core/src/main/resources/hudson/model/PasswordParameterDefinition/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Default\ Value= +Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/hudson/model/PasswordParameterDefinition/index.jelly b/core/src/main/resources/hudson/model/PasswordParameterDefinition/index.jelly index 9bac23608cc5a435122249e64f2429574c9cbe8b..81b8c0190ae2a9bca17389a5205e2723999564d6 100644 --- a/core/src/main/resources/hudson/model/PasswordParameterDefinition/index.jelly +++ b/core/src/main/resources/hudson/model/PasswordParameterDefinition/index.jelly @@ -29,7 +29,7 @@ THE SOFTWARE.
    - +
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_bg.properties b/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_bg.properties index e21c565e42f8e8dcdc2bcb10a6dcbd1d5af46658..3f060afc098d9625f8823ca0d701ba29f24b561e 100644 --- a/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_bg.properties +++ b/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -format="{0} ({1}), \u043F\u0440\u0435\u0434\u0438 {2}" +format=\ + {0} ({1}), \u043f\u0440\u0435\u0434\u0438 {2} diff --git a/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_sr.properties b/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_sr.properties index bdde2cdba969b97e91c8cc0abb2f1c88122cca3c..dde884e8fe859f8e6fea6c488a4fecf33bfd18bf 100644 --- a/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_sr.properties +++ b/core/src/main/resources/hudson/model/PermalinkProjectAction/Permalink/link_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -format={0}({1}), {2} pre +format={0}({1}), {2} \u043F\u0440\u0435 diff --git a/core/src/main/resources/hudson/model/ProxyView/configure-entries_de.properties b/core/src/main/resources/hudson/model/ProxyView/configure-entries_de.properties index 5222cc089fee446a84e4bc2205871f2428b65aab..a206e6c6db9581a6be8b9ae754086cfc2861a842 100644 --- a/core/src/main/resources/hudson/model/ProxyView/configure-entries_de.properties +++ b/core/src/main/resources/hudson/model/ProxyView/configure-entries_de.properties @@ -1,25 +1,25 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -View\ name=Name der Ansicht -The\ name\ of\ a\ global\ view\ that\ will\ be\ shown.=\ - Name einer globalen Ansicht, der angezeigt wird. +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +View\ name=Name der Ansicht +The\ name\ of\ a\ global\ view\ that\ will\ be\ shown.=\ + Name einer globalen Ansicht, der angezeigt wird. diff --git a/core/src/main/resources/hudson/model/ProxyView/configure-entries_sr.properties b/core/src/main/resources/hudson/model/ProxyView/configure-entries_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6cb8749ad81cc5c9589e2d8e2dbf3611cb0ebd19 --- /dev/null +++ b/core/src/main/resources/hudson/model/ProxyView/configure-entries_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +View\ name=\u0418\u043C\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 +The\ name\ of\ a\ global\ view\ that\ will\ be\ shown.=\u0418\u043C\u0435 \u0433\u043B\u043E\u0431\u0430\u043B\u043D\u043E\u0433 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \u043A\u043E\u0458\u0438 \u045B\u0435 \u0431\u0438\u0442\u0438 \u043F\u0440\u0438\u043A\u0430\u0437\u0430\u043D. diff --git a/core/src/main/resources/hudson/model/ProxyView/newViewDetail_de.properties b/core/src/main/resources/hudson/model/ProxyView/newViewDetail_de.properties index 984d1a11b0d7604eb8d829e58844eb074225eb7d..8e833e78bfc5b86a59dcef22c5d16320b8ec1cf9 100644 --- a/core/src/main/resources/hudson/model/ProxyView/newViewDetail_de.properties +++ b/core/src/main/resources/hudson/model/ProxyView/newViewDetail_de.properties @@ -1,24 +1,24 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Shows\ the\ content\ of\ a\ global\ view.=\ +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Shows\ the\ content\ of\ a\ global\ view.=\ Zeigt den Inhalt einer globalen Ansicht. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/ProxyView/newViewDetail_sr.properties b/core/src/main/resources/hudson/model/ProxyView/newViewDetail_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b38fb5f6e69d5a2395baa1268eddecfde9ad6c3c --- /dev/null +++ b/core/src/main/resources/hudson/model/ProxyView/newViewDetail_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Shows\ the\ content\ of\ a\ global\ view.=\u041F\u0440\u0438\u043A\u0430\u0437\u0443\u0458\u0435 \u0441\u0430\u0434\u0440\u0436\u0430\u0458 \u0433\u043B\u0430\u0432\u043D\u043E\u0433 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 + diff --git a/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_bg.properties b/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..648b75e6637bbae33660ef7aefae3c568a86fc54 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Keep\ this\ build\ forever=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0437\u0430\u0432\u0438\u043d\u0430\u0433\u0438 diff --git a/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_sr.properties b/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..bdd27859e3648113fabeab67b7f68c1bc50aef88 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/KeepLogBuildBadge/badge_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Keep\ this\ build\ forever=\u0417\u0430\u043F\u0430\u043C\u0442\u0438 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0437\u0430\u0443\u0432\u0435\u043A diff --git a/core/src/main/resources/hudson/model/Computer/_script_ja.properties b/core/src/main/resources/hudson/model/Run/artifacts-index_bg.properties similarity index 82% rename from core/src/main/resources/hudson/model/Computer/_script_ja.properties rename to core/src/main/resources/hudson/model/Run/artifacts-index_bg.properties index ce17ad737a3cb7baac3b33f3ce763e06ae7e6c04..38b8e8f3880c8b4c17ef79e7d2104b27914b06ca 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_ja.properties +++ b/core/src/main/resources/hudson/model/Run/artifacts-index_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=\ - \u30B9\u30EC\u30FC\u30D6\u306EJVM\u3067\u5B9F\u884C\u3055\u308C\u307E\u3057\u305F\u3002 +Build\ Artifacts=\ + \u041e\u0431\u0435\u043a\u0442\u0438 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e diff --git a/core/src/main/resources/hudson/model/Run/artifacts-index_sr.properties b/core/src/main/resources/hudson/model/Run/artifacts-index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ed4de01fde7ef5216cdc493545f19f9e4e9ac742 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/artifacts-index_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Build\ Artifacts=\u0410\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/hudson/model/Run/configure_bg.properties b/core/src/main/resources/hudson/model/Run/configure_bg.properties index c42f51fe96ab814c54479592c0b39accc08b3976..1d4af2f277c76c531e65e127ffb912539ec12914 100644 --- a/core/src/main/resources/hudson/model/Run/configure_bg.properties +++ b/core/src/main/resources/hudson/model/Run/configure_bg.properties @@ -1,6 +1,29 @@ -# This file is under the MIT License by authors - -Description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 -DisplayName=\u041F\u043E\u0437\u043D\u0430\u0442 \u043A\u0430\u0442\u043E -LOADING=\u0417\u0410\u0420\u0415\u0416\u0414\u0410\u041D\u0415 -Save=\u0417\u0430\u043F\u0430\u0437\u0432\u0430\u043D\u0435 +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Description=\ + \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +DisplayName=\ + \u0418\u043c\u0435 \u0437\u0430 \u0438\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 +LOADING=\ + \u0417\u0410\u0420\u0415\u0416\u0414\u0410\u041d\u0415 +Save=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/Run/configure_sr.properties b/core/src/main/resources/hudson/model/Run/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6fffe044fdec08c34825c2c2537113dd19048f4f --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/configure_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +LOADING=\u0423\u0427\u0418\u0422\u0410\u0412\u0410\u040A\u0415 +DisplayName=\u0418\u043C\u0435 \u0437\u0430 \u043F\u0440\u0438\u043A\u0430\u0437 +Description=\u041E\u043F\u0438\u0441 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 diff --git a/core/src/main/resources/hudson/model/Run/confirmDelete.jelly b/core/src/main/resources/hudson/model/Run/confirmDelete.jelly index 41c42b3eb08ae785a12c2dbda4ad731716eaec3b..c48788d423d4f653b9baa4cfb7334b109854d172 100644 --- a/core/src/main/resources/hudson/model/Run/confirmDelete.jelly +++ b/core/src/main/resources/hudson/model/Run/confirmDelete.jelly @@ -24,20 +24,23 @@ THE SOFTWARE. - + - - + + -

    ${%Warning}: ${msg}

    -
    +

    ${%Warning}: ${msg}

    + -
    - ${%Are you sure about deleting the build?} - - + +
    + ${%Are you sure about deleting the build?} + + +
    -
    -
    + +
    diff --git a/core/src/main/resources/hudson/model/Run/confirmDelete_bg.properties b/core/src/main/resources/hudson/model/Run/confirmDelete_bg.properties index 8d430987acfeaeda0731fad8c3aee8707dc6a5af..378fa43b75a821688acb109babf8cd7b6f84c860 100644 --- a/core/src/main/resources/hudson/model/Run/confirmDelete_bg.properties +++ b/core/src/main/resources/hudson/model/Run/confirmDelete_bg.properties @@ -1,4 +1,28 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ build?=\u041D\u0430\u0438\u0441\u0442\u0438\u043D\u0430 \u043B\u0438 \u0436\u0435\u043B\u0430\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u0431\u0438\u043B\u0434\u0430? -Yes=\u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ build?=\ + \u041d\u0430\u0438\u0441\u0442\u0438\u043d\u0430 \u043b\u0438 \u0436\u0435\u043b\u0430\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e\u0442\u043e? +Yes=\ + \u0414\u0430 +Warning=\ + \u041f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u0435 diff --git a/core/src/main/resources/hudson/model/Run/confirmDelete_sr.properties b/core/src/main/resources/hudson/model/Run/confirmDelete_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..79339b25a8d75dd2e4e53b0618245ddb0335c43c --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/confirmDelete_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Warning=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435 +Yes=\u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ build?=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443? diff --git a/core/src/main/resources/hudson/model/Run/console_bg.properties b/core/src/main/resources/hudson/model/Run/console_bg.properties index 5b84fa8cfd52ff709af25c2aba8fafee8518a4f8..e4a3d944382c497ac600ab4c96f6256c1b7f7287 100644 --- a/core/src/main/resources/hudson/model/Run/console_bg.properties +++ b/core/src/main/resources/hudson/model/Run/console_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Console\ Output=\u041A\u043E\u043D\u0437\u043E\u043B\u0430 \u0441 \u0440\u0435\u0437\u0443\u043B\u0442\u0430\u0442\u0430 +Console\ Output=\ + \u041a\u043e\u043d\u0437\u043e\u043b\u0430 \u0441 \u0440\u0435\u0437\u0443\u043b\u0442\u0430\u0442\u0430 +# Skipping {0,number,integer} KB.. Full Log +skipSome=\ + \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 {0,number,integer}\u200aKB\u2026 \u041f\u044a\u043b\u0435\u043d \u0436\u0443\u0440\u043d\u0430\u043b diff --git a/core/src/main/resources/hudson/model/Run/console_pl.properties b/core/src/main/resources/hudson/model/Run/console_pl.properties index 10ae388c90e1ad6e9461dbfc4d4c35817a69a969..5e82220e612cb898a8473222571e76578e676b88 100644 --- a/core/src/main/resources/hudson/model/Run/console_pl.properties +++ b/core/src/main/resources/hudson/model/Run/console_pl.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Console\ Output=Wyj\u015Bcie Konsoli +Console\ Output=Logi konsoli View\ as\ plain\ text=Poka\u017C jako tekst niesformatowany skipSome=Pomini\u0119to {0,number,integer} KB.. Poka\u017C wszystko diff --git a/core/src/main/resources/hudson/model/Run/console_sr.properties b/core/src/main/resources/hudson/model/Run/console_sr.properties index c4c0552d2851007ad6f1fa6e8fd2c12e3aab49eb..3e24c621d1ec455dc8602b94d65e6245a592acdc 100644 --- a/core/src/main/resources/hudson/model/Run/console_sr.properties +++ b/core/src/main/resources/hudson/model/Run/console_sr.properties @@ -1,4 +1,5 @@ # This file is under the MIT License by authors -Console\ Output=Ispis konzole -View\ as\ plain\ text=Vidi kao obi\u010Dan tekst +Console\ Output=\u0418\u0441\u0445\u043E\u0434 \u0438\u0437 \u043A\u043E\u043D\u0437\u043E\u043B\u0435 +View\ as\ plain\ text=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u043E\u0431\u0438\u0447\u043D\u043E\u0433 \u0442\u0435\u043A\u0441\u0442\u0430 +skipSome=\u041F\u0440\u0435\u0441\u043A\u0430\u0447\u0435 {0,number,integer} KB.. \u041A\u043E\u043C\u043F\u043B\u0435\u0442\u0430\u043D \u0436\u0443\u0440\u043D\u0430\u043B diff --git a/core/src/main/resources/hudson/model/Run/delete-retry_bg.properties b/core/src/main/resources/hudson/model/Run/delete-retry_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..dc8c79c7803a8683e14d24be975aee4aeb21168c --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/delete-retry_bg.properties @@ -0,0 +1,31 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# Deletion of the build failed +Not\ successful=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e\u0442\u043e +# Retry delete +Retry\ delete=\ + \u041d\u043e\u0432 \u043e\u043f\u0438\u0442 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +# Show reason +Show\ reason=\ + \u041f\u043e\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u0442\u0430 diff --git a/core/src/main/resources/hudson/model/Run/delete-retry_sr.properties b/core/src/main/resources/hudson/model/Run/delete-retry_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d5454cf7ecc162c2b43a4bc949bd72b23e1f7318 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/delete-retry_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Retry\ delete=\u041F\u043E\u043A\u0443\u0448\u0430\u0458 \u0431\u0440\u0438\u0441\u0430\u045A\u0435 \u043F\u043E\u043D\u043E\u0432\u043E +Show\ reason=\u041F\u0440\u0438\u043A\u0430\u0436\u0438 \u0440\u0430\u0437\u043B\u043E\u0433 +Not\ successful=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E diff --git a/core/src/main/resources/hudson/model/Run/delete_bg.properties b/core/src/main/resources/hudson/model/Run/delete_bg.properties index 470632246eda87cc2a587503b13c864f24a53c52..47e6e98e8e4c1ad0e2ce88b4b8cfaef955b80f54 100644 --- a/core/src/main/resources/hudson/model/Run/delete_bg.properties +++ b/core/src/main/resources/hudson/model/Run/delete_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Delete\ this\ build=\u0418\u0437\u0442\u0440\u0438\u0439 \u0431\u0438\u043B\u0434\u0430 +Delete\ this\ build=\ +\u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e\u0442\u043e diff --git a/core/src/main/resources/hudson/model/Run/delete_pl.properties b/core/src/main/resources/hudson/model/Run/delete_pl.properties index 2a23b65679804a818e05aff1ced8570b0d3c673f..2ae6db49379570ce181965715e6303dd5970fc39 100644 --- a/core/src/main/resources/hudson/model/Run/delete_pl.properties +++ b/core/src/main/resources/hudson/model/Run/delete_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Delete\ this\ build=Usu\u0144 t\u0105 wersje +Delete\ this\ build=Usu\u0144 to zadanie diff --git a/core/src/main/resources/hudson/model/Run/delete_sr.properties b/core/src/main/resources/hudson/model/Run/delete_sr.properties index b5ac4708b170019884b2232d2b6cd6a2b9de0489..50398669a83ff5c45fc9a65268ee3fec376c5449 100644 --- a/core/src/main/resources/hudson/model/Run/delete_sr.properties +++ b/core/src/main/resources/hudson/model/Run/delete_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Delete\ this\ build=Obrisi build +Delete\ this\ build=\u0423\u043A\u043B\u043E\u043D\u0438 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 diff --git a/core/src/main/resources/hudson/model/Run/logKeep.jelly b/core/src/main/resources/hudson/model/Run/logKeep.jelly index fe9545e7562b4913d0b5c52db17c83f2fd5a3db0..10175e3aa4e24b8a3cd73304ef6d2da398a6a626 100644 --- a/core/src/main/resources/hudson/model/Run/logKeep.jelly +++ b/core/src/main/resources/hudson/model/Run/logKeep.jelly @@ -27,7 +27,7 @@ THE SOFTWARE. --> - +
    diff --git a/core/src/main/resources/hudson/model/Run/logKeep_bg.properties b/core/src/main/resources/hudson/model/Run/logKeep_bg.properties index 8433c19b126c012e722855587b4b794e3d0030ab..bce91f780be51c76cf6bb223f1123cdad7790d7e 100644 --- a/core/src/main/resources/hudson/model/Run/logKeep_bg.properties +++ b/core/src/main/resources/hudson/model/Run/logKeep_bg.properties @@ -1,3 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Keep\ this\ build\ forever=\u041F\u0430\u0437\u0438 \u0431\u0438\u043B\u0434\u0430 \u0437\u0430\u0432\u0438\u043D\u0430\u0433\u0438 +Keep\ this\ build\ forever=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e\u0442\u043e \u0437\u0430\u0432\u0438\u043d\u0430\u0433\u0438 +Don''t\ keep\ this\ build\ forever=\ + \u0418\u0437\u0433\u0440\u0430\u0434\u0435\u043d\u043e\u0442\u043e \u0434\u0430 \u043d\u0435 \u0441\u0438 \u043f\u0430\u0437\u0438 \u0437\u0430\u0432\u0438\u043d\u0430\u0433\u0438 diff --git a/core/src/main/resources/hudson/model/Run/logKeep_sr.properties b/core/src/main/resources/hudson/model/Run/logKeep_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9c069ff8dff40d6500f622898e284aa87d42d793 --- /dev/null +++ b/core/src/main/resources/hudson/model/Run/logKeep_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Don't\ keep\ this\ build\ forever=\u041D\u0435\u043C\u043E\u0458 \u0437\u0430\u0434\u0440\u0436\u0430\u0442\u0438 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +Keep\ this\ build\ forever=\u0417\u0430\u0434\u0440\u0436\u0438 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +Don''t\ keep\ this\ build\ forever=\u041D\u0435\u043C\u043E\u0458 \u0437\u0430\u0434\u0440\u0436\u0430\u0442\u0438 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 diff --git a/core/src/main/resources/hudson/model/RunParameterDefinition/config_sr.properties b/core/src/main/resources/hudson/model/RunParameterDefinition/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0f48747b5adc43813e160680d33536a67096363b --- /dev/null +++ b/core/src/main/resources/hudson/model/RunParameterDefinition/config_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Project=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +Description=\u041E\u043F\u0438\u0441 +Filter=\u0424\u0438\u043B\u0442\u0435\u0440 +All\ Builds=\u0421\u0432\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Completed\ Builds\ Only=\u0421\u0430\u043C\u043E \u0437\u0430\u0432\u0440\u0448\u0435\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Successful\ Builds\ Only=\u0421\u0430\u043C\u043E \u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Stable\ Builds\ Only=\u0421\u0430\u043C\u043E \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher.jelly b/core/src/main/resources/hudson/model/Slave/help-launcher.jelly index 7b80362ec3878a33040587a9cbab652a1f8c2a82..c9156b09fdc9fddef746f21ae46ee9f8a95c84f6 100644 --- a/core/src/main/resources/hudson/model/Slave/help-launcher.jelly +++ b/core/src/main/resources/hudson/model/Slave/help-launcher.jelly @@ -26,7 +26,7 @@ THE SOFTWARE.
    - ${%Controls how Jenkins starts this slave.} + ${%Controls how Jenkins starts this agent.}
    diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_da.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_da.properties deleted file mode 100644 index 15f2e396ca912b38a3e1e407425d9a6577b94340..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_da.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Controls\ how\ Jenkins\ starts\ this\ slave.=Styrer hvordan Jenkins starter denne slave. diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_de.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_de.properties deleted file mode 100644 index dc586b7e4b543be0be2ef2e0aa0765f990612b97..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_de.properties +++ /dev/null @@ -1 +0,0 @@ -Controls\ how\ Jenkins\ starts\ this\ slave.=Steuert, wie Jenkins den Slave-Knoten startet. diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_es.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_es.properties index bb2e5e2309cbe695da9336fd9039ccb7ba97eb39..94f86e708e6ea67894fa3d58d55939571c9d2814 100644 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_es.properties +++ b/core/src/main/resources/hudson/model/Slave/help-launcher_es.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Controls\ how\ Jenkins\ starts\ this\ slave.=Controla cmo Jenkins inicia este esclavo. +Controls\ how\ Jenkins\ starts\ this\ agent.=Controla como Jenkins inicia este agente. diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_pt_BR.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_pt_BR.properties deleted file mode 100644 index d02da19515a997773e959e20be5f3434a125c651..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_pt_BR.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva, Fernando Boaglio -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Controls\ how\ Jenkins\ starts\ this\ slave.=Controla como o Jenkins inicia esse slave diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_sr.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2e4d562fe1c5f5548a41cff9805477e0288f7366 --- /dev/null +++ b/core/src/main/resources/hudson/model/Slave/help-launcher_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Controls\ how\ Jenkins\ starts\ this\ agent.=\u041F\u043E\u0434\u0435\u0441\u0438 \u043D\u0430\u0447\u0438\u043D \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0442\u0430 \u043A\u0440\u043E\u0437 Jenkins. diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_tr.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_tr.properties deleted file mode 100644 index c897a4126fdf5faabcdfd4a86b06e165064b09ca..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_tr.properties +++ /dev/null @@ -1 +0,0 @@ -Controls\ how\ Jenkins\ starts\ this\ slave.= Jenkins'?n slave'i nas?l ba?lataca??n? kontrol eder. diff --git a/core/src/main/resources/hudson/model/Slave/help-launcher_zh_TW.properties b/core/src/main/resources/hudson/model/Slave/help-launcher_zh_TW.properties deleted file mode 100644 index 53d4c8d02152394c3f0b99c9f3033088bf9caa64..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-launcher_zh_TW.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Controls\ how\ Jenkins\ starts\ this\ slave.=\u63a7\u5236 Jenkins \u4f7f\u7528\u4ec0\u9ebc\u65b9\u5f0f\u555f\u52d5 Slave\u3002 diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS.html index 477c19c6a081db2b71fb6647b690ea500ca5488b..6915c41fb38de9121d1ab21ba74d4dbea34ed781 100644 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS.html +++ b/core/src/main/resources/hudson/model/Slave/help-remoteFS.html @@ -1,36 +1,34 @@

    - A slave needs to have a directory dedicated to Jenkins. Specify - the path of this work directory on the slave. It is best to use - an absolute path, such as '/var/jenkins' or 'c:\jenkins'. This - should be a path local to the slave machine. There's no need for - this path to be visible from the master, under normal circumstances. - + An agent needs to have a directory dedicated to Jenkins. Specify + the path to this directory on the agent. It is best to use + an absolute path, such as /var/jenkins or c:\jenkins. + This should be a path local to the agent machine. There is no need for + this path to be visible from the master.

    - Slaves do not maintain important data (other than active workspaces - of projects last built on it), so you can possibly set the slave - workspace to a temporary directory. The only downside of doing this - is that you may lose the up-to-date workspace if the slave is turned off. - + Agents do not maintain important data; all job configurations, build logs and + artifacts are stored on the master, so it would be possible to use a temporary + directory as the agent root directory. +
    + However, by giving an agent a directory that is not deleted after a machine + reboot, for example, the agent can cache data such as tool installations, or + build workspaces. This prevents unnecessary downloading of tools, or checking + out source code again when builds start to run on this agent again after a + reboot.

    - If you use a relative path, such as './jenkins-slave', the path will - be relative to the current working directory that the launcher provides. + If you use a relative path, such as ./jenkins-agent, the path will be + relative to the working directory provided by the Launch method.

      -
    • For launchers where Jenkins controls starting the slave process, such +
    • For launchers where Jenkins controls starting the agent process, such as SSH, the current working directory will typically be consistent, - e.g. the user's home directory. This means that Jenkins will be able to - rely on the caching of tool installations and workspaces from previous - builds. -
    • -
    • For launchers where Jenkins has no control over starting the slave + e.g. the user's home directory.
    • +
    • For launchers where Jenkins has no control over starting the agent process, such as JNLP when launched from either the command line or via a web browser link, the current working directory may change between - launches of the slave and use of a relative path may prove problematic. + launches of the agent and use of a relative path may prove problematic. +
      The principal issue encountered when using relative paths with launchers like JNLP is the proliferation of stale workspaces and tool installation - on the slave machine. This can cause disk space issues. - Note: there are some cloud providers that specifically use relative - paths with the JNLP launcher to allow for dynamically provisioned pools - of semi-heterogeneous slaves.
    • + on the agent machine. This can cause disk space issues.
    diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_de.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_de.html deleted file mode 100644 index e507e718423d9682f52ff9abf92f458cfe48aaf3..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_de.html +++ /dev/null @@ -1,16 +0,0 @@ -
    -

    - Ein Slave-Knoten benötigt ein Verzeichnis, das Jenkins exklusiv - zur Verfügung steht. Geben Sie den absoluten Pfad dieses - Arbeitsverzeichnisses auf dem Slave-Knoten an, z.B. - '/export/home/jenkins' oder 'c:\jenkins'. Dieses Verzeichnis muß unter normalen - Umständen nicht vom Master aus erreichbar sein. - -

    - Slave-Knoten speichern keine wichtigen Daten (abgesehen von den - aktiven Arbeitsbereichen derjenigen Projekte, die zuletzt auf dem - Slave-Knoten gebaut wurden). Sie können daher gefahrlos das Slave-Arbeitsverzeichnis - auf ein temporäres Verzeichnis setzen. Der einzige Nachteil dieses Vorgehens - wäre der Verlust der aktuellen Arbeitsbereiche, falls der Slave-Knoten - abgeschaltet würde. -

    diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_pt_BR.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_pt_BR.html deleted file mode 100644 index 5f995b42e9fc0a61fcb9e9f82fada8e0316a370d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_pt_BR.html +++ /dev/null @@ -1,13 +0,0 @@ -div> - -

    - Um slave precisa ter um diretório dedicado ao Jenkins. Especifique - o caminho absoluto deste diretório de trabalho no slave, tal como - '/export/home/jenkins'. - -

    - Slaves não mantém dados importantes (além dos workspaces ativos - dos últimos projetos construídos neles), assim você pode configurar o - workspace do slave para um diretório temporário. A única desvantagem de fazer isto - é que você pode perder o workspace atualizado se o slave for desligado. -

    diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_tr.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_tr.html deleted file mode 100644 index 19357e537ba4f4364a675c24a29eb5c2a7a6ce24..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_tr.html +++ /dev/null @@ -1,14 +0,0 @@ -
    - -

    - Slave'in üzerinde bir dizini, Jenkins'ın kullanımı için ayırmanız - gerekmektedir. Bu alana, bu dizinin mutlak yolunu yazmanız gerekir - ('/export/home/jenkins' gibi). Bu dizinin yolu slave makineye göredirr. Normal şartlar altında master tarafından - görünür olmasına gerek yoktur. - -

    - Slave'ler çok önemli veriler oluşturmazlar (üzerinde çalışan projelerin - aktif çalışma alanları dışında). Dolayısıyla, slave'in çalışma alanı, geçici - bir dizine ayarlanabilir. Bu şekilde yapmanın tek dezavantajı, slave çevrim - dışı olduğunda, güncel çalışma alanını kaybedebilecek olmanızdır. -

    diff --git a/core/src/main/resources/hudson/model/Slave/help-remoteFS_zh_TW.html b/core/src/main/resources/hudson/model/Slave/help-remoteFS_zh_TW.html deleted file mode 100644 index ff327c4bdd424fc5fc554ca08fb3899d3970ef2e..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/Slave/help-remoteFS_zh_TW.html +++ /dev/null @@ -1,10 +0,0 @@ -
    -

    - Slave 上要有 Jenkins 專用的目錄。 - 請指定這個工作目錄在 Slave 上的完整路徑,例如 '/var/jenkins' 或是 'c:\jenkins'。 - Master 不用直接存取到這個路徑。 - -

    - Slave 上不會儲存重要資訊 (只會存最近建置專案的工作區),所以您也可以把 Slave 工作區設在暫存目錄裡。 - 唯一的缺點是當 Slave 停掉時,您可能會看不到工作區的最新內容。 -

    diff --git a/core/src/main/resources/hudson/model/StringParameterDefinition/config_sr.properties b/core/src/main/resources/hudson/model/StringParameterDefinition/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..93ae61cbc27445f788318b046a8b57ac40f83f26 --- /dev/null +++ b/core/src/main/resources/hudson/model/StringParameterDefinition/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Default\ Value=\u041F\u043E\u0434\u0440\u0430\u0437\u0443\u043C\u0435\u0432\u0430\u043D\u0430 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442 +Description= diff --git a/core/src/main/resources/hudson/model/TaskAction/log_sr.properties b/core/src/main/resources/hudson/model/TaskAction/log_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9f1c8091f3f190584b6d80762824f66dae0fb98c --- /dev/null +++ b/core/src/main/resources/hudson/model/TaskAction/log_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Clear\ error\ to\ retry=\u0418\u0437\u0431\u0440\u0438\u0448\u0438 \u0433\u0440\u0435\u0448\u043A\u0443 \u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0443\u0448\u0430\u0458 diff --git a/core/src/main/resources/hudson/model/TextParameterDefinition/config_sr.properties b/core/src/main/resources/hudson/model/TextParameterDefinition/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..cf61857320cdf09d347e042b898d227464304114 --- /dev/null +++ b/core/src/main/resources/hudson/model/TextParameterDefinition/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Default\ Value=\u041F\u043E\u0434\u0440\u0430\u0437\u0443\u043C\u0435\u0432\u0430\u043D\u0430 \u0432\u0440\u0435\u0434\u043D\u043E\u0441\u0442 +Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/hudson/model/TreeView/sidepanel2_sr.properties b/core/src/main/resources/hudson/model/TreeView/sidepanel2_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f8ec299e020f6eb33f50a540d14d21a6d7cfde3b --- /dev/null +++ b/core/src/main/resources/hudson/model/TreeView/sidepanel2_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +New\ View=\u041D\u043E\u0432\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_bg.properties b/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_bg.properties index 1fbb10639b78cc32a0b3283449470a94b97bede4..adee465bca3116d715acb20e770cd46f4712cef7 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_bg.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_bg.properties @@ -1,3 +1,23 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Preparation=\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043A\u0430 +Preparation=\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_sr.properties index fa1e2190e2a1567c2902e80825e1b0d2d293780d..05cfddd60fb4ef6900ba6253dec69eb74cff472d 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/ConnectionCheckJob/row_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Preparation=Priprema +Preparation=\u041F\u0440\u0438\u043F\u0440\u0435\u043C\u0430\u045A\u0435 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.jelly b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.jelly index 48e602863cf6c6435a0d0fdd9abeaf2f6fd52c93..cdb895fde6e12fb9572a3e334f3b7d48f0db7adc 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.jelly +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message.jelly @@ -39,6 +39,14 @@ THE SOFTWARE. + + + ${%UpgradeFailed(ucData.core.version,upJob.errorMessage,rootURL+'/updateCenter/')} + + + + + ${%UpgradeProgress(ucData.core.version,rootURL+'/updateCenter/')} diff --git a/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c5eac1c6208bfe11b8992059ec3cc67ccf50c47a --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/CoreUpdateMonitor/message_sr.properties @@ -0,0 +1,9 @@ +# This file is under the MIT License by authors + +UpgradeComplete=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 \u0458\u0435 \u0433\u043E\u0442\u043E\u0432\u043E +UpgradeCompleteRestartNotSupported=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 \u0458\u0435 \u0433\u043E\u0442\u043E\u0432\u043E, \u0430\u043B\u0438 \u043D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435. +UpgradeFailed=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 \u0458\u0435 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E +Retry=\u041F\u043E\u043A\u0443\u0448\u0430\u0458 \u043F\u043E\u043D\u043E\u0432\u043E +UpgradeProgress=\u041D\u0430\u043F\u0440\u0435\u0434\u0430\u043A \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0430 +NewVersionAvailable=\u0418\u043C\u0430 \u043D\u043E\u0432\u0430 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 +Or\ Upgrade\ Automatically=\u0438\u043B\u0438 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u0458 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..08ab00907c71b78a41b29889c939518eb8d92f9c --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Failure/status_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Failure=\u0413\u0440\u0435\u0448\u043A\u0430 +Details=\u0414\u0435\u0442\u0430\u0459\u0438 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f9195b9f58e4401d0955412e87159a09e568223f --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Installing/status_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Installing=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Pending/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Pending/status_sr.properties index baf65f0336f049e5bf10a83f92bbf2e7c1585179..cf0838acf528c4a923cbcfc821b88453cd708849 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Pending/status_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Pending/status_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Pending=U toku +Pending=\u0423 \u0442\u043E\u043A\u0443 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Success/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Success/status_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..66d22b692af99cea0939fe26f38b15044e8ce145 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/DownloadJob/Success/status_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Success=\u0423\u0441\u043F\u0435\u0448\u043D\u043E diff --git a/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly new file mode 100644 index 0000000000000000000000000000000000000000..f98ff8bc4a431b26986bc16500d3e43e6161596e --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row.jelly @@ -0,0 +1,33 @@ + + + + + + ${it.plugin.displayName} + + ${%Enabled Dependency} + + + diff --git a/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3af25ed5fbf53c6f83f82478b1651df22a7f2176 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/EnableJob/row_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Enabled\ Dependency=\u041E\u043C\u043E\u0433\u0443\u045B\u0435\u043D\u0430 \u0437\u0430\u0432\u0438\u0441\u043D\u0430 \u043C\u043E\u0434\u0443\u043B\u0430 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly new file mode 100644 index 0000000000000000000000000000000000000000..c6a2e93587004569520b157ac92846dbb7bb199e --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row.jelly @@ -0,0 +1,33 @@ + + + + + + ${it.plugin.displayName} + + ${%Already Installed} + + + diff --git a/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c9523af58af1af95a6710ad2c2bc14a089d3de12 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/NoOpJob/row_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Already\ Installed=\u0412\u0435\u045B \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u043E diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Canceled/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Canceled/status_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..efa35bc645facadd3beea5309dff454831dcc9f3 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Canceled/status_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Canceled=\u041E\u0442\u043A\u0430\u0437\u0430\u043D\u043E diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Failure/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Failure/status_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..17c0cafed8bfd6890aa42d37fe755c5eda6def75 --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Failure/status_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Failure=\u0413\u0440\u0435\u0448\u043A\u0430 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_sr.properties index baf65f0336f049e5bf10a83f92bbf2e7c1585179..cf0838acf528c4a923cbcfc821b88453cd708849 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Pending/status_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Pending=U toku +Pending=\u0423 \u0442\u043E\u043A\u0443 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7775a5ee2afa4610063a9394ab8c0a46e6c421cc --- /dev/null +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/Running/status_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Running=\u0412\u0440\u0448\u0438 \u0441\u0435 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_sr.properties index 5ff318c3cfb5c8b4168f645a1994df7d1b7b5c78..0797fb4ce944137dcd526bb39ccb178484b70bf6 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/RestartJenkinsJob/row_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Restarting\ Jenkins=Restart Jenkins-a +Restarting\ Jenkins=\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 Jenkins diff --git a/core/src/main/resources/hudson/model/UpdateCenter/body_bg.properties b/core/src/main/resources/hudson/model/UpdateCenter/body_bg.properties index 2417dc93a146825a83e008d224d9c66bc4ad5667..8f9a6ef6384109981b1baee7e1479aa37e269347 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/body_bg.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/body_bg.properties @@ -1,5 +1,25 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Go\ back\ to\ the\ top\ page=\u041E\u0431\u0440\u0430\u0442\u043D\u043E \u043A\u044A\u043C \u043E\u0441\u043D\u043E\u0432\u043D\u0430\u0442\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 -warning=\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439\u0442\u0435 Jenkins, \u043A\u043E\u0433\u0430\u0442\u043E \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u044F\u0442\u0430 \u043F\u0440\u0438\u043A\u043B\u044E\u0447\u0438 \u0438 \u043D\u044F\u043C\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 -you\ can\ start\ using\ the\ installed\ plugins\ right\ away=\u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u043F\u043E\u043B\u0437\u0432\u0430\u0442\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0438\u0442\u0435 \u043F\u0440\u0438\u0441\u0442\u0430\u0432\u043A\u0438 \u0441\u0435\u0433\u0430 +Go\ back\ to\ the\ top\ page=\u041e\u0431\u0440\u0430\u0442\u043d\u043e \u043a\u044a\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 +warning=\u0420\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439\u0442\u0435 Jenkins, \u043a\u043e\u0433\u0430\u0442\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f\u0442\u0430 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0438 \u0438 \u043d\u044f\u043c\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 +you\ can\ start\ using\ the\ installed\ plugins\ right\ away=\u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u043f\u043e\u043b\u0437\u0432\u0430\u0442\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0438\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u0435\u0433\u0430 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/body_pl.properties b/core/src/main/resources/hudson/model/UpdateCenter/body_pl.properties index d63f523d32a37569f3533a311a9046b2f7d347e9..8c519ef315ab3942a8381ff40ed0ca16e05d2279 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/body_pl.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/body_pl.properties @@ -21,5 +21,5 @@ # THE SOFTWARE. Go\ back\ to\ the\ top\ page=Wr\u00F3\u0107 do strony g\u0142\u00F3wnej -warning=Zrestartuj Jenkinsa gdy instalacja si\u0119 zako\u0144czy i \u017Cadne zadanie nie b\u0119dzie wykonywane +warning=Uruchom ponownie Jenkinsa, gdy instalacja si\u0119 zako\u0144czy i \u017Cadne zadanie nie b\u0119dzie wykonywane you\ can\ start\ using\ the\ installed\ plugins\ right\ away=Mo\u017Cesz ju\u017C zacz\u0105\u0107 korzysta\u0107 z zainstalowanych wtyczek diff --git a/core/src/main/resources/hudson/model/UpdateCenter/body_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/body_sr.properties index fc0d020534f965dac25486b71963a3851d364877..d91543fb320bcda8fc85b439a1586b240c57995e 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/body_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/body_sr.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -Go\ back\ to\ the\ top\ page=Povratak na vrh strane -warning=Restartujte Jenkins kada se zavr\u0161i instalacija i nema job-ova koji su u toku -you\ can\ start\ using\ the\ installed\ plugins\ right\ away=Mo\u017Eete po\u010Deti da koristite instalirani dodatak odmah +Go\ back\ to\ the\ top\ page=\u041F\u043E\u0432\u0440\u0430\u0442\u0430\u043A +warning=\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0438\u0442\u0435 Jenkins \u043A\u0430\u0434\u0430 \u0431\u0443\u0434\u0435 \u0441\u0435 \u0437\u0430\u0432\u0440\u0448\u0438\u043B\u0430 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u0438 \u043D\u0435 \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u043E \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 \u0443 \u0442\u043E\u043A\u0443 +you\ can\ start\ using\ the\ installed\ plugins\ right\ away=\u041C\u043E\u0436\u0435\u0442\u0435 \u043E\u0434\u043C\u0430\u0445 \u043F\u043E\u0447\u0435\u0442\u0438 \u0434\u0430 \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/index_bg.properties b/core/src/main/resources/hudson/model/UpdateCenter/index_bg.properties index 97c35ef9dcc77121b36c12a8318636df110e652c..4d7fc887a0e5e51e64aaf8f04383b3a53f47ebec 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/index_bg.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/index_bg.properties @@ -1,3 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Installing\ Plugins/Upgrades=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u043D\u0435 \u043D\u0430 \u043F\u043B\u044A\u0433\u0438\u043D\u0438/\u044A\u043F\u0433\u0440\u0435\u0439\u0434\u0438 +Installing\ Plugins/Upgrades=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438/\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f +Update\ Center=\ + \u0426\u0435\u043d\u0442\u044a\u0440 \u0437\u0430 \u043e\u0431\u043d\u043e\u0432\u044f\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/index_pl.properties b/core/src/main/resources/hudson/model/UpdateCenter/index_pl.properties index 11dfad78d018cbb9af3d44dc0b8dc69612e95a4b..df69a1766b3b3dde170ab0e61badd6d910e9c170 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/index_pl.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/index_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Installing\ Plugins/Upgrades=Instalowanie Wtyczek/Aktualizacji +Installing\ Plugins/Upgrades=Instalowanie wtyczek i aktualizacji diff --git a/core/src/main/resources/hudson/model/UpdateCenter/index_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/index_sr.properties index 22d5060384d5bf285cda51d20dbae81ba993e5c6..8832564b2b9ce2172051b1da7f809384f2c22416 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/index_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/index_sr.properties @@ -1,3 +1,4 @@ # This file is under the MIT License by authors -Installing\ Plugins/Upgrades=Instalacija dodataka/nadogradnja +Update\ Center=\u0426\u0435\u043D\u0442\u0430\u0440 \u0437\u0430 \u0430\u0436\u0443\u0440\u0438\u0440\u0430\u045A\u0435 +Installing\ Plugins/Upgrades=\u0418\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u043C\u043E\u0434\u0443\u043B\u0435 \u0438 \u043D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly index 3880cfa74c642c187160337ea8d423b6b00821b6..5f9d40194f0f594dc9caa0efa9e4e534bc08bab9 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel.jelly @@ -32,7 +32,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_bg.properties b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_bg.properties index c7e62818b2d0646ecbd142f2fdfd29234fb5c07d..302e18f26add97c54020b8baa5dda021f5be704a 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_bg.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_bg.properties @@ -1,5 +1,25 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Back\ to\ Dashboard=\u041E\u0431\u0440\u0430\u0442\u043D\u043E \u043A\u044A\u043C \u041D\u0430\u0447\u0430\u043B\u0435\u043D \u0435\u043A\u0440\u0430\u043D -Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0430 Jenkins -Manage\ Plugins=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0430 \u043F\u043B\u044A\u0433\u0438\u043D\u0438 +Back\ to\ Dashboard=\u041e\u0431\u0440\u0430\u0442\u043d\u043e \u043a\u044a\u043c \u041d\u0430\u0447\u0430\u043b\u0435\u043d \u0435\u043a\u0440\u0430\u043d +Manage\ Jenkins=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 Jenkins +Manage\ Plugins=\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043b\u044a\u0433\u0438\u043d\u0438 diff --git a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_pl.properties b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_pl.properties index 8727a0134675d9b668437628effad41d10ead239..30d61be913f4fdf6b1c7c7b733fd98f35c171f2c 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_pl.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_pl.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Back\ to\ Dashboard=Wr\u00F3\u0107 na Stron\u0119 G\u0142\u00F3wn\u0105 -Manage\ Jenkins=Zarz\u0105dzanie Jenkins +Back\ to\ Dashboard=Powr\u00F3t do tablicy +Manage\ Jenkins=Zarz\u0105dzanie Jenkinsem Manage\ Plugins=Zarz\u0105dzanie wtyczkami diff --git a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_sr.properties b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_sr.properties index a82734d03eb7ebf549ace1f4184283b32e7a2e5f..b2340e67976a89d618e357e659e5e89eb3bd01e7 100644 --- a/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_sr.properties +++ b/core/src/main/resources/hudson/model/UpdateCenter/sidepanel_sr.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -Back\ to\ Dashboard=Povratak na po\u010Detnu stranu -Manage\ Jenkins=Upravljanje Jenkins-om -Manage\ Plugins=Upravljanje dodacima +Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C +Manage\ Plugins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u043C\u043E\u0434\u0443\u043B\u0438\u043C\u0430 +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 diff --git a/core/src/main/resources/hudson/model/UsageStatistics/footer.jelly b/core/src/main/resources/hudson/model/UsageStatistics/footer.jelly index c1c8abcc9fe28fa9c5b66472ef25eb6d45f7407e..b532b3d746749f00c8cc0aae4bedec456b5ee418 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/footer.jelly +++ b/core/src/main/resources/hudson/model/UsageStatistics/footer.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. diff --git a/core/src/main/resources/hudson/model/UsageStatistics/global_sr.properties b/core/src/main/resources/hudson/model/UsageStatistics/global_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0d9545b6dc9acd505a943a5ea510de689a3fc042 --- /dev/null +++ b/core/src/main/resources/hudson/model/UsageStatistics/global_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +statsBlurb=\u041F\u043E\u043C\u043E\u0437\u0438 \u043D\u0430\u043C \u0434\u0430 \u043F\u043E\u0431\u043E\u0459\u0448\u0430\u043C\u043E Jenkins \u0448\u0430\u0459\u0435\u045B\u0438 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u043E \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0443 \u0438 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458\u0435 \u043E \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438\u043C\u0430 Jenkins \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0443. \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.html b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.html index 2ec5cf132aced3823e916cb620b6f4644424b120..37b1e5cc6501c14d9b9cbe2340409f3cc7351bf7 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.html +++ b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected.html @@ -1,6 +1,6 @@
    Knowing how Jenkins is used is a tremendous help in guiding the direction of the development, especially - for open-source projects where users are inheritenly hard to track down. When this option is enabled, + for open-source projects where users are inherently hard to track down. When this option is enabled, Jenkins periodically send information about your usage of Jenkins.

    @@ -8,9 +8,9 @@

    • Your Jenkins version -
    • For your master and each slave, OS type, and # of executors +
    • For your master and each agent, OS type, and # of executors
    • Plugins that are installed and their versions -
    • Number jobs per each job type in your Jenkins +
    • Number of jobs per each job type in your Jenkins

    @@ -18,7 +18,4 @@ (except information inherently revealed by HTTP, such as the IP address). Tabulated data of these usage statistics submissions will be shared with the community. -

    - You can read - the discussion of this mechanism in the community, and you are welcome to add your voice here.

    diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_de.html b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_de.html deleted file mode 100644 index f3229055b6c1a2954a936ca6c438a95868f12e1d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_de.html +++ /dev/null @@ -1,24 +0,0 @@ -
    - Zu wissen, wie Jenkins genutzt wird, ist ungemein hilfreich, wenn es um die Richtung der - Weiterentwicklung geht - insbesondere bei OpenSource-Projekten, bei denen die Anwender - nicht genau bekannt sind. Wenn angewählt, sendet Jenkins in Abständen Informationen über - die Nutzung dieser Instanz. -

    - Diese Informationen umfassen ausschließlich: -

      -
    • Ihre Jenkins-Version
    • -
    • Für jeden Master- und Slave-Knoten: Betriebssystem und Anzahl der Build-Prozessoren
    • -
    • Installierte Plugins und deren Version
    • -
    • Anzahl per angelegten Jobs pro Jobtyp
    • -
    - -

    - Diese Informationen enthalten nichts, was Sie identifiziert oder uns erlauben könnte, - mit Ihnen in Kontakt zu treten (außer Daten, die inhärent bei HTTP übermittelt werden, - wie beispielsweise IP-Adressen). Diese Daten werden in zusammengefasster Form als - Nutzungsstatistiken der Jenkins-Community zur Verfügung gestellt. - -

    - Lesen Sie die - Diskussion dieser Funktion in der Jenkins-Community - und steuern Sie gerne Ihre Meinung dazu bei! -

    diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_fr.html b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_fr.html index 2fdf5eea3ba6c503f159d862d692f3cccb519fae..8d4df6df9de874f58bd40ced028d0d3351ab502c 100644 --- a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_fr.html +++ b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_fr.html @@ -15,9 +15,9 @@

    - Cette information ne contient rien qui vous identifie ou qui nous permet de vous contacter + Cette information ne contient rien qui vous identifie ou qui nous permette de vous contacter (hors certaines informations intrinsèques à HTTP, comme votre adresse IP). - Les données compilées de ces statistiques d'utilisation selon partagées avec la communauté. + Les données compilées de ces statistiques d'utilisation seront partagées avec la communauté.

    N'hésitez pas à lire diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_pt_BR.html b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_pt_BR.html new file mode 100644 index 0000000000000000000000000000000000000000..bde77e44f1cb38d581a251799ede138f18b80d04 --- /dev/null +++ b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_pt_BR.html @@ -0,0 +1,20 @@ +

    diff --git a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_zh_TW.html b/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_zh_TW.html deleted file mode 100644 index 65e59953f2a5687055b1de09902fd1a8d40f5d79..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/model/UsageStatistics/help-usageStatisticsCollected_zh_TW.html +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/core/src/main/resources/hudson/model/User/builds_bg.properties b/core/src/main/resources/hudson/model/User/builds_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..c1eb64e7be7b75e8e5eb9906ea756fb5a6ad7851 --- /dev/null +++ b/core/src/main/resources/hudson/model/User/builds_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# Builds for {0} +title=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u0437\u0430 \u201e{0}\u201c diff --git a/core/src/main/resources/hudson/model/User/builds_pl.properties b/core/src/main/resources/hudson/model/User/builds_pl.properties index 44e113ee04495aba98b04724d057bbb6c4245d23..e95f03aedb77cc185bb8a7b176c05f33fa26426d 100644 --- a/core/src/main/resources/hudson/model/User/builds_pl.properties +++ b/core/src/main/resources/hudson/model/User/builds_pl.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -title=Budowy {0} +title=Zadania u\u017Cytkownika {0} diff --git a/core/src/main/resources/hudson/model/User/builds_sr.properties b/core/src/main/resources/hudson/model/User/builds_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..debfdbad945d6a20fb4c198f6ee0c8d595483014 --- /dev/null +++ b/core/src/main/resources/hudson/model/User/builds_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +title=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0437\u0430 {0} diff --git a/core/src/main/resources/hudson/model/User/configure_bg.properties b/core/src/main/resources/hudson/model/User/configure_bg.properties index 5594063fb90146922ed09a7232b4bcb93ac982ba..5770347ec5ce141219382ebb7fd43c0ceb58609a 100644 --- a/core/src/main/resources/hudson/model/User/configure_bg.properties +++ b/core/src/main/resources/hudson/model/User/configure_bg.properties @@ -1,4 +1,31 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 -Full\ name=\u041f\u044a\u043b\u043d\u043e \u0438\u043c\u0435 +Description=\ + \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +Full\ name=\ + \u041f\u044a\u043b\u043d\u043e \u0438\u043c\u0435 +# User \u2018{0}\u2019 Configuration +title=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u201e{0}\u201c +Save=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/model/User/configure_pl.properties b/core/src/main/resources/hudson/model/User/configure_pl.properties index 9f7991a2af4424bcc48327005d6bb70a42b4f5cc..ee7056f22e608cd62a6a1997e681114cbbc94f7f 100644 --- a/core/src/main/resources/hudson/model/User/configure_pl.properties +++ b/core/src/main/resources/hudson/model/User/configure_pl.properties @@ -1,4 +1,27 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Copyright (c) 2004-2016, Sun Microsystems, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. Description=Opis Full\ name=Twoje imi\u0119 i nazwisko +# User \u2018{0}\u2019 Configuration +title=Konfiguracja u\u017Cytkownika \u2018{0}\u2019 +Save=Zapisz diff --git a/core/src/main/resources/hudson/model/User/configure_sr.properties b/core/src/main/resources/hudson/model/User/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c7fb0bbcca5c093fa9fd7d05b1396c95944af712 --- /dev/null +++ b/core/src/main/resources/hudson/model/User/configure_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +title=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 \u2018{0}\u2019 +Full\ name=\u0418\u043C\u0435 \u0438 \u043F\u0440\u0435\u0437\u0438\u043C\u0435 +Description=\u041E\u043F\u0438\u0441 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 diff --git a/core/src/main/resources/hudson/model/User/delete_bg.properties b/core/src/main/resources/hudson/model/User/delete_bg.properties index 7597cd31c248b62b41255c9f4a8a9a4bb87edde4..f369356c7d8da5724601996f73e5b1b1994eb764 100644 --- a/core/src/main/resources/hudson/model/User/delete_bg.properties +++ b/core/src/main/resources/hudson/model/User/delete_bg.properties @@ -1,4 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Are\ you\ sure\ about\ deleting\ the\ user\ from\ Jenkins?=\u0421\u0438\u0433\u0443\u0440\u0435\u043D \u043B\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0436\u0435\u043B\u0430\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u044F \u043E\u0442 Jenkins? -Yes=\u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ user\ from\ Jenkins?=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u043e\u0442 Jenkins? +Yes=\ + \u0414\u0430 diff --git a/core/src/main/resources/hudson/model/User/delete_de.properties b/core/src/main/resources/hudson/model/User/delete_de.properties index 65cf14106f0edf288696977f5af77edbbd95a34f..2adbdfd815addde8d4bd1588f851444ce904722d 100644 --- a/core/src/main/resources/hudson/model/User/delete_de.properties +++ b/core/src/main/resources/hudson/model/User/delete_de.properties @@ -1,25 +1,25 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Are\ you\ sure\ about\ deleting\ the\ user\ from\ Jenkins?=\ - Mchten Sie den Benutzer wirklich lschen? -Yes=Ja +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Are\ you\ sure\ about\ deleting\ the\ user\ from\ Jenkins?=\ + Mchten Sie den Benutzer wirklich lschen? +Yes=Ja diff --git a/core/src/main/resources/hudson/model/User/delete_sr.properties b/core/src/main/resources/hudson/model/User/delete_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..24274a814edff5c8bf7732080b36b02f6670fa5a --- /dev/null +++ b/core/src/main/resources/hudson/model/User/delete_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Are\ you\ sure\ about\ deleting\ the\ user\ from\ Jenkins?=\u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 \u0441\u0430 Jenkins? +Yes=\u0414\u0430 diff --git a/core/src/main/resources/hudson/model/User/index_bg.properties b/core/src/main/resources/hudson/model/User/index_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..a8cee7815f657a7c9faa5f8915c8435c3cd31b28 --- /dev/null +++ b/core/src/main/resources/hudson/model/User/index_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Jenkins\ User\ Id=\ + \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b \u043d\u0430 Jenkins +Groups=\ + \u0413\u0440\u0443\u043f\u0438 diff --git a/core/src/main/resources/hudson/model/User/index_pl.properties b/core/src/main/resources/hudson/model/User/index_pl.properties index f9e21a20ece65fe879d87eb0b66e39c85700c269..b349e3a89f1eaf6addbf26a3983dd84d0da8e89d 100644 --- a/core/src/main/resources/hudson/model/User/index_pl.properties +++ b/core/src/main/resources/hudson/model/User/index_pl.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Jenkins\ User\ Id=Id u\u017Cytkownika +Jenkins\ User\ Id=Identyfikator u\u017Cytkownika diff --git a/core/src/main/resources/hudson/model/User/index_sr.properties b/core/src/main/resources/hudson/model/User/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..02d60641847924e326e2fe3c293e13520424ab09 --- /dev/null +++ b/core/src/main/resources/hudson/model/User/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Groups=\u0413\u0440\u0443\u043F\u0435 +Jenkins\ User\ Id=Jenkins \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u043E\u043D\u0438 \u0431\u0440\u043E\u0458 diff --git a/core/src/main/resources/hudson/model/User/sidepanel.jelly b/core/src/main/resources/hudson/model/User/sidepanel.jelly index 126bdae5d808700d621d0fa9abe0a2380234d028..46bad7a60514cd98df83a1a54a14f5233684f980 100644 --- a/core/src/main/resources/hudson/model/User/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/User/sidepanel.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/User/sidepanel_bg.properties b/core/src/main/resources/hudson/model/User/sidepanel_bg.properties index 5e7993309cf51c27efb0463281f40eb25c8a43d0..9389f80f6935bd2b8346c26a576efffce232a334 100644 --- a/core/src/main/resources/hudson/model/User/sidepanel_bg.properties +++ b/core/src/main/resources/hudson/model/User/sidepanel_bg.properties @@ -1,7 +1,32 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Builds=\u0411\u0438\u043B\u0434\u043E\u0432\u0435 -Configure=\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 -Delete=\u0418\u0437\u0442\u0440\u0438\u0439 -People=\u0425\u043E\u0440\u0430 -Status=\u0421\u0442\u0430\u0442\u0443\u0441 +Builds=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +Configure=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +Delete=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 +People=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 +Status=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 diff --git a/core/src/main/resources/hudson/model/User/sidepanel_pl.properties b/core/src/main/resources/hudson/model/User/sidepanel_pl.properties index 5292105692451a354897350a6d324bc564a1ca81..5cfaa27c4a5f3fc6a70e286b168ca95d41bca29f 100644 --- a/core/src/main/resources/hudson/model/User/sidepanel_pl.properties +++ b/core/src/main/resources/hudson/model/User/sidepanel_pl.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors -Builds=Build''''y +Builds=Zadania Configure=Konfiguracja Delete=Usu\u0144 My\ Views=Moje widoki diff --git a/core/src/main/resources/hudson/model/User/sidepanel_sr.properties b/core/src/main/resources/hudson/model/User/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c7bf9e97cb812eaf9ac4d2f65a3e655291a85d36 --- /dev/null +++ b/core/src/main/resources/hudson/model/User/sidepanel_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +People=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 +Status=\u0421\u0442\u0430\u045A\u0435 +Builds=\u0418\u0437\u0433\u0440\u0430\u0434\u045Ae +Configure=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +Delete=\u0423\u043A\u043B\u043E\u043D\u0438 +My\ Views=\u041C\u043E\u0458\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0438 diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties index de84134b005541dc9ebfef502d32c23faffa3081..8f97078287e8d2c01bb6865e7d504cbfc31f76bd 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_bg.properties @@ -1,6 +1,37 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Last\ Active=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0430\u043A\u0442\u0438\u0432\u0435\u043D -Name=\u0418\u043C\u0435 -On=\u041D\u0430 -People=\u0425\u043E\u0440\u0430 +Name=\ + \u0418\u043c\u0435 +On=\ + \u041d\u0430 +People=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 +All\ People=\ + \u0412\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 +User\ Id=\ + \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b +blurb=\ + \u0412\u043a\u043b\u044e\u0447\u0432\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0437\u043d\u0430\u0442\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u043d\u043e \u0442\u0435\u0437\u0438, \u043a\u043e\u0438\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0430\u0442\u0430 \u043e\u0431\u043b\u0430\u0441\u0442\ + \u043c\u043e\u0436\u0435 \u0434\u0430 \u0438\u0437\u0431\u0440\u043e\u0438, \u043a\u0430\u043a\u0442\u043e \u0438 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u0438 \u0432 \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0442\u0430 \u043f\u0440\u0438 \u043f\u043e\u0434\u0430\u0432\u0430\u043d\u0435. +Last\ Commit\ Activity=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438 \u043f\u043e\u0434\u0430\u0432\u0430\u043d\u0438\u044f diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_pl.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_pl.properties index 9748cfd3ffdc0336c6ddd7db22f6d7f45f9d3358..0c78d03b5ab3f64b4a56acef58cd5aa50faa3cae 100644 --- a/core/src/main/resources/hudson/model/View/AsynchPeople/index_pl.properties +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_pl.properties @@ -23,5 +23,8 @@ Last\ Active=Ostatnio aktywny Name=Nazwa On=Na -People=Ludzie +People=U\u017Cytkownicy User\ Id=Identyfikator u\u017Cytkownika +Last\ Commit\ Activity=Ostatnia zmiana +blurb=Prezentuje wszystkich uwierzytelnionych u\u017Cytkownik\u00F3w w\u0142\u0105cznie z identyfikatorem oraz osoby wymienione w opisach zarejestrowanych zmian. + diff --git a/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties b/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a44ab2742a405a3f9ef102fb9e492a1ce97a8671 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/AsynchPeople/index_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +People=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 +blurb=\u0422\u0430\u0431\u0435\u043B\u0430 \u0441\u0432\u0438\u0445 Jenkins \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430, \u0443\u043A\u0459\u0443\u0447\u0443\u0458\u0443\u045B\u0438 \u0441\u0432\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0435 \u043A\u043E\u0458e \u0441\u0438\u0441\u0442\u0435\u043C \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0458\u0435 \u043C\u043E\u0436\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438, \u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438 \u0443 \u043A\u043E\u043C\u0438\u0442-\u043F\u043E\u0440\u0443\u043A\u0430\u043C\u0430 \u0435\u0432\u0438\u0434\u0435\u043D\u0442\u0438\u0440\u0430\u043D\u0438 \u0443 \u0434\u043D\u0435\u0432\u043D\u0438\u043A\u0430\u043C\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0430. +User\ Id=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u043E\u043D\u0438 \u0431\u0440\u043E\u0458 +Name=\u0418\u043C\u0435 +Last\ Commit\ Activity=\u0417\u0430\u0434\u045A\u0435 \u0430\u043A\u0442\u0438\u0432\u0430\u043D +On=\u043D\u0430 +All\ People=\u0421\u0432\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 +Last\ Active=\u0417\u0430\u0434\u045A\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0441\u0442 diff --git a/core/src/main/resources/hudson/model/View/People/index_bg.properties b/core/src/main/resources/hudson/model/View/People/index_bg.properties index 630c28cfcdb84d27ce6bc1a025929a20cc8d34a8..92e26b0d18582b08dc165857b285a10b2a11d90f 100644 --- a/core/src/main/resources/hudson/model/View/People/index_bg.properties +++ b/core/src/main/resources/hudson/model/View/People/index_bg.properties @@ -1,3 +1,28 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -People=\u0425\u043E\u0440\u0430 +People=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 +# Moved to asynchPeople for performance reasons. +Moved\ to\ asyncPeople=\ + \u041f\u0440\u0435\u043c\u0435\u0441\u0442\u0435\u043d\u043e \u0432 \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044a\u0440\u0445\u0443\ + \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\u0442\u0435 \u0437\u0430 \u043f\u043e-\u0434\u043e\u0431\u0440\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442. diff --git a/core/src/main/resources/hudson/model/View/People/index_sr.properties b/core/src/main/resources/hudson/model/View/People/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b2ba8ffa19ffe354c0d0d1bb541a9b2382df8e43 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/People/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +People=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 +Moved\ to\ asyncPeople=\u041F\u0440\u0435\u043C\u0435\u0448\u045B\u0435\u043D\u043E \u043D\u0430 asyncPeople diff --git a/core/src/main/resources/hudson/model/View/ajaxBuildQueue.jelly b/core/src/main/resources/hudson/model/View/ajaxBuildQueue.jelly index 2f1614be49bbba181d70428e6046cdbed3569cbb..a26339d7d57ef09933b964f647d2e63891c5d76a 100644 --- a/core/src/main/resources/hudson/model/View/ajaxBuildQueue.jelly +++ b/core/src/main/resources/hudson/model/View/ajaxBuildQueue.jelly @@ -28,6 +28,6 @@ THE SOFTWARE. - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/View/builds_bg.properties b/core/src/main/resources/hudson/model/View/builds_bg.properties index ef45208337a87a52381a56792c0f83a180a8fb7d..905bf14ee08d4bc7a01b007e71d71a4cb209c0b1 100644 --- a/core/src/main/resources/hudson/model/View/builds_bg.properties +++ b/core/src/main/resources/hudson/model/View/builds_bg.properties @@ -1,4 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Export\ as\ plain\ XML=\u0415\u043A\u0441\u043F\u043E\u0440\u0442 \u0432 XML -buildHistory=\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u043E\u0442 \u0431\u0438\u043B\u0434\u043E\u0432\u0435 \u043D\u0430 {0} +Export\ as\ plain\ XML=\ + \u0418\u0437\u043d\u0430\u0441\u044f\u043d\u0435 \u0432 XML +buildHistory=\ + \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u043d\u0430 \u201e{0}\u201c diff --git a/core/src/main/resources/hudson/model/View/builds_lt.properties b/core/src/main/resources/hudson/model/View/builds_lt.properties index 3ad781ecaf0fc93875c1ffa6bead70c1cd238f15..503881cfcfd72ffd00c1c8407093b9ef65d23c23 100644 --- a/core/src/main/resources/hudson/model/View/builds_lt.properties +++ b/core/src/main/resources/hudson/model/View/builds_lt.properties @@ -1,4 +1,2 @@ # This file is under the MIT License by authors - -Export\ as\ plain\ XML=Eksportuoti kaip XML buildHistory={0} surinkimo istorija diff --git a/core/src/main/resources/hudson/model/View/builds_pl.properties b/core/src/main/resources/hudson/model/View/builds_pl.properties index 2f4df2378637e608a2957f30031e9d245f53272d..1ab9fce1207c9257347aaad86418ff90533b8d3c 100644 --- a/core/src/main/resources/hudson/model/View/builds_pl.properties +++ b/core/src/main/resources/hudson/model/View/builds_pl.properties @@ -21,4 +21,4 @@ # THE SOFTWARE. Export\ as\ plain\ XML=Eksportuj jako XML -buildHistory=Historia kompilacji projektu {0} +buildHistory=Historia zada\u0144 dla widoku {0} diff --git a/core/src/main/resources/hudson/model/View/builds_sr.properties b/core/src/main/resources/hudson/model/View/builds_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e8da756a6969d908fdd6681bc6e8aae222eb4437 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/builds_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +buildHistory=\u0418\u0441\u0442\u043E\u0440\u0438\u0458\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 {0} +Export\ as\ plain\ XML=\u0418\u0437\u0432\u0435\u0437\u0438 \u0443 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u043E\u043C XML \u0444\u043E\u0440\u043C\u0430\u0442\u0443 diff --git a/core/src/main/resources/hudson/model/View/configure.jelly b/core/src/main/resources/hudson/model/View/configure.jelly index b0c41a8387ec9370e8cbe345009491135d9774af..11d4ea1f8635a734d4a812b5bcc2cccc4e05123f 100644 --- a/core/src/main/resources/hudson/model/View/configure.jelly +++ b/core/src/main/resources/hudson/model/View/configure.jelly @@ -36,7 +36,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/model/View/configure_lt.properties b/core/src/main/resources/hudson/model/View/configure_lt.properties index e8d0d7de41b89ed842af1319f8af4e78f68ced5e..c455fc8dc546d750d10b20ec1e140cb2edc44132 100644 --- a/core/src/main/resources/hudson/model/View/configure_lt.properties +++ b/core/src/main/resources/hudson/model/View/configure_lt.properties @@ -1,4 +1,6 @@ # This file is under the MIT License by authors - Description=Apra\u0161ymas Name=Pavadinimas +OK=Gerai +Filter\ build\ executors=Filtruoti vykdytojus +Filter\ build\ queue=Filtruoti vykdymo eil\u0119 diff --git a/core/src/main/resources/hudson/model/View/configure_pl.properties b/core/src/main/resources/hudson/model/View/configure_pl.properties index e9a7446b35494ee84ff2da7f02cca91a99a8338b..0659364ac10affb4c975db7ae59c90f5d70991cd 100644 --- a/core/src/main/resources/hudson/model/View/configure_pl.properties +++ b/core/src/main/resources/hudson/model/View/configure_pl.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors Description=Opis -Filter\ build\ executors=Filtr wykonawc\u00F3w Builda -Filter\ build\ queue=Filtr kolejki budowania +Filter\ build\ executors=Filtr wykonawc\u00F3w zada\u0144 +Filter\ build\ queue=Filtr kolejki zada\u0144 Name=Nazwa diff --git a/core/src/main/resources/hudson/model/View/configure_sr.properties b/core/src/main/resources/hudson/model/View/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2a667b1e7e6cab1cbbe06f3479eb6774abb0481b --- /dev/null +++ b/core/src/main/resources/hudson/model/View/configure_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Edit\ View=\u0417\u0440\u0435\u0434\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +Name=\u0418\u043C\u0435 +Description=\u041E\u043F\u0438\u0441 +Filter\ build\ queue=\u041F\u0440\u043E\u0444\u0438\u043B\u0442\u0440\u0438\u0440\u0430\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u043D\u0438 \u0440\u0435\u0434 +Filter\ build\ executors=\u041F\u0440\u043E\u0444\u0438\u043B\u0442\u0440\u0438\u0440\u0430\u0458 \u0433\u0440\u0430\u0434\u0438\u0442\u0435\u0459\u0435 +OK=\u0423\u0440\u0435\u0434\u0443 diff --git a/core/src/main/resources/hudson/model/View/delete_lt.properties b/core/src/main/resources/hudson/model/View/delete_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..9ac81dd69ab60782eddee35da5671ecd22b14de3 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/delete_lt.properties @@ -0,0 +1,4 @@ +# /jenkins-core/src/main/resources/hudson/model/View/delete_lt.properties + +Are\ you\ sure\ about\ deleting\ the\ view?=Ar tikrai norite i\u0161trinti \u0161i\u0105 skilt\u012F? +Yes=Taip diff --git a/core/src/main/resources/hudson/model/View/delete_sr.properties b/core/src/main/resources/hudson/model/View/delete_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e6dd5680f97ce36a7385dab914ffae341dc62727 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/delete_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Yes=\u0414\u0430 +Are\ you\ sure\ about\ deleting\ the\ view?=\u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434? diff --git a/core/src/main/resources/hudson/model/View/index_lt.properties b/core/src/main/resources/hudson/model/View/index_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..c035444137fb427d3755b6fa84e489f58464c4a2 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/index_lt.properties @@ -0,0 +1 @@ +Dashboard=Skydelis diff --git a/core/src/main/resources/hudson/model/View/index_sr.properties b/core/src/main/resources/hudson/model/View/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b5b7c47fc69cb624c90290f3bedf74431eded241 --- /dev/null +++ b/core/src/main/resources/hudson/model/View/index_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Dashboard=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0438 \u043F\u0430\u043D\u0435\u043B diff --git a/core/src/main/resources/hudson/model/View/newJob.jelly b/core/src/main/resources/hudson/model/View/newJob.jelly index ba6ae05161056b184b9373389040fc7c251e73a1..ffd1f4e44e7e6669ec3fdbc07e52d9211201c504 100644 --- a/core/src/main/resources/hudson/model/View/newJob.jelly +++ b/core/src/main/resources/hudson/model/View/newJob.jelly @@ -22,20 +22,57 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - - - + + + + + + - - - - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/AuthorizationStrategy/Unsecured/help_zh_CN.html b/core/src/main/resources/hudson/security/AuthorizationStrategy/Unsecured/help_zh_CN.html index 764b333cb1e2da7d92e6320003b5a15028f89222..c505cde8bd54adc4ef652af3647d776dfdafc22e 100644 --- a/core/src/main/resources/hudson/security/AuthorizationStrategy/Unsecured/help_zh_CN.html +++ b/core/src/main/resources/hudson/security/AuthorizationStrategy/Unsecured/help_zh_CN.html @@ -1,7 +1,7 @@ -
    - 不执行任何授权,任何人都能完全控制Jenkins,这包括没有登录的匿名用户. - -

    - 这种情况对于可信任的环境(比如公司内网)非常有用,或者你只是使用授权做一些个性化的支持.这样的话,如果某人想快速的更改Jenkins,他就能够避免被强制登录. - +

    + 不执行任何授权,任何人都能完全控制Jenkins,这包括没有登录的匿名用户. + +

    + 这种情况对于可信任的环境(比如公司内网)非常有用,或者你只是使用授权做一些个性化的支持.这样的话,如果某人想快速的更改Jenkins,他就能够避免被强制登录. +

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error_sr.properties b/core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..53c32244ac8f179c7dcf69dc96b79cdf1cacfe78 --- /dev/null +++ b/core/src/main/resources/hudson/security/FederatedLoginService/UnclaimedIdentityException/error_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +loginError=\u0413\u0440\u0435\u0448\u043A\u0430 \u043F\u0440\u0438\u0458\u0430\u0432\u0435: {0} \u043D\u0435\u043C\u0430 \u0430\u0441\u043E\u0446\u0438\u0458\u0430\u0446\u0438\u0458\u0435 +blurb={0} "{1}" \u043D\u0438\u0458\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u043E \u0441\u0430 \u0431\u0438\u043B\u043E \u043A\u043E\u0458\u0438\u043C Jenkins \u043D\u0430\u043B\u043E\u0433\u043E\u043C. \ + \u0410\u043A\u043E \u0432\u0435\u045B \u0438\u043C\u0430\u0433\u0435 \u043D\u0430\u043B\u043E\u0433 \u0438 \u043F\u043E\u043A\u0443\u0448\u0430\u0432\u0430\u0442\u0435 \u0434\u0430 \u043F\u043E\u0432\u0435\u0436\u0435\u0442\u0435 {0} \u0441 \u045A\u0438\u043C, \ + \u043E\u0432\u043E \u043D\u0438\u0458\u0435 \u043F\u0440\u0430\u0432\u043E \u043C\u0435\u0441\u0442\u043E \u0437\u0430 \u0442\u043E. \u0420\u0430\u0434\u0438\u0458\u0435
    1. Login
    2. \u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 \u0432\u0430\u0448\u0435 \u0438\u043C\u0435
    3. \u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u043D\u0430 "\u0423\u0440\u0435\u0434\u0438" \u043B\u0438\u043D\u043A, \u0438 \ +
    4. \u043F\u043E\u0432\u0435\u0436\u0438\u0442\u0435 \u043D\u043E\u0432\u0438 {0} \u0441\u0430 \u0442\u0435 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435
    + diff --git a/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config.jelly b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config.jelly new file mode 100644 index 0000000000000000000000000000000000000000..0e627effbc99edb9527bbd7dca0bce593721564d --- /dev/null +++ b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config.jelly @@ -0,0 +1,7 @@ + + + + + + diff --git a/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config_sr.properties b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4037369d9798f35bb149e6eea535f6b83118a636 --- /dev/null +++ b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Allow\ anonymous\ read\ access=\u0414\u043E\u0437\u0432\u043E\u043B\u0438 \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438\u043C \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 diff --git a/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help-allowAnonymousRead.html b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help-allowAnonymousRead.html new file mode 100644 index 0000000000000000000000000000000000000000..0f357d28e154a9b5a7cbf8fb0c88a67e650bdf3a --- /dev/null +++ b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help-allowAnonymousRead.html @@ -0,0 +1,3 @@ +
    + If checked, this will allow users who are not authenticated to access Jenkins in a read-only mode. +
    diff --git a/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help_zh_CN.html b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help_zh_CN.html index 454c73eb129bbd4cf775d3850c8b2638eab98d46..5be288ecc6122b4b8417e115d55db47531b9e3f3 100644 --- a/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help_zh_CN.html +++ b/core/src/main/resources/hudson/security/FullControlOnceLoggedInAuthorizationStrategy/help_zh_CN.html @@ -1,6 +1,6 @@ -
    - 这种授权模式下,每个登录用户都持有对Jenkins的全部控制权限.只有匿名用户没有全部控制权,匿名用户只有查看权限. - -

    - 这种授权模式的好处是强制用户登录后才能执行操作,这样你可以随时记录谁都做了什么操作.这种设置也适用于公共使用的Jenkins,只有你信任的人才拥有账户. +

    + 这种授权模式下,每个登录用户都持有对Jenkins的全部控制权限.只有匿名用户没有全部控制权,匿名用户只有查看权限. + +

    + 这种授权模式的好处是强制用户登录后才能执行操作,这样你可以随时记录谁都做了什么操作.这种设置也适用于公共使用的Jenkins,只有你信任的人才拥有账户.

    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/config_sr.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5d8616dadac63e0781789bf7418a10706436fdd4 --- /dev/null +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/config_sr.properties @@ -0,0 +1,23 @@ +# This file is under the MIT License by authors + +Default\ view=\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +Home\ directory=\u0413\u043B\u0430\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C +System\ Message=\u0414\u043E\u0431\u0440\u043E\u0434\u043E\u0448\u043B\u0438 +LOADING=\u0423\u0427\u0418\u0422\u0410\u0412\u0410\u040A\u0415 +statsBlurb=\u041F\u043E\u0448\u0430\u0459\u0438 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435 \u043E \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0443 \u0438 \u0438\u0437\u0432\u0435\u0448\u0442\u0430\u0458\u0438 \u043E \u0433\u0440\u0435\u0448\u043A\u0430\u043C\u0430 Jenkins-\u0430. +Global\ properties=\u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 +Views\ Tab\ Bar=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0438 +My\ Views\ Tab\ Bar=\u041C\u043E\u0458\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0438 +name=\u0438\u043C\u0435 +JDKs=JDK-\u043E\u0432\u0438 +JDK\ installations=JDK \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435 +List\ of\ JDK\ installations\ on\ this\ system=\u0421\u043F\u0438\u0441\u0430\u043A JDK \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435 \u043D\u0430 \u043E\u0432\u043E\u043C \u0441\u0438\u0441\u0442\u0435\u043C\u0443 +no.such.JDK=\u041D\u0435 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u0442\u0430\u043A\u0430\u0432 JDK +Configure\ System=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u0441\u0438\u0441\u0442\u0435\u043C +Master/Slave\ Support=\u041F\u043E\u0434\u0440\u0448\u043A\u0435 \u0433\u043B\u0430\u0432\u043D\u0438\u043C \u0438 \u043F\u043E\u043C\u043E\u045B\u043D\u0438\u043C \u043C\u0430\u0448\u0438\u043D\u0430\u043C\u0430 +Slaves=\u041F\u043E\u043C\u043E\u045B\u043D\u0438 +slaves.description=\u0421\u043F\u0438\u0441\u0430\u043A \u043F\u043E\u043C\u043E\u045B\u043D\u0438\u0445 \u043C\u0430\u0448\u0438\u043D\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u043E\u0432\u0430\u043D\u0438 \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u043E\u0458 Jenkins \u043C\u0430\u0448\u0438\u043D\u0438. \u0417\u0430\u0434\u0430\u0446\u0438 \u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u043F\u043E\u0434\u0435\u0448\u0435\u043D\u0438 \u0434\u0430 \u0431\u0443\u0434\u0443 \u0438\u0437\u0432\u0440\u0448\u0435\u043D\u0438 \u043D\u0430 \u043F\u043E\u043C\u043E\u045B\u043D\u0438\u043C \u043C\u0430\u0448\u0438\u043D\u0430\u043C\u0430. +launch\ command=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 \u0437\u0430 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 +description=\u041E\u043F\u0438\u0441 +usage=\u0423\u043F\u043E\u0442\u0440\u0435\u0431\u0430 +remote\ FS\ root=\u041A\u043E\u0440\u0435\u043D \u0443\u0434\u0430\u0459\u0435\u043D\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-agentProtocol.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-agentProtocol.html new file mode 100644 index 0000000000000000000000000000000000000000..bf0c73bfb216ae9d043f38db8b768eb294d0fca1 --- /dev/null +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-agentProtocol.html @@ -0,0 +1,4 @@ +
    + Jenkins uses a TCP port to communicate with various remote agents. This option allows control + over which agent protocols are enabled. +
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort.html index 37d845e2c7f8324e8178973305ed2e1d63b00642..69a4760025cdde9e6c01846525ac0a5ce504088c 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort.html +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort.html @@ -1,7 +1,7 @@
    - Jenkins uses a TCP port to communicate with slave agents launched via JNLP. + Jenkins uses a TCP port to communicate with agent agents launched via JNLP. Normally this port is chosen randomly to avoid collisions, but this would - make securing the system difficult. If you are not using JNLP slaves, + make securing the system difficult. If you are not using JNLP agents, it's recommend to disable this TCP port. Alternatively, you can specify the fixed port number so that you can configure your firewall accordingly.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_de.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_de.html deleted file mode 100644 index bad870a7789f8fed3934a8af765ef702b5909eba..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_de.html +++ /dev/null @@ -1,8 +0,0 @@ -
    - Jenkins verwendet einen TCP-Port, um mit Slave-Knoten zu kommunizieren, die - über JNLP gestartet wurden. Normalerweise wird dieser Port zufällig - gewählt, um Kollisionen zu vermeiden - dies erschwert jedoch die Absicherung - des Systems. Wenn Sie keine JNLP-Slave-Knoten einsetzen, wird empfohlen, - diesen TCP-Port zu deaktivieren. Alternativ können Sie auch einen statischen Port - festlegen, um Ihre Firewall entsprechend leichter konfigurieren zu können. -
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_pt_BR.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_pt_BR.html deleted file mode 100644 index 9e11fe0054075d4e05d301f4f4060dad8f2c7b72..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_pt_BR.html +++ /dev/null @@ -1,7 +0,0 @@ -
    - O Jenkins usa uma porta TCP para se comunicar com os agentes slave lançados via JNLP. - Normalmente esta porta é escolhida aleatóriamente para evitar colisões, mas isto - tornaria difícil fazer a segurança do sistema. Se você não estiver usado slaves JNLP, - é recomendado desabilitar esta porta TCP. Alternativamente, você pode especificar - um número de porta específico tal que você possa configurar seu firewall corretamente. -
    diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_tr.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_tr.html deleted file mode 100644 index d3de5461df137b8390ed4410486ef29ccde99516..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_tr.html +++ /dev/null @@ -1,9 +0,0 @@ -
    - Jenkins, JNLP aracılığı ile başlatılan slave'ler ile iletişiminde TCP portunu - kullanır. Her ne kadar bu port numarası, herhangi bir çakışmayı önlemek adına - rastgele verilse de, sistem güvenliğinin yönetiminde zorluk çıkaracaktır. Eğer - JNLP slave'i kullanmıyorsanız, bu TCP port numarasını devre dışı bırakınız. - Buna alternatif olarak, bu port numarasını sabit bir numara olarak belirlerseniz, - firewall kurallarını buna göre daha rahat ayarlayabilirsiniz (Port numarası sabit olduğundan, - firewall kurallarını bir defa tanımlamanız yeterli olabilecektir). -
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_zh_TW.html b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_zh_TW.html deleted file mode 100644 index 6f7678ed46f8ff674f5d8bdb50e0c658a28a8a65..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/help-slaveAgentPort_zh_TW.html +++ /dev/null @@ -1,6 +0,0 @@ -
    - Jenkins 使用 TCP 連接埠與透過 JNLP 啟動的 Slave 代理程式溝通。 - 為了避免衝突,連接埠一般是隨機挑選的,但可能造成系統資安的困擾。 - 如果您沒有任何 JNLP Slave,建議關閉這個 TCP 連接埠。 - 或是,您可以指定固定的連接埠數值,方便您調整防火牆設定。 -
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy index 249d4cfbe84e08544c84abeea444951b3448051d..f082a3fce5e3d94e9d565f37752ed6e7faf681f6 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.groovy @@ -3,6 +3,7 @@ package hudson.security.GlobalSecurityConfiguration import hudson.security.SecurityRealm import hudson.markup.MarkupFormatterDescriptor import hudson.security.AuthorizationStrategy +import jenkins.AgentProtocol import jenkins.model.GlobalConfiguration import hudson.Functions import hudson.model.Descriptor @@ -11,7 +12,7 @@ def f=namespace(lib.FormTagLib) def l=namespace(lib.LayoutTagLib) def st=namespace("jelly:stapler") -l.layout(norefresh:true, permission:app.ADMINISTER, title:my.displayName) { +l.layout(norefresh:true, permission:app.ADMINISTER, title:my.displayName, cssclass:request.getParameter('decorate')) { l.main_panel { h1 { l.icon(class: 'icon-secure icon-xlg') @@ -25,8 +26,42 @@ l.layout(norefresh:true, permission:app.ADMINISTER, title:my.displayName) { set("descriptor", my.descriptor); f.optionalBlock( field:"useSecurity", title:_("Enable security"), checked:app.useSecurity) { - f.entry (title:_("TCP port for JNLP slave agents"), field:"slaveAgentPort") { - f.serverTcpPort() + f.entry(title: _("TCP port for JNLP agents"), field: "slaveAgentPort") { + if (my.slaveAgentPortEnforced) { + if (my.slaveAgentPort == -1) { + text(_("slaveAgentPortEnforcedDisabled")) + } else if (my.slaveAgentPort == 0) { + text(_("slaveAgentPortEnforcedRandom")) + } else { + text(_("slaveAgentPortEnforced", my.slaveAgentPort)) + } + } else { + f.serverTcpPort() + } + } + f.advanced(title: _("Agent protocols"), align:"left") { + f.entry(title: _("Agent protocols")) { + def agentProtocols = my.agentProtocols; + table(width:"100%") { + for (AgentProtocol p : AgentProtocol.all()) { + if (p.name != null && !p.required) { + f.block() { + f.checkbox(name: "agentProtocol", + title: p.displayName, + checked: agentProtocols.contains(p.name), + json: p.name); + } + tr() { + td(colspan:"2"); + td(class:"setting-description"){ + st.include(from:p, page: "description", optional:true); + } + td(); + } + } + } + } + } } f.entry (title:_("Disable remember me"), field: "disableRememberMe") { diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.properties new file mode 100644 index 0000000000000000000000000000000000000000..4c959311a8f28ad3ea271a517aa8eefdd2b5d896 --- /dev/null +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index.properties @@ -0,0 +1,3 @@ +slaveAgentPortEnforced=enforced to {0,number,#} on startup through system property. +slaveAgentPortEnforcedRandom=enforced to random port on startup through system property. +slaveAgentPortEnforcedDisabled=disabled on startup through system property. diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_da.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_da.properties index 0e53ad060ca03e4103b3890b01451443715b8747..02bb05699528c596634bed1f380d8b78d53d3e0e 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_da.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_da.properties @@ -22,7 +22,6 @@ LOADING=INDL\u00C6SER Enable\ security=Sl\u00E5 sikkerhed til -TCP\ port\ for\ JNLP\ slave\ agents=TCP port til JNLP slaveagenter Markup\ Formatter= Access\ Control=Adgangskontrol Security\ Realm=Sikkerheds Realm diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_de.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_de.properties index ed694c8119c556067d012bdd6b92fd527fe7c851..a9010fb71201f4cbbe4a226c28ece6b9c7b8f59b 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_de.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_de.properties @@ -22,7 +22,6 @@ LOADING=LADE DATEN Enable\ security=Jenkins absichern -TCP\ port\ for\ JNLP\ slave\ agents=TCP-Port f\u00fcr JNLP-Slave Disable\ remember\ me=Deaktiviere "Anmeldedaten speichern" Markup\ Formatter=Markup-Formatierer Access\ Control=Zugriffskontrolle diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_es.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_es.properties index 60f4150e2e6c55892e1801a0440099c49fb97e7d..87d48443d5a2e4f1be760a5a3142f7c5180769d5 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_es.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_es.properties @@ -22,9 +22,9 @@ LOADING=CARGANDO Enable\ security=Activar seguridad -TCP\ port\ for\ JNLP\ slave\ agents=Puerto TCP de JNLP para los agentes en los nodos secundarios +TCP\ port\ for\ JNLP\ agents=Puerto TCP de JNLP para los agentes en los nodos secundarios Markup\ Formatter= Access\ Control=Control de acceso -Security\ Realm=Seguuridad +Security\ Realm=Seguridad Authorization=Autorizaci\u00F3n Save=Guardar diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fi.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fi.properties index f0de13e17dd955f2dd7841e42d7060f1cbebf861..5757a35336fa1ffb182ae0d8b521783697af4505 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fi.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fi.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Enable\ security=Aktivoi kirjautuminen -TCP\ port\ for\ JNLP\ slave\ agents= Markup\ Formatter= Access\ Control=P\u00E4\u00E4synhallinta Security\ Realm= diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fr.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fr.properties index 3a8cc73e953e258597a1cede3764681e736f4ab9..d70ab48cd399f3f207d3852bfecebdd7825c7e22 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fr.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_fr.properties @@ -22,7 +22,6 @@ LOADING=CHARGEMENT Enable\ security=Activer la s\u00E9curit\u00E9 -TCP\ port\ for\ JNLP\ slave\ agents=Port TCP pour les agents esclaves JNLP Markup\ Formatter= Access\ Control=Contr\u00F4le de l''acc\u00E8s Security\ Realm=Royaume pour la s\u00E9curit\u00E9 (Realm) diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_hu.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_hu.properties index 4f86f54d340b6005bf35351f068d57019514941f..2e3b82f0545a5d23f7ea31047bb8320ae5ca6d65 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_hu.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_hu.properties @@ -22,7 +22,6 @@ LOADING=BET\u00D6LT\u00C9S Enable\ security= -TCP\ port\ for\ JNLP\ slave\ agents= Markup\ Formatter= Access\ Control= Security\ Realm= diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ja.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ja.properties index 6eeaeab03992c931d865bcaee24b388609972c2b..73d37c2c966dfe15892e861d37ce93bf3fb95741 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ja.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ja.properties @@ -22,7 +22,6 @@ LOADING=\u30ed\u30fc\u30c9\u4e2d... Enable\ security=\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u3092\u6709\u52b9\u5316 -TCP\ port\ for\ JNLP\ slave\ agents=JNLP\u30b9\u30ec\u30fc\u30d6\u7528TCP\u30dd\u30fc\u30c8\u756a\u53f7 Markup\ Formatter=\u30de\u30fc\u30af\u30a2\u30c3\u30d7\u8a18\u6cd5 Access\ Control=\u30a2\u30af\u30bb\u30b9\u5236\u5fa1 Security\ Realm=\u30e6\u30fc\u30b6\u30fc\u60c5\u5831 diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_nl.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_nl.properties index 0f6020cc66fa29c868b89c3fd406c18927e3109a..38a67ec667c9d6bc1d4614619da07e84f8b3689f 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_nl.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_nl.properties @@ -22,7 +22,6 @@ LOADING=OPHALEN Enable\ security=Activeer beveiliging -TCP\ port\ for\ JNLP\ slave\ agents=TCP-poort voor JNLP-slaafnodes Markup\ Formatter= Access\ Control=Toegangscontrole Security\ Realm=Beveiligingszone diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_pt_BR.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_pt_BR.properties index 2a28726538637122933d0c6b1e38e41b6753a844..b920631d0b89fddf7febea09990a1967b6958edd 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_pt_BR.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_pt_BR.properties @@ -22,7 +22,6 @@ LOADING=Carregando Enable\ security=Habilitar segurana -TCP\ port\ for\ JNLP\ slave\ agents=Porta TCP para agentes slave JNLP Markup\ Formatter=Formatador de markup Access\ Control=Controle de acesso Security\ Realm=Dom\u00ednio (realm) de seguran\u00e7a diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ru.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ru.properties index 49891a4e3086f44408d6c634d9be54f724fe086a..156daf036bb58de7906548a57592bcd487403a39 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ru.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_ru.properties @@ -22,7 +22,6 @@ LOADING=\u0417\u0410\u0413\u0420\u0423\u0417\u041A\u0410 Enable\ security=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0437\u0430\u0449\u0438\u0442\u0443 -TCP\ port\ for\ JNLP\ slave\ agents=TCP \u043f\u043e\u0440\u0442 \u0434\u043b\u044f JNLP \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0445 \u0430\u0433\u0435\u043d\u0442\u043e\u0432 Markup\ Formatter= Access\ Control=\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u0430 Security\ Realm=\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u0437\u0430\u0449\u0438\u0442\u044b (realm) diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_sr.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..abb41de481cbc87bc18d3bbbb483fe6ec2004009 --- /dev/null +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_sr.properties @@ -0,0 +1,11 @@ +# This file is under the MIT License by authors + +LOADING=\u0423\u0427\u0418\u0422\u0410\u0412\u0410\u040A\u0415 +Enable\ security=\u0423\u043A\u0459\u0443\u0447\u0438 \u0441\u0438\u0441\u0442\u0435\u043C \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442\u0438 +Markup\ Formatter=\u0424\u043E\u0440\u043C\u0430\u0442\u0435\u0440 \u0437\u0430 Markup +Access\ Control=\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0435 +Security\ Realm=\u041E\u0431\u043B\u0430\u0441\u0442 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442\u0438 (Realm) +Authorization=\u041E\u0432\u043B\u0430\u0448\u045B\u0435\u045A\u0435 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +Disable\ remember\ me=\u0418\u0441\u043A\u0459\u0443\u0447\u0438 \u043E\u0434\u043B\u0438\u043A\u0443 "\u0437\u0430\u043F\u0430\u043C\u0442\u0438 \u043C\u0435" +TCP\ port\ for\ JNLP\ agents=\u041F\u043E\u0440\u0442 TCP \u0437\u0430 JNLP \u0430\u0433\u0435\u043D\u0442\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_tr.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_tr.properties index 383c978db64ab1e1cfb2dfca5d0e82d80333dd08..1ef7e7eb538c5d9cf0b3f5de93adb416eb08f33e 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_tr.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_tr.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. Enable\ security=G\u00fcvenli\u011fi devreye al -TCP\ port\ for\ JNLP\ slave\ agents=JNLP Slave ajanlar\u0131 i\u00e7in TCP portu Markup\ Formatter= Access\ Control=Eri\u015fim Kontrol\u00fc Security\ Realm=G\u00fcvenlik Alan\u0131 diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_CN.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_CN.properties index dda1fcfe45dc63a3f5c8abfd57da331a46649001..a4a5ce68ddbca2eda3172c3fd4ac26bc9f6a7e1c 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_CN.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_CN.properties @@ -22,7 +22,6 @@ LOADING=\u52A0\u8F7D\u4E2D Enable\ security=\u542f\u7528\u5b89\u5168 -TCP\ port\ for\ JNLP\ slave\ agents=JNLP\u8282\u70b9\u4ee3\u7406\u7684TCP\u7aef\u53e3 Markup\ Formatter= Access\ Control=\u8bbf\u95ee\u63a7\u5236 Security\ Realm=\u5b89\u5168\u57df diff --git a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_TW.properties b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_TW.properties index 7966bc9a90826b03e885b7e9fde80080cb5419ee..103ce2ab039014cf80d5f2c0b30a8fe1c9ec670b 100644 --- a/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_TW.properties +++ b/core/src/main/resources/hudson/security/GlobalSecurityConfiguration/index_zh_TW.properties @@ -23,7 +23,6 @@ LOADING=\u8f09\u5165\u4e2d Enable\ security=\u555f\u7528\u5b89\u5168\u6027 -TCP\ port\ for\ JNLP\ slave\ agents=JNLP Slave \u4ee3\u7406\u7a0b\u5f0f TCP \u57e0 Markup\ Formatter=\u6a19\u8a18\u683c\u5f0f\u5668 Access\ Control=\u5b58\u53d6\u63a7\u5236 Security\ Realm=\u5b89\u5168\u6027\u9818\u57df diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config.jelly index f97a4c9e9e93d8436b41928cf71b9e5e32dc5330..02c43b5764d0e23be852023a21afa7c08d3d4402 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config.jelly @@ -24,12 +24,10 @@ THE SOFTWARE. - - - \ No newline at end of file + diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..2f216c9c4b3dec1d20b66e005393c15b362c27a6 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Password=\ + \u041f\u0430\u0440\u043e\u043b\u0430 +Confirm\ Password=\ + \u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..681f4b037d9f5f8a7907123624689c7b13d15e97 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/Details/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Password=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 +Confirm\ Password=\u041F\u043E\u0442\u0432\u0440\u0434\u0438\u0442\u0435 \u043B\u043E\u0437\u0438\u043D\u043A\u0443 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly index bb12a30aa9afbe82834f61d0ee0560be40b64c6a..a4e2f822f2e7807c37bc351832968ece7be4f329 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm.jelly @@ -22,67 +22,48 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - + - - - - - - - - -

    ${title}

    -
    - -
    - ${data.errorMessage} -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ${%Username}:
    ${%Password}:
    ${%Confirm password}:
    ${%Full name}:
    ${%E-mail address}:
    ${%Enter text as shown}: -
    - [captcha] -
    - - - +

    ${title}

    +
    + +
    + ${data.errorMessage}
    - - +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ${%Username}:
    ${%Password}:
    ${%Confirm password}:
    ${%Full name}:
    ${%E-mail address}:
    ${%Enter text as shown}: +
    + [captcha] +
    +
    diff --git a/core/src/main/resources/hudson/model/Executor/causeOfDeath.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage.jelly similarity index 56% rename from core/src/main/resources/hudson/model/Executor/causeOfDeath.jelly rename to core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage.jelly index 55559f68e81b912a2d9ede5bfb5d0171ab07967a..8009ad6518ed8c94505bbb7bdc8f7e23aef4172b 100644 --- a/core/src/main/resources/hudson/model/Executor/causeOfDeath.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryFormPage.jelly @@ -1,7 +1,7 @@ + - - - - - - - - + + + + + + + + - - -

    - - ${%Thread is still alive} -

    -
    - -

    - - ${%Thread has died} -

    -
    ${h.printThrowable(it.causeOfDeath)}
    -
    -            ${%more info}
    -          
    -
    - - -
    -
    +
    + + + +
    diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..c4cd36253cfb0cf4982a647eaa30aa2eee0f521c --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_bg.properties @@ -0,0 +1,36 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +E-mail\ address=\ + \u0410\u0434\u0440\u0435\u0441 \u043d\u0430 \u0435-\u043f\u043e\u0449\u0430 +Password=\ + \u041f\u0430\u0440\u043e\u043b\u0430 +Username=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b +Confirm\ password=\ + \u041f\u043e\u0442\u0432\u044a\u0440\u0436\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 +Enter\ text\ as\ shown=\ + \u0412\u044a\u0432\u0435\u0434\u0435\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442 +Sign\ up=\ + \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0435 +Full\ name=\ + \u041f\u044a\u043b\u043d\u043e \u0438\u043c\u0435 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pl.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pl.properties index 232cf06c4bbf0baa4b121a252cb27b51e0fbcf3c..789580f522d7ac99df05080a14da4fa42b200a07 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pl.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_pl.properties @@ -1,6 +1,7 @@ # This file is under the MIT License by authors -Confirm\ password=Has\u0142o +Sign\ up=Zarejestruj si\u0119 +Confirm\ password=Powt\u00F3rz has\u0142o E-mail\ address=Adres e-mail Full\ name=Pe\u0142na nazwa Password=Has\u0142o diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..661b93a0e3135cf90b95a2b6893631ef16e289ce --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/_entryForm_sr.properties @@ -0,0 +1,9 @@ +# This file is under the MIT License by authors + +Username=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 +Password=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 +Confirm\ password=\u041F\u043E\u0442\u0432\u0440\u0434\u0438\u0442\u0435 \u043B\u043E\u0437\u0438\u043D\u043A\u0443 +Full\ name=\u0418\u043C\u0435 \u0438 \u043F\u0440\u0435\u0437\u0438\u043C\u0435 +Enter\ text\ as\ shown=\u0423\u043D\u0435\u0441\u0438\u0442\u0435 \u0442\u0435\u043A\u0441\u0442 \u043A\u0430\u043A\u043E \u0458\u0435 \u043F\u0440\u0438\u043A\u0430\u0437\u0430\u043D +E-mail\ address=\u0410\u0434\u0440\u0435\u0441\u0430 \u0435-\u043F\u043E\u0448\u0442\u0435 +Sign\ up=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser.jelly index aed3d5c5c89b8e30db8a050ad3b2ed2bf2821aae..daacc17bfc479390f379266536a1f3bbc3f79344 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser.jelly @@ -27,5 +27,5 @@ THE SOFTWARE. --> - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..46d7918e2d079bea09c03434b98b563c37fa6ee3 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Create\ User=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a1eb18f901895a5af60e94979cda052ca8c8a24d --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/addUser_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Create\ User=\u041A\u0440\u0435\u0438\u0440\u0430\u0458 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_bg.properties index ffc13666309aa7e5a60642a081eb0c35849b0cc8..e4fb7946c9ebb369927e5ee73cd0d05f4d545ddc 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_bg.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_bg.properties @@ -1,3 +1,28 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Allow\ users\ to\ sign\ up=\u041F\u043E\u0437\u0432\u043E\u043B\u0438 \u0432\u0445\u043E\u0434 \u043D\u0430 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 +Allow\ users\ to\ sign\ up=\ + \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\u0442\u0435 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u0442 +Captcha\ Support=\ + \u041f\u043e\u0434\u0434\u0440\u044a\u0436\u043a\u0430 \u043d\u0430 \u201eCaptcha\u201c +Enable\ captcha\ on\ sign\ up=\ + \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u201eCaptcha\u201c \u043f\u0440\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7da135998fcefbd98cadf4c946d520af22f88db3 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Enable\ captcha\ on\ sign\ up=\u0422\u0440\u0430\u0436\u0438 Captcha \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0435 +Captcha\ Support=\u041F\u043E\u0434\u0440\u0448\u043A\u0430 \u0437\u0430 Captcha +Allow\ users\ to\ sign\ up=\u0414\u043E\u0437\u0432\u043E\u043B\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 \u0434\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443\u0458\u0443 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser.jelly index bc44b42accee8be4b4b2b19ed6646f5735b1376c..6ebd369ae0a1f0d7c10eaf619b13c221343d716d 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser.jelly @@ -27,5 +27,5 @@ THE SOFTWARE. --> - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..6fe330a0341e8dd356c414c272d64175f6259114 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Create\ First\ Admin\ User=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u044a\u0440\u0432\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b-\u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ac2c4ccf6ad349e419f1f0b7f548bf78aba8cbce --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/firstUser_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Create\ First\ Admin\ User=\u041A\u0440\u0435\u0438\u0440\u0430\u0458 \u043F\u0440\u0432\u043E\u0433 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help-allowsSignup_bg.html b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help-allowsSignup_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..daa6a4ffd632b2e7bcfed6cba35997ef61ce0d7a --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help-allowsSignup_bg.html @@ -0,0 +1,14 @@ +
    + Стандартно Jenkins позволява на потребителите да си създават регистрации чрез + връзката за това в горния, десен ъгъл. + Ако не искате произволни хора да се регистрират, оставете полето правно. +

    + В такъв случай някой с административни права ще трябва да създава + регистрациите. +

    + Стандартно Jenkins не използва графична защита, че човек, а не скрипт създава + регистрацията. Ако такава функционалност ви трябва, инсталирайте съответната + приставка, напр. + JCaptcha + Plugin. +

    diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_bg.html b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..924283f48fc9699292ea91ecf4005af847bf0b11 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_bg.html @@ -0,0 +1,6 @@ +
    + Използвайте списъка на потребители на Jenkins за + идентификация, вместо това да го прави външна система. Този вариант е подходящ + за по-малки инсталации, при които няма вече съществуваща база от данни с + потребители. +
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_zh_CN.html b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_zh_CN.html index 5967d98f9ade94f91e07594c700d9f92a7d0c676..754a47f59cc02a5f667d8222f32b9f83c35a0f98 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_zh_CN.html +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/help_zh_CN.html @@ -1,5 +1,5 @@ -
    - 使用Hudson自己的用户列表验证, - 而不是外部系统代理. - 这适用于没有用户数据库小范围的设定. +
    + 使用Hudson自己的用户列表验证, + 而不是外部系统代理. + 这适用于没有用户数据库小范围的设定.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly index d39afff6f9f97144928e2a2a1d9bee0c04b47c9f..9b7fe9d0fae2be471385ab3aecdaddf90f254aa0 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly @@ -43,7 +43,7 @@ THE SOFTWARE. ${user.id} ${user} - + diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_bg.properties index f86036026a3b36c14ef98ea7dc5caf614b7eed94..8542ec0a26cabd25a0c30ab309491ecb82e6c37c 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_bg.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_bg.properties @@ -1,5 +1,33 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Name=\u0418\u043C\u0435 -Users=\u041F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 -blurb=\u0422\u0435\u0437\u0438 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438 \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0432\u043B\u0438\u0437\u0430\u0442 \u0432 Jenkins. \u0422\u043E\u0432\u0430 \u0435 \u0441\u044A\u043A\u0440\u0430\u0442\u0435\u043D\u0430 \u0432\u0435\u0440\u0441\u0438\u044F \u043D\u0430 \u043D\u0430 \u0442\u043E\u0437\u0438 \u0441\u043F\u0438\u0441\u044A\u043A, \u043A\u043E\u0439\u0442\u043E \u0441\u044A\u0434\u044A\u0440\u0436\u0430 \u0441\u044A\u0449\u043E \u0438 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043D\u043E \u0441\u044A\u0437\u0434\u0430\u0434\u0435\u043D\u0438\u0442\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B\u0438, \u043A\u043E\u0438\u0442\u043E \u043D\u0430 \u043F\u0440\u0430\u043A\u0442\u0438\u043A\u0430 \u0441\u0430\u043C\u043E \u0441\u0430 \u043A\u043E\u043C\u0438\u0442\u043D\u0430\u043B\u0438 \u043D\u044F\u043A\u043E\u043B\u043A\u043E \u043F\u044A\u0442\u0438 \u043F\u043E \u043D\u044F\u043A\u043E\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0438 \u0438 \u043D\u044F\u043C\u0430\u0442 \u0434\u0438\u0440\u0435\u043A\u0442\u0435\u043D \u0434\u043E\u0441\u0442\u044A\u043F \u0434\u043E Jenkins. +Name=\ + \u0418\u043c\u0435 +Users=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 +blurb=\ + \u0422\u0435\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u0430\u0442 \u0434\u0430 \u0441\u0435 \u0432\u043f\u0438\u0448\u0430\u0442 \u0432 Jenkins. \u0422\u043e\u0432\u0430 \u0435 \u0441\u044a\u043a\u0440\u0430\u0442\u0435\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430\ + \u0442\u043e\u0437\u0438 \u0441\u043f\u0438\u0441\u044a\u043a, \u043a\u043e\u0439\u0442\u043e \u0441\u044a\u0434\u044a\u0440\u0436\u0430 \u0441\u044a\u0449\u043e \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\ + \u0441\u044a\u0437\u0434\u0430\u0434\u0435\u043d\u0438\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u043a\u043e\u0438\u0442\u043e \u043d\u044f\u043a\u043e\u0433\u0430 \u0441\u0430 \u043f\u043e\u0434\u0430\u0432\u0430\u043b\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u043f\u043e \u043d\u044f\u043a\u043e\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438 \u0438\ + \u043d\u044f\u043c\u0430\u0442 \u0434\u0438\u0440\u0435\u043a\u0442\u0435\u043d \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e Jenkins. +User\ Id=\ + \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ee02493ef6d4d9fe61e94fa4b4c77bf2380cd322 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Users=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 +blurb=\ +\u041E\u0432\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0432\u0438 \u043C\u043E\u0433\u0443 \u0441\u0435 \u043F\u0440\u0438\u0458\u0430\u0432\u0438\u0442\u0438 \u043D\u0430 Jenkins, \u0448\u0442\u043E \u0458\u0435 \u043F\u043E\u0434\u0441\u043A\u0443\u043F \u043E\u0432\u043E\u0433 \u0441\u043F\u0438\u0441\u043A\u0430, \ +\u043A\u043E\u0458\u0438 \u0441\u0430\u0434\u0440\u0436\u0438 \u0438 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438-\u043A\u0440\u0435\u0438\u0440\u0430\u043D\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0435 \u0431\u0435\u0437 \u043A\u0438\u0440\u0435\u043A\u043D\u043E\u0433 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0430 \u043D\u0430 Jenkins. +User\ Id=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u043E\u043D\u0438 \u0431\u0440\u043E\u0458 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 +Name=\u0418\u043C\u0435 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_bg.properties index 8eac1a5473c9208fe69ee5c565108e0c6f358e7a..78ad3489c1dfc8b6b40058b2e9b7ac196af9e3b9 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_bg.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -sign\ up=\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F +sign\ up=\ + \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_pl.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_pl.properties index 2256c9f917a5dfe3ade00d0d109e93cd626d862d..72d26aa862bacc2b623fb1eec0dda4fe80a143f2 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_pl.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -sign\ up=za\u0142\u00F3\u017C konto +sign\ up=Za\u0142\u00F3\u017C konto diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_sr.properties index 35c26ea458054a9e4dfe2d747c766c9284502766..a98e2bb9c38d5b2ae07fd8e58354defa7b662af3 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_sr.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/loginLink_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -sign\ up=\u043D\u0430\u043F\u0440\u0430\u0432\u0438 \u043D\u0430\u043B\u043E\u0433 +sign\ up=\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly index 49ef418e78c589de9071d272fe0aabfba0d32121..8d864d01e9d039652025073070074cfdbd2c4546 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel.jelly @@ -28,7 +28,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_bg.properties index c70e0de0f2ac856ee49caacf59fe182dc5e283ad..0c64b93b0eb4aa87a7ee8906efb3f9f2b36a8c91 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_bg.properties +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_bg.properties @@ -1,5 +1,28 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Back\ to\ Dashboard=\u041E\u0431\u0440\u0430\u0442\u043D\u043E \u043A\u044A\u043C \u0442\u0430\u0431\u043B\u043E\u0442\u043E -Create\ User=\u0421\u044A\u0437\u0434\u0430\u0439 \u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043B -Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0430 Jenkins +Back\ to\ Dashboard=\ + \u041a\u044a\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f \u0435\u043a\u0440\u0430\u043d +Create\ User=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b +Manage\ Jenkins=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 Jenkins diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..13d517fbbc5202f3d4e4a562355414341fb7a37b --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/sidepanel_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C +Create\ User=\u041A\u0440\u0435\u0438\u0440\u0430\u0458 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430 +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup.jelly index 656e96c3c9eff6ac8391064b0442ef18dfec2200..f2477da1df27b8d967884626afd7833e2bf731ce 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup.jelly @@ -27,5 +27,5 @@ THE SOFTWARE. --> - + diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly index 01c0197a6201335932e0ffb50df2934937c44242..8daec8d38125220336aadd180767915648741af5 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity.jelly @@ -27,5 +27,5 @@ THE SOFTWARE. --> - + \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..00b146e5d08bae3238240499bedfad516054b576 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Sign\ up=\ + \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1315accaf12589e0d1c0c3898e550040396dff4 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signupWithFederatedIdentity_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Sign\ up=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..00b146e5d08bae3238240499bedfad516054b576 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Sign\ up=\ + \u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1315accaf12589e0d1c0c3898e550040396dff4 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/signup_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Sign\ up=\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success_bg.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..41525cba68adb2ccfa37ca8b6fc2c8c29ea1b746 --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Success=\ + \u0423\u0441\u043f\u0435\u0445 +description=\ + \u0412\u043f\u0438\u0441\u0430\u043d\u0438 \u0441\u0442\u0435. \u041a\u044a\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430. diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success_sr.properties b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e27a6feb9293ea45ec807da6fd3cd9dacd3a043e --- /dev/null +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/success_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Success=\u0423\u0441\u043F\u0435\u0448\u043D\u043E +description=\u041F\u0440\u0438\u0458\u0430\u0432\u0459\u0435\u043D\u0438 \u0441\u0442\u0435. \u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u0433\u043B\u0430\u0432\u043D\u043E\u0458 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438. diff --git a/core/src/main/resources/hudson/security/LegacyAuthorizationStrategy/help_zh_CN.html b/core/src/main/resources/hudson/security/LegacyAuthorizationStrategy/help_zh_CN.html index 368bdbd2f1bd324293d74f2b494cad4a1f33d372..6b6133460e875a080c80092342560e910efae4d4 100644 --- a/core/src/main/resources/hudson/security/LegacyAuthorizationStrategy/help_zh_CN.html +++ b/core/src/main/resources/hudson/security/LegacyAuthorizationStrategy/help_zh_CN.html @@ -1,4 +1,4 @@ -
    - 适用于Jenkins1.164以前的版本.也就是说,如果你是"admin"角色,那么你将拥有Jenkins的一切控制权,其它角色(包括匿名用户) - 只有查看权限. +
    + 适用于Jenkins1.164以前的版本.也就是说,如果你是"admin"角色,那么你将拥有Jenkins的一切控制权,其它角色(包括匿名用户) + 只有查看权限.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/LegacySecurityRealm/config_bg.properties b/core/src/main/resources/hudson/security/LegacySecurityRealm/config_bg.properties index a37824abc66ac8eb9afa5fff7307e117a450471e..6bc00b09971b2966eb109c570cfcb994a850fcc2 100644 --- a/core/src/main/resources/hudson/security/LegacySecurityRealm/config_bg.properties +++ b/core/src/main/resources/hudson/security/LegacySecurityRealm/config_bg.properties @@ -1,3 +1,30 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Unprotected\ URLs=\u043D\u0435\u0437\u0430\u0449\u0438\u0442\u0435\u043D URL +Unprotected\ URLs=\ + \u041d\u0435\u0437\u0430\u0449\u0438\u0442\u0435\u043d \u0430\u0434\u0440\u0435\u0441 +# These URLs (and URLs starting with these prefixes plus a /) should require no authentication. \ +# If possible, configure your container to pass these requests straight to Jenkins without requiring login. +blurb=\ + \u0422\u0435\u0437\u0438 \u0430\u0434\u0440\u0435\u0441\u0438, \u043a\u0430\u043a\u0442\u043e \u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0438\u0442\u0435 \u0441 \u0434\u043e\u0431\u0430\u0432\u0435\u043d\u0430 \u043d\u0430\u043a\u043b\u043e\u043d\u0435\u043d\u0430 \u0447\u0435\u0440\u0442\u0430 \u201e/\u201c \u0432 \u043a\u0440\u0430\u044f, \u043d\u0435\ + \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u043d\u0443\u0436\u0434\u0430\u044f\u0442 \u043e\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f. \u0410\u043a\u043e \u0435 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0437\u0430\ + \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438 \u0434\u0430 \u043f\u0440\u0435\u0434\u0430\u0432\u0430 \u0442\u0435\u0437\u0438 \u0437\u0430\u044f\u0432\u043a\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043d\u043e \u043d\u0430 Jenkins, \u0431\u0435\u0437 \u0434\u0430 \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0432\u043f\u0438\u0441\u0432\u0430\u043d\u0435. diff --git a/core/src/main/resources/hudson/security/LegacySecurityRealm/config_pl.properties b/core/src/main/resources/hudson/security/LegacySecurityRealm/config_pl.properties index 559f8a43bc4dcacfe97454f5997f4c5413d03684..a940c52cf5a153728936ac6c974c8a2403b75376 100644 --- a/core/src/main/resources/hudson/security/LegacySecurityRealm/config_pl.properties +++ b/core/src/main/resources/hudson/security/LegacySecurityRealm/config_pl.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors Unprotected\ URLs=Niezabezpieczone URL -blurb=Te URL''e (i URL''e rozpoczynaj\u0105ce si\u0119 od prefiksu i /) nie powinny wymaga\u0107 autoryzacji. Je\u015Bli to mo\u017Cliwe, skonfiguruj kontener aby przes\u0142a\u0107 te \u017C\u0105dania bezpo\u015Brednio do Jenkins''a bez logowania. +blurb=Te URL''e (i URL''e rozpoczynaj\u0105ce si\u0119 od prefiksu i /) nie powinny wymaga\u0107 autoryzacji. Je\u015Bli to mo\u017Cliwe, skonfiguruj kontener aby przes\u0142a\u0107 te \u017C\u0105dania bezpo\u015Brednio do Jenkinsa bez logowania. diff --git a/core/src/main/resources/hudson/security/LegacySecurityRealm/config_sr.properties b/core/src/main/resources/hudson/security/LegacySecurityRealm/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d76a9217726af8f1e21cf2dc5a2a2488c4324722 --- /dev/null +++ b/core/src/main/resources/hudson/security/LegacySecurityRealm/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Unprotected\ URLs=\u041D\u0435\u0437\u0430\u0448\u0442\u0438\u045B\u0435\u043D\u0435 URL \u0430\u0434\u0440\u0435\u0441\u0435 +blurb=\u041E\u0432\u043E\u0458 \u0430\u0434\u0440\u0435\u0441\u0438, \u043A\u0430\u043E \u0438 \u043E\u0441\u0442\u0430\u043B\u0438\u043C \u0441\u0430 \u0434\u043E\u0434\u0430\u0442\u043D\u043E\u0458 \u0446\u0440\u0442\u0438 "/" \u043D\u0430 \u043A\u0440\u0430\u0458\u0443, \u043D\u0438\u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0430. \u0410\u043A\u043E \u0458\u0435 \u0442\u043E \u043C\u043E\u0433\u0443\u045B\u0435, \u043D\u0430\u043C\u0435\u0441\u0442\u0438 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440 \u0434\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043D\u043E \u043F\u0440\u0435\u043D\u043E\u0441\u0438 \u0437\u0430\u0445\u0442\u0435\u0432\u0435 \u043D\u0430 Jenkins \u0431\u0435\u0437 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0435. diff --git a/core/src/main/resources/hudson/security/LegacySecurityRealm/help_bg.html b/core/src/main/resources/hudson/security/LegacySecurityRealm/help_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..f715198cea96773fe2aee54be83f53e2cf13e2c7 --- /dev/null +++ b/core/src/main/resources/hudson/security/LegacySecurityRealm/help_bg.html @@ -0,0 +1,16 @@ +
    + Използване на контейнера за сървлети за идентификация на потребителите по спецификация. + Това е, което Jenkins правеше до версия 1.163, включително. Полезно е в следните случаи: + +
      +
    1. + Използвали сте Jenkins преди версия 1.164 и искате да запазите поведението. +
    2. +
    3. + Вече сте настроили контейнера да ползва правилната област за сигурност и + искате Jenkins просто да я ползва. (Понякога контейнерите имат по-добра + документация или ползват специфичен начин или реализация на връзка с област + потребители.) +
    4. +
    +
    diff --git a/core/src/main/resources/hudson/security/LegacySecurityRealm/help_zh_CN.html b/core/src/main/resources/hudson/security/LegacySecurityRealm/help_zh_CN.html index eac120de565a27bb6d9fc3df702dc130de4b566d..666444d94b5c80ba6ac6191da88ea7da1bd89ea3 100644 --- a/core/src/main/resources/hudson/security/LegacySecurityRealm/help_zh_CN.html +++ b/core/src/main/resources/hudson/security/LegacySecurityRealm/help_zh_CN.html @@ -1,13 +1,13 @@ -
    - 使用Servlet容器认证用户,遵循Servlet规范. - 这是Jenkins1.163版本遗留的历史.这主要对下列情况非常有用: - -
      -
    1. - 你使用1.164之前版本的Jenkins并且愿意继续使用. -
    2. -
    3. - 你已经在你的容器上配置了很好的安全域,并且宁愿Jenkins继续使用它.(有些容器提供更好的文档或者能够定制实现用户的安全域) -
    4. -
    +
    + 使用Servlet容器认证用户,遵循Servlet规范. + 这是Jenkins1.163版本遗留的历史.这主要对下列情况非常有用: + +
      +
    1. + 你使用1.164之前版本的Jenkins并且愿意继续使用. +
    2. +
    3. + 你已经在你的容器上配置了很好的安全域,并且宁愿Jenkins继续使用它.(有些容器提供更好的文档或者能够定制实现用户的安全域) +
    4. +
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/Messages_bg.properties b/core/src/main/resources/hudson/security/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..48f7068dc993719b323f49f5cf5aa67c96870b44 --- /dev/null +++ b/core/src/main/resources/hudson/security/Messages_bg.properties @@ -0,0 +1,104 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +GlobalSecurityConfiguration.DisplayName=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430 +GlobalSecurityConfiguration.Description=\ + \u041e\u0441\u0438\u0433\u0443\u0440\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430 \u043d\u0430 Jenkins \u2014 \u043a\u043e\u0439 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0433\u043e \u0434\u043e\u0441\u0442\u044a\u043f\u0432\u0430 \u0438 \u043f\u043e\u043b\u0437\u0432\u0430. + +HudsonPrivateSecurityRealm.WouldYouLikeToSignUp=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u0442 \u043d\u0430 \u201e{0} {1}\u201c \u0435 \u043d\u0435\u043f\u043e\u0437\u043d\u0430\u0442 \u0437\u0430 Jenkins. \u0418\u0441\u043a\u0430\u0442\u0435 \u043b\u0438 \u0434\u0430 \u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u0442\u0435? +LegacyAuthorizationStrategy.DisplayName=\ + \u041e\u0441\u0442\u0430\u0440\u044f\u043b \u0440\u0435\u0436\u0438\u043c + +HudsonPrivateSecurityRealm.DisplayName=\ + \u0411\u0430\u0437\u0430\u0442\u0430 \u043e\u0442 \u0434\u0430\u043d\u043d\u0438 \u0441 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u043d\u0430 Jenkins +HudsonPrivateSecurityRealm.Details.DisplayName=\ + \u041f\u0430\u0440\u043e\u043b\u0430 +HudsonPrivateSecurityRealm.Details.PasswordError=\ + \u0414\u0432\u0435\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u0438 \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430\u0442, \u0430 \u0442\u0440\u044f\u0431\u0432\u0430. \u0412\u044a\u0432\u0435\u0434\u0435\u0442\u0435 \u0433\u0438 \u043e\u0442\u043d\u043e\u0432\u043e. +HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\u0442\u0435 +HudsonPrivateSecurityRealm.ManageUserLinks.Description=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435/\u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435/\u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438\u0442\u0435 \u043d\u0430 Jenkins + +HudsonPrivateSecurityRealm.CreateAccount.TextNotMatchWordInImage=\ + \u0422\u0435\u043a\u0441\u0442\u044a\u0442 \u043d\u0435 \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u044f \u043d\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e\u0442\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 +HudsonPrivateSecurityRealm.CreateAccount.PasswordNotMatch=\ + \u041f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 +HudsonPrivateSecurityRealm.CreateAccount.PasswordRequired=\ + \u041f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u0430 +HudsonPrivateSecurityRealm.CreateAccount.UserNameRequired=\ + \u0418\u043c\u0435\u0442\u043e \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e +HudsonPrivateSecurityRealm.CreateAccount.InvalidEmailAddress=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0430\u0434\u0440\u0435\u0441 \u043d\u0430 \u0435-\u043f\u043e\u0449\u0430 +HudsonPrivateSecurityRealm.CreateAccount.UserNameAlreadyTaken=\ + \u0418\u043c\u0435\u0442\u043e \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u0435 \u0437\u0430\u0435\u0442\u043e + +FullControlOnceLoggedInAuthorizationStrategy.DisplayName=\ + \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0430\u043b\u0438\u0442\u0435 \u0441\u0435, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u043c\u043e\u0433\u0430\u0442 \u0432\u0441\u0438\u0447\u043a\u043e + +AuthorizationStrategy.DisplayName=\ + \u0412\u0441\u0435\u043a\u0438 \u043c\u043e\u0436\u0435 \u0432\u0441\u0438\u0447\u043a\u043e + +LDAPSecurityRealm.DisplayName=\ + LDAP +LDAPSecurityRealm.SyntaxOfServerField=\ + \u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u044a\u0442 \u043d\u0430 \u043f\u043e\u043b\u0435\u0442\u043e \u0437\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430 \u0435: \u0421\u042a\u0420\u0412\u042a\u0420 \u0438\u043b\u0438 \u0421\u042a\u0420\u0412\u042a\u0420:\u041f\u041e\u0420\u0422, \u0438\u043b\u0438\ + ldaps://\u0421\u042a\u0420\u0412\u042a\u0420[:\u041f\u041e\u0420\u0422] +LDAPSecurityRealm.UnknownHost=\ + \u041d\u0435\u043f\u043e\u0437\u043d\u0430\u0442 \u0445\u043e\u0441\u0442: {0} +LDAPSecurityRealm.UnableToConnect=\ + \u041d\u044f\u043c\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u0441 \u201e{0}\u201c : {1} +LDAPSecurityRealm.InvalidPortNumber=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u043d\u043e\u043c\u0435\u0440 \u043d\u0430 \u043f\u043e\u0440\u0442 + +LegacySecurityRealm.Displayname=\ + \u041e\u0441\u0442\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u0437\u0430 \u0441\u044a\u0440\u0432\u043b\u0435\u0442\u0438 \u0434\u0430 \u0441\u0435 \u0433\u0440\u0438\u0436\u0438 \u0437\u0430 \u0442\u043e\u0432\u0430 + +UserDetailsServiceProxy.UnableToQuery=\ + \u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043f\u043e\u043b\u0443\u0447\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f \u201e{0}\u201c + +PAMSecurityRealm.DisplayName=\ + \u0411\u0430\u0437\u0430\u0442\u0430 \u043e\u0442 \u0434\u0430\u043d\u043d\u0438 \u0441 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0438 \u0433\u0440\u0443\u043f\u0438 \u043d\u0430 Unix +PAMSecurityRealm.ReadPermission=\ + Jenkins \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0447\u0435\u0442\u0435 \u0444\u0430\u0439\u043b\u0430 \u201e/etc/shadow\u201c. +PAMSecurityRealm.BelongToGroup=\ + \u201e{0}\u201c \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0432 \u0433\u0440\u0443\u043f\u0430 \u201e{1}\u201c, \u0437\u0430 \u0434\u0430 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0447\u0435\u0442\u0435 \u0444\u0430\u0439\u043b\u0430 \u201e/etc/shadow\u201c. +PAMSecurityRealm.RunAsUserOrBelongToGroupAndChmod=\ + Jenkins \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d \u043a\u0430\u0442\u043e \u201e{0}\u201c \u0438\u043b\u0438 \u201e{1}\u201c \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0435 \u0432 \u0433\u0440\u0443\u043f\u0430 \u201e{2}\u201c \u0438\ + \u0442\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201echmod g+r /etc/shadow\u201c, \u0437\u0430 \u0434\u0430 \u0441\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438 \u043d\u0430\ + Jenkins \u0434\u0430 \u0447\u0435\u0442\u0435 \u0444\u0430\u0439\u043b\u0430 \u201e/etc/shadow\u201c. +PAMSecurityRealm.Success=\ + \u0423\u0441\u043f\u0435\u0445 +PAMSecurityRealm.User=\ + \u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b \u201e{0}\u201c +PAMSecurityRealm.CurrentUser=\ + \u0422\u0435\u043a\u0443\u0449\u0438\u044f\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b +PAMSecurityRealm.Uid=\ + \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b: {0} + +# not in use +Permission.Permissions.Title=\ + \u041b\u0438\u043f\u0441\u0432\u0430 +AccessDeniedException2.MissingPermission=\ + \u201e{0}\u201c \u043d\u044f\u043c\u0430 \u043f\u0440\u0430\u0432\u043e\u0442\u043e \u201e{1}\u201c diff --git a/core/src/main/resources/hudson/security/Messages_de.properties b/core/src/main/resources/hudson/security/Messages_de.properties index bbfb5b50c090ca673074e785b3b1fc073decfd0f..e55f61bbb0d661d59151d815209a8f66d4037449 100644 --- a/core/src/main/resources/hudson/security/Messages_de.properties +++ b/core/src/main/resources/hudson/security/Messages_de.properties @@ -55,10 +55,10 @@ UserDetailsServiceProxy.UnableToQuery=Benutzerinformationen konnten nicht abgefr PAMSecurityRealm.DisplayName=Unix Benutzer-/Gruppenverzeichnis PAMSecurityRealm.ReadPermission=Jenkins ben\u00f6tigt Leserechte f\u00fcr /etc/shadow -PAMSecurityRealm.BelongToGroup={0} mu\u00df zu Gruppe {1} geh\u00f6ren, um /etc/shadow lesen zu k\u00f6nnen. +PAMSecurityRealm.BelongToGroup={0} muss zu Gruppe {1} geh\u00f6ren, um /etc/shadow lesen zu k\u00f6nnen. PAMSecurityRealm.RunAsUserOrBelongToGroupAndChmod=\ - Entweder mu\u00df Jenkins als {0} ausgef\u00fchrt werden, oder {1} mu\u00df zu Gruppe {2} geh\u00f6ren und \ - ''chmod g+r /etc/shadow'' mu\u00df ausgef\u00fchrt werden, damit Jenkins /etc/shadow lesen kann. + Entweder muss Jenkins als {0} ausgef\u00fchrt werden, oder {1} muss zu Gruppe {2} geh\u00f6ren und \ + ''chmod g+r /etc/shadow'' muss ausgef\u00fchrt werden, damit Jenkins /etc/shadow lesen kann. PAMSecurityRealm.Success=Erfolgreich PAMSecurityRealm.User=Benutzer ''{0}'' PAMSecurityRealm.CurrentUser=Aktueller Benutzer diff --git a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ja.properties b/core/src/main/resources/hudson/security/Messages_pl.properties similarity index 80% rename from core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ja.properties rename to core/src/main/resources/hudson/security/Messages_pl.properties index c466a762ce0908e64e4b1c534eb37c4a22e8df13..347024e6a586fcc06fef985f97d165b6d19a3db1 100644 --- a/core/src/main/resources/hudson/model/ParametersDefinitionProperty/config_ja.properties +++ b/core/src/main/resources/hudson/security/Messages_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe +# Copyright (c) 2016, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -19,6 +19,5 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -This\ build\ is\ parameterized=\u30d3\u30eb\u30c9\u306e\u30d1\u30e9\u30e1\u30fc\u30bf\u5316 -Add\ Parameter=\u30d1\u30e9\u30e1\u30fc\u30bf\u306e\u8ffd\u52a0 \ No newline at end of file +GlobalSecurityConfiguration.DisplayName=Konfiguracja globalnych zabezpiecze\u0144 +GlobalSecurityConfiguration.Description=Bezpiecze\u0144stwo Jenkinsa: okre\u015Bl, kto ma dost\u0119p i mo\u017Ce u\u017Cywa\u0107 systemu. diff --git a/core/src/main/resources/hudson/security/Messages_pt_BR.properties b/core/src/main/resources/hudson/security/Messages_pt_BR.properties index ff131580258d526b327ae2186be6fe89cad26de4..25d77261323a2eafc76e0e3f18d88b263ac7386b 100644 --- a/core/src/main/resources/hudson/security/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/security/Messages_pt_BR.properties @@ -22,7 +22,7 @@ GlobalSecurityConfiguration.DisplayName=Configurar seguran\u00e7a global GlobalSecurityConfiguration.Description=Fa\u00e7a a seguran\u00e7a no Jenkins; defina quem pode usar/acessar o sistema. -HudsonPrivateSecurityRealm.WouldYouLikeToSignUp=This {0} {1} is new to Jenkins. Would you like to sign up? +HudsonPrivateSecurityRealm.WouldYouLikeToSignUp=O {0} {1} \u00e9 novo no Jenkins. Voc\u00ea deseja se cadastrar ? LegacyAuthorizationStrategy.DisplayName=Modo legado HudsonPrivateSecurityRealm.Details.DisplayName=Senha @@ -35,17 +35,17 @@ Permission.Permissions.Title=N/A # Success PAMSecurityRealm.Success=Sucesso # Unable to connect to {0} : {1} -LDAPSecurityRealm.UnableToConnect=No foi possvel conectar {0} : {1} +LDAPSecurityRealm.UnableToConnect=N\u00e3o foi poss\u00edvel conectar {0} : {1} # Logged-in users can do anything -FullControlOnceLoggedInAuthorizationStrategy.DisplayName=Usu\u00e1rios logados n\u00e3o conseguem fazer nada +FullControlOnceLoggedInAuthorizationStrategy.DisplayName=Usu\u00e1rios logados conseguem fazer qualquer coisa # Unix user/group database -PAMSecurityRealm.DisplayName=Usu\u00e1rio Unix / grupo banco da dados +PAMSecurityRealm.DisplayName=Usu\u00e1rio ou grupo do UNIX # User ''{0}'' PAMSecurityRealm.User=Usu\u00e1rio ''{0}'' # {0} needs to belong to group {1} to read /etc/shadow PAMSecurityRealm.BelongToGroup= {0} precisa pertencer ao grupo {1} para ler /etc/shadow # Anyone can do anything -AuthorizationStrategy.DisplayName=Ningu\u00e9m consegue fazer nada +AuthorizationStrategy.DisplayName=Qualquer um pode fazer qualquer coisa # Invalid port number LDAPSecurityRealm.InvalidPortNumber=N\u00famero de porta inv\u00e1lido # Unknown host: {0} @@ -62,7 +62,7 @@ AccessDeniedException2.MissingPermission= {0} est\u00e1 faltando a permiss\u00e3 # Manage Users HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=Gerenciar usu\u00e1rios # Delegate to servlet container -LegacySecurityRealm.Displayname=Delegar para o container servlet +LegacySecurityRealm.Displayname=Delegar para o servlet container # LDAP LDAPSecurityRealm.DisplayName=LDAP # Jenkins''s own user database diff --git a/core/src/main/resources/hudson/security/Messages_sr.properties b/core/src/main/resources/hudson/security/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0e944f27fb8cd18f9d84260b6ebb631c5e35eb02 --- /dev/null +++ b/core/src/main/resources/hudson/security/Messages_sr.properties @@ -0,0 +1,36 @@ +# This file is under the MIT License by authors + +GlobalSecurityConfiguration.DisplayName=\u0421\u0438\u0433\u0443\u0440\u043D\u043E\u0441\u043D\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +GlobalSecurityConfiguration.Description=\u041E\u0431\u0435\u0437\u0431\u0435\u0434\u0438 Jenkins \u2014 \u043A\u043E \u0438\u043C\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u0441\u0438\u0441\u0442\u0435\u043C\u0443. +HudsonPrivateSecurityRealm.WouldYouLikeToSignUp=\u041E\u0432\u0430\u0458 {0} {1} \u0458\u0435 \u043D\u043E\u0432\u043E Jenkins-\u0443. \u0414\u0430\u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0443\u0458\u0435\u0442\u0435? +LegacyAuthorizationStrategy.DisplayName=\u0421\u0442\u0430\u0440\u0438 \u0440\u0435\u0436\u0438\u043C +HudsonPrivateSecurityRealm.DisplayName=\u0411\u0430\u0437\u0430 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430 \u0437\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0435 \u0443\u043D\u0443\u0442\u0430\u0440 Jenkins +HudsonPrivateSecurityRealm.Details.DisplayName=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 +HudsonPrivateSecurityRealm.Details.PasswordError=\u041B\u043E\u0437\u0438\u043D\u043A\u0435 \u0441\u0435 \u043D\u0435 \u043F\u043E\u043A\u043B\u0430\u043F\u0430\u0458\u0443. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u0443\u043D\u0435\u0441\u0438\u0442\u0435 \u043F\u043E\u043D\u043E\u0432\u043E. +HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430 +HudsonPrivateSecurityRealm.ManageUserLinks.Description=\ \u041A\u0440\u0435\u0438\u0440\u0430\u0458/\u0438\u0437\u0431\u0440\u0438\u0448\u0438/\u0443\u0440\u0435\u0434\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0435 \u0441\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u043E\u043C \u043D\u0430 Jenkins +HudsonPrivateSecurityRealm.CreateAccount.TextNotMatchWordInImage=\u0422\u0435\u043A\u0441\u0442 \u043D\u0435 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430 \u0440\u0435\u045B \u043F\u043E\u043A\u0430\u0437\u0430\u043D \u0441\u043B\u0438\u043A\u043E\u043C +HudsonPrivateSecurityRealm.CreateAccount.PasswordNotMatch=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 \u0441\u0435 \u043D\u0435 \u043F\u043E\u043A\u043B\u0430\u043F\u0430 +HudsonPrivateSecurityRealm.CreateAccount.PasswordRequired=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u0430 +HudsonPrivateSecurityRealm.CreateAccount.UserNameRequired=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +HudsonPrivateSecurityRealm.CreateAccount.InvalidEmailAddress=\u041D\u0435\u0432\u0430\u0436\u0435\u045B\u0430 \u0430\u0434\u0440\u0435\u0441\u0430 \u0435-\u043F\u043E\u0448\u0442\u0435 +HudsonPrivateSecurityRealm.CreateAccount.UserNameAlreadyTaken=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 \u0458\u0435 \u0432\u0435\u045B \u0437\u0430\u0443\u0437\u0435\u0442\u043E +FullControlOnceLoggedInAuthorizationStrategy.DisplayName=\u041F\u0440\u0438\u0458\u0430\u0432\u0459\u0435\u043D\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \u043C\u043E\u0433\u0443 \u0441\u0432\u0435 +AuthorizationStrategy.DisplayName=\u0421\u0432\u0438 \u043C\u043E\u0433\u0443 \u0441\u0432\u0435 +LDAPSecurityRealm.DisplayName=LDAP +LDAPSecurityRealm.SyntaxOfServerField=\u0428\u0430\u0431\u043B\u043E\u043D \u0441\u0435\u0440\u0432\u0435\u0440 \u043F\u043E\u0459\u0443 \u0458\u0435 \u0421\u0415\u0420\u0412\u0415\u0420 \u0438\u043B\u0438 \u0421\u0415\u0420\u0412\u0415\u0420:\u041F\u041E\u0420\u0422 or ldaps://\u0421\u0415\u0420\u0412\u0415\u0420[:\u041F\u041E\u0420\u0422] +LDAPSecurityRealm.UnknownHost=\u041D\u0435\u043F\u043E\u0437\u043D\u0430\u0442\u0438 \u0445\u043E\u0441\u0442: {0} +LDAPSecurityRealm.UnableToConnect=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0441\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u0442\u0438 \u043D\u0430 {0} : {1} +LDAPSecurityRealm.InvalidPortNumber=\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u0430\u043D \u0431\u0440\u043E\u0458 \u043F\u043E\u0440\u0442\u0430 +LegacySecurityRealm.Displayname=\u0414\u0435\u043B\u0435\u0433\u0438\u0440\u0430\u0458 \u0441\u0435\u0440\u0432\u043B\u0435\u0442 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0443 +UserDetailsServiceProxy.UnableToQuery=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043F\u0440\u043E\u0458\u0430\u045B\u0438 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0443 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430: {0} +PAMSecurityRealm.DisplayName=\u0411\u0430\u0437\u0430 \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430 \u043E \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430/\u0433\u0440\u0443\u043F\u0430 \u043D\u0430 Unix +PAMSecurityRealm.ReadPermission=Jenkins \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043E \u0434\u0430 \u0431\u0443\u0434\u0435 \u0443 \u0441\u0442\u0430\u045A\u0443 \u0434\u0430 \u0443\u0447\u0438\u0442\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 "/etc/shadow". +PAMSecurityRealm.BelongToGroup={0} \u043C\u043E\u0440\u0430 \u043F\u0440\u0438\u043F\u0430\u0434\u0430\u0442\u0438 \u0433\u0440\u0443\u043F\u0438 {1} \u0434\u0430 \u0431\u0438 \u0443\u0447\u0438\u0442\u0430\u043E /etc/shadow +PAMSecurityRealm.RunAsUserOrBelongToGroupAndChmod=Jenkins \u0442\u0440\u0435\u0431\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u043A\u0430\u043E {0} \u0438\u043B\u0438 {1} \u0442\u0440\u0435\u0431\u0430 \u043F\u0438\u0440\u0430\u0434\u0430\u0442\u0438 \u0433\u0440\u0443\u043F\u0438 {2} \u0438 \u2018chmod g+r /etc/shadow\u2019 \u0442\u0440\u0435\u0431\u0430 \u0431\u0438\u0442\u0438 \u0438\u0437\u0432\u0440\u0448\u0435\u043D\u043E \u0434\u0430 \u0431\u0438 Jenkins \u0443\u0447\u0438\u0442\u0430\u043E /etc/shadow +PAMSecurityRealm.Success=\u0423\u0441\u043F\u0435\u0448\u043D\u043E +PAMSecurityRealm.User=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u043A '{0}' +PAMSecurityRealm.Uid=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u043E\u043D\u0438 \u0431\u0440\u043E\u0458 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A\u0430: {0} +PAMSecurityRealm.CurrentUser=\u0422\u0440\u0435\u043D\u0443\u0442\u043D\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A +Permission.Permissions.Title=\u041D/\u0414 +AccessDeniedException2.MissingPermission={0} \u0444\u0430\u043B\u0438 \u043E\u0432\u043B\u0430\u0448\u045B\u0435\u045A\u0435 {1} \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/Messages_zh_CN.properties b/core/src/main/resources/hudson/security/Messages_zh_CN.properties index a69de52c6a64dbe61012e10ba4dbe025d128172e..aeedb5f01c14271ea5c2499bccac1cd01c0f64d9 100644 --- a/core/src/main/resources/hudson/security/Messages_zh_CN.properties +++ b/core/src/main/resources/hudson/security/Messages_zh_CN.properties @@ -1,59 +1,59 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -LegacyAuthorizationStrategy.DisplayName=\u9057\u7559\u6a21\u5f0f - -HudsonPrivateSecurityRealm.DisplayName=Jenkins\u4e13\u6709\u7528\u6237\u6570\u636e\u5e93 -HudsonPrivateSecurityRealm.Details.DisplayName=\u5bc6\u7801 -HudsonPrivateSecurityRealm.Details.PasswordError=\ - \u786e\u8ba4\u5bc6\u7801\u4e0e\u7b2c\u4e00\u6b21\u8f93\u5165\u7684\u4e0d\u4e00\u81f4. \ - \u8bf7\u786e\u8ba4\u4e24\u6b21\u5bc6\u7801\u8f93\u5165\u76f8\u540c. -HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=\u7ba1\u7406\u7528\u6237 -HudsonPrivateSecurityRealm.ManageUserLinks.Description=\u521b\u5efa/\u5220\u9664/\u4fee\u6539Jenkins\u7528\u6237 - -FullControlOnceLoggedInAuthorizationStrategy.DisplayName=\u767b\u5f55\u7528\u6237\u53ef\u4ee5\u505a\u4efb\u4f55\u4e8b - -AuthorizationStrategy.DisplayName=\u4efb\u4f55\u7528\u6237\u53ef\u4ee5\u505a\u4efb\u4f55\u4e8b(\u6ca1\u6709\u4efb\u4f55\u9650\u5236) - -LDAPSecurityRealm.DisplayName=LDAP -LDAPSecurityRealm.SyntaxOfServerField=Syntax of server field is SERVER or SERVER:PORT or ldaps://SERVER[:PORT] -LDAPSecurityRealm.UnknownHost=Unknown host: {0} -LDAPSecurityRealm.UnableToConnect=Unable to connect to {0} : {1} -LDAPSecurityRealm.InvalidPortNumber=Invalid port number - -LegacySecurityRealm.Displayname=Servlet\u5bb9\u5668\u4ee3\u7406 - -UserDetailsServiceProxy.UnableToQuery=\u6ca1\u6709\u68c0\u7d22\u5230\u8fd9\u4e2a\u7528\u6237\u4fe1\u606f: {0} - -PAMSecurityRealm.DisplayName=Unix\u7528\u6237/\u7ec4\u6570\u636e\u5e93 -PAMSecurityRealm.ReadPermission=Jenkins\u9700\u8981\u6709/etc/shadow\u8bfb\u7684\u6743\u9650 -PAMSecurityRealm.BelongToGroup={0}\u5fc5\u987b\u5c5e\u4e8e{1}\u7ec4\u6765\u8bfb\u53d6/etc/shadow -PAMSecurityRealm.RunAsUserOrBelongToGroupAndChmod=\ - Either Jenkins needs to run as {0} or {1} needs to belong to group {2} and ''chmod g+r /etc/shadow'' needs to be done to enable Jenkins to read /etc/shadow -PAMSecurityRealm.Success=\u6210\u529f -PAMSecurityRealm.User=\u7528\u6237 ''{0}'' -PAMSecurityRealm.CurrentUser=\u5f53\u524d\u7528\u6237 -PAMSecurityRealm.Uid=uid: {0} - -# not in use -Permission.Permissions.Title=N/A -AccessDeniedException2.MissingPermission={0}\u6ca1\u6709{1}\u6743\u9650 +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant, Seiji Sogabe +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +LegacyAuthorizationStrategy.DisplayName=\u9057\u7559\u6a21\u5f0f + +HudsonPrivateSecurityRealm.DisplayName=Jenkins\u4e13\u6709\u7528\u6237\u6570\u636e\u5e93 +HudsonPrivateSecurityRealm.Details.DisplayName=\u5bc6\u7801 +HudsonPrivateSecurityRealm.Details.PasswordError=\ + \u786e\u8ba4\u5bc6\u7801\u4e0e\u7b2c\u4e00\u6b21\u8f93\u5165\u7684\u4e0d\u4e00\u81f4. \ + \u8bf7\u786e\u8ba4\u4e24\u6b21\u5bc6\u7801\u8f93\u5165\u76f8\u540c. +HudsonPrivateSecurityRealm.ManageUserLinks.DisplayName=\u7ba1\u7406\u7528\u6237 +HudsonPrivateSecurityRealm.ManageUserLinks.Description=\u521b\u5efa/\u5220\u9664/\u4fee\u6539Jenkins\u7528\u6237 + +FullControlOnceLoggedInAuthorizationStrategy.DisplayName=\u767b\u5f55\u7528\u6237\u53ef\u4ee5\u505a\u4efb\u4f55\u4e8b + +AuthorizationStrategy.DisplayName=\u4efb\u4f55\u7528\u6237\u53ef\u4ee5\u505a\u4efb\u4f55\u4e8b(\u6ca1\u6709\u4efb\u4f55\u9650\u5236) + +LDAPSecurityRealm.DisplayName=LDAP +LDAPSecurityRealm.SyntaxOfServerField=Syntax of server field is SERVER or SERVER:PORT or ldaps://SERVER[:PORT] +LDAPSecurityRealm.UnknownHost=Unknown host: {0} +LDAPSecurityRealm.UnableToConnect=Unable to connect to {0} : {1} +LDAPSecurityRealm.InvalidPortNumber=Invalid port number + +LegacySecurityRealm.Displayname=Servlet\u5bb9\u5668\u4ee3\u7406 + +UserDetailsServiceProxy.UnableToQuery=\u6ca1\u6709\u68c0\u7d22\u5230\u8fd9\u4e2a\u7528\u6237\u4fe1\u606f: {0} + +PAMSecurityRealm.DisplayName=Unix\u7528\u6237/\u7ec4\u6570\u636e\u5e93 +PAMSecurityRealm.ReadPermission=Jenkins\u9700\u8981\u6709/etc/shadow\u8bfb\u7684\u6743\u9650 +PAMSecurityRealm.BelongToGroup={0}\u5fc5\u987b\u5c5e\u4e8e{1}\u7ec4\u6765\u8bfb\u53d6/etc/shadow +PAMSecurityRealm.RunAsUserOrBelongToGroupAndChmod=\ + Either Jenkins needs to run as {0} or {1} needs to belong to group {2} and ''chmod g+r /etc/shadow'' needs to be done to enable Jenkins to read /etc/shadow +PAMSecurityRealm.Success=\u6210\u529f +PAMSecurityRealm.User=\u7528\u6237 ''{0}'' +PAMSecurityRealm.CurrentUser=\u5f53\u524d\u7528\u6237 +PAMSecurityRealm.Uid=uid: {0} + +# not in use +Permission.Permissions.Title=N/A +AccessDeniedException2.MissingPermission={0}\u6ca1\u6709{1}\u6743\u9650 diff --git a/core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly b/core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly index 63de7d90a34a2557a3ca6ebd0110f72e5b2adb03..8b065c318b2c5b4f40aff81e366be098fe93c470 100644 --- a/core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly +++ b/core/src/main/resources/hudson/security/SecurityRealm/loginLink.jelly @@ -25,9 +25,5 @@ THE SOFTWARE. - - - - - ${%login} + ${%login} diff --git a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_bg.properties b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_bg.properties index 13f77447402faded9c48b60a492bf8f30fbf0b01..c63343d4501e174352700c8f62cbe55586e17c46 100644 --- a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_bg.properties +++ b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -login=\u0432\u0445\u043E\u0434 +login=\ + \u0432\u0445\u043e\u0434 diff --git a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_de.properties b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_de.properties index 6d9fd63908ef42685a8975a49d3f0d0e00a55440..832a4943058a373cc0445de64f9e61f3018c7061 100644 --- a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_de.properties +++ b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_de.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -login=anmelden +login=Anmelden diff --git a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_pl.properties b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_pl.properties index a17c45ef4e3e9efccbcba8a4c8a8c681631d36a8..8df91bd9295e680fdf53a47af04db6fca77117e0 100644 --- a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_pl.properties +++ b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -login=zaloguj si\u0119 +login=Logowanie diff --git a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_sr.properties b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_sr.properties index d57edbe1596c5720c5239d8f0f8b3cf2ae38c86b..c7e7a1693ed818feeb9746e42b3dec95098fb470 100644 --- a/core/src/main/resources/hudson/security/SecurityRealm/loginLink_sr.properties +++ b/core/src/main/resources/hudson/security/SecurityRealm/loginLink_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -login=Prijavi se +login=\u041F\u0440\u0438\u0458\u0430\u0432\u0438 \u0441\u0435 diff --git a/core/src/main/resources/hudson/security/SecurityRealm/signup_sr.properties b/core/src/main/resources/hudson/security/SecurityRealm/signup_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b84ffe86ae4cfbcb0ec2b576b3186802314c1954 --- /dev/null +++ b/core/src/main/resources/hudson/security/SecurityRealm/signup_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Signup\ not\ supported=\u041F\u0440\u0438\u0458\u0430\u0432\u0430 \u043D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 +Sign\ up=\u041F\u0440\u0438\u0458\u0430\u0432\u0438 \u0441\u0435 +This\ is\ not\ supported\ in\ the\ current\ configuration.=\u041D\u0438\u0458\u0435 \u043F\u043E\u0434\u0440\u0436\u0430\u043D\u043E \u0437\u0430 \u0442\u0435\u043A\u0443\u045B\u0443 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0458\u0443 diff --git a/core/src/main/resources/hudson/security/csrf/DefaultCrumbIssuer/config_sr.properties b/core/src/main/resources/hudson/security/csrf/DefaultCrumbIssuer/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..28f532fc9e5289979365484fc00dc05852520f45 --- /dev/null +++ b/core/src/main/resources/hudson/security/csrf/DefaultCrumbIssuer/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Enable\ proxy\ compatibility=\u041E\u043C\u043E\u0433\u0443\u045B\u0438 \u043A\u043E\u043C\u043F\u0430\u0442\u0438\u0431\u0438\u043B\u0438\u043D\u043E\u0441\u0442 proxy-\u0430 diff --git a/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/config_sr.properties b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e81a8855eac1824cc63e19e9902323323f47e10b --- /dev/null +++ b/core/src/main/resources/hudson/security/csrf/GlobalCrumbIssuerConfiguration/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Prevent\ Cross\ Site\ Request\ Forgery\ exploits=\u0421\u043F\u0440\u0435\u0447\u0438 Cross Site Request Forgery \u043F\u0440\u043E\u0432\u0430\u043B\u0435 +Crumbs=\u041C\u0440\u0432\u0438\u0446\u0435 +Crumb\ Algorithm=\u0410\u043B\u0433\u043E\u0440\u0438\u0442\u0430\u043C \u043C\u0440\u0432\u0438\u0446\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/security/csrf/Messages_bg.properties b/core/src/main/resources/hudson/security/csrf/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..e42f9fceae54ce53c9ad2c88cad709b6a65e2bcd --- /dev/null +++ b/core/src/main/resources/hudson/security/csrf/Messages_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +DefaultCrumbIssuer.DisplayName=\ + \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e \u0441\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u044a\u0442\u0435\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 diff --git a/core/src/main/resources/hudson/security/csrf/Messages_sr.properties b/core/src/main/resources/hudson/security/csrf/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b67ab3e3df42129c13d5f416e0ea888b0e2525ce --- /dev/null +++ b/core/src/main/resources/hudson/security/csrf/Messages_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +DefaultCrumbIssuer.DisplayName=\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438 \u0438\u0437\u0434\u0430\u0432\u0430\u0447 \u043C\u0440\u0432\u0438\u0446\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr.html b/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr.html index 08a970a6bf9051f76a3e2ca0af4f0ec23e9fdc92..75a258c36e5076fc109dd4363f469adb8a398f6e 100644 --- a/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr.html +++ b/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr.html @@ -1,5 +1,5 @@
    - You can place the upward limit to the number of slaves that Jenkins may launch from this cloud. + You can place the upward limit to the number of agents that Jenkins may launch from this cloud. This is useful for avoiding surprises in the billing statement.

    diff --git a/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr_zh_TW.html b/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr_zh_TW.html deleted file mode 100644 index a8a73747dfceed6968d51f1f91cba5c0e0a118f7..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/AbstractCloudImpl/help-instanceCapStr_zh_TW.html +++ /dev/null @@ -1,11 +0,0 @@ -

    - 您可以設定 Jenkins 在這片雲中可以啟動的 Slave 上限數目。 - 可以避免收到帳單時受到太大的震憾。 - -

    - 以輸入 3 為例,Jenkins 在雲端執行個體數沒達上限前才能再啟動一個新的。 - 在這個方式下,最糟就算 Jenkins 起了執行個體後就置之不理,您還是有能同時執行的個體數上限。 - -

    - 不填的話代表不設上限。 -

    diff --git a/core/src/main/resources/hudson/slaves/CommandConnector/config_sr.properties b/core/src/main/resources/hudson/slaves/CommandConnector/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..67a16da6ab6c0c3496e316b353bf41ad98ec2e99 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/CommandConnector/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Launch\ command=\u0418\u0437\u0432\u0440\u0448\u0438 \u043F\u0440\u043E\u0433\u0440\u0430\u043C \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/config_sr.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f7053d115b3b9fc20527432f3615086f9eb5cb8b --- /dev/null +++ b/core/src/main/resources/hudson/slaves/CommandLauncher/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Launch\ command=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 \u0437\u0430 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command.html b/core/src/main/resources/hudson/slaves/CommandLauncher/help-command.html index 7177d11330b66c754a9fd2600ef82ba64aad2002..ad61686f9fcf2878546f1e7b10d78f87c0d11ca2 100644 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command.html +++ b/core/src/main/resources/hudson/slaves/CommandLauncher/help-command.html @@ -1,8 +1,8 @@
    - Command to be used to launch a slave agent program, which controls the slave + Command to be used to launch an agent program, which controls the agent computer and communicates with the master. Jenkins assumes that the executed program launches the slave.jar program on the correct - slave machine. + machine.

    A copy of slave.jar can be downloaded from here. @@ -11,9 +11,9 @@ In a simple case, this could be something like "ssh hostname java -jar ~/bin/slave.jar". - However, it is often a good idea to write a small shell script, like the following, on a slave + However, it is often a good idea to write a small shell script, like the following, on an agent so that you can control the location of Java and/or slave.jar, as well as set up any - environment variables specific to this slave node, such as PATH. + environment variables specific to this node, such as PATH.

     #!/bin/sh
    @@ -21,7 +21,7 @@ exec java -jar ~/bin/slave.jar
     

    - You can use any command to run a process on the slave machine, such as RSH, + You can use any command to run a process on the agent machine, such as RSH, as long as stdin/stdout of this process will be connected to "java -jar ~/bin/slave.jar" eventually. diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_de.html b/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_de.html deleted file mode 100644 index 699a7272084a61483750401b9e962c4d1205ffbd..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_de.html +++ /dev/null @@ -1,42 +0,0 @@ -

    - Befehl, um einen Slave-Agenten zu starten, der den Slave-Knoten kontrolliert - und mit dem Master-Knoten kommuniziert. - -

    - Wenn in diesem Feld ein Befehl angegeben ist, so wird dieser auf dem Master-Knoten - ausgeführt. Jenkins nimmt in diesem Fall an, daß der ausgeführte Befehl - das Programm slave.jar auf dem jeweiligen Slave-Knoten startet. - -

    - slave.jar befindet sich als WEB-INF/slave.jar. - -

    - Ein einfachen Fällen, könnte der Befehl zum Beispiel so aussehen: - "ssh hostname java -jar ~/bin/slave.jar". - - Trotzdem ist es meistens eine gute Idee, ein kleines Shell-Skript wie das - folgende auf dem Slave-Knoten einzusetzen. Dies ermöglicht zum einen, den Pfad der - verwendeten Java-Installation und/oder des Archives slave.jar - zu kontrollieren, als auch Umgebungsvariablen zu setzen, die spezifisch für - den jeweiligen Slave-Knoten sind (etwa PATH). - -

    -#!/bin/sh
    -exec java -jar ~/bin/slave.jar
    -
    - -

    - Sie können jeden beliebigen Befehl verwenden, um einen Prozess auf dem - Slave-Knoten zu starten, z.B. rsh, solange die Standardein- und ausgabe - (STDIN, STDOUT) dieses Prozesses mit "java -jar ~/bin/slave.jar" verbunden sind. -

    - - In einer größeren Installation könnte man außerdem in Betracht ziehen, - slave.jar von einem gemeinsamen Netzlaufwerk zu laden, so daß die - komplette Installation einfacher aktualisiert werden kann. - -

    - Tipp: Eine Einstellung von "ssh -v hostname" kann hilfreich bei der Analyse von - Verbindungsproblemen sein. - -

    diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_pt_BR.html b/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_pt_BR.html deleted file mode 100644 index 406267125f0a11bea95f984bf019865d6aa29522..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_pt_BR.html +++ /dev/null @@ -1,53 +0,0 @@ -
    - Comando para ser usado para lançar o program agente na máquina slave, o qual controla o - computador slave e se comunica com o master. - -

    Agentes slave JNLP

    -

    - Deixe este campo vazio se você quiser lançar os agentes slave via JNLP. - Com esta configuração, a página de informações do slave (jenkins/computer/***/) - terá um ícone de lançamento JNLP, e você poderá clicar no link da máquina slave - correta para lançar o agente slave via JNLP. -

    - Este modo é conveniente para slaves Windows que frequentemente não tem um mecanismo - de execução remota. - -

    Agentes slave ssh/rsh

    -

    - Quando um comando real é especificado neste campo, - este comando é executado na máquina - master, e o Jenkins assume que o programa executado lança o programa slave.jar - na máquina slave correta. - - -

    - Uma cópia de slave.jar pode ser encontrada em WEB-INF/slave.jar dentro de - jenkins.war. - -

    - Em um simples caso, isto poderia ser - algo como "ssh hostname java -jar ~/bin/slave.jar". - - Entretanto, é uma boa idéia escrever um pequeno shell script, como o seguinte, em um slave - tal que você possa controlar a localização do Java e/ou slave.jar, bem como configurar - qualquer variável de ambiente específica para este nó slave, tal como PATH. - -

    -#!/bin/sh
    -exec java -jar ~/bin/slave.jar
    -
    - -

    - Você pode usar qualquer comando para executar um processo na máquina slave, tal como RSH, - desde que as entrada/saída padrão (stdin/stdout) deste processo estejam eventualmente - conectadas a "java -jar ~/bin/slave.jar". - -

    - Em uma grande implantação, também é valioso considerar carregar slave.jar de - uma localização comum montada via NFS, assim você não tem que atualizar este arquivo toda vez - que você atualizar o Jenkins. - -

    - Definir isto como "ssh -v hostname" pode ser útil para depurar questões de - conectividade. -

    diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_tr.html b/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_tr.html deleted file mode 100644 index 98943c41928c7c8703b54c8b1d5686c86684a5e1..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_tr.html +++ /dev/null @@ -1,38 +0,0 @@ -
    - Slave ajanı, slave bilgisayarı kontrol eder ve master bilgisayar ile iletişiminden - sorumludur. Buraya yazılacak komut, slave ajanı çalıştıracak komuttur. - -

    - Jenkins, burada belirtilen komutun, doğru slave üzerinde slave.jar'ı doğru şekilde - çalıştıracağını varsayar ve bu komutu master üzerinde çalıştırır. - - -

    - slave.jar'ın bir kopyası, jenkins.war'ın içerisinde WEB-INF - klasörü altında bulunabilir. - -

    - En basit şekilde, yazılacak komut "ssh hostname java -jar ~/bin/slave.jar" - şeklinde olmalıdır. - - Yinede aşağıdaki gibi bir shell script yazarsanız, Java'nın ve slave.jar'ın yerlerini - ve bu slave'e özgü olabilecek ortam değişkenlerini (mesela PATH), kolaylıkla - yönetebilirsiniz. - -

    -#!/bin/sh
    -exec java -jar ~/bin/slave.jar
    -
    - -

    - ?alıştırılacak komutun stdin/stdout metodları "java -jar ~/bin/slave.jar" ile - ilişkili olduğu sürece, slave makinede RSH gibi komutları çalıştırabilirsiniz. - -

    - Daha geniş bir sistemde, slave.jar dosyasını ortak bir dizinden (NFS-mounted) - okutursanız, Husdon'ı her güncellediğinizde slave'leri ayrı ayrı güncellemek zorunda kalmazsınız. - -

    - Bu kısımda "ssh -v hostname" şeklinde bir kullanım, bağlantıda oluşabilecek sorunları - çözmede yardımcı olacaktır. -

    diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_zh_TW.html b/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_zh_TW.html deleted file mode 100644 index af1e220f352fb434cce7960bb8475261856452c6..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help-command_zh_TW.html +++ /dev/null @@ -1,29 +0,0 @@ -
    - 啟動 Slave 代理程式的指令,可以控制 Slave 電腦並與 Master 溝通。 - Jenkins 假設執行的程式會在正式的 Slave 機器上啟動 slave.jar。 - -

    - 可以由這裡下載 slave.jar。 - -

    - 簡單一點就像 "ssh 主機名稱 java -jar ~/bin/slave.jar"。 - - 但是,一般會建議您在 Slave 上面寫一個小 Shell Script,控制 Java 及 slave.jar 的位置, - 也能設定 PATH 這類節點間不盡相同的環境變數。就像: - -

    -#!/bin/sh
    -exec java -jar ~/bin/slave.jar
    -
    - -

    - 您可以使用任何指令執行 Slave 機器上的程式,例如 RSH。 - 只要最後程式的 stdin 及 stdout 被連到 "java -jar ~/bin/slave.jar" 就好。 - -

    - 大型部署環境下,可以考慮從掛載 NFS 的共通位置中載入 slave.jar, - 就不用每次升級 Jenkins 時還要同步更新每部機器上的這個檔案。 - -

    - 設定成 "ssh -v 主機名稱" 可以幫助您處理連線問題。 -

    diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help.properties index e4d34a73f132adb67ee519a26dd63d205b8ce344..ea17495f1d071d95edc2eb9428ac4656dee9c87b 100644 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help.properties +++ b/core/src/main/resources/hudson/slaves/CommandLauncher/help.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blurb=Starts a slave by having Jenkins execute a command from the master. \ - Use this when the master is capable of remotely executing a process on a slave, such as through ssh/rsh. +blurb=Starts an agent by having Jenkins execute a command from the master. \ + Use this when the master is capable of remotely executing a process on another machine, e.g. via SSH or RSH. diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_da.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help_da.properties deleted file mode 100644 index 0c16c82c0780222b14f61d56f462ae051c21ca2b..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help_da.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Starter en ny slave ved at Jenkins k\u00f8rer en kommando p\u00e5 master''en. \ -Brug dette n\u00e5r master''en er i stand til at fjernafvikle en proces p\u00e5 slaven, for eksempel igennem ssh/rsh. diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_fr.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help_fr.properties deleted file mode 100644 index 724e3797a69535f0b971f555442b8bf0f8625bc0..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help_fr.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe, Eric Lefevre-Ardant -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Lance un esclave en demandant Jenkins d''excuter une commande partir de la machine matre. \ - Utilisez cela quand le matre est capable d''excuter distance des processus sur la machine esclave, par exemple par ssh/rsh. diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_ja.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help_ja.properties deleted file mode 100644 index c1dd1e4e0344b42c43cf579ef34b387554e36ec8..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help_ja.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=\u30DE\u30B9\u30BF\u304B\u3089\u30B3\u30DE\u30F3\u30C9\u3092\u5B9F\u884C\u3057\u3066\u30B9\u30EC\u30FC\u30D6\u3092\u8D77\u52D5\u3057\u307E\u3059\u3002\ - ssh\u3084rsh\u7D4C\u7531\u7B49\u3067\u3001\u30DE\u30B9\u30BF\u304C\u30B9\u30EC\u30FC\u30D6\u306E\u30D7\u30ED\u30BB\u30B9\u3092\u30EA\u30E2\u30FC\u30C8\u304B\u3089\u5B9F\u884C\u3067\u304D\u308B\u5834\u5408\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002 diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_pt_BR.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help_pt_BR.properties deleted file mode 100644 index cccf5c035eb2d4be14c7bac919d5c337347a4faa..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help_pt_BR.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva, Fernando Boaglio -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# Starts a slave by having Jenkins execute a command from the master. \ -# Use this when the master is capable of remotely executing a process on a slave, such as through ssh/rsh. -blurb=Iniciar um slave executando por um comando executado no master \ - Se n\u00e3o for poss\u00edvel, execute o comando via ssh/rsh - - diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_sr.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1f0dde07739dabebc261922fc594c560b4db6f52 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/CommandLauncher/help_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u041F\u043E\u043A\u0440\u0435\u043D\u0435 \u0430\u0433\u0435\u043D\u0442\u0430 \u0442\u0430\u043A\u043E \u0448\u0442\u043E Jenkins \u0438\u0437\u0432\u0440\u0448\u0438 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 \u0441\u0430 \u0433\u043B\u0430\u0432\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435. \u041A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043E\u0432\u0443 \u043E\u043F\u0446\u0438\u0458\u0443 \u043A\u0430\u0434 \u0433\u043E\u0434 \u0433\u043B\u0430\u0432\u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0458\u0435 \u0443 \u0441\u0442\u0430\u045A\u0443 \u0434\u0430 \u0438\u0437\u0432\u0440\u0448\u0438 \u043F\u0440\u043E\u0446\u0435\u0441 \u043D\u0430 \u0434\u0440\u0443\u0433\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438, \u043D\u043F\u0440. \u043F\u0440\u0435\u043A\u043E SSH \u0438\u043B\u0438 RSH. diff --git a/core/src/main/resources/hudson/slaves/CommandLauncher/help_zh_TW.properties b/core/src/main/resources/hudson/slaves/CommandLauncher/help_zh_TW.properties deleted file mode 100644 index 7900696b3b1c19f7dad52dc1627195f81c199345..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/CommandLauncher/help_zh_TW.properties +++ /dev/null @@ -1,24 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=\u8b93 Jenkins \u5728 Master \u4e0a\u57f7\u884c\u6307\u4ee4\u555f\u52d5 Slave\u3002\ - \u9069\u7528\u65bc\u53ef\u4ee5\u9060\u7aef\u57f7\u884c Slave \u7a0b\u5f0f\u7684 Master\uff0c\u4f8b\u5982\u900f\u904e ssh \u6216 rsh\u3002 diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main.jelly b/core/src/main/resources/hudson/slaves/ComputerLauncher/main.jelly index 698a2674ee1989d132e78c4e546eb547f951b760..70b5aa9137a6c55e8315839b89dc113bbabc3427 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main.jelly +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main.jelly @@ -34,7 +34,7 @@ THE SOFTWARE.
    - +
    @@ -42,7 +42,7 @@ THE SOFTWARE.
    - +
    diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_bg.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_bg.properties deleted file mode 100644 index 6f764d513ee3ce16d3e680cd355a061cf09a7318..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_bg.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Launch\ slave\ agent=\u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0439 \u0430\u0433\u0435\u043D\u0442\u0430 \u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0430\u0442\u0430 diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_da.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_da.properties index 16c281121633f1d2bdb0e5925d13e727af4aed21..51d84878fdaf84726355e4068bee9664994958e6 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_da.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_da.properties @@ -20,7 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Launch\ slave\ agent=Start slave agenter launchingDescription=Denne node er ved at starte op See\ log\ for\ more\ details=Se loggen for flere detaljer -Relaunch\ slave\ agent=Genstart slave agent diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_de.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_de.properties index 0646fb1fb33400e819ad1983fde44e53ab723f9d..d9bfb36500684d6eb8c5a8d7aec63a6b934da598 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_de.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_de.properties @@ -21,6 +21,3 @@ # THE SOFTWARE. See\ log\ for\ more\ details=Mehr dazu im Systemprotokoll -Launch\ slave\ agent=Slave-Agenten starten -launchingDescription=Dieser Knoten ist offline, weil Jenkins den dortigen Slave-Agenten nicht starten konnte. -Relaunch\ slave\ agent=Slave-Agenten neu starten diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_es.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_es.properties index c999de630b7855eae7f8442fb33de4074c38bbfe..6d65f4a03fa16a54d4fa49229787881e435df778 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_es.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_es.properties @@ -22,5 +22,5 @@ launchingDescription=Este nodo va a ser ejecutado. See\ log\ for\ more\ details=Echa un vistazo al log para ver mas detalles -Launch\ slave\ agent=Lanzar agente esclavo -Relaunch\ slave\ agent=Relanzar agente esclavo +Launch\ agent=Lanzar agente +Relaunch\ agent=Relanzar agente diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_fr.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_fr.properties index 9607e04b059631b2c3797902c18ab34fb7eed93b..5b28b80fdc476abbed8c74cfad7f6fe10ab35714 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_fr.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_fr.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. See\ log\ for\ more\ details=Voir les logs pour plus de dtails -Launch\ slave\ agent=Lancer l''agent esclave diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_ja.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_ja.properties index 7d1cb847a6bbf7accb271df9cf3066fb8359df54..1b6052a5e5646fac975e129e862abbcb18d0b730 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_ja.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_ja.properties @@ -21,6 +21,4 @@ # THE SOFTWARE. See\ log\ for\ more\ details=\u8A73\u7D30\u306F\u30ED\u30B0\u3092\u53C2\u7167 -Launch\ slave\ agent=\u30B9\u30EC\u30FC\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u8D77\u52D5 -Relaunch\ slave\ agent=\u30B9\u30EC\u30FC\u30D6\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u3092\u518D\u8D77\u52D5 launchingDescription=\u3053\u306E\u30CE\u30FC\u30C9\u306F\u8D77\u52D5\u6E08\u307F\u3067\u3059\u3002 diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties index 58f89245df93db3de92ad1b365f43ce71bb74cd9..4fc0b8c1b0a44c58ec90947705d6827f2beb3962 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_pt_BR.properties @@ -20,8 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Relaunch\ slave\ agent=Relan\u00e7ar o agente slave # This node is being launched. launchingDescription=Este n\u00f3 est\u00e1 sendo lan\u00e7ado -Launch\ slave\ agent=Lan\u00e7ar agente slave See\ log\ for\ more\ details=Veja o log para mais detalhes diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sr.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..23f7fceb55abd588e379e5fed687044ea740dbcf --- /dev/null +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +launchingDescription=\u041E\u0432\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u0441\u0435 \u043F\u043E\u043A\u0440\u0435\u045B\u0435 +See\ log\ for\ more\ details=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B \u0437\u0430 \u0432\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430 +Relaunch\ agent=\u041F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0438 \u0430\u0433\u0435\u043D\u0442 +Launch\ agent=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0430\u0433\u0435\u043D\u0442 +description=\u041E\u0432\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 \u045B\u0435 \u0431\u0438\u0442\u0438 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0430. diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sv_SE.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sv_SE.properties index 42f78c2c362ef40fd109546595783cf95799ccf6..61a5469b2318742d81c26b12215c932f6d562f9a 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sv_SE.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_sv_SE.properties @@ -20,6 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Launch\ slave\ agent=Starta agent See\ log\ for\ more\ details=Se loggen f\u00F6r mer information description=Denna nod \u00E4r fr\u00E5nkopplad eftersom Jenkins kunde inte starta agenten p\u00E5 noden. diff --git a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_zh_TW.properties b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_zh_TW.properties index 8505469b0969a0dba2e01ccfa63ef31183da04c8..787a6ef670694e80117edf514073031bb741f53b 100644 --- a/core/src/main/resources/hudson/slaves/ComputerLauncher/main_zh_TW.properties +++ b/core/src/main/resources/hudson/slaves/ComputerLauncher/main_zh_TW.properties @@ -22,5 +22,3 @@ launchingDescription=\u672C\u7BC0\u9EDE\u6B63\u5728\u555F\u52D5\u4E2D\u3002 See\ log\ for\ more\ details=\u67E5\u770B\u65E5\u8A8C\u53D6\u5F97\u8A73\u7D30\u8CC7\u6599 -Relaunch\ slave\ agent=\u91CD\u65B0\u555F\u52D5 Slave \u4EE3\u7406\u7A0B\u5F0F -Launch\ slave\ agent=\u555F\u52D5 Slave \u4EE3\u7406\u7A0B\u5F0F diff --git a/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config.jelly b/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config.jelly index 843cb9d3c9c30162f5c8fa28f020ce9b0abc21b0..798f805eed268a7a088148c9dd1b8d4797ca322f 100644 --- a/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config.jelly +++ b/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config.jelly @@ -25,5 +25,5 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config_sr.properties b/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..147ac620f18b6184b4922674a1ce155506121653 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/DelegatingComputerLauncher/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Actual\ launch\ method=\u041C\u0435\u0442\u043E\u0434 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly index 667e123f29eaf03ea62eccdf28b61f2aa63980c1..c06a9e1d3522a8a1c46e35b92566c13d88f9ed0c 100644 --- a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly +++ b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries.jelly @@ -47,9 +47,10 @@ THE SOFTWARE. + - + @@ -63,10 +64,11 @@ THE SOFTWARE. - + + - + - + diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_ru.properties b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_ru.properties index 453808d5bc19d6c3153049f616fc13d2d3b246be..5a6688a923fa90e62904606209384b35b2655074 100644 --- a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_ru.properties +++ b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_ru.properties @@ -20,14 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Master/Slave\ Support=\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u043b\u0430\u0432\u043d\u044b\u0439/\u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0439 Master=\u0413\u043b\u0430\u0432\u043d\u044b\u0439 Name=\u0418\u043c\u044f Description=\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 This\ Jenkins\ server=\u0421\u0435\u0440\u0432\u0435\u0440 Jenkins \#\ of\ executors=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432-\u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 Local\ FS\ root=\u041a\u043e\u0440\u0435\u043d\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0424\u0421 -Slaves=\u041f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u043d\u044b\u0435 Name\ is\ mandatory=\u0418\u043c\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044f \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043e Number\ of\ executors\ is\ mandatory.=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043e Remote\ root\ directory=\u041a\u043e\u0440\u0435\u043d\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0439 \u0424\u0421 diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_sr.properties b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..080510945b9c451fdab2b21ba227d1ce88edd614 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/DumbSlave/configure-entries_sr.properties @@ -0,0 +1,18 @@ +# This file is under the MIT License by authors + +Description=\u041E\u043F\u0438\u0441 +\#\ of\ executors=\u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 +Remote\ root\ directory=\u0423\u0434\u0430\u0459\u0435\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u043A\u043E\u0440\u0435\u043D\u0430 +Labels=\u041B\u0430\u0431\u0435\u043B\u0435 +Launch\ method=\u041C\u0435\u0442\u043E\u0434 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 +Availability=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0441\u0442 +Node\ Properties=\u041F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 +Master=\u0413\u043B\u0430\u0432\u043D\u0430 +Name=\u0418\u043C\u0435 +This\ Jenkins\ server=\u041E\u0432\u0430 Jenkins \u043C\u0430\u0448\u0438\u043D\u0430 +Local\ FS\ root=\u041A\u043E\u0440\u0435\u043D \u043B\u043E\u043A\u0430\u043B\u043D\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 +Name\ is\ mandatory=\u0418\u043C\u0435 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +Number\ of\ executors\ is\ mandatory.=\u0411\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +Remote\ directory\ is\ mandatory.=\u0423\u0434\u0430\u0459\u0435\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u043A\u043E\u0440\u0435\u043D\u0430 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +Usage=\u0423\u043F\u043E\u0442\u0440\u0435\u0431\u0430 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail.properties index 273ee6a2e6aea0fcac06dfdff86368f486b0cfac..70c380808ff77399815a4182564d0328627aa7fc 100644 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail.properties +++ b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail.properties @@ -21,7 +21,7 @@ # THE SOFTWARE. detail=\ - Adds a plain, dumb slave to Jenkins. This is called "dumb" because Jenkins doesn\u2019t provide \ - higher level of integration with these slaves, such as dynamic provisioning. \ - Select this type if no other slave types apply — for example such as when you are adding \ + Adds a plain, permanent agent to Jenkins. This is called "permanent" because Jenkins doesn\u2019t provide \ + higher level of integration with these agents, such as dynamic provisioning. \ + Select this type if no other agent types apply — for example such as when you are adding \ a physical computer, virtual machines managed outside Jenkins, etc. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_da.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_da.properties deleted file mode 100644 index 71e4c731a47a6948f3300f1e386d62af7c71aa0f..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_da.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -detail=Tilf\u00f8jer en almindelig dum slave til Jenkins. Disse slaver kaldes ''dumme'' da Jenkins ikke \ -tilbyder et h\u00f8jere niveau af kontrol over disse slaver, s\u00e5som dynamisk provisionering. \ -V\u00e6lg denne type hvis ingen anden slavetype passer — for eksempel hvis du \ -tilf\u00f8jer en fysisk computer/ virtuel maskine bestyret udenfor Jenkins, mv. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_de.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_de.properties deleted file mode 100644 index 0941e4501820a9e2c2a5293ab72f85e786407a3d..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_de.properties +++ /dev/null @@ -1,23 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -detail=F\u00FCgt einen einfachen, simplen Slave-Knoten hinzu. Der Knotentyp hei\u00DFt "dumb" (=einfach, simpel), da er \u00FCber keine enge Integration mit Jenkins verf\u00FCgt, wie etwa dynamische Aktualisierungen. Verwenden Sie diesen Knotentyp, wenn keine anderen Knotentypen passen — zum Beispiel wenn Sie einen real existierenden Rechner hinzuf\u00FCgen oder virtuelle Maschinen erg\u00E4nzen, die ausserhalb von Jenkins verwaltet werden, usw. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_es.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_es.properties index fee95acacc0fde8817efa09d30afe7957e46a453..97159a95122da634b740310e35c93251e4d7a2c4 100644 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_es.properties +++ b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_es.properties @@ -21,8 +21,8 @@ # THE SOFTWARE. detail=\ - Aadir un esclavo pasivo a Jenkins. Es llamado ''pasivo'' porque Jenkins no provee ningun tipo de \ - integracin de alto nivel con estos esclavos, como pueda ser aprovisionamiento dinmico. \ + Aadir un agente permanente a Jenkins. Es llamado ''permanente'' porque Jenkins no provee ningun tipo de \ + integracin de alto nivel con estos agentes, como pueda ser aprovisionamiento dinmico. \ Selecciona este tipo si no hay ningn otro tipo mas adecuado. Por ejemplo cuando se aaden \ maquinas fsicas o virtuales gestionadas desde fuera de Jenkins, etc. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_fr.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_fr.properties deleted file mode 100644 index 6aabb89a4ed8d1824d4ca5b8d519d029b92afba8..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_fr.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Eric Lefevre-Ardant -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -detail=\ - Ajoute un esclave simple Jenkins. Cet esclave est dit "passif" ("dumb") car Jenkins ne fournit pas \ - d''intgration d''un niveau plus lev pour ce type d''esclave, comme le provisioning dynamique. \ - Slectionnez ce type si aucun autre type d''esclave ne s''applique — par exemple quand vous \ - ajoutez un ordinateur physique, une machine virtuelle gre sparment de Jenkins, etc. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_ja.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_ja.properties deleted file mode 100644 index 9e288307c57f9653181670b65407baeb9ed1b9c5..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_ja.properties +++ /dev/null @@ -1,27 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -detail=\ - \u30B7\u30F3\u30D7\u30EB\u3067\u57FA\u672C\u7684\u306A\u6A5F\u80FD\u3060\u3051\u3092\u6301\u3064\u30B9\u30EC\u30FC\u30D6\u3092\u8FFD\u52A0\u3057\u307E\u3059\u3002\u51E6\u7406\u91CF\u306B\u5FDC\u3058\u3066\u52D5\u7684\u306B\u30B9\u30EC\u30FC\u30D6\u3092\u8FFD\u52A0\u3059\u308B\u3088\u3046\u306A\u3001\ - \u9AD8\u30EC\u30D9\u30EB\u306E\u6A5F\u80FD\u3092\u63D0\u4F9B\u3057\u306A\u3044\u305F\u3081"\u30C0\u30E0(dumb)"\u3068\u547C\u3070\u308C\u307E\u3059\u3002\ - \u30B3\u30F3\u30D4\u30E5\u30FC\u30BF\u30FC\u3082\u3057\u304F\u306F\u3001Jenkins\u304C\u7BA1\u7406\u3057\u306A\u3044\u4EEE\u60F3\u30DE\u30B7\u30F3\u3092\u8FFD\u52A0\u3059\u308B\u3088\u3046\u306A\u3068\u304D\u306B\u3001\u4ED6\u306E\u30B9\u30EC\u30FC\u30D6\u3092\u5229\u7528\u3067\u304D\u306A\u3051\u308C\u3070\u3001\ - \u3053\u306E\u30BF\u30A4\u30D7\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_pt_BR.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_pt_BR.properties deleted file mode 100644 index 7a0e6597c5a77e93f8a247b90fe2293b81311598..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_pt_BR.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva, Fernando Boaglio -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# \ -# Adds a plain, dumb slave to Jenkins. This is called "dumb" because Jenkins doesn''t provide \ -# higher level of integration with these slaves, such as dynamic provisioning. \ -# Select this type if no other slave types apply — for example such as when you are adding \ -# a physical computer, virtual machines managed outside Jenkins, etc. -detail=Adiciona um slave simples e burro ao Jenkins. \u00c9 chamado "burro" porque o Jenkins n\u00e3o prov\u00ea um maior n\u00edvel de integra\u00e7\u00e3o com estes slaves, como um provisionamento din\u00e2mico. Selecione este tipo se nenhum outro slave se aplica; por exemplo como quando voc\u00ea est\u00e1 adicionando um computador f\u00edsico, m\u00e1quinas virtuais gerenci\u00e1veis fora do Jenkins, etc. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_sr.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6b58ffb55f2387a366ba08dce5127f0f598b56bd --- /dev/null +++ b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +detail=\ +\u0414\u043E\u0434\u0430 \u043E\u0431\u0438\u0447\u0430\u043D, \u0442\u0440\u0430\u0458\u043D\u0438 \u0430\u0433\u0435\u043D\u0442 Jenkins-\u0443. \u0422\u0440\u0430\u0458\u043D\u043E \u0458\u0435 \u0437\u0430\u0448\u0442\u043E \u043D\u0435\u0434\u0430\u0458\u0435 \u0432\u0435\u045B\u0438 \u043D\u0438\u0432\u043E \u0438\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0458\u0435 \u0441\u0430 \u043E\u0432\u0438\u043C \u0430\u0433\u0435\u043D\u0442\u0438\u043C\u0430, \u043A\u0430\u043E \u0434\u0438\u043D\u0430\u043C\u0438\u0447\u043D\u043E \u0441\u043D\u0430\u0431\u0434\u0435\u0432\u0430\u045A\u0435. \u0418\u0437\u0430\u0431\u0435\u0440\u0438\u0442\u0435 \u043E\u0432\u043E \u0430\u043A\u043E \u0434\u0440\u0443\u0433\u0435 \u0432\u0440\u0441\u0442\u0435 \u0430\u0433\u0435\u043D\u0430\u0442\u0430 \u043D\u0435 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0430\u0458\u0443 — \u043D\u043F\u0440. \u043A\u0430\u0442 \u0434\u043E\u0434\u0430\u0458\u0435\u0442\u0435 \u0440\u0430\u0447\u0443\u043D\u0430\u0440 \u0438\u043B\u0438 \u0432\u0438\u0440\u0442\u0443\u0435\u043B\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 \u0441\u043F\u043E\u0459\u043E\u043C Jenkins-\u0430. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_sv_SE.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_sv_SE.properties deleted file mode 100644 index 08870374414d2d84ec3a124127816a6645d9f2ff..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_sv_SE.properties +++ /dev/null @@ -1,3 +0,0 @@ -# This file is under the MIT License by authors - -detail=L\u00E4gger till en normal dum slav till Jenkins. Denna kallas "dum" eftersom Jenkins inte tillhandah\u00E5ller en h\u00F6gniv\u00E5integrering med slavarna, s\u00E5som dynamisk provisionering. V\u00E4lj denna typ om inga andra slavtyper g\u00E5r att till\u00E4mpa – som t ex n\u00E4r du l\u00E4gger till en fysisk dator, virtuella maskiner som hanteras utanf\u00F6r Jenkins, osv. diff --git a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_zh_TW.properties b/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_zh_TW.properties deleted file mode 100644 index ea5e453e15851c7360af58f4434c94dc81f4eb70..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/DumbSlave/newInstanceDetail_zh_TW.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -detail=\ - \u65b0\u589e\u967d\u6625 Slave \u5230 Jenkins \u88e1\u3002\ - \u4e4b\u6240\u4ee5\u53eb\u505a\u300c\u967d\u6625\u300d\uff0c\u662f\u56e0\u70ba Jenkins \u6c92\u6709\u63d0\u4f9b\u9019\u985e Slave \u4e00\u4e9b\u9032\u968e\u6574\u5408\u529f\u80fd\uff0c\u4f8b\u5982\u52d5\u614b\u4f48\u5efa\u3002\ - \u6c92\u6709\u5176\u4ed6\u9069\u5408\u7684 Slave \u985e\u578b\u6642\u53ef\u4ee5\u4f7f\u7528\uff0c\u4f8b\u5982\u591a\u52a0\u4e86\u4e00\u90e8\u96fb\u8166\uff0c\u6216\u662f\u4e0d\u53d7 Jenkins \u7ba1\u7406\u7684\u865b\u64ec\u6a5f\u5668...\u3002 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config.jelly b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config.jelly index 9cd7fbc2e62435eea4c88448b14e1f1b1419eb8e..b2becef5dcbae82e4b2d81bc94e03c8c0480af7d 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config.jelly +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config.jelly @@ -24,13 +24,13 @@ THE SOFTWARE. - + - + - + diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ca.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ca.properties index 1c81470a77b6901969a22d007479a63166045e89..312c2fd01a5d5f2c5c30ded838e1c5b35fee9792 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ca.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ca.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -name=nom -value=valor +Name=nom +Value=valor diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_da.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_da.properties index c433ae0a8283f0b787d3f3b0789c1d4095603083..86e73838343fb23f0c5a23e58e18e70af065073a 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_da.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_da.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -name=navn -value=v\u00e6rdi -List\ of\ key-value\ pairs=Liste af n\u00f8gle-v\u00e6rdi par +Name=navn +Value=v\u00e6rdi +List\ of\ variables=Liste af n\u00f8gle-v\u00e6rdi par diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_de.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_de.properties index b5a66fb4912a6d9bc65a7d1e03d691b3ae2758d5..ccbb48667ec81422ff4b107d94ca690cde686cd9 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_de.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_de.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Liste der Schlssel/Wert-Paare -name=Name -value=Wert +List\ of\ variables=Liste der Variablen +Name=Name +Value=Wert diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es.properties index a490ffc34e43802560013be904a59464b81e183f..b0f51c8581bc34247add4e7c3188d68ffea359be 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Lista de nombre-valores -name=nombre -value=valor +List\ of\ variables=Lista de nombre-valores +Name=nombre +Value=valor diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es_AR.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es_AR.properties index c0989a3782f7782872b7f628d988a344137d295c..7ff0c10db68597b0ab9a2731aeab137691b01beb 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es_AR.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_es_AR.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -name=nombre -value=valor +Name=nombre +Value=valor diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fi.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fi.properties index 95f1c7a0dcb99ead2f3e30411f640d7b0f8a8498..5ee81b48f516ea68ed111b57ae00ad481f66a8d1 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fi.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fi.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Lista avain-arvo pareja -name=nimi -value=arvo +List\ of\ variables=Lista avain-arvo pareja +Name=nimi +Value=arvo diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fr.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fr.properties index 1512c60d9f95ce1b3c1edadc1313470ca78313a6..5c0bd6de9375bc5fb0df18ef2f4f42f3b597f661 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fr.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_fr.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Liste des paires cl-valeur -name=nom -value=valeur +List\ of\ variables=Liste des paires cl-valeur +Name=nom +Value=valeur diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_he.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_he.properties index d732df9452c0885f6fd4d03420653ec75064a7cf..fced55bf18541ccb917b1827139d628b5f52b026 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_he.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_he.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -List\ of\ key-value\ pairs=\u05E8\u05E9\u05D9\u05DE\u05D4 \u05E9\u05DC \u05E9\u05D3\u05D4-\u05E2\u05E8\u05DA -name=\u05E9\u05DD -value=\u05E2\u05E8\u05DA +List\ of\ variables=\u05E8\u05E9\u05D9\u05DE\u05D4 \u05E9\u05DC \u05E9\u05D3\u05D4-\u05E2\u05E8\u05DA +Name=\u05E9\u05DD +Value=\u05E2\u05E8\u05DA diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_it.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_it.properties index 155f8ee2f4234c347cb5aa37ccce62d751c4006c..becdcdad03241462274272b46658931da2c7dd0a 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_it.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_it.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -List\ of\ key-value\ pairs=Lista di coppie chiave-valore -name=nome -value=valore +List\ of\ variables=Lista di coppie chiave-valore +Name=nome +Value=valore diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ja.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ja.properties index c5a5bf79f8081ea9834bb01bab9bf9749ccd27e0..d4ee4ce65bfbf0f86c875c90211ab47ade28e75a 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ja.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ja.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=\u30AD\u30FC\u3068\u5024\u306E\u30EA\u30B9\u30C8 -name=\u30AD\u30FC -value=\u5024 +List\ of\ variables=\u30AD\u30FC\u3068\u5024\u306E\u30EA\u30B9\u30C8 +Name=\u30AD\u30FC +Value=\u5024 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ko.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ko.properties index 328e56c2d4dbf58ad9f613b059093382a29ee648..3118f5607d5cdd329ece03f7d20c00ce1197acc5 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ko.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ko.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -List\ of\ key-value\ pairs=\uD0A4-\uAC12 \uBAA9\uB85D -name=\uC774\uB984 -value=\uAC12 +List\ of\ variables=\uD0A4-\uAC12 \uBAA9\uB85D +Name=\uC774\uB984 +Value=\uAC12 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_lt.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_lt.properties index 106fcf98020beddd716dfc35c46f2e7852dc85dc..9c2b27879ab93369e39202435fba7c5798e798e9 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_lt.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_lt.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -name=pavadinimas -value=reik\u0161m\u0117 +Name=pavadinimas +Value=reik\u0161m\u0117 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nb_NO.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nb_NO.properties index 934d2f3a66fcc9a82532f41136d38324cf6df1bf..63f92aa21357edb88e8ac5cf50f1e25d342e7d06 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nb_NO.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nb_NO.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Liste over n\u00F8kkel-verdi par -name=N\u00F8kkel -value=Verdi +List\ of\ variables=Liste over n\u00F8kkel-verdi par +Name=N\u00F8kkel +Value=Verdi diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nl.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nl.properties index ccdff27ce16fc33c44a4f4723c658f5d928d98d9..47de859a2bf1bee4901c661a05209ecf73e2cf42 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nl.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_nl.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Lijst van sleutel-waarde-paren -name=naam -value=waarde +List\ of\ variables=Lijst van sleutel-waarde-paren +Name=naam +Value=waarde diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pl.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pl.properties index 6590886f6c3cf0de82ad77d734e7ebde83daa66e..7774f0d27f61cc629dc14568d871c7ff654245b9 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pl.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pl.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -List\ of\ key-value\ pairs=Lista par klucz-warto\u015B\u0107 -name=nazwa -value=warto\u015B\u0107 +List\ of\ variables=Lista par klucz-warto\u015B\u0107 +Name=nazwa +Value=warto\u015B\u0107 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_BR.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_BR.properties index c1c03bf6e81b8bc2fd296b51e053b4730c859cf2..4d580ac490070e92059698ebf01af0fc478b1216 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_BR.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -value=valor -name=nome -List\ of\ key-value\ pairs=Lista de pares de chave-valor +Value=valor +Name=nome +List\ of\ variables=Lista de pares de chave-valor diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_PT.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_PT.properties index 7454a85ecc1619672586a1ff29f4604030b9c50b..a1bab80dd3eae8424359c599e1409085ea70dec2 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_PT.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_pt_PT.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -List\ of\ key-value\ pairs=Lista de pares chave-valor -name=nome -value=valor +List\ of\ variables=Lista de pares chave-valor +Name=nome +Value=valor diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ru.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ru.properties index 369f0bf0333ac8b8c292e913ac2e38ad6c16372d..bdb277f7a12eba9a8d7d51dd68e58a366311ba43 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ru.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_ru.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=\u0421\u043F\u0438\u0441\u043E\u043A \u043F\u0430\u0440 "\u043A\u043B\u044E\u0447-\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435" -name=\u0438\u043C\u044F -value=\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 +List\ of\ variables=\u0421\u043F\u0438\u0441\u043E\u043A \u043F\u0430\u0440 "\u043A\u043B\u044E\u0447-\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435" +Name=\u0438\u043C\u044F +Value=\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sk.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sk.properties index 7cbfa3b0551e7f01f1b39a66ac528054574befa1..5d8d7592e304a403b8520fc14a592ba1d6bfd6a0 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sk.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sk.properties @@ -1,5 +1,5 @@ # This file is under the MIT License by authors -List\ of\ key-value\ pairs=Zoznam p\u00E1rov k\u013E\u00FA\u010D - hodnota -name=k\u013E\u00FA\u010D -value=hodnota +List\ of\ variables=Zoznam p\u00E1rov k\u013E\u00FA\u010D - hodnota +Name=k\u013E\u00FA\u010D +Value=hodnota diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sr.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a656ba685a96f4f732f557b722f37d24f19780cd --- /dev/null +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +List\ of\ variables=\u0421\u043F\u0438\u0441\u0430\u043A \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 +Name=\u0418\u043C\u0435 +Value=\u0412\u0440\u0435\u0434\u043D\u043E\u0441\u0442 diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sv_SE.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sv_SE.properties index 89f32c98c574f80e39ab8288e09cf511641a1676..2c29646a5c9e13d17116f981f9f55e117e175a9d 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sv_SE.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_sv_SE.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Lista p\u00E5 nyckel-v\u00E4rde par -name=namn -value=v\u00E4rde +List\ of\ variables=Lista p\u00E5 nyckel-v\u00E4rde par +Name=namn +Value=v\u00E4rde diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_CN.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_CN.properties index 3d6d6b76d85e84db99919385e6c87e10b4477e9b..e70d102c3c05bc4a0c620292d2b83c3f6b34bb8d 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_CN.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_CN.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=\u952E\u503C\u5BF9\u5217\u8868 -name=\u952E -value=\u503c +List\ of\ variables=\u952E\u503C\u5BF9\u5217\u8868 +Name=\u952E +Value=\u503c diff --git a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_TW.properties b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_TW.properties index 7176ec4fa6182791a0c86dae55170ac24a28dfbc..ad09037b0f8e56686241b3e4b2db542bc6e5cf01 100644 --- a/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_TW.properties +++ b/core/src/main/resources/hudson/slaves/EnvironmentVariablesNodeProperty/config_zh_TW.properties @@ -21,6 +21,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -List\ of\ key-value\ pairs=Key-Value \u5c0d\u61c9\u6e05\u55ae -name=\u540d\u7a31 -value=\u503c +List\ of\ variables=Key-Value \u5c0d\u61c9\u6e05\u55ae +Name=\u540d\u7a31 +Value=\u503c diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/config_sr.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f33e2853a0de8ed3b651a8b914f2f3ba5b5f6849 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Tunnel\ connection\ through=\u041F\u043E\u0432\u0435\u0436\u0438 \u043F\u043E\u043C\u043E\u045B\u0435\u043C \u0442\u0443\u043D\u0435\u043B\u0430 +JVM\ options=JVM \u043E\u043F\u0446\u0438\u0458\u0435 diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html index a790e8cb3c2a4d2f653aada47322d6ec3c9d6a1d..085afd9482112d1e404f3e1f2f07bf1a2682d515 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs.html @@ -1,5 +1,5 @@
    - If the slave JVM should be launched with additional VM arguments, such as "-Xmx256m", + If the agent JVM should be launched with additional VM arguments, such as "-Xmx256m", specify those here. List of all the options are available here.
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_de.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_de.html deleted file mode 100644 index cba877b87d5bbf6f2d1dfde691588949c996dd19..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_de.html +++ /dev/null @@ -1,5 +0,0 @@ -
    - Soll die Slave-JVM mit zusätzlichen VM-Argumenten gestartet werden, z.B. "-Xmx256m", - können Sie diese hier angeben. Eine Liste aller unterstützten Optionen finden Sie - hier. -
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_zh_TW.html b/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_zh_TW.html deleted file mode 100644 index c60736e61b84f4f335ee15215d1a6dd8fdf2dac5..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help-vmargs_zh_TW.html +++ /dev/null @@ -1,4 +0,0 @@ -
    - 要是 Slave JVM 啟動時需要指定 "-Xmx256m" 這類額外的 VM 參數,可以在這裡設定。 - 在這裡可以看到所有選項。 -
    \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties index b0c7d4df397006357fab55c274c84e5010293562..6d4dfb1b47a9e8c4d228d078ebac2ea2921e4f2f 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help.properties @@ -20,7 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blurb=Starts a slave by launching an agent program through JNLP. \ - The launch in this case is initiated by the slave, \ - thus slaves need not be IP reachable from the master (e.g. behind the firewall.) \ - It is still possible to start a launch without GUI, for example as a Windows service. \ No newline at end of file +blurb=Allows an agent to be launched using Java Web Start.
    \ + In this case, a JNLP file must be opened on the agent machine, which will \ + establish a TCP connection to the Jenkins master.
    \ + This means that the agent need not be reachable from the master; the agent \ + just needs to be able to reach the master. If you have enabled security via \ + the Configure Global Security page, you can customise the port on \ + which the Jenkins master will listen for incoming JNLP agent connections.
    \ + By default, the JNLP agent will launch a GUI, but it's also possible to run \ + a JNLP agent without a GUI, e.g. as a Window service. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_da.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_da.properties deleted file mode 100644 index 9a21976acd5d5bc58540cc5ff84d307d7180dd34..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_da.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Starter en slave via et agentprogram gennem JNLP. \ -Slave opstarten bliver i dette tilf\u00e6lde initieret af slaven, \ -s\u00e5ledes beh\u00f8ver slaven i dette tilf\u00e6lde ikke at v\u00e6re IP tilg\u00e6ngelig fra master''en (f.eks. bag en firewall.) \ -Det er ogs\u00e5 her muligt at starte slaven uden GUI, for eksempel som en Windows service. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties index 76bb39241adc9160114a1bfbb2b96e80eb0233f7..26aee9fd3a1fb2bf83bcab1b346fe4dd540dd0ea 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_es.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -blurb=Arranca un esclavo ejecutando un programa agente usando JNLP.\ - De modo que el esclavo inicia la ejecucin, por lo que los esclavos no necesitan una IP accesible desde el master. \ +blurb=Arranca un agente haciendo uso de JNLP.\ + De modo que el agente inicia la ejecucin, por lo que los agentes no necesitan una IP accesible desde el master. \ Incluso es posible arrancar una ejecucin sin GUI, como puede ser un servicio Windows. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_fr.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_fr.properties deleted file mode 100644 index 796bd6c0064f51289b45bc032159923f40f8ca16..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_fr.properties +++ /dev/null @@ -1,26 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe, Eric Lefevre-Ardant -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=Lance un esclave en dmarrant un agent par JNLP. \ - Le lancement dans ce cas est initi par l''esclave ; \ - ainsi, les esclaves n''ont pas besoin d''tre accessibles par IP par la machine matre (par exemple s''ils sont derrire un firewall.) \ - Il reste possible de lancer un dmarrage sans GUI, par exemple par un service Windows. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_ja.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_ja.properties deleted file mode 100644 index 6318fac04eb15e690d90a1a0e450a4765627102c..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_ja.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=JNLP\u7D4C\u7531\u3067\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30D7\u30ED\u30B0\u30E9\u30E0\u3092\u5B9F\u884C\u3059\u308B\u3053\u3068\u3067\u30B9\u30EC\u30FC\u30D6\u3092\u8D77\u52D5\u3057\u307E\u3059\u3002\ - \u3053\u306E\u5834\u5408\u8D77\u52D5\u306F\u30B9\u30EC\u30FC\u30D6\u304B\u3089\u958B\u59CB\u3059\u308B\u306E\u3067\u3001\u30B9\u30EC\u30FC\u30D6\u306F\u30DE\u30B9\u30BF\u304B\u3089IP\u30EA\u30FC\u30C1\u30E3\u30D6\u30EB\u3067\u3042\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093(\u4F8B \u30D5\u30A1\u30A4\u30A2\u30FC\u30A6\u30A9\u30FC\u30EB\u306E\u4E2D\u306A\u3069)\u3002\ - \u4F8B\u3048\u3070Windows\u30B5\u30FC\u30D3\u30B9\u306A\u3069\u3001GUI\u306A\u3057\u3067\u3082\u8D77\u52D5\u3059\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u3059\u3002 diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_pt_BR.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_pt_BR.properties deleted file mode 100644 index 7aee9cf2b8d5b1554154435be65ced2328512d1b..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_pt_BR.properties +++ /dev/null @@ -1,31 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva, Fernando Boaglio -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# Starts a slave by launching an agent program through JNLP. \ -# The launch in this case is initiated by the slave, \ -# thus slaves need not be IP reachable from the master (e.g. behind the firewall.) \ -# It is still possible to start a launch without GUI, for example as a Windows service. -blurb=Iniciar um slave pelo programa agente JNLP. \ - Nesse caso, o lan\u00e7amento \u00e9 iniciado pelo slave, \ - porem o endere\u00e7o IP do Slave precisa ser alcan\u00e7avel pelo master (ex.: firewall ou proxy), - Tamb\u00e9m \u00e9 possivel lan\u00e7ar sem GUI, por exemplo como um servi\u00e7o do Windows. - diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_sr.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..fba74a2438d697f47ff671f19b8d3f06b9aad048 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_sr.properties @@ -0,0 +1,11 @@ +# This file is under the MIT License by authors + +blurb=\u041E\u043C\u043E\u0433\u0443\u045B\u0430\u0432\u0430 \u0434\u0430 \u0441\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0435 \u0430\u0433\u0435\u043D\u0442 \u043F\u0440\u0435\u043A\u043E Java Web Start.
    \ + \u0423 \u0442\u043E\u043C \u0441\u043B\u0443\u0447\u0430\u0458\u0443, JNLP \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043E\u0442\u0432\u043E\u0440\u0435\u043D\u0430 \u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0438 \u0430\u0433\u0435\u043D\u0442\u0430, \u043A\u043E\u0458\u0430 \u045B\u0435 \u0431\u0438\u0442\u0438 \ + \u043F\u043E\u0432\u0435\u0436\u0435\u043D\u0430 TCP \u0432\u0435\u0437\u043E\u043C \u043D\u0430 Jenkins \u043C\u0430\u0441\u0442\u0435\u0440.
    \ + \u0410\u0433\u0435\u043D\u0442 \u043D\u0435 \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u0434\u043E\u0441\u0442\u0443\u043F\u0430\u043D \u043C\u0430\u0441\u0442\u0435\u0440\u043E\u043C; \u0430\u0433\u0435\u043D\u0442 \ + \u0458\u0435\u0434\u0438\u043D\u043E \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u0443 \u0441\u0442\u0430\u045A\u0443 \u0434\u0430 \u043D\u0430\u0452\u0435 \u043C\u0430\u0441\u0442\u0435\u0440\u0430. \u0410\u043A\u043E \u0441\u0442\u0435 \u043E\u043C\u043E\u0433\u0443\u045B\u0438\u043B\u0438 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u0438 \u0440\u0435\u0436\u0438\u043C \ + \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438 \u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442\u0438, \u043C\u043E\u0436\u0435\u0442\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438 \u043F\u043E\u0440\u0442 \u043F\u0440\u0435\u043A\u043E \ + \u043A\u043E\u0458\u0435 \u045B\u0435 \u043C\u0430\u0441\u0442\u0435\u0440 Jenkins \u043C\u0430\u0448\u0438\u043D\u0430 \u0441\u043B\u0443\u0448\u0430\u0442\u0438 \u0437\u0430 \u0434\u043E\u043B\u0430\u0437\u0435\u045B\u0435 JNLP \u0432\u0435\u0437\u0435.
    \ + JNLP \u0430\u0433\u0435\u043D\u0442 \u045B\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u043A\u0438 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0458\u0441, \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043C\u043E\u0433\u0443\u045B\u0435 \u0458\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0438 \ + JNLP \u0430\u0433\u0435\u043D\u0442\u0430 \u0431\u0435\u0437 \u0433\u0440\u0430\u0444\u0438\u0447\u043A\u043E\u0433 \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0438\u0458\u0441\u0430, \u043D\u043F\u0440. \u043A\u0430\u043E Windows \u0441\u0435\u0440\u0432\u0438\u0441. \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_zh_TW.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/help_zh_TW.properties deleted file mode 100644 index 19db6e81fff70bda6de1a97642bf2032e3591ab9..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/help_zh_TW.properties +++ /dev/null @@ -1,25 +0,0 @@ -# The MIT License -# -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -blurb=\u900f\u904e JNLP \u555f\u52d5 Slave \u4ee3\u7406\u7a0b\u5f0f\u3002\ - \u7531 Slave \u4e3b\u52d5\u7684\u555f\u52d5\u65b9\u5f0f\uff0cMaster \u4e0d\u7528\u76f4\u63a5 IP \u9023\u7dda\u5230 Slave (\u4f8b\u5982\u5728\u9632\u706b\u7246\u5f8c)\u3002\ - \u9019\u7a2e\u65b9\u5f0f\u4e00\u6a23\u53ef\u4ee5\u4e0d\u900f\u904e GUI \u555f\u52d5\uff0c\u4f8b\u5982\u5b89\u88dd\u6210 Windows \u670d\u52d9\u3002 diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly index 1e99285e5ce8366044bc2d1eb71203a80ab74afc..e371a9b040e61d23d5e449d0d08f2bae75863cb7 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.jelly @@ -34,7 +34,7 @@ THE SOFTWARE.

    - ${%Connect slave to Jenkins one of these ways:} + ${%Connect agent to Jenkins one of these ways:}

    • @@ -42,20 +42,20 @@ THE SOFTWARE. ${%launch agent} - ${%Launch agent from browser on slave} + ${%Launch agent from browser}

    • - ${%Run from slave command line:} + ${%Run from agent command line:}

      javaws ${h.inferHudsonURL(request)}${it.url}slave-agent.jnlp
    • - ${%Or if the slave is headless:} + ${%Or if the agent is headless:}

      java${it.launcher.vmargs == null ? '' : ' ' + it.launcher.vmargs} -jar slave.jar -jnlpUrl ${h.inferHudsonURL(request)}${it.url}slave-agent.jnlp
    • @@ -63,7 +63,7 @@ THE SOFTWARE.
    • - ${%Run from slave command line:} + ${%Run from agent command line:}

      java${it.launcher.vmargs == null ? '' : ' ' + it.launcher.vmargs} -jar slave.jar -jnlpUrl ${h.inferHudsonURL(request)}${it.url}slave-agent.jnlp -secret ${it.jnlpMac}
      diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties index b73c1bc2b2dafe03dda0e76910b6fda1c4d6d4b1..d4770fa4c753c1851274433880fc0bf6667d86f7 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -slaveAgentPort.disabled=TCP port for JNLP slave agents is disabled. configure.link.text=Go to security configuration screen and change it diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_da.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_da.properties index af983756bd328c28a0db5cc16bed5eceece40878..e34b1b1c5354e987b3bb11fec330a267abbc334e 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_da.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_da.properties @@ -20,10 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways\:=Forbind Jenkins til slaver p\u00e5 en af f\u00f8lgende m\u00e5der: launch\ agent=start agent Connected\ via\ JNLP\ agent.=Forbundet via JNLP agent. -Or\ if\ the\ slave\ is\ headless\:=Eller hvis slaven er hovedl\u00f8s: -Run\ from\ slave\ command\ line\:=K\u00f8r fra slavens kommandolinje: -slaveAgentPort.disabled=TCP port for JNLP slave agent er sl\u00e5et fra. -Launch\ agent\ from\ browser\ on\ slave=Start agent fra browser p\u00e5 slaven diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_de.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_de.properties index c3c9a4be4a06b6628c5c881d1ee39b340cd4c6f8..80908374b09993a1b8c3b804568b29099f950487 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_de.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_de.properties @@ -20,11 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -slaveAgentPort.disabled=TCP-Port fr JNLP-Slaves ist deaktiviert. configure.link.text=Zur globalen Sicherheitskonfiguration wechseln und ndern -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways\:=Der Slave kann eine Verbindung zum Jenkins-Master mit einer der folgenden Mglichkeiten aufbauen: launch\ agent=Agent starten -Launch\ agent\ from\ browser\ on\ slave=Agent aus einem Webbrowser auf den Slave starten -Run\ from\ slave\ command\ line\:=Agent aus der Kommandozeile heraus starten: -Or\ if\ the\ slave\ is\ headless\:=Oder falls der Slave keine GUI anbietet ("headless"-Modus): Connected\ via\ JNLP\ agent.=Verbunden ber JNLP-Agent. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_es.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_es.properties index b47a4cb7bde055d96b82114412aa7523184cef73..390cf03a391b488ce4a606b0694d9506ca6421e3 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_es.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_es.properties @@ -20,11 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -slaveAgentPort.disabled=El puerto TCP para los agentes esclavos via JNLP est deshabilitado. +slaveAgentPort.disabled=El puerto TCP para los agentes via JNLP est deshabilitado. launch\ agent=Lanzar agente -Or\ if\ the\ slave\ is\ headless\:=O si el esclavo no tiene pantalla -Run\ from\ slave\ command\ line\:=Ejecutar desde la lnea de comandos del esclavo -Launch\ agent\ from\ browser\ on\ slave=Lanzar el agente desde el navegador en el esclavo -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways\:=Conectar el esclavo a Jenkins usando uno de estos mtodos +Or\ if\ the\ agent\ is\ headless\:=O si el agente no tiene pantalla +Run\ from\ agent\ command\ line\:=Ejecutar agente desde la lnea de comandos del nodo +Launch\ agent\ from\ browser=Lanzar el agente desde el navegador en el nodo +Connect\ agent\ to\ Jenkins\ one\ of\ these\ ways\:=Conectar el agente a Jenkins usando uno de estos mtodos Connected\ via\ JNLP\ agent.=Conectado a travs del agente JNLP diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_fr.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_fr.properties index d8483c0298cfd237766a818dded97e6a54d43378..e0bca578cf312f99aface6dc7f5d4e714bb33934 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_fr.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_fr.properties @@ -20,9 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -slaveAgentPort.disabled=Le port TCP pour l''esclave JNLP est d\u00E9sactiv\u00E9. -Launch\ agent\ from\ browser\ on\ slave=Lancer l''agent \u00E0 partir du navigateur sur l''esclave -Run\ from\ slave\ command\ line:=Ex\u00E9cuter l''esclave \u00E0 partir de l\u2019interpr\u00E8te de commandes +Run\ from\ agent\ command\ line:=Ex\u00E9cuter l''esclave \u00E0 partir de l\u2019interpr\u00E8te de commandes launch\ agent=lancer l''agent -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways:=Connecter l''esclave \u00E0 Jenkins avec l''une des mani\u00E8res suivantes: +Connect\ agent\ to\ Jenkins\ one\ of\ these\ ways:=Connecter l''esclave \u00E0 Jenkins avec l''une des mani\u00E8res suivantes: Connected\ via\ JNLP\ agent.=Connect\u00E9 via l\u2019agent JNLP. diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ja.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ja.properties index 224e55109519603cb861184b75a51f7425811310..49e9af614f09ac63ebe9e7544d5f7779cd0d886c 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ja.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ja.properties @@ -20,11 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -slaveAgentPort.disabled=JNLP\u30b9\u30ec\u30fc\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u7528\u306eTCP\u30dd\u30fc\u30c8\u306f\u4f7f\u7528\u3067\u304d\u307e\u305b\u3093\u3002 -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways\:=\u6b21\u306e\u3044\u305a\u308c\u304b\u306e\u65b9\u6cd5\u3067\u30b9\u30ec\u30fc\u30d6\u3092Jenkins\u306b\u63a5\u7d9a\u3057\u307e\u3059\u3002 launch\ agent=\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u306e\u8d77\u52d5 -Launch\ agent\ from\ browser\ on\ slave=\u30b9\u30ec\u30fc\u30d6\u4e0a\u306e\u30d6\u30e9\u30a6\u30b6\u304b\u3089\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u3092\u8d77\u52d5 -Run\ from\ slave\ command\ line\:=\u30b9\u30ec\u30fc\u30d6\u3067\u30b3\u30de\u30f3\u30c9\u30e9\u30a4\u30f3\u304b\u3089\u8d77\u52d5: -Or\ if\ the\ slave\ is\ headless\:=\u3082\u3057\u304f\u306f\u3001\u30b9\u30ec\u30fc\u30d6\u3067X\u304c\u8d77\u52d5\u3057\u3066\u3044\u306a\u3044\u5834\u5408: Connected\ via\ JNLP\ agent.=JNLP\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u7d4c\u7531\u3067\u63a5\u7d9a -configure.link.text=\u30b0\u30ed\u30fc\u30d0\u30eb\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u8a2d\u5b9a\u30da\u30fc\u30b8\u3067\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \ No newline at end of file +configure.link.text=\u30b0\u30ed\u30fc\u30d0\u30eb\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u306e\u8a2d\u5b9a\u30da\u30fc\u30b8\u3067\u5909\u66f4\u3057\u3066\u304f\u3060\u3055\u3044\u3002 diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties index a20ddaa4b963ff0478a2d0510dd2b08ec06f9f6f..af9f3c2747aa242b72047ca0921c064994365d65 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_pt_BR.properties @@ -20,13 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Or\ if\ the\ slave\ is\ headless\:=Ou, se o slave \u00e9 sem master -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways\:=Conecta slave ao Jenkins por uma dessas maneiras: -Run\ from\ slave\ command\ line\:=Executar comando de linha pelo slave launch\ agent=Lan\u00e7ar agente # TCP port for JNLP slave agents is disabled. slaveAgentPort.disabled=Porta TCP para JNLP est\u00e1 desativada -Launch\ agent\ from\ browser\ on\ slave=Lan\u00e7ar agente de um navegador do slave Connected\ via\ JNLP\ agent.=Conectado via JNLP agente. # Go to security configuration screen and change it configure.link.text=V\u00e1 para a p\u00e1gina de configura\u00e7\u00e3o de seguran\u00e7a para alterar diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ru.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ru.properties index ce15ab9cf4ab408fe262b9615c0141c9dfa0371f..0fc4329cd29aadfb7d1a4b6c657d4b8836a03517 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ru.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_ru.properties @@ -20,8 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways:=\u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C slave \u043A Jenkins \u043E\u0434\u043D\u0438\u043C \u0438\u0437 \u0441\u043F\u043E\u0441\u043E\u0431\u043E\u0432: Connected\ via\ JNLP\ agent.=\u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D \u0447\u0435\u0440\u0435\u0437 JNLP \u0430\u0433\u0435\u043D\u0442\u0430. -Launch\ agent\ from\ browser\ on\ slave=\u0417\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0430\u0433\u0435\u043D\u0442\u0430 \u0438\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043D\u0430 slave -Run\ from\ slave\ command\ line:=\u0412\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u0432 \u043A\u043E\u043C\u043C\u0430\u043D\u0434\u043D\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u043E\u0434\u0447\u0438\u043D\u0435\u043D\u043D\u043E\u0433\u043E \u0443\u0437\u043B\u0430 +Run\ from\ agent\ command\ line:=\u0412\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u0432 \u043A\u043E\u043C\u043C\u0430\u043D\u0434\u043D\u043E\u0439 \u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u043E\u0434\u0447\u0438\u043D\u0435\u043D\u043D\u043E\u0433\u043E \u0443\u0437\u043B\u0430 launch\ agent=\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0430\u0433\u0435\u043D\u0442\u0430 diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_sr.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c3626b46510ecb0ca7ff43b93ff7770cd3387cb0 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +slaveAgentPort.disabled=\u041F\u043E\u0440\u0442 TCP \u0437\u0430 JNLP \u0458\u0435 \u0437\u0430\u0442\u0432\u043E\u0440\u0435\u043D +configure.link.text=\u0418\u0442\u0438\u0442\u0435 \u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u0437\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442\u0438 \u0438 \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0435 \u0433\u0430 +Connect\ agent\ to\ Jenkins\ one\ of\ these\ ways\:=\u041F\u043E\u0432\u0435\u0436\u0438\u0442\u0435 \u0441\u0435 \u0441\u0430 Jenkins-\u043E\u043C \u043F\u0443\u0442\u0435\u043C: +launch\ agent=\u043F\u043E\u043A\u0440\u0435\u043D\u0438 \u0430\u0433\u0435\u043D\u0442\u0430 +Launch\ agent\ from\ browser=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0441\u0430 \u0432\u0435\u0431-\u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447\u0430 +Run\ from\ agent\ command\ line\:=\u0418\u0437\u0432\u0440\u0448\u0438 \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435: +Or\ if\ the\ agent\ is\ headless\:=\u0418\u043B\u0438, \u0430\u043A\u043E \u0430\u0433\u0435\u043D\u0442 \u043D\u0435 \u0438\u043C\u0430 \u0435\u043A\u0440\u0430\u043D\u0430 +Connected\ via\ JNLP\ agent.=\u041F\u043E\u0432\u0435\u0437\u0430\u043D\u043E \u043F\u0443\u0442\u0435\u043C JNLP \u0430\u0433\u0435\u043D\u0442\u0430. +Run\ from\ agent\ command\ line=\u0418\u0437\u0432\u0440\u0448\u0438 \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 +Connect\ agent\ to\ Jenkins\ one\ of\ these\ ways=\u041F\u043E\u0432\u0435\u0436\u0438\u0442\u0435 \u0441\u0435 \u0441\u0430 Jenkins-\u043E\u043C \u043F\u0443\u0442\u0435\u043C diff --git a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_zh_TW.properties b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_zh_TW.properties index 821a4ee9cbc68d6d8a47f708d5a714d7ab964150..7c50bf1b268182bc26ff1e28ab478e7b04300257 100644 --- a/core/src/main/resources/hudson/slaves/JNLPLauncher/main_zh_TW.properties +++ b/core/src/main/resources/hudson/slaves/JNLPLauncher/main_zh_TW.properties @@ -20,10 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -slaveAgentPort.disabled=JNLP Slave \u4ee3\u7406\u7a0b\u5f0f\u7684 TCP \u9023\u63a5\u57e0\u5df2\u95dc\u9589\u3002 -Connect\ slave\ to\ Jenkins\ one\ of\ these\ ways\:=\u53ef\u4ee5\u7528\u4e0b\u9762\u9019\u4e9b\u65b9\u6cd5\u5c07 Slave \u9023\u5230 Jenkins: launch\ agent=\u555f\u52d5\u4ee3\u7406\u7a0b\u5f0f -Launch\ agent\ from\ browser\ on\ slave=\u5728 Slave \u7684\u700f\u89bd\u5668\u4e0a\u555f\u52d5\u4ee3\u7406\u7a0b\u5f0f -Run\ from\ slave\ command\ line\:=\u7531 Slave \u547d\u4ee4\u5217\u57f7\u884c: -Or\ if\ the\ slave\ is\ headless\:=\u5982\u679c Slave \u6c92\u6709\u5468\u908a: Connected\ via\ JNLP\ agent.=\u5C07\u7531 JNLP \u4EE3\u7406\u7A0B\u5F0F\u5EFA\u7ACB\u9023\u7DDA\u3002 diff --git a/core/src/main/resources/hudson/slaves/Messages.properties b/core/src/main/resources/hudson/slaves/Messages.properties index 7f55e6ed669140795fd40bc02f98f698c422b158..4d270b626b474f0e9666f1d5abca7ec057346cdf 100644 --- a/core/src/main/resources/hudson/slaves/Messages.properties +++ b/core/src/main/resources/hudson/slaves/Messages.properties @@ -20,24 +20,25 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -RetentionStrategy.Always.displayName=Keep this slave on-line as much as possible -RetentionStrategy.Demand.displayName=Take this slave on-line when in demand and off-line when idle +RetentionStrategy.Always.displayName=Keep this agent online as much as possible +RetentionStrategy.Demand.displayName=Take this agent online when in demand, and offline when idle RetentionStrategy.Demand.OfflineIdle=Offline because computer was idle; it will be relaunched when needed. -CommandLauncher.displayName=Launch slave via execution of command on the Master -JNLPLauncher.displayName=Launch slave agents via Java Web Start -ComputerLauncher.unexpectedError=Unexpected error in launching a slave. This is probably a bug in Jenkins -ComputerLauncher.abortedLaunch=Launching slave process aborted. +CommandLauncher.displayName=Launch agent via execution of command on the master +JNLPLauncher.displayName=Launch agent via Java Web Start +ComputerLauncher.unexpectedError=Unexpected error in launching an agent. This is probably a bug in Jenkins +ComputerLauncher.abortedLaunch=Launching agent process aborted. CommandLauncher.NoLaunchCommand=No launch command specified ConnectionActivityMonitor.OfflineCause=Repeated ping attempts failed -DumbSlave.displayName=Dumb Slave +DumbSlave.displayName=Permanent Agent NodeProvisioner.EmptyString= -OfflineCause.LaunchFailed=This node is offline because Jenkins failed to launch the slave agent on it. +OfflineCause.LaunchFailed=This agent is offline because Jenkins failed to launch the agent process on it. OfflineCause.connection_was_broken_=Connection was broken: {0} SimpleScheduledRetentionStrategy.FinishedUpTime=Computer has finished its scheduled uptime -SimpleScheduledRetentionStrategy.displayName=Take this slave on-line according to a schedule +SimpleScheduledRetentionStrategy.displayName=Take this agent online according to a schedule EnvironmentVariablesNodeProperty.displayName=Environment variables SlaveComputer.DisconnectedBy=Disconnected by {0}{1} NodeDescripter.CheckName.Mandatory=Name is mandatory ComputerLauncher.NoJavaFound=Java version {0} was found but 1.6 or later is needed. ComputerLauncher.JavaVersionResult={0} -version returned {1}. ComputerLauncher.UknownJavaVersion=Couldn\u2019t figure out the Java version of {0} +Cloud.ProvisionPermission.Description=Provision new nodes diff --git a/core/src/main/resources/hudson/slaves/Messages_bg.properties b/core/src/main/resources/hudson/slaves/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..6d537b2277f9a2ac10b1d815f296692659eb5b40 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/Messages_bg.properties @@ -0,0 +1,74 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +RetentionStrategy.Demand.OfflineIdle=\ + \u041d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u0437\u0430\u0449\u043e\u0442\u043e \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u0431\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0430. \u0429\u0435 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442. +CommandLauncher.NoLaunchCommand=\ + \u041d\u0435 \u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0437\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435. +ConnectionActivityMonitor.OfflineCause=\ + \u041c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u0438\u0442\u0435 \u043e\u043f\u0438\u0442\u0438 \u0437\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u0447\u0440\u0435\u0437 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eping\u201c \u0441\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438 +NodeProvisioner.EmptyString=\ + +OfflineCause.connection_was_broken_=\ + \u0412\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u0431\u0435 \u043f\u0440\u0435\u043a\u044a\u0441\u043d\u0430\u0442\u0430: {0} +SimpleScheduledRetentionStrategy.FinishedUpTime=\ + \u041a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u044a\u0442 \u043f\u0440\u0438\u0432\u044a\u0440\u0448\u0438 \u043f\u043b\u0430\u043d\u0438\u0440\u0430\u043d\u043e\u0442\u043e \u0432\u0440\u0435\u043c\u0435 \u0437\u0430 \u0440\u0430\u0431\u043e\u0442\u0430 +EnvironmentVariablesNodeProperty.displayName=\ + \u041f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0438 \u043d\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430 +SlaveComputer.DisconnectedBy=\ + \u0412\u0440\u044a\u0437\u043a\u0430\u0442\u0430 \u0431\u0435 \u043f\u0440\u0435\u043a\u044a\u0441\u043d\u0430\u0442\u0430 \u043e\u0442 \u201e{0}{1}\u201c +NodeDescripter.CheckName.Mandatory=\ + \u0418\u043c\u0435\u0442\u043e \u0435 \u0437\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e +ComputerLauncher.NoJavaFound=\ + \u041e\u0442\u043a\u0440\u0438\u0442\u0430 \u0431\u0435 \u0432\u0435\u0440\u0441\u0438\u044f \u201e{0}\u201c \u043d\u0430 Java, \u043d\u043e \u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u043e\u043d\u0435 \u201e1.6\u201c. +ComputerLauncher.JavaVersionResult=\ + \u041a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201e{0} -version\u201c \u0432\u044a\u0440\u043d\u0430 \u201e{1}\u201c. +ComputerLauncher.UknownJavaVersion=\ + \u0412\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 Java \u043d\u0430 \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 +# Unexpected error in launching an agent. This is probably a bug in Jenkins +ComputerLauncher.unexpectedError=\ + \u041d\u0435\u043e\u0447\u0430\u043a\u0432\u0430\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0430. \u0422\u043e\u0432\u0430 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0435 \u0433\u0440\u0435\u0448\u043a\u0430 \u0432 Jenkins +# Permanent Agent +DumbSlave.displayName=\ + \u041f\u043e\u0441\u0442\u043e\u044f\u043d\u0435\u043d \u0430\u0433\u0435\u043d\u0442 +# Take this agent online when in demand, and offline when idle +RetentionStrategy.Demand.displayName=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0437\u0438 \u0430\u0433\u0435\u043d\u0442 \u043f\u0440\u0438 \u043d\u0443\u0436\u0434\u0430. \u041a\u043e\u0433\u0430\u0442\u043e \u0430\u0433\u0435\u043d\u0442\u044a\u0442 \u0431\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0430, \u0434\u0430\ + \u0441\u0435 \u0438\u0437\u0432\u0435\u0436\u0434\u0430 \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f. +# Launch agent via Java Web Start +JNLPLauncher.displayName=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442 \u0441 Java Web Start +# Keep this agent online as much as possible +RetentionStrategy.Always.displayName=\ + \u0410\u0433\u0435\u043d\u0442\u044a\u0442 \u0434\u0430 \u0435 \u043e\u043d\u043b\u0430\u0439\u043d \u043a\u043e\u043b\u043a\u043e\u0442\u043e \u043c\u043e\u0436\u0435 \u043f\u043e-\u0434\u044a\u043b\u0433\u043e +# Launch agent via execution of command on the master +CommandLauncher.displayName=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442 \u0447\u0440\u0435\u0437 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 +# This agent is offline because Jenkins failed to launch the agent process on it. +OfflineCause.LaunchFailed=\ + \u0410\u0433\u0435\u043d\u0442\u044a\u0442 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u0437\u0430\u0449\u043e\u0442\u043e Jenkins \u043d\u0435 \u0443\u0441\u043f\u044f \u0434\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0430 \u043c\u0443. +# Take this agent online according to a schedule +SimpleScheduledRetentionStrategy.displayName=\ + \u0410\u0433\u0435\u043d\u0442\u044a\u0442 \u0434\u0430 \u0435 \u043d\u0430 \u0438 \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f \u043f\u043e \u0440\u0430\u0437\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +# Launching agent process aborted. +ComputerLauncher.abortedLaunch=\ + \u041f\u0440\u043e\u0446\u0435\u0441\u044a\u0442 \u0437\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0433\u0435\u043d\u0442\u0430 \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0438 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e diff --git a/core/src/main/resources/hudson/slaves/Messages_da.properties b/core/src/main/resources/hudson/slaves/Messages_da.properties index dc7acae2fd4e48001c236c58cf024ec4aa498dbe..ab97271a14fa67b5e5c5efee98ff8b6469294c06 100644 --- a/core/src/main/resources/hudson/slaves/Messages_da.properties +++ b/core/src/main/resources/hudson/slaves/Messages_da.properties @@ -20,19 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -SimpleScheduledRetentionStrategy.displayName=Bring denne slave online efter en tidsplan -RetentionStrategy.Always.displayName=Hold denne slave online s\u00e5 meget som muligt RetentionStrategy.Demand.OfflineIdle=Offline da computeren var i tomgang; vil blive genstartet n\u00e5r n\u00f8dvendigt. SimpleScheduledRetentionStrategy.FinishedUpTime=Computeren har afsluttet sin planlagte oppetid EnvironmentVariablesNodeProperty.displayName=Milj\u00f8variable -DumbSlave.displayName=Dum Slave -ComputerLauncher.abortedLaunch=Opstart af slaveproces afbrudt. -JNLPLauncher.displayName=Start slaveagenter via JNLP CommandLauncher.NoLaunchCommand=Ingen opstartskommando givet ConnectionActivityMonitor.OfflineCause=Gentagne pingfors\u00f8g fejlede -OfflineCause.LaunchFailed=Denne node er offline da Jenkins ikke kunne starte slaveagenten p\u00e5 den. -RetentionStrategy.Demand.displayName=Bring denne slavenode online efter behov, og offline n\u00e5r i tomgang -CommandLauncher.displayName=Start slave ved at k\u00f8re en kommando p\u00e5 master''en SlaveComputer.DisconnectedBy=Frakoblet af {0}{1} -ComputerLauncher.unexpectedError=Uforudset fejl under slaveopstart. Dette skyldes formentlig en fejl i Jenkins NodeProvisioner.EmptyString= diff --git a/core/src/main/resources/hudson/slaves/Messages_de.properties b/core/src/main/resources/hudson/slaves/Messages_de.properties index e1a50ba29395cd42d438e31a8f6230f77c59db5f..39ae4cf2d0b68a93c60f9f93c2c3a23326370fb1 100644 --- a/core/src/main/resources/hudson/slaves/Messages_de.properties +++ b/core/src/main/resources/hudson/slaves/Messages_de.properties @@ -21,18 +21,7 @@ # THE SOFTWARE. ConnectionActivityMonitor.OfflineCause=Ping-Versuche scheiterten wiederholt -RetentionStrategy.Always.displayName=Slave immer angeschaltet lassen -RetentionStrategy.Demand.displayName=Slave nur bei Bedarf anschalten, ansonsten abschalten -RetentionStrategy.Demand.OfflineIdle=Slave war im Leerlauf -CommandLauncher.displayName=Starte Slave durch Ausfhrung eines Kommandos auf dem Master -JNLPLauncher.displayName=Starte Slave-Agenten ber JNLP -ComputerLauncher.unexpectedError=Unerwarteter Fehler beim Starten eines Slave-Prozesses aufgetreten. Vermutlich handelt es sich um einen Fehler in Jenkins. -ComputerLauncher.abortedLaunch=Start eines Slave-Prozesses abgebrochen. CommandLauncher.NoLaunchCommand=Kein Startkommando angegeben. -DumbSlave.displayName=Dumb slave -OfflineCause.LaunchFailed=Dieser Knoten ist nicht verfgbar, weil Jenkins den Slave nicht starten konnte. -SimpleScheduledRetentionStrategy.displayName=Slave zeitgesteuert anschalten -SimpleScheduledRetentionStrategy.FinishedUpTime=Slave hat seine geplante Online-Zeit beendet. EnvironmentVariablesNodeProperty.displayName=Umgebungsvariablen NodeProvisioner.EmptyString= SlaveComputer.DisconnectedBy=Getrennt durch Benutzer {0}{1} diff --git a/core/src/main/resources/hudson/slaves/Messages_es.properties b/core/src/main/resources/hudson/slaves/Messages_es.properties index 3b70c0bce8870df1a3866355d847bb399eb5bdff..e12811db84e957a531372db7b7ee7d7982af80c8 100644 --- a/core/src/main/resources/hudson/slaves/Messages_es.properties +++ b/core/src/main/resources/hudson/slaves/Messages_es.properties @@ -20,19 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -RetentionStrategy.Always.displayName=Mantener este nodo en lnea el mximo de tiempo posible -RetentionStrategy.Demand.displayName=Poner este nodo en lnea cuando haya demanda, y fuera de lnea cuando no hayan trabajos RetentionStrategy.Demand.OfflineIdle=Fuera de lnea porque no es necesario, el servicio se volver a iniciar cuando haya demanda -CommandLauncher.displayName=Arrancar el nodo ejecutando un comando desde el nodo principal -JNLPLauncher.displayName=Ejecutar el agente en el nodo secundario utilizando JNLP -ComputerLauncher.unexpectedError=Error inesperado al lanzar un nodo secundario. Posiblemente sea un error de Jenkins (bug) -ComputerLauncher.abortedLaunch=El inicio del agente en el nodo secundario ha sido abortado. CommandLauncher.NoLaunchCommand=No se ha especificado ningn comando ConnectionActivityMonitor.OfflineCause=No hubo respuesta a ''ping'' despues de varios intentos -DumbSlave.displayName=Secundario pasivo -OfflineCause.LaunchFailed=Este nodo est fuera de lnea porque Jenkins no pudo iniciar el agente esclavo. SimpleScheduledRetentionStrategy.FinishedUpTime=El nodo ha finalizado el tiempo programado de estar on-line -SimpleScheduledRetentionStrategy.displayName=Programar cundo se debe poner este nodo secundario en lnea. EnvironmentVariablesNodeProperty.displayName=Variables de entorno SlaveComputer.DisconnectedBy=Desconectado por {0}{1} NodeProvisioner.EmptyString= diff --git a/core/src/main/resources/hudson/slaves/Messages_fr.properties b/core/src/main/resources/hudson/slaves/Messages_fr.properties index bbf337332212bc419d64b2c9bfaa09392dba47e8..d044dac640a5c330e07b89dde9cc707f3449ccf8 100644 --- a/core/src/main/resources/hudson/slaves/Messages_fr.properties +++ b/core/src/main/resources/hudson/slaves/Messages_fr.properties @@ -20,14 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -RetentionStrategy.Always.displayName=Garder cet esclave en ligne autant que possible -RetentionStrategy.Demand.displayName=Mettre cet esclave en ligne \u00e0 la demande et hors-ligne si inutilis\u00e9 -CommandLauncher.displayName=Lancer l''esclave via l''ex\u00e9cution d''une commande sur le ma\u00eetre -JNLPLauncher.displayName=Lancer les agents esclaves par JNLP -ComputerLauncher.unexpectedError=Erreur inattendue au lancement d''un esclave. Probablement un bug dans Jenkins -ComputerLauncher.abortedLaunch=Lancement de l''esclave annul\u00e9. CommandLauncher.NoLaunchCommand=Aucune commande de lancement sp\u00e9cifi\u00e9e -DumbSlave.displayName=Esclave passif -OfflineCause.LaunchFailed=Ce noeud est d\u00e9connect\u00e9 parce que Jenkins n''a pas r\u00e9ussi \u00e0 lancer l''agent esclave dessus. -SimpleScheduledRetentionStrategy.displayName=D\u00e9connecte cet esclave selon des horaires EnvironmentVariablesNodeProperty.displayName=Variables d''environnement diff --git a/core/src/main/resources/hudson/slaves/Messages_ja.properties b/core/src/main/resources/hudson/slaves/Messages_ja.properties index c8eeb5f76269b70ea68bd0c78c89614d0b4a675c..a5bf2adebc8cbe015b5741d24336cabf6f805b29 100644 --- a/core/src/main/resources/hudson/slaves/Messages_ja.properties +++ b/core/src/main/resources/hudson/slaves/Messages_ja.properties @@ -20,20 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -RetentionStrategy.Always.displayName=\u53ef\u80fd\u306a\u9650\u308a\u30aa\u30f3\u30e9\u30a4\u30f3\u306e\u307e\u307e\u306b\u3059\u308b -RetentionStrategy.Demand.displayName=\u8981\u6c42\u6642\u306b\u306f\u30aa\u30f3\u30e9\u30a4\u30f3\u306b\u3057\u3001\u5f85\u6a5f\u4e2d\u306b\u306f\u30aa\u30d5\u30e9\u30a4\u30f3\u306b\u3059\u308b RetentionStrategy.Demand.OfflineIdle=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u304c\u5f85\u6a5f\u4e2d\u306a\u306e\u3067\u30aa\u30d5\u30e9\u30a4\u30f3\u3067\u3059\u3002\u5fc5\u8981\u306b\u306a\u3063\u305f\u3089\u518d\u3073\u8d77\u52d5\u3057\u307e\u3059\u3002 -CommandLauncher.displayName=\u30de\u30b9\u30bf\u30fc\u3067\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u30b9\u30ec\u30fc\u30d6\u3092\u8d77\u52d5 -JNLPLauncher.displayName=JNLP\u7d4c\u7531\u3067\u30b9\u30ec\u30fc\u30d6\u3092\u8d77\u52d5 -ComputerLauncher.unexpectedError=\u30b9\u30ec\u30fc\u30d6\u306e\u8d77\u52d5\u4e2d\u306b\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\u3002\u3053\u308c\u306f\u305f\u3076\u3093Jenkins\u306e\u30d0\u30b0\u3067\u3059\u3002 -ComputerLauncher.abortedLaunch=\u30b9\u30ec\u30fc\u30d6\u306e\u8d77\u52d5\u30d7\u30ed\u30bb\u30b9\u304c\u4e2d\u65ad\u3057\u307e\u3057\u305f\u3002 CommandLauncher.NoLaunchCommand=\u8d77\u52d5\u30b3\u30de\u30f3\u30c9\u304c\u6307\u5b9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093\u3002 ConnectionActivityMonitor.OfflineCause=\u4f55\u5ea6\u3082ping\u304c\u5931\u6557\u3057\u307e\u3057\u305f\u3002 -DumbSlave.displayName=\u30c0\u30e0\u30b9\u30ec\u30fc\u30d6 NodeProvisioner.EmptyString= -OfflineCause.LaunchFailed=\u30b9\u30ec\u30fc\u30d6\u30a8\u30fc\u30b8\u30a7\u30f3\u30c8\u306e\u8d77\u52d5\u306b\u5931\u6557\u3057\u305f\u305f\u3081\u3001\u3053\u306e\u30ce\u30fc\u30c9\u306f\u30aa\u30d5\u30e9\u30a4\u30f3\u3067\u3059\u3002 SimpleScheduledRetentionStrategy.FinishedUpTime=\u30b3\u30f3\u30d4\u30e5\u30fc\u30bf\u306e\u52d5\u4f5c\u53ef\u80fd\u6642\u9593\u304c\u7d42\u4e86\u3057\u307e\u3057\u305f\u3002 -SimpleScheduledRetentionStrategy.displayName=\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306b\u5f93\u3063\u3066\u30aa\u30f3\u30e9\u30a4\u30f3\u306b\u3059\u308b EnvironmentVariablesNodeProperty.displayName=\u74b0\u5883\u5909\u6570 SlaveComputer.DisconnectedBy={0}\u304c\u30aa\u30d5\u30e9\u30a4\u30f3\u306b\u3057\u3066\u3044\u307e\u3059\u3002{1} NodeDescripter.CheckName.Mandatory=\u30ce\u30fc\u30c9\u540d\u306f\u5fc5\u9808\u3067\u3059\u3002 diff --git a/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties b/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties index 090702e6599bf1222d1ac67a5f06a973bc676866..9cd2f871d914b6342801fb196798b7983fff0cea 100644 --- a/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/Messages_pt_BR.properties @@ -20,16 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -RetentionStrategy.Always.displayName=Manter este slave ligado tanto quanto for poss\u00edvel -RetentionStrategy.Demand.displayName=Deixar este slave ligado quando em demanda e desligado quando inativo -CommandLauncher.displayName=Lan\u00e7ar o slave via execu\u00e7\u00e3o de comando no Master -JNLPLauncher.displayName=Lan\u00e7ar os agentes slave via JNLP -ComputerLauncher.unexpectedError=Erro ErrorUnexpected no lan\u00e7amento de um slave. Este \u00e9 provavelmente um bug no Jenkins -ComputerLauncher.abortedLaunch=Processo de lan\u00e7amento de slave abortado. -# Take this slave on-line according to a schedule -SimpleScheduledRetentionStrategy.displayName=Colocar o slave online de acordo com o agendamento -# This node is offline because Jenkins failed to launch the slave agent on it. -OfflineCause.LaunchFailed=Esse n\u00f3 est\u00e1 offline porque Jenkins falhou ao lan\u00e7ar o agente slave # No launch command specified CommandLauncher.NoLaunchCommand=Sem nenhum comando de lan\u00e7amento especificado # Offline because computer was idle; it will be relaunched when needed. @@ -43,8 +33,6 @@ SimpleScheduledRetentionStrategy.FinishedUpTime=O computador terminou o seu temp NodeProvisioner.EmptyString= # Environment variables EnvironmentVariablesNodeProperty.displayName=Vari\u00e1veis de ambiente -# Dumb Slave -DumbSlave.displayName=Slave burro # Java version {0} was found but 1.6 or later is needed. ComputerLauncher.NoJavaFound=A vers\u00e3o {0} do Java foi encontrada, mas a vers\u00e3o 1.6 ou mais nova \u00e9 necess\u00e1ria. # Couldn\u2019t figure out the Java version of {0} diff --git a/core/src/main/resources/hudson/slaves/Messages_sr.properties b/core/src/main/resources/hudson/slaves/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7c3235dec4fde016849efe32e30572d8186cc5d1 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/Messages_sr.properties @@ -0,0 +1,24 @@ +# This file is under the MIT License by authors + +RetentionStrategy.Always.displayName=\u0414\u0440\u0436\u0438 \u043E\u0432\u043E\u0433 \u0430\u0433\u0435\u043D\u0442\u0430 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u043E\u0433 \u043A\u043E\u043B\u0438\u043A\u043E \u0433\u043E\u0434 \u043C\u043E\u0433\u0443\u045B\u0435 +RetentionStrategy.Demand.displayName=\u041F\u043E\u0432\u0435\u0436\u0438 \u043E\u0432\u043E\u0433 \u0430\u0433\u0435\u043D\u0442\u0430 \u043A\u0430\u0434\u0430 \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u043E \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E, \u0430 \u043F\u0440\u0435\u043A\u0438\u043D\u0438 \u0432\u0435\u0437\u0443 \u043A\u0430\u0434\u0430 \u0437\u0430\u0441\u0442\u043E\u0458\u0438. +RetentionStrategy.Demand.OfflineIdle=\u041D\u0438\u0458\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u043E, \u0458\u0435\u0440 \u0458\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u0437\u0430\u0441\u0442\u043E\u0458\u0430\u043D\u0430. \u0411\u0438\u045B\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442 \u043A\u0430\u0434\u0430 \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u043E \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E. +CommandLauncher.displayName=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0430\u0433\u0435\u043D\u0442\u0430 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0443 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438 +JNLPLauncher.displayName=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0430\u0433\u0435\u043D\u0442\u0430 \u0441\u0430 Java Web Start +ComputerLauncher.unexpectedError=\u041D\u0435\u043E\u0447\u0435\u043A\u0438\u0432\u0430\u043D\u0430 \u0433\u0440\u0435\u0448\u043A\u0430 \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0442\u0430. \u041E\u0432\u043E \u0458\u0435 \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0433\u0440\u0435\u0448\u043A\u0430 \u0443 Jenkins. +ComputerLauncher.abortedLaunch=\u041F\u0440\u043E\u0446\u0435\u0441 \u0437\u0430 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435 \u0430\u0433\u0435\u043D\u0442\u0430 \u0458\u0435 \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u0442. +ConnectionActivityMonitor.OfflineCause=\u041F\u043E\u043D\u043E\u0432\u0459\u0435\u043D\u0438 \u043F\u043E\u043A\u0443\u0448\u0430\u0458\u0438 \u0434\u0430 \u0441\u0435 \u0441\u0442\u0443\u043F\u0438 \u043A\u043E\u043D\u0442\u0430\u043A\u0442 \u043F\u0440\u0435\u043A\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0435 "ping" \u0441\u0443 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0438. +CommandLauncher.NoLaunchCommand=\u041D\u0438\u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0430 \u0437\u0430 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0435. +DumbSlave.displayName=\u0421\u0442\u0430\u043B\u043D\u0438 \u0430\u0433\u0435\u043D\u0442 +NodeProvisioner.EmptyString= +OfflineCause.LaunchFailed=\u0410\u0433\u0435\u043D\u0442 \u043D\u0438\u0458\u0435 \u043F\u0440\u0438\u043A\u0459\u0443\u0447\u0435\u043D \u0458\u0435\u0440 Jenkins \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043E \u0434\u0430 \u043F\u043E\u043A\u0440\u0435\u043D\u0435 \u043F\u0440\u043E\u0446\u0435\u0441 \u043D\u0430 \u045A\u0435\u0433\u0430. +OfflineCause.connection_was_broken_=\u0412\u0435\u0437\u0430 \u0458\u0435 \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u0430: {0} +SimpleScheduledRetentionStrategy.FinishedUpTime=\u041C\u0430\u0448\u0438\u043D\u0430 \u0458\u0435 \u0437\u0430\u0432\u0440\u0448\u0438\u043B\u0430 \u043F\u043B\u0430\u043D\u0438\u0440\u0430\u043D\u043E \u0432\u0440\u0435\u043C\u0435 \u0440\u0430\u0434\u0430 +SimpleScheduledRetentionStrategy.displayName=\u041F\u043E\u0432\u0435\u0436\u0438 \u0430\u0433\u0435\u043D\u0442\u0430 \u043F\u0440\u0435\u043C\u0430 \u0440\u0430\u0441\u043F\u043E\u0440\u0435\u0434\u0443 +EnvironmentVariablesNodeProperty.displayName=\u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 +SlaveComputer.DisconnectedBy=\u041F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u0430 \u0432\u0435\u0437\u0430 \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 {0}{1} +NodeDescripter.CheckName.Mandatory=\u0418\u043C\u0435 \u0458\u0435 \u043E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +ComputerLauncher.NoJavaFound=\u041F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u043E \u0458\u0435 Java \u0432\u0435\u0440\u0437\u0438\u0458\u0430 {0}, \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0458\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0430 1.6. +ComputerLauncher.JavaVersionResult=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 {0} -version \u0458\u0435 \u0432\u0440\u0430\u0442\u0438\u043B\u043E {1}. +ComputerLauncher.UknownJavaVersion=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043E\u0434\u0440\u0435\u0434\u0438\u0438\u0442\u0438 Java \u0432\u0435\u0440\u0437\u0438\u0458\u0443 {0} +Cloud.ProvisionPermission.Description=\u041E\u0434\u0440\u0435\u0434\u0438 \u043D\u043E\u0432\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/Messages_tr.properties b/core/src/main/resources/hudson/slaves/Messages_tr.properties deleted file mode 100644 index 316c3dd85c998bb5d8af369acc0dea9df7629505..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/slaves/Messages_tr.properties +++ /dev/null @@ -1,28 +0,0 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Oguz Dag -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -RetentionStrategy.Always.displayName=Bu slave''i m\u00fcmk\u00fcn oldu\u011funca on-line konumda tut -RetentionStrategy.Demand.displayName=Bu slave''i ihtiya\u00e7 an\u0131nda on-line, bekleme durumlar\u0131nda off-line konuma getir. -CommandLauncher.displayName=Master''da \u00e7al\u0131\u015ft\u0131r\u0131lan bir komut ile bu slave''i harekete ge\u00e7ir -JNLPLauncher.displayName=JNLP yard\u0131m\u0131 ile slave ajan\u0131 harekete ge\u00e7ir -ComputerLauncher.unexpectedError=Slave harekete ge\u00e7irilirken umulmad\u0131k bir hata olu\u015ftu. Jenkins''daki bir bug''dan dolay\u0131 olabilir. -ComputerLauncher.abortedLaunch=Slave''i harekete ge\u00e7irme i\u015flemi iptal edildi. \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/Messages_zh_TW.properties b/core/src/main/resources/hudson/slaves/Messages_zh_TW.properties index c7fb50e753dc604086db9b6faeadd37290b98235..833fe2031343813dedb9f6623a391b475dc8f79d 100644 --- a/core/src/main/resources/hudson/slaves/Messages_zh_TW.properties +++ b/core/src/main/resources/hudson/slaves/Messages_zh_TW.properties @@ -20,29 +20,20 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -CommandLauncher.displayName=\u5728 Master \u4e0a\u57f7\u884c\u6307\u4ee4\u555f\u52d5 Slave CommandLauncher.NoLaunchCommand=\u6c92\u6709\u6307\u5b9a\u555f\u52d5\u6307\u4ee4 -ComputerLauncher.abortedLaunch=Slave \u555f\u52d5\u7a0b\u5e8f\u5df2\u4e2d\u6b62\u3002 -ComputerLauncher.unexpectedError=\u555f\u52d5 Slave \u6642\u767c\u751f\u9810\u671f\u5916\u7684\u932f\u8aa4\u3002\u53ef\u80fd\u662f Jenkins \u672c\u8eab\u7684 Bug ComputerLauncher.JavaVersionResult={0} -version \u56de\u50b3 {1}\u3002 ComputerLauncher.NoJavaFound=\u627e\u5230 Java {0} \u7248\uff0c\u4e0d\u904e\u6211\u5011\u8981\u7684\u662f 1.5 \u6216\u66f4\u65b0\u7684\u7248\u672c\u3002 ComputerLauncher.UknownJavaVersion=\u4e0d\u77e5\u9053 {0} \u7684 Java \u7248\u672c ConnectionActivityMonitor.OfflineCause=\u91cd\u8907 Ping \u5931\u6557 -DumbSlave.displayName=\u967d\u6625 Slave EnvironmentVariablesNodeProperty.displayName=\u74b0\u5883\u8b8a\u6578 -JNLPLauncher.displayName=\u900f\u904e Java Web Start \u555f\u52d5 Slave \u4ee3\u7406\u7a0b\u5f0f NodeDescripter.CheckName.Mandatory=\u4e00\u5b9a\u8981\u8f38\u5165\u540d\u7a31 -OfflineCause.LaunchFailed=\u7bc0\u9ede\u96e2\u7dda\uff0c\u56e0\u70ba Jenkins \u7121\u6cd5\u555f\u52d5\u4e0a\u9762\u7684 Slave \u4ee3\u7406\u7a0b\u5f0f\u3002 -RetentionStrategy.Always.displayName=\u76e1\u53ef\u80fd\u8b93 Slave \u4e0a\u7dda RetentionStrategy.Demand.OfflineIdle=\u96fb\u8166\u9592\u7f6e\u96e2\u7dda\uff0c\u9700\u8981\u6642\u624d\u6703\u88ab\u555f\u52d5\u3002 -RetentionStrategy.Demand.displayName=\u9700\u8981\u6642\u624d\u8b93 Slave \u4e0a\u7dda\uff0c\u9592\u7f6e\u6642\u5c31\u96e2\u7dda\u3002 -SimpleScheduledRetentionStrategy.displayName=\u4f9d\u64da\u6392\u7a0b\u8b93 Slave \u4e0a\u7dda SimpleScheduledRetentionStrategy.FinishedUpTime=\u96fb\u8166\u5df2\u7d93\u505a\u6eff\u4e86\u6392\u5b9a\u7684\u4e0a\u7dda\u6642\u9593 SlaveComputer.DisconnectedBy=\u7531 {0} \u4e2d\u65b7\u9023\u7dda{1} diff --git a/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_de.properties b/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_de.properties index 8bbec34fbf1dcb328c18194be64509e47853d728..70ae2479d6a2315220e63145e0c6fd5e2ab7e748 100644 --- a/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_de.properties +++ b/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_de.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + Connection\ was\ broken=Verbindung abgebrochen \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_sr.properties b/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c90bb813262f987a28ec2f09f0ea24f854c42f81 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/OfflineCause/ChannelTermination/cause_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Connection\ was\ broken=\u0412\u0435\u0437\u0430 \u0458\u0435 \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u0430 diff --git a/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_bg.properties b/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_bg.properties index 4a2c20e29224581d9acb4ff56d555469a11e1fcb..ccdd23736684ee480ef00cf6175d7d26f078d2b8 100644 --- a/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_bg.properties +++ b/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -See\ log\ for\ more\ details=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u043D\u0430 \u043B\u043E\u0433\u0430 \u0437\u0430 \u043F\u043E\u0432\u0435\u0447\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F +See\ log\ for\ more\ details=\ + \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430\u0439\u0442\u0435 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 diff --git a/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_sr.properties b/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5095bc44ec1b20cac211f924b3180d486c211ba0 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/OfflineCause/LaunchFailed/cause_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +See\ log\ for\ more\ details=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B \u0437\u0430 \u0432\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430 diff --git a/core/src/main/resources/hudson/slaves/OfflineCause/cause.jelly b/core/src/main/resources/hudson/slaves/OfflineCause/cause.jelly index a6676efe9f1f099762779b6bb4e093f15d6f58cb..51a05a144aaf6f2cd9c85cb0dc6b553ae23185b4 100644 --- a/core/src/main/resources/hudson/slaves/OfflineCause/cause.jelly +++ b/core/src/main/resources/hudson/slaves/OfflineCause/cause.jelly @@ -29,7 +29,7 @@ THE SOFTWARE.
      - + ${it}
      diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Demand/config_sr.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Demand/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6e5107cd17cfe6b103d30bd6a889a0f6e59e9046 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/RetentionStrategy/Demand/config_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +In\ demand\ delay=\u041A\u0430\u0448\u045A\u0435\u045A\u0435 \u043D\u0430\u043A\u043E\u043D \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0430\u045A\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0430 +In\ demand\ delay\ is\ mandatory\ and\ must\ be\ a\ number.=\u041A\u0430\u0448\u045A\u0435\u045A\u0435 \u043D\u0430\u043A\u043E\u043D \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0430\u045A\u0430 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E. +Idle\ delay=\u041A\u0430\u0448\u045A\u0435\u045A\u0435 \u043D\u0430\u043A\u043E\u043D \u0437\u0430\u0432\u0440\u0448\u0435\u0442\u043A\u0430 +Idle\ delay\ is\ mandatory\ and\ must\ be\ a\ number.=\u041A\u0430\u0448\u045A\u0435\u045A\u0435 \u043D\u0430\u043A\u043E\u043D \u0437\u0430\u0432\u0440\u0448\u0435\u0442\u043A\u0430 \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E. diff --git a/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_sr.properties b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b95c745f05aee69fdfdbeb423e77542da3458c87 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/RetentionStrategy/Scheduled/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Startup\ Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 +Shutdown\ Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u0433\u0430\u0448\u0435\u045A\u0430 diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config.jelly b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config.jelly index e06ed7537b2800b927f7ec7d1899b5e99e5da996..3ef03e52aab3629e3073254811f2ca4783770f4d 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config.jelly +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config.jelly @@ -35,7 +35,7 @@ THE SOFTWARE. name="retentionStrategy.upTimeMins" value="${instance.upTimeMins}" checkMessage="${%Scheduled Uptime is mandatory and must be a number.}"/> - + diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_da.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_da.properties index e7e0e0e452585f2e1791d533b5223e230a674487..525c94f6a199dcaefa7aca1cb1006357b807a33f 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_da.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_da.properties @@ -22,6 +22,6 @@ Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=Planlagt oppetid er obligatorisk og skal v\u00e6re et tal. Scheduled\ Uptime=Planlagt oppetid -Keep\ on-line\ while\ jobs\ are\ running=Hold on-line n\u00e5r jobs k\u00f8rer +Keep\ online\ while\ jobs\ are\ running=Hold on-line n\u00e5r jobs k\u00f8rer Startup\ Schedule=Opstartstidsplan uptime.description=Antal minutter noden skal holdes oppe. Hvis dette er l\u00e6ngere end opstartstidsplanen vil noden altid v\u00e6re online. diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_de.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_de.properties index 35f248248399f8ea47369ff28e98d78505dabe0c..6ba64a98e46539bb2193ad45537da002b061cf5b 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_de.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_de.properties @@ -23,6 +23,5 @@ Startup\ Schedule=Anschaltzeitplan Scheduled\ Uptime=Verfgbare Zeit Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=Verfgbare Zeit muss angegeben werden und eine Zahl sein. -Keep\ on-line\ while\ jobs\ are\ running=Slave angeschaltet lassen, solange Jobs laufen. uptime.description=\ Dies ist die Zeit in Minuten, die dieser Knoten verfgbar bleibt. Ist der Zeitraum lnger als die Zeitabstnde im Zeitplan, dann ist der Knoten dauerhaft verfgbar. diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_es.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_es.properties index 54a97e1b5d1d41d0db33ca793866eb706fa86c55..5275f2d573ff4d590a8649c7933fbd1a10af6d8f 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_es.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_es.properties @@ -23,5 +23,5 @@ Startup\ Schedule=Tiempo de inicio programado Scheduled\ Uptime=Tiempo de ejecucin programado Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=El tiempo de ejecucin programado es obligatorio y debe ser un nmero -Keep\ on-line\ while\ jobs\ are\ running=Mantener en lnea mientras hayan tareas en ejecucin +Keep\ online\ while\ jobs\ are\ running=Mantener en lnea mientras hayan tareas en ejecucin uptime.description=El nmero de minutos para mantener el nodo activo. Si es mayor que el tiempo programado para arrancar, el nodo estar permanentemente en lnea diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_fr.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_fr.properties index 8cadc09c4942f2b3a9d3d4913bbaebe916d175fe..7e776863eb4f4fd53d74ad25a5751f70645d5982 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_fr.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_fr.properties @@ -24,4 +24,4 @@ Startup\ Schedule=D Scheduled\ Uptime=Dure du mode actif Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=Le Uptime pr\u00E9vu est obligatoire et doit \u00EAtre un nombre. Scheduled\ Uptime\ is\ mandatory.=La dure est obligatoire. -Keep\ on-line\ while\ jobs\ are\ running=Garder actif tant que des jobs sont en cours. +Keep\ online\ while\ jobs\ are\ running=Garder actif tant que des jobs sont en cours. diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_ja.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_ja.properties index 28cb24e19eeddd5e3499133952184a29f7a85719..efbad4f8bd6899d5aafdbde79bd9d6f9433f2a03 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_ja.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_ja.properties @@ -23,6 +23,6 @@ Startup\ Schedule=\u8D77\u52D5\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB Scheduled\ Uptime=\u52D5\u4F5C\u53EF\u80FD\u6642\u9593 Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=\u52D5\u4F5C\u53EF\u80FD\u6642\u9593\u306F\u3001\u5FC5\u9808\u304B\u3064\u6570\u5B57\u3067\u3059\u3002 -Keep\ on-line\ while\ jobs\ are\ running=\u30B8\u30E7\u30D6\u8D77\u52D5\u4E2D\u306F\u30AA\u30F3\u30E9\u30A4\u30F3\u3092\u7DAD\u6301 +Keep\ online\ while\ jobs\ are\ running=\u30B8\u30E7\u30D6\u8D77\u52D5\u4E2D\u306F\u30AA\u30F3\u30E9\u30A4\u30F3\u3092\u7DAD\u6301 uptime.description=\ - \u30CE\u30FC\u30C9\u3092\u30AA\u30F3\u30E9\u30A4\u30F3\u306E\u307E\u307E\u7DAD\u6301\u3059\u308B\u6642\u9593(\u5206)\u3067\u3059\u3002\u3053\u306E\u5024\u304C\u8D77\u52D5\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u9593\u9694\u3088\u308A\u9577\u3051\u308C\u3070\u3001\u30CE\u30FC\u30C9\u306F\u5E38\u306B\u30AA\u30F3\u30E9\u30A4\u30F3\u306E\u307E\u307E\u306B\u306A\u308A\u307E\u3059\u3002\u3000 \ No newline at end of file + \u30CE\u30FC\u30C9\u3092\u30AA\u30F3\u30E9\u30A4\u30F3\u306E\u307E\u307E\u7DAD\u6301\u3059\u308B\u6642\u9593(\u5206)\u3067\u3059\u3002\u3053\u306E\u5024\u304C\u8D77\u52D5\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u9593\u9694\u3088\u308A\u9577\u3051\u308C\u3070\u3001\u30CE\u30FC\u30C9\u306F\u5E38\u306B\u30AA\u30F3\u30E9\u30A4\u30F3\u306E\u307E\u307E\u306B\u306A\u308A\u307E\u3059\u3002\u3000 diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_pt_BR.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_pt_BR.properties index 4022c771703cc360f39aac4136d04a145ef32323..39bd2696607ff99e237efeb555616ca83fec51f3 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_pt_BR.properties @@ -25,5 +25,5 @@ Startup\ Schedule=Agenda de inicializa # \ # The number of minutes to keep the node up for. If this is longer than the startup schedule, then the node will remain constantly on-line. uptime.description=O n\u00famero de minutos para manter o n\u00f3 no ar -Keep\ on-line\ while\ jobs\ are\ running=Manter on-line enquanto estiverem rodando jobs +Keep\ online\ while\ jobs\ are\ running=Manter on-line enquanto estiverem rodando jobs Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=Agenda de uptime \u00e9 obrigat\u00f3ria e precisa ser um n\u00famero. diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_sr.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4a372ed19400c05dce9b0cc8f5b1453db4402fc1 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Startup\ Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 +Scheduled\ Uptime=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u0432\u0440\u0435\u043C\u0435\u043D\u0430 \u043D\u0435\u043F\u0440\u0435\u043A\u0438\u0434\u043D\u043E\u0433 \u0440\u0430\u0434\u0430 +uptime.description=\u041A\u043E\u043B\u0438\u043A\u043E \u043C\u0438\u043D\u0443\u0442\u0430 \u045B\u0435 \u0441\u0435 \u043E\u0434\u0440\u0436\u0430\u0432\u0430\u0442\u0438 \u0432\u0435\u0437\u0443 \u0441\u0430 \u043C\u0430\u0448\u0438\u043D\u043E\u043C. \u0410\u043A\u043E \u043F\u0440\u0435\u043A\u043E\u0440\u0430\u0447\u0443\u0458\u0435 \u0440\u0430\u0441\u043F\u043E\u0440\u0435\u0434 \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430, \u043E\u043D\u0434\u0430 \u045B\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u043E\u0441\u0442\u0430\u0442\u0438 \u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0430. +Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.= +Keep\ online\ while\ jobs\ are\ running=\u041E\u0434\u0440\u0436\u0438 \u0432\u0435\u0437\u0443 \u0434\u043E\u043A \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u0458\u0443 \u0437\u0430\u0434\u0430\u0446\u0438 diff --git a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_zh_TW.properties b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_zh_TW.properties index f29f194e2d04dc9eaff4e97feaf699e0c382a51c..87e353f0c6fcf76dd53dbd31b54b378df717c94f 100644 --- a/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_zh_TW.properties +++ b/core/src/main/resources/hudson/slaves/SimpleScheduledRetentionStrategy/config_zh_TW.properties @@ -24,4 +24,4 @@ Startup\ Schedule=\u555F\u52D5\u6392\u7A0B Scheduled\ Uptime=\u6392\u5B9A\u7684\u904B\u4F5C\u6642\u9593 uptime.description=\u7BC0\u9EDE\u4E0A\u7DDA\u7684\u5206\u9418\u6578\u3002\u5982\u679C\u8D85\u904E\u4E0B\u6B21\u555F\u52D5\u6392\u7A0B\u7684\u6642\u9593\uFF0C\u9019\u500B\u7BC0\u9EDE\u5C31\u6703\u4E00\u76F4\u5728\u7DDA\u4E0A\u3002 Scheduled\ Uptime\ is\ mandatory\ and\ must\ be\ a\ number.=\u6392\u5B9A\u7684\u904B\u4F5C\u6642\u9593\u4E00\u5B9A\u8981\u8F38\u5165\u6578\u5B57\u3002 -Keep\ on-line\ while\ jobs\ are\ running=\u9084\u6709 Job \u57F7\u884C\u6642\u4FDD\u6301\u5728\u4E0A\u7DDA\u72C0\u614B +Keep\ online\ while\ jobs\ are\ running=\u9084\u6709 Job \u57F7\u884C\u6642\u4FDD\u6301\u5728\u4E0A\u7DDA\u72C0\u614B diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/already-launched.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/already-launched.jelly index 497c61514fa1b4b58176b2fed809f0da55881435..cd905e18abd314fb9fa679f5b4f8de9b895590c1 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/already-launched.jelly +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/already-launched.jelly @@ -3,7 +3,7 @@ - The slave has been already launched. + The agent has been already launched. diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_bg.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..d3ab8094c7852c1cfcffe60d44f8c7587d278222 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_bg.properties @@ -0,0 +1,31 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Yes=\ + \u0414\u0430 +disconnect=\ + \u0418\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f +# You can optionally explain why you are taking this node offline, so that others can see why: +blurb=\ + \u041c\u043e\u0436\u0435 \u0434\u0430 \u043e\u0431\u044f\u0441\u043d\u0438\u0442\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438 \u0437\u0430\u0449\u043e \u0432\u0430\u0434\u0438\u0442\u0435 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430 \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f: +Are\ you\ sure\ about\ disconnecting?=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430 \u0438\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f? diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_de.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_de.properties index 4956c0ef8ef88414b3e17ed0f93ab2734fffbb2e..a8ed85eac17b8b536ec3b2b77d20a723b88683ef 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_de.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_de.properties @@ -24,5 +24,4 @@ disconnect=Trennen blurb=\ Sie knnen optional kurz erklren, warum Sie den Knoten abschalten. Dieser Text ist \ sichtbar fr andere Benutzer: -Are\ you\ sure\ about\ disconnecting?=Mchten Sie die Verbindung zum Slave wirklich trennen? Yes=Ja diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_sr.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8dd7d8cc41e09cfddd71ec4eeca90d876be31680 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/disconnect_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +disconnect=\u043F\u0440\u0435\u043A\u0438\u043D\u0438 \u0432\u0435\u0437\u0443 +Are\ you\ sure\ about\ disconnecting?=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u0438\u043B\u0438\u0442\u0435 \u0434\u0430 \u043F\u0440\u0435\u043A\u0438\u043D\u0435\u0442\u0435 \u0432\u0435\u0437\u0443? +Yes=\u0414\u0430 +blurb=\u041C\u043E\u0436\u0435\u0442\u0435 \u043E\u043F\u0446\u0438\u043E\u043D\u043E \u043D\u0430\u0432\u0435\u0441\u0442\u0430 \u0440\u0430\u0437\u043B\u043E\u0433 \u0437\u0430\u0448\u0442\u043E \u0441\u0435 \u043F\u0440\u0435\u043A\u0438\u0434\u0430 \u0432\u0435\u0437\u0430: diff --git a/core/src/main/resources/hudson/model/Computer/_script_pt_BR.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/log_bg.properties similarity index 84% rename from core/src/main/resources/hudson/model/Computer/_script_pt_BR.properties rename to core/src/main/resources/hudson/slaves/SlaveComputer/log_bg.properties index 76ece934fa5f04e393e196d2118d0010c81e6ccc..cc395f5fcb68be1a05fe68b97b911e48fd1687f0 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/log_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Cleiber Silva, Fernando Boaglio +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=A execu\u00e7\u00e3o aconteceu no agente JVM slave. +Log\ Records=\ + \u0416\u0443\u0440\u043d\u0430\u043b\u043d\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/log_sr.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/log_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..342f76eea2c02c11e790cbdbcc839e2bcf664d9f --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/log_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Log\ Records=\u0416\u0443\u0440\u043D\u0430\u043B \u043F\u043E\u0434\u0430\u0446\u0438 \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_bg.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_bg.properties index 008958ca66733bda2ba49240ca5c0f74fc5a2a15..91b3578924953a79adbe844b46de363e5b9316af 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_bg.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Log=\u041B\u043E\u0433 -System\ Information=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u0430 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F +Log=\ + \u0416\u0443\u0440\u043d\u0430\u043b +System\ Information=\ + \u0421\u0438\u0441\u0442\u0435\u043c\u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f +Disconnect=\ + \u041f\u0440\u0435\u043a\u044a\u0441\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430 diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_sr.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..072ff6db922c12bd1bed8b8182ae3f0999992860 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel2_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Log=\u0416\u0443\u0440\u043D\u0430\u043B +System\ Information=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 +Disconnect=\u041F\u0440\u0435\u043A\u0438\u043D\u0438 \u0432\u0435\u0437\u0443 diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel_sr.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5986eb659ef0f052be6ed5a5629c916bd0409b57 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/sidepanel_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +System\ Information=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 +Back\ to\ List=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u0441\u043F\u0438\u0441\u043A\u0443 +Status=\u0421\u0442\u0430\u045A\u0435 +Log=\u0416\u0443\u0440\u043D\u0430\u043B +Disconnect=\u041F\u0440\u0435\u043A\u0438\u043D\u0438 \u0432\u0435\u0437\u0443 +Build\ History=\u0418\u0441\u0442\u043E\u0440\u0438\u0458\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly index 9f25865224223b8e63fcf30e7a13b63c6dd66d91..aff376cb8af2d79c16d1c3abb245df417a2149a7 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly @@ -37,7 +37,7 @@ THE SOFTWARE. codebase="${rootURL}computer/${h.encode(it.node.nodeName)}/"> - Slave Agent for ${it.displayName} + Agent for ${it.displayName} Jenkins project @@ -57,7 +57,6 @@ THE SOFTWARE. - diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly index f44b0a726904e61f036ffb694c753db761173c2d..279fc74807f66d8c1557bc41a743ce89c2dd1dbd 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo.jelly @@ -44,7 +44,7 @@ THE SOFTWARE. - +

      ${it.oSDescription} slave, version ${it.slaveVersion}

      @@ -53,10 +53,10 @@ THE SOFTWARE.
      - ${%System Information is unavailable when slave is offline.} + ${%System Information is unavailable when agent is offline.}
      - \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message_pt_BR.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_bg.properties similarity index 51% rename from core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message_pt_BR.properties rename to core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_bg.properties index c2aeee6083202e372cc14b42319596d5658e8b81..71fab9b73b9b2c9397c6121b25dc83efcb3fd90e 100644 --- a/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,11 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# This version of Jenkins comes with new versions of the following plugins that are currently \ -# pinned in \ -# the plugin manager. \ -# It is recommended to upgrade them to at least the version bundled with Jenkins. -blurb=Essa vers\u00e3o do Jenkins vem com as vers\u00f5es novas dos seguintes plugins \ - pinned no \ - gerenciador de plugin. \ - \u00c9 recomendado atualizar para pelo menos a vers\u00e0o que vem junto com o Jenkins. +System\ Information\ is\ unavailable\ when\ slave\ is\ offline.=\ + \u041a\u043e\u0433\u0430\u0442\u043e \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u0438\u044f\u0442 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u043b\u0438\u043f\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430. +System\ Information=\ +\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 +System\ Information\ is\ unavailable\ when\ agent\ is\ offline.=\ + \u041a\u043e\u0433\u0430\u0442\u043e \u0430\u0433\u0435\u043d\u0442\u044a\u0442 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u043b\u0438\u043f\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430. diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_ja.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_ja.properties index 68f9d62e9faee33956e3337a4b58bb5ff8babfbe..946b7ac4cb260f3c39aca5948b35f66bba464e7f 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_ja.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_ja.properties @@ -21,5 +21,3 @@ # THE SOFTWARE. System\ Information=\u30b7\u30b9\u30c6\u30e0\u60c5\u5831 -System\ Information\ is\ unavailable\ when\ slave\ is\ offline.=\ -\u30b9\u30ec\u30fc\u30d6\u304c\u30aa\u30d5\u30e9\u30a4\u30f3\u306e\u5834\u5408\u306b\u306f\u3001\u30b7\u30b9\u30c6\u30e0\u60c5\u5831\u306f\u5229\u7528\u3067\u304d\u307e\u305b\u3093\u3002 \ No newline at end of file diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_pt_BR.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_pt_BR.properties index 7ca948edf62492e507731fcc2b2fc0a52972983d..54e0a66aa7c226b166e6b7c006fc14357ad34d6c 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_pt_BR.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_pt_BR.properties @@ -21,4 +21,3 @@ # THE SOFTWARE. System\ Information=Informa\u00e7t\u00e3o de sistema -System\ Information\ is\ unavailable\ when\ slave\ is\ offline.=As informa\u00e7\u00f5es do sistema n\u00e3o est\u00e3o dispon\u00edveis quando o sistema est\u00e1 offline. diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_sr.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a5f7432961709b0955223c6b87bba81f3bdd2da6 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/systemInfo_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +System\ Information=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 +System\ Information\ is\ unavailable\ when\ agent\ is\ offline.=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0443\u0447\u0438\u0442\u0430\u0442\u0438 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043A\u0430\u0434 \u0458\u0435 \u043C\u0430\u0448\u043D\u0438\u0430 \u043D\u0435\u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0430. +System\ Information\ is\ unavailable\ when\ slave\ is\ offline.=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0443\u0447\u0438\u0442\u0430\u0442\u0438 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043A\u0430\u0434 \u0458\u0435 \u043F\u043E\u043C\u043E\u045B\u043D\u0430 \u043C\u0430\u0448\u043D\u0438\u0430 \u043D\u0435\u043F\u043E\u0432\u0435\u0437\u0430\u043D\u0430. +System\ Properties=\u041F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 +Environment\ Variables=\u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0435 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0435 +Thread\ Dump=\u0414\u0435\u043F\u043E\u043D\u0438\u0458\u0430 \u043D\u0438\u0442\u043E\u0432\u0430 diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_bg.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..9603430d1a76792a35b018e6ffa7333baf62ca17 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_bg.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# {0} Thread Dump +title=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043d\u0438\u0448\u043a\u0430 {0} +Thread\ Dump=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043d\u0438\u0448\u043a\u0430 diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_de.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_de.properties index 6dc1884ce59426e72f0c73f655c1f6b4acd8e3d9..11b66c852d16e4003bf412268fe5b080195a94dc 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_de.properties +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_de.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNEC - -title={0} Thread Dump -Thread\ Dump=Thread Dump +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNEC + +title={0} Thread Dump +Thread\ Dump=Thread Dump diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_sr.properties b/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..59ba3a01f64d01682935dfd97ecf4fdb516b0ba9 --- /dev/null +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/threadDump_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +title={0} \u0414\u0435\u043F\u043E\u043D\u0438\u0458\u0430 \u043D\u0438\u0442\u043E\u0432\u0430 +Thread\ Dump={0} \u0414\u0435\u043F\u043E\u043D\u0438\u0458\u0430 \u043D\u0438\u0442\u043E\u0432\u0430 diff --git a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.jelly b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.jelly index cff5a427239c26be78fcb470b67f4cc9c64f7314..abb03fe4b9230bdf9baa41c0df7600ce4174e823 100644 --- a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.jelly +++ b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.jelly @@ -40,8 +40,11 @@ THE SOFTWARE. - - - + + + + + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.properties b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.properties index 9fb285ad65861afba6dd3c2a0fc21e8b7d371fa5..62475e21160dc4c163d884a0c151273bb15f6550 100644 --- a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.properties +++ b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config.properties @@ -22,4 +22,5 @@ allowEmptyArchive=Do not fail build if archiving returns nothing onlyIfSuccessful=Archive artifacts only if build is successful -defaultExcludes=Use default excludes \ No newline at end of file +defaultExcludes=Use default excludes +caseSensitive=Treat include and exclude patterns as case sensitive \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_pl.properties b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_pl.properties index 3752d192fa74fd5b3cc09d5d2a502a2ab0d65c51..75d09b7600c68e7f15a4beb685b43fa393e10449 100644 --- a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_pl.properties +++ b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright 2014 Jesse Glick. +# Copyright 2014-2016 Jesse Glick, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,14 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Fingerprint\ all\ archived\ artifacts=Odcisk palca wszystkich zarchiwizowanych artefakt\u00f3w +Fingerprint\ all\ archived\ artifacts=Odcisk palca wszystkich zarchiwizowanych artefakt\u00F3w +Files\ to\ archive=Pliki do zarchiwizowania +# Do not fail build if archiving returns nothing +allowEmptyArchive=Nie oznaczaj zadania niepowodzeniem, je\u015Bli nie odnaleziono plik\u00F3w do zarchiwizowania +Excludes=Pliki do pomini\u0119cia +# Treat include and exclude patterns as case sensitive +caseSensitive=Uwzgl\u0119dniaj wielko\u015B\u0107 liter przy filtrowaniu plik\u00F3w do zarchiwizowania +# Archive artifacts only if build is successful +onlyIfSuccessful=Archiwizuj pliki tylko, je\u015Bli zadanie zako\u0144czy\u0142o si\u0119 powodzeniem +# Use default excludes +defaultExcludes=U\u017Cywaj domy\u015Blnego filtru dla plik\u00F3w, kt\u00F3re nale\u017Cy pomin\u0105\u0107 diff --git a/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_sr.properties b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..09d2f6b36348493159abb1cd99b9b3fb7a8a1530 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/ArtifactArchiver/config_sr.properties @@ -0,0 +1,9 @@ +# This file is under the MIT License by authors + +Files\ to\ archive=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0437\u0430 \u0430\u0440\u0445\u0438\u0432\u0430\u045A\u0435 +Excludes=\u0418\u0437\u0441\u043A\u0459\u0443\u0447\u0435\u045A\u0430 +allowEmptyArchive=\u041D\u0435\u043C\u043E\u0458 \u043E\u043A\u043E\u043D\u0447\u0430\u0442\u0438 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0430\u043A\u043E \u0430\u0440\u0445\u0438\u0432\u0430\u0442\u043E\u0440 \u043D\u0435 \u0443\u0441\u043F\u0435 +onlyIfSuccessful=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u0458 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0435 \u0441\u0430\u043C\u043E \u043A\u0430\u0434\u0430 \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u0430 +Fingerprint\ all\ archived\ artifacts=\u0423\u0437\u043C\u0438 \u043E\u0442\u0438\u0441\u043A\u0435 \u0441\u0432\u0438\u0445 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043D\u0438\u043C \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438\u043C\u0430 +defaultExcludes=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u0443\u043E\u0431\u0438\u0447\u0430\u0458\u0435\u043D\u0430 \u0438\u0437\u0443\u0437\u0438\u043C\u0430\u045A\u0430 +caseSensitive=\u0422\u0440\u0435\u0442\u0438\u0440\u0430\u0458 \u043F\u0435\u043B\u0438\u043A\u0430 \u0438 \u043C\u0430\u043B\u0430 \u0441\u043B\u043E\u0432\u0430 \u043F\u043E \u0438\u0437\u0443\u0437\u0438\u043C\u0430\u045A\u0430 \u0438 \u0443\u0437\u0438\u043C\u0430\u045A\u0430 \u0448\u0430\u0431\u043B\u043E\u043D\u0435 \u0458\u0435\u0434\u043D\u0430\u0438\u043C diff --git a/core/src/main/resources/hudson/tasks/ArtifactArchiver/help-caseSensitive.html b/core/src/main/resources/hudson/tasks/ArtifactArchiver/help-caseSensitive.html new file mode 100644 index 0000000000000000000000000000000000000000..4d8200d06370e4e2e5dcd5cef3b596ec02c03da7 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/ArtifactArchiver/help-caseSensitive.html @@ -0,0 +1,5 @@ +
      + Artifact archiver uses Ant org.apache.tools.ant.DirectoryScanner which by default is case sensitive. + For instance, if the job produces *.hpi files, pattern "**/*.HPI" will fail to find them.

      + This option can be used to disable case sensitivity. When it's unchecked, pattern "**/*.HPI" will match any *.hpi files, or pattern "**/cAsEsEnSiTiVe.jar" will match a file called caseSensitive.jar. +
      \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/ArtifactArchiver/help-defaultExcludes_sr.properties b/core/src/main/resources/hudson/tasks/ArtifactArchiver/help-defaultExcludes_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1ca86e02143950b1835a0525a02dbdaaf25644e6 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/ArtifactArchiver/help-defaultExcludes_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +p1=\u0410\u0440\u0445\u0438\u0432\u0430\u0442\u043E\u0440 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 \u043A\u043E\u0440\u0438\u0441\u0442\u0438 Ant org.apache.tools.ant.DirectoryScanner, \u0448\u0442\u043E \u0438\u0441\u043A\u0459\u0443\u0447\u0443\u0458\u0435 \u043D\u0430\u0440\u0435\u0434\u043D\u0435 \u0448\u0430\u0431\u043B\u043E\u043D\u0435: +p2=\u041E\u0432\u0430 \u043E\u043F\u0446\u0438\u0458\u0430 \u043F\u0440\u0443\u0436\u0438 \u043C\u043E\u0433\u0443\u045B\u043D\u043E\u0441\u0442 \u0434\u0430 \u0441\u0435 \u0443\u043A\u0459\u0443\u0447\u0435 \u0438\u043B\u0438 \u0438\u0441\u043A\u0459\u0443\u0447\u0435 Ant \u0438\u0437\u0443\u0437\u0438\u043C\u0430\u045A\u0430. \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/BatchFile/config.jelly b/core/src/main/resources/hudson/tasks/BatchFile/config.jelly index 35e5f89c41f8d4e87cee4fe4ddda4607cc91727f..19fbdcef646d218856ddb69b2dff12fd7bedf283 100644 --- a/core/src/main/resources/hudson/tasks/BatchFile/config.jelly +++ b/core/src/main/resources/hudson/tasks/BatchFile/config.jelly @@ -28,4 +28,9 @@ THE SOFTWARE. description="${%description(rootURL)}">
      + + + + + diff --git a/core/src/main/resources/hudson/tasks/BatchFile/config_sr.properties b/core/src/main/resources/hudson/tasks/BatchFile/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..cccacf6fa85480cab21e00a57e4d91af7633de8a --- /dev/null +++ b/core/src/main/resources/hudson/tasks/BatchFile/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Command=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 +description=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458 \u0441\u043F\u0438\u0441\u0430\u043A \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 diff --git a/core/src/main/resources/hudson/tasks/BatchFile/help-unstableReturn.html b/core/src/main/resources/hudson/tasks/BatchFile/help-unstableReturn.html new file mode 100644 index 0000000000000000000000000000000000000000..8dc41ec39c9961f97d1555b333a4d2a5c0408f0b --- /dev/null +++ b/core/src/main/resources/hudson/tasks/BatchFile/help-unstableReturn.html @@ -0,0 +1,9 @@ +
      + If set, the batch errorlevel result that will be interpreted as an unstable build result. + If the final errorlevel matches the value, the build results will be set to unstable and + next steps will be continued. Supported values match the widest errorlevel range for Windows + like systems. In Windows NT4 and beyond the ERRORLEVEL is stored as a four byte, signed integer, + yielding maximum and minimum values of 2147483647 and -2147483648, respectively. Older versions + of Windows use 2 bytes. DOS like systems use single byte, yelding errorlevels between 0-255. + The value 0 is ignored and does not make the build unstable to keep the default behaviour consistent. +
      diff --git a/core/src/main/resources/hudson/tasks/BuildTrigger/config_de.properties b/core/src/main/resources/hudson/tasks/BuildTrigger/config_de.properties index 1c6ccb631a50caec5b516e51b918ea27aa7e55b2..76d3309d9099c06ff1fff01da5e1012ed9a43476 100644 --- a/core/src/main/resources/hudson/tasks/BuildTrigger/config_de.properties +++ b/core/src/main/resources/hudson/tasks/BuildTrigger/config_de.properties @@ -1,25 +1,26 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Projects\ to\ build=Zu bauende Projekte -Trigger\ even\ if\ the\ build\ is\ unstable=Auslsen, selbst wenn der Build instabil ist. -Trigger\ even\ if\ the\ build\ fails=Auslsen, selbst wenn der Build fehlschlgt. \ No newline at end of file +# The MIT License +# +# Copyright (c) 2004-2015, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Projects\ to\ build=Zu bauende Projekte +Trigger\ only\ if\ build\ is\ stable=Nur auslsen, wenn der Build stabil ist +Trigger\ even\ if\ the\ build\ is\ unstable=Auslsen, selbst wenn der Build instabil ist +Trigger\ even\ if\ the\ build\ fails=Auslsen, selbst wenn der Build fehlschlgt \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/BuildTrigger/config_sr.properties b/core/src/main/resources/hudson/tasks/BuildTrigger/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0065e35dc1fbe08bed686f135821bf303299bb41 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/BuildTrigger/config_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Trigger\ only\ if\ build\ is\ stable=\u0418\u0437\u0430\u0437\u043E\u0432\u0438 \u0441\u0430\u043C\u043E \u0430\u043A\u043E \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 +Trigger\ even\ if\ the\ build\ is\ unstable=\u0418\u0437\u0430\u0437\u043E\u0432\u0438 \u0447\u0430\u043A \u0438 \u0430\u043A\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 +Trigger\ even\ if\ the\ build\ fails=\u0418\u0437\u0430\u0437\u043E\u0432\u0438 \u0447\u0430\u043A \u0438 \u0430\u043A\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u0431\u0443\u0434\u0435 \u0443\u0441\u043F\u0435\u043B\u0430 +Projects\ to\ build=\u041F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_sr.properties b/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2af320ae8fa9fc3a91676e825625f9ca1b62b96c --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/FingerprintAction/index_sr.properties @@ -0,0 +1,9 @@ +# This file is under the MIT License by authors + +Recorded\ Fingerprints=\u0417\u0430\u0431\u0435\u043B\u0435\u0436\u0435\u043D\u0435 \u043E\u0441\u0442\u0438\u0441\u043A\u0435 +File=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 +Original\ owner=\u041E\u0440\u0438\u0433\u0438\u043D\u0430\u043B\u043D\u0438 \u0432\u043B\u0430\u0441\u043D\u0438\u043A +Age=\u0421\u0442\u0430\u0440\u043E\u0441\u0442 +outside\ Jenkins=\u0441\u043F\u043E\u0459\u043E\u043C Jenkins-\u0430 +this\ build=\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +more\ details=\u0414\u0435\u0442\u0430\u0459\u0438 \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Fingerprinter/config_sr.properties b/core/src/main/resources/hudson/tasks/Fingerprinter/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0c97635891ca966630bafa58c07a5a50a7b7de9b --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Fingerprinter/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Files\ to\ fingerprint=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0437\u0430 \u043E\u0442\u0438\u0441\u0430\u043A diff --git a/core/src/main/resources/hudson/tasks/LogRotator/config_bg.properties b/core/src/main/resources/hudson/tasks/LogRotator/config_bg.properties index 090901ab68dfe431bb0a57b8c44960a6215b1b89..39f0694dfcae5db7461f880d41c6fc87532f766f 100644 --- a/core/src/main/resources/hudson/tasks/LogRotator/config_bg.properties +++ b/core/src/main/resources/hudson/tasks/LogRotator/config_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,6 +20,25 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Days\ to\ keep\ artifacts=\u0414\u043D\u0438, \u043F\u0440\u0435\u0437 \u043A\u043E\u0438\u0442\u043E \u0434\u0430 \u0441\u0435 \u043F\u0430\u0437\u044F\u0442 \u0430\u0440\u0442\u0438\u0444\u0430\u043A\u0442\u0438\u0442\u0435 -Days\ to\ keep\ builds=\u0414\u043D\u0438, \u043F\u0440\u0435\u0437 \u043A\u043E\u0438\u0442\u043E \u0434\u0430 \u0441\u0435 \u043F\u0430\u0437\u044F\u0442 \u0431\u0438\u043B\u0434\u043E\u0432\u0435\u0442\u0435 -if\ not\ empty,\ only\ up\ to\ this\ number\ of\ build\ records\ are\ kept=\u0430\u043A\u043E \u043D\u0435 \u0435 \u043F\u0440\u0430\u0437\u043D\u043E, \u0434\u0430 \u0441\u0435 \u043F\u0430\u0437\u044F\u0442 \u0441\u0430\u043C\u043E \u0442\u043E\u043B\u043A\u043E\u0432\u0430 \u0437\u0430\u043F\u0438\u0441\u0438 \u0437\u0430 \u0431\u0438\u043B\u0434\u043E\u0432\u0435 +Days\ to\ keep\ artifacts=\ + \u0411\u0440\u043e\u0439 \u0434\u043d\u0438 \u0437\u0430 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 +Days\ to\ keep\ builds=\ + \u0411\u0440\u043e\u0439 \u0434\u043d\u0438 \u0437\u0430 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +if\ not\ empty,\ only\ up\ to\ this\ number\ of\ build\ records\ are\ kept=\ + \u043f\u0440\u0438 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0441\u0435 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u0442 \u043d\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442 \u0442\u043e\u0437\u0438 \u0431\u0440\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 \u0437\u0430\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +if\ not\ empty,\ only\ up\ to\ this\ number\ of\ builds\ have\ their\ artifacts\ retained=\ + \u043f\u0440\u0438 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0441\u0435 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u0442 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 \u043e\u0442 \u043d\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442 \u0442\u043e\u0437\u0438 \u0431\u0440\u043e\u0439\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +Max\ \#\ of\ builds\ to\ keep=\ + \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u0435\u043d \u0431\u0440\u043e\u0439 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0438 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 +if\ not\ empty,\ build\ records\ are\ only\ kept\ up\ to\ this\ number\ of\ days=\ + \u043f\u0440\u0438 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0437\u0430\u043f\u0438\u0441\u0438\u0442\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u0441\u0435 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u0442 \u043d\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442\ + \u043f\u043e\u0441\u043e\u0447\u0435\u043d\u0438\u044f \u0431\u0440\u043e\u0439 \u0434\u043d\u0438 +if\ not\ empty,\ artifacts\ from\ builds\ older\ than\ this\ number\ of\ days\ will\ be\ deleted,\ but\ the\ logs,\ history,\ reports,\ etc\ for\ the\ build\ will\ be\ kept=\ + \u043f\u0440\u0438 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438\u0442\u0435 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u0441\u0435 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u0442 \u043d\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442\ + \u043f\u043e\u0441\u043e\u0447\u0435\u043d\u0438\u044f \u0431\u0440\u043e\u0439 \u0434\u043d\u0438, \u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0438\u0442\u0435 (\u0436\u0443\u0440\u043d\u0430\u043b\u0438, \u0438\u0441\u0442\u043e\u0440\u0438\u044f, \u0434\u043e\u043a\u043b\u0430\u0434\u0438) \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430\ + \u0441\u0435 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u0442 \u0437\u0430\u0432\u0438\u043d\u0430\u0433\u0438 +Max\ \#\ of\ builds\ to\ keep\ with\ artifacts=\ + \u043f\u0440\u0438 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438\u0442\u0435 \u043e\u0442 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 \u0441\u0435 \u0441\u044a\u0445\u0440\u0430\u043d\u044f\u0432\u0430\u0442 \u043d\u0435 \u043f\u043e\u0432\u0435\u0447\u0435 \u043e\u0442\ + \u043f\u043e\u0441\u043e\u0447\u0435\u043d\u0438\u044f \u0431\u0440\u043e\u0439 \u0434\u043d\u0438 diff --git a/core/src/main/resources/hudson/tasks/LogRotator/config_pl.properties b/core/src/main/resources/hudson/tasks/LogRotator/config_pl.properties index a6aa76c5ae8168a39936a2dd471caab07da785a1..ff13ee9006df17a7fc434d80b3ac0875e709e1b0 100644 --- a/core/src/main/resources/hudson/tasks/LogRotator/config_pl.properties +++ b/core/src/main/resources/hudson/tasks/LogRotator/config_pl.properties @@ -1,4 +1,30 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Copyright (c) 2004-2016, Sun Microsystems, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. Days\ to\ keep\ artifacts=Ilo\u015B\u0107 dni przechowywania artefaktu -Days\ to\ keep\ builds=Ilo\u015B\u0107 dni przechowywania builda +Days\ to\ keep\ builds=Maksymalny czas przechowywania w dniach +if\ not\ empty,\ build\ records\ are\ only\ kept\ up\ to\ this\ number\ of\ days=Je\u015Bli nie jest puste, zadania s\u0105 przechowywane tyle dni, ile podano +if\ not\ empty,\ only\ up\ to\ this\ number\ of\ build\ records\ are\ kept=Je\u015Bli nie jest puste, przechowywanych jest tyle zada\u0144, ile podano +Max\ \#\ of\ builds\ to\ keep\ with\ artifacts=Maksymalna ilo\u015B\u0107 zada\u0144 przechowywanych z artefaktami +if\ not\ empty,\ only\ up\ to\ this\ number\ of\ builds\ have\ their\ artifacts\ retained=Je\u015Bli nie jest puste, przechowywanych jest tyle zada\u0144 z artefaktami, ile podano +if\ not\ empty,\ artifacts\ from\ builds\ older\ than\ this\ number\ of\ days\ will\ be\ deleted,\ but\ the\ logs,\ history,\ reports,\ etc\ for\ the\ build\ will\ be\ kept=Je\u015Bli nie jest puste, artefakty z zada\u0144 starsze ni\u017C podana ilo\u015B\u0107 dni b\u0119d\u0105 usuni\u0119te, ale rejestr zdarze\u0144, historia, raporty itp b\u0119d\u0105 zachowane +Max\ \#\ of\ builds\ to\ keep=Maksymalna ilo\u015B\u0107 zada\u0144 do przechowania diff --git a/core/src/main/resources/hudson/tasks/LogRotator/config_sr.properties b/core/src/main/resources/hudson/tasks/LogRotator/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..60ccb45301a83d175466af95215560639ea8e40f --- /dev/null +++ b/core/src/main/resources/hudson/tasks/LogRotator/config_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +Days\ to\ keep\ builds=\u0411\u0440\u043E\u0458 \u0434\u0430\u043D\u0430 \u0437\u0430 \u0447\u0443\u0432\u0430\u045A\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +if\ not\ empty,\ build\ records\ are\ only\ kept\ up\ to\ this\ number\ of\ days=\u0410\u043A\u043E \u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E, \u0431\u0440\u043E\u0458 \u0434\u0430\u043D\u0430 \u0437\u0430 \u0447\u0443\u0432\u0430\u045A\u0435 \u0438\u0441\u043A\u0430\u0437\u0435 \u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438. +Max\ \#\ of\ builds\ to\ keep=\u041A\u043E\u043B\u0438\u043A\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0437\u0430 \u0447\u0443\u0432\u0430\u045A\u0435 +if\ not\ empty,\ only\ up\ to\ this\ number\ of\ build\ records\ are\ kept=\u0410\u043A\u043E \u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E, \u0431\u0440\u043E\u0458 \u0437\u0430\u043F\u0438\u0441\u0430 \u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438 \u0437\u0430 \u0447\u0443\u0432\u0430\u045A\u0435. +if\ not\ empty,\ artifacts\ from\ builds\ older\ than\ this\ number\ of\ days\ will\ be\ deleted,\ but\ the\ logs,\ history,\ reports,\ etc\ for\ the\ build\ will\ be\ kept= +Max\ \#\ of\ builds\ to\ keep\ with\ artifacts=\u041C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u0430\u043D \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u045A\u0430 \u043A\u043E\u0458\u0430 \u045B\u0435 \u0431\u0438\u0442\u0438 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0430 \u0437\u0430\u0458\u0435\u0434\u043D\u043E \u0441\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438\u043C\u0430 +if\ not\ empty,\ only\ up\ to\ this\ number\ of\ builds\ have\ their\ artifacts\ retained=\u0410\u043A\u043E \u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E, \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0447\u0438\u0458\u0438 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 \u045B\u0435 \u0431\u0438\u0442\u0438 \u0441\u0430\u0447\u0443\u0432\u0430\u045A\u0438. +Days\ to\ keep\ artifacts=\u041A\u043E\u043B\u0438\u043A\u043E \u0434\u0430\u043D\u0430 \u0434\u0430 \u0441\u0435 \u0447\u0443\u0432\u0430\u0458\u0443 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 diff --git a/core/src/main/resources/hudson/tasks/Maven/MavenInstallation/config_sr.properties b/core/src/main/resources/hudson/tasks/Maven/MavenInstallation/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2fbb8bde38001bf90e43c02d70be99315bd965fa --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Maven/MavenInstallation/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 diff --git a/core/src/main/resources/hudson/tasks/Maven/config.jelly b/core/src/main/resources/hudson/tasks/Maven/config.jelly index 4ec0da1d82d5dd1319ce8e68f2de1f4fdab431b3..e2c26ad4e757f5bbe97fbf3a20520714b2810b35 100644 --- a/core/src/main/resources/hudson/tasks/Maven/config.jelly +++ b/core/src/main/resources/hudson/tasks/Maven/config.jelly @@ -47,11 +47,14 @@ THE SOFTWARE. + + + - + - + - \ No newline at end of file + diff --git a/core/src/main/resources/hudson/tasks/Maven/config_bg.properties b/core/src/main/resources/hudson/tasks/Maven/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..11dff5faa966a23f0888f0fd89e2b28d36c65b0e --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Maven/config_bg.properties @@ -0,0 +1,42 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Default=\ + \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438 +JVM\ Options=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 JVM +Settings\ file=\ + \u0424\u0430\u0439\u043b \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +Goals=\ + \u0426\u0435\u043b\u0438 +POM=\ + POM +Global\ Settings\ file=\ + \u0424\u0430\u0439\u043b \u0441 \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +Use\ private\ Maven\ repository=\ + \u0418\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0447\u0430\u0441\u0442\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043d\u0430 Maven +Properties=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 +Maven\ Version=\ + \u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Maven +Inject\ build\ variables=\ + \u0412\u043c\u044a\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0438 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e diff --git a/core/src/main/resources/hudson/tasks/Maven/config_de.properties b/core/src/main/resources/hudson/tasks/Maven/config_de.properties index 331c887901e16ba0d8332d19ea5b51c6c5c4850c..aea56f22f937b6c8c08f97a815ab01bcd4b87949 100644 --- a/core/src/main/resources/hudson/tasks/Maven/config_de.properties +++ b/core/src/main/resources/hudson/tasks/Maven/config_de.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# Copyright (c) 2004-2015, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,12 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Maven\ Version=Maven Version +Maven\ Version=Maven-Version Default=Standard Goals=Goals POM=POM Properties=Eigenschaften ("properties") JVM\ Options=JVM-Optionen Use\ private\ Maven\ repository=Privates Maven-Repository verwenden +Settings\ file=Settings-Datei +Global\ Settings\ file=Globale Settings-Datei diff --git a/core/src/main/resources/hudson/tasks/Maven/config_sr.properties b/core/src/main/resources/hudson/tasks/Maven/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..670a5b13eaaf981358cb4d6e855fa47848dbfc27 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Maven/config_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +Maven\ Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 Maven-\u0430 +Default=\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u043E +Goals=\u0426\u0438\u0459\u0435\u0432\u0438 +POM=POM +Properties=\u041F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 +JVM\ Options=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 JVM +Inject\ build\ variables=\u0423\u0431\u0430\u0446\u0438\u0432\u0430\u045A\u0435 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +Use\ private\ Maven\ repository=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u043F\u0440\u0438\u0432\u0430\u0442\u043D\u043E Maven \u0441\u043F\u0440\u0435\u043C\u0438\u0448\u0442\u0435 +Settings\ file=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +Global\ Settings\ file=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0433\u043B\u043E\u0431\u0430\u043B\u043D\u0438\u0445 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html new file mode 100644 index 0000000000000000000000000000000000000000..6bf14bbfb23543dae13e4371c2e5818989b3499f --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Maven/help-injectBuildVariables.html @@ -0,0 +1,5 @@ +
      + Pass all build variables into maven process in form of java properties. This is seldom needed as Jenkins provides it as + environment variables anyway. Preferred way to access Jenkins build variables is to explicitly map it to property in + Properties section (MY_VAR=${MY_VAR}). +
      diff --git a/core/src/main/resources/hudson/tasks/Maven/help_sr.properties b/core/src/main/resources/hudson/tasks/Maven/help_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c1657bcbbf13dda58cf8b4c61afe22c1f98e81f1 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Maven/help_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +para1=\u0417\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 \u043A\u043E\u0458\u0438 \u043A\u043E\u0440\u0438\u0441\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043C \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 Maven. \u041E\u0432\u043E \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u045B\u0435 \u0443\u043A\u0430\u0437\u0430\u0442\u0438 \u0434\u0430 Jenkins \u043A\u043E\u0440\u0438\u0441\u0442\u0438 Maven \u0441\u0430 \u0434\u0430\u0442\u0438\u043C \u0446\u0438\u0459\u0435\u0432\u0438\u043C\u0430 \u0438 \u043E\u043F\u0446\u0438\u0458\u0430\u043C\u0430. \u0410\u043A\u043E Maven \u0437\u0430\u0432\u0440\u0448\u0438 \u0441\u0430 \u043D\u0435\u043D\u0443\u043B\u043D\u0438\u043C \u043A\u043E\u0434\u043E\u043C, \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u045B\u0435 \u0441\u0435 \u0441\u043C\u0430\u0442\u0440\u0430\u0442\u0438 \u043D\u0435\u0443\u0441\u043F\u0435\u043D\u043E\u0433. \u041C\u0435\u0452\u0443\u0442\u0438\u043C \u043D\u0435\u043A\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0435 Maven \u0438\u043C\u0430\u0458\u0443 \u0433\u0440\u0435\u0448\u043A\u0443 \u043A\u043E\u0458\u0430 \u0432\u0440\u0430\u045B\u0430 \u043F\u043E\u0433\u0440\u0435\u0448\u0430\u043D \u043A\u043E\u0434 \u043F\u043E \u0437\u0430\u0432\u0440\u0448\u0435\u0442\u043A\u0443. +para2=Jenkins \u043F\u0440\u0435\u043D\u0435\u0441\u0435 \ + \u0440\u0430\u0437\u043D\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 Maven-\u0443, \u043A\u043E\u0458\u0430 \u0441\u0443 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043F\u043E \u0448\u0430\u0431\u043B\u043E\u043D\u0443 "$'{'env.VARIABLENAME}". +para3=\u0422\u0435 \u0438\u0441\u0442\u0435 \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0435 \u043C\u043E\u0433\u0443 \u0441\u0435 \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u043F\u0440\u0435\u043A\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 (\u0430\u043A\u043E \u043F\u043E\u0437\u043E\u0432\u0435\u0442\u0435 Maven \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435). \u041D\u0430 \u043F\u0440\u0438\u043C\u0435\u0440, \u043C\u043E\u0436\u0435\u0442\u0435 \u0434\u0430 \u043E\u0434\u0440\u0435\u0434\u0438\u0442\u0435 diff --git a/core/src/main/resources/hudson/tasks/Messages.properties b/core/src/main/resources/hudson/tasks/Messages.properties index f7ceb03840cf05f6cd5796681f514f8148e9f3e5..67417b1e72bef9796a38504657503246b2803d98 100644 --- a/core/src/main/resources/hudson/tasks/Messages.properties +++ b/core/src/main/resources/hudson/tasks/Messages.properties @@ -39,6 +39,8 @@ If you really did mean to archive all the files in the workspace, please specify ArtifactArchiver.NoMatchFound=No artifacts found that match the file pattern "{0}". Configuration error? BatchFile.DisplayName=Execute Windows batch command +BatchFile.invalid_exit_code_range=Invalid errorlevel value: {0}. Check help section +BatchFile.invalid_exit_code_zero=ERRORLEVEL zero is ignored and does not make the build unstable BuildTrigger.Disabled={0} is disabled. Triggering skipped BuildTrigger.DisplayName=Build other projects @@ -47,6 +49,7 @@ BuildTrigger.NoSuchProject=No such project \u2018{0}\u2019. Did you mean \u2018{ BuildTrigger.NoProjectSpecified=No project specified BuildTrigger.NotBuildable={0} is not buildable BuildTrigger.Triggering=Triggering a new build of {0} +BuildTrigger.ok_ancestor_is_null=Ancestor/Context Unknown: the project specified cannot be validated BuildTrigger.warning_access_control_for_builds_in_glo=Warning: \u2018Access Control for Builds\u2019 in global security configuration is empty, so falling back to legacy behavior of permitting any downstream builds to be triggered BuildTrigger.warning_this_build_has_no_associated_aut=Warning: this build has no associated authentication, so build permissions may be lacking, and downstream projects which cannot even be seen by an anonymous user will be silently skipped BuildTrigger.warning_you_have_no_plugins_providing_ac=Warning: you have no plugins providing access control for builds, so falling back to legacy behavior of permitting any downstream builds to be triggered @@ -80,3 +83,5 @@ Maven.NotMavenDirectory={0} doesn\u2019t look like a Maven directory Maven.NoExecutable=Couldn\u2019t find any executable in {0} Shell.DisplayName=Execute shell +Shell.invalid_exit_code_range=Invalid exit code value: {0}. Check help section +Shell.invalid_exit_code_zero=Exit code zero is ignored and does not make the build unstable \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Messages_bg.properties b/core/src/main/resources/hudson/tasks/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..efeb1a84fb84138ee6291c8a9d904dfac9dfddf2 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Messages_bg.properties @@ -0,0 +1,139 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Ant.DisplayName=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 ant. +Ant.ExecFailed=\ + \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430. +Ant.ExecutableNotFound=\ + \u0412 \u0443\u043a\u0430\u0437\u0430\u043d\u0430\u0442\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f \u043d\u0430 ant \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043e\u0442\u043a\u0440\u0438\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u043c\u0438\u044f\u0442 \u0444\u0430\u0439\u043b. +Ant.GlobalConfigNeeded=\ + \u041f\u0440\u043e\u0431\u0432\u0430\u0439\u0442\u0435 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 ant. +Ant.NotADirectory=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f. +Ant.NotAntDirectory=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441 ant. +Ant.ProjectConfigNeeded= \ + \u041f\u0440\u043e\u0431\u0432\u0430\u0439\u0442\u0435 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0438\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f\u0442\u0430 \u043d\u0430 ant \u0437\u0430 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430. + +ArtifactArchiver.ARCHIVING_ARTIFACTS=\ + \u0410\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438\u0442\u0435 +ArtifactArchiver.DisplayName=\ + \u0410\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438\u0442\u0435 +ArtifactArchiver.SkipBecauseOnlyIfSuccessful=\ + \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043d\u0435\u0442\u043e, \u0437\u0430\u0449\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e. +ArtifactArchiver.FailedToArchive=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438: {0} +ArtifactArchiver.NoIncludes=\ + \u041d\u0435 \u0441\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u0438 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u0438 \u0437\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043d\u0435.\n\ + \u041f\u0440\u043e\u0431\u0432\u0430\u0439\u0442\u0435 \u0434\u0430 \u0443\u043a\u0430\u0436\u0435\u0442\u0435 \u0448\u0430\u0431\u043b\u043e\u043d \u0437\u0430 \u0438\u043c\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435.\n\ + \u0410\u043a\u043e \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u0442\u0435 \u0432\u0441\u0438\u0447\u043a\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435 \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043c\u044f\u0441\u0442\u043e, \u0443\u043a\u0430\u0436\u0435\u0442\u0435 \u201e**\u201c. +ArtifactArchiver.NoMatchFound=\ + \u041d\u0438\u043a\u043e\u0439 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442 \u043d\u0435 \u0441\u044a\u0432\u043f\u0430\u0434\u0430 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 \u201e{0}\u201c. \u0422\u043e\u0432\u0430 \u0433\u0440\u0435\u0448\u043a\u0430 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043b\u0438 \u0435? + +BatchFile.DisplayName=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0438 \u0441 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 \u043d\u0430 Windows + +BuildTrigger.Disabled=\ + \u0417\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u201e{0}\u201c \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d\u0430. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u045d +BuildTrigger.DisplayName=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0434\u0440\u0443\u0433\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438 +BuildTrigger.InQueue=\ + \u201e{0}\u201c \u0432\u0435\u0447\u0435 \u0435 \u0432 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430 +BuildTrigger.NoSuchProject=\ + \u041d\u044f\u043c\u0430 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0438\u043c\u0435 \u201e{0}\u201c. \u201e{1}\u201c \u043b\u0438 \u0438\u043c\u0430\u0442\u0435 \u043f\u0440\u0435\u0434\u0432\u0438\u0434? +BuildTrigger.NoProjectSpecified=\ + \u041d\u0435 \u0435 \u0443\u043a\u0430\u0437\u0430\u043d \u043f\u0440\u043e\u0435\u043a\u0442 +BuildTrigger.NotBuildable=\ + \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438 +BuildTrigger.Triggering=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c +BuildTrigger.warning_access_control_for_builds_in_glo=\ + \u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u041f\u043e\u043b\u0435\u0442\u043e \u201e\u041f\u0440\u0430\u0432\u0430 \u0437\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430\u201c \u0432 \u043e\u0431\u0449\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\ + \u0437\u0430 \u0441\u0438\u0433\u0443\u0440\u043d\u043e\u0441\u0442\u0442\u0430 \u043d\u0435 \u0435 \u043f\u043e\u043f\u044a\u043b\u043d\u0435\u043d\u043e. \u0429\u0435 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u0441\u0442\u0430\u0440\u044f\u043b\u043e\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0430\ + \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0438, \u0437\u0430\u0432\u0438\u0441\u0435\u0449\u0438 \u043e\u0442 \u0442\u0430\u0437\u0438 +BuildTrigger.warning_this_build_has_no_associated_aut=\ + \u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u043b\u0438\u043f\u0441\u0432\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0437\u0430 \u0442\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435, \u0437\u0430\u0442\u043e\u0432\u0430 \u0438 \u043f\u0440\u0430\u0432\u0430\u0442\u0430 \u043a\u044a\u043c\ + \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0430 \u043f\u044a\u043b\u043d\u0438. \u0417\u0430\u0432\u0438\u0441\u0435\u0449\u0438\u0442\u0435 \u043e\u0442 \u0442\u043e\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0438, \u043a\u043e\u0438\u0442\u043e\ + \u043d\u0435 \u0441\u0435 \u0432\u0438\u0436\u0434\u0430\u0442 \u043e\u0442 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438, \u0449\u0435 \u0431\u044a\u0434\u0430\u0442 \u043f\u0440\u043e\u043f\u0443\u0441\u043d\u0430\u0442\u0438. +BuildTrigger.warning_you_have_no_plugins_providing_ac=\ + \u041f\u0420\u0415\u0414\u0423\u041f\u0420\u0415\u0416\u0414\u0415\u041d\u0418\u0415: \u043b\u0438\u043f\u0441\u0432\u0430\u0442 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043f\u0440\u0430\u0432\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. \u0429\u0435\ + \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043e\u0441\u0442\u0430\u0440\u044f\u043b\u043e\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438\ + \u0437\u0430\u0434\u0430\u0447\u0438, \u0437\u0430\u0432\u0438\u0441\u0435\u0449\u0438 \u043e\u0442 \u0442\u0430\u0437\u0438 +BuildTrigger.you_have_no_permission_to_build_=\ + \u041d\u044f\u043c\u0430\u0442\u0435 \u043f\u0440\u0430\u0432\u0430 \u0434\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0435 \u201e{0}\u201c + +CommandInterpreter.CommandFailed=\ + \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 +CommandInterpreter.UnableToDelete=\ + \u0421\u043a\u0440\u0438\u043f\u0442\u044a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0442\u0440\u0438\u0435 \u201e{0}\u201c +CommandInterpreter.UnableToProduceScript=\ + \u041d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0430 \u0441\u043a\u0440\u0438\u043f\u0442 + +Fingerprinter.Aborted=\ + \u041f\u0440\u0435\u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0435\u043d\u043e +Fingerprinter.Action.DisplayName=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u0446\u0438 +Fingerprinter.DigestFailed=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0447\u0438\u0441\u043b\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u044f \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u043a \u043d\u0430 \u201e{0}\u201c +Fingerprinter.DisplayName=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u0446\u0438 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0437\u0430 \u043f\u0440\u043e\u0441\u043b\u0435\u0434\u044f\u0432\u0430\u043d\u0435 \u043d\u0430\ + \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e +Fingerprinter.Failed=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u0446\u0438 +Fingerprinter.FailedFor=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u044f \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u043a \u043d\u0430 \u201e{0}\u201c +Fingerprinter.Recording=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u0442\u0435 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u0446\u0438 + +InstallFromApache=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043e\u0442 \u0441\u0430\u0439\u0442\u0430 \u043d\u0430 Apache + +JavadocArchiver.DisplayName=\ + \u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 Java +JavadocArchiver.DisplayName.Generic=\ + \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 +JavadocArchiver.DisplayName.Javadoc=\ + \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0437\u0430 Java +TestJavadocArchiver.DisplayName.Javadoc=\ + \u0422\u0435\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 Java +JavadocArchiver.NoMatchFound=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0437\u0430 Java \u0432 \u201e{0}\u201c: {1} +JavadocArchiver.Publishing=\ + \u041f\u0443\u0431\u043b\u0438\u043a\u0443\u0432\u0430\u043d\u0435 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 Java +JavadocArchiver.UnableToCopy=\ + \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f\u0442\u0430 \u0437\u0430 Java \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043a\u043e\u043f\u0438\u0440\u0430 \u043e\u0442 \u201e{0}\u201c \u0432 \u201e{1}\u201c + +Maven.DisplayName=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0430 \u0446\u0435\u043b \u043d\u0430 Maven +Maven.ExecFailed=\ + \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 +Maven.NotMavenDirectory=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 Maven +Maven.NoExecutable=\ + \u041d\u044f\u043c\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0438\u043c \u0444\u0430\u0439\u043b \u0432 \u201e{0}\u201c + +Shell.DisplayName=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0435\u043d \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440 +# Ancestor/Context Unknown: the project specified cannot be validated +BuildTrigger.ok_ancestor_is_null=\ + \u041d\u0435\u043f\u043e\u0437\u043d\u0430\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b/\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442: \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438 diff --git a/core/src/main/resources/hudson/tasks/Messages_sr.properties b/core/src/main/resources/hudson/tasks/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a5eee350c3bbf8259165e4e464d3a62ed3a2a2c8 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Messages_sr.properties @@ -0,0 +1,55 @@ +# This file is under the MIT License by authors + +Ant.DisplayName=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 Ant +Ant.ExecFailed=\u0438\u0437\u0431\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E. +Ant.ExecutableNotFound=\u0423 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u043E\u0458 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0438 Ant "{0}" \u043D\u0438\u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0430. +Ant.GlobalConfigNeeded=\u041F\u043E\u043A\u0443\u0448\u0430\u0458\u0442\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u0434\u0430 \u043D\u0430\u0432\u0435\u0434\u0435\u0442\u0435 \u043B\u043E\u043A\u0430\u0446\u0438\u0458\u0443 Ant \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435. +Ant.NotADirectory={0} \u043D\u0438\u0458\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C +Ant.NotAntDirectory={0} \u043D\u0438\u0458\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0437\u0430 Ant +Ant.ProjectConfigNeeded=\u041F\u043E\u043A\u0443\u0448\u0430\u0458\u0442\u0435 \u0434\u0430 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u0430\u043A \u0434\u0430 \u0438\u0437\u0430\u0431\u0435\u0440\u0435\u0442\u0435 \u043C\u0435\u0441\u0442\u043E \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435 Ant. +ArtifactArchiver.ARCHIVING_ARTIFACTS=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u045A\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 +ArtifactArchiver.DisplayName=\u0410\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u0458 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438 +ArtifactArchiver.SkipBecauseOnlyIfSuccessful=\u041F\u0440\u0435\u0441\u043A\u043E\u045B\u0430\u0432\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u045A\u0435 \u0437\u0430\u0448\u0442\u043E \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430 +ArtifactArchiver.FailedToArchive=\u041D\u0435\u0443\u0441\u043F\u0440\u0435\u0448\u043D\u043E \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u045A\u0435 \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442\u0438: {0} +ArtifactArchiver.NoIncludes=\u041D\u0435\u043C\u0430 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u0445 \u043F\u0440\u0435\u0434\u043C\u0435\u0442\u0430 \u0437\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u045A\u0435.\n\ +\u0418\u0437\u0433\u043B\u0435\u0434\u0430 \u0434\u0430 \u043D\u0438\u0441\u0442\u0435 \u043D\u0430\u0432\u0435\u043B\u0438 \u0448\u0430\u0431\u043B\u043E\u043D \u0438\u043C\u0435\u043D\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u0432\u0440\u0430\u0442\u0438\u0442\u0435 \u0441\u0435 \u043D\u0430 \u0442\u0430\u0458 \u0435\u043A\u0440\u0430\u043D \u0438 \u0443\u043D\u0435\u0441\u0438\u0442\u0435 \u0433\u0430.\n\ +\u0410\u043A\u043E \u0437\u0430\u0438\u0441\u0442\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430 \u0441\u0432\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0443 \u0440\u0430\u0434\u043D\u043E\u043C \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0443, \u0443\u043D\u0435\u0441\u0438\u0442\u0435 "**" +ArtifactArchiver.NoMatchFound=\u041D\u0438 \u0458\u0435\u0434\u0430\u043D \u0430\u0440\u0442\u0435\u0444\u0430\u043A\u0442 \u0441\u0435 \u043D\u0435 \u043F\u043E\u043A\u043B\u0430\u043F\u0430 \u0441\u0430 \u0448\u0430\u0431\u043B\u043E\u043D\u043E\u043C "{0}". \u0414\u0430\u043B\u0438 \u0438\u043C\u0430 \u0433\u0440\u0435\u0448\u0430\u043A\u0430 \u0443 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0443? +BatchFile.DisplayName=\u0418\u0437\u0432\u0440\u0448\u0438 Windows \u043A\u043E\u043C\u0430\u043D\u0434\u0443 +BuildTrigger.Disabled={0} \u0458\u0435 \u043E\u0431\u0443\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u0438 \u043D\u0435\u043C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0437\u0430\u0437\u043E\u0432\u0430\u0442\u0438 +BuildTrigger.DisplayName=\u0418\u0437\u0433\u0440\u0430\u0434\u0438 \u0434\u0440\u0443\u0433\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 +BuildTrigger.InQueue={0} \u0458\u0435 \u0432\u0435\u045B \u0443 \u0440\u0435\u0434\u0443 +BuildTrigger.NoSuchProject=\u041D\u0435\u043C\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 ''{0}''. \u0414\u0430\u043B\u0438 \u0441\u0442\u0435 \u043C\u0438\u0441\u043B\u0438\u043B\u0438 ''{1}''? +BuildTrigger.NoProjectSpecified=\u041D\u0438\u0458\u0435 \u043D\u0430\u0432\u0435\u0434\u0435\u043D \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +BuildTrigger.NotBuildable={0} \u043D\u0435\u043C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0438 +BuildTrigger.Triggering=\u041F\u043E\u0447\u0438\u045A\u0435 \u043D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0437\u0430 {0} +BuildTrigger.ok_ancestor_is_null=\u041D\u0435\u043F\u043E\u0437\u043D\u0430\u0442 \u0440\u043E\u0434\u0438\u0442\u0435\u043B/\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442: \u043D\u0430\u0432\u0435\u0434\u0435\u043D \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u043F\u0440\u043E\u0432\u0435\u0440\u0435\u043D +BuildTrigger.warning_access_control_for_builds_in_glo=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043F\u043E\u0459\u0435 '\u041A\u043E\u043D\u0442\u0440\u043E\u043B\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0430' \u0443 \u043E\u043F\u0448\u0442\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0438\u043C\u0430 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442\u0438 \u043D\u0438\u0458\u0435 \u0438\u0441\u043F\u0443\u045A\u0435\u043Do. \u041A\u043E\u0440\u0438\u0441\u0442\u0438\u045B\u0435 \u0441\u0435 \u0441\u0442\u0430\u0440\u043E \u043F\u043E\u043D\u0430\u0448\u0430\u045A\u0435 \u043A\u043E\u0458\u0435 \u0434\u043E\u0437\u0432\u043E\u0459\u0430\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0441\u0432\u0438\u0445 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 \u043A\u043E\u0458\u0435 \u0437\u0430\u0432\u0438\u0441\u0435 \u043E\u0434 \u043E\u0432\u0435. +BuildTrigger.warning_this_build_has_no_associated_aut=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u043C\u0430 \u043A\u0430\u043D\u0430\u043B \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0435, \u043F\u0430 \u045B\u0435 \u0434\u043E\u0437\u0432\u043E\u043B\u0435 \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u0458\u0430\u0442\u0438 \u0438 \u043E\u043D\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \u043A\u043E\u0458\u0438 \u0437\u0430\u0432\u0438\u0441\u0435 \u043E\u0434 \u043E\u0432\u0435 \u0430 \u043D\u0438\u0441\u0443 \u0432\u0438\u0434\u0459\u0438\u0432\u0438 \u0430\u043D\u043E\u043D\u0438\u043C\u043D\u0438\u043C \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438\u043C\u0430, \u045B\u0435 \u0431\u0438\u0442\u0438 \u043F\u0440\u0435\u0441\u043A\u043E\u045B\u0435\u043D\u0438. +BuildTrigger.you_have_no_permission_to_build_=\u041D\u0435\u043C\u0430\u0442\u0435 \u043F\u0440\u0430\u0432\u043E \u0434\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u0438\u0442\u0435 {0} +CommandInterpreter.CommandFailed=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E +CommandInterpreter.UnableToDelete=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0438\u0437\u0431\u0440\u0438\u0441\u0430\u0442\u0438 \u0441\u043A\u0440\u0438\u043F\u0442 {0} +CommandInterpreter.UnableToProduceScript=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043A\u0440\u0435\u0438\u0440\u0430\u0442\u0438 \u0441\u043A\u0440\u0438\u043F\u0442 {0} +Fingerprinter.Aborted=\u041F\u0440\u0435\u043A\u0438\u043D\u0443\u0442\u043E +Fingerprinter.Action.DisplayName=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0445 \u043E\u0442\u0438\u0441\u0430\u043A\u0430 +Fingerprinter.DigestFailed=\u041D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E \u043E\u0431\u0440\u0430\u0447\u0443\u043D \u043D\u0430 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u043E\u043C \u043E\u0442\u0438\u0441\u043A\u0443 {0} +Fingerprinter.DisplayName=\u0421\u043D\u0438\u043C\u0438 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0435 \u043E\u0442\u0438\u0441\u043A\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0434\u0430 \u043F\u0440\u0430\u0442\u0438\u0442\u0435 \u045A\u0438\u0445\u043E\u0432\u0443 \u0443\u043F\u043E\u0442\u0435\u0431\u0440\u0443 +BuildTrigger.warning_you_have_no_plugins_providing_ac=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435: \u043D\u0435\u043C\u0430\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043A\u043E\u0458\u0435 \u0434\u0435\u043B\u0435 \u043F\u0440\u0438\u0441\u0442\u0443\u043F, \u043F\u0430 \u0441\u0435 \u0432\u0440\u0430\u045B\u0430 \u043D\u0430\u0437\u0430\u0434 \u043D\u0430 \u0440\u0435\u0436\u0438\u043C \u043A\u043E\u0458\u0438 \u0438\u0437\u0430\u0437\u0438\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0438\u0437\u0432\u0438\u0441\u043D\u0438\u0445 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. +Fingerprinter.Failed=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u043D\u0438\u043C\u0430\u045A\u0435 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0445 \u043E\u0442\u0438\u0441\u043A\u0430 +Fingerprinter.FailedFor=\u041D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0441\u043D\u0438\u043C\u0430\u045A\u0435 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0443 \u043E\u0442\u0438\u0441\u043A\u0443 \u0437\u0430 {0} +Fingerprinter.Recording=\u0421\u043D\u0438\u043C\u0430\u045A\u0435 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438\u0445 \u043E\u0442\u0438\u0441\u043A\u0430 +InstallFromApache=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u045A\u0435 \u043E\u0434 \u0441\u0430\u0438\u0442\u0430 Apache +JavadocArchiver.DisplayName=\u041F\u0443\u0431\u043B\u0438\u043A\u0443\u0458\u0442\u0435 Javadoc +JavadocArchiver.DisplayName.Javadoc=Javadoc +JavadocArchiver.DisplayName.Generic=\u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442 +TestJavadocArchiver.DisplayName.Javadoc=Test Javadoc +JavadocArchiver.NoMatchFound=\u041D\u0438\u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D Javadoc {0}: {1} +JavadocArchiver.Publishing=\u041F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u045A\u0435 Javadoc +JavadocArchiver.UnableToCopy=Javadoc \u043D\u0435\u043C\u043E\u0436\u0435 \u0431\u0438\u0442\u0438 \u0438\u0441\u043A\u043E\u043F\u0438\u0440\u0430\u043D \u043E\u0434 {0} \u043D\u0430 {1} +Maven.DisplayName=\u0418\u0437\u0432\u0440\u0448\u0438 \u0432\u0440\u0445\u043E\u0432\u043D\u0435 Maven \u0446\u0438\u0459\u0435\u0432\u0435 +Maven.ExecFailed=\u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \u0458\u0435 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u043E +Maven.NotMavenDirectory={0} \u043D\u0435 \u043B\u0438\u0447\u0438 \u043D\u0430 Maven \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C +Maven.NoExecutable=\u041D\u0438\u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u043E \u0438\u0437\u0432\u0440\u0448\u043D\u0430 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0443 {0} +Shell.DisplayName=\u0418\u0437\u0432\u0440\u0448\u0438 shell \u043A\u043E\u043C\u0430\u043D\u0434\u0443 +Maven.NotADirectory={0} \u043D\u0438\u0458\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C +Indien= \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Shell/config.groovy b/core/src/main/resources/hudson/tasks/Shell/config.groovy index 3e81fb53d44e2344e43687acabae6b4f0c81d85b..58c4880bf22ffecd7f705e8eeb18addc32c335e2 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config.groovy +++ b/core/src/main/resources/hudson/tasks/Shell/config.groovy @@ -27,3 +27,10 @@ f=namespace(lib.FormTagLib) f.entry(title:_("Command"),description:_("description",rootURL)) { f.textarea(name: "command", value: instance?.command, class: "fixed-width", 'codemirror-mode': 'shell', 'codemirror-config': "mode: 'text/x-sh'") } + +f.advanced() { + f.entry(title:_("Exit code to set build unstable"), field: "unstableReturn") { + f.number(clazz:"positive-number", value: instance?.unstableReturn, min:1, max:255, step:1) + } + +} diff --git a/core/src/main/resources/hudson/tasks/Shell/config.properties b/core/src/main/resources/hudson/tasks/Shell/config.properties index 5918ee6a1abad32630f30d40ae2c1a95e000c199..0d7b36f4a5a187009b57a54bbcab48a69a31434b 100644 --- a/core/src/main/resources/hudson/tasks/Shell/config.properties +++ b/core/src/main/resources/hudson/tasks/Shell/config.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -description=See the list of available environment variables \ No newline at end of file +description=See the list of available environment variables diff --git a/core/src/main/resources/hudson/tasks/Shell/config_sr.properties b/core/src/main/resources/hudson/tasks/Shell/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1b4980ff65f0b0cb6022d17b6023366771e0455d --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Shell/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +description=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0441\u043F\u0438\u0441\u0430\u043A \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0430 +Command=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Shell/global_sr.properties b/core/src/main/resources/hudson/tasks/Shell/global_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..aa7f83e47ac5d202177f531b0b894e3aff2fc950 --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Shell/global_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Shell=\u0409\u0443\u0441\u043A\u0430 +Shell\ executable=\u041F\u0443\u0442 \u0434\u043E \u0459\u0443\u0441\u043A\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/tasks/Shell/help-unstableReturn.html b/core/src/main/resources/hudson/tasks/Shell/help-unstableReturn.html new file mode 100644 index 0000000000000000000000000000000000000000..bc6426fa3dfb02a2e8e09105f0b368d91b04e16c --- /dev/null +++ b/core/src/main/resources/hudson/tasks/Shell/help-unstableReturn.html @@ -0,0 +1,5 @@ +
      + If set, the shell exit code that will be interpreted as an unstable build result. If the exit code matches the value, + the build results will be set to 'unstable' and next steps will be continued. On Unix-like it is a value between 0-255. + The value 0 is ignored and does not make the build unstable to keep the default behaviour consistent. +
      diff --git a/core/src/main/resources/hudson/tasks/Shell/help_fr.html b/core/src/main/resources/hudson/tasks/Shell/help_fr.html index 9979cbce153ce633d576e7cfbc76e385b45d3b11..109ebce63a99f31ee26d47a4ec778a7d3bc426a2 100644 --- a/core/src/main/resources/hudson/tasks/Shell/help_fr.html +++ b/core/src/main/resources/hudson/tasks/Shell/help_fr.html @@ -1,19 +1,19 @@
      - Lance un script Shell (par dfaut l'aide de sh, mais cela est configurable) pour construire le projet. - Le script sera lanc avec le workspace comme rpertoire courant. + Lance un script Shell (par défaut à l'aide de sh, mais cela est configurable) pour construire le projet. + Le script sera lancé avec le workspace comme répertoire courant. Entrez le contenu de votre script shell. Si votre script n'a pas de ligne de titre du type #!/bin/sh, - alors le shell configur pour l'ensemble du systme sera utilis. + alors le shell configuré pour l'ensemble du système sera utilisé. Si votre script contient une telle ligne, vous pourrez utiliser un autre langage de script - (comme #!/bin/perl) ou contrler les options que le shell utilise. + (comme #!/bin/perl) ou contrôler les options que le shell utilise.

      - Par dfaut, le shell sera invoqu avec l'option "-ex". Par consquent, toutes les commandes seront - affiches avant d'tre excutes et le build sera considr en chec si l'une de ces commandes - renvoie un code de retour diffrent de zro. + Par défaut, le shell sera invoqué avec l'option "-ex". Par conséquent, toutes les commandes seront + affichées avant d'être exécutées et le build sera considéré en èchec si l'une de ces commandes + renvoie un code de retour différent de zéro. Encore une fois, vous pouvez ajouter la ligne #!/bin/... pour modifier ce comportement.

      - Une bonne pratique est de ne pas mettre un long script ici. A la place, pensez ajouter le script shell + Une bonne pratique est de ne pas mettre un long script ici. A la place, pensez à ajouter le script shell dans l'outil de gestion de configuration et appelez simplement ce script depuis Jenkins. - Ainsi, vous garderez trace des changements apports votre script. + Ainsi, vous garderez trace des changements apportés à votre script.

      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/config_sr.properties b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..de532cad164042ca3914b5615f757736977827b3 --- /dev/null +++ b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Command=\u041A\u043E\u043C\u0430\u043D\u0434\u0430 +Tool\ Home=\u0413\u043B\u0430\u0432\u043D\u0438 \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u0430\u043B\u0430\u0442\u0430 diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command.html index a313706d701c2102b116676afceb0951a9d6634b..d84dbd5713e2271f62dcfc47187b20ad6fab40b3 100644 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command.html +++ b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command.html @@ -1,4 +1,4 @@
      - Command to run on the slave node to install the tool. + Command to run on the agent node to install the tool. The command will always be run, so it should be a quick no-op if the tool is already installed.
      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_de.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_de.html deleted file mode 100644 index c2ea0fec7a2ca9541079f67b8b84fd3fe0177fa9..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_de.html +++ /dev/null @@ -1,5 +0,0 @@ -
      - Kommando, das auf dem Slave ausgeführt wird, um das Hilfsprogramm zu installieren. - Dieses Kommando wird bei jedem Build ausgeführt - es sollte also eine schnelle, neutrale Operation sein, - wenn das Hilfsprogramm bereits auf dem Slave installiert ist. -
      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_CN.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_CN.html index c98784a54c59154132a3f9025fca166eca29c9ce..648904897aafeba41d67c4d63c6001f6924a6419 100644 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_CN.html +++ b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_CN.html @@ -1,4 +1,4 @@ -
      - 在子节点上使用命令安装工具, - 命令会一直运行,如果工具已经安装了,就要这个命令迅速的运行完成并且没有任何操作. -
      +
      + 在子节点上使用命令安装工具, + 命令会一直运行,如果工具已经安装了,就要这个命令迅速的运行完成并且没有任何操作. +
      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_TW.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_TW.html deleted file mode 100644 index e9d06e036cd2d78d320351e36728674e07015d09..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-command_zh_TW.html +++ /dev/null @@ -1,4 +0,0 @@ -
      - 在 Slave 節點上安裝工具要執行的指令。 - 每次都會執行這個指令,所以如果工具已經安裝好了,指令應該要不做任何事盡快結束。 -
      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-toolHome_zh_CN.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-toolHome_zh_CN.html index 870a2b330d82ea874e2a9cecf6a26e5bb724278c..133842fd340b837a07baf02dd4e74266a2fa4fdd 100644 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-toolHome_zh_CN.html +++ b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help-toolHome_zh_CN.html @@ -1,4 +1,4 @@ -
      - 安装工具的目录. - (如果需要吧工具解压到磁盘上,可能是一个绝对路径.) -
      +
      + 安装工具的目录. + (如果需要吧工具解压到磁盘上,可能是一个绝对路径.) +
      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_de.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_de.html index 64f14fecfc9299ad83ae1721395394c344cd50a1..da52cbe61d4eebfbada6274dc57b212495df20e9 100644 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_de.html +++ b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_de.html @@ -1,6 +1,6 @@

      Startet ein Shell-Kommando Ihrer Wahl, um das Hilfsprogramm zu installieren. - Unter Ubuntu könnte das beispielsweise so aussehen (unter der Annahme, daß + Unter Ubuntu könnte das beispielsweise so aussehen (unter der Annahme, dass der Jenkins-Benutzer in /etc/sudoers gelistet ist):

      diff --git a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_zh_CN.html b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_zh_CN.html index c11feb02928847de48e1f5160451e55945586e5b..1815c2a214098114382ada648d8627e352757393 100644 --- a/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_zh_CN.html +++ b/core/src/main/resources/hudson/tools/AbstractCommandInstaller/help_zh_CN.html @@ -1,21 +1,21 @@ -

      - 运行Shell命令来安装你选择的工具.用Ubunte举例, - 假设Jenkins用户在/etc/sudoers内: -

      -
      sudo apt-get --yes install openjdk-6-jdk
      -

      - (这个例子中指定 /usr/lib/jvm/java-6-openjdk 作为工具安装目录.) -

      -

      - 其它情况的例子,在(x86) Linux下安装JDK6, - 你可以使用DLJ: -

      -
      bin=jdk-6u13-dlj-linux-i586.bin
      -if [ \! -f $bin ]
      -then
      -    wget --no-verbose http://download.java.net/dlj/binaries/$bin
      -    sh $bin --unpack --accept-license
      -fi
      -

      - (这个例子中指定 jdk1.6.0_13 作为安装目录DLJ:.) -

      +

      + 运行Shell命令来安装你选择的工具.用Ubunte举例, + 假设Jenkins用户在/etc/sudoers内: +

      +
      sudo apt-get --yes install openjdk-6-jdk
      +

      + (这个例子中指定 /usr/lib/jvm/java-6-openjdk 作为工具安装目录.) +

      +

      + 其它情况的例子,在(x86) Linux下安装JDK6, + 你可以使用DLJ: +

      +
      bin=jdk-6u13-dlj-linux-i586.bin
      +if [ \! -f $bin ]
      +then
      +    wget --no-verbose http://download.java.net/dlj/binaries/$bin
      +    sh $bin --unpack --accept-license
      +fi
      +

      + (这个例子中指定 jdk1.6.0_13 作为安装目录DLJ:.) +

      diff --git a/core/src/main/resources/hudson/tools/DownloadFromUrlInstaller/config_sr.properties b/core/src/main/resources/hudson/tools/DownloadFromUrlInstaller/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b1e0ab0aa0c5230304c692af0438d41657c31ce7 --- /dev/null +++ b/core/src/main/resources/hudson/tools/DownloadFromUrlInstaller/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/config_de.properties b/core/src/main/resources/hudson/tools/InstallSourceProperty/config_de.properties index 1c6dbf61f9a22d64dc6d2d630a994bbd8674471c..2e5b756d0d2c5592eb1ce43fa1fdbae5ed08539c 100644 --- a/core/src/main/resources/hudson/tools/InstallSourceProperty/config_de.properties +++ b/core/src/main/resources/hudson/tools/InstallSourceProperty/config_de.properties @@ -1,24 +1,24 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Add\ Installer=Installationsverfahren hinzufgen +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add\ Installer=Installationsverfahren hinzufgen Delete\ Installer=Installationsverfahren entfernen \ No newline at end of file diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/config_sr.properties b/core/src/main/resources/hudson/tools/InstallSourceProperty/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0e2e34192b93f02e1f9dda2dc40b94e1f35b3b72 --- /dev/null +++ b/core/src/main/resources/hudson/tools/InstallSourceProperty/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Delete\ Installer=\u0423\u043A\u043B\u043E\u043D\u0438 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0442\u043E\u0440 +Add\ Installer=\u0414\u043E\u0434\u0430\u0458\u0442\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0442\u043E\u0440 diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/config_zh_CN.properties b/core/src/main/resources/hudson/tools/InstallSourceProperty/config_zh_CN.properties index b7378656a38f7815a980412e92919418579c6bcc..e349cd159c34d1691bef536ccd4ff54ad82012fc 100644 --- a/core/src/main/resources/hudson/tools/InstallSourceProperty/config_zh_CN.properties +++ b/core/src/main/resources/hudson/tools/InstallSourceProperty/config_zh_CN.properties @@ -1,24 +1,24 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Add\ Installer=\u65b0\u589e\u5b89\u88c5 +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add\ Installer=\u65b0\u589e\u5b89\u88c5 Delete\ Installer=\u5220\u9664\u5b89\u88c5 \ No newline at end of file diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html b/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html index dcf41ecf37dec2f74ccb830f1d94bd4eb96cbb1f..bd817db61d2522bd06dc2beb646f799acbd14f32 100644 --- a/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html +++ b/core/src/main/resources/hudson/tools/InstallSourceProperty/help.html @@ -1,6 +1,5 @@
      - Choose this option to let Jenkins install this tool for you on demand, - to the location you configured above. + Choose this option to let Jenkins install this tool for you on demand.

      If you check this option, you'll then be asked to configure a series @@ -11,5 +10,5 @@ For a platform-independent tool (such as Ant), configuring multiple installers for a single tool makes not much sense, but for a platform dependent tool, multiple installer configurations allow you to run a different set up script - depending on the slave environment. + depending on the agent environment.

      diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/help_de.html b/core/src/main/resources/hudson/tools/InstallSourceProperty/help_de.html deleted file mode 100644 index 18f3f9c8fb5b04bdb7537350150ee802d784d9a4..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/tools/InstallSourceProperty/help_de.html +++ /dev/null @@ -1,14 +0,0 @@ -
      - Verwenden diese Option, wenn Jenkins bei Bedarf automatisch Hilfsprogramme - am angegebenen Ort installieren soll. - -

      - Wenn Sie diese Option anwählen, müssen Sie für jedes Hilfsprogramm eines - oder mehrere Installationsverfahren konfigurieren. - -

      - Für ein plattformunabhängiges Hilfsprogramm (z.B. Apache Ant) ist es wenig - sinnvoll, mehrere Installationsverfahren anzugeben. Bei einem plattformabhängigen - Hilfsprogramm hingegen, können Sie so gezielt das Installationsverfahren der - jeweiligen Slave-Plattform anpassen. -

      diff --git a/core/src/main/resources/hudson/tools/InstallSourceProperty/help_zh_TW.html b/core/src/main/resources/hudson/tools/InstallSourceProperty/help_zh_TW.html deleted file mode 100644 index 40248d0da3c7c72e47cf527c5043765d0c0ae054..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/tools/InstallSourceProperty/help_zh_TW.html +++ /dev/null @@ -1,10 +0,0 @@ -
      - 這個功能能讓 Jenkins 依您的需求,將工具安裝到您上面設定的地方去。 - -

      - 選用這個功能用,您需要設定一系列的工具「安裝程式」,每個安裝程式都定義 Jenkins 該如何安裝這項工具。 - -

      - 對不限定平台的工具 (例如 Ant) 設定多個「安裝程式」並不合理。 - 但是對平台相關的工具來說,多個安裝程式設定,讓您可以依 Slave 環境不同執行專屬的安裝 Script。 -

      diff --git a/core/src/main/resources/hudson/tools/JDKInstaller/DescriptorImpl/credentialOK_sr.properties b/core/src/main/resources/hudson/tools/JDKInstaller/DescriptorImpl/credentialOK_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..fef7da675572e9d473493dd306b3dec4e8d50790 --- /dev/null +++ b/core/src/main/resources/hudson/tools/JDKInstaller/DescriptorImpl/credentialOK_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Credential\ is\ saved=\u0421\u0430\u0447\u0443\u0432\u0430\u043D\u043E \u0458\u0435 \u0430\u043A\u0440\u0435\u0434\u0438\u0442\u0438\u0432\u0430\u0442 +Close=\u0417\u0430\u0432\u0440\u0448\u0438 diff --git a/core/src/main/resources/hudson/tools/JDKInstaller/DescriptorImpl/enterCredential_sr.properties b/core/src/main/resources/hudson/tools/JDKInstaller/DescriptorImpl/enterCredential_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c1866bea55fe68032b123509c7e27de8104dcb49 --- /dev/null +++ b/core/src/main/resources/hudson/tools/JDKInstaller/DescriptorImpl/enterCredential_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Enter\ Your\ Oracle\ Account=\u0423\u043D\u0435\u0441\u0438\u0442\u0435 \u0432\u0430\u0448 Oracle \u043D\u0430\u043B\u043E\u0433 +description=\u0414\u0430 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0438\u0442\u0435 \u0441\u0442\u0430\u0440\u0438\u0458\u0438\u043C \u0432\u0435\u0440\u0437\u0438\u0458\u0430\u043C\u0430 JDK, \u043C\u043E\u0440\u0430\u0442\u0435 \u0438\u043C\u0430\u0442\u0438 Oracle \u043D\u0430\u043B\u043E\u0433. +Username=\u041A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435 +Password=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 +OK=\u0423\u0440\u0435\u0434\u0443 diff --git a/core/src/main/resources/hudson/tools/JDKInstaller/config_sr.properties b/core/src/main/resources/hudson/tools/JDKInstaller/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5d1762543aff2701514aa739d2ab9c6559362fb3 --- /dev/null +++ b/core/src/main/resources/hudson/tools/JDKInstaller/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 +I\ agree\ to\ the\ Java\ SE\ Development\ Kit\ License\ Agreement=\u041F\u0440\u0438\u0441\u0442\u0430\u0458\u0435\u043C \u043D\u0430 \u0443\u0433\u043E\u0432\u043E\u0440 \u043E \u043B\u0438\u0446\u0435\u043D\u0446\u0438 Java SE Development Kit diff --git a/core/src/main/resources/hudson/tools/Messages.properties b/core/src/main/resources/hudson/tools/Messages.properties index e5d553866d776c1b9fbf76b01eeccece24fcbd36..a59e064de78dec0a38f361709807922d7bebcb47 100644 --- a/core/src/main/resources/hudson/tools/Messages.properties +++ b/core/src/main/resources/hudson/tools/Messages.properties @@ -36,4 +36,5 @@ InstallSourceProperty.DescriptorImpl.displayName=Install automatically JDKInstaller.DescriptorImpl.displayName=Install from java.sun.com JDKInstaller.DescriptorImpl.doCheckId=Define JDK ID JDKInstaller.DescriptorImpl.doCheckAcceptLicense=You must agree to the license to download the JDK. -ToolDescriptor.NotADirectory={0} is not a directory on the Jenkins master (but perhaps it exists on some slaves) +ToolDescriptor.NotADirectory={0} is not a directory on the Jenkins master (but perhaps it exists on some agents) +CannotBeInstalled=Installer "{0}" cannot be used to install "{1}" on the node "{2}" diff --git a/core/src/main/resources/hudson/tools/Messages_bg.properties b/core/src/main/resources/hudson/tools/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..299ea8527ef96737ab8e170d9ed3c3f7874a270f --- /dev/null +++ b/core/src/main/resources/hudson/tools/Messages_bg.properties @@ -0,0 +1,62 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ToolLocationNodeProperty.displayName=\ + \u041c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438\u0442\u0435 +CommandInstaller.DescriptorImpl.displayName=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0430 \u043e\u0431\u0432\u0438\u0432\u043a\u0430\u0442\u0430 +CommandInstaller.no_command=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0443\u043a\u0430\u0436\u0435\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u043a\u043e\u044f\u0442\u043e \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438. +CommandInstaller.no_toolHome=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0443\u043a\u0430\u0436\u0435\u0442\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u0442\u043e \u043d\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438\u0442\u0435 +BatchCommandInstaller.DescriptorImpl.displayName=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0444\u0430\u0439\u043b +JDKInstaller.FailedToInstallJDK=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 JDK (\u0440\u0430\u0437\u0432\u043e\u0439\u043d\u0438\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0437\u0430 Java). \u0418\u0437\u0445\u043e\u0434\u043d\u0438\u044f\u0442 \u043a\u043e\u0434\ + \u0435 {0} +JDKInstaller.RequireOracleAccount=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 JDK (\u0440\u0430\u0437\u0432\u043e\u0439\u043d\u0438\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0437\u0430 Java) \u0438\u0437\u0438\u0441\u043a\u0432\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f\ + \u043a\u044a\u043c Oracle. \u0412\u044a\u0432\u0435\u0434\u0435\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u043e\u0442\u043e \u0441\u0438 \u0438\u043c\u0435 \u0438\ + \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 +JDKInstaller.UnableToInstallUntilLicenseAccepted=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043f\u0440\u0438\u0435\u043c\u0435\u0442\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0430 \u0437\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0442\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 JDK (\u0440\u0430\u0437\u0432\u043e\u0439\u043d\u0438\u0442\u0435\ + \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0437\u0430 Java). +ZipExtractionInstaller.DescriptorImpl.displayName=\ + \u0420\u0430\u0437\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0441 \u0440\u0430\u0437\u0448\u0438\u0440\u0435\u043d\u0438\u0435 *.zip/*.tar.gz +ZipExtractionInstaller.bad_connection=\ + \u0421\u044a\u0440\u0432\u044a\u0440\u044a\u0442 \u043e\u0442\u043a\u0430\u0437\u0430 \u0432\u0440\u044a\u0437\u043a\u0430\u0442\u0430. +ZipExtractionInstaller.malformed_url=\ + \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u0435\u043d \u0430\u0434\u0440\u0435\u0441. +ZipExtractionInstaller.could_not_connect=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0430 \u0432\u0440\u044a\u0437\u043a\u0430 \u043a\u044a\u043c \u0430\u0434\u0440\u0435\u0441\u0430. +InstallSourceProperty.DescriptorImpl.displayName=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 +JDKInstaller.DescriptorImpl.displayName=\ + \u0418\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435 \u043e\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 java.sun.com +JDKInstaller.DescriptorImpl.doCheckId=\ + \u0423\u043a\u0430\u0437\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043d\u0430 JDK (\u0440\u0430\u0437\u0432\u043e\u0439\u043d\u0438\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0437\u0430 Java) +JDKInstaller.DescriptorImpl.doCheckAcceptLicense=\ + \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u043f\u0440\u0438\u0435\u043c\u0435\u0442\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0430, \u0437\u0430 \u0434\u0430 \u0441\u0432\u0430\u043b\u0438\u0442\u0435 JDK (\u0440\u0430\u0437\u0432\u043e\u0439\u043d\u0438\u0442\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438 \u0437\u0430 Java). +# {0} is not a directory on the Jenkins master (but perhaps it exists on some agents) +ToolDescriptor.NotADirectory=\ + \u201e{0}\u201c \u043d\u0435 \u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u043d\u0430 Jenkins, \u043d\u043e \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0441\u044a\u0449\u0435\u0441\u0442\u0432\u0443\u0432\u0430\ + \u043d\u0430 \u043d\u044f\u043a\u043e\u0438 \u043e\u0442 \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u0438\u0442\u0435 \u043a\u043e\u043c\u043f\u044e\u0442\u0440\u0438 diff --git a/core/src/main/resources/hudson/tools/Messages_ja.properties b/core/src/main/resources/hudson/tools/Messages_ja.properties index ac2fff6e077dddf9bec7aba51d3ad875f23ecc02..2e82dec80a1a3be71dd03e1314673dc0d7bf7ca3 100644 --- a/core/src/main/resources/hudson/tools/Messages_ja.properties +++ b/core/src/main/resources/hudson/tools/Messages_ja.properties @@ -37,4 +37,3 @@ InstallSourceProperty.DescriptorImpl.displayName=\u81ea\u52d5\u30a4\u30f3\u30b9\ JDKInstaller.DescriptorImpl.displayName=java.sun.com\u304b\u3089\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb JDKInstaller.DescriptorImpl.doCheckId=JDK\u306eID\u3092\u5b9a\u7fa9\u3057\u3066\u304f\u3060\u3055\u3044\u3002 JDKInstaller.DescriptorImpl.doCheckAcceptLicense=JDK\u3092\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9\u3059\u308b\u306b\u306f\u4f7f\u7528\u8a31\u8afe\u306b\u540c\u610f\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002 -ToolDescriptor.NotADirectory=\u30de\u30b9\u30bf\u30fc\u4e0a\u306e{0}\u306f\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u3067\u306f\u3042\u308a\u307e\u305b\u3093(\u30b9\u30ec\u30fc\u30d6\u306b\u306f\u3042\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093)\u3002 \ No newline at end of file diff --git a/core/src/main/resources/hudson/tools/Messages_pt_BR.properties b/core/src/main/resources/hudson/tools/Messages_pt_BR.properties index 91d0955134a311cb96177b22975b0311d96fd2e0..b69eff530a86f19684693da67e29731f32b6e3f2 100644 --- a/core/src/main/resources/hudson/tools/Messages_pt_BR.properties +++ b/core/src/main/resources/hudson/tools/Messages_pt_BR.properties @@ -52,5 +52,4 @@ CommandInstaller.no_toolHome=\u00c9 necess\u00e1rio fornecer um diret\u00f3rio h JDKInstaller.RequireOracleAccount=Instalar o JDK exige uma conta na Oracle. Por favor informe seu usu\u00e1ro/senha # Run Batch Command BatchCommandInstaller.DescriptorImpl.displayName=Executar comando em lotes -# {0} is not a directory on the Jenkins master (but perhaps it exists on some slaves) -ToolDescriptor.NotADirectory={0} n\u00e3o \u00e9 um diret\u00f3rio no Jenkins master (por\u00e9m pode existir em alguns slaves) + diff --git a/core/src/main/resources/hudson/tools/Messages_sr.properties b/core/src/main/resources/hudson/tools/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4266f9e1801f13cc0a909213e70fc21fbbc4d36e --- /dev/null +++ b/core/src/main/resources/hudson/tools/Messages_sr.properties @@ -0,0 +1,19 @@ +# This file is under the MIT License by authors + +ToolLocationNodeProperty.displayName=\u041B\u043E\u043A\u0430\u0446\u0438\u0458\u0435 \u0430\u043B\u0430\u0442\u0430 +CommandInstaller.DescriptorImpl.displayName=\u0418\u0437\u0432\u0440\u0448\u0438 shell \u043A\u043E\u043C\u0430\u043D\u0434\u0443 +CommandInstaller.no_command=\u041C\u043E\u0440\u0430\u0442\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 \u0437\u0430 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 +CommandInstaller.no_toolHome=\u041C\u043E\u0440\u0430\u0442\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438 \u0433\u043B\u0430\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0437\u0430 \u0430\u043B\u0430\u0442\u0435. +BatchCommandInstaller.DescriptorImpl.displayName=\u0418\u0437\u0432\u0440\u0448\u0438 batch \u043A\u043E\u043C\u0430\u043D\u0434\u0443 +JDKInstaller.FailedToInstallJDK=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u045A\u0435 JDK \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E. Exit code={0} +JDKInstaller.RequireOracleAccount=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u045A\u0435 JDK-\u0430 \u0437\u0430\u0445\u0442\u0435\u0432\u0430 Oracle \u043D\u0430\u043B\u043E\u0433. \u041C\u043E\u043B\u0438\u043C\u043E \u0443\u043D\u0435\u0441\u0438\u0442\u0435 \u043A\u043E\u0440\u0438\u0438\u0441\u043D\u0438\u0447\u043A\u043E \u0438\u043C\u0435/\u043B\u043E\u0437\u0438\u043D\u043A\u0443 +JDKInstaller.UnableToInstallUntilLicenseAccepted=\u041C\u043E\u0440\u0430\u0442\u0435 \u043F\u0440\u0438\u0445\u0432\u0430\u0442\u0438\u0442\u0438 \u043B\u0438\u0446\u0435\u043D\u0446\u0443 \u0437\u0430 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043A\u0443 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0443 JDK-\u0430. +ZipExtractionInstaller.DescriptorImpl.displayName=\u0420\u0430\u0441\u043A\u043F\u0430\u043A\u0443\u0458 *.zip/*.tar.gz +ZipExtractionInstaller.malformed_url=\u041D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u043D\u0430 URL \u0430\u0434\u0440\u0435\u0441\u0430. +ZipExtractionInstaller.bad_connection=\u0421\u0435\u0440\u0432\u0435\u0440 \u0458\u0435 \u043E\u0434\u0431\u0438\u043E \u043F\u043E\u0432\u0435\u0437\u0438\u0432\u0430\u045A\u0435. +ZipExtractionInstaller.could_not_connect=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u043B\u043E \u0443\u0441\u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u0432\u0435\u0437\u0443 \u0441\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u043E\u043C. +InstallSourceProperty.DescriptorImpl.displayName=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E +JDKInstaller.DescriptorImpl.displayName=\u0418\u043D\u0441\u0442\u0430\u043B\u0438\u0440\u0430\u0458 \u0441\u0430 \u0430\u0434\u0440\u0435\u0441\u0435 java.sun.com +JDKInstaller.DescriptorImpl.doCheckId=\u041D\u0430\u0432\u0435\u0434\u0438 JDK ID +JDKInstaller.DescriptorImpl.doCheckAcceptLicense=\u041C\u043E\u0440\u0430\u0442\u0435 \u043F\u0440\u0438\u0445\u0432\u0430\u0442\u0438\u0442\u0438 \u043B\u0438\u0446\u0435\u043D\u0446\u0443 \u0434\u0430 \u043F\u0440\u0435\u0443\u0437\u043C\u0435\u0442\u0435 JDK. +ToolDescriptor.NotADirectory={0} \u043D\u0438\u0458\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u043D\u0430 Jenkins \u043C\u0430\u0448\u0438\u043D\u0438 (\u0430\u043B\u0438 \u043C\u043E\u0433\u0443\u045B\u0435 \u0434\u0430 \u043F\u043E\u0441\u0442\u043E\u0458\u0438 \u043D\u0430 \u043D\u0435\u043A\u0438\u043C \u043E\u0434 \u0430\u0433\u0435\u043D\u0430\u0442\u0430) \ No newline at end of file diff --git a/core/src/main/resources/hudson/tools/Messages_zh_CN.properties b/core/src/main/resources/hudson/tools/Messages_zh_CN.properties index 2bec02c1b1036826d1512ee8b5890374e2d3f6ec..e580a8cdbfdf35bb916a03c7ff0e35dcfd77219f 100644 --- a/core/src/main/resources/hudson/tools/Messages_zh_CN.properties +++ b/core/src/main/resources/hudson/tools/Messages_zh_CN.properties @@ -1,36 +1,36 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -ToolLocationNodeProperty.displayName=Tool Locations -CommandInstaller.DescriptorImpl.displayName=\u8fd0\u884c\u547d\u4ee4 -CommandInstaller.no_command=\u5fc5\u987b\u63d0\u4f9b\u4e00\u4e2a\u8fd0\u884c\u547d\u4ee4. -CommandInstaller.no_toolHome=\u5fc5\u987b\u63d0\u4f9b\u4e00\u4e2a\u5de5\u5177\u6839\u76ee\u5f55. -JDKInstaller.FailedToInstallJDK=\u5b89\u88c5JDK\u5931\u8d25. \u9519\u8bef\u4ee3\u7801={0} -JDKInstaller.UnableToInstallUntilLicenseAccepted=\u6ca1\u6709\u63a5\u53d7\u8bb8\u53ef\u4e4b\u524d\u4e0d\u80fd\u591f\u81ea\u52a8\u5b89\u88c5. -ZipExtractionInstaller.DescriptorImpl.displayName=\u89e3\u538b *.zip/*.tar.gz -ZipExtractionInstaller.bad_connection=\u670d\u52a1\u5668\u62d2\u7edd\u94fe\u63a5. -ZipExtractionInstaller.malformed_url=\u9519\u8bef\u7684URL. -ZipExtractionInstaller.could_not_connect=\u4e0d\u80fd\u94fe\u63a5URL. -InstallSourceProperty.DescriptorImpl.displayName=\u81ea\u52a8\u5b89\u88c5 -JDKInstaller.DescriptorImpl.displayName=\u4ece java.sun.com\u5b89\u88c5 -JDKInstaller.DescriptorImpl.doCheckId=\u5b9a\u4e49JDK ID +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Seiji Sogabe +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ToolLocationNodeProperty.displayName=Tool Locations +CommandInstaller.DescriptorImpl.displayName=\u8fd0\u884c\u547d\u4ee4 +CommandInstaller.no_command=\u5fc5\u987b\u63d0\u4f9b\u4e00\u4e2a\u8fd0\u884c\u547d\u4ee4. +CommandInstaller.no_toolHome=\u5fc5\u987b\u63d0\u4f9b\u4e00\u4e2a\u5de5\u5177\u6839\u76ee\u5f55. +JDKInstaller.FailedToInstallJDK=\u5b89\u88c5JDK\u5931\u8d25. \u9519\u8bef\u4ee3\u7801={0} +JDKInstaller.UnableToInstallUntilLicenseAccepted=\u6ca1\u6709\u63a5\u53d7\u8bb8\u53ef\u4e4b\u524d\u4e0d\u80fd\u591f\u81ea\u52a8\u5b89\u88c5. +ZipExtractionInstaller.DescriptorImpl.displayName=\u89e3\u538b *.zip/*.tar.gz +ZipExtractionInstaller.bad_connection=\u670d\u52a1\u5668\u62d2\u7edd\u94fe\u63a5. +ZipExtractionInstaller.malformed_url=\u9519\u8bef\u7684URL. +ZipExtractionInstaller.could_not_connect=\u4e0d\u80fd\u94fe\u63a5URL. +InstallSourceProperty.DescriptorImpl.displayName=\u81ea\u52a8\u5b89\u88c5 +JDKInstaller.DescriptorImpl.displayName=\u4ece java.sun.com\u5b89\u88c5 +JDKInstaller.DescriptorImpl.doCheckId=\u5b9a\u4e49JDK ID JDKInstaller.DescriptorImpl.doCheckAcceptLicense=\u4f60\u5fc5\u987b\u63a5\u53d7\u8bb8\u53ef\u624d\u80fd\u4e0b\u8f7dJDK. \ No newline at end of file diff --git a/core/src/main/resources/hudson/tools/ToolInstallation/config_sr.properties b/core/src/main/resources/hudson/tools/ToolInstallation/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..43f1c62da537908e9df3c48c18f610413f97dee2 --- /dev/null +++ b/core/src/main/resources/hudson/tools/ToolInstallation/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Installation\ directory=\u0414\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435 diff --git a/core/src/main/resources/hudson/tools/ToolInstallation/global_sr.properties b/core/src/main/resources/hudson/tools/ToolInstallation/global_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..29ed2bdfe933b09d45e961cfc95a619a8eb5813e --- /dev/null +++ b/core/src/main/resources/hudson/tools/ToolInstallation/global_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +title={0} \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435 +description=\u0421\u043F\u0438\u0441\u0430\u043A {0} \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0430 \u043D\u0430 \u043E\u0432\u043E\u043C \u0441\u0438\u0441\u0442\u0435\u043C\u0443 +label.add=\u0414\u043E\u0434\u0430\u0458 {0} +label.delete=\u0423\u043A\u043B\u043E\u043D\u0438 {0} diff --git a/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config_sr.properties b/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..75b78b9087645bed789acb2668c963df21d1dc9d --- /dev/null +++ b/core/src/main/resources/hudson/tools/ToolLocationNodeProperty/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +List\ of\ tool\ locations=\u0421\u043F\u0438\u0441\u0430\u043A \u043B\u043E\u043A\u0430\u0446\u0438\u0458\u0435 \u0430\u043B\u0430\u0442\u0430 +Name=\u0418\u043C\u0435 +Home=\u0413\u043B\u0430\u0432\u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0430 diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/config_sr.properties b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5e571ab0d946787af58e4f3b7035628508e1c46a --- /dev/null +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Download\ URL\ for\ binary\ archive=URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0437\u0430 \u043F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u045A\u0435 \u0430\u0440\u0445\u0438\u0432\u0443 +Subdirectory\ of\ extracted\ archive=\u041F\u043E\u0434\u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0440\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u0430\u043D\u0435 \u0430\u0440\u0445\u0438\u0432\u0435 diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-subdir_zh_CN.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-subdir_zh_CN.html index 078d18a7e51b843844159b2558cac40f421b56fe..2bd6d150d189bea6d3026a451a0ff3590b3218a1 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-subdir_zh_CN.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-subdir_zh_CN.html @@ -1,3 +1,3 @@ -
      - 可选子目录,用来放置下载文件和解压文件的目录。 -
      +
      + 可选子目录,用来放置下载文件和解压文件的目录。 +
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html index d6934a776ffd875c6f4ccef6a768b6e90dc0692f..9637265029d9721bcb0bde1e6ebd32b149bcf31e 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url.html @@ -3,5 +3,5 @@ Should be either a ZIP or a GZip-compressed TAR file. The timestamp on the server will be compared to the local version (if any) so you can publish updates easily. - The URL must be accessible from the Jenkins master but need not be accessible from slaves. + The URL must be accessible from the Jenkins master but need not be accessible from agents. diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_de.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_de.html deleted file mode 100644 index 40c7f1ed63207eba085c9aebf7b374f4cea63eb9..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_de.html +++ /dev/null @@ -1,12 +0,0 @@ -
      - URL, von der das Hilfsprogramm als binäres Archiv heruntergeladen werden kann. - Es werden ZIP- und GZIP-komprimierte TAR-Archive unterstützt. - -

      - Der Zeitstempel des Archivs auf dem Server wird mit der lokal installierten Version - (soweit vorhanden) verglichen, so daß Updates einfach veröffentlicht werden können. - -

      - Die URL muß vom Jenkins-Master aus erreichbar sein, nicht aber von jedem einzelnen - Slave-Knoten. -

      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_CN.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_CN.html index f7c2dfcbfc582dcdf8d528a6c7566283671fadff..1f1fe1d8c0db170c558237e24f4743da66b41d88 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_CN.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_CN.html @@ -1,5 +1,5 @@ -
      - 从URL下载的工具包(二进制)应该是一个ZIP文件或者GZip压缩过的TAR文件. - 服务器上的时间戳会比对本地版本(如果有的话),所以你可以轻松的发布升级. - URL必须从Jenkins的主节点访问,但是不需要从子节点访问. -
      +
      + 从URL下载的工具包(二进制)应该是一个ZIP文件或者GZip压缩过的TAR文件. + 服务器上的时间戳会比对本地版本(如果有的话),所以你可以轻松的发布升级. + URL必须从Jenkins的主节点访问,但是不需要从子节点访问. +
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_TW.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_TW.html deleted file mode 100644 index 06a1b92db6ad7700c66f032bc6a14ea5c92a8647..0000000000000000000000000000000000000000 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help-url_zh_TW.html +++ /dev/null @@ -1,6 +0,0 @@ -
      - 可以下載工具壓縮檔的 URL。 - 只支援 ZIP 或是 GZip 壓縮過的 TAR 檔。 - 伺服器上的檔案時間會跟本地版本 (如果有的話) 比較,所以您可以很輕鬆的發佈更新。 - URL 要能從 Jenkins Master 連到,不過 Slave 連不到也沒關係。 -
      diff --git a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_CN.html b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_CN.html index 07d98d5b0dc8225c8886d15f3b68f36f879d9e58..a8a451caf2ae0283fd820142f7acf248c82e5902 100644 --- a/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_CN.html +++ b/core/src/main/resources/hudson/tools/ZipExtractionInstaller/help_zh_CN.html @@ -1,6 +1,6 @@ -
      - 下载工具包并安装在Jenkins下的工作目录中. - 例如:http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip - (选择离你最近的镜像服务器) - 并指定一个子目录apache-ant-1.7.1. -
      +
      + 下载工具包并安装在Jenkins下的工作目录中. + 例如:http://apache.promopeddler.com/ant/binaries/apache-ant-1.7.1-bin.zip + (选择离你最近的镜像服务器) + 并指定一个子目录apache-ant-1.7.1. +
      diff --git a/core/src/main/resources/hudson/tools/label.jelly b/core/src/main/resources/hudson/tools/label.jelly index 83d70f14ed068e7023b9224efb7292628a0b36f9..1ec52e77192ec4097fba9d3362e868f5000c991d 100644 --- a/core/src/main/resources/hudson/tools/label.jelly +++ b/core/src/main/resources/hudson/tools/label.jelly @@ -25,7 +25,7 @@ THE SOFTWARE. Puts the input field for allowing an user to limit this installer to a certain label. - Meant to be used from config.jelly of ToolInstaller subypes. + Meant to be used from config.jelly of ToolInstaller subtypes. diff --git a/core/src/main/resources/hudson/tools/label_bg.properties b/core/src/main/resources/hudson/tools/label_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..4e5c521f335599c7a57fbdd49b3b4eaafa9c3189 --- /dev/null +++ b/core/src/main/resources/hudson/tools/label_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Label=\ + \u0415\u0442\u0438\u043a\u0435\u0442 diff --git a/core/src/main/resources/hudson/tools/label_sr.properties b/core/src/main/resources/hudson/tools/label_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..33f28373715a29a2ea7637dd0d3f67422d43f7b4 --- /dev/null +++ b/core/src/main/resources/hudson/tools/label_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Label=\u041B\u0430\u0431\u0435\u043B\u0430 diff --git a/core/src/main/resources/hudson/triggers/Messages.properties b/core/src/main/resources/hudson/triggers/Messages.properties index b883be434fbc5c8eef51c597d8dfe9cfd07367ca..d01e59aec9f423bd41e9ce1b7f41550eda9cb88b 100644 --- a/core/src/main/resources/hudson/triggers/Messages.properties +++ b/core/src/main/resources/hudson/triggers/Messages.properties @@ -30,3 +30,4 @@ TimerTrigger.no_schedules_so_will_never_run=No schedules so will never run TimerTrigger.TimerTriggerCause.ShortDescription=Started by timer TimerTrigger.would_last_have_run_at_would_next_run_at=Would last have run at {0}; would next run at {1}. Trigger.init=Initializing timer for triggers +SCMTrigger.AdministrativeMonitorImpl.DisplayName=Too Many SCM Polling Threads diff --git a/core/src/main/resources/hudson/triggers/Messages_bg.properties b/core/src/main/resources/hudson/triggers/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..cc701ff73deb692c791b40437b3d8a9193f774a5 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/Messages_bg.properties @@ -0,0 +1,42 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +SCMTrigger.DisplayName=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 +SCMTrigger.getDisplayName=\ + \u0416\u0443\u0440\u043d\u0430\u043b \u0437\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438\u0442\u0435 \u043d\u0430 \u201e{0}\u201c +SCMTrigger.BuildAction.DisplayName=\ + \u0416\u0443\u0440\u043d\u0430\u043b \u0437\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438\u0442\u0435 +SCMTrigger.SCMTriggerCause.ShortDescription=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u043e \u043e\u0442 \u043f\u0440\u043e\u043c\u044f\u043d\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 +TimerTrigger.DisplayName=\ + \u041f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +TimerTrigger.MissingWhitespace=\ + \u041b\u0438\u043f\u0441\u0432\u0430 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0430\u0442\u0430 \u0437\u043d\u0430\u043a\u0430 \u201e*\u201c. +TimerTrigger.TimerTriggerCause.ShortDescription=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d \u043e\u0442 \u0445\u0440\u043e\u043d\u043e\u043c\u0435\u0442\u044a\u0440 +TimerTrigger.would_last_have_run_at_would_next_run_at=\ + \u041f\u0440\u0435\u0434\u0438\u0448\u043d\u043e\u0442\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u0431\u0438 \u0431\u0438\u043b\u043e \u0432 {0}. \u0421\u043b\u0435\u0434\u0432\u0430\u0449\u043e\u0442\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0432\u0430 \u0434\u0430 \u0435 \u0432 {1}. +Trigger.init=\ + \u0421\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0440\u0435\u043c\u0435\u0442\u043e \u043d\u0430 \u0445\u0440\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u0442\u0435 +TimerTrigger.no_schedules_so_will_never_run=\ + \u041d\u0438\u043a\u043e\u0433\u0430 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u0438, \u0437\u0430\u0449\u043e\u0442\u043e \u043b\u0438\u043f\u0441\u0432\u0430 \u0445\u0440\u043e\u043d\u043e\u043c\u0435\u0442\u044a\u0440. diff --git a/core/src/main/resources/hudson/triggers/Messages_de.properties b/core/src/main/resources/hudson/triggers/Messages_de.properties index 2e0701017c1ee3299e8f3423b60848dafe415e4f..980049540ac745511e7ca08aee59e5dc5b196415 100644 --- a/core/src/main/resources/hudson/triggers/Messages_de.properties +++ b/core/src/main/resources/hudson/triggers/Messages_de.properties @@ -25,5 +25,8 @@ SCMTrigger.getDisplayName={0} Abfrage-Protokoll SCMTrigger.BuildAction.DisplayName=Abfrage-Protokoll SCMTrigger.SCMTriggerCause.ShortDescription=Build wurde durch eine SCM-nderung ausgelst. TimerTrigger.DisplayName=Builds zeitgesteuert starten +TimerTrigger.MissingWhitespace=Es scheinen Leerzeichen zwischen * und * zu fehlen. +TimerTrigger.no_schedules_so_will_never_run=Kein Zeitplan vorhanden, somit wird der Job nie ausgef\u00fchrt werden. TimerTrigger.TimerTriggerCause.ShortDescription=Build wurde zeitgesteuert ausgelst. +TimerTrigger.would_last_have_run_at_would_next_run_at=Letzter Lauf am {0}; Nchster Lauf am {1}. Trigger.init=Initialsiere Timer fr Build-Auslser \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_de.properties b/core/src/main/resources/hudson/triggers/Messages_pl.properties similarity index 54% rename from core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_de.properties rename to core/src/main/resources/hudson/triggers/Messages_pl.properties index 7ba8a96e3cab2ba9fcf9be8b89866b862c139046..68191b91ca6f26464ac4d9133e9c741ab6582fd0 100644 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_de.properties +++ b/core/src/main/resources/hudson/triggers/Messages_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# Copyright (c) 2016, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -19,9 +19,14 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - -body=\ - Dieses Profil ist das meistgenutzte in Jenkins. Jenkins baut Ihr Projekt, wobei Sie \ - universell jedes SCM System mit jedem Build-Verfahren kombinieren knnen. Dieses Profil \ - ist nicht nur auf das Bauen von Software beschrnkt, sondern kann darber hinaus \ - auch fr weitere Anwendungsgebiete verwendet werden. +SCMTrigger.DisplayName=Pobierz z repozytorium kodu +SCMTrigger.getDisplayName={0} Rejestr pobrania z repozytorium kodu +SCMTrigger.BuildAction.DisplayName=Rejestr pobrania z repozytorium kodu +SCMTrigger.SCMTriggerCause.ShortDescription=Uruchomione przez zmian\u0119 w repozytorium kodu +TimerTrigger.DisplayName=Buduj cyklicznie +TimerTrigger.MissingWhitespace=Wygl\u0105da, \u017Ce brakuje odst\u0119pu mi\u0119dzy * a *. +TimerTrigger.no_schedules_so_will_never_run=Brak harmonogramu, wi\u0119c nie zostanie nigdy uruchomiony +TimerTrigger.TimerTriggerCause.ShortDescription=Uruchomione przez zegar +TimerTrigger.would_last_have_run_at_would_next_run_at=Ostatnio uruchomione o {0}; kolejne uruchomienie o {1}. +Trigger.init=Inicjalizowanie zegara dla wyzwalaczy +SCMTrigger.AdministrativeMonitorImpl.DisplayName=Zbyt wiele w\u0105tk\u00F3w repozytorium kodu diff --git a/core/src/main/resources/hudson/triggers/Messages_sr.properties b/core/src/main/resources/hudson/triggers/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..bae7a834ffdf1c7e5e670c9fd98fdee0d5d2c8ca --- /dev/null +++ b/core/src/main/resources/hudson/triggers/Messages_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +SCMTrigger.DisplayName=\u0410\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u0458 \u0441\u0438\u0441\u0442\u0435\u043C \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +SCMTrigger.getDisplayName=\u0416\u0443\u0440\u043D\u0430\u043B \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430 {0} +SCMTrigger.BuildAction.DisplayName=\u0416\u0443\u0440\u043D\u0430\u043B \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430 +SCMTrigger.SCMTriggerCause.ShortDescription=\u041F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u043E \u043D\u0430\u043A\u043E\u043D \u043F\u0440\u043E\u043C\u0435\u043D\u0438 \u0443 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0431\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +TimerTrigger.DisplayName=\u041F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +TimerTrigger.MissingWhitespace=\u0418\u043C\u0430 \u043F\u0440\u0430\u0437\u043D\u043E\u0433 \u043C\u0435\u0441\u0442\u0430 \u0438\u0437\u043C\u0435\u0452\u0443 * \u0437\u043D\u0430\u043A\u043E\u0432\u0430. +TimerTrigger.no_schedules_so_will_never_run=\u041D\u0435\u043C\u0430 \u0440\u0430\u0441\u043F\u043E\u0440\u0435\u0434\u0430, \u043D\u0435\u045B\u0435 \u0441\u0435 \u043D\u0438\u0448\u0442\u0430 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 +TimerTrigger.TimerTriggerCause.ShortDescription=\u041F\u043E\u0447\u0435\u0442\u043E \u0448\u0442\u043E\u043F\u0435\u0440\u0438\u0446\u043E\u043C +TimerTrigger.would_last_have_run_at_would_next_run_at=\u041F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0431\u0438 \u0431\u0438\u043B\u0430 {0}. \u0421\u043B\u0435\u0434\u0435\u045B\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0431\u0438 \u0441\u043B\u0435\u0434\u0435\u043B\u043E {1}. +Trigger.init=\u0421\u0442\u0430\u0440\u0442\u043E\u0432\u0430\u045A\u0435 \u0448\u0442\u043E\u043F\u0435\u0440\u0438\u0446\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/message_sr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ef1f9eb3242cc1434447b818f6064e9aa625c3f0 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/AdministrativeMonitorImpl/message_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=\u041D\u0435\u043C\u0430 \u0434\u043E\u0432\u043E\u0459\u043D\u043E \u043D\u0438\u0442\u043E\u0432\u0430 \u0437\u0430 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u0438 \u0431\u0440\u043E\u0458 \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0437\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430.\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u0434\u0430 \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0435 \u043D\u0438\u0458\u0435 \u0438\u0437\u0432\u0438\u0441\u0438\u043B\u043E, \u0438 \u043F\u043E\u0432\u0435\u045B\u0430\u0458\u0442\u0435 \u0432\u0440\u043E\u0458 \u043D\u0438\u0442\u043E\u0432\u0430 \u0430\u043A\u043E \u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E. diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_sr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f43b5d6be0c928f22a475c8c55944778269a1fd5 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/BuildAction/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Polling\ Log=\u0416\u0443\u0440\u043D\u0430\u043B \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430 +View\ as\ plain\ text=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458 \u043A\u0430\u043E \u043E\u0431\u0438\u0447\u0430\u043D \u0442\u0435\u043A\u0441\u0442 +blurb=\u041D\u0430 \u043E\u0432\u043E\u0458 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438 \u0441\u0435 \u043D\u0430\u043B\u0430\u0436\u0438 \u0436\u0443\u0440\u043D\u0430\u043B \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430 \u043A\u043E\u0458\u0438 \u0458\u0435 \u0438\u0437\u0430\u0437\u0432\u0430\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443. diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_nl.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_nl.properties index 4471513f78662bf0e44078a7ff07a634423853d5..53a87ca60e1b0c8dc337af21796e9da666faf799 100644 --- a/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_nl.properties +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_nl.properties @@ -21,7 +21,6 @@ # THE SOFTWARE. clogged=Er zijn meer versiebeheersbemonsteringen gepland dan er behandeld kunnen worden, dus de draden kunnen de vraag niet bijhouden. Kijk na of je bemonstering blijft hangen en/of verhoog het aantal draden indien nodig. Current\ SCM\ Polling\ Activities=Huidige versiebeheersbemonsteringen. -clogged=Er zijn meer versiebeheersbemonsteringen gepland dan er behandeld kunnen worden, dus de draden kunnen de vraag niet bijhouden. Kijk na of je bemonstering blijft hangen en/of verhoog het aantal draden indien nodig. No\ polling\ activity\ is\ in\ progress.=Geen versiecontrolebemonsteringen actief. The\ following\ polling\ activities\ are\ currently\ in\ progress\:=Volgende versiecontrolebemonsteringen zijn actief: Project=Project diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_sr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2e80cfed42c3f455444ec0ef29e09c2ac01647e6 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/DescriptorImpl/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Current\ SCM\ Polling\ Activities=\u0422\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0435 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +clogged= +No\ polling\ activity\ is\ in\ progress.=\u041D\u0435\u043C\u0430 \u0442\u0435\u043A\u0443\u045B\u0435\u0433 \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430. +The\ following\ polling\ activities\ are\ currently\ in\ progress\:=\u0422\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0435: +Project=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +Running\ for=\u0423 \u0442\u043E\u043A\u0443 \u043E\u0434 diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_bg.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_bg.properties index 04a00fee1b0277693cac43d72f9c641b343ca43b..c0af5effc4dc8ee926a7034bc929b679129e1c71 100644 --- a/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_bg.properties +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_bg.properties @@ -1,4 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Polling\ has\ not\ run\ yet.=\u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043D\u0430\u0442\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043D\u0435 \u0435 \u043C\u0438\u043D\u0430\u043B\u0430 \u0432\u0441\u0435 \u043E\u0449\u0435. -title="{0}" +Polling\ has\ not\ run\ yet.=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u0430\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0441\u0435 \u043e\u0449\u0435 \u043d\u0435 \u0435 \u043c\u0438\u043d\u0430\u043b\u0430. +title=\ + {0} diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_sr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..200fb78789e5e90cfc19ccb4e3d5ac428d87c43e --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/SCMAction/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +title={0} +Polling\ has\ not\ run\ yet.=\u0410\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0435 \u043D\u0438\u0458\u0435 \u0458\u043E\u0448 \u0438\u0437\u0432\u0435\u0434\u0435\u043D\u043E diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/config.jelly b/core/src/main/resources/hudson/triggers/SCMTrigger/config.jelly index d9d8f944427587ef8527a7a0f61c2a9688a7c062..86fef6659b22049d9b55bda757dc9d04e5bfe8c8 100644 --- a/core/src/main/resources/hudson/triggers/SCMTrigger/config.jelly +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/config.jelly @@ -25,7 +25,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/config_pl.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/config_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..ce553b93e066d2a952de71fc09c55453699d7e82 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/config_pl.properties @@ -0,0 +1,22 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Schedule=Harmonogram diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/config_sr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..197650f6bc511431da3cd74a5a0e53266f07ab0c --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 +Ignore\ post-commit\ hooks=\u0418\u0437\u0433\u043D\u043E\u0440\u0438\u0448\u0438 \u043F\u043E\u0441\u043B\u0435 \u043A\u043E\u043C\u0438\u0442\u043D\u0435 hook-\u043E\u0432\u0435 diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/global_sr.properties b/core/src/main/resources/hudson/triggers/SCMTrigger/global_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..bf10b5aeb8f6e1b313b994c113658a1cd47b0651 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/global_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +SCM\ Polling=\u0410\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0435 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +Max\ #\ of\ concurrent\ polling=\u041C\u0430\u043A\u0441. \u0431\u0440\u043E\u0458 \u043F\u0430\u0440\u0430\u043B\u0435\u043B\u043D\u043E\u0433 \u0430\u043D\u043A\u0435\u0442\u0438\u0440\u0430\u045A\u0430 diff --git a/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html b/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html index c0bfa8607983cafdc2e4239ef60de48583966ae7..60ec679775b8e75223bfe71ab19f769f334233f7 100644 --- a/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html +++ b/core/src/main/resources/hudson/triggers/SCMTrigger/help_de.html @@ -5,7 +5,7 @@

      Bedenken Sie, dass dies für das Versionsverwaltungssystem CVS eine äußerst ressourcenintensive Operation darstellt, da Jenkins bei jeder Abfrage den - kompletten Arbeitsbereich überprüfen und mit dem CVS-Server abgleichen muß. + kompletten Arbeitsbereich überprüfen und mit dem CVS-Server abgleichen muss. Ziehen Sie daher alternativ einen "Push"-Auslöser in Betracht, wie er in diesem Dokument beschrieben wird. diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/config_pl.properties b/core/src/main/resources/hudson/triggers/TimerTrigger/config_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..2210111174e63efdd2c1bb1ce7633cf034eb928d --- /dev/null +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/config_pl.properties @@ -0,0 +1,22 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Schedule=-Harmonogram diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/config_sr.properties b/core/src/main/resources/hudson/triggers/TimerTrigger/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..04f58629e45cdf8407174d4a27da32c5ff2e0ec1 --- /dev/null +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Schedule=\u0420\u0430\u0441\u043F\u043E\u0440\u0435\u0434 diff --git a/core/src/main/resources/hudson/triggers/TimerTrigger/help-spec.html b/core/src/main/resources/hudson/triggers/TimerTrigger/help-spec.html index 4ce69c94b967bc3055369d7a2929e3192164d259..bfe1d96e2193ea3affc7171c55d87c8f104f8502 100644 --- a/core/src/main/resources/hudson/triggers/TimerTrigger/help-spec.html +++ b/core/src/main/resources/hudson/triggers/TimerTrigger/help-spec.html @@ -73,8 +73,10 @@ H/15 * * * * # every ten minutes in the first half of every hour (three times, perhaps at :04, :14, :24) H(0-29)/10 * * * * -# once every two hours every weekday (perhaps at 10:38 AM, 12:38 PM, 2:38 PM, 4:38 PM) -H 9-16/2 * * 1-5 +# once every two hours at 45 minutes past the hour starting at 9:45 AM and finishing at 3:45 PM every weekday. +45 9-16/2 * * 1-5 +# once in every two hours slot between 9 AM and 5 PM every weekday (perhaps at 10:38 AM, 12:38 PM, 2:38 PM, 4:38 PM) +H H(9-16)/2 * * 1-5 # once a day on the 1st and 15th of every month except December H H 1,15 1-11 * diff --git a/core/src/main/resources/hudson/util/AWTProblem/index.jelly b/core/src/main/resources/hudson/util/AWTProblem/index.jelly index c5acf32c36df703099d7d654a87208063ccc02b7..ec8df8e3292a309d6c52e778b26f634c2769a70b 100644 --- a/core/src/main/resources/hudson/util/AWTProblem/index.jelly +++ b/core/src/main/resources/hudson/util/AWTProblem/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties b/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0740e9258ccadbc0077bb3769f9f548ea7311caa --- /dev/null +++ b/core/src/main/resources/hudson/util/AWTProblem/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +errorMessage=AWT \u043D\u0438\u0458\u0435 \u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u043D\u0430 \u043E\u0432\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438. \u041C\u043E\u0436\u0434\u0430 \u0431\u0438 \u0442\u0440\u0435\u0431\u0430\u043B\u0438 \u043F\u043E\u0447\u0435\u0442\u0438 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0435 \u0441\u0430 \u043E\u043F\u0446\u0438\u0458\u043E\u043C "-Djava.awt.headless=true"? \u0418\u0441\u0442\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435: https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+got+java.awt.headless+problem diff --git a/core/src/main/resources/hudson/util/AdministrativeError/message.jelly b/core/src/main/resources/hudson/util/AdministrativeError/message.jelly index bb30dc1ee7fc93a7b085ef794a744d6aa0d138b7..3b48c00afbd3035e3b57cc95d5ec44891d7c13f4 100644 --- a/core/src/main/resources/hudson/util/AdministrativeError/message.jelly +++ b/core/src/main/resources/hudson/util/AdministrativeError/message.jelly @@ -26,6 +26,6 @@ THE SOFTWARE.

      \ No newline at end of file diff --git a/core/src/main/resources/hudson/util/AdministrativeError/message_de.properties b/core/src/main/resources/hudson/util/AdministrativeError/message_de.properties index 2b27281eccf0e97dc49f8da3b77e60e70554443e..c216359fe65298792a8b172e9b554aedd2777e96 100644 --- a/core/src/main/resources/hudson/util/AdministrativeError/message_de.properties +++ b/core/src/main/resources/hudson/util/AdministrativeError/message_de.properties @@ -1,23 +1,23 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + See\ the\ log\ for\ more\ details=Im Protokoll knnen weitere Hinweise stehen. \ No newline at end of file diff --git a/core/src/main/resources/hudson/util/AdministrativeError/message_sr.properties b/core/src/main/resources/hudson/util/AdministrativeError/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7b02204db79c0ef5191c339e392f9b2bbed698c7 --- /dev/null +++ b/core/src/main/resources/hudson/util/AdministrativeError/message_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +See\ the\ log\ for\ more\ details=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B \u0437\u0430 \u0458\u043E\u0448 \u0434\u0435\u0442\u0430\u0459\u0430 diff --git a/core/src/main/resources/hudson/util/DoubleLaunchChecker/index_sr.properties b/core/src/main/resources/hudson/util/DoubleLaunchChecker/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d250950537cae703f6ee1bb9b51e1cba86a6225f --- /dev/null +++ b/core/src/main/resources/hudson/util/DoubleLaunchChecker/index_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +message=Jenkins \u0458\u0435 \u043E\u0442\u043A\u0440\u0438\u043E \u0434\u0430 \u0441\u0442\u0435 \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u043B\u0438 \u0432\u0438\u0448\u0435 \u0438\u043D\u0441\u0442\u0430\u043D\u0446\u0430 Jenkins-\u0430 \u043A\u043E\u0458\u0435 \u0434\u0435\u043B\u0435 \u0438\u0441\u0442\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C "{0}". \u0414\u0430 \u043D\u0435\u0431\u0438 \u0431\u0438\u043B\u043E \u0447\u0443\u0434\u043D\u043E\u0433 \u043F\u043E\u043D\u0430\u0448\u0430\u045A\u0430 Jenkins-\u0430 \u0438\u0441\u043F\u0440\u0430\u0432\u0438\u0442\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C \u043E\u0434\u043C\u0430\u0445. +This\ Jenkins=\u041E\u0432\u0430\u0458 Jenkins +Other\ Jenkins=\u0414\u0440\u0443\u0433\u0438 Jenkins +label=\u0418\u0437\u0433\u043D\u043E\u0440\u0438\u0448\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C \u0438 \u043D\u0430\u0441\u0442\u0430\u0432\u0438 \u043A\u043E\u0440\u0438\u0448\u045B\u0435\u045A\u0435\u043C Jenkins-\u0430. diff --git a/core/src/main/resources/hudson/util/HudsonFailedToLoad/index.jelly b/core/src/main/resources/hudson/util/HudsonFailedToLoad/index.jelly index a69eb1d4db749e636d0d261424ab559e288fa77a..3c868da831464a1eee1f2fa58847056419f06694 100644 --- a/core/src/main/resources/hudson/util/HudsonFailedToLoad/index.jelly +++ b/core/src/main/resources/hudson/util/HudsonFailedToLoad/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/HudsonFailedToLoad/index_sr.properties b/core/src/main/resources/hudson/util/HudsonFailedToLoad/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..eabbc4121e5d2db79760cfd41634218d6ab3e7e6 --- /dev/null +++ b/core/src/main/resources/hudson/util/HudsonFailedToLoad/index_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 diff --git a/core/src/main/resources/hudson/util/HudsonIsLoading/index_cs.properties b/core/src/main/resources/hudson/util/HudsonIsLoading/index_cs.properties new file mode 100644 index 0000000000000000000000000000000000000000..a81c0e7598561d779dd236490536c745dfcbcf8e --- /dev/null +++ b/core/src/main/resources/hudson/util/HudsonIsLoading/index_cs.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=Po\u010Dkejte pros\u00EDm, ne\u017E aplikace Jenkins zcela nab\u011Bhne +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Jakmile bude Jenkins p\u0159ipraven, str\u00E1nka se automaticky obnov\u00ED. diff --git a/core/src/main/resources/hudson/util/HudsonIsLoading/index_lt.properties b/core/src/main/resources/hudson/util/HudsonIsLoading/index_lt.properties index c8b6f0f5c819e6e7da988613352ce7cb64ced886..2813056a234133de3e593ce2b62074d49c98243a 100644 --- a/core/src/main/resources/hudson/util/HudsonIsLoading/index_lt.properties +++ b/core/src/main/resources/hudson/util/HudsonIsLoading/index_lt.properties @@ -1,24 +1,6 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# This file is under the MIT License by authors -Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=\u012Ejungti automatin\u012F atnaujinim\u0105 -Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Nauja u\u017Eduotis +# /jenkins-core/src/main/resources/hudson/util/HudsonIsLoading/index_lt.properties + +Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=Jenkins ruo\u0161iamas darbui, pra\u0161ome palaukti +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Kuomet Jenkins bus paruo\u0161tas, J\u016Bs\u0173 nar\u0161ykl\u0117 persikraus automati\u0161kai. diff --git a/core/src/main/resources/hudson/util/HudsonIsLoading/index_pl.properties b/core/src/main/resources/hudson/util/HudsonIsLoading/index_pl.properties index 6fa17050039477eaab18d9db3f2bb385d38fa702..f97f2f86474d5662cf105fcda8a90f3b2acc99bd 100644 --- a/core/src/main/resources/hudson/util/HudsonIsLoading/index_pl.properties +++ b/core/src/main/resources/hudson/util/HudsonIsLoading/index_pl.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=Poczekaj prosz\u0119 a\u017C Jenkins b\u0119dzie gotowy do pracy -Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Twoja przegl\u0105darka prze\u0142aduje si\u0119 automatycznie kiedy Jenkins b\u0119dzie gotowy. +Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=Poczekaj prosz\u0119, a\u017C Jenkins b\u0119dzie gotowy do pracy +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=Twoja przegl\u0105darka automatycznie prze\u0142aduje stron\u0119, kiedy Jenkins b\u0119dzie gotowy. diff --git a/core/src/main/resources/hudson/util/HudsonIsLoading/index_sr.properties b/core/src/main/resources/hudson/util/HudsonIsLoading/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..50eaf9d58e86f7ad736ff112ae4537e22e960b9e --- /dev/null +++ b/core/src/main/resources/hudson/util/HudsonIsLoading/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=\u0412\u0430\u0448 \u0432\u0435\u0431-\u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447 \u045B\u0435 \u0441\u0435 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u043E\u0441\u0432\u0435\u0436\u0438\u0442\u0438 \u043A\u0430\u0434\u0430 \u0431\u0443\u0434\u0435 Jenkins \u0431\u0438\u043E \u0441\u043F\u0440\u0435\u043C\u0430\u043D. +Please\ wait\ while\ Jenkins\ is\ getting\ ready\ to\ work=\u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u0441\u0430\u0447\u0435\u043A\u0430\u0458\u0442\u0435 \u0434\u043E\u043A \u0441\u0435 Jenkins \u043F\u0440\u0438\u043F\u0440\u0435\u043C\u0430. diff --git a/core/src/main/resources/hudson/util/HudsonIsRestarting/index_sr.properties b/core/src/main/resources/hudson/util/HudsonIsRestarting/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4e15203825ee374211cf74c10edb6822a5d784e1 --- /dev/null +++ b/core/src/main/resources/hudson/util/HudsonIsRestarting/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Please\ wait\ while\ Jenkins\ is\ restarting=\u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u0441\u0430\u0447\u0435\u043A\u0430\u0458\u0442\u0435 \u0434\u043E\u043A \u0441\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u045B\u0435 Jenkins. +Your\ browser\ will\ reload\ automatically\ when\ Jenkins\ is\ ready.=\u0412\u0430\u0448 \u0432\u0435\u0431-\u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447 \u045B\u0435 \u0441\u0435 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 \u043E\u0441\u0432\u0435\u0436\u0438\u0442\u0438 \u043A\u0430\u0434\u0430 \u0431\u0443\u0434\u0435 Jenkins \u0431\u0438\u043E \u0441\u043F\u0440\u0435\u043C\u0430\u043D. diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.jelly b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.jelly index 6c88a89b9069d403010558449f40f3a93ca583a9..e516ea80253c676482022ee1a20bac5ee132b2ce 100644 --- a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.jelly +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_sr.properties b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..05bb055a5f0db4cbee370efdb0515d76abbc92e6 --- /dev/null +++ b/core/src/main/resources/hudson/util/IncompatibleAntVersionDetected/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +errorMessage=Jenkins \u0458\u0435 \u043E\u0442\u043A\u0440\u0438\u043E \u0434\u0430 \u0432\u0430\u0448 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440 \u043D\u0435 \u043F\u043E\u0434\u0440\u0436\u0430\u0432\u0430 Ant\ +(Ant \u043A\u043B\u0430\u0441\u0435 \u0443\u0447\u0438\u0442\u0430\u043D\u0435 \u043E\u0434 {0}) diff --git a/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index.jelly b/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index.jelly index 76407ab939e962a48adf6dd4955f250687434b94..926a5cfd795e7293b21bcdab9e699ed273e3b587 100644 --- a/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index.jelly +++ b/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index_sr.properties b/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..09631cb8e93f865ffe1e858201f4ab4647dcdffb --- /dev/null +++ b/core/src/main/resources/hudson/util/IncompatibleServletVersionDetected/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +errorMessage=Jenkins \u0458\u0435 \u043E\u0442\u043A\u0440\u0438\u043E \u0434\u0430 \u0432\u0430\u0448 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440 \u043D\u0435 \u043F\u043E\u0434\u0440\u0436\u0430\u0432\u0430 Servlet 2.4\ +(API \u0441\u0435\u0440\u0432\u043B\u0435\u0442\u0430 \u0443\u0447\u0438\u0442\u0430\u043D\u043E \u043E\u0434 {0}) diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.jelly b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.jelly index ee1d8a07975d1f12c62d70eb557f6dabd8d013f1..c9baaa5ce28544b35ba1acaefe0099df8c2eaa9a 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.jelly +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties index 6ddf791bee7fc28f2ff7e6086e248cff5e5a9600..5b55c0c15ebf7b50a75970b5f281d34adbce3a26 100644 --- a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_de.properties @@ -1,33 +1,33 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Error=Fehler -OS\ Name=Betriebssystem -VM\ Name=VM Name -Vendor=Hersteller -Version=Version -Detected\ JVM=Gefundene JVM -errorMessage=\ - Die gefundene Java Virtual Machine (JVM) wird von Jenkins nicht untersttzt. \ - Jenkins ist auf die Bibliothek XStream angewiesen, welche aber nicht mit der \ - gefundenen JVM funktioniert. \ - Mehr dazu... +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Error=Fehler +OS\ Name=Betriebssystem +VM\ Name=VM Name +Vendor=Hersteller +Version=Version +Detected\ JVM=Gefundene JVM +errorMessage=\ + Die gefundene Java Virtual Machine (JVM) wird von Jenkins nicht untersttzt. \ + Jenkins ist auf die Bibliothek XStream angewiesen, welche aber nicht mit der \ + gefundenen JVM funktioniert. \ + Mehr dazu... diff --git a/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c969814074eca5d21854f53be466666155719d1d --- /dev/null +++ b/core/src/main/resources/hudson/util/IncompatibleVMDetected/index_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +errorMessage=Jenkins \u0458\u0435 \u043F\u0440\u043E\u043D\u0430\u0448\u0430\u043E \u0434\u0430 \u0432\u0430\u0448\u0430 JVM \u043D\u0438\u0458\u0435 \u043F\u043E\u0434\u0440\u0436\u0430\u043D\u0430, \u0437\u0431\u043E\u0433 \u043D\u0435\u043A\u0438\u0445 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430 \u043E\u0434 \u043A\u043E\u0458\u0435 Jenkins \u0437\u0430\u0432\u0438\u0441\u0438.\ +\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 this FAQ \u0433\u0434\u0435 \u0438\u043C\u0430 \u0432\u0438\u043F\u0435 \u0434\u0435\u0442\u0430\u0459\u0430. +Detected\ JVM= +Vendor=\u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0452\u0430\u0447 +Version=\u0412\u0435\u0440\u0437\u0438\u0458\u0430 +VM\ Name=\u0418\u043C\u0435 \u0432\u0438\u0440\u0442\u0443\u0435\u043B\u043D\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 +OS\ Name=\u0418\u043C\u0435 \u043E\u043F\u0435\u0440\u0430\u0442\u0438\u0432\u043D\u043E\u0433 \u0441\u0438\u0441\u0442\u0435\u043C\u0430 diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.jelly b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.jelly index e3ef38d31bc26051b04ef084e3342eed674f15cb..0dc65cfc2836b5cba8478c0795dabf591c7c54e6 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.jelly +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties index 23904e44e7da5649f269d08d33d21e96e62eca89..c9a99678929f5c60103559a006ea32fed94b3b31 100644 --- a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_de.properties @@ -1,33 +1,33 @@ -# The MIT License -# -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Error=Fehler -errorMessage.1=\ - Jenkins scheint nicht gengend Ausfhrungsrechte zu besitzen (vgl. untenstehenden \ - Stacktrace). Eine hufige Ursache dafr ist ein aktivierter Security Manager. \ - Ist dieser absichtlich aktiviert, mssen Sie Jenkins ausreichende Ausfhrungsrechte \ - zuteilen. Falls nicht (oder Sie keinen blassen Schimmer haben, was ein "Security \ - Manager" ist), ist es am Einfachsten, den Security Manager abzuschalten. -errorMessage.2=\ - Wie Sie den Security Manager Ihres Web-Containers abschalten, entnehmen Sie \ - der containerspezifischen \ - Jenkins-Dokumentation. +# The MIT License +# +# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Error=Fehler +errorMessage.1=\ + Jenkins scheint nicht gengend Ausfhrungsrechte zu besitzen (vgl. untenstehenden \ + Stacktrace). Eine hufige Ursache dafr ist ein aktivierter Security Manager. \ + Ist dieser absichtlich aktiviert, mssen Sie Jenkins ausreichende Ausfhrungsrechte \ + zuteilen. Falls nicht (oder Sie keinen blassen Schimmer haben, was ein "Security \ + Manager" ist), ist es am Einfachsten, den Security Manager abzuschalten. +errorMessage.2=\ + Wie Sie den Security Manager Ihres Web-Containers abschalten, entnehmen Sie \ + der containerspezifischen \ + Jenkins-Dokumentation. diff --git a/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a3def1735b8f69e704bd03e0cfb7fcbbd27cbd3f --- /dev/null +++ b/core/src/main/resources/hudson/util/InsufficientPermissionDetected/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +errorMessage.1=Jenkins je \u043E\u0442\u043A\u0440\u0438o \u0434\u0430 \u043D\u0435\u043C\u0430 \u043E\u0432\u043B\u0430\u0448\u045B\u0435\u045A\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430, \u0435\u0432\u0438\u0434\u0435\u043D\u0442\u0438\u0440\u0430\u043D\u043E \u043F\u0440\u0430\u0442\u0435\u045B\u043E\u0458 \u0442\u0440\u0430\u0441\u0438 \u0441\u0442\u0435\u043A\u043E\u043C. \u0412\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0458\u0435 \u0437\u0431\u043E\u0433 \u043D\u0435\u043A\u043E\u0433 \u043D\u0430\u0434\u0437\u043E\u0440\u043D\u043E\u0433 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0430, \u043A\u043E\u0458\u0438 \u0431\u0438 \u0442\u0440\u0435\u0431\u043E \u0434\u0430 \u0441\u0435 \u043F\u043E\u0434\u0435\u0441\u0438 \u0438\u043B\u0438 \u0438\u0441\u043A\u0459\u0443\u0447\u0438. +errorMessage.2=\u0423\u043F\u0443\u0441\u0442\u0432\u043E \u043A\u0430\u043A\u043E \u0443\u0433\u0430\u0441\u0438\u0442\u0438 security manager \u0443 \u0432\u0430\u0448\u0435\u043C \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0443 \u0441\u0435 \u043D\u0430\u043B\u0430\u0437\u0438 \u0443 \u0447\u043B\u0430\u043D\u043A\u0443 \ + \ + \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0430 \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0430 \u0443 Jenkins-\u0443. +de= diff --git a/core/src/main/resources/hudson/util/JNADoublyLoaded/index_sr.properties b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a774b7e8f9d294cae4406b3f764cefe289992fd0 --- /dev/null +++ b/core/src/main/resources/hudson/util/JNADoublyLoaded/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Failed\ to\ load\ JNA=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u043B\u043E \u0443\u0447\u0438\u0442\u0430\u0442\u0438 JNA +blurb=\u0414\u0440\u0443\u0433\u0430 \u0438\u043D\u0441\u0442\u0430\u043D\u0446\u0430 JNA \u0458\u0435 \u0432\u0435\u045B \u0443\u0447\u0438\u0442\u0430\u043D\u0430 \u0443 classloader, \u043F\u043E\u0442\u043E\u043C Jenkins \u043D\u0435\u043C\u043E\u0436\u0435 \u0443\u0447\u0438\u0442\u0430\u0442\u0438 \u0441\u0432\u043E\u0458\u0443 \u043A\u043E\u043F\u0438\u0458\u0443. \u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0412\u0438\u043A\u0438 \u0437\u0430 \u0432\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430. diff --git a/core/src/main/resources/hudson/util/JenkinsReloadFailed/index.groovy b/core/src/main/resources/hudson/util/JenkinsReloadFailed/index.groovy index 761ec1c4e0b0a41d491b42eeacf554748b9e8ebd..9405ab55c63f1b2d2af5631c6bc095e7c24c408b 100644 --- a/core/src/main/resources/hudson/util/JenkinsReloadFailed/index.groovy +++ b/core/src/main/resources/hudson/util/JenkinsReloadFailed/index.groovy @@ -1,6 +1,9 @@ import hudson.Functions def l = namespace(lib.LayoutTagLib) +def st = namespace("jelly:stapler") + +st.statusCode(value: 500) l.layout { l.header(title:"Jenkins") diff --git a/core/src/main/resources/hudson/util/JenkinsReloadFailed/index_sr.properties b/core/src/main/resources/hudson/util/JenkinsReloadFailed/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2a99f9eb88d6b9bbd5d963e270fcd3a4faf5c8ac --- /dev/null +++ b/core/src/main/resources/hudson/util/JenkinsReloadFailed/index_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +msg=Jenkins \u0458\u0435 \u0431\u0438\u043E \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u0442 \u0434\u043E\u043A \u0458\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u0438\u0447\u0438\u0442\u0430\u0432\u0430\u043E \u043F\u043E\u0442\u0430\u043A\u0435 \u0441\u0430 \u0434\u0438\u0441\u043A\u0430, \u0438 \u043F\u043E\u0442\u043E\u043C \u0442\u043E\u0433\u0430 \u0458\u0435 \u0441\u0442\u0430\u043E \u0434\u0430 \u0431\u0438 \u0441\u0435 \u0441\u043F\u0440\u0435\u0447\u0438\u043B\u043E \u0433\u0443\u0431\u0438\u0442\u0430\u043A \u043F\u043E\u0434\u0430\u0442\u0430\u043A\u0430. \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0438\u0442\u0435 Jenkins. \ No newline at end of file diff --git a/core/src/main/resources/hudson/util/Messages_bg.properties b/core/src/main/resources/hudson/util/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..0877faf1c27a67664d93e914acf05af8daf3b8e8 --- /dev/null +++ b/core/src/main/resources/hudson/util/Messages_bg.properties @@ -0,0 +1,38 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ClockDifference.InSync=\ + \u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u0430\u043d +ClockDifference.Ahead=\ + {0} \u043d\u0430\u043f\u0440\u0435\u0434 +ClockDifference.Behind=\ + {0} \u043d\u0430\u0437\u0430\u0434 +ClockDifference.Failed=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 +FormFieldValidator.did_not_manage_to_validate_may_be_too_sl=\ + \u041d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 {0} (\u043c\u043e\u0436\u0435 Jenkins \u0434\u0430 \u0435 \u043f\u0440\u0435\u043a\u0430\u043b\u0435\u043d\u043e \u0431\u0430\u0432\u0435\u043d) +FormValidation.ValidateRequired=\ + \u0417\u0430\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u0430 \u0441\u0442\u043e\u0439\u043d\u043e\u0441\u0442 +FormValidation.Error.Details=\ + (\u0434\u0435\u0442\u0430\u0439\u043b\u0438) +HttpResponses.Saved=\ + \u0417\u0430\u043f\u0430\u0437\u0435\u043d\u043e diff --git a/core/src/main/resources/hudson/util/Messages_sr.properties b/core/src/main/resources/hudson/util/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a813bf1695eef8857567f0c9726bf6a9d63503bf --- /dev/null +++ b/core/src/main/resources/hudson/util/Messages_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +ClockDifference.InSync=\u0421\u0438\u043D\u0445\u0440\u043E\u043D\u0438\u0437\u043E\u0432\u0430\u043D\u043E +ClockDifference.Ahead={0} \u0438\u0441\u043F\u0440\u0435\u0434 +ClockDifference.Behind={0} \u0438\u0437\u0430 +ClockDifference.Failed=\u041F\u0440\u043E\u0432\u0435\u0440\u0430 \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u0430. +FormFieldValidator.did_not_manage_to_validate_may_be_too_sl=\u041F\u0440\u043E\u0432\u0435\u0440\u0430 {0} \u043D\u0438\u0458\u0435 \u0443\u0441\u043F\u0435\u043B\u043E. \u041C\u043E\u0433\u0443\u045B\u0435 \u0458\u0435 \u0434\u0430 Jenkins \u043D\u0438\u0458\u0435 \u0434\u043E\u0432\u043E\u0459\u043D\u043E \u0431\u0440\u0437. +FormValidation.Error.Details=(\u043F\u0440\u0438\u0434\u0430\u0436\u0438 \u0434\u0435\u0442\u0430\u0459\u0435) +FormValidation.ValidateRequired=\u041E\u0431\u0430\u0432\u0435\u0437\u043D\u043E +HttpResponses.Saved=\u0421\u0430\u0447\u0443\u0432\u0430\u043D\u043E \ No newline at end of file diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index.jelly b/core/src/main/resources/hudson/util/NoHomeDir/index.jelly index a75b653e04531f719bcde13f25187e04f01bdd6e..0476004a78585d0532bd39215387df955003ee1b 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index.jelly +++ b/core/src/main/resources/hudson/util/NoHomeDir/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties index c834d9aa69debb583a6a485f37c2cf2a87c61bdb..05f9fe5256f40bf7e26ab44d6da0d078fcdc3eb9 100644 --- a/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_de.properties @@ -1,32 +1,32 @@ -# The MIT License -# -# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Error=Fehler -errorMessage.1=\ - Das Stammverzeichnis ''{0}'' konnte nicht angelegt werden. In den meisten Fllen ist \ - dies ein Dateirechte-Problem. -errorMessage.2=\ - Um das Stammverzeichnis zu ndern, verwenden Sie die Umgebungsvariable JENKINS_HOME \ - oder die Java-Systemeigenschaft JENKINS_HOME. Weitere Details entnehmen Sie \ - der containerspezifischen \ - Jenkins-Dokumentation. - +# The MIT License +# +# Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Error=Fehler +errorMessage.1=\ + Das Stammverzeichnis ''{0}'' konnte nicht angelegt werden. In den meisten Fllen ist \ + dies ein Dateirechte-Problem. +errorMessage.2=\ + Um das Stammverzeichnis zu ndern, verwenden Sie die Umgebungsvariable JENKINS_HOME \ + oder die Java-Systemeigenschaft JENKINS_HOME. Weitere Details entnehmen Sie \ + der containerspezifischen \ + Jenkins-Dokumentation. + diff --git a/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties b/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ea9d4b334e3846895e9a3c7c9cda8fde03b4de1a --- /dev/null +++ b/core/src/main/resources/hudson/util/NoHomeDir/index_sr.properties @@ -0,0 +1,9 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +errorMessage.1=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043A\u0440\u0435\u0438\u0440\u0430\u0442\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u2018{0}\u2019, \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0437\u0431\u043E\u0433 \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u0442\u043A\u0430 \u043F\u0440\u0430\u0432\u0430. +errorMessage.2=\ + \u0414\u0430 \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0435 \u0433\u043B\u0430\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C, \u043A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 JENKINS_HOME \u043F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0443 \u0438\u043B\u0438 \ + JENKINS_HOME \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0443 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0443. \ + \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0414\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u043E \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u0438\u043C\u0430 \ + \u0437\u0430 \u0458\u043E\u0448 \u0434\u0435\u0442\u0430\u0459\u0430. \ No newline at end of file diff --git a/core/src/main/resources/hudson/util/NoTempDir/index.jelly b/core/src/main/resources/hudson/util/NoTempDir/index.jelly index c78d70f11caed032e645095a7ebdb1cdc6b64db4..f6b27dcef0c3d160d64267853ffb764d4d9febf7 100644 --- a/core/src/main/resources/hudson/util/NoTempDir/index.jelly +++ b/core/src/main/resources/hudson/util/NoTempDir/index.jelly @@ -24,6 +24,7 @@ THE SOFTWARE. + diff --git a/core/src/main/resources/hudson/util/NoTempDir/index_sr.properties b/core/src/main/resources/hudson/util/NoTempDir/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b4cd0a780b197673274e1296d5e39c05be428134 --- /dev/null +++ b/core/src/main/resources/hudson/util/NoTempDir/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Error=\u0413\u0440\u0435\u0448\u043A\u0430 +description=\ + \u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043A\u0440\u0435\u0438\u0440\u0430\u0442\u0438 \u043F\u0440\u0438\u0432\u0440\u0435\u043C\u0435\u043D\u0443 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443, \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0437\u0431\u043E\u0433 \u043B\u043E\u0448\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A \u043A\u043E\u043D\u0442\u0435\u0458\u043D\u0435\u0440\u043E\u043C. JVM \u043A\u043E\u0440\u0438\u0441\u0442\u0438 "{0}" \u0437\u0430 \u043F\u0440\u0438\u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C. \u0414\u0430\u043B\u0438 \u043F\u043E\u0441\u0442\u043E\u0458\u0438, \u0438 \u0434\u0430\u043B\u0438 \u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u043F\u0438\u0441\u0430\u0442\u0438 \u043F\u043E \u045A\u0435\u043C\u0443? diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column_bg.properties b/core/src/main/resources/hudson/views/BuildButtonColumn/column_bg.properties index 400d3577717b2ee3bd4b528e8b5c82c35c465495..c201dceb91173b32ca47f8b1894aaecd0aaad58e 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/column_bg.properties +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build_scheduled=\u0411\u0438\u043B\u0434\u0430 \u0431\u0435\u0448\u0435 \u043D\u0430\u0441\u0440\u043E\u0447\u0435\u043D -Schedule_a_build=\u041D\u0430\u0441\u0440\u043E\u0447\u0438 \u0431\u0438\u043B\u0434 \u0437\u0430 {0} +Build_scheduled=\ + \u041d\u0430\u0441\u0440\u043e\u0447\u0435\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Schedule_a_build=\ + \u041d\u0430\u0441\u0440\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c +Schedule_a_build_with_parameters=\ + \u041d\u0430\u0441\u0440\u043e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0438 diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column_lt.properties b/core/src/main/resources/hudson/views/BuildButtonColumn/column_lt.properties index 77fe4d6a89ec0d6921bd3210b54134cad397f67b..7a6d26a1d92e47cd81f73d8b7068f0d0e8d1a640 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/column_lt.properties +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column_lt.properties @@ -20,5 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build_scheduled=Kompiliavimo tvarkara\u0161tis -Schedule_a_build=Planuoti u\u017Eduot\u012F\u003a {0} +Build_scheduled=U\u017Eduotis suplanuota +Schedule_a_build=Paruo\u0161ti vykdymui: {0} +#Schedule_a_build_with_parameters= diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column_pl.properties b/core/src/main/resources/hudson/views/BuildButtonColumn/column_pl.properties index 2b3d505f7be1616475886f91072a40c795b77db7..3179ca1b18ec7ed99e425a39228c720f7c715387 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/column_pl.properties +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column_pl.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build_scheduled=Zaplanowany build -Schedule_a_build=Dodaj kompilacj\u0119 do kolejki dla {0} -Schedule_a_build_with_parameters=Zbuduj z parametrami dla {0} +Build_scheduled=Zadanie zosta\u0142o zaplanowane +Schedule_a_build=Dodaj zadanie do kolejki dla {0} +Schedule_a_build_with_parameters=Uruchom z parametrami dla {0} diff --git a/core/src/main/resources/hudson/views/BuildButtonColumn/column_sr.properties b/core/src/main/resources/hudson/views/BuildButtonColumn/column_sr.properties index 98c763b42ce4280a77c7f6bec05e9523f67bb62a..7711217d55162944b738d21f309edc1f885c4db2 100644 --- a/core/src/main/resources/hudson/views/BuildButtonColumn/column_sr.properties +++ b/core/src/main/resources/hudson/views/BuildButtonColumn/column_sr.properties @@ -1,4 +1,5 @@ # This file is under the MIT License by authors Build_scheduled=Plan pokretanja -Schedule_a_build=Zaka\u017Ei gradnju \u0437\u0430 {0} +Schedule_a_build=\u0417\u0430\u043A\u0430\u0436\u0438 \u0433\u0440\u0430\u0434\u045A\u0443 \u0437\u0430 {0} +Schedule_a_build_with_parameters=\u0417\u0430\u043A\u0430\u0436\u0438 \u0433\u0440\u0430\u0434\u045A\u0443 \u0441\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0438\u043C\u0430: {0} diff --git a/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs.jelly b/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs.jelly index 10b55865f6aef2cf8ce977f243f4b32a87362a0c..e49686bf358c1081a0432af8452f4c83839d9002 100644 --- a/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs.jelly +++ b/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs.jelly @@ -26,8 +26,8 @@ THE SOFTWARE. - - + + +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -New\ View=\u041D\u043E\u0432 \u0438\u0437\u0433\u043B\u0435\u0434 +New\ View=\ + \u041d\u043e\u0432 \u0438\u0437\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs_sr.properties b/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs_sr.properties index e072208cd44cfcb66986afab9efe2ae273b658e8..f8ec299e020f6eb33f50a540d14d21a6d7cfde3b 100644 --- a/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs_sr.properties +++ b/core/src/main/resources/hudson/views/DefaultMyViewsTabBar/myViewTabs_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -New\ View=Novi pogled +New\ View=\u041D\u043E\u0432\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs.jelly b/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs.jelly index 10b55865f6aef2cf8ce977f243f4b32a87362a0c..e49686bf358c1081a0432af8452f4c83839d9002 100644 --- a/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs.jelly +++ b/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs.jelly @@ -26,8 +26,8 @@ THE SOFTWARE. - - + + # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -New\ View=\u041D\u043E\u0432 \u0438\u0437\u0433\u043B\u0435\u0434 +New\ View=\ + \u041d\u043e\u0432 \u0438\u0437\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_sr.properties b/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_sr.properties index d115f683741c97018bc0e2bb4d4392948aa4c4f9..f8ec299e020f6eb33f50a540d14d21a6d7cfde3b 100644 --- a/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_sr.properties +++ b/core/src/main/resources/hudson/views/DefaultViewsTabBar/viewTabs_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -New\ View=Novi prikaz +New\ View=\u041D\u043E\u0432\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/hudson/model/Computer/_script_da.properties b/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config_bg.properties similarity index 84% rename from core/src/main/resources/hudson/model/Computer/_script_da.properties rename to core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config_bg.properties index 8bc431804971ab5ac410b37b5795ce74b5f77717..d92ae346a92272810b8de0a81455a6f5f30b3ad9 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_da.properties +++ b/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. Kohsuke Kawaguchi. Knud Poulsen. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=Denne eksekvering sker i slave agentens JVM. +Default\ view=\ + \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435\u043d \u0438\u0437\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config_sr.properties b/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..136fa5e10584f72524ce606e5ab38b93d6eebf7b --- /dev/null +++ b/core/src/main/resources/hudson/views/GlobalDefaultViewConfiguration/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Default\ view=\u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/JobColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/JobColumn/columnHeader_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c573467a68a04843b02f6138d52aed3f8d358ee2 --- /dev/null +++ b/core/src/main/resources/hudson/views/JobColumn/columnHeader_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Job=\u0417\u0430\u0434\u0430\u0442\u0430\u043A diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_bg.properties b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_bg.properties index a4eb002195025e81f2dde2ccaf92c7dd3840d557..bc3f6e1c227a0c7b3d4840735845d4b12c8361bd 100644 --- a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_bg.properties +++ b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Duration=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0430 \u043F\u0440\u043E\u0434\u044A\u043B\u0436\u0438\u0442\u0435\u043B\u043D\u043E\u0441\u0442 +Last\ Duration=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0430 \u043f\u0440\u043e\u0434\u044a\u043b\u0436\u0438\u0442\u0435\u043b\u043d\u043e\u0441\u0442 diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_pl.properties b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_pl.properties index a7ea02acbfffaf3ef403e72f865367f87dfd7b99..450a3a885331801399a4686781191284b9a5db12 100644 --- a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_pl.properties +++ b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Duration=Ostatni Czas Trwania +Last\ Duration=Czas trwania diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_sr.properties index 0dc0c40cfeb37d6c14adfecce606279e48d74c6b..04663dcd00f8252d8e77da63d77be0ba241d8419 100644 --- a/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_sr.properties +++ b/core/src/main/resources/hudson/views/LastDurationColumn/columnHeader_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Last\ Duration=Poslednje trajanje +Last\ Duration=\u0422\u0440\u0430\u0458\u0430\u045A\u0435 \u0437\u0430\u0434\u045A\u0435\u0433 diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/column_bg.properties b/core/src/main/resources/hudson/views/LastDurationColumn/column_bg.properties index c7bb92380325cf6254a331f7f808bfc01855d6e4..16104e2cd096e9e02147fea03489f4af2be5134e 100644 --- a/core/src/main/resources/hudson/views/LastDurationColumn/column_bg.properties +++ b/core/src/main/resources/hudson/views/LastDurationColumn/column_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -N/A=\u043D\u0435 \u0435 \u043D\u0430\u043B\u0438\u0447\u043D\u043E +N/A=\ + \u043b\u0438\u043f\u0441\u0432\u0430 diff --git a/core/src/main/resources/hudson/views/LastDurationColumn/column_sr.properties b/core/src/main/resources/hudson/views/LastDurationColumn/column_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8a2491e155deeae4f4576167a8c063bdfd7e621f --- /dev/null +++ b/core/src/main/resources/hudson/views/LastDurationColumn/column_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +N/A=\u041D/\u0414 diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_bg.properties b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_bg.properties index 1193a2c148987f1167497f8faeb39df4db518243..ce8b3902b9829e1d6892f8e6ff002567240fcb19 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_bg.properties +++ b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Failure=\u041F\u043E\u0441\u043B\u0435\u0434\u0435\u043D \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u0435\u043D +Last\ Failure=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_pl.properties b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_pl.properties index 4cd147a02b6cf6ab0ed297c86bcae4b59a3a0f7a..37b1ca45e7681a1e163d65e01b5361205ae7ff48 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_pl.properties +++ b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Failure=Ostatni B\u0142\u0105d +Last\ Failure=Ostatni b\u0142\u0105d diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_sr.properties index a26e6b3c24da85ae819949dc03197044e41d519b..8109ac216398c309bb8e6e247f627a353bc9c222 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_sr.properties +++ b/core/src/main/resources/hudson/views/LastFailureColumn/columnHeader_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Last\ Failure=Poslednja gre\u0161ka +Last\ Failure=\u0417\u0430\u0434\u045A\u0435 \u0441\u0430 \u0433\u0440\u0435\u0448\u043A\u0430\u043C\u0430 diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/column_bg.properties b/core/src/main/resources/hudson/views/LastFailureColumn/column_bg.properties index bf85796b54605134c665d9a6cfa65b4d90fb84e9..16104e2cd096e9e02147fea03489f4af2be5134e 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/column_bg.properties +++ b/core/src/main/resources/hudson/views/LastFailureColumn/column_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -N/A=- +N/A=\ + \u043b\u0438\u043f\u0441\u0432\u0430 diff --git a/core/src/main/resources/hudson/views/LastFailureColumn/column_sr.properties b/core/src/main/resources/hudson/views/LastFailureColumn/column_sr.properties index 5506e1cdd2ff593eaa7aad1920e6c4ae696e137c..8a2491e155deeae4f4576167a8c063bdfd7e621f 100644 --- a/core/src/main/resources/hudson/views/LastFailureColumn/column_sr.properties +++ b/core/src/main/resources/hudson/views/LastFailureColumn/column_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -N/A=Nije dostupno +N/A=\u041D/\u0414 diff --git a/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_bg.properties b/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..8eaf3a2bd444f3da15b263d01a76d1a87e2b6298 --- /dev/null +++ b/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Last\ Stable=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3d3642c740dd8bcd38b879fdff869b4168a8bdde --- /dev/null +++ b/core/src/main/resources/hudson/views/LastStableColumn/columnHeader_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Last\ Stable=\u0417\u0430\u0434\u045A\u0435 \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 diff --git a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_fr.properties b/core/src/main/resources/hudson/views/LastStableColumn/column_bg.properties similarity index 89% rename from test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_fr.properties rename to core/src/main/resources/hudson/views/LastStableColumn/column_bg.properties index 87c0ef6252ecf4f8a7437b029b97651a1d44b179..16104e2cd096e9e02147fea03489f4af2be5134e 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_fr.properties +++ b/core/src/main/resources/hudson/views/LastStableColumn/column_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Save=Sauvegarder +N/A=\ + \u043b\u0438\u043f\u0441\u0432\u0430 diff --git a/core/src/main/resources/hudson/views/LastStableColumn/column_sr.properties b/core/src/main/resources/hudson/views/LastStableColumn/column_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8a2491e155deeae4f4576167a8c063bdfd7e621f --- /dev/null +++ b/core/src/main/resources/hudson/views/LastStableColumn/column_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +N/A=\u041D/\u0414 diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_bg.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_bg.properties index 20e2cc8d349342de9443039b6231bf81a865a8ca..1510b1a47f723400467e8694ddb6bf94901cce95 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_bg.properties +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Success=\u041F\u043E\u0441\u043B\u0435\u0434\u0435\u043D \u0443\u0441\u043F\u0435\u0448\u0435\u043D +Last\ Success=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_pl.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_pl.properties index c09e14ce7cda04cb21a2bbaed23616057af63b5b..d188be71e23297a0a682dff79ab55de84c5156e4 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_pl.properties +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Last\ Success=Ostatni Sukces +Last\ Success=Ostatni sukces diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_sr.properties index 6dd5d603403254bae2b0a58c8ad928c97526ef60..977d468796a48149d71aebc91dee00c19ca02d0b 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_sr.properties +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/columnHeader_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Last\ Success=Poslednje uspe\u0161no +Last\ Success=\u0417\u0430\u0434\u045A\u0435 \u0443\u0441\u043F\u0435\u0448\u043Da diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/column_bg.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/column_bg.properties index c7bb92380325cf6254a331f7f808bfc01855d6e4..16104e2cd096e9e02147fea03489f4af2be5134e 100644 --- a/core/src/main/resources/hudson/views/LastSuccessColumn/column_bg.properties +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/column_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -N/A=\u043D\u0435 \u0435 \u043D\u0430\u043B\u0438\u0447\u043D\u043E +N/A=\ + \u043b\u0438\u043f\u0441\u0432\u0430 diff --git a/core/src/main/resources/hudson/views/LastSuccessColumn/column_sr.properties b/core/src/main/resources/hudson/views/LastSuccessColumn/column_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8a2491e155deeae4f4576167a8c063bdfd7e621f --- /dev/null +++ b/core/src/main/resources/hudson/views/LastSuccessColumn/column_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +N/A=\u041D/\u0414 diff --git a/core/src/main/resources/hudson/views/Messages_bg.properties b/core/src/main/resources/hudson/views/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..69a1733513e235d58fb549bf37b2b9f20ca3a19e --- /dev/null +++ b/core/src/main/resources/hudson/views/Messages_bg.properties @@ -0,0 +1,42 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +BuildButtonColumn.DisplayName=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +JobColumn.DisplayName=\ + \u0418\u043c\u0435 +LastDurationColumn.DisplayName=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u0442\u0440\u0430\u0435\u043d\u0435 +LastFailureColumn.DisplayName=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u0435\u043d \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +LastStableColumn.DisplayName=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u044f +LastSuccessColumn.DisplayName=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +StatusColumn.DisplayName=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 +WeatherColumn.DisplayName=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 +DefaultViewsTabsBar.DisplayName=\ + \u041b\u0435\u043d\u0442\u0430 \u0437\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0442\u0435 \u0438\u0437\u0433\u043b\u0435\u0434\u0438 +DefaultMyViewsTabsBar.DisplayName=\ + \u041b\u0435\u043d\u0442\u0430 \u0437\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u0442\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0438\u0437\u0433\u043b\u0435\u0434\u0438 diff --git a/test/src/main/resources/org/jvnet/hudson/test/SleepBuilder/config_pt.properties b/core/src/main/resources/hudson/views/Messages_pl.properties similarity index 90% rename from test/src/main/resources/org/jvnet/hudson/test/SleepBuilder/config_pt.properties rename to core/src/main/resources/hudson/views/Messages_pl.properties index 78367259590b457602d42c9a87d269df133f85d1..088bf10ca230014164cfc1d1eb346b085b8de59b 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/SleepBuilder/config_pt.properties +++ b/core/src/main/resources/hudson/views/Messages_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Copyright (c) 2016, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Time=Tempo +JobColumn.DisplayName=Nazwa diff --git a/core/src/main/resources/hudson/views/Messages_sr.properties b/core/src/main/resources/hudson/views/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0ed7e3366a9995a8a8589eed382a7703d96da81c --- /dev/null +++ b/core/src/main/resources/hudson/views/Messages_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +BuildButtonColumn.DisplayName=\u0414\u0443\u0433\u043C\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +JobColumn.DisplayName=\u0418\u043C\u0435 +LastFailureColumn.DisplayName=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +LastDurationColumn.DisplayName=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u043E \u0442\u0440\u0430\u0458\u0430\u045A\u0435 +LastSuccessColumn.DisplayName=\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +LastStableColumn.DisplayName=\u041F\u043E\u0441\u043B\u0435\u0434\u045A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +StatusColumn.DisplayName=\u0421\u0442\u0430\u045A\u0435 +WeatherColumn.DisplayName=\u0412\u0440\u0435\u043C\u0435\u043D\u0441\u043A\u0430 \u043F\u0440\u043E\u0433\u043D\u043E\u0437\u0430 +DefaultViewsTabsBar.DisplayName=\u0422\u0440\u0430\u043A\u0430 \u0437\u0430 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0435 +DefaultMyViewsTabsBar.DisplayName=\u0422\u0440\u0430\u043A\u0430 \u0437\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u0435 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/config_bg.properties b/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/config_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..49ebba10eb7cd725fe9ca702ff4e014fbae83bb3 --- /dev/null +++ b/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/config_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +My\ Views\ Tab\ Bar=\ + \u041b\u0435\u043d\u0442\u0430 \u0437\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0441\u043a\u0438 \u0438\u0437\u0433\u043b\u0435\u0434\u0438 diff --git a/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/config_sr.properties b/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c99dc05905aac7591d1a80df3d152f69425a494c --- /dev/null +++ b/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +My\ Views\ Tab\ Bar=\u0422\u0440\u0430\u043A\u0430 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0447\u043A\u0438\u0445 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 +Views\ Tab\ Bar=\u0422\u0440\u0430\u043A\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/help-myViewsTabBar_bg.html b/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/help-myViewsTabBar_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..e37a61aa9b7f5cf4089ca748ae81d70223f88a53 --- /dev/null +++ b/core/src/main/resources/hudson/views/MyViewsTabBar/GlobalConfigurationImpl/help-myViewsTabBar_bg.html @@ -0,0 +1,7 @@ +
      + Ако сте създали множество собствени изгледи в „Моите изгледи“, лентата за + изгледите става прекалено дълга. Точката за разширение „MyViewsTabBar“ дава + възможност на приставките да предоставят собствена реализация на лентата. + Това падащо меню съдържа наличните реализации за лентата. Само една от тях + може да е включена. Изберете я от падащия списък. +
      \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_bg.properties b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_bg.properties index 21599b2bde9f3ea0b04bfd06bce085e372d01d13..2eec4596f7604db9a1376ad0d619a4f105c43e3c 100644 --- a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_bg.properties +++ b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Status\ of\ the\ last\ build=\u0421\u044A\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u043D\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u044F \u0431\u0438\u043B\u0434 +Status\ of\ the\ last\ build=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +S=\ + \u0421 diff --git a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_pl.properties b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_pl.properties index ba4a18392195d71c1592aff0d729d721ecb90efc..4890220afc7322f7724536d216fc3a9228123c10 100644 --- a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_pl.properties +++ b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Status\ of\ the\ last\ build=Status ostatniej kompilacji +Status\ of\ the\ last\ build=Status ostatniego zadania diff --git a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_sr.properties index 23fd1afde124d3f9be116e602bc9a9460808c0f6..cd82ecab210a3691fd8f11af285fe1ec58e4bc33 100644 --- a/core/src/main/resources/hudson/views/StatusColumn/columnHeader_sr.properties +++ b/core/src/main/resources/hudson/views/StatusColumn/columnHeader_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Status\ of\ the\ last\ build=Status poslednje gradnje +Status\ of\ the\ last\ build=\u0421\u0442\u0430\u045A\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u045A\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/hudson/model/Computer/_script_zh_TW.properties b/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/config_bg.properties similarity index 84% rename from core/src/main/resources/hudson/model/Computer/_script_zh_TW.properties rename to core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/config_bg.properties index e7d191f786a25da99dd4aa3cd04ad8a1d1edd6d4..274d1ccc14e84955e2c4175f12a95f77901ef1e8 100644 --- a/core/src/main/resources/hudson/model/Computer/_script_zh_TW.properties +++ b/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/config_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2013, Chunghwa Telecom Co., Ltd., Pei-Tang Huang +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -This\ execution\ happens\ in\ the\ slave\ agent\ JVM.=\u5728 Slave \u4ee3\u7406\u7a0b\u5f0f\u7684 JVM \u4e2d\u57f7\u884c\u3002 +Views\ Tab\ Bar=\ + \u041b\u0435\u043d\u0442\u0430 \u0437\u0430 \u0438\u0437\u0433\u043b\u0435\u0434\u0438 diff --git a/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/config_sr.properties b/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d8d6bba6d01168738ef81d8dd61a97636244094a --- /dev/null +++ b/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Views\ Tab\ Bar=\u0422\u0440\u0430\u043A\u0430 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/help-viewsTabBar_bg.html b/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/help-viewsTabBar_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..2c4e9cc5a5ad271d9c0c563e5931aa81b5f0af58 --- /dev/null +++ b/core/src/main/resources/hudson/views/ViewsTabBar/GlobalConfigurationImpl/help-viewsTabBar_bg.html @@ -0,0 +1,8 @@ +
      + + Ако сте създали множество собствени изгледи, стандартната лента за изгледите + става прекалено дълга. Точката за разширение „ViewsToolBar“ дава възможност + на приставките да предоставят собствена реализация на лентата. Това падащо + меню съдържа наличните реализации за лентата. Само една от тях може да е + включена. Изберете я от падащия списък. +
      \ No newline at end of file diff --git a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_bg.properties b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_bg.properties index d2eff49e0b5a3a505ffec731c8ec94aebac7c5f0..e956271eda99289f1a177f9c44630a8bc406f175 100644 --- a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_bg.properties +++ b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_bg.properties @@ -1,3 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=\u0410\u0433\u0440\u0435\u0433\u0438\u0440\u0430\u043D \u0441\u0442\u0430\u0442\u0443\u0441 \u043E\u0442 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0442\u0435 \u0431\u0438\u043B\u0434\u043E\u0432\u0435 +Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f +W=\ + \u0421 diff --git a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pl.properties b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pl.properties index f518d43c5a30ff1dfb8aebfe3916a6bb7ff8311e..2df8e482e59a117f01c78a34d229dd3bc0ea4a95 100644 --- a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pl.properties +++ b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=Raport z ostatnich wykona\u0144 +Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=Raport z ostatnich zada\u0144 diff --git a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_sr.properties b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_sr.properties index 9e5e28e3a5aee799ac4192f8c12eb497039c817a..a82a73c5f89719d74fccb5792ba94674fd6ce645 100644 --- a/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_sr.properties +++ b/core/src/main/resources/hudson/views/WeatherColumn/columnHeader_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=Vremenski izve\u0161taj prikazuje prikupljen status posljednjih verzija +Weather\ report\ showing\ aggregated\ status\ of\ recent\ builds=\u0412\u0440\u0435\u043C\u0435\u043D\u0441\u043A\u0430 \u043F\u0440\u043E\u0433\u043D\u043E\u0437\u0430 \u043A\u043E\u0458\u0430 \u043F\u0440\u0438\u043A\u0430\u0436\u0435 \u0443\u043E\u043F\u0448\u0442\u0438 \u0441\u0442\u0430\u045A\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u045A\u0438\u0445 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.jelly b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.jelly index 639002d53743ce96b2b80efb63c2a83df8eb18ba..54309319f0a3533df9717e4d36a4cd8e44a57e8f 100644 --- a/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.jelly +++ b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.jelly @@ -27,52 +27,6 @@ THE SOFTWARE. Render build histories. --> - - - - - - -
    - - - - - - + + diff --git a/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.properties b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.properties new file mode 100644 index 0000000000000000000000000000000000000000..5e590c38363667eb7dd30ceffcc75c7de42977ed --- /dev/null +++ b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries.properties @@ -0,0 +1 @@ +confirm=Are you sure you want to cancel the queued run of {0}? diff --git a/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_bg.properties b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_bg.properties index da63260520d130864997b2eccfa449b8ed9a6409..ac4cc7fd3e6d3184accce3ebc2dc20b47f9277ac 100644 --- a/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_bg.properties +++ b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_bg.properties @@ -1,4 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -cancel\ this\ build=\u043E\u0442\u043A\u0430\u0436\u0438 -pending=\u0438\u0437\u0447\u0430\u043A\u0432\u0430\u043D\u0435 +cancel\ this\ build=\ + \u041e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +pending=\ + \u041f\u0440\u0435\u0434\u0441\u0442\u043e\u0438 diff --git a/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_sr.properties b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f318f6c79876cf1cff2ff8fb42184903ca1d05db --- /dev/null +++ b/core/src/main/resources/hudson/widgets/BuildHistoryWidget/entries_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +confirm=\u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043E\u0442\u043A\u0430\u0436\u0435\u0442\u0435 \u043F\u043B\u0430\u043D\u0438\u0440\u0430\u043D\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 {0}? +cancel\ this\ build=\u041E\u0442\u043A\u0430\u0436\u0438 \u043E\u0432\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +pending=\u0427\u0435\u043A\u0430\u0458\u0443\u045B\u0438 +Expected\ build\ number=O\u0447\u0435\u043A\u0438\u0432\u0430\u043D \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \ No newline at end of file diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/ajaxBuildHistory.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/ajaxBuildHistory.jelly index 1011d9510eb2df5d3f58a5af9cce7bdec13c1d29..4d01266f09a95774f36cc3b215f4c989b08ccd1e 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/ajaxBuildHistory.jelly +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/ajaxBuildHistory.jelly @@ -25,10 +25,6 @@ THE SOFTWARE. - - -
    -
    -
    - -
    - -
    - #${queuedItems.size()==1 ? it.owner.nextBuildNumber - : it.owner.nextBuildNumber+queuedItems.size()-i-1} -
    -
    -
    - - - - (${%pending}—) - - - (${%pending}) - - - -
    - -
    -
    -
    -
    -
    - - - -
    -
    -
    -
    - -
    - + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entries.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/entries.jelly index 2a49d5a6981c971ed4f312d492dd6668c7df5713..8c07368d68f839346b02583f5aed2daa88097b86 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entries.jelly +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entries.jelly @@ -27,9 +27,9 @@ THE SOFTWARE. --> - + - - + + \ No newline at end of file diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly index 44e3f664e383bbd25f77308ed718ecf1d0c96866..42212f8583678db862275323a427bc0d38a12389 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.jelly @@ -26,10 +26,12 @@ THE SOFTWARE. Render a single build history entry indicated by ${build} --> - - - - + + + + + +
    @@ -42,7 +44,7 @@ THE SOFTWARE. - +
    @@ -59,8 +61,8 @@ THE SOFTWARE.
    - - + +
    diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.properties new file mode 100644 index 0000000000000000000000000000000000000000..6aa3af4cc19b3750c49d1c803ab7b18c9f7551c5 --- /dev/null +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry.properties @@ -0,0 +1 @@ +confirm=Are you sure you want to abort {0}? diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_bg.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_bg.properties index 75285c4330bd15251abea45c569d3e43518b71be..210cd27a86c6e57f69f27c2bb9b95ece818681ac 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_bg.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Console\ Output=\u041A\u043E\u043D\u0437\u043E\u043B\u0435\u043D \u0438\u0437\u0445\u043E\u0434 +Console\ Output=\ + \u041a\u043e\u043d\u0437\u043e\u043b\u0435\u043d \u0438\u0437\u0445\u043e\u0434 diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pl.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pl.properties index 3dc5cc2c1e0a9998e457438159491881f0a17c35..d648319d06bf1b55c02d28b3e4547e6dc6d99f38 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pl.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_pl.properties @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Console\ Output=Wyj\u015Bcie konsoli +Console\ Output=Logi konsoli diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_sr.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_sr.properties index 1695ebc85e80a6304df2939da855403a729a27c9..c44ac8dff6a868776511419ed5a3dcb34f6fb73f 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/entry_sr.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/entry_sr.properties @@ -1,3 +1,4 @@ # This file is under the MIT License by authors -Console\ Output=Konzolni Output +confirm=\u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043E\u0442\u043A\u0430\u0436\u0435\u0442\u0435 \u043F\u043B\u0430\u043D\u0438\u0440\u0430\u043D\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 {0}? +Console\ Output=\u041A\u043E\u043D\u0437\u043E\u043B\u043D\u0438 \u0438\u0441\u0445\u043E\u0434 diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly b/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly index f43ba940688401f2bda57cb516e1c844a4497ba6..b4ffcd388584e4272b98c3f7f5e8980ac123fde4 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/index.jelly @@ -51,10 +51,30 @@ THE SOFTWARE. - + +
    +
    + + + +
    + - - + + + + + + +
    + x + +
    + + + + + - ${%More ...} -
    +
    diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/index_bg.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/index_bg.properties index 5797ac76ce0efdb95f1c6519de80672760aa965f..4711b43705b5feb4c195543d06062698e643bdc4 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/index_bg.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/index_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -More\ ...=\u041F\u043E\u0432\u0435\u0447\u0435... -for\ all=\u0437\u0430 \u0432\u0441\u0438\u0447\u043A\u0438 -for\ failures=\u0437\u0430 \u043F\u0440\u043E\u043F\u0430\u0434\u0430\u0449\u0438\u0442\u0435 -trend=\u0442\u0440\u0435\u043D\u0434 +for\ all=\ + \u0437\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 +for\ failures=\ + \u0437\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438\u0442\u0435 +trend=\ + \u0442\u0440\u0435\u043d\u0434 +Clear=\ + \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 +find=\ + \u0422\u044a\u0440\u0441\u0435\u043d\u0435 diff --git a/core/src/main/resources/hudson/widgets/HistoryWidget/index_sr.properties b/core/src/main/resources/hudson/widgets/HistoryWidget/index_sr.properties index 7c753aa453a0ccabfd8f3b3fb5961e6ac41ef2f3..f3e3827619ab97300caa7489638f81de77ba40d1 100644 --- a/core/src/main/resources/hudson/widgets/HistoryWidget/index_sr.properties +++ b/core/src/main/resources/hudson/widgets/HistoryWidget/index_sr.properties @@ -1,5 +1,8 @@ # This file is under the MIT License by authors -More\ ...=Vi\u0161e -for\ all=za sve -for\ failures=za otkaze +for\ all=\u0437\u0430 \u0441\u0432\u0435 +for\ failures=\u0437\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0438\u0435 +trend=\u0442\u0440\u0435\u043D\u0434 +Clear=\u0418\u0437\u0431\u0440\u0438\u0448\u0438 +find=\u043F\u043E\u0442\u0440\u0430\u0436\u0438 +More\ ...=\u0412\u0438\u0448\u0435 diff --git a/core/src/main/resources/hudson/widgets/Messages_bg.properties b/core/src/main/resources/hudson/widgets/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..32947f29e176c8f63acebf8b967e3cb1dd4d4c6f --- /dev/null +++ b/core/src/main/resources/hudson/widgets/Messages_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +BuildHistoryWidget.DisplayName=\ + \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 diff --git a/test/src/main/resources/org/jvnet/hudson/test/SleepBuilder/config_pt_BR.properties b/core/src/main/resources/hudson/widgets/Messages_pl.properties similarity index 90% rename from test/src/main/resources/org/jvnet/hudson/test/SleepBuilder/config_pt_BR.properties rename to core/src/main/resources/hudson/widgets/Messages_pl.properties index 78367259590b457602d42c9a87d269df133f85d1..0bf1fc9fa93fed78443c9ddc296eb6dfb8bc19d9 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/SleepBuilder/config_pt_BR.properties +++ b/core/src/main/resources/hudson/widgets/Messages_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Copyright (c) 2016, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Time=Tempo +BuildHistoryWidget.DisplayName=Historia zada\u0144 diff --git a/core/src/main/resources/hudson/widgets/Messages_sr.properties b/core/src/main/resources/hudson/widgets/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..ba1355710a585afc9a6e407ad387c75a5b57172c --- /dev/null +++ b/core/src/main/resources/hudson/widgets/Messages_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +BuildHistoryWidget.DisplayName=\u0418\u0441\u0442\u043E\u0440\u0438\u0458\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \ No newline at end of file diff --git a/core/src/main/resources/hudson/win32errors_ja.properties b/core/src/main/resources/hudson/win32errors_ja.properties index e5332c59037a73a4c1f91133ab4a23026a176c67..3fec9b845efb3fc010a50cc69078de94d0489d3e 100644 --- a/core/src/main/resources/hudson/win32errors_ja.properties +++ b/core/src/main/resources/hudson/win32errors_ja.properties @@ -574,8 +574,6 @@ error273= \ \u672A\u77E5\u306E\u30A8\u30E9\u30FC (0x111) error274= \ \u672A\u77E5\u306E\u30A8\u30E9\u30FC (0x112) -error267= \ -\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u540D\u304C\u7121\u52B9\u3067\u3059\u3002 error275= \ \u62E1\u5F35\u5C5E\u6027\u304C\u30D0\u30C3\u30D5\u30A1\u306B\u304A\u3055\u307E\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002 error276= \ diff --git a/core/src/main/resources/jenkins/diagnosis/HsErrPidList/index_lt.properties b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/index_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..dbb4cf4fdd7a36b4b51cc5073b817eff4650eaf3 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/index_lt.properties @@ -0,0 +1,9 @@ +blurb=\u0160ios JVM l\u016b\u017eimo ataskaitos rastos \u0161iame Jenkinse. \ + Jei manote, kad problema Jenkinse, pra\u0161ome apie tai prane\u0161ti. \ + Jenkinsas remiasi heuristika ie\u0161kodamas \u0161i\u0173 fail\u0173. Patikimesniam aptikimui galite prid\u0117ti \ + -XX:ErrorFile=/path/to/hs_err_pid%p.log kaip j\u016bs\u0173 JVM argument\u0105. +ago=prie\u0161 {0} +Name=Pavadinimas +Date=Data +Java\ VM\ Crash\ Reports=Java VM l\u016b\u017eimo ataskaitos +Delete=Trinti diff --git a/core/src/main/resources/jenkins/diagnosis/HsErrPidList/index_sr.properties b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e1b2a24bec56b1179327af929b792318580f9ab5 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/index_sr.properties @@ -0,0 +1,11 @@ +# This file is under the MIT License by authors + +Java\ VM\ Crash\ Reports=\u0418\u0437\u0432\u0435\u0448\u0440\u0430\u0458\u0438 JVM \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438\u043C\u0430 +blurb=\u041D\u0430\u0452\u0435\u043D\u0438 \u0441\u0443 \u0438\u0437\u0432\u0435\u0448\u0440\u0430\u0458\u0438 JVM \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438\u043C\u0430 \u0437\u0430 \u043E\u0432\u0443 Jenkins \u043C\u0430\u0448\u0438\u043D\u0443. \ + \u0410\u043A\u043E \u043C\u0438\u0441\u043B\u0438\u0442\u0435 \u0434\u0430 \u0441\u0442\u0435 \u043D\u0430\u0448\u043B\u0438 \u043F\u0440\u043E\u0431\u043B\u0435\u043C \u0441\u0430 Jenkins-\u043E\u043C, \u043C\u043E\u043B\u0438\u043C\u043E \u043F\u0440\u0438\u0458\u0430\u0432\u0438 \u0433\u0430. \ + Jenkins \u043A\u043E\u0440\u0438\u0441\u0442\u0438 \u043D\u0435\u043A\u043E\u043B\u0438\u043A\u043E \u0445\u0435\u0443\u0440\u0438\u0441\u0442\u0438\u043A\u0435 \u0434\u0430 \u043F\u0440\u043E\u043D\u0430\u0452\u0435 \u043E\u0432\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435. \u041A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 JVM \u043E\u043F\u0446\u0438\u0458\u0443 \ + -XX:ErrorFile=/path/to/hs_err_pid%p.log \u0437\u0430 \u043F\u043E\u0443\u0437\u0434\u0430\u043D\u0438\u0458\u0435 \u043F\u0440\u0435\u0442\u0440\u0430\u0436\u0438\u0432\u0430\u045A\u0435. +Name=\u0418\u043C\u0435 +Date=\u0414\u0430\u0442\u0443\u043C +ago=\u043F\u0440\u0435 {0} +Delete=\u0418\u0437\u0431\u0440\u0438\u0448\u0438 diff --git a/core/src/main/resources/jenkins/diagnosis/HsErrPidList/message_lt.properties b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/message_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1d4ebb62d19e8874400b102e64e5aaf74f51b25 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/message_lt.properties @@ -0,0 +1 @@ +blurb=Pana\u0161u, kad \u0161is Jenkinsas nul\u016b\u017eo. Pra\u0161ome patikrinti \u017eurnal\u0105. diff --git a/core/src/main/resources/jenkins/diagnosis/HsErrPidList/message_sr.properties b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e58a04dbd01d60ed4bb092a05aaf7c46cefe7f86 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnosis/HsErrPidList/message_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +blurb=Jenkins \u0458\u0435 \u043F\u0440\u0435\u0441\u0442\u0430\u043E \u0434\u0430 \u0440\u0430\u0434\u0438. \u041C\u043E\u043B\u0438\u043C\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B. diff --git a/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message.jelly b/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message.jelly new file mode 100644 index 0000000000000000000000000000000000000000..80d6bd1e5f077ad0edef1189dd4b3c1f4a9dd658 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message.jelly @@ -0,0 +1,11 @@ + + +
    + ${%Warning!} + ${%blurb(app.initLevel)} + ${%Example: usage of} @Initializer(after = InitMilestone.COMPLETED) ${%in a plugin} + (JENKINS-37759). + ${%Please} ${%report a bug} ${%in the Jenkins bugtracker}. + +
    +
    diff --git a/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message.properties b/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message.properties new file mode 100644 index 0000000000000000000000000000000000000000..c34fa2df469d857f2db20092ca270de69aba3f5e --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message.properties @@ -0,0 +1,6 @@ +blurb= Jenkins initialization has not reached the COMPLETED initialization milestone after the configuration reload. \ + Current state is: \"{0}\". \ + Such invalid state may cause undefined incorrect behavior of Jenkins plugins. \ + It is likely an issue with the jenkins initialization or reloading task graph. + + diff --git a/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message_sr.properties b/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8635ae34b570fad63316b5f00913409cf73df0e5 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/CompletedInitializationMonitor/message_sr.properties @@ -0,0 +1,12 @@ +# This file is under the MIT License by authors + +Warning!=\u0423\u043F\u043E\u0437\u043E\u0440\u0435\u045A\u0435! +blurb=\u0418\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0458\u0430 Jenkins-\u0430 \u043D\u0438\u0458\u0435 \u0434\u043E\u0441\u0442\u0438\u0433\u043B\u043E \u0434\u043E \u0444\u0430\u0437\u0435 COMPLETED \u043F\u043E\u0441\u043B\u0435 \u043F\u043E\u043D\u043E\u0432\u043E\u0433 \u0443\u0447\u0438\u0442\u0430\u045A\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430. \ + \u0422\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u0441\u0442\u0430\u045A\u0435 \u0458\u0435: "{0}". \ + \u041E\u0432\u0430\u043A\u0432\u043E \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u043D\u043E \u0441\u0442\u0430\u045A\u0435 \u043C\u043E\u0436\u0435 \u0434\u043E\u0432\u0435\u0441\u0442\u0438 \u0434\u043E \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430 \u0441\u0430 Jenkins \u043C\u043E\u0434\u0443\u043B\u0438\u043C\u0430. \ + \u0412\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u0438\u043C\u0430 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430 \u0441\u0430 \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0458\u043E\u043C \u0438\u043B\u0438 \u0443\u0447\u0438\u0442\u0430\u045A\u0430 task graph. +Example\:\ usage\ of=\u041F\u0440\u0438\u043C\u0435\u0440: +in\ a\ plugin=\u0443 \u043C\u043E\u0434\u0443\u043B\u0438 +Please=\u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, +report\ a\ bug=\u043F\u0440\u0438\u0432\u0430\u0458\u0438 \u0433\u0440\u0435\u0448\u043A\u0443 +in\ the\ Jenkins\ bugtracker=\u043D\u0430 \u0441\u0438\u0441\u0442\u0435\u043C \u0437\u0430 \u043F\u0440\u0430\u045B\u0435\u045A\u0435 \u0433\u0440\u0435\u0448\u0430\u043A\u0430 diff --git a/core/src/main/resources/jenkins/diagnostics/Messages.properties b/core/src/main/resources/jenkins/diagnostics/Messages.properties new file mode 100644 index 0000000000000000000000000000000000000000..17a3543c5667c16822fdab75ff58009b6bef2600 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/Messages.properties @@ -0,0 +1,2 @@ +CompletedInitializationMonitor.DisplayName=Jenkins Initialization Monitor +SecurityIsOffMonitor.DisplayName=Disabled Security diff --git a/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message.properties b/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message.properties deleted file mode 100644 index c1fc741c55c806b76d197c4b9dbdc3bddad85211..0000000000000000000000000000000000000000 --- a/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message.properties +++ /dev/null @@ -1,4 +0,0 @@ -blurb=This version of Jenkins comes with new versions of the following plugins that are currently \ - pinned in \ - the plugin manager. \ - It is recommended to upgrade them to at least the version bundled with Jenkins. diff --git a/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message_ja.properties b/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message_ja.properties deleted file mode 100644 index b0eb2a9b606174b1117c21dfbf600f4fa8aa8d50..0000000000000000000000000000000000000000 --- a/core/src/main/resources/jenkins/diagnostics/PinningIsBlockingBundledPluginMonitor/message_ja.properties +++ /dev/null @@ -1,32 +0,0 @@ -# The MIT License -# -# Copyright (c) 2015, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -# This version of Jenkins comes with new versions of the following plugins that are currently \ -# pinned in \ -# the plugin manager. \ -# It is recommended to upgrade them to at least the version bundled with Jenkins. - - -blurb=\u3053\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306eJenkins\u3067\u306f\u3001\u30d7\u30e9\u30b0\u30a4\u30f3\u30de\u30cd\u30fc\u30b8\u30e3\u30fc\u3067\ -\u30d4\u30f3\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u6b21\u306e\u30d7\u30e9\u30b0\u30a4\u30f3\u304c\ -\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3055\u308c\u3066\u3044\u307e\u3059\u3002\ -\u30d4\u30f3\u304c\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u308b\u30d7\u30e9\u30b0\u30a4\u30f3\u3092\u3001\u5c11\u306a\u304f\u3068\u3082Jenkins\u306b\u30d0\u30f3\u30c9\u30eb\u3055\u308c\u3066\u3044\u308b\u30d0\u30fc\u30b8\u30e7\u30f3\u306b\u30a2\u30c3\u30d7\u30c7\u30fc\u30c8\u3059\u308b\u3053\u3068\u3092\u63a8\u5968\u3057\u307e\u3059\u3002 diff --git a/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_cs.properties b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_cs.properties new file mode 100644 index 0000000000000000000000000000000000000000..2cae869ce180d72f3ce6cb7a5bde144d9eb110b1 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_cs.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Setup\ Security=Nastaven\u00ED zabezpe\u010Den\u00ED +Dismiss=Rozum\u00EDm +blurb=Nezabezpe\u010Den\u00FD b\u011Bh aplikace Jenkins umo\u017E\u0148uje komukoliv na s\u00EDti spou\u0161t\u011Bt procesy va\u0161\u00EDm \ + jm\u00E9nem. Pro omezen\u00ED tohoto zneu\u017Eit\u00ED pros\u00EDm zva\u017Ete zapnut\u00ED autentizace do aplikace Jenkins. diff --git a/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_lt.properties b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..43f1984922f5744b373de8429a340a053a7628b8 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_lt.properties @@ -0,0 +1,4 @@ +blurb=Neapsaugotas Jenkinsas leid\u017eia bet kam tinkle paleisti procesus j\u016bs\u0173 vardu. \ + Apsvarstykite galimyb\u0119 bent jau \u012fjungti autentikacij\u0105, kad b\u016bt\u0173 sunkiau piktnaud\u017eiauti. +Setup\ Security=Nustatyti saugum\u0105 +Dismiss=Praleisti diff --git a/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_pl.properties b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..4a432255090f40c2120da143d828c23225725740 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_pl.properties @@ -0,0 +1,4 @@ +blurb=Dost\u0119p do niezabezpieczonego Jenkinsa pozwala ka\u017Cdemu w sieci wykonywa\u0107 akcje w twoim imieniu. \ + Rozwa\u017C przynajmniej w\u0142\u0105czenie uwierzytelnienia by zniech\u0119ci\u0107 do nadu\u017Cy\u0107. +Setup\ Security=W\u0142\u0105cz uwierzytelnienie +Dismiss=Ignoruj diff --git a/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_sr.properties b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..170a58076ae490438bdfecb49d5a763f8f8eaac3 --- /dev/null +++ b/core/src/main/resources/jenkins/diagnostics/SecurityIsOffMonitor/message_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Setup\ Security=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E\u0441\u0442 +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 +blurb=\u041D\u0435\u043E\u0431\u0435\u0437\u0431\u0435\u0436\u0435\u043D\u0435 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0435 Jenkins-\u0430 \u0434\u0430\u0458\u0435 \u0431\u0438\u043B\u043E \u043A\u043E\u043C\u0435 \u043D\u0430 \u043C\u0440\u0435\u0436\u0438 \u043F\u0440\u0438\u0441\u0442\u0443\u043F \u043F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0443 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430. \ + \u0422\u0440\u0435\u0431\u0430\u043B\u043E \u0431\u0438 \u0431\u0430\u0440\u0435\u043C \u0443\u043A\u0459\u0443\u0447\u0438\u0442\u0438 \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u043A\u0430\u0446\u0438\u0458\u0443 \u0434\u0430 \u0441\u0435 \u043F\u0440\u0435\u0447\u0438 \u0437\u043B\u043E\u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0430. diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.jelly b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.jelly new file mode 100644 index 0000000000000000000000000000000000000000..02a02dc408b8db9ae7e05db202e7ac1ad9c36afb --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.jelly @@ -0,0 +1,47 @@ + + + + +
    + +
    + +
    +
    +
    +
    diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties new file mode 100644 index 0000000000000000000000000000000000000000..417fce51c27e738802c35f857d8fe948c4fee733 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token.properties @@ -0,0 +1,9 @@ +authenticate-security-token.getting.started=Getting Started +authenticate-security-token.unlock.jenkins=Unlock Jenkins +jenkins.install.findSecurityTokenMessage=To ensure Jenkins is securely set up by the administrator, \ +a password has been written to the log (not sure where to find it?) and this file on the server:

    {0}

    +authenticate-security-token.copy.password=Please copy the password from either location and paste it below. +authenticate-security-token.error=ERROR: +authenticate-security-token.password.incorrect=The password entered is incorrect, please check the file for the correct password +authenticate-security-token.password.administrator=Administrator password +authenticate-security-token.continue=Continue diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4a62fa8f78b28a82ed9b5f8446fa49d0daf6951b --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_fr.properties @@ -0,0 +1,13 @@ +authenticate-security-token.getting.started=D\u00e9marrage +authenticate-security-token.unlock.jenkins=D\u00e9bloquer Jenkins +jenkins.install.findSecurityTokenMessage=Pour \u00eatre s\u00fbr que que Jenkins soit configur\u00e9 de fa\u00e7on s\u00e9curis\u00e9e \ +par un administrateur, un mot de passe a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 dans le fichier de logs \ +(o\u00f9 le trouver) \ +ainsi que dans ce fichier sur le serveur :

    {0}

    +authenticate-security-token.copy.password=Veuillez copier le mot de passe depuis un des 2 endroits et le coller \ +ci-dessous. +authenticate-security-token.error=ERREUR: +authenticate-security-token.password.incorrect=Le mot de passe saisi est incorrect, veuillez v\u00e9rifier \ +dans le fichier le mot de passe correct +authenticate-security-token.password.administrator=Mot de passe administrateur +authenticate-security-token.continue=Continuer \ No newline at end of file diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..04d18031fd7c24677da64409d3df7bc1e03e14c4 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_lt.properties @@ -0,0 +1,9 @@ +authenticate-security-token.getting.started=\u012evadas +authenticate-security-token.unlock.jenkins=Atrakinti Jenkins\u0105 +jenkins.install.findSecurityTokenMessage=Kad u\u017etikrintum\u0117me kad Jenkins\u0105 saugiai paruo\u0161\u0117 administratorius, \ +slapta\u017eodis buvo \u012fra\u0161ytas \u012f \u017eurnal\u0105 (ne\u017einote, kur j\u012f rasti?) ir \u0161\u012f fail\u0105 serveryje:

    {0}

    +authenticate-security-token.copy.password=Pra\u0161ome nukopijuoti slapta\u017eiod\u012f i\u0161 bet kurios vietos \u012f \u017eemiau esant\u012f lauk\u0105. +authenticate-security-token.error=KLAIDA: +authenticate-security-token.password.incorrect=\u012evestas neteisingas slapta\u017eodis, pra\u0161ome patikrinti fail\u0105 ir rasti teising\u0105 slapta\u017eod\u012f +authenticate-security-token.password.administrator=Administratoriaus slapta\u017eodis +authenticate-security-token.continue=T\u0119sti diff --git a/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..de25ba64e87f38cb5ffd96d85d5c639c21989c86 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/authenticate-security-token_sr.properties @@ -0,0 +1,11 @@ +# This file is under the MIT License by authors + +authenticate-security-token.getting.started=\u041F\u043E\u0447\u0435\u0442\u0430\u043A +authenticate-security-token.unlock.jenkins=\u041E\u0442\u043A\u0459\u0443\u0447\u0430\u0458 Jenkins +jenkins.install.findSecurityTokenMessage=\u0414\u0430 \u0431\u0443\u0434\u0435 \u0431\u0438\u043E \u043F\u0440\u0438\u0441\u0442\u0443\u043F Jenkins-\u0443 \u043E\u0431\u0435\u0437\u0431\u0435\u0452\u0435\u043D, \ +\u043B\u043E\u0437\u0438\u043D\u043A\u0430 \u0458\u0435 \u0431\u0438\u043B\u0430 \u0438\u0437\u043F\u0438\u0441\u0430\u043D\u0430 \u0436\u0443\u0440\u043D\u0430\u043B\u0443 (\u043D\u0438\u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0433\u0434\u0435 \u0441\u0435 \u0442\u043E \u043D\u0430\u043B\u0430\u0437\u0438?) \u0438 \u0443 \u043E\u0432\u043E\u0458 \u0434\u0430\u0442\u043E\u0442\u0435\u0446\u0438 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0443:

    {0}

    +authenticate-security-token.copy.password=\u041C\u043E\u043B\u0438\u043C\u043E \u0438\u0441\u043A\u043E\u043F\u0438\u0440\u0430\u0458\u0442\u0435 \u043B\u043E\u0437\u0438\u043D\u043A\u0443 \u0441\u0430 \u0458\u0435\u0434\u043D\u0443 \u043E\u0434 \u0442\u0438\u0445 \u043B\u043E\u043A\u0430\u0446\u0438\u0458\u0430 \u0438 \u0443\u0431\u0430\u0446\u0438\u0458\u0435 \u0443 \u043E\u0434\u0433\u043E\u0432\u0430\u0440\u0443\u0458\u0443\u045B\u0435 \u043F\u043E\u0459\u0435. +authenticate-security-token.error=\u0413\u0420\u0415\u0428\u041A\u0410: +authenticate-security-token.password.incorrect=\u041D\u0430\u0432\u0435\u0434\u0435\u043D\u0430 \u043B\u043E\u0437\u0438\u043D\u043A\u0430 \u0441\u0435 \u043D\u0435 \u043F\u043E\u043A\u043B\u0430\u043F\u0430, \u043C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441 \u043F\u043E\u0442\u0440\u0430\u0436\u0438\u0442\u0435 \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0443 \u0437\u0430 \u0442\u0430\u0447\u043D\u0443 \u043B\u043E\u0437\u0438\u043D\u043A\u0443. +authenticate-security-token.password.administrator=\u041B\u043E\u0437\u0438\u043D\u043A\u0430 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430 +authenticate-security-token.continue=\u041D\u0430\u0441\u0442\u0430\u0432\u0438 diff --git a/core/src/main/resources/jenkins/install/SetupWizard/client-scripts.jelly b/core/src/main/resources/jenkins/install/SetupWizard/client-scripts.jelly new file mode 100644 index 0000000000000000000000000000000000000000..dcaa4219a11e0ce947b43a08fdacec0a386370fc --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/client-scripts.jelly @@ -0,0 +1,7 @@ + + + + + + + diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser.properties new file mode 100644 index 0000000000000000000000000000000000000000..75ce472514bcc2537286e4a4eed35e7d0d911182 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser.properties @@ -0,0 +1 @@ +Create\ First\ Admin\ User=Create First Admin User \ No newline at end of file diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_fr.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3769685377be96ae94467b9f683921d36b1eb475 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_fr.properties @@ -0,0 +1 @@ +Create\ First\ Admin\ User=Cr\u00e9er le 1er utilisateur Administrateur \ No newline at end of file diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_lt.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..140b61fc0402671e3801586d0872d678b14bc939 --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_lt.properties @@ -0,0 +1 @@ +Create\ First\ Admin\ User=Sukurti pirm\u0105 administratoriaus naudotoj\u0105 diff --git a/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_sr.properties b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6d39904f8d076c404ab83c42cb5462edb91c6c6a --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/setupWizardFirstUser_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Create\ First\ Admin\ User=\u041A\u0440\u0435\u0438\u0440\u0430\u0458\u0442\u0435 \u043F\u0440\u0432\u043E\u0433 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430 diff --git a/core/src/main/resources/jenkins/install/SetupWizard/wizard-ui.jelly b/core/src/main/resources/jenkins/install/SetupWizard/wizard-ui.jelly new file mode 100644 index 0000000000000000000000000000000000000000..b25f58b27394a55bfafdad76655445d38ee59dba --- /dev/null +++ b/core/src/main/resources/jenkins/install/SetupWizard/wizard-ui.jelly @@ -0,0 +1,15 @@ + + + + + + + + diff --git a/core/src/main/resources/jenkins/install/UpgradeWizard/client-scripts.jelly b/core/src/main/resources/jenkins/install/UpgradeWizard/client-scripts.jelly new file mode 100644 index 0000000000000000000000000000000000000000..a00b91d05e975300d5a3abe1922a562c478764dc --- /dev/null +++ b/core/src/main/resources/jenkins/install/UpgradeWizard/client-scripts.jelly @@ -0,0 +1,86 @@ + + + + +
    +
    + + %{Snooze} + +
    + ${%msg.before} + ${%msg.link} + ${%msg.after} +
    +
    +
    + + +
    + +
    +
    diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.properties b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.properties new file mode 100644 index 0000000000000000000000000000000000000000..60f6fe569480c5a58b2b391b1c5c96d075c485c8 --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/footer.properties @@ -0,0 +1 @@ +tooltip=There are {0} active administrative monitors. \ No newline at end of file diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.css b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.css new file mode 100644 index 0000000000000000000000000000000000000000..21aad475e01a8b3548446f09f89c929633250ddd --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.css @@ -0,0 +1,70 @@ +#visible-am-container { + float: right; +} +#visible-am-button { + text-align: center; + font-size: 20px; + font-weight: bold; + background-color: #e01716; + color: #fff;; + margin: 0; + line-height: 40px; + text-decoration: none; + min-width: 2em; + display: inline-block; + position: relative; + transition: all .1s; +} +#visible-am-button:hover, #visible-am-button:focus, #visible-am-button:active { + background: #e23635; +} +#visible-am-container.visible #visible-am-button { + box-shadow: inset 0px 1px 14px rgba(0,0,0,.5); +} +#visible-am-container div#visible-am-list { + position: absolute; + top: 35px; + right: 2%; + margin-left:2%; + height: auto; + z-index: 0; + padding: 2em; + border: 1px solid #aa; + text-align: left; + display: block; + background-color: #fff; + border-radius: 5px; + box-shadow: 0 7px 20px rgba(0,0,0,.1); + transition: all .15s cubic-bezier(.84,.03,.21,.96); + opacity: 0; + transform: scale(0); +} +#visible-am-container.visible div#visible-am-list { + opacity: 1; + transform: scale(1); + z-index: 1000; +} +#visible-am-container #visible-am-button:after { + content: ''; + display: inline-block; + position: absolute; + bottom: -5px; + left: 32%; + width: 0; + height: 0; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #fff; + opacity: 0; + transition: all .05s; +} +#visible-am-container.visible #visible-am-button:after { + opacity: 1; + bottom: 4px; + transition: all .25s; +} +#visible-am-container .am-message { + display: block; + line-height: 1.4em; + margin-bottom: 1.4em; +} \ No newline at end of file diff --git a/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.js b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.js new file mode 100644 index 0000000000000000000000000000000000000000..a11957cfea9b6c21110dca0a74d70437d7487edf --- /dev/null +++ b/core/src/main/resources/jenkins/management/AdministrativeMonitorsDecorator/resources.js @@ -0,0 +1,39 @@ +function amCloser(e) { + var list = document.getElementById('visible-am-list'); + var el = e.target; + while (el) { + if (el === list) { + return; // clicked in the list + } + el = el.parentElement; + } + hideVisibleAmList(); +}; +function amEscCloser(e) { + if (e.keyCode == 27) { + amCloser(e); + } +}; +function amContainer() { + return document.getElementById('visible-am-container'); +}; +function hideVisibleAmList(e) { + amContainer().classList.remove('visible'); + document.removeEventListener('click', amCloser); + document.removeEventListener('keydown', amEscCloser); +} +function showVisibleAmList(e) { + amContainer().classList.add('visible'); + setTimeout(function() { + document.addEventListener('click', amCloser); + document.addEventListener('keydown', amEscCloser); + }, 1); +} +function toggleVisibleAmList(e) { + if (amContainer().classList.contains('visible')) { + hideVisibleAmList(e); + } else { + showVisibleAmList(e); + } + e.preventDefault(); +} \ No newline at end of file diff --git a/core/src/main/resources/jenkins/management/Messages.properties b/core/src/main/resources/jenkins/management/Messages.properties index 67893483393818b080888b1f456e4abc1c3bfd2c..9913ab66d28ffbf30f008a5b5359ce374ac5941e 100644 --- a/core/src/main/resources/jenkins/management/Messages.properties +++ b/core/src/main/resources/jenkins/management/Messages.properties @@ -25,6 +25,9 @@ ConfigureLink.DisplayName=Configure System ConfigureLink.Description=Configure global settings and paths. +ConfigureTools.DisplayName=Global Tool Configuration +ConfigureTools.Description=Configure tools, their locations and automatic installers. + ReloadLink.DisplayName=Reload Configuration from Disk ReloadLink.Description=Discard all the loaded data in memory and reload everything from file system.\n\ Useful when you modified config files directly on disk. @@ -53,3 +56,5 @@ NodesLink.Description=Add, remove, control and monitor the various nodes that Je ShutdownLink.DisplayName_prepare=Prepare for Shutdown ShutdownLink.DisplayName_cancel=Cancel Shutdown ShutdownLink.Description=Stops executing new builds, so that the system can be eventually shut down safely. + +AdministrativeMonitorsDecorator.DisplayName=Administrative Monitors Notifier diff --git a/core/src/main/resources/jenkins/management/Messages_bg.properties b/core/src/main/resources/jenkins/management/Messages_bg.properties index f5fcc33c85c93655b5576e2f4673d1431e63ef35..b605e22c46dba4e5fb4166ae14aa5423d1ce83cc 100644 --- a/core/src/main/resources/jenkins/management/Messages_bg.properties +++ b/core/src/main/resources/jenkins/management/Messages_bg.properties @@ -1,7 +1,6 @@ -# # The MIT License # -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,16 +19,67 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# -PluginsLink.Description=\u0414\u043E\u0431\u0430\u0432\u044F\u043D\u0435, \u043F\u0440\u0435\u043C\u0430\u0445\u0432\u0430\u043D\u0435, \u0441\u043F\u0438\u0440\u0430\u043D\u0435 \u0438 \u043F\u0443\u0441\u043A\u0430\u043D\u0435 \u043D\u0430 \u043F\u043B\u044A\u0433\u0438\u043D\u0438, \u043A\u043E\u0438\u0442\u043E \u043C\u043E\u0433\u0430\u0442 \u0434\u0430 \u0440\u0430\u0437\u0448\u0438\u0440\u044F\u0442 \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u043D\u043E\u0441\u0442\u0442\u0430 \u043D\u0430 Jenkins. -ConfigureLink.DisplayName=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u0430 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430 -ConfigureLink.Description=\u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u043D\u0435 \u043D\u0430 \u0433\u043B\u0430\u0432\u043D\u0438\u0442\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0438 \u043F\u044A\u0442\u0435\u043A\u0438 -SystemInfoLink.Description=\u041F\u043E\u043A\u0430\u0437\u0432\u0430 \u0440\u0430\u0437\u043D\u043E\u043E\u0431\u0440\u0430\u0437\u043D\u0430 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u0437\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u0441 \u0446\u0435\u043B \u0434\u0430 \u0430\u0441\u0438\u0441\u0442\u0438\u0440\u0430 \u043E\u0442\u0441\u0442\u0440\u0430\u043D\u044F\u0432\u0430\u043D\u0435\u0442\u043E \u043D\u0430 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438. -StatisticsLink.DisplayName=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430 \u043D\u0430 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043D\u0435\u0442\u043E -NodesLink.DisplayName=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0438 -PluginsLink.DisplayName=\u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0430 \u043F\u043B\u044A\u0433\u0438\u043D\u0438 -ShutdownLink.DisplayName_prepare=\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043A\u0430 \u0437\u0430 \u0438\u0437\u043A\u043B\u044E\u0447\u0432\u0430\u043D\u0435 -ReloadLink.DisplayName=\u041F\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043D\u0435 \u043D\u0430 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043E\u0442 \u0434\u0438\u0441\u043A\n\ - \u041F\u043E\u043B\u0435\u0437\u043D\u043E \u0435 \u0430\u043A\u043E \u0441\u0442\u0435 \u043C\u043E\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0430\u043B\u0438 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043E\u043D\u043D\u0438\u0442\u0435 \u0444\u0430\u0439\u043B\u043E\u0432\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043D\u043E \u043D\u0430 \u0434\u0438\u0441\u043A\u0430. -SystemInfoLink.DisplayName=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u0430 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F. +ConfigureLink.DisplayName=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 +ConfigureLink.Description=\ + \u041e\u0431\u0449\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438 \u043f\u044a\u0442\u0438\u0449\u0430. + +ReloadLink.DisplayName=\ + \u041f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u043e\u0442 \u0434\u0438\u0441\u043a\u0430 +ReloadLink.Description=\ + \u0418\u0437\u0447\u0438\u0441\u0442\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 \u0432 \u043f\u0430\u043c\u0435\u0442\u0442\u0430 \u0438 \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 \u043e\u0442\ + \u0434\u0438\u0441\u043a\u0430.\n\u0422\u043e\u0432\u0430 \u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e, \u043a\u043e\u0433\u0430\u0442\u043e \u0441\u0442\u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u044f\u043b\u0438 \u0444\u0430\u0439\u043b\u043e\u0432\u0435\u0442\u0435 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u043e \u0434\u0438\u0441\u043a\u0430. + +PluginsLink.DisplayName=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438\u0442\u0435 +PluginsLink.Description=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435, \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435, \u0441\u043f\u0438\u0440\u0430\u043d\u0435 \u0438 \u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438, \u043a\u043e\u0438\u0442\u043e \u0434\u043e\u043f\u044a\u043b\u0432\u0430\u0442 \u0438\ + \u0440\u0430\u0437\u0448\u0438\u0440\u044f\u0432\u0430\u0442 \u0432\u044a\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438\u0442\u0435 \u043d\u0430 Jenkins. + +SystemInfoLink.DisplayName=\ + \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 +SystemInfoLink.Description=\ + \u0418\u0437\u0432\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430 \u0441 \u0446\u0435\u043b \u043e\u0442\u0441\u0442\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438. + +SystemLogLink.DisplayName=\ + \u0421\u0438\u0441\u0442\u0435\u043c\u0435\u043d \u0436\u0443\u0440\u043d\u0430\u043b +SystemLogLink.Description=\ + \u0412 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u0438\u044f \u0436\u0443\u0440\u043d\u0430\u043b \u0441\u0435 \u0437\u0430\u043f\u0438\u0441\u0432\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f\u0442\u0430 \u043e\u0442 java.util.logging \u0437\u0430\ + Jenkins. + +StatisticsLink.DisplayName=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0430 \u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0432\u0430\u043d\u0435\u0442\u043e +StatisticsLink.Description=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u043d\u0438\u0442\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u0438, \u0437\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043d\u0435 \u043d\u0430 \u0435\u0432\u0435\u043d\u0442\u0443\u0430\u043b\u043d\u0430\u0442\u0430 \u043d\u0443\u0436\u0434\u0430 \u043e\u0442 \u043e\u0449\u0435\ + \u043c\u0430\u0448\u0438\u043d\u0438 \u0437\u0430 Jenkins. + +CliLink.DisplayName=\ + Jenkins \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434 +CliLink.Description=\ + \u0414\u043e\u0441\u0442\u044a\u043f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 Jenkins \u043e\u0442 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0438\u044f \u0440\u0435\u0434 \u0438\u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442. + +ConsoleLink.DisplayName=\ + \u041a\u043e\u043d\u0437\u043e\u043b\u0430 +ConsoleLink.Description=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u0435\u043d \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043d\u0435, \u043e\u0442\u043a\u0440\u0438\u0432\u0430\u043d\u0435 \u0438 \u043e\u0442\u0441\u0442\u0440\u0430\u043d\u044f\u0432\u0430\u043d\u0435\ + \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438. + +NodesLink.DisplayName=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0438 +NodesLink.Description=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435, \u043f\u0440\u0435\u043c\u0430\u0445\u0432\u0430\u043d\u0435, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u0438\u0442\u0435 \u043c\u0430\u0448\u0438\u043d\u0438, \u043d\u0430 \u043a\u043e\u0438\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0438 Jenkins. + +ShutdownLink.DisplayName_prepare=\ + \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0437\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 +ShutdownLink.DisplayName_cancel=\ + \u041e\u0442\u043c\u044f\u043d\u0430 \u043d\u0430 \u0438\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435\u0442\u043e +ShutdownLink.Description=\ + \u041d\u0435\u0434\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f, \u0437\u0430 \u0434\u0430 \u043c\u043e\u0436\u0435 \u0432 \u0434\u0430\u0434\u0435\u043d \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u0430\u0448\u0438\u043d\u0430\u0442\u0430 \u0434\u0430 \u0431\u044a\u0434\u0435\ + \u0441\u043f\u0440\u044f\u043d\u0430. +# Configure tools, their locations and automatic installers. +ConfigureTools.Description=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0432\u0430\u043d\u0435 \u043d\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438\u0442\u0435, \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0442\u0430 \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0442\u043e \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430\u043d\u0435. +# Global Tool Configuration +ConfigureTools.DisplayName=\ + \u041e\u0431\u0449\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0438\u0442\u0435 diff --git a/core/src/main/resources/jenkins/management/Messages_fr.properties b/core/src/main/resources/jenkins/management/Messages_fr.properties index 45bddad13df722305d8699d5ee46a56bca314321..4449f47d3cc9fd6149a125c6146aec5a0150ca50 100644 --- a/core/src/main/resources/jenkins/management/Messages_fr.properties +++ b/core/src/main/resources/jenkins/management/Messages_fr.properties @@ -25,6 +25,9 @@ ConfigureLink.DisplayName=Configurer le syst\u00e8me ConfigureLink.Description=Configurer les param\u00e8tres g\u00e9n\u00e9raux et les chemins de fichiers. +ConfigureTools.DisplayName=Configuration globale des outils +ConfigureTools.Description=Configurer les outils, leur localisation et les installeurs automatiques. + ReloadLink.DisplayName=Recharger la configuration \u00e0 partir du disque ReloadLink.Description=Supprimer toutes les donn\u00e9es en m\u00e9moire et recharger tout \u00e0 partir du syst\u00e8me de fichiers.\n\ Utile quand vous modifiez les fichiers de configuration directement sur le disque. diff --git a/core/src/main/resources/jenkins/management/Messages_lt.properties b/core/src/main/resources/jenkins/management/Messages_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..929aa43e71f172085bbe47cfc3cd6babaaef61a4 --- /dev/null +++ b/core/src/main/resources/jenkins/management/Messages_lt.properties @@ -0,0 +1,32 @@ +# This file is under the MIT License by authors + +CliLink.Description=Prieiti/tvarkyti Jenkins\u0105 i\u0161 j\u016Bs\u0173 aplinkos arba skripto. +CliLink.DisplayName=Jenkins CLI + +ConfigureLink.Description=Konfig\u016Bruoti globalius nustatymus ir kelius. +ConfigureLink.DisplayName=Konfig\u016Bruoti sistem\u0105 + +ConsoleLink.Description=Vykdo nurodyt\u0105 skript\u0105 administravimui/problem\u0173-aptikimui/diagnostikai. +ConsoleLink.DisplayName=Skript\u0173 konsol\u0117 + +NodesLink.Description=Prid\u0117ti, i\u0161imti, valdyti ir steb\u0117ti skirtingus mazgus, kuriuose Jenkinsas vykdo darbus. +NodesLink.DisplayName=Valdyti mazgus + +PluginsLink.Description=Prid\u0117ti, i\u0161imti, i\u0161jungti ir \u012Fjungti priedus, kurie gali papildyti Jenkinso funkcionalum\u0105. +PluginsLink.DisplayName=Valdyti priedus + +ReloadLink.Description=I\u0161mesti visus \u012F atmint\u012F \u012Fkeltus duomenis ir visk\u0105 \u012Fkelti i\u0161 naujo i\u0161 fail\u0173 sistemos.\nNaudinga, kai failus pakeit\u0117te tiesiai diske. +ReloadLink.DisplayName=I\u0161 naujo \u012Fkelti konfig\u016Bracij\u0105 i\u0161 disko + +ShutdownLink.Description=Sustabdo nauj\u0173 darb\u0173 vykdym\u0105, kad b\u016Bt\u0173 galima saugiai i\u0161jungti sistem\u0105. +ShutdownLink.DisplayName_cancel=Nutraukti i\u0161jungim\u0105 +ShutdownLink.DisplayName_prepare=Pasiruo\u0161ti i\u0161jungimui + +StatisticsLink.Description=Patikrinkite j\u016Bs\u0173 resurs\u0173 naudojim\u0105 ir pa\u017Ei\u016Br\u0117kite, ar jums reikia daugiau kompiuteri\u0173 darbams. +StatisticsLink.DisplayName=Apkrovos statistika + +SystemInfoLink.Description=Rodo \u012Fvairi\u0105 aplinkos informacij\u0105, kuri padeda aptikti problemas. +SystemInfoLink.DisplayName=Sistemos informacija + +SystemLogLink.Description=Sistemos \u017Eurnale kaupiama informacija i\u0161 java.util.logging i\u0161vesties, susijusios su Jenkinsu. +SystemLogLink.DisplayName=Sistemos \u017Eurnalas diff --git a/core/src/main/resources/jenkins/management/Messages_pl.properties b/core/src/main/resources/jenkins/management/Messages_pl.properties index 174a79fbe61708fa9782c72467b3748f44e46531..bae564f04c786bfad970ece5f1698f9cf87b9231 100644 --- a/core/src/main/resources/jenkins/management/Messages_pl.properties +++ b/core/src/main/resources/jenkins/management/Messages_pl.properties @@ -1,7 +1,6 @@ -# # The MIT License # -# Copyright (c) 2012, CloudBees, Intl., Nicolas De loof +# Copyright (c) 2012-2016, CloudBees, Intl., Nicolas De loof, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,17 +19,39 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# -PluginsLink.Description=Dodaj, usu\u0144, wy\u0142\u0105cz lub w\u0142\u0105cz wtyczki kt\u00F3re mog\u0105 rozszerzy\u0107 funkcjonalno\u015B\u0107 Jenkinsa. ConfigureLink.DisplayName=Skonfiguruj system ConfigureLink.Description=Konfiguruj ustawienia globalne i \u015Bcie\u017Cki. + +ReloadLink.DisplayName=Odczytaj ponownie konfiguracj\u0119 z dysku ReloadLink.Description=Porzu\u0107 wszystkie dane za\u0142adowane w pami\u0119ci i za\u0142aduj wszystko z systemu plik\u00F3w.\n\ Opcja u\u017Cyteczna gdy zmodyfikowano pliki konfiguracyjne bezpo\u015Brednio z dysku. -StatisticsLink.DisplayName=Statystyki Obci\u0105\u017Cenia -PluginsLink.DisplayName=Zarz\u0105dzaj dodatkami + +PluginsLink.DisplayName=Zarz\u0105dzaj wtyczkami +PluginsLink.Description=Dodaj, usu\u0144, wy\u0142\u0105cz lub w\u0142\u0105cz wtyczki kt\u00F3re mog\u0105 rozszerzy\u0107 funkcjonalno\u015B\u0107 Jenkinsa. + +SystemInfoLink.DisplayName=Informacje o systemie +SystemInfoLink.Description=Wy\u015Bwietla wiele \u015Brodowiskowych informacji pomocnych przy rozwi\u0105zywaniu problem\u00F3w. + +StatisticsLink.DisplayName=Statystyki obci\u0105\u017Cenia +StatisticsLink.Description=Sprawd\u017A obci\u0105\u017Cenie zasob\u00F3w systemowych i dowiedz si\u0119, czy nie potrzebujesz wi\u0119cej maszyn do uruchamiania zada\u0144. + +SystemLogLink.DisplayName=Dziennik systemowy +SystemLogLink.Description=Dziennik systemowy gromadzi wywoy\u0142ania java.util.logging powi\u0105zane z Jenkinsem. + +CliLink.DisplayName=Wiersz polece\u0144 Jenkinsa +CliLink.Description=Zarz\u0105dzaj Jenkinsem poziomu z wiersza polece\u0144 lub systemu. + +ConsoleLink.DisplayName=Konsola skrypt\u00F3w +ConsoleLink.Description=Wykonuje dowolny skrypt pomocny do cel\u00F3w administracyjnych, usuwania usterek i diagnostyki. + +NodesLink.DisplayName=Zarz\u0105dzaj w\u0119z\u0142ami +NodesLink.Description=Dodawaj, usuwaj, kontroluj i monitoruj r\u00F3\u017Cne w\u0119z\u0142y, na kt\u00F3rych Jenkins uruchamia zadania. + ShutdownLink.DisplayName_prepare=Przygotuj do wy\u0142\u0105czenia -ReloadLink.DisplayName=Odczytaj ponownie konfiguracj\u0119 z dysku -ShutdownLink.Description=Zatrzyma wykonanie nowych build\u00F3w, tak by system m\u00F3g\u0142by\u0107 bezpiecznie wy\u0142\u0105czony. ShutdownLink.DisplayName_cancel=Anuluj wy\u0142\u0105czenie -SystemInfoLink.DisplayName=Informacje o systemie +ShutdownLink.Description=Zatrzyma wykonanie nowych build\u00F3w, tak by system m\u00F3g\u0142by\u0107 bezpiecznie wy\u0142\u0105czony. +# Global Tool Configuration +ConfigureTools.DisplayName=Globalne narz\u0119dzia do konfiguracji +# Configure tools, their locations and automatic installers. +ConfigureTools.Description=Konfiguruj narz\u0119dzia, \u015Bcie\u017Cki do nich i automatyczne instalatory diff --git a/core/src/main/resources/jenkins/management/Messages_sr.properties b/core/src/main/resources/jenkins/management/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..276429a4ad27305c3a32f57347b9c36813092206 --- /dev/null +++ b/core/src/main/resources/jenkins/management/Messages_sr.properties @@ -0,0 +1,26 @@ +# This file is under the MIT License by authors + +ConfigureLink.DisplayName=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +ConfigureLink.Description=\u041E\u0431\u0448\u0442\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0438 \u043F\u0443\u0442\u0435\u0432\u0438. +ConfigureTools.DisplayName=\u041E\u0431\u0448\u0442\u0435 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u0430\u043B\u0430\u0442\u0430 +ConfigureTools.Description=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 \u0430\u043B\u0430\u0442\u0435, \u043B\u043E\u043A\u0430\u0446\u0438\u0458\u0435, \u0438 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0443 \u0438\u043D\u0441\u0442\u0430\u043B\u0430\u0446\u0438\u0458\u0443 +ReloadLink.DisplayName=\u041F\u043E\u043D\u043E\u0432\u043E \u0443\u0447\u0438\u0442\u0430\u0458 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0430 \u0434\u0438\u0441\u043A\u0430 +ReloadLink.Description=\u0418\u0437\u0431\u0440\u0438\u0448\u0438 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0430 \u043C\u0435\u043C\u043E\u0440\u0438\u0458\u0435 \u0438 \u0443\u0447\u0438\u0442\u0430\u0458 \u0441\u0430 \u0434\u0438\u0441\u043A\u0430.\n \u041A\u043E\u0440\u0438\u0441\u043D\u043E \u043A\u0430\u0434\u0430 \u0441\u0442\u0435 \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u043B\u0438 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043D\u043E \u043D\u0430 \u0434\u0438\u0441\u043A\u0443. +PluginsLink.Description=\u0414\u043E\u0434\u0430\u0458\u0442\u0435, \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435, \u0438\u043B\u0438 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438\u0442\u0435 \u043C\u043E\u0434\u0443\u043B\u0435 \u043A\u043E\u0458\u0435 \u043F\u0440\u043E\u0448\u0438\u0440\u0443\u0458\u0443 \u043C\u043E\u0433\u0443\u045B\u043D\u043E\u0441\u0442\u0435 Jenkins-\u0430. +PluginsLink.DisplayName=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u043C\u043E\u0434\u0443\u043B\u0430 +SystemInfoLink.DisplayName=\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0435 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 +SystemInfoLink.Description=\u041F\u0440\u0438\u043A\u0430\u0437\u0443\u0458\u0435 \u0440\u0430\u0437\u043D\u0443 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0458\u0443 \u043E \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0434\u0430 \u0431\u0443 \u043F\u043E\u043C\u0430\u0433\u0430\u043B\u043E \u0441\u0430 \u0440\u0435\u0448\u0430\u0432\u0430\u045A\u0435\u043C \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438\u043C\u0430. +SystemLogLink.DisplayName=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 +SystemLogLink.Description=\u0416\u0443\u0440\u043D\u0430\u043B \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u0437\u0430\u043F\u0438\u0441\u0443\u0458\u0435 \u0438\u0441\u0445\u043E\u0434 java.util.logging \u043A\u043E\u0458\u0438 \u0441\u0435 \u043E\u0434\u043D\u043E\u0441\u0438 \u043D\u0430 Jenkins. +StatisticsLink.DisplayName=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435 \u043E \u043E\u043F\u0442\u0435\u0440\u0435\u045B\u0435\u045A\u0443 +StatisticsLink.Description=\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u043E\u043F\u0442\u0435\u0440\u0435\u045B\u0435\u045A\u0435 \u043D\u0430\u0434 \u0440\u0435\u0441\u0443\u0440\u0441\u0438\u043C\u0430 \u0434\u0430 \u0431\u0438 \u0441\u0442\u0435 \u043E\u0434\u0440\u0435\u0434\u0438\u043B\u0438 \u0430\u043A\u043E \u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0432\u0438\u0448\u0435 \u043C\u0430\u0448\u0438\u043D\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443. +CliLink.Description=\u0414\u043E\u0441\u0442\u0443\u043F\u0438\u0442\u0435 \u0438 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u0458\u0442\u0435 Jenkins-\u043E\u043C \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 \u0438\u043B\u0438 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u043C. +CliLink.DisplayName=Jenkins \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 +ConsoleLink.DisplayName=\u041A\u043E\u043D\u0437\u043E\u043B\u0430 +ConsoleLink.Description=\u0418\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0432\u0435 \u0437\u0430 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0458\u0443 \u0438 \u043E\u0442\u043A\u0440\u0438\u0432\u0430\u045A\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430. +NodesLink.DisplayName=\u0423\u043F\u0440\u0430\u0432\u0438 \u043C\u0430\u0448\u0438\u043D\u0430\u043C\u0430 +NodesLink.Description=\u0414\u043E\u0434\u0430\u0458\u0442\u0435, \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435, \u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 \u043D\u0430 \u043A\u0438\u043C \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u0458\u0443 \u0437\u0430\u0434\u0430\u0446\u0438. +ShutdownLink.DisplayName_prepare=\u041F\u0440\u0438\u043F\u0440\u0435\u043C\u0438 \u0437\u0430 \u0433\u0430\u0448\u0435\u045A\u0435 +ShutdownLink.Description=\u0417\u0430\u0443\u0441\u0442\u0430\u0432\u0438 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u043D\u043E\u0432\u0438\u0445 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430, \u0434\u0430 \u0431\u0438 \u0441\u0438\u0441\u0442\u0435\u043C \u043C\u043E\u0433\u0430\u043E \u0431\u0438\u0442\u0438 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E \u0438\u0441\u043A\u0459\u0443\u0447\u0435\u043D. +ShutdownLink.DisplayName_cancel=\u041E\u0442\u043A\u0430\u0436\u0438 \u0433\u0430\u0448\u0435\u045A\u0435 +Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C \ No newline at end of file diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties index 29bc40f579b7cf0ca0f8659407021331db317bf8..57020cf14bc8e37a2c963fbbbd3af777dfc648d2 100644 --- a/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties +++ b/core/src/main/resources/jenkins/management/PluginsLink/info_pl.properties @@ -22,4 +22,4 @@ # THE SOFTWARE. # -updates\ available=uaktualnienia s\u0105 dost\u0119pne +updates\ available=aktualizacje s\u0105 dost\u0119pne diff --git a/core/src/main/resources/jenkins/management/PluginsLink/info_sr.properties b/core/src/main/resources/jenkins/management/PluginsLink/info_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0182d883887045a76fb84fe9f883ed0b7639fdf4 --- /dev/null +++ b/core/src/main/resources/jenkins/management/PluginsLink/info_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +updates\ available=\u0418\u043C\u0430 \u043D\u043E\u0432\u0438\u0445 \u043D\u0430\u0434\u0433\u0440\u0430\u0434\u045A\u0430 diff --git a/test/src/main/resources/org/jvnet/hudson/test/CaptureEnvironmentBuilder/config.jelly b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details.jelly similarity index 84% rename from test/src/main/resources/org/jvnet/hudson/test/CaptureEnvironmentBuilder/config.jelly rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details.jelly index 9d137d24a0b893d9610c894370a04e80f25eaed2..a5f3d0a4d713c9d65e3a25e3fd2908cd2d4f8cdd 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/CaptureEnvironmentBuilder/config.jelly +++ b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details.jelly @@ -1,7 +1,8 @@ + - \ No newline at end of file + + + diff --git a/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_sr.properties b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a0f4b42884f54a098f6f5107abc201bfeaba1d55 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/config-details_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Strategy=\u0420\u0435\u0436\u0438\u043C diff --git a/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help.html new file mode 100644 index 0000000000000000000000000000000000000000..15ee4f5f338d5a1ba81afdcf7fa74d87d78d8a12 --- /dev/null +++ b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help.html @@ -0,0 +1,51 @@ +
    + This determines when, if ever, build records for this project should be + discarded. Build records include the console output, archived artifacts, and + any other metadata related to a particular build. +

    + Keeping fewer builds means less disk space will be used in the Build Record + Root Directory, which is specified on the Configure System screen. +

    + + Jenkins offers two options for determining when builds should be discarded: +

      +
    1. + Build age: discard builds if they reach a certain age; for example, seven + days old. +
    2. + Build count: discard the oldest build if a certain number of builds + already exist. +
    + These two options can be active at the same time, so you can keep builds for + 14 days, but only up to a limit of 50 builds, for example. If either limit is + exceeded, then any builds beyond that limit will be discarded. +

    + You can also ensure that important builds are kept forever, regardless of the + setting here — click the Keep this build forever button on the + build page. +
    + The last stable and last successful build are also excluded from these rules. + +


    + + In the Advanced section, the same options can be specified, but + specifically for build artifacts. If enabled, build artifacts will be + discarded for any builds which exceed the defined limits. The builds + themselves will still be kept; only the associated artifacts, if any, will be + deleted. +

    + For example, if a project builds some software and produces a large installer, + which is archived, you may wish to always keep the console log and information + about which source control commit was built, while for disk space reasons, you + may want to keep only the last three installers that were built. +
    + This can make sense for projects where you can easily recreate the same + artifacts later by building the same source control commit again. + +


    + + Note that Jenkins does not discard items immediately when this configuration + is updated, or as soon as any of the configured values are exceeded; these + rules are evaluated each time that a build of this project completes. +
    diff --git a/war/src/main/webapp/help/project-config/log-rotation_de.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_de.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_de.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_de.html diff --git a/war/src/main/webapp/help/project-config/log-rotation_fr.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_fr.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_fr.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_fr.html diff --git a/war/src/main/webapp/help/project-config/log-rotation_ja.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_ja.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_ja.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_ja.html diff --git a/war/src/main/webapp/help/project-config/log-rotation_pt_BR.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_pt_BR.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_pt_BR.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_pt_BR.html diff --git a/war/src/main/webapp/help/project-config/log-rotation_ru.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_ru.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_ru.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_ru.html diff --git a/war/src/main/webapp/help/project-config/log-rotation_tr.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_tr.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_tr.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_tr.html diff --git a/war/src/main/webapp/help/project-config/log-rotation_zh_TW.html b/core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_zh_TW.html similarity index 100% rename from war/src/main/webapp/help/project-config/log-rotation_zh_TW.html rename to core/src/main/resources/jenkins/model/BuildDiscarderProperty/help_zh_TW.html diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/ExceptionInterruption/summary.groovy b/core/src/main/resources/jenkins/model/CauseOfInterruption/ExceptionInterruption/summary.groovy deleted file mode 100644 index bcc6ce149289494d09a7661e5a41c209f7904cf7..0000000000000000000000000000000000000000 --- a/core/src/main/resources/jenkins/model/CauseOfInterruption/ExceptionInterruption/summary.groovy +++ /dev/null @@ -1,5 +0,0 @@ -package jenkins.model.CauseOfInterruption.ExceptionInterruption - -import hudson.util.FormValidation; - -raw(FormValidation.error(my.cause, my.cause.message).renderHtml()); diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.groovy b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.groovy index ec48cb9efaf362b6b4e0defe98c1f9c8e889172d..b75b2386f95bfcb7aaf612ec9f2a95f333255b65 100644 --- a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.groovy +++ b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.groovy @@ -1,4 +1,9 @@ package jenkins.model.CauseOfInterruption.UserInterruption; // by default we just print the short description. -raw(_("blurb",my.user.fullName, rootURL+'/'+my.user.url)) \ No newline at end of file +def user = my.userOrNull +if (user != null) { + raw(_("blurb", user.fullName, rootURL+'/'+user.url)) +} else { + raw(_("userNotFound", my.userId)) +} diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.properties b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.properties index 1f1f63c2bced9e8dcbda322ad0c3d6127ab5f4c4..1ada7d261b140d9a47bbaa4da7cdffd44a4b9b8e 100644 --- a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.properties +++ b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary.properties @@ -1 +1,2 @@ -blurb=Aborted by user {0} \ No newline at end of file +blurb=Aborted by user {0} +userNotFound=Aborted by user {0} diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_ja.properties b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_ja.properties index e2d2051a6e1b5c013e972a401894689fff2e3a17..3cd254db98c9992dd0aa682f0c28c4106dd2b9da 100644 --- a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_ja.properties +++ b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_ja.properties @@ -1 +1,2 @@ -blurb=\u30e6\u30fc\u30b6\u30fc {0} \u306b\u3088\u308a\u4e2d\u65ad \ No newline at end of file +blurb=\u30e6\u30fc\u30b6\u30fc {0} \u306b\u3088\u308a\u4e2d\u65ad +userNotFound=\u30e6\u30fc\u30b6\u30fc {0} \u306b\u3088\u308a\u4e2d\u65ad diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_pl.properties b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_pl.properties index 0095ece665717b8c3e01065e4517b9530baa7cbc..d2c91f76b00ac81566300ef4844379c61cf9dadd 100644 --- a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_pl.properties +++ b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_pl.properties @@ -1 +1,2 @@ -blurb=Przerwane przez u\u017Cytkownika {0} \ No newline at end of file +blurb=Przerwane przez u\u017cytkownika {0} +userNotFound=Przerwane przez u\u017cytkownika {0} diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_sr.properties b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a88ce0631cae526ce3dc5bf038f65a498bd59a6a --- /dev/null +++ b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +blurb=\u041e\u0442\u043a\u0430\u0437\u0430\u043d\u043e \u043a\u043e\u0440\u0438\u0441\u043d\u0438\u043a\u043e\u043c {0} +userNotFound=\u041e\u0442\u043a\u0430\u0437\u0430\u043d\u043e \u043a\u043e\u0440\u0438\u0441\u043d\u0438\u043a\u043e\u043c {0} diff --git a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_zh_TW.properties b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_zh_TW.properties index db917957563b21c1f8043f882355428694831555..3b2ac62c063258e245c2815a36ef9baac269d8b5 100644 --- a/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/CauseOfInterruption/UserInterruption/summary_zh_TW.properties @@ -22,3 +22,4 @@ # THE SOFTWARE. blurb=\u7531\u4f7f\u7528\u8005 {0} \u4e2d\u6b62 +userNotFound=\u7531\u4f7f\u7528\u8005 {0} \u4e2d\u6b62 diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.groovy b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.groovy index bfcc1c0335b723dcba95c3263667f536396c11f3..31cdf2c1ff7b5a8450db3a1602e34e7a1b67c1e0 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.groovy +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.groovy @@ -3,7 +3,7 @@ package jenkins.model.CoreEnvironmentContributor; def l = namespace(lib.JenkinsTagLib) // also advertises those contributed by Run.getCharacteristicEnvVars() -["BUILD_NUMBER","BUILD_ID","BUILD_DISPLAY_NAME","JOB_NAME","BUILD_TAG","EXECUTOR_NUMBER","NODE_NAME","NODE_LABELS","WORKSPACE","JENKINS_HOME","JENKINS_URL","BUILD_URL","JOB_URL"].each { name -> +["BUILD_NUMBER","BUILD_ID","BUILD_DISPLAY_NAME","JOB_NAME", "JOB_BASE_NAME","BUILD_TAG","EXECUTOR_NUMBER","NODE_NAME","NODE_LABELS","WORKSPACE","JENKINS_HOME","JENKINS_URL","BUILD_URL","JOB_URL"].each { name -> l.buildEnvVar(name:name) { raw(_("${name}.blurb")) } diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties index c8040aad7af6a0dc443c596ad471b9b704c29623..72c8c0ae3bb9819afa9131fa933233a604083ec6 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv.properties @@ -1,14 +1,15 @@ BUILD_NUMBER.blurb=The current build number, such as "153" BUILD_ID.blurb=The current build ID, identical to BUILD_NUMBER for builds created in 1.597+, but a YYYY-MM-DD_hh-mm-ss timestamp for older builds BUILD_DISPLAY_NAME.blurb=The display name of the current build, which is something like "#153" by default. -JOB_NAME.blurb=Name of the project of this build, such as "foo" or "foo/bar". (To strip off folder paths from a Bourne shell script, try: $'{'JOB_NAME##*/}) -BUILD_TAG.blurb=String of "jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}". Convenient to put into a resource file, a jar file, etc for easier identification. +JOB_NAME.blurb=Name of the project of this build, such as "foo" or "foo/bar". +JOB_BASE_NAME.blurb=Short Name of the project of this build stripping off folder paths, such as "foo" for "bar/foo". +BUILD_TAG.blurb=String of "jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}". All forward slashes ('/') in the JOB_NAME are replaced with dashes ('-'). Convenient to put into a resource file, a jar file, etc for easier identification. EXECUTOR_NUMBER.blurb=\ The unique number that identifies the current executor \ (among executors of the same machine) that\u2019s \ carrying out this build. This is the number you see in \ the "build executor status", except that the number starts from 0, not 1. -NODE_NAME.blurb=Name of the slave if the build is on a slave, or "master" if run on master +NODE_NAME.blurb=Name of the agent if the build is on an agent, or "master" if run on master NODE_LABELS.blurb=Whitespace-separated list of labels that the node is assigned. WORKSPACE.blurb=The absolute path of the directory assigned to the build as a workspace. JENKINS_HOME.blurb=The absolute path of the directory assigned on the master node for Jenkins to store data. diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties index bbd98cb35aa269abc84b937b4a4646c9637a14fa..fa8b2cc15b0ece380f955beedb8bca4f40833778 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_de.properties @@ -8,9 +8,8 @@ BUILD_TAG.blurb=Eine Zeichenkette in der Form "jenkins-$'{'JOB_NAME}-$ EXECUTOR_NUMBER.blurb=Die laufende Nummer des Build-Prozessors, der den aktuellen Build ausf\u00FChrt \ (aus den Build-Prozessoren desselben Rechners). \ Dies ist die Nummer, die Sie auch im Build-Prozessor Status sehen - \ - mit der Ausnahme, da\u00DF bei der Umgebungsvariable die Z\u00E4hlung bei 0 und nicht \ + mit der Ausnahme, dass bei der Umgebungsvariable die Z\u00E4hlung bei 0 und nicht \ bei 1 beginnt. -NODE_NAME.blurb=Name des Build-Slaves, wenn auf einem Build-Slave gebaut wird, oder "master" wenn auf dem Master-Server gebaut wird. NODE_LABELS.blurb=Durch Leerzeichen getrennte Liste von Labels, die dem Knoten zugeordnet sind. WORKSPACE.blurb=Der absolute Pfad zum Arbeitsbereich. JENKINS_HOME.blurb=Der absolute Pfad des Verzeichnisses, in dem der Master-Server seine Daten speichert. diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties index 7026f87f9db9dc503de23ab0d76004a9b9a6b489..a0d15385dd9d17fd8d457a024ba4f59b8b7cf230 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_fr.properties @@ -7,7 +7,6 @@ EXECUTOR_NUMBER.blurb=Le num\u00E9ro unique qui identifie l'ex\u00E9cuteur coura (parmi les ex\u00E9cuteurs d'une m\u00EAme machine) qui a contruit ce build. \ Il s'agit du num\u00E9ro que vous voyez dans le "statut de l'ex\u00E9cuteur du build", \ sauf que la num\u00E9rotation commence \u00E0 0 et non \u00E0 1. -NODE_NAME.blurb= NODE_LABELS.blurb= WORKSPACE.blurb=Le chemin absolu vers le r\u00E9pertoire de travail. JENKINS_HOME.blurb= diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties index d66e0424dfe9d2dcc9d3fe6cb76dcea70c3a5181..49d12ea4058f5ad5959d0598b715706414b6a027 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_ja.properties @@ -5,7 +5,6 @@ BUILD_TAG.blurb=\u6587\u5B57\u5217 "jenkins-$'{'JOB_NAME}-$'{'BUILD_NU \u7C21\u6613\u306A\u8B58\u5225\u5B50\u3068\u3057\u3066\u3001\u30EA\u30BD\u30FC\u30B9\u30D5\u30A1\u30A4\u30EB\u3084jar\u30D5\u30A1\u30A4\u30EB\u306A\u3069\u306B\u4ED8\u4E0E\u3059\u308B\u306E\u306B\u4FBF\u5229\u3067\u3059\u3002 EXECUTOR_NUMBER.blurb=\u3053\u306E\u30D3\u30EB\u30C9\u3092\u5B9F\u884C\u3057\u3066\u3044\u308B\u73FE\u5728\u306E\u30A8\u30B0\u30BC\u30AD\u30E5\u30FC\u30BF\u30FC\u3092\u8B58\u5225\u3059\u308B(\u540C\u4E00\u30DE\u30B7\u30F3\u306E\u4E2D\u3067)\u30E6\u30CB\u30FC\u30AF\u306A\u756A\u53F7\u3002\ "\u30D3\u30EB\u30C9\u5B9F\u884C\u72B6\u614B"\u306B\u8868\u793A\u3055\u308C\u3066\u3044\u308B\u6570\u5B57\u3067\u3059\u304C\u30011\u3067\u306F\u306A\u304F0\u304B\u3089\u59CB\u307E\u308B\u6570\u5B57\u3067\u3059\u3002 -NODE_NAME.blurb=\u30D3\u30EB\u30C9\u304C\u5B9F\u884C\u3055\u308C\u308B\u30B9\u30EC\u30FC\u30D6\u306E\u540D\u79F0\u3002\u30DE\u30B9\u30BF\u30FC\u3067\u5B9F\u884C\u3055\u308C\u308B\u5834\u5408\u306F"master"\u3002 NODE_LABELS.blurb=\u30CE\u30FC\u30C9\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30E9\u30D9\u30EB\u306E\u30EA\u30B9\u30C8\uFF08\u30B9\u30DA\u30FC\u30B9\u533A\u5207\u308A)\u3002 WORKSPACE.blurb=\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u7D76\u5BFE\u30D1\u30B9\u3002 JENKINS_HOME.blurb= diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties index cd999280d16febafa49abe3542269ad6d2cc6410..b127be505e0ca6e302de6375a88d773551f97f49 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_nl.properties @@ -7,7 +7,6 @@ EXECUTOR_NUMBER.blurb=Het unieke nummer, waarmee uw huidige uitvoerder ge\u00EFd Dit is het nummer dat u terugvindt in de "Status uitvoerders"-tabel op de hoofdpagina. \ Merk wel dat in die tabel geteld wordt vanaf 1. Uitvoerder 1 in de "Status uitvoerders"-tabel \ komt dus overeen met een "EXECUTOR_NUMBER" gelijk aan 0. -NODE_NAME.blurb= NODE_LABELS.blurb= WORKSPACE.blurb=Het absolute pad naar de werkplaats. JENKINS_HOME.blurb= diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8772ef9dd5816fa629121bf83e8823d6fb440c94 --- /dev/null +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_sr.properties @@ -0,0 +1,16 @@ +# This file is under the MIT License by authors + +BUILD_NUMBER.blurb=\u0422\u0440\u0435\u043D\u0443\u0442\u043D\u0438 \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435, \u043A\u0430\u043E \u043D\u043F\u0440. "153" +BUILD_ID.blurb=ID \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435, \u0438\u0434\u0435\u043D\u0442\u0438\u0447\u0430\u043D BUILD_NUMBER \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u043F\u043E\u0441\u043B\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0435 1.597, \u0430 \u0448\u0430\u0431\u043B\u043E\u043D\u0443 YYYY-MM-DD_hh-mm-ss \u0437\u0430 \u0441\u0442\u0430\u0440\u0438\u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. +BUILD_DISPLAY_NAME.blurb=\u0418\u043C\u0435 \u0442\u0440\u0435\u043D\u0443\u0442\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435, \u0448\u0442\u043E \u0438\u043D\u0430\u0447\u0435 \u043B\u0438\u0447\u0438 \u043D\u0430 "#153". +JOB_NAME.blurb=\u0418\u043C\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0430 \u0437\u0430 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443, \u043D\u043F\u0440. "foo" \u0438\u043B\u0438 "foo/bar". +JOB_BASE_NAME.blurb=\u041A\u0440\u0430\u0442\u043A\u043E \u0438\u043C\u0435 \u043E\u0434 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0437\u0430 \u043E\u0432\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 (\u043D\u0435 \u043F\u0443\u043D\u043E \u043F\u0443\u0442\u0430\u045A\u0435), \u043D\u043F\u0440. "foo" for "bar/foo". +BUILD_TAG.blurb=\u041D\u0438\u0437 "jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}". \u0421\u0432\u0435 \u043A\u043E\u0441\u0435 \u0446\u0440\u0442\u0435 ('/') \u0443 JOB_NAME \u0441\u0443 \u0437\u0430\u043C\u0435\u045A\u0435\u043D\u0438 \u0446\u0440\u0442\u0438\u0446\u0430\u043C\u0430 ('-'). \u041F\u043E\u0433\u043E\u0434\u043D\u043E \u0458\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0438 \u0443 resource, jar, \u0438\u0442\u0434. \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0437\u0430. +EXECUTOR_NUMBER.blurb=\u0408\u0435\u0434\u0438\u043D\u0441\u0442\u0432\u0435\u043D\u0438 \u0431\u0440\u043E\u0458 \u043A\u043E\u0458\u0438 \u0438\u043D\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0443\u0458\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 (\u043E\u0434 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u043D\u0430 \u0438\u0441\u0442\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438) \u043E\u0432\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435. \u0411\u0440\u043E\u0458\u0430 \u0441\u043B\u0438\u0447\u0430\u043D \u043E\u0432\u043E\u043C\u0435, \u043A\u043E\u0458\u0438 \u043F\u043E\u0447\u0438\u045A\u0435 \u0441\u0430 0 \u0430 \u043D\u0435 1, \u0458\u0435 \u043F\u0440\u0438\u043A\u0430\u0437\u0430\u043D \u043F\u0440\u0438 "\u0441\u0442\u0430\u045A\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435". +NODE_NAME.blurb=\u0418\u043C\u0435 \u0430\u0433\u0435\u043D\u0442\u0430 \u0430\u043A\u043E \u0441\u0435 \u0438\u0437\u0432\u0440\u0448\u0430\u0432\u0430 \u043D\u0430 \u0442\u0430\u043A\u0432\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438, \u0438\u043B\u0438 "master" \u0430\u043A\u043E \u043D\u0430 \u0442\u0430\u043A\u0432\u043E\u0458. +NODE_LABELS.blurb= +WORKSPACE.blurb=\u0420\u0430\u0437\u043C\u0430\u043A-\u043E\u0434\u0432\u043E\u0458\u0435\u043D\u0438 \u0441\u043F\u0438\u0441\u0430\u043A \u043B\u0430\u0431\u0435\u043B\u0430 \u0434\u043E\u0434\u0435\u0459\u0435\u043D\u043E \u043C\u0430\u0448\u0438\u043D\u0438. +JENKINS_HOME.blurb=\u041F\u0443\u043D\u043E \u043F\u0443\u0442\u0430\u045A\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0443 \u0434\u043E\u0434\u0435\u0459\u0435\u043D\u043E \u0433\u043B\u0430\u0432\u043D\u043E\u0458 \u043C\u0430\u0448\u0438\u043D\u0438, \u0433\u0434\u0435 \u045B\u0435 Jenkins \u0447\u0443\u0432\u0430\u0442\u0438 \u0441\u0432\u043E\u0458\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435. +JENKINS_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 Jenkins URL-\u0430\u0434\u0440\u0435\u0441\u0430, \u043A\u0430\u043E http://server:port/jenkins/ (\u0441\u0430\u043C\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E \u0430\u043A\u043E \u0458\u0435 Jenkins URL \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E \u0443 \u0441\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430) +BUILD_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435, \u043D\u043F\u0440. http://server:port/jenkins/job/foo/15/ (Jenkins URL \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E) +JOB_URL.blurb=\u041A\u043E\u043C\u043F\u043B\u0435\u0442\u043D\u0430 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0437\u0430\u0434\u0430\u0442\u043A\u0430, \u043D\u043F\u0440. http://server:port/jenkins/job/foo/ (Jenkins URL \u043C\u043E\u0440\u0430 \u0431\u0438\u0442\u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0459\u0435\u043D\u043E) \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_tr.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_tr.properties index b0a753fdc1456047cfd0fecab053ecdf76736b4c..b3438af07babe413d30d85c79f85fa8c93e19549 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_tr.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_tr.properties @@ -3,7 +3,6 @@ BUILD_ID.blurb= JOB_NAME.blurb= BUILD_TAG.blurb= EXECUTOR_NUMBER.blurb= -NODE_NAME.blurb= NODE_LABELS.blurb= WORKSPACE.blurb= JENKINS_HOME.blurb= diff --git a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties index 3c9e7ba68a4fcd33ba3a94f12a15ccb1df85418d..346c969498fead1f5d139d4aaf62b3fd619f4cb7 100644 --- a/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties +++ b/core/src/main/resources/jenkins/model/CoreEnvironmentContributor/buildEnv_zh_TW.properties @@ -28,7 +28,6 @@ BUILD_TAG.blurb="jenkins-$'{'JOB_NAME}-$'{'BUILD_NUMBER}" \u5b57\u EXECUTOR_NUMBER.blurb=\ \u57f7\u884c\u672c\u6b21\u5efa\u7f6e\u7684\u57f7\u884c\u7a0b\u5f0f\u7de8\u865f\uff0c\u53ef\u7528\u4f86\u9451\u5225\u540c\u6a5f\u5668\u4e0a\u7684\u4e0d\u540c\u57f7\u884c\u7a0b\u5f0f\u3002\ \u4e5f\u5c31\u662f\u60a8\u5728\u300c\u5efa\u7f6e\u57f7\u884c\u7a0b\u5f0f\u72c0\u614b\u300d\u88e1\u770b\u5230\u7684\u865f\u78bc\uff0c\u53ea\u662f\u9019\u88e1\u5f9e 0 \u958b\u59cb\u7b97\uff0c\u4e0d\u662f 1\u3002 -NODE_NAME.blurb=\u5982\u679c\u5efa\u7f6e\u662f\u5728 Slave \u7bc0\u9ede\u4e0a\u57f7\u884c\uff0c\u5c31\u662f\u7bc0\u9ede\u7684\u540d\u7a31; \u5982\u679c\u5728 Master \u4e0a\u8dd1\u5c31\u986f\u793a "master" NODE_LABELS.blurb=\u4ee5\u7a7a\u767d\u5206\u9694\u7684\u7bc0\u9ede\u6a19\u7c64\u6e05\u55ae\u3002 WORKSPACE.blurb=\u5efa\u7f6e\u5de5\u4f5c\u5340\u76ee\u9304\u7684\u7d55\u5c0d\u8def\u5f91\u3002 JENKINS_HOME.blurb=Master \u7bc0\u9ede\u8cc7\u6599\u5b58\u653e\u76ee\u9304\u7684\u7d55\u5c0d\u8def\u5f91\u3002 diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_de.properties b/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..e0bb5e6898783ea7c16a67760212f4d739efccc5 --- /dev/null +++ b/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_de.properties @@ -0,0 +1,27 @@ +# The MIT License +# +# Copyright 2015 Jesse Glick, Harald Albers. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +blurb=\ + Sie verwenden momentan Ihren Browser zum Download von Metadaten ber Plugins und Tools. \ + Dieses Verfahren gilt als unzuverlssig und unsicher. \ + Sie sollten erwgen, zu Server-basierten Downloads zu wechseln. +Dismiss=Ignorieren \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_lt.properties b/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..c6c204e38e4588200af58c22e7818109e5453d0c --- /dev/null +++ b/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_lt.properties @@ -0,0 +1,5 @@ +blurb=\ + J\u016bs dabar naudojate nar\u0161ykl\u0117s atsiuntim\u0105, kad gautum\u0117te metaduomenis Jenkinso priedams ir \u012frankiams. \ + Tai turi patikimumo problem\u0173 ir n\u0117ra visi\u0161kai saugu. \ + Apsvarstykite persijungim\u0105 \u012f serverio-pus\u0117s atsiuntim\u0105. +Dismiss=Praleisti diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_sr.properties b/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e8fb16b532d010fb9f5563435cdb223dca5b2327 --- /dev/null +++ b/core/src/main/resources/jenkins/model/DownloadSettings/Warning/message_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +blurb=\ + \u0422\u0440\u0435\u043D\u0443\u0442\u043D\u043E \u0432\u0435\u0431-\u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447\u0435\u043C \u043F\u0440\u0435\u0443\u0437\u0438\u0430\u0442\u0435 \u043C\u0435\u0442\u0430\u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u043E Jenkins \u043C\u043E\u0434\u0443\u043B\u0438\u043C\u0430 \u0438 \u0430\u043B\u0430\u0442\u0438\u043C\u0430. \ + \u0418\u043C\u0430 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430\u0442\u0430 \u0441\u0430 \u043E\u0432\u0438\u043C \u043C\u0435\u0442\u043E\u0434\u043E\u043C, \u0438 \u043D\u0435 \u0441\u043C\u0430\u0442\u0440\u0430 \u0441\u0435 \u043F\u043E\u0442\u043F\u0443\u043D\u043E \u0441\u0438\u0433\u0443\u0440\u043D\u0438\u043C. \ + \u0420\u0430\u0437\u043C\u043E\u0442\u0440\u0438\u0442\u0435 \u043F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u045A\u0435 \u0441\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u043C. +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/config.groovy b/core/src/main/resources/jenkins/model/DownloadSettings/config.groovy index 6b0751e5634286586463211f2dd690d829b11321..f7662819453eb8ae0c33790c0e7c02d876e9fd1b 100644 --- a/core/src/main/resources/jenkins/model/DownloadSettings/config.groovy +++ b/core/src/main/resources/jenkins/model/DownloadSettings/config.groovy @@ -2,7 +2,8 @@ package jenkins.security.DownloadSettings def f = namespace(lib.FormTagLib) -// TODO avoid indentation somehow -f.entry(field: "useBrowser") { - f.checkbox(title: _("Use browser for metadata download")) +f.section(title:_("Plugin Manager")) { + f.entry(field: "useBrowser") { + f.checkbox(title: _("Use browser for metadata download")) + } } diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/config_de.properties b/core/src/main/resources/jenkins/model/DownloadSettings/config_de.properties index 2d8110051f024d0a014389a86436c313f1d49c54..be68d8e226d42a639969ed172780500177258d1a 100644 --- a/core/src/main/resources/jenkins/model/DownloadSettings/config_de.properties +++ b/core/src/main/resources/jenkins/model/DownloadSettings/config_de.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2014, Harald Albers +# Copyright (c) 2014-2015, Harald Albers # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Download\ Preferences = Downloads -Use\ Browser = Browser verwenden +Use\ browser\ for\ metadata\ download = Browser zum Download von Metadaten verwenden diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/config_ja.properties b/core/src/main/resources/jenkins/model/DownloadSettings/config_ja.properties index 9d4a1dad1e5027127553e7bcbfcc7b869d379f1b..3f7949a961a2fbec73d6f934360734668cc9126b 100644 --- a/core/src/main/resources/jenkins/model/DownloadSettings/config_ja.properties +++ b/core/src/main/resources/jenkins/model/DownloadSettings/config_ja.properties @@ -20,5 +20,4 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Download\ Preferences = \u30c0\u30a6\u30f3\u30ed\u30fc\u30c9 Use\ Browser = \u30d6\u30e9\u30a6\u30b6\u3092\u4f7f\u7528 diff --git a/core/src/main/resources/jenkins/model/DownloadSettings/config_sr.properties b/core/src/main/resources/jenkins/model/DownloadSettings/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..76414275dddfa182587716623810ea00896f2cd5 --- /dev/null +++ b/core/src/main/resources/jenkins/model/DownloadSettings/config_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Use\ Browser=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u0432\u0435\u0431-\u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447 +Use\ browser\ for\ metadata\ download=\u041F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u0458 \u043C\u0435\u0442\u0430\u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 \u0432\u0435\u0431-\u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447\u0435\u043C \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/config_sr.properties b/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..29a7fbccd48a0ecfc0adfc93139a7199d0d499e9 --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalCloudConfiguration/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Delete\ cloud=\u0423\u043A\u043B\u043E\u043D\u0438 cloud +Cloud=Cloud +Add\ a\ new\ cloud=\u0414\u043E\u0434\u0430\u0458 \u043D\u043E\u0432\u0438 cloud \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/GlobalNodePropertiesConfiguration/config_sr.properties b/core/src/main/resources/jenkins/model/GlobalNodePropertiesConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f3244eb9c96937e2d0ec21edb67755e153439341 --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalNodePropertiesConfiguration/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Global\ properties=\u0413\u043B\u043E\u0431\u0430\u043B\u043D\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config_fr.properties b/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f561adbdff3e933714b40c5b52973b675a5c756f --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config_fr.properties @@ -0,0 +1,3 @@ +useNamingStrategy=Restreindre le nommage de projet +namingStrategyTitel=Strat\u00E9gie de nommage +strategy=Strat\u00E9gie \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config_sr.properties b/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b8a5aa7afa74a18e35ecf4a58cfbabc588aad59f --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalProjectNamingStrategyConfiguration/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +useNamingStrategy=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u0448\u0435\u043C\u0443 \u0438\u043C\u0435\u043D\u043E\u0432\u0430\u045A\u0430 \u0437\u0430 \u043D\u0430\u0437\u0438\u0432 \u0437\u0430\u0434\u0430\u0442\u0430\u043A\u0430 +namingStrategyTitel=\u0428\u0435\u043C\u0430 \u0438\u043C\u0435\u043D\u043E\u0432\u0430\u045A\u0430 +strategy=\u0428\u0435\u043C\u0430 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/config_sr.properties b/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..dd06cd0724c3b45e18356f64e95bf157941982c5 --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Quiet\ period=\u041F\u0435\u0440\u0438\u043E\u0434 \u045B\u0443\u0442\u0430\u045A\u0430 diff --git a/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod.html b/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod.html index fb8b2665a6f65933d1d052eab4db1b45a7566c85..4beaab60a76463e39086b7cf6daa88bc1f37dee4 100644 --- a/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod.html +++ b/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod.html @@ -1,21 +1,23 @@
    - If set, a newly scheduled build waits for this many seconds before actually being built. - This is useful for: -
      -
    • - Collapsing multiple CVS change notification e-mails into one (some CVS changelog - e-mail generation scripts generate multiple e-mails in quick succession when - a commit spans across directories). -
    • -
    • - If your coding style is such that you commit one logical change in a few cvs/svn - operations, then setting a longer quiet period would prevent Jenkins from building - it prematurely and reporting a failure. -
    • -
    • - Throttling builds. If your Jenkins installation is too busy with too many builds, - setting a longer quiet period can reduce the number of builds. -
    • -
    - If not explicitly set at project-level, the system-wide default value is used. -
    \ No newline at end of file + When this option is checked, newly triggered builds of this project will be + added to the queue, but Jenkins will wait for the specified period of time + before actually starting the build. +

    + For example, if your builds take a long time to execute, you may want to + prevent multiple source control commits that are made at approximately the + same time from triggering multiple builds. Enabling the quiet period would + prevent a build from being started as soon as Jenkins discovers the first + commit; this would give the developer the chance to push more commits which + would be included in the build when it starts. This reduces the size of the + queue, meaning that developers would get feedback faster for their series of + commits, and the load on the Jenkins system would be reduced. +

    + If a new build of this project is triggered while a build is already sitting + in the queue, waiting for its quiet period to end, the quiet period will not + be reset. The newly triggered build will not be added to the queue, unless + this project is parameterised and the build has different parameters to the + build already in the queue. +

    + If this option is not checked, then the system-wide default value from the + Configure System screen will be used. +

    diff --git a/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod_de.html b/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod_de.html index c3091d33ee1d45406affa4f996c15de4525228c5..2d9143797d8c8bd48d46ab7f9faf642ae6c80857 100644 --- a/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod_de.html +++ b/core/src/main/resources/jenkins/model/GlobalQuietPeriodConfiguration/help-quietPeriod_de.html @@ -11,7 +11,7 @@
  10. Ihr Programmierstil es erfordert, eine logische Änderung in mehreren CVS/SVN-Operationen durchzuführen. Eine verlängerte Ruheperiode verhindert - in diesem Falle, daß Jenkins einen Build verfrüht startet und einen Fehlschlag + in diesem Falle, dass Jenkins einen Build verfrüht startet und einen Fehlschlag meldet.
  11. @@ -22,4 +22,4 @@ Ein systemweiter Vorgabewert wird verwendet, wenn nicht auf Projektebene ein expliziter Wert angegeben wird. -
  12. \ No newline at end of file +
    diff --git a/core/src/main/resources/jenkins/model/GlobalSCMRetryCountConfiguration/config_sr.properties b/core/src/main/resources/jenkins/model/GlobalSCMRetryCountConfiguration/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..583c36f8a6981229d0ca8fb037e8883da4ca04eb --- /dev/null +++ b/core/src/main/resources/jenkins/model/GlobalSCMRetryCountConfiguration/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +SCM\ checkout\ retry\ count=\u0411\u0440\u043E\u0458 \u043F\u043E\u043A\u0443\u0448\u0430\u0458\u0430 \u043F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message.jelly b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message.jelly new file mode 100644 index 0000000000000000000000000000000000000000..bc2149f7529667ab145820eb68a84a4f14a222df --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message.jelly @@ -0,0 +1,34 @@ + + + +
    + ${%description(it.systemPropertyName, it.expectedPort)} +
    +
    + +
    +
    +
    +
    diff --git a/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message.properties b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message.properties new file mode 100644 index 0000000000000000000000000000000000000000..e4f6f0fd8c5ca473867295db5fec2f9658826165 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/EnforceSlaveAgentPortAdministrativeMonitor/message.properties @@ -0,0 +1,2 @@ +description=JNLP Agent Port has been changed but was specified through system property {0} on startup. Its value will be reset to {1,number,#} on restart. +reset=Reset to {0,number,#} diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..342570a4e1b9d14752a8193fb86abbd7cded86e7 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_lt.properties @@ -0,0 +1,5 @@ +\#\ of\ executors=# vykdytoj\u0173 +Labels=Etiket\u0117s +Node\ Properties=Mazgo savyb\u0117s +Save=\u012era\u0161yti +Description=Apra\u0161ymas diff --git a/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7329797f439b498777c6825858cbd99e86f76b9c --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/MasterComputer/configure_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Labels=\u041B\u0430\u0431\u0435\u043B\u0435 +Node\ Properties=\u041F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 \u043C\u0430\u0448\u0438\u043D\u0435 +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +\#\ of\ executors=\u0431\u0440\u043E\u0458 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 +Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/jenkins/model/Jenkins/_cli_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/_cli_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9eb1d202ee067eb6fe942fdc6bd0d5a404d41566 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_cli_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Jenkins\ CLI=Jenkins \u0441\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u043D\u0435 \u043B\u0438\u043D\u0438\u0458\u0435 +Available\ Commands=\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/Jenkins/_restart_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/_restart_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..74184c4dcc0b7d69a808b896c885801672d739a0 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_restart_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Yes=\ + \u0414\u0430 +Are\ you\ sure\ about\ restarting\ Jenkins?=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 Jenkins? +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=\ + \u0421 \u0442\u0435\u043a\u0443\u0449\u0438\u0442\u0435 \u0441\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Jenkins \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430. diff --git a/core/src/main/resources/jenkins/model/Jenkins/_restart_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/_restart_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..8d9d9476c750b9111b4677e0794d0e95cf3cc089 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_restart_lt.properties @@ -0,0 +1,3 @@ +Yes=Taip +Are\ you\ sure\ about\ restarting\ Jenkins?=Ar tikrai norite i\u0161 naujo paleisti Jenkins\u0105? +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=Jenkinsas toks, koks dabar yra sukonfig\u016bruotas, negali pats sav\u0119s paleisti i\u0161 naujo. diff --git a/core/src/main/resources/jenkins/model/Jenkins/_restart_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/_restart_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..fa62a6b2c3380c2555f06d7baacbe968062448b0 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_restart_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Are\ you\ sure\ about\ restarting\ Jenkins?=\u0414\u0430\u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0435 Jenkins? +Yes=\u0414\u0430 +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=\u041D\u0435\u043C\u043E\u0436\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0438 Jenkins \u043F\u043E \u043E\u0432\u0438\u043C \u043F\u043E\u0441\u0442\u0430\u0432\u0446\u0438\u043C\u0430 diff --git a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..0aee9fd59206203971cc97206ca6267599b14782 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_bg.properties @@ -0,0 +1,29 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=\ + \u0421 \u0442\u0435\u043a\u0443\u0449\u0438\u0442\u0435 \u0441\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 Jenkins \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430. +Yes=\ + \u0414\u0430 +Are\ you\ sure\ about\ restarting\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442\u0435 Jenkins? \u0422\u043e\u0439 \u0449\u0435 \u0441\u0435 \u0440\u0435\u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430 \u0441\ + \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 \u0442\u0435\u043a\u0443\u0449\u0438 \u0437\u0430\u0434\u0430\u0447\u0438. diff --git a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..5c38c9a87a2ea6857392ce7c05f778771f2323b0 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_lt.properties @@ -0,0 +1,3 @@ +Are\ you\ sure\ about\ restarting\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=Ar tikrai norite i\u0161 naujo paleisti Jenkins\u0105? Jenkinsas bus paleistas i\u0161 naujo, kai visi vykdomi darbai bus baigti. +Yes=Taip +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=Toks, kaip dabar sukonfig\u016bruotas, Jenkinas negali pats sav\u0119s paleisti i\u0161 naujo. diff --git a/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..430f57df18031ffddbe0713ff71decc9e492cfc4 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/_safeRestart_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Are\ you\ sure\ about\ restarting\ Jenkins?\ Jenkins\ will\ restart\ once\ all\ running\ jobs\ are\ finished.=\u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0435\u0442\u0435 Jenkins \u043A\u0430\u0434 \u0441\u0432\u0435 \u0442\u0435\u043A\u0443\u045B\u0435 \u043F\u043E\u0441\u043B\u043E\u0432\u0435 \u0431\u0443\u0434\u0443 \u0431\u0438\u043B\u0435 \u0433\u043E\u0442\u043E\u0432\u0435? +Yes=\u0414\u0430 +Jenkins\ cannot\ restart\ itself\ as\ currently\ configured.=\u041D\u0435\u043C\u043E\u0436\u0435 \u0441\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u043A\u0440\u0435\u043D\u0443\u0442\u0438 Jenkins \u0437\u0430 \u043E\u0432\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0438\u043C\u0430. diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_sv_SE.properties b/core/src/main/resources/jenkins/model/Jenkins/accessDenied_bg.properties similarity index 83% rename from core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_sv_SE.properties rename to core/src/main/resources/jenkins/model/Jenkins/accessDenied_bg.properties index a1827f1712ad630b15d0331af3ba0f910260c0af..fd265916bd4fba86cf539ca625e170cf698b0082 100644 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_sv_SE.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/accessDenied_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -body=Detta \u00E4r en central del i Jenkins. Jenkins kommer att bygga ditt projekt med valfri versionshanterare och med vilket byggsystem som helst, och detta kan \u00E4ven anv\u00E4ndas f\u00F6r n\u00E5got annat \u00E4n mjukvarubyggen. +Access\ Denied=\ + \u041e\u0442\u043a\u0430\u0437\u0430\u043d \u0434\u043e\u0441\u0442\u044a\u043f +Jenkins\ Login=\ + \u0412\u043f\u0438\u0441\u0432\u0430\u043d\u0435 \u0432 Jenkins diff --git a/core/src/main/resources/jenkins/model/Jenkins/accessDenied_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/accessDenied_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..8edee3fe6237b18373730240ca9cd1f8691cbae8 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/accessDenied_lt.properties @@ -0,0 +1,2 @@ +Jenkins\ Login=Jenkins prisijungimas +Access\ Denied=Prieiga atmesta diff --git a/core/src/main/resources/jenkins/model/Jenkins/accessDenied_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/accessDenied_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5dc7a3e054e7f795713472732350e61dfc830f48 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/accessDenied_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Jenkins\ Login=\u041F\u0440\u0438\u0458\u0430\u0432\u0430 \u043D\u0430 Jenkins +Access\ Denied=\u041F\u0440\u0438\u0441\u0442\u0443\u043F \u043E\u0434\u0431\u0438\u0458\u0435\u043D diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure.jelly b/core/src/main/resources/jenkins/model/Jenkins/configure.jelly index fee18794ffb6c67ed69e7ef1b72c91ccc26bb0b7..e95226abb1f1350f8aade9d7c456aba381018cfe 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/configure.jelly @@ -62,7 +62,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/jenkins/model/Jenkins/configureExecutors.jelly b/core/src/main/resources/jenkins/model/Jenkins/configureExecutors.jelly index 921dc65e3e6b17f319caf0b207c777fed38de425..751bea6574aa53e80a64e7e15ad3973976448ce4 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configureExecutors.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/configureExecutors.jelly @@ -36,12 +36,12 @@ THE SOFTWARE. This page has moved

    - Starting 1.271, slave configuration is split into individual configuration page per slave, + Starting 1.271, agent configuration is split into individual configuration page per agent, accessible from here.

      -
    • To configure existing slaves, click the above link, click their name, and then click the config link from the left
    • -
    • To add a new slave, click the above link, and click "add new slave"
    • +
    • To configure existing agents, click the above link, click their name, and then click the config link from the left
    • +
    • To add a new agent, click the above link, and click "add new agent"
    diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/configure_bg.properties index 6b96eea0407b1b23db27a2b064e3ad7fb85de1b3..dac6a7bdc1f63db4a22782e12b237faa8a989d2d 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/configure_bg.properties @@ -1,7 +1,38 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Build\ Record\ Root\ Directory=\u0411\u0430\u0437\u043E\u0432\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u044F \u043D\u0430 \u0431\u0438\u043B\u0434\u0430 -Home\ directory=\u041D\u0430\u0447\u0430\u043B\u043D\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u044F -LOADING=\u0417\u0410\u0420\u0415\u0416\u0414\u0410\u041D\u0415 -System\ Message=\u0421\u0438\u0441\u0442\u0435\u043C\u043D\u043E \u0441\u044A\u043E\u0431\u0449\u0435\u043D\u0438\u0435 -Workspace\ Root\ Directory=\u0411\u0430\u0437\u043E\u0432\u0430 \u0440\u0430\u0431\u043E\u0442\u043D\u0430 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u044F +Build\ Record\ Root\ Directory=\ + \u0411\u0430\u0437\u043e\u0432\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +Home\ directory=\ + \u0414\u043e\u043c\u0430\u0448\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f +LOADING=\ + \u0417\u0410\u0420\u0415\u0416\u0414\u0410\u041d\u0415 +System\ Message=\ + \u0421\u0438\u0441\u0442\u0435\u043c\u043d\u043e \u0441\u044a\u043e\u0431\u0449\u0435\u043d\u0438\u0435 +Workspace\ Root\ Directory=\ + \u0411\u0430\u0437\u043e\u0432\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u043e\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e +Configure\ System=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0432\u0430\u043d\u0435 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 +Save=\ + \u0417\u0430\u043f\u0430\u0437\u0432\u0430\u043d\u0435 +Apply=\ + \u041f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0435 diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure_fr.properties b/core/src/main/resources/jenkins/model/Jenkins/configure_fr.properties index dba2e1dcfcfaff1298bd8860bc9f7d70d405e9e3..8683592c013be7ec3b8607e9d9e3ea49b57ce8a0 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure_fr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/configure_fr.properties @@ -20,9 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Home\ directory=Rpertoire Home -System\ Message=Message du systme +Home\ directory=R\u00E9pertoire Home +System\ Message=Message du syst\u00E8me Workspace\ Root\ Directory=R\u00E9pertoire racine de l''espace de travail (workspace) Save=Enregistrer +Apply=Appliquer Build\ Record\ Root\ Directory=R\u00E9pertoire racine des constructions LOADING=CHARGEMENT diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/configure_lt.properties index 5ec9b9de628388fa220291c72782d2295cb90f04..371e6713db7ada607c492a7e2597c596fffc5787 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/configure_lt.properties @@ -1,6 +1,8 @@ -# This file is under the MIT License by authors - -Home\ directory=Nam\u0173 katalogas -LOADING=KRAUNASI -System\ Message=Sistemin\u0117 \u017Einut\u0117 -Workspace\ Root\ Directory=Darbastalio \u0160aknin\u0117 Direktorija +Home\ directory=Nam\u0173 aplankas +LOADING=\u012eKELIAMA +System\ Message=Sisteminis prane\u0161imas +Workspace\ Root\ Directory=Darbastalio \u0161akninis aplankas +Build\ Record\ Root\ Directory=Vykdymo \u012fra\u0161o \u0161akninis aplankas +Configure\ System=Konfig\u016bruoti sistem\u0105 +Save=\u012era\u0161yti +Apply=Pritaikyti diff --git a/core/src/main/resources/jenkins/model/Jenkins/configure_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/configure_sr.properties index ba97cef5b0f09abf3f280dd48f9d6c066d7a8cb5..c6e2ed92554df6c393065fa12d66bfaea9e13797 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/configure_sr.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/configure_sr.properties @@ -1,7 +1,10 @@ # This file is under the MIT License by authors -Build\ Record\ Root\ Directory=Osnovni direktorijum build rezultata -Home\ directory=Pocetni direktorijum -LOADING=Ucitavanje -System\ Message=Sistemska poruka -Workspace\ Root\ Directory=Osnovni direktorijum okruzenja +Build\ Record\ Root\ Directory=\u041E\u0441\u043D\u043E\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0440\u0435\u0437\u0443\u043B\u0430\u0442\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Home\ directory=\u041F\u043E\u045B\u0435\u0442\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C +LOADING=\u0423\u0427\u0418\u0422\u0410\u0412\u0410\u040A\u0415 +System\ Message=\u0421\u0438\u0441\u0442\u0435\u043C\u0441\u043A\u0430 \u043F\u043E\u0440\u0443\u043A\u0430 +Workspace\ Root\ Directory=\u0413\u043B\u0430\u0432\u043D\u0438 \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C \u0440\u0430\u0434\u043D\u043E\u0433 \u043F\u0440\u043E\u0441\u0442\u043E\u0440\u0430 +Configure\ System=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u0441\u0438\u0441\u0442\u0435\u043C\u043E\u043C +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +Apply=\u041F\u0440\u0438\u043C\u0435\u043D\u0438 diff --git a/core/src/main/resources/jenkins/model/Jenkins/downgrade_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/downgrade_bg.properties index 6e827c7d05508156b59abd948c95ba3dae22a34e..f1691452f783b0a0dbf9f6d736f7fdb1846640d0 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/downgrade_bg.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/downgrade_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Restore\ the\ previous\ version\ of\ Jenkins=\u0412\u044A\u0437\u0441\u0442\u0430\u043D\u043E\u0432\u044F\u0432\u0430\u043D\u0435 \u043D\u0430 \u043F\u0440\u0435\u0434\u0438\u0448\u043D\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044F \u043D\u0430 Jenkins -buttonText=\u0412\u044A\u0437\u0441\u0442\u0430\u043D\u043E\u0432\u044F\u0432\u0430\u043D\u0435 \u0434\u043E {0} +Restore\ the\ previous\ version\ of\ Jenkins=\ + \u0412\u0440\u044a\u0449\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u0438\u0448\u043d\u0430\u0442\u0430 \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Jenkins +buttonText=\ + \u0412\u0440\u044a\u0449\u0430\u043d\u0435 \u043a\u044a\u043c {0} diff --git a/core/src/main/resources/jenkins/model/Jenkins/downgrade_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/downgrade_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..88b48e9acf7dacbb88686bbe752bfc755d7d8993 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/downgrade_lt.properties @@ -0,0 +1,2 @@ +buttonText=Nuleisti versij\u0105 iki {0} +Restore\ the\ previous\ version\ of\ Jenkins=Atstatyti ankstesn\u0119 Jenkinso versij\u0105 diff --git a/core/src/main/resources/jenkins/model/Jenkins/downgrade_pl.properties b/core/src/main/resources/jenkins/model/Jenkins/downgrade_pl.properties index a7ca7cdb6ae107267e6fd7d56bbbe30c27c1e0c2..02a32fa88e48bebc55b33eca3c044073f26499d5 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/downgrade_pl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/downgrade_pl.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Restore\ the\ previous\ version\ of\ Jenkins=Przywr\u00F3\u0107 poprzedni\u0105 wersj\u0119 Jenkins''a -buttonText=Obni\u017C do +Restore\ the\ previous\ version\ of\ Jenkins=Przywr\u00F3\u0107 poprzedni\u0105 wersj\u0119 Jenkinsa +buttonText=Obni\u017C do {0} diff --git a/core/src/main/resources/jenkins/model/Jenkins/downgrade_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/downgrade_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d04470f1d0c87a9dc8374ed465f097b426c5cf8b --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/downgrade_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +buttonText=\u0412\u0440\u0430\u0442\u0438 \u043D\u0430\u0437\u0430\u0434 \u043D\u0430 {0} +Restore\ the\ previous\ version\ of\ Jenkins=\u0412\u0440\u0430\u0442\u0438 \u043D\u0430 \u043F\u0440\u0435\u0442\u043D\u043E\u0434\u043D\u0443 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 Jenkins-\u0430 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..15765bd910f8b8f5fd2b402062bd94f7ac2bdfd3 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_bg.properties @@ -0,0 +1,40 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Check=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 +File\ to\ check=\ + \u0424\u0430\u0439\u043b \u0437\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 +Check\ File\ Fingerprint=\ + \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u044f \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u043a \u043d\u0430 \u0444\u0430\u0439\u043b\u0430 +# \ +# Got a jar file but don\u2019t know which version it is?
    \ +# Find that out by checking the fingerprint against \ +# the database in Jenkins +description=\ + \u041d\u0435 \u0437\u043d\u0430\u0435\u0442\u0435 \u0432\u0435\u0440\u0441\u0438\u044f\u0442\u0430 \u043d\u0430 \u043d\u044f\u043a\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u0435\u043d \u201e.jar\u201c \u0444\u0430\u0439\u043b?
    + \u041f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0437\u0430 \u0446\u0438\u0444\u0440\u043e\u0432\u0438\u044f \u043c\u0443 \u043e\u0442\u043f\u0435\u0447\u0430\u0442\u044a\u043a \u0432 \u0431\u0430\u0437\u0430\u0442\u0430 \u043d\u0430 Jenkins. +# https://wiki.jenkins-ci.org/display/JENKINS/Fingerprint +fingerprint.link=\ + https://wiki.jenkins-ci.org/display/JENKINS/Fingerprint +more\ details=\ + \u041e\u0449\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_et.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_et.properties index a34ae03918583dfd2e282d439e127bf27487b75a..3c4ef25a9641625076808e004b39c855a6cd7692 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_et.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_et.properties @@ -4,6 +4,6 @@ Check=Kontrolli Check\ File\ Fingerprint=Kontrolli Faili Signatuuri File\ to\ check=Kontrolli faili description=Sul on jar fail aga sa ei tea tema versiooninumbrit?
    Leia see kontrollides faili signatuuri Jenkinsi andmebaasist. -
    Leia see Jenkinsi s\u00F5rmej\u00E4lgede andmebaasist. -
    Leia see Jenkinsi s\u00F5rmej\u00E4lgede andmebaasist. +# TODO was this supposed to be part of the previous description? +#
    Leia see Jenkinsi s\u00F5rmej\u00E4lgede andmebaasist. more\ details=lisadetailid diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..7478165497b4de0217dffacb029238c3f8a832e3 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_lt.properties @@ -0,0 +1,8 @@ +description=\ + Gavote jar fail\u0105 bet ne\u017einote, kokia jo versija?
    \ + Su\u017einokite patikrindami antspaud\u0105 Jenkinso duomen\u0173 baz\u0117je +fingerprint.link=https://wiki.jenkins-ci.org/display/JENKINS/Fingerprint +Check=Tikrinti +Check\ File\ Fingerprint=Tikrinti failo antspaud\u0105 +more\ details=daugiau informacijos +File\ to\ check=Tikrinti fail\u0105 diff --git a/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..786cab1e466b1ce9fb2c4b19220ee03ef9293c00 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/fingerprintCheck_sr.properties @@ -0,0 +1,10 @@ +# This file is under the MIT License by authors + +Check\ File\ Fingerprint=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 +description=\u041D\u0435\u0437\u043D\u0430\u0442\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 \u043E\u0434 \u043D\u0435\u043A\u0435 '.jar' \u0430\u0440\u0445\u0438\u0432\u0435?
    \ +\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u043F\u043E \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u043E\u043C \u043E\u0442\u0438\u0441\u043A\u0443. +fingerprint.link=https://wiki.jenkins-ci.org/display/JENKINS/Fingerprint +more\ details=\u0412\u0438\u0448\u0435 \u0434\u0435\u0442\u0430\u0459\u0430 +File\ to\ check=\u0410\u0440\u0445\u0438\u0432\u0430 \u0437\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0432\u0430\u045A\u0435 +Check=\u041F\u0440\u043E\u0432\u0435\u0440\u0438 +Find=\u041F\u0440\u043E\u043D\u0430\u0452\u0438 diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..0c54a47690e83852ff511079e36009c2bc39432c --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/help-markupFormatter_bg.html @@ -0,0 +1,16 @@ +
    + На места като описанията на проект, потребител, изглед или изграждане, + Jenkins ви позволява да въведете свободен, описателен текст. + + Тази настройка определя как този свободен текст се преобразува до HTML. + Стандартно счита текста за HTML и го ползва както е (това поведение е за + съвместимост с предишни версии). + +

    + Това е доста уобно и хората го ползват, за да зареждат <iframe>, + <script> и т.н., това позволяна на недробонамерените потребители да + извършат атаки чрез + XSS. + Ако рискът е прекомерно голям, инсталирайте допълнителна приставка за + форматиране на текста и ползвайте нея. +

    diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir.html b/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir.html index 2d7c1159f51a176347c43e418dfdf860b228ead1..ebe0002239d3776f7c87fab0b72e39fcc5ceb1fb 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir.html @@ -1,15 +1,28 @@
    - Specify where Jenkins would store records of the past builds. - This value can include the following variables. - + Specifies where Jenkins will store build records on the file system. This + includes the console output and other metadata generated by a build. +

    + This value may include the following variables:

      -
    • ${JENKINS_HOME} — Jenkins home directory. -
    • ${ITEM_ROOTDIR} — Root directory of a job for which the default workspace is allocated. -
    • ${ITEM_FULL_NAME} — '/'-separated job name, like "foo/bar". +
    • ${JENKINS_HOME} — Absolute path of the Jenkins home + directory +
    • ${ITEM_ROOTDIR} — Absolute path of the directory + where Jenkins stores the configuration and related metadata for a + given job +
    • ${ITEM_FULL_NAME} — The full name of a given job, + which may be slash-separated, e.g. foo/bar for the job + bar in folder foo
    - + The value must include ${ITEM_ROOTDIR} or + ${ITEM_FULL_NAME}, so that each job can store its build records + separately. +

    + Changing this value allows you to store build records on a larger, but + slower disk, rather than on the same disk where builds are executed. +

    + Any changes to this value will take effect as soon as this configuration + page is saved, but note that Jenkins will not automatically migrate any data + from the current build record root directory.

    - Changing this value allows you to put build records on a bigger but slow disk, - while keeping JENKINS_HOME on highly available backed up drive, for example. - Default value is ${ITEM_ROOTDIR}/builds. -

    \ No newline at end of file + The default value is ${ITEM_ROOTDIR}/builds. +
    diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir_bg.html b/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..e30240fe001a9693fdaab8a5f15f7172bf8aa443 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/help-rawBuildsDir_bg.html @@ -0,0 +1,29 @@ +
    + Указва мястото във файловата система, където Jenkins ще запазва + записите за изгражданията. Това включва изхода от конзолата, както и дугите + метаданни, които се генерират при изграждане. +

    + Стойността може да включва следните променливи: +

      +
    • ${JENKINS_HOME} — абсолютният път до домашната директория + на Jenkins; +
    • ${ITEM_ROOTDIR} — абсолютният път до директорията, в която + Jenkins запазвъ настройките и свързаните метаданни за определено + задание; +
    • ${ITEM_FULL_NAME} — пълното име на заданието, което може да + съдържа наклонени черти, напр. foo/bar за заданието + bar в папка foo +
    + Стойността трябва да включва ${ITEM_ROOTDIR} или + ${ITEM_FULL_NAME}, за да може всяко задание да запазва записите за + изгражданията отделно. +

    + Можете да промените стойността, за да държите записите на по-голям, но + по-бавен диск в сравнение с този, на който се извършват изгражданията. +

    + Промените по стойността ще влязат в сила веднага след подаването на тази + страница с настройки. Jenkins няма автоматично да мигрира каквито и да е + данни от текущата директория за изграждане. +

    + Стандартната стойност е ${ITEM_ROOTDIR}/builds. +

    diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir.html b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir.html index 7906d5c1909d73b9f4ebd4548fe9513f8a5656b0..0249a88dd4804bc9b77b56dc2d5e3550193523d9 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir.html @@ -1,15 +1,30 @@
    - Specify where Jenkins would store job workspaces on the master node. - (It has no effect on builds run on slaves.) - This value can include the following variables. - + Specifies where Jenkins will store workspaces for builds that are executed + on the master.
    + It has no effect on builds that are executed on agents. +

    + This value may include the following variables:

      -
    • ${JENKINS_HOME} — Jenkins home directory. -
    • ${ITEM_ROOTDIR} — Root directory of a job for which the default workspace is allocated. -
    • ${ITEM_FULL_NAME} — '/'-separated job name, like "foo/bar". +
    • ${JENKINS_HOME} — Absolute path of the Jenkins home + directory +
    • ${ITEM_ROOTDIR} — Absolute path of the directory + where Jenkins stores the configuration and related metadata for a + given job +
    • ${ITEM_FULL_NAME} — The full name of a given job, + which may be slash-separated, e.g. foo/bar for the job + bar in folder foo
    - + The value should normally include ${ITEM_ROOTDIR} or + ${ITEM_FULL_NAME}, otherwise different jobs will end up sharing the + same workspace. +

    + As builds tend to be disk I/O intensive, changing this value enables you to + put build workspaces on faster storage hardware, such as SSDs or even RAM + disks. +

    + Any changes to this value will take effect as soon as this configuration + page is saved, but note that Jenkins will not automatically migrate any data + from the current workspace root directory.

    - Changing this value allows you to put workspaces on SSD, SCSI, or even ram disks. - Default value is ${ITEM_ROOTDIR}/workspace. -

    \ No newline at end of file + The default value is ${JENKINS_HOME}/workspace/${ITEM_FULLNAME}. +
    diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_bg.html b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_bg.html new file mode 100644 index 0000000000000000000000000000000000000000..63c090bb308ba7920c99285be7c6f7b840b59e10 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_bg.html @@ -0,0 +1,30 @@ +
    + Указва мястото във файловата система, където Jenkins ще запазва + изгражданията на основния компютър.
    + Това не влияе на подчинените компютри. +

    + Стойността може да включва следните променливи: +

      +
    • ${JENKINS_HOME} — абсолютният път до домашната директория + на Jenkins; +
    • ${ITEM_ROOTDIR} — абсолютният път до директорията, в която + Jenkins запазвъ настройките и свързаните метаданни за определено + задание; +
    • ${ITEM_FULL_NAME} — пълното име на заданието, което може да + съдържа наклонени черти, напр. foo/bar за заданието + bar в папка foo +
    + Стойността трябва да включва ${ITEM_ROOTDIR} или + ${ITEM_FULL_NAME}, за да може всяко задание да запазва + изгражданията отделно. +

    + Понеже при изгражданията доминират входно-изходните операции, може да + смените стойността, за да ползвате по-бърз хардуер като SSDs или дори + дискове в RAM паметта. +

    + Промените по стойността ще влязат в сила веднага след подаването на тази + страница с настройки. Jenkins няма автоматично да мигрира каквито и да е + данни от текущата директория за изграждане. +

    + Стандартната стойност е ${JENKINS_HOME}/workspace/${ITEM_FULLNAME}. +

    diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_ja.html b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_ja.html index b5547fffe1f121f474a4a2a6e8d94a07a6740e76..6967b33ac69496b206f73384d4a3b4d85dc04ff0 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_ja.html +++ b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_ja.html @@ -10,5 +10,5 @@

    この値を変更することで、ワークスペースをSSD、SCSIあるいはRAMディスク上にワークスペースを配置することができます。 - デフォルト値は、${ITEM_ROOTDIR}/workspaceです。 + デフォルト値は、${JENKINS_HOME}/workspace/${ITEM_FULLNAME}です。

    diff --git a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_zh_TW.html b/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_zh_TW.html deleted file mode 100644 index e849c6f5c0e308cb49d52fdb20695c695c416fc3..0000000000000000000000000000000000000000 --- a/core/src/main/resources/jenkins/model/Jenkins/help-rawWorkspaceDir_zh_TW.html +++ /dev/null @@ -1,13 +0,0 @@ -
    - 設定 Jenkins 在 Master 節點上存放作業工作區的地方 (對 Slave 節點上的建置無效),可以使用下列變數: - -
      -
    • ${JENKINS_HOME} — Jenkins 主目錄。 -
    • ${ITEM_ROOTDIR} — 作業根目錄,也就是放預設工作區的地方。 -
    • ${ITEM_FULL_NAME} — 用 '/' 隔開的作業名稱,例如 "foo/bar"。 -
    - -

    - 讓您可以把工作區放到 SSD, SCSI 甚至是 Ram Disk 上。 - 預設值是 ${ITEM_ROOTDIR}/workspace。 -

    \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..cf4e0133fde04b420a4de4b0557e2e171aab1f71 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_bg.properties @@ -0,0 +1,68 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# The last build fatally failed. A new build is in progress. +red_anime=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0431\u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e. \u0412 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0442\u0435\u0447\u0435 \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u043e\u0442\u043e. +# The project has never been built before, or the project is disabled. +grey=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u043d\u0435 \u0435 \u0431\u0438\u043b \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d \u0434\u043e\u0441\u0435\u0433\u0430 \u0438\u043b\u0438 \u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0435\u043d. +# Project health is 20% or less. You can hover the mouse over the project\u2019s icon for a more detailed explanation. +health-00to20=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0435 \u0437\u0434\u0440\u0430\u0432 \u043d\u0430 [0;20]\u200a%. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0440\u044a\u0436\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0435\u0446\u0430 \u043d\u0430\ + \u043c\u0438\u0448\u043a\u0430\u0442\u0430 \u043d\u0430\u0434 \u0438\u043a\u043e\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. +# The last build was successful but unstable. A new build is in progress. +yellow_anime=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u043d\u043e \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e. \u0412 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0442\u0435\u0447\u0435 \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u043e\u0442\u043e. +# The last build was successful. +blue=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e. +# The last build was successful but unstable.\ +# This is primarily used to represent test failures. +yellow=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u043d\u043e \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u043d\u043e. \u041d\u0430\u0439-\u0447\u0435\u0441\u0442\u043e \u0442\u043e\u0432\u0430 \u0441\u0435 \u0434\u044a\u043b\u0436\u0438 \u043d\u0430\ + \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0438 \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u0435\u0442\u0435. +# The last build fatally failed. +red=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0431\u0435 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u043e. +# Project health is over 40% and up to 60%. You can hover the mouse over the project\u2019s icon for a more detailed explanation. +health-41to60=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0435 \u0437\u0434\u0440\u0430\u0432 \u043d\u0430 (40;60]\u200a%. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0440\u044a\u0436\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0435\u0446\u0430 \u043d\u0430\ + \u043c\u0438\u0448\u043a\u0430\u0442\u0430 \u043d\u0430\u0434 \u0438\u043a\u043e\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. +# The last build was successful. A new build is in progress. +blue_anime=\ + \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0431\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e. \u0412 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0442\u0435\u0447\u0435 \u0441\u043b\u0435\u0434\u0432\u0430\u0449\u043e\u0442\u043e. +# Project health is over 20% and up to 40%. You can hover the mouse over the project\u2019s icon for a more detailed explanation. +health-21to40=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0435 \u0437\u0434\u0440\u0430\u0432 \u043d\u0430 (20;40]\u200a%. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0440\u044a\u0436\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0435\u0446\u0430 \u043d\u0430\ + \u043c\u0438\u0448\u043a\u0430\u0442\u0430 \u043d\u0430\u0434 \u0438\u043a\u043e\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. +# Project health is over 60% and up to 80%. You can hover the mouse over the project\u2019s icon for a more detailed explanation. +health-61to80=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0435 \u0437\u0434\u0440\u0430\u0432 \u043d\u0430 (60;80]\u200a%. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0440\u044a\u0436\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0435\u0446\u0430 \u043d\u0430\ + \u043c\u0438\u0448\u043a\u0430\u0442\u0430 \u043d\u0430\u0434 \u0438\u043a\u043e\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. +# Project health is over 80%. You can hover the mouse over the project\u2019s icon for a more detailed explanation. +health-81plus=\ + \u041f\u0440\u043e\u0435\u043a\u0442\u044a\u0442 \u0435 \u0437\u0434\u0440\u0430\u0432 \u043d\u0430 (80;100]\u200a%. \u0417\u0430 \u043f\u043e\u0432\u0435\u0447\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430\u0434\u0440\u044a\u0436\u0442\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0435\u0446\u0430 \u043d\u0430\ + \u043c\u0438\u0448\u043a\u0430\u0442\u0430 \u043d\u0430\u0434 \u0438\u043a\u043e\u043d\u0430\u0442\u0430 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. +# The first build of the project is in progress. +grey_anime=\ + \u0412 \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0442\u0435\u0447\u0435 \u043f\u044a\u0440\u0432\u043e\u0442\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_es.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_es.properties index 4cf758e8d334c73eb9f0108a85fff3cb5b55bcc9..825dbb92b66140483d726d0672e7f5c0c5c19478 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_es.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_es.properties @@ -33,4 +33,4 @@ health-81plus=El estado de salud del proyecto supera el 80%. Puedes situar el ra health-00to20=El estado de salud del proyecto es inferior al 20%. Puedes situar el rat\u00F3n sobre el icono para ver una explicaci\u00F3n detallada. health-41to60=El estado de salud del proyecto est\u00E1 entre el 40% y el 60%. Puedes situar el rat\u00F3n sobre el icono para ver una explicaci\u00F3n detallada. health-21to40=El estado de salud del proyecto est\u00E1 entre el 20% y el 40%. Puedes situar el rat\u00F3n sobre el icono para ver una explicaci\u00F3n detallada. -health-61to80=El estado de salud del proyecto est\u00E1 entre el 80% y 80%. Puedes situar el rat\u00F3n sobre el icono para ver una explicaci\u00F3n detallada. +health-61to80=El estado de salud del proyecto est\u00E1 entre el 60% y 80%. Puedes situar el rat\u00F3n sobre el icono para ver una explicaci\u00F3n detallada. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_lt.properties index f16e98122a91da6e819aee4cd1e4e8ff87c54d42..6321019b97365973c86d34b6f57784f82fc76c1f 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_lt.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_lt.properties @@ -1,3 +1,14 @@ -# This file is under the MIT License by authors - -grey=Projektas dar nebuvo surinkin\u0117jamas, arba projektas i\u0161jungtas. +grey=Projektas dar nebuvo vykdomas, arba jis i\u0161jungtas. +grey_anime=Vyksta pirmas darbo vykdymas. +blue=Paskutinis vykdymas buvo s\u0117kmingas. +blue_anime=Paskutinis vykdymas buvo s\u0117kmingas. Vyksta naujas vykdymas. +yellow=Paskutinis vykdymas buvo s\u0117kmingas, bet nestabilus.\ + Tai pagrinde naudojama parodyti, kad nepavyko testai. +yellow_anime=Paskutinis vykdymas buvo s\u0117kmingas, bet nestabilus. Vyksta naujas vykdymas. +red=Paskutinis vykdymas visi\u0161kai nepavyko. +red_anime=Paskutinis vykdymas visi\u0161kai nepavyko. Vyksta naujas vykdymas. +health-81plus=Projekto sveikata vir\u0161 80%. Galite u\u017evesti pel\u0119 vir\u0161 projekto piktogramos detalesniam paai\u0161kinimui. +health-61to80=Projekto sveikata vir\u0161 60% ir \u017eemiau 80%. Galite u\u017evesti pel\u0119 vir\u0161 projekto piktogramos detalesniam paai\u0161kinimui. +health-41to60=Projekto sveikata vir\u0161 40% ir \u017eemiau 60%. Galite u\u017evesti pel\u0119 vir\u0161 projekto piktogramos detalesniam paai\u0161kinimui. +health-21to40=Projekto sveikata vir\u0161 20% ir \u017eemiau 40%. Galite u\u017evesti pel\u0119 vir\u0161 projekto piktogramos detalesniam paai\u0161kinimui. +health-00to20=Projekto sveikata \u017eemiau 20%. Galite u\u017evesti pel\u0119 vir\u0161 projekto piktogramos detalesniam paai\u0161kinimui. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_pl.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_pl.properties index 3e072ee7641986b9668a374d67486eb8b376c406..5b008064d984b2acfa8c1ca124d8acc08d5bce45 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/legend_pl.properties +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_pl.properties @@ -1,10 +1,15 @@ # This file is under the MIT License by authors -blue=Ostatnie budowanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie. -blue_anime=Ostatnie budowanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie. Nowa wersja jest w trakcie budowy. -grey=Projekt nie zosta\u0142 dotychczas zbudowany lub jest wy\u0142\u0105czony. -grey_anime=Trwa pierwsze budowanie projektu. -red=Ostatnia wgrywka nie powiod\u0142a si\u0119. -red_anime=Ostatnia wgrywka nie powiod\u0142a si\u0119. Nowa wersja jest w trakcie budowy. -yellow=Ostatnie budowanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie, lecz wersja jest niestabilna. To oznaczenie stosowane jest dla projekt\u00F3w, w kt\u00F3rych testy zako\u0144czy\u0142y si\u0119 niepowodzeniem. -yellow_anime=Ostatnie budowanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie, lecz wersja jest niestabilna. Nowa wersja jest w trakcie budowy. +blue=Ostatnie zadanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie. +blue_anime=Ostatnie zadanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie. Nowa wersja jest w trakcie budowy. +grey=Zadanie nie zosta\u0142o dotychczas zako\u0144czone lub jest wy\u0142\u0105czony. +grey_anime=Trwa pierwsze zadanie projektu. +red=Ostatnie zadanie projektu nie powiod\u0142o si\u0119. +red_anime=Ostatnie zadanie projektu nie powiod\u0142o si\u0119. Nowa wersja jest w trakcie budowy. +yellow=Ostatnie zadanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie, lecz wersja jest niestabilna. To oznaczenie stosowane jest dla projekt\u00F3w, w kt\u00F3rych testy zako\u0144czy\u0142y si\u0119 niepowodzeniem. +yellow_anime=Ostatnie zadanie projektu zako\u0144czy\u0142o si\u0119 pomy\u015Blnie, lecz wersja jest niestabilna. Nowa wersja jest w trakcie budowy. +health-81plus=Budowanie zako\u0144czone pomy\u015Blnie w ponad 80 procent przypadk\u00F3w. Przesu\u0144 myszk\u0119 nad ikon\u0119 projektu, aby sprawdzi\u0107 szczeg\u00F3\u0142y. +health-61to80=Budowanie zako\u0144czone pomy\u015Blnie pomi\u0119dzy 60 a 80 procent przypadk\u00F3w. Przesu\u0144 myszk\u0119 nad ikon\u0119 projektu, aby sprawdzi\u0107 szczeg\u00F3\u0142y. +health-41to60=Budowanie zako\u0144czone pomy\u015Blnie pomi\u0119dzy 40 a 60 procent przypadk\u00F3w. Przesu\u0144 myszk\u0119 nad ikon\u0119 projektu, aby sprawdzi\u0107 szczeg\u00F3\u0142y. +health-21to40=Budowanie zako\u0144czone pomy\u015Blnie pomi\u0119dzy 20 a 40 procent przypadk\u00F3w. Przesu\u0144 myszk\u0119 nad ikon\u0119 projektu, aby sprawdzi\u0107 szczeg\u00F3\u0142y. +health-00to20=Budowanie zako\u0144czone pomy\u015Blnie w poni\u017Cej 20 procent przypadk\u00F3w. Przesu\u0144 myszk\u0119 nad ikon\u0119 projektu, aby sprawdzi\u0107 szczeg\u00F3\u0142y. diff --git a/core/src/main/resources/jenkins/model/Jenkins/legend_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/legend_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..3397c9f26a67e367228f2e81b24e2d31775fbd6c --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/legend_sr.properties @@ -0,0 +1,20 @@ +# This file is under the MIT License by authors + +grey=\u041F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043D\u0438\u0458\u0435 \u043F\u0440\u0435 \u0431\u0438\u0458\u043E \u0438\u0437\u0433\u0440\u0430\u0452\u0435\u043D, \u0438\u043B\u0438 \u0458\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0435\u043D. +grey_anime=\u041F\u0440\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443 +blue=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0431\u0438\u043B\u0430 \u0443\u0441\u043F\u0435\u0448\u043D\u0430 +blue_anime=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0431\u0438\u043B\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430. \u041D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443. +yellow=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0430\u043B\u0438 \u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430. \u041D\u0430\u0458\u0447\u0435\u0448\u045B\u0435 \u0441\u0435 \u0442\u043E \u0434\u0435\u0448\u0430\u0432\u0430 \u0437\u0431\u043E\u0433 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0438\u043C\u0430 \u043F\u0440\u0438\u043B\u0438\u043A\u043E\u043C \u0442\u0435\u0441\u0442\u0438\u0440\u0430\u045A\u0430. +yellow_anime=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u0430 \u0430\u043B\u0438 \u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430. \u041D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443. +red=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430. +red_anime=\u0417\u0430\u0434\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430. \u041D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443. +health-81plus=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u043F\u0440\u0435\u043A\u043E 80%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-61to80=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 60 \u0438 80%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-41to60=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 40 \u0438 60%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-21to40=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 20 \u0438 40%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-00to20=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0441\u043F\u043E\u0434 20%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-00to19=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 0 \u0438 20%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-20to39=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 20 \u0438 40%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-40to59=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 40 \u0438 60%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-60to79=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u0438\u0437\u043C\u0435\u0452\u0443 60 \u0438 80%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. +health-80plus=\u0417\u0434\u0440\u0430\u0432\u0459\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 \u0458\u0435 \u043F\u0440\u0435\u043A\u043E 80%. \u041F\u0440\u0438\u0432\u0443\u0446\u0438\u0442\u0435 \u043C\u0438\u0448 \u043F\u0440\u0435\u043A\u043E \u045A\u0435\u043D\u0435 \u0438\u043A\u043E\u043D\u0438\u0446\u0435 \u0437\u0430 \u0434\u0435\u0442\u0430\u0459\u043D\u0438\u0458\u0438 \u043E\u043F\u0438\u0441. diff --git a/core/src/main/resources/jenkins/model/Jenkins/load-statistics_bg.properties b/core/src/main/resources/jenkins/model/Jenkins/load-statistics_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..9d46fdd58162847c762eb28160906fdfedf9b41c --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/load-statistics_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Load\ Statistics=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0430 \u043d\u0430\u0442\u043e\u0432\u0430\u0440\u0432\u0430\u043d\u0435\u0442\u043e diff --git a/core/src/main/resources/jenkins/model/Jenkins/load-statistics_lt.properties b/core/src/main/resources/jenkins/model/Jenkins/load-statistics_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..780e7508931b3fd87a7109e260992dc03d9557fc --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/load-statistics_lt.properties @@ -0,0 +1 @@ +Load\ Statistics=Apkrovos statistika diff --git a/core/src/main/resources/jenkins/model/Jenkins/load-statistics_sr.properties b/core/src/main/resources/jenkins/model/Jenkins/load-statistics_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..8c5dc1f569c0f039b1e16def515786c14bf05071 --- /dev/null +++ b/core/src/main/resources/jenkins/model/Jenkins/load-statistics_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Load\ Statistics=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435 \u043E \u043E\u043F\u0442\u0435\u0440\u0435\u045B\u0435\u045A\u0443 diff --git a/core/src/main/resources/jenkins/model/Jenkins/login.jelly b/core/src/main/resources/jenkins/model/Jenkins/login.jelly index a5f68b1178875730d3c1618d2d17ba09d11a87e7..cb4ed08319326802fe45af74cd784ba73e6901c0 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/login.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/login.jelly @@ -24,6 +24,11 @@ THE SOFTWARE. + + + + + @@ -35,7 +40,7 @@ THE SOFTWARE. - + @@ -70,4 +75,6 @@ THE SOFTWARE. + + diff --git a/core/src/main/resources/jenkins/model/Jenkins/loginError.jelly b/core/src/main/resources/jenkins/model/Jenkins/loginError.jelly index 6f7c2bfb2261dfa52c22e32b4e3d243f1b75dfef..a5a9549aca606774ed6612f90724a82228c75a71 100644 --- a/core/src/main/resources/jenkins/model/Jenkins/loginError.jelly +++ b/core/src/main/resources/jenkins/model/Jenkins/loginError.jelly @@ -27,6 +27,10 @@ THE SOFTWARE. + + + + + + + + + + + + + diff --git a/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_fr.properties b/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..058bb4c878a55a8fa20e142306eb7fa3e258da5c --- /dev/null +++ b/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_fr.properties @@ -0,0 +1,3 @@ +namePattern=Pattern du nom +description=Description +forceExistingJobs=Forcer les jobs existants \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_sr.properties b/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..20c36676bd023fe99b4fcade32cc4567dd774acf --- /dev/null +++ b/core/src/main/resources/jenkins/model/ProjectNamingStrategy/PatternProjectNamingStrategy/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +namePattern=\u0428\u0430\u0431\u043B\u043E\u043D \u0438\u043C\u0435\u043D\u0430 +description=\u041E\u043F\u0438\u0441 +forceExistingJobs=\u0444\u043E\u0440\u0441\u0438\u0440\u0430\u0458 \u043F\u043E\u0441\u0442\u043E\u0458\u0435\u045B\u0435 \u0437\u0430\u0434\u0430\u0442\u043A\u0435 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_sr.properties b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..54c6d656480817716ee4ede665c048b134b5d354 --- /dev/null +++ b/core/src/main/resources/jenkins/model/RunIdMigrator/UnmigrationInstruction/index_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Copied=\u0418\u0441\u043A\u043E\u043F\u0438\u0440\u0430\u043D\u043E diff --git a/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index.jelly b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index.jelly new file mode 100644 index 0000000000000000000000000000000000000000..fa755e5b76fb0c93eaaefd47783740dc44f51899 --- /dev/null +++ b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index.jelly @@ -0,0 +1,22 @@ + + + + + + + + + + + + +

    ${%Instance Identity}

    +

    ${%blurb}

    +

    ${%Public Key}

    +
    ${it.publicKey}
    +

    ${%Fingerprint}

    +
    ${it.fingerprint}
    +
    +
    +
    diff --git a/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index.properties b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index.properties new file mode 100644 index 0000000000000000000000000000000000000000..618080811c4c9f7f1dc9a2e1627c90c9463baf38 --- /dev/null +++ b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index.properties @@ -0,0 +1,3 @@ +blurb=Every Jenkins instance has a pair of public and private keys used to uniquely identify that Jenkins instance. \ + The public key is published in the X-Instance-Identity header for web requests against the Jenkins UI. \ + You can also find the key and the fingerprint of the key on this page. diff --git a/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_sr.properties b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..58733a6ee4db87e49d13667d3fc2bc3d3ab362d6 --- /dev/null +++ b/core/src/main/resources/jenkins/model/identity/IdentityRootAction/index_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Instance\ Identity=\u0418\u0434\u0435\u043D\u0442\u0438\u0442\u0435\u0442 \u0438\u043D\u0441\u0442\u0430\u043D\u0446\u0435 +blurb=\u0421\u0432\u0430\u043A\u0430 \u0438\u043D\u0441\u0442\u0430\u043D\u0446\u0430 Jenkins-\u0430 \u0438\u043C\u0430 \u043F\u0430\u0440 \u043E\u0434 \u0458\u0430\u0432\u043D\u0435 \u0438 \u043F\u0440\u0438\u0432\u0430\u0442\u043D\u0435 \u043A\u0459\u0443\u0447\u0435\u0432\u0435 \u043A\u043E\u0458\u0435 \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0443\u0458\u0443 \u0442\u0443 \u043C\u0430\u0448\u0438\u043D\u0443. \ + \u0408\u0430\u0432\u043D\u0438 \u043A\u0459\u0443\u0447 \u0441\u0435 \u043F\u0440\u0438\u043A\u0430\u0437\u0443\u0458\u0435 X-Instance-Identity header \u043D\u0430 \u0432\u0435\u0431-\u0437\u0430\u0445\u0442\u0435\u0432\u0438\u043C\u0430 \u043F\u0440\u0435\u043C\u0430 Jenkins UI.\ + \u041C\u043E\u0436\u0435 \u0441\u0435 \u0438\u0441\u0442\u043E \u043D\u0430\u045B\u0438 \u043A\u0459\u0443\u0447 \u0438 \u0434\u0438\u0433\u0438\u0442\u0430\u043B\u0430\u043D \u043E\u0442\u0438\u0441\u0430\u043A \u043A\u0459\u0443\u0447\u0430 \u043D\u0430 \u043E\u0432\u043E\u0458 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0438. +Public\ Key=\u0408\u0430\u0432\u043D\u0438 \u043A\u0459\u0443\u0447 +Fingerprint=\u0414\u0438\u0433\u0438\u0442\u0430\u043B\u043D\u0438 \u043E\u0442\u0438\u0441\u0430\u043A diff --git a/core/src/main/resources/jenkins/model/item_category/Messages.properties b/core/src/main/resources/jenkins/model/item_category/Messages.properties new file mode 100644 index 0000000000000000000000000000000000000000..b0aac4f438c9cd0dc093467b0ec72c56e97ddea6 --- /dev/null +++ b/core/src/main/resources/jenkins/model/item_category/Messages.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Copyright (c) 2016, CloudBees, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Uncategorized.DisplayName=Uncategorized +Uncategorized.Description=Item types that have not yet been categorized by their plugin maintainer. +StandaloneProjects.DisplayName=Standalone Projects +StandaloneProjects.Description=Create projects with a self-contained configuration and history. These projects can be at the top-level or grouped within folders. +NestedProjects.DisplayName=Nested Projects +NestedProjects.Description=Create project categories or project hierarchies with folders. Folders can be created manually or automatically based on repositories. diff --git a/core/src/main/resources/jenkins/model/item_category/Messages_sr.properties b/core/src/main/resources/jenkins/model/item_category/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..78be22c9781c814e3a66613e91f74f16627d8cdb --- /dev/null +++ b/core/src/main/resources/jenkins/model/item_category/Messages_sr.properties @@ -0,0 +1,8 @@ +# This file is under the MIT License by authors + +Uncategorized.DisplayName=\u041D\u0435\u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0441\u0430\u043D\u043E +Uncategorized.Description=\u0412\u0440\u0441\u0442\u0435 \u0441\u0442\u0430\u0432\u043A\u0430 \u043A\u043E\u0458\u0435 \u043D\u0438\u0441\u0443 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0441\u0430\u043D\u0438 \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 \u043E\u0434\u0440\u0436\u0438\u0432\u0430\u0447\u0430 \u043C\u043E\u0434\u0443\u043B\u0435. +StandaloneProjects.DisplayName=\u0421\u0430\u043C\u043E\u0441\u0442\u0430\u043B\u043D\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 +StandaloneProjects.Description=\u041A\u0440\u0435\u0438\u0440\u0430\u0458\u0442\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 \u0441\u0430 \u0441\u0430\u043C\u043E\u0441\u0442\u0430\u043B\u043D\u0438\u043C \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0430\u043C\u0430 \u0438 \u0438\u0441\u0442\u043E\u0440\u0438\u0458\u043E\u043C. \u041E\u0432\u0430\u043A\u0432\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u043D\u0430 \u043D\u0430\u0458\u0432\u0438\u0448\u0435\u043C \u043D\u0438\u0432\u043E\u0443 \u0438\u043B\u0438 \u0433\u0440\u0443\u043F\u0438\u0441\u0430\u043D\u0438 \u0444\u043E\u043B\u0434\u0435\u0440\u0438\u043C\u0430. +NestedProjects.DisplayName=\u041F\u043E\u0434\u0440\u0435\u0452\u0435\u043D\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 +NestedProjects.Description=\u041A\u0440\u0435\u0438\u0440\u0430\u0458\u0442\u0435 \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u0458\u0435 \u0438\u043B\u0438 \u0445\u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0458\u0435 \u043F\u043E\u043C\u043E\u045B\u0443 \u0444\u043E\u043B\u0434\u0435\u0440\u0438\u043C\u0430, \u043A\u043E\u0458\u0438 \u043C\u043E\u0433\u0443 \u0431\u0438\u0442\u0438 \u0440\u0443\u0447\u043D\u043E \u0438\u043B\u0438 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E \u043A\u0440\u0435\u0438\u0440\u0430\u043D\u0438 \u043F\u0440\u0435\u043C\u0430 \u0441\u0430\u0447\u0443\u0432\u0430\u043D\u0438\u043C. diff --git a/core/src/main/resources/jenkins/model/queue/CompositeCauseOfBlockage/summary.jelly b/core/src/main/resources/jenkins/model/queue/CompositeCauseOfBlockage/summary.jelly new file mode 100644 index 0000000000000000000000000000000000000000..76fc4313b05a5a028c04bdeccb6021ac5d05cac7 --- /dev/null +++ b/core/src/main/resources/jenkins/model/queue/CompositeCauseOfBlockage/summary.jelly @@ -0,0 +1,32 @@ + + + + + + + ; + + + diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config_lt.properties b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..db5473988c149953fc8d335055d63854096402da --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config_lt.properties @@ -0,0 +1 @@ +File\ path=Failo kelias diff --git a/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config_sr.properties b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..79580f19b1649b276f2ec7ab73317087f6a9c22d --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/FilePathGlobalSettingsProvider/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +File\ path=\u041F\u0443\u0442 \u0434\u043E \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 diff --git a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/config_lt.properties b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/config_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..db5473988c149953fc8d335055d63854096402da --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/config_lt.properties @@ -0,0 +1 @@ +File\ path=Failo kelias diff --git a/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/config_sr.properties b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..79580f19b1649b276f2ec7ab73317087f6a9c22d --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/FilePathSettingsProvider/config_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +File\ path=\u041F\u0443\u0442 \u0434\u043E \u0434\u0430\u0442\u043E\u0442\u0435\u043A\u0435 diff --git a/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config_fr.properties b/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..922175ad863c56dc97f0fcd40e7054dad8e2acc0 --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config_fr.properties @@ -0,0 +1,3 @@ +Maven\ Configuration=Configuration Maven +Default\ settings\ provider=Fournisseur de r\u00e9glages par d\u00e9faut +Default\ global\ settings\ provider=Fournisseur de r\u00e9glages globaux par d\u00e9faut \ No newline at end of file diff --git a/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config_sr.properties b/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..56881420328f1f61ebe9a6639d8a4bc1847b7478 --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/GlobalMavenConfig/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Maven\ Configuration=\u041F\u043E\u0441\u0442\u0430\u0432\u0438 Maven +Default\ settings\ provider=\u041F\u0440\u043E\u0432\u0430\u0458\u0434\u0435\u0440 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438\u0445 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0438\u043C\u0430 +Default\ global\ settings\ provider=\u041F\u0440\u043E\u0432\u0430\u0458\u0434\u0435\u0440 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0438\u0445 \u0433\u043B\u043E\u0431\u0430\u043B\u043D\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0438\u043C\u0430 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/mvn/Messages_bg.properties b/core/src/main/resources/jenkins/mvn/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..be7a195a39f728800e32198e28af8a84546fd3d0 --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/Messages_bg.properties @@ -0,0 +1,30 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +DefaultSettingsProvider.DisplayName=\ + \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 maven +DefaultGlobalSettingsProvider.DisplayName=\ + \u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430 maven +FilePathGlobalSettingsProvider.DisplayName=\ + \u0413\u043b\u043e\u0431\u0430\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u0442 \u0444\u0430\u0439\u043b\u043e\u0432\u0430\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 +FilePathSettingsProvider.DisplayName=\ + \u0424\u0430\u0439\u043b \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432\u044a\u0432 \u0444\u0430\u0439\u043b\u043e\u0432\u0430\u0442\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 diff --git a/core/src/main/resources/jenkins/mvn/Messages_fr.properties b/core/src/main/resources/jenkins/mvn/Messages_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e97f3b9e29a168a6fd31e0ee228f36d39c0352c9 --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/Messages_fr.properties @@ -0,0 +1,4 @@ +DefaultSettingsProvider.DisplayName=Utiliser les r\u00e9glages Maven par d\u00e9faut +DefaultGlobalSettingsProvider.DisplayName=Utiliser les r\u00e9glages globaux Maven par d\u00e9faut +FilePathGlobalSettingsProvider.DisplayName=Fichier de r\u00e9glages globaux Maven sur le syst\u00e8me de fichiers +FilePathSettingsProvider.DisplayName=Fichier de r\u00e9glages Maven sur le syst\u00e8me de fichiers \ No newline at end of file diff --git a/core/src/main/resources/jenkins/mvn/Messages_lt.properties b/core/src/main/resources/jenkins/mvn/Messages_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..bfe228203a988e3de3abc7ce2704b2d61b2b861b --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/Messages_lt.properties @@ -0,0 +1,4 @@ +DefaultSettingsProvider.DisplayName=Naudoti numatytuosius maven nustatymus +DefaultGlobalSettingsProvider.DisplayName=Naudoti numatytuosius maven globalius nustatymus +FilePathGlobalSettingsProvider.DisplayName=Galobali\u0173 nustatym\u0173 failas fail\u0173 sistemoje +FilePathSettingsProvider.DisplayName=Nustatym\u0173 failas fail\u0173 sistemoje diff --git a/core/src/main/resources/jenkins/mvn/Messages_sr.properties b/core/src/main/resources/jenkins/mvn/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..20d33fc6688ae333d4c0aa4bca5af284241ea5a8 --- /dev/null +++ b/core/src/main/resources/jenkins/mvn/Messages_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +DefaultSettingsProvider.DisplayName=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0430 maven \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +DefaultGlobalSettingsProvider.DisplayName=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0434\u043D\u0430 \u0433\u043B\u043E\u0431\u0430\u043B\u043D\u0430 maven \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +FilePathGlobalSettingsProvider.DisplayName=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u0433\u043B\u043E\u0431\u0430\u043B\u043D\u0438\u043C \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0430 \u0434\u0438\u0441\u043A\u0430 +FilePathSettingsProvider.DisplayName=\u0414\u0430\u0442\u043E\u0442\u0435\u043A\u0430 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 \u0441\u0430 \u0434\u0438\u0441\u043A\u0430 diff --git a/core/src/main/resources/jenkins/security/ApiTokenProperty/config_sr.properties b/core/src/main/resources/jenkins/security/ApiTokenProperty/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e7ad742d80358e0000bb255996ec30a116a3532c --- /dev/null +++ b/core/src/main/resources/jenkins/security/ApiTokenProperty/config_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Show\ API\ Token=\u041F\u0440\u0438\u043A\u0430\u0436\u0438 \u0410\u041F\u0418 \u0422\u043E\u043A\u0435\u043D +API\ Token=\u0410\u041F\u0418 \u0422\u043E\u043A\u0435\u043D +Change\ API\ Token=\u0423\u0440\u0435\u0434\u0438 \u0410\u041F\u0418 \u0422\u043E\u043A\u0435\u043D diff --git a/core/src/main/resources/jenkins/security/Messages.properties b/core/src/main/resources/jenkins/security/Messages.properties index fc71097d03319ea6664c5325a8535c65bd252c24..e09dca3e79758277e4fc1be3e1a943366d9053c2 100644 --- a/core/src/main/resources/jenkins/security/Messages.properties +++ b/core/src/main/resources/jenkins/security/Messages.properties @@ -21,5 +21,7 @@ # THE SOFTWARE. ApiTokenProperty.DisplayName=API Token -ApiTokenProperty.ChangeToken.Success=
    Updated
    +ApiTokenProperty.ChangeToken.TokenIsHidden=Token is hidden +ApiTokenProperty.ChangeToken.Success=
    Updated. See the new token in the field above
    +ApiTokenProperty.ChangeToken.SuccessHidden=
    Updated. You need to login as the user to see the token
    RekeySecretAdminMonitor.DisplayName=Re-keying \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/Messages_bg.properties b/core/src/main/resources/jenkins/security/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..01bff534b4ef4f5b395855d1fb85d37eff2661c3 --- /dev/null +++ b/core/src/main/resources/jenkins/security/Messages_bg.properties @@ -0,0 +1,33 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ApiTokenProperty.DisplayName=\ + \u041d\u0438\u0437 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0437\u0430 API +ApiTokenProperty.ChangeToken.TokenIsHidden=\ + \u041d\u0438\u0437\u044a\u0442 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0435 \u0441\u043a\u0440\u0438\u0442 +ApiTokenProperty.ChangeToken.Success=\ +
    \u041f\u0440\u043e\u043c\u0435\u043d\u0435\u043d. \u041d\u043e\u0432\u0438\u044f\u0442 \u043d\u0438\u0437 \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0435 \u0432 \u043f\u043e\u043b\u0435\u0442\u043e \u043e\u0442\u0433\u043e\u0440\u0435
    +ApiTokenProperty.ChangeToken.SuccessHidden=\ +
    \u041f\u0440\u043e\u043c\u0435\u043d\u0435\u043d. \u0422\u0440\u044f\u0431\u0432\u0430 \u0434\u0430 \u0432\u043b\u0435\u0437\u0435\u0442\u0435 \u043a\u0430\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f, \u0437\u0430 \u0434\u0430 \u0432\u0438\u0434\u0438\u0442\u0435 \u043d\u0438\u0437\u0430 \u0437\u0430\ + \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f
    +RekeySecretAdminMonitor.DisplayName=\ + \u0421\u044a\u0437\u0434\u0430\u0432\u0430\u043d\u0435 \u043d\u0430 \u043d\u043e\u0432 \u043a\u043b\u044e\u0447 diff --git a/core/src/main/resources/jenkins/security/Messages_sr.properties b/core/src/main/resources/jenkins/security/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5e74fc20dd234d29c9f83993deee986651c8ea7b --- /dev/null +++ b/core/src/main/resources/jenkins/security/Messages_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +ApiTokenProperty.DisplayName=\u0422\u043E\u043A\u0435\u043D \u0437\u0430 \u0410\u041F\u0418 +ApiTokenProperty.ChangeToken.TokenIsHidden=\u0422\u043E\u043A\u0435\u043D \u0458\u0435 \u0441\u0430\u043A\u0440\u0438\u0432\u0435\u043D +ApiTokenProperty.ChangeToken.Success=
    \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u043E. \u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0435 \u043D\u043E\u0432\u0438 \u0442\u043E\u043A\u0435\u043D \u043F\u0440\u0438\u043A\u0430\u0437\u0430\u043D \u0438\u0437\u043D\u0430\u0434.
    +ApiTokenProperty.ChangeToken.SuccessHidden=
    \u0410\u0436\u0443\u0440\u0438\u0440\u0430\u043D\u043E. \u041C\u043E\u0440\u0430\u0442\u0435 \u0441\u0435 \u043F\u0440\u0438\u0458\u0430\u0432\u0438\u0442\u0438 \u043A\u0430\u043E \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u043A \u0434\u0430 \u0431\u0438 \u043C\u043E\u0433\u043B\u0438 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u0438 \u0442\u043E\u043A\u0435\u043D.
    +RekeySecretAdminMonitor.DisplayName=\u041F\u043E\u043D\u043E\u0432\u043E \u0445\u0435\u0448\u0438\u0440\u0430\u045A\u0435 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..90928beebd07034481842218da527cae63a5171e --- /dev/null +++ b/core/src/main/resources/jenkins/security/RekeySecretAdminMonitor/message_sr.properties @@ -0,0 +1,19 @@ +# This file is under the MIT License by authors + +pleaseRekeyAsap=\ + \u0417\u0431\u043E\u0433 \u043E\u0442\u0440\u0438\u0432\u0435\u043D\u0435 \u0440\u0430\u045A\u0438\u0432\u043E\u0441\u0442\u0438, \u043C\u043E\u0440\u0430\u043C\u043E \ + \u043F\u0440\u043E\u043C\u0435\u043D\u0438\u0442\u0438 \u043A\u0459\u0443\u0447 \u0437\u0430 \u0448\u0438\u0444\u0440\u043E\u0432\u0430\u045A\u0435 \u0442\u0430\u0458\u043D\u0438 \u0434\u0430 \u0434\u0438\u0441\u043A\u0443. \ + \u0422\u0430\u0458 \u043F\u0440\u043E\u0446\u0435\u0441 \u043F\u0440\u0435\u0442\u0440\u0430\u0436\u0438 \u0432\u0435\u043B\u0438\u043A\u0438 \u0434\u0435\u043E \u0432\u0430\u0448\u0435\u0433 $JENKINS_HOME ({0}) \u0434\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C\u0430, \ + \u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u0438\u0437\u0433\u0440\u0430\u0447\u0443\u043D\u0430 \u0445\u0435\u0448 \u0437\u0430 \u043F\u0440\u043E\u043D\u0430\u0452\u0435\u043D\u0435 \u043F\u043E\u0434\u0430\u0442\u043A\u0435, \u0448\u0442\u043E \u043C\u043E\u0436\u0435 \u043F\u0440\u0438\u043B\u0438\u0447\u043D\u043E \u0434\u0443\u0433\u043E \u0442\u0440\u0430\u0458\u0430\u0442\u0438. \ + \u041F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u043E\u0432\u0430\u0458 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0433\u0434\u0435 \u0441\u0435 \u043F\u0438\u0448\u0435 \u043E \u0432\u0438\u0448\u0435 \u0438\u043C\u043F\u043B\u0438\u043A\u0430\u0446\u0438\u0458\u0430 \u0438 \u0434\u0440\u0443\u0433\u0430\u0447\u0438\u0458\u0435 \u043D\u0430\u0447\u0438\u043D\u0435 \ + \u041E\u0432\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0458\u0430 \u0441\u0435 \u043C\u043E\u0436\u0435 \u0431\u0435\u0437\u0431\u0435\u0434\u043D\u043E \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u0443 \u043F\u043E\u0437\u0430\u0434\u0438\u043D\u0438, \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043E\u0431\u0430\u0437\u0440\u0438\u0432\u0438 \u043A\u043E\u0440\u0438\u0441\u043D\u0438\u0446\u0438 \ + \u0431\u0438 \u043C\u043E\u0433\u043B\u0438 \u043D\u0430\u043F\u0440\u0430\u0432\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0435 \u043A\u043E\u043F\u0438\u0458\u0435 \u043F\u043E\u0434\u0430\u0446\u0438\u043C\u0430. + +rekeyInProgress=\u041F\u043E\u043D\u043E\u0432\u043E \u0445\u0435\u0448\u0438\u0440\u0430\u045A\u0435 \u0458\u0435 \u0443 \u0442\u043E\u043A\u0443. \u041C\u043E\u0436\u0435\u0442\u0435 \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0438 \u0436\u0443\u0440\u043D\u0430\u043B. + +rekeySuccessful=\ + Secrets in your $JENKINS_HOME \u0458\u0435 \u0443\u0441\u043F\u0435\u0448\u043D\u043E \u0438\u0437\u0445\u0435\u0448\u0438\u0440\u0430\u043D\u043E. \ + \u041C\u043E\u043B\u0438\u043C\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B, \u043F\u043E\u0442\u0432\u0440\u0434\u0438\u0442\u0435, \u0438 \u043D\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u0435 \u0438\u043B\u0438 \u043F\u043E\u043D\u043E\u0432\u043E \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435. + +rekeyHadProblems=\ + \u041F\u043E\u043D\u043E\u0432\u043E \u0445\u0435\u0448\u0438\u0440\u0430\u045A\u0435 \u0458\u0435 \u0433\u043E\u0442\u043E\u0432\u043E, \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u0431\u0438\u043B\u043E \u0458\u0435 \u0433\u0440\u0435\u0448\u0430\u043A\u0430. \u041C\u043E\u043B\u0438\u043C\u043E \u043F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458\u0442\u0435 \u0436\u0443\u0440\u043D\u0430\u043B. \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties index 95377db31494e0fa361c9991a0fee8bdb9c63936..7b49ac2619017a6e9e4d5ebf998c279308067972 100644 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties +++ b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message.properties @@ -1,2 +1,2 @@ -blurb=Jenkins has rejected some commands from slaves, because we are unsure if it is open for slaves to execute, \ +blurb=Jenkins has rejected some commands from agents, because we are unsure if it is open for agents to execute, \ but this rejection has probably broken some builds. You should examine the situation to see if they should be whitelisted. \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties index dd8765f735c1568efa2872ecee9bafa307791cac..25a215256fc0346491e80ab32c70e4560ee3cd9c 100644 --- a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties +++ b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_pt_BR.properties @@ -20,9 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Jenkins has rejected some commands from slaves, because we are unsure if it is open for slaves to execute, \ -# but this rejection has probably broken some builds. You should examine the situation to see if they should be whitelisted. -blurb=Jenkins rejeitou alguns comandos dos slaves, porque no tem certeza se est disponvel para chamar os slaves, \ - e essa rejeio provavelmente quebrou alguns builds. Voc deve examinar a situao e avaliar se est Ok. Examine= Dismiss= diff --git a/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_sr.properties b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e2deed27ee8912418fdd2df2e05e9239d7907bd1 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/AdminCallableMonitor/message_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Examine=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0458 +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 +blurb=Jenkins \u0458\u0435 \u043E\u0434\u0431\u0438\u0458\u043E \u043D\u0435\u043A\u0435 \u0430\u0433\u0435\u043D\u0442\u043E\u0432\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0435, \u0437\u0430\u0448\u0442\u043E \u043D\u0438\u0458\u0435 \u0458\u0430\u0441\u043D\u043E \u0430\u043A\u043E \u0458\u0435 \u0434\u043E\u0437\u0432\u043E\u0459\u0435\u043D\u043E \u0430\u0433\u0435\u043D\u0442\u0438\u043C\u0430, \ + \u043C\u0435\u0452\u0443\u0442\u0438\u043C \u043E\u0432\u0430 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u0458\u0430 \u0458\u0435 \u0432\u0435\u0440\u043E\u0432\u0430\u0442\u043D\u043E \u043F\u0440\u0435\u043A\u0438\u043D\u0443\u043B\u0430 \u043D\u0435\u043A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430. \u0420\u0430\u0437\u043C\u0438\u0441\u043B\u0438\u0442\u0435 \u0430\u043A\u043E \u0431\u0438 \u043C\u043E\u0433\u043E \u0434\u043E\u0437\u0432\u043E\u043B\u0438\u0442\u0438 \u0430\u0433\u0435\u043D\u0442\u0438\u043C\u0430. diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly index 62dbc88621143584e0f9dceea3ac85d100ea37fc..d4c181f80fda2aa43b65852acf78be29f51b0b7a 100644 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly +++ b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index.jelly @@ -26,14 +26,14 @@ THE SOFTWARE. -

    ${%Slave → Master Access Control}

    +

    ${%Agent → Master Access Control}

    - Jenkins master is now more strict about what commands its slaves can send to the master. + Jenkins master is now more strict about what commands its agents can send to the master. Unfortunately, this prevents some plugins from functioning correctly, as those plugins do not - specify which commands are open for slaves to execute and which ones are not. + specify which commands are open for agents to execute and which ones are not. While plugin developers work on updating this, - as an administrator, you can mark commands as OK for slaves to execute (aka "whitelisting".) + as an administrator, you can mark commands as OK for agents to execute (aka "whitelisting".)

    Please see the discussion of this feature to @@ -41,8 +41,8 @@ THE SOFTWARE.
    - The slave → master access control subsystem is currently disabled. - This is unsafe if you have slaves from other less trusted people. + The agent → master access control subsystem is currently disabled. + This is unsafe if you have agents from other less trusted people. You can put it back on from Global Security Configuration UI
    @@ -50,7 +50,7 @@ THE SOFTWARE.

    Currently Whitelisted Commands

    - The following commands are currently whitelisted for slaves to execute them on the master. + The following commands are currently whitelisted for agents to execute them on the master. Type in any fully-qualified class names to white list them:

    @@ -60,8 +60,8 @@ THE SOFTWARE.

    Currently Rejected Commands

    - Slaves have attempted to use the following functionalities but the plugins that implement them - did not specify whether they are usable from slaves or not. Check ones you want to whitelist: + Agents have attempted to use the following functionalities but the plugins that implement them + did not specify whether they are usable from agents or not. Check ones you want to whitelist:

      @@ -86,7 +86,7 @@ THE SOFTWARE.

      File Access Rules

      - The following rules control which part of $JENKINS_HOME can be access from slaves: + The following rules control which part of $JENKINS_HOME can be access from agents:

      diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties index 4b360251eb3569fc8ae93e88da0b54800f637f94..a4a88ca399f001980fc113132dc59144b43f3d8e 100644 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties +++ b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_ja.properties @@ -20,6 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Slave\ &\#8594;\ Master\ Access\ Control=\u30b9\u30ec\u30fc\u30d6 - \u30de\u30b9\u30bf\u9593 \u30a2\u30af\u30bb\u30b9\u5236\u5fa1 Whitelist=\u30db\u30ef\u30a4\u30c8\u30ea\u30b9\u30c8 Update=\u66f4\u65b0 diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties index 8ec4887e0ecc9cd7db2653157758908400ad7146..42d23f6efe164d5a375be47276ba267b115825db 100644 --- a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties +++ b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_pt_BR.properties @@ -20,6 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Slave\ &\#8594;\ Master\ Access\ Control=controle de acesso ao Master slave Whitelist= Update= diff --git a/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_sr.properties b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..605e8f9eda413db9aedff6a206b3087890c146ed --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/AdminWhitelistRule/index_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Whitelist= +Agent\ \u2192\ Master\ Access\ Control= +Update=\u0410\u0436\u0443\u0440\u0438\u0440\u0430\u0458 diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties index 7c847a2111d74b89d96fc92a2e3d3f55a32480fb..fe6e52c2b579164671b71a280806f8148ff1d976 100644 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties +++ b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message.properties @@ -1,2 +1,2 @@ -blurb=Slave to master security subsystem is currently off. \ +blurb=Agent to master security subsystem is currently off. \ Please read the documentation and consider turning it on. \ No newline at end of file diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties index 154336201bd04646cad69f657c2fd9871a729e60..9fcd4e14738e21f58175a55e8b450ffb33e71cf1 100644 --- a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties +++ b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_pt_BR.properties @@ -22,7 +22,5 @@ Examine= Dismiss= -# Slave to master security subsystem is currently off. \ # Please read the documentation and consider turning it on. -blurb=O slave para o master security subsystem est\u00e1 desligado. \ Por favor leia a documenta\u00e7\u00e3o e ligue novamente. diff --git a/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_sr.properties b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f92800a9ed9c8d08b5f41452de60ea74d284cca9 --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/MasterKillSwitchWarning/message_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Examine= +Dismiss=\u041E\u0442\u043A\u0430\u0436\u0438 +blurb=\u0421\u0438\u0441\u0442\u0435\u043C \u043E\u0431\u0435\u0437\u0431\u0435\u0436\u0438\u0432\u0430\u045A\u0430 \u0432\u0435\u0437\u043E\u043C \u0438\u0437\u043C\u0435\u0452\u0443 \u0430\u0433\u0435\u043D\u0442\u0430 \u0438 \u043C\u0430\u0441\u0442\u0435\u0440\u0430 \u0458\u0435 \u0438\u0441\u043A\u0459\u0443\u0447\u0435\u043D. \ + \u041C\u043E\u043B\u0438\u043C\u043E \u0432\u0430\u0441, \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0458\u0442\u0435 \u0434\u043E\u043A\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0458\u0443 \u0438 \u0443\u043A\u0459\u0443\u0447\u0438\u0442\u0435 \u0430\u043A\u043E \u0432\u0430\u043C \u0458\u0435 \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E. diff --git a/core/src/main/resources/jenkins/security/s2m/Messages.properties b/core/src/main/resources/jenkins/security/s2m/Messages.properties new file mode 100644 index 0000000000000000000000000000000000000000..25f919d28e4049c1280ba0a07d5f8330223f48bb --- /dev/null +++ b/core/src/main/resources/jenkins/security/s2m/Messages.properties @@ -0,0 +1,2 @@ +AdminCallableMonitor.DisplayName=Rejected Agent \u2192 Master Access Attempt +MasterKillSwitchWarning.DisplayName=Disabled Agent \u2192 Master Access Control diff --git a/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf b/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf index faa7cffa16235e5d7fc7ae7c9318d2cf52133086..c1883cc56295d1a4aa9940a04223fa989306a732 100644 --- a/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf +++ b/core/src/main/resources/jenkins/security/s2m/filepath-filter.conf @@ -36,5 +36,5 @@ allow create,mkdirs,read,stat,write /.+ # cobertura also writes out annotated sources to a dir under the job: allow create,mkdirs,read,stat,write /jobs/.+/cobertura.* -# all the other accesses that aren't specified here will be left upto other rules in this directory. +# all the other accesses that aren't specified here will be left up to other rules in this directory. # if no rules in those other files matches, then the access will be rejected. diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol/description.jelly b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol/description.jelly new file mode 100644 index 0000000000000000000000000000000000000000..d848342d48d194ad336aebbe55a2397ee493d251 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol/description.jelly @@ -0,0 +1,4 @@ + + + ${%Accepts connections from remote clients so that they can be used as additional build agents} + diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol/description_sr.properties b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol/description_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..040bfa046563def3f213fd3aed77809e076027ff --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol/description_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Accepts\ connections\ from\ remote\ clients\ so\ that\ they\ can\ be\ used\ as\ additional\ build\ agents=\u041F\u0440\u0438\u0445\u0432\u0430\u0442\u0430 \u0432\u0435\u0437\u0435 \u043E\u0434 \u043A\u043B\u0438\u0458\u0435\u043D\u0442\u0438\u043C\u0430 \u0434\u0430 \u0431\u0438 \u043C\u043E\u0433\u043B\u0438 \u0441\u0435 \u0443\u043F\u043E\u0442\u0440\u0435\u0431\u0438\u0442\u0438 \u043A\u0430\u043E \u0434\u043E\u0434\u0430\u0442\u043D\u0435 \u0430\u0433\u0435\u043D\u0442\u0435 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443. diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol2/description.jelly b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol2/description.jelly new file mode 100644 index 0000000000000000000000000000000000000000..b3c0c584443270b51fbf6a8d68cad9ed9c6e3375 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol2/description.jelly @@ -0,0 +1,4 @@ + + + ${%Extends the version 1 protocol by adding a per-client cookie, so that we can detect a reconnection from the agent and take appropriate action} + diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol2/description_sr.properties b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol2/description_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a073aa440e6928c7c92a1d0b0fff1103b3ad284d --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol2/description_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Extends\ the\ version\ 1\ protocol\ by\ adding\ a\ per-client\ cookie,\ so\ that\ we\ can\ detect\ a\ reconnection\ from\ the\ agent\ and\ take\ appropriate\ action=\u041D\u0430\u0434\u0433\u0440\u0430\u0452\u0443\u0458\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 1 \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B\u0430 \u0434\u043E\u0434\u0430\u0432\u0430\u045B\u0438 cookie \u0441\u0432\u0430\u043A\u043E\u043C \u043A\u043B\u0438\u0458\u0435\u043D\u0442\u0443, \u0448\u0442\u043E \u043E\u043C\u043E\u0433\u0443\u0458\u0443\u045B\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043F\u043E\u0432\u0435\u0437\u0438\u0432\u0430\u045A\u0435 \u0441\u0430 \u0430\u0433\u0435\u043D\u0442\u043E\u043C. diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol3/description.jelly b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol3/description.jelly new file mode 100644 index 0000000000000000000000000000000000000000..c052dfe335ebad1dd26214fe826cf02022197b42 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol3/description.jelly @@ -0,0 +1,4 @@ + + + ${%Extends the version 2 protocol by adding basic encryption but requires a thread per client} + diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol3/description_sr.properties b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol3/description_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f15cfe231992cb083d56eb06d61878446ae93993 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol3/description_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Extends\ the\ version\ 2\ protocol\ by\ adding\ basic\ encryption\ but\ requires\ a\ thread\ per\ client=\u041D\u0430\u0434\u0433\u0440\u0430\u0452\u0443\u0458\u0435 \u0432\u0435\u0440\u0437\u0438\u0458\u0443 2 \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B\u0430 \u0434\u043E\u0434\u0430\u0432\u0430\u0458\u0443\u045B\u0438 \u0448\u0438\u0444\u0440\u043E\u0432\u0430\u045A\u0435 (\u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E \u0458\u0435\u0434\u0430\u043D \u043D\u0438\u0437 \u0437\u0430 \u0441\u0432\u0430\u043A\u043E\u0433 \u043A\u043B\u0438\u0458\u0435\u043D\u0442\u0430) diff --git a/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.jelly b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.jelly new file mode 100644 index 0000000000000000000000000000000000000000..31c51e4ce9518b7bd35bba2ee1d69159e58c21a4 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/JnlpSlaveAgentProtocol4/description.jelly @@ -0,0 +1,4 @@ + + + ${%A TLS secured connection between the master and the agent performed by TLS upgrade of the socket.} + diff --git a/core/src/main/resources/jenkins/slaves/Messages.properties b/core/src/main/resources/jenkins/slaves/Messages.properties new file mode 100644 index 0000000000000000000000000000000000000000..7085843d8b73948c0b4827dc93ce0690acadae91 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/Messages.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Copyright 2016 Stephen Connolly +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +JnlpSlaveAgentProtocol.displayName=Java Web Start Agent Protocol/1 +JnlpSlaveAgentProtocol2.displayName=Java Web Start Agent Protocol/2 +JnlpSlaveAgentProtocol3.displayName=Java Web Start Agent Protocol/3 +JnlpSlaveAgentProtocol4.displayName=Java Web Start Agent Protocol/4 diff --git a/core/src/main/resources/jenkins/slaves/systemInfo/Messages_bg.properties b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..6c477fbf3eef705b8db42569d19c3c81424d6060 --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_bg.properties @@ -0,0 +1,30 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +SystemPropertySlaveInfo.DisplayName=\ + \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0437\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 +EnvVarsSlaveInfo.DisplayName=\ + \u041f\u0440\u043e\u043c\u0435\u043d\u043b\u0438\u0432\u0438 \u043d\u0430 \u0441\u0440\u0435\u0434\u0430\u0442\u0430 +ThreadDumpSlaveInfo.DisplayName=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0441\u0442\u0435\u043a\u043e\u0432\u0435 \u043d\u0430 \u043d\u0438\u0448\u043a\u0438\u0442\u0435 +ClassLoaderStatisticsSlaveInfo.DisplayName=\ + \u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0430 \u043d\u0430 \u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043e\u0442\u0434\u0430\u043b\u0435\u0447\u0435\u043d\u0438 \u043a\u043b\u0430\u0441\u043e\u0432\u0435 diff --git a/core/src/main/resources/jenkins/slaves/systemInfo/Messages_lt.properties b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_lt.properties index e3a8c972b9f7b6f290df07fc288aeb056de0c44e..2cc8fdaef1915ab559810f21686916ed4240364d 100644 --- a/core/src/main/resources/jenkins/slaves/systemInfo/Messages_lt.properties +++ b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_lt.properties @@ -1,4 +1,6 @@ # This file is under the MIT License by authors -EnvVarsSlaveInfo.DisplayName=Aplinkos kintamieji -SystemPropertySlaveInfo.DisplayName=Sistemos savyb\u0117s +ClassLoaderStatisticsSlaveInfo.DisplayName = Nutolusio klasi\u0173 \u012Fk\u0117l\u0117jo statistika +EnvVarsSlaveInfo.DisplayName = Aplinkos kintamieji +SystemPropertySlaveInfo.DisplayName = Sistemos savyb\u0117s +ThreadDumpSlaveInfo.DisplayName = Gijos informacija diff --git a/core/src/main/resources/jenkins/slaves/systemInfo/Messages_sr.properties b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e6738c3bfc378ce4020603545569e8713f3ce76e --- /dev/null +++ b/core/src/main/resources/jenkins/slaves/systemInfo/Messages_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +SystemPropertySlaveInfo.DisplayName=\u0421\u0438\u0441\u0442\u0435\u043C\u0441\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u043A\u0435 +EnvVarsSlaveInfo.DisplayName=\u041F\u0440\u043E\u043C\u0435\u043D\u0459\u0438\u0432\u0435 \u043E\u043A\u043E\u043B\u0438\u043D\u0435 +ThreadDumpSlaveInfo.DisplayName=\u0414\u0435\u043F\u043E\u043D\u0438\u0458a \u043D\u0438\u0442\u043E\u0432\u0430 +ClassLoaderStatisticsSlaveInfo.DisplayName=\u0421\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0435 \u0443\u0447\u0438\u0442\u0430\u045A\u0435 \u043A\u043B\u0430\u0441\u043E\u0432\u0430 \u0441\u0430 \u0434\u0430\u043B\u0435\u043A\u0430 diff --git a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy new file mode 100644 index 0000000000000000000000000000000000000000..1d95d69be7225b48527927c139b6d7c3042baae1 --- /dev/null +++ b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.groovy @@ -0,0 +1,44 @@ +package jenkins.tools.GlobalToolConfiguration + +import hudson.Functions +import hudson.model.Descriptor + +def f=namespace(lib.FormTagLib) +def l=namespace(lib.LayoutTagLib) +def st=namespace("jelly:stapler") + +l.layout(norefresh:true, permission:app.ADMINISTER, title:my.displayName) { + l.side_panel { + l.tasks { + l.task(icon:"icon-up icon-md", href:rootURL+'/', title:_("Back to Dashboard")) + l.task(icon:"icon-setting icon-md", href:"${rootURL}/manage", title:_("Manage Jenkins")) + } + } + l.main_panel { + h1 { + l.icon(class: 'icon-setting icon-xlg') + // TODO more appropriate icon + text(my.displayName) + } + + p() + div(class:"behavior-loading", _("LOADING")) + + f.form(method:"post",name:"config",action:"configure") { + Functions.getSortedDescriptorsForGlobalConfig(my.FILTER).each { Descriptor descriptor -> + set("descriptor",descriptor) + set("instance",descriptor) + f.rowSet(name:descriptor.jsonSafeClassName) { + st.include(from:descriptor, page:descriptor.globalConfigPage) + } + } + + f.bottomButtonBar { + f.submit(value:_("Save")) + f.apply(value:_("Apply")) + } + } + + st.adjunct(includes: "lib.form.confirm") + } +} diff --git a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.properties b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.properties new file mode 100644 index 0000000000000000000000000000000000000000..78874d14ee68d2e42323cdf17395462e4b0ceef4 --- /dev/null +++ b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index.properties @@ -0,0 +1,2 @@ +Back\ to\ Dashboard=Back to Dashboard +Manage\ Jenkins=Manage Jenkins \ No newline at end of file diff --git a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_fr.properties b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d5801fd6950a10fc7777caabf97fbdc27798da02 --- /dev/null +++ b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_fr.properties @@ -0,0 +1,4 @@ +Back\ to\ Dashboard=Retour au tableau de bord +Manage\ Jenkins=Administrer Jenkins +Save=Enregistrer +Apply=Appliquer \ No newline at end of file diff --git a/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_sr.properties b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0d6d81f5bc032d679c36858df30e23c43818902c --- /dev/null +++ b/core/src/main/resources/jenkins/tools/GlobalToolConfiguration/index_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Back\ to\ Dashboard=\u041D\u0430\u0437\u0430\u0434 \u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043D\u0443 \u043F\u0430\u043D\u0435\u043B\u0443 +Manage\ Jenkins=\u0423\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 Jenkins-\u043E\u043C +Save=\u0421\u0430\u0447\u0443\u0432\u0430\u0458 +Apply=\u041F\u0440\u0438\u043C\u0435\u043D\u0438 \ No newline at end of file diff --git a/core/src/main/resources/jenkins/triggers/Messages.properties b/core/src/main/resources/jenkins/triggers/Messages.properties index 9ba056bf6f2df9fab92ef324c8437889e1f1eb9a..9f71ea4895786029ef416abc0343dd457b1dca38 100644 --- a/core/src/main/resources/jenkins/triggers/Messages.properties +++ b/core/src/main/resources/jenkins/triggers/Messages.properties @@ -22,3 +22,4 @@ ReverseBuildTrigger.build_after_other_projects_are_built=Build after other projects are built ReverseBuildTrigger.running_as_cannot_even_see_for_trigger_f=Running as {0} cannot even see {1} for trigger from {2} +SCMTriggerItem.PollingVetoed=SCM polling vetoed by {0} diff --git a/core/src/main/resources/jenkins/triggers/Messages_bg.properties b/core/src/main/resources/jenkins/triggers/Messages_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..1fb7250fa1c32b8c57c7985e2b1f229ec4b4d509 --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/Messages_bg.properties @@ -0,0 +1,30 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ReverseBuildTrigger.build_after_other_projects_are_built=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u0441\u043b\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u0434\u0440\u0443\u0433\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438. +ReverseBuildTrigger.running_as_cannot_even_see_for_trigger_f=\ + \u041f\u0440\u043e\u0446\u0435\u0441, \u0440\u0430\u0431\u043e\u0442\u0435\u0449 \u0441 \u043f\u0440\u0430\u0432\u0430\u0442\u0430 \u043d\u0430 \u201e{0}\u201c \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0432\u0438\u0434\u0438 \u0437\u0430\u0434\u0430\u0447\u0430\u0442\u0430 \u201e{1}\u201c \u043e\u0442\ + \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u0442\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u201e{2}\u201c. +# SCM polling vetoed by {0} +SCMTriggerItem.PollingVetoed=\ + \u0417\u0430\u044f\u0432\u043a\u0438\u0442\u0435 \u043a\u044a\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u0441\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441\u043f\u0440\u0435\u043d\u0438 \u043e\u0442 {0}. diff --git a/core/src/main/resources/jenkins/triggers/Messages_de.properties b/core/src/main/resources/jenkins/triggers/Messages_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..e819499d8c4cde915829bdaba26c09888969560e --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/Messages_de.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright 2015 Harald Albers +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +ReverseBuildTrigger.build_after_other_projects_are_built=Starte Build, nachdem andere Projekte gebaut wurden diff --git a/core/src/main/resources/jenkins/triggers/Messages_lt.properties b/core/src/main/resources/jenkins/triggers/Messages_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..ca27c3e1f2b0123a6c7677ef1c972db91ca2e437 --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/Messages_lt.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +ReverseBuildTrigger.build_after_other_projects_are_built=Vykdyti pabaigus kitus projektus +ReverseBuildTrigger.running_as_cannot_even_see_for_trigger_f=Vykdomas kaip {0} net negali matyti {1} trigeriui i\u0161 {2} diff --git a/core/src/main/resources/jenkins/triggers/Messages_sr.properties b/core/src/main/resources/jenkins/triggers/Messages_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6a6c113a30ec36ab2c413c9bfc503176b529acab --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/Messages_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +ReverseBuildTrigger.build_after_other_projects_are_built=\u0418\u0437\u0433\u0440\u0430\u0434\u0438 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 +SCMTriggerItem.PollingVetoed=\u0417\u0430\u0445\u0442\u0435\u0432\u0438 \u043F\u0440\u0435\u043C\u0430 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0430 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 \u0441\u0443 \u043F\u0440\u0438\u0432\u0440\u0435\u043C\u0435\u043D\u043E \u0441\u0443\u0441\u043F\u0435\u043D\u0434\u043E\u0432\u0430\u043D\u0438 \u043E\u0434 \u0441\u0442\u0440\u0430\u043D\u0435 {0}. +ReverseBuildTrigger.running_as_cannot_even_see_for_trigger_f=\u0418\u0437\u0431\u0440\u0448\u0430\u0432\u0430\u045A\u0435 \u043A\u0430\u043E {0} \u043D\u0435\u043C\u043E\u0436\u0435 \u043F\u0440\u0438\u0441\u0442\u0443\u043F\u0438\u0442\u0438 \u043D\u0438 {1} \u0437\u0430 \u0438\u0437\u0430\u0437\u0438\u0432\u0430\u045A\u0435 \u043E\u0434 {2} \ No newline at end of file diff --git a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_nl.properties b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_de.properties similarity index 74% rename from core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_nl.properties rename to core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_de.properties index 7d46644c79c4bc3277c937e1e788a3ddf25f02f7..75c162d626ed101beed9f1ff21930db5b121934c 100644 --- a/core/src/main/resources/hudson/model/FreeStyleProject/newJobDetail_nl.properties +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_de.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, id:sorokh +# Copyright (c) 2004-2015, Sun Microsystems, Inc., Kohsuke Kawaguchi, Simon Wiest # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -body=Dit is de basisfunctionaliteit van Jenkins. Bij dit type project kun je gebruik maken van een willekeurige combinatie van versiebeheer- en bouwsysteem. Je zou Jenkins zelfs kunnen gebruiken voor andere zaken dan het bouwen van software. +Projects\ to\ watch=Zu berwachende Projekte +Trigger\ only\ if\ build\ is\ stable=Nur auslsen, wenn der Build stabil ist +Trigger\ even\ if\ the\ build\ is\ unstable=Auslsen, selbst wenn der Build instabil ist +Trigger\ even\ if\ the\ build\ fails=Auslsen, selbst wenn der Build fehlschlgt \ No newline at end of file diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_lt.properties b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..fecbec18c40cd894a8a1f28c296964df02aff768 --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_lt.properties @@ -0,0 +1,4 @@ +Projects\ to\ watch=Steb\u0117ti projektus +Trigger\ only\ if\ build\ is\ stable=Paleisti, tik jei vykdymas stabilus +Trigger\ even\ if\ the\ build\ is\ unstable=Paleisti, net jei vykdymas nestabilus +Trigger\ even\ if\ the\ build\ fails=Paleisti, net jei vykdymas nepavyko diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pl.properties b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..1dc6324ab4868007215e1f617004b491748577f0 --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_pl.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Trigger\ only\ if\ build\ is\ stable=Uruchamiaj tylko, je\u015Bli zadanie by\u0142o stabilne +Trigger\ even\ if\ the\ build\ is\ unstable=Uruchamiaj nawet, je\u015Bli zadanie by\u0142o niestabilne +Projects\ to\ watch=Obserwowane projekty +Trigger\ even\ if\ the\ build\ fails=Uruchamiaj nawet, je\u015Bli zadanie nie powiod\u0142o si\u0119 diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_sr.properties b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..37827874c80858e715ded39b7cc2eefb855cc07c --- /dev/null +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/config_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +Trigger\ only\ if\ build\ is\ stable=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0441\u0430\u043C\u043E \u0430\u043A\u043E \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 +Trigger\ even\ if\ the\ build\ is\ unstable=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0438 \u0430\u043A\u043E \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u0441\u0442\u0430\u0431\u0438\u043B\u043D\u0430 +Trigger\ even\ if\ the\ build\ fails=\u041F\u043E\u043A\u0440\u0435\u043D\u0438 \u0438 \u0430\u043A\u043E \u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0430 +Projects\ to\ watch=\u041F\u0440\u043E\u0458\u0435\u043A\u0442\u0435 \u043A\u043E\u0458\u0435 \u043F\u0440\u0430\u0442\u0438\u0442\u0435 diff --git a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/help_de.html b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/help_de.html index 513cf57fdc8300de4e04f706eb90dc4cb9fa7da8..d37d2f2d63f8ec22db145f447362ec7bb9d537e7 100644 --- a/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/help_de.html +++ b/core/src/main/resources/jenkins/triggers/ReverseBuildTrigger/help_de.html @@ -1,6 +1,6 @@

      - Richtet einen Build-Auslöser ein, so daß immer dann, wenn ein anderes + Richtet einen Build-Auslöser ein, so dass immer dann, wenn ein anderes Projekt erfolgreich gebaut wurde, ein neuer Build dieses Projekts geplant wird. Dies ist beispielsweise sehr praktisch, um ausführliche Tests an einen erfolgreichen Build anzuschließen. @@ -9,4 +9,4 @@ unter "Post-Build Aktionen". Eine Veränderung hier wird automatisch von den anderen Projekten reflektiert.

      -
      \ No newline at end of file + diff --git a/core/src/main/resources/jenkins/widgets/BuildQueueWidget/index.groovy b/core/src/main/resources/jenkins/widgets/BuildQueueWidget/index.groovy index 94cccd7979e1336d9bcbeb8fb3161ffa0ca5957d..ae013561c731f279200176e245fe04c5bd70c258 100644 --- a/core/src/main/resources/jenkins/widgets/BuildQueueWidget/index.groovy +++ b/core/src/main/resources/jenkins/widgets/BuildQueueWidget/index.groovy @@ -2,4 +2,4 @@ package jenkins.widgets.BuildQueueWidget; def t = namespace(lib.JenkinsTagLib.class) -t.queue(items:view.approximateQueueItemsQuickly, it:view, filtered:view.filterQueue) +t.queue(items:view.queueItems, it:view, filtered:view.filterQueue) diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/ajaxBuildHistory.jelly b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/ajaxBuildHistory.jelly new file mode 100644 index 0000000000000000000000000000000000000000..6fdf095c515a066caf759207480b52cc7e230680 --- /dev/null +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/ajaxBuildHistory.jelly @@ -0,0 +1,41 @@ + + + + + + + + +
    ${%User}:
    ${%Password}:
    + +
    + + +
    +
    +
    + +
    \ No newline at end of file diff --git a/test/src/main/resources/org/jvnet/hudson/test/FailureBuilder/config.jelly b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/entries.jelly similarity index 86% rename from test/src/main/resources/org/jvnet/hudson/test/FailureBuilder/config.jelly rename to core/src/main/resources/jenkins/widgets/HistoryPageFilter/entries.jelly index 9d137d24a0b893d9610c894370a04e80f25eaed2..622a838738fe7d97b7baa7c1e70bf9eb544842b3 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/FailureBuilder/config.jelly +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/entries.jelly @@ -23,4 +23,7 @@ THE SOFTWARE. --> - \ No newline at end of file + + + + \ No newline at end of file diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly new file mode 100644 index 0000000000000000000000000000000000000000..be46285a1329341cf6e0878f05b698708b85e7c5 --- /dev/null +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items.jelly @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + +
    +
    + +
    + +
    + #${queuedItems.size()==1 ? it.widget.owner.nextBuildNumber + : it.widget.owner.nextBuildNumber+queuedItems.size()-i-1} +
    +
    +
    + + + + (${%pending}—) + + + (${%pending}) + + + +
    + +
    +
    +
    +
    +
    + + + +
    +
    +
    + + +
    +
    +
    diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_lt.properties b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..09e8130a80e1a6557da41e00189d10c4695994c1 --- /dev/null +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_lt.properties @@ -0,0 +1,3 @@ +cancel\ this\ build=nutraukti \u0161\u012f vykdym\u0105 +Expected\ build\ number=Tik\u0117tinas vykdymo numeris +pending=laukiama diff --git a/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_sr.properties b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..fc95a97d121885b3e15359a2c3a643ae9c44a07a --- /dev/null +++ b/core/src/main/resources/jenkins/widgets/HistoryPageFilter/queue-items_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Expected\ build\ number=\u041E\u0447\u0435\u043A\u0438\u0432\u0430\u043D \u0431\u0440\u043E\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +pending=\u0447\u0435\u043A\u0430\u045A\u0435 +cancel\ this\ build=\u043E\u0442\u043A\u0430\u0436\u0438 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 diff --git a/core/src/main/resources/lib/form/advanced_bg.properties b/core/src/main/resources/lib/form/advanced_bg.properties index 633eba41b841800c6825643da0f1e2321a798ce4..73e08e7b8d1384046676f12a65659ffe6807805a 100644 --- a/core/src/main/resources/lib/form/advanced_bg.properties +++ b/core/src/main/resources/lib/form/advanced_bg.properties @@ -1,3 +1,27 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Advanced=\u0417\u0430 \u043D\u0430\u043F\u0440\u0435\u0434\u043D\u0430\u043B\u0438 +Advanced=\ + \u0417\u0430 \u043d\u0430\u043f\u0440\u0435\u0434\u043d\u0430\u043b\u0438 +# One or more fields in this block have been edited. +customizedFields=\ + \u041f\u043e\u043d\u0435 \u0435\u0434\u043d\u043e \u043f\u043e\u043b\u0435 \u0432 \u0442\u0430\u0437\u0438 \u0441\u0435\u043a\u0446\u0438\u044f \u0435 \u043f\u0440\u043e\u043c\u0435\u043d\u0435\u043d\u043e. diff --git a/core/src/main/resources/lib/form/advanced_sr.properties b/core/src/main/resources/lib/form/advanced_sr.properties index a16b944ce5abc73f3b2fc09d405f3b9cb9388777..a30766522dca83576b731b7bb9fb1af656a0369e 100644 --- a/core/src/main/resources/lib/form/advanced_sr.properties +++ b/core/src/main/resources/lib/form/advanced_sr.properties @@ -1,3 +1,4 @@ # This file is under the MIT License by authors -Advanced=Napredno +Advanced=\u041D\u0430\u043F\u0440\u0435\u0434\u043D\u043E +customizedFields=\u0408\u0435\u0434\u043D\u043E \u0438\u043B\u0438 \u0432\u0438\u0448\u0435 \u043F\u043E\u0459\u0430 \u0443 \u043E\u0432\u043E\u0458 \u0458\u0435\u0434\u0438\u043D\u0438\u0446\u0438 \u0441\u0443 \u043F\u0440\u043E\u043C\u0435\u045A\u0435\u043D\u0430 diff --git a/core/src/main/resources/lib/form/apply.jelly b/core/src/main/resources/lib/form/apply.jelly index 0551d1d1159299b5118593284621da72d1010f3c..86455202ec8dc23516cb8be82cc24ee9d73e9f7a 100644 --- a/core/src/main/resources/lib/form/apply.jelly +++ b/core/src/main/resources/lib/form/apply.jelly @@ -32,8 +32,11 @@ THE SOFTWARE. When this button is pressed, the FORM element fires the "jenkins:apply" event that allows interested parties to write back whatever states back into the INPUT elements. + + The text of the apply button. + - +
    \ No newline at end of file diff --git a/core/src/main/resources/lib/form/apply_bg.properties b/core/src/main/resources/lib/form/apply_bg.properties index f102d04d10a40a7ae5a824cc262e290613e02fa4..673c532564ea1b5f2e5ec58a08134ed11b333d38 100644 --- a/core/src/main/resources/lib/form/apply_bg.properties +++ b/core/src/main/resources/lib/form/apply_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Apply=\u041F\u0440\u0438\u043B\u043E\u0436\u0438 +Apply=\ + \u041f\u0440\u0438\u043b\u0430\u0433\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/form/apply_sr.properties b/core/src/main/resources/lib/form/apply_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..c5e16ef3c95fd0347447429bcebe9813fb7c9a69 --- /dev/null +++ b/core/src/main/resources/lib/form/apply_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Apply=\u041F\u0440\u0438\u043C\u0435\u043D\u0438 diff --git a/core/src/main/resources/lib/form/booleanRadio.jelly b/core/src/main/resources/lib/form/booleanRadio.jelly index ea8895231203cc088c64e09c0d2794ba0e9da6b6..2f9bca9b9b049bfe80f9910bef1a777587c87c09 100644 --- a/core/src/main/resources/lib/form/booleanRadio.jelly +++ b/core/src/main/resources/lib/form/booleanRadio.jelly @@ -1,47 +1,47 @@ - - - - - Binds a boolean field to two radio buttons that say Yes/No OK/Cancel Top/Bottom. - - - Databinding field. - - - Text to be displayed for the 'true' value. Defaults to 'Yes'. - - - Text to be displayed for the 'false' value. Defaults to 'No'. - - - - - - - - - - + + + + + Binds a boolean field to two radio buttons that say Yes/No OK/Cancel Top/Bottom. + + + Databinding field. + + + Text to be displayed for the 'true' value. Defaults to 'Yes'. + + + Text to be displayed for the 'false' value. Defaults to 'No'. + + + + + + + + + + diff --git a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_pt_BR.properties b/core/src/main/resources/lib/form/booleanRadio_bg.properties similarity index 89% rename from test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_pt_BR.properties rename to core/src/main/resources/lib/form/booleanRadio_bg.properties index deb9192a353e7f2540d148d7a2b5703a3e125344..9794be3509e96850afed5fa2c5e99264f53bc4dc 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_pt_BR.properties +++ b/core/src/main/resources/lib/form/booleanRadio_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Save=Salvar +Yes=\ + \u0414\u0430 +No=\ + \u041d\u0435 diff --git a/core/src/main/resources/lib/form/booleanRadio_sr.properties b/core/src/main/resources/lib/form/booleanRadio_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a5a8a51739e1d4cc8731157efe2f2fe6ab604c4a --- /dev/null +++ b/core/src/main/resources/lib/form/booleanRadio_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Yes=\u0414\u0430 +No=\u041D\u0435 diff --git a/core/src/main/resources/lib/form/breadcrumb-config-outline_bg.properties b/core/src/main/resources/lib/form/breadcrumb-config-outline_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..64afa8914f755410802796ef3bb918c9672da9a5 --- /dev/null +++ b/core/src/main/resources/lib/form/breadcrumb-config-outline_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +configuration=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 diff --git a/core/src/main/resources/lib/form/breadcrumb-config-outline_sr.properties b/core/src/main/resources/lib/form/breadcrumb-config-outline_sr.properties index bb8447c4cb3fd4b0247e3a5c480a3f8305199a0b..4e198232c753868d8e585530d67922a34e0bdc9c 100644 --- a/core/src/main/resources/lib/form/breadcrumb-config-outline_sr.properties +++ b/core/src/main/resources/lib/form/breadcrumb-config-outline_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -configuration=konfiguracija +configuration=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 diff --git a/core/src/main/resources/lib/form/checkbox.jelly b/core/src/main/resources/lib/form/checkbox.jelly index eda309a14e36dfa4b2bb211540cd554ca678dcca..240e612c0ea8f74da66106b902d991d55c1b37e7 100644 --- a/core/src/main/resources/lib/form/checkbox.jelly +++ b/core/src/main/resources/lib/form/checkbox.jelly @@ -44,6 +44,9 @@ THE SOFTWARE. + + If set to true, this will take precedence over the onclick attribute and prevent the state of the checkbox from being changed. + Used for databinding. TBD. @@ -63,7 +66,7 @@ THE SOFTWARE. name="${name}" value="${attrs.value}" title="${attrs.tooltip}" - onclick="${attrs.onclick}" id="${attrs.id}" class="${attrs.negative!=null ? 'negative' : null} ${attrs.checkUrl!=null?'validated':''}" + onclick="${attrs.readonly=='true' ? 'return false;' : attrs.onclick}" id="${attrs.id}" class="${attrs.class} ${attrs.negative!=null ? 'negative' : null} ${attrs.checkUrl!=null?'validated':''}" checkUrl="${attrs.checkUrl}" checkDependsOn="${attrs.checkDependsOn}" json="${attrs.json}" checked="${value ? 'true' : null}"/> diff --git a/core/src/main/resources/lib/form/confirm.js b/core/src/main/resources/lib/form/confirm.js index d5948c3aa28c742ffb8d0cd3ae4b3883a4efba09..64f40eb26717c77113423101eeb4a2f839a82617 100644 --- a/core/src/main/resources/lib/form/confirm.js +++ b/core/src/main/resources/lib/form/confirm.js @@ -33,9 +33,6 @@ } function initConfirm() { - // Timeout is needed since some events get sent on page load for some reason. - // Shouldn't hurt anything for this to only start monitoring events after a few millis;. - setTimeout(function() { var configForm = document.getElementsByName("config"); if (configForm.length > 0) { configForm = configForm[0] @@ -78,7 +75,6 @@ for ( var i = 0; i < inputs.length; i++) { $(inputs[i]).on('input', confirm); } - }, 100); } window.onbeforeunload = confirmExit; diff --git a/core/src/main/resources/lib/form/descriptorList.jelly b/core/src/main/resources/lib/form/descriptorList.jelly index 23db23166595716a22ebc201a6f6a3988d8cca42..ec74decd6e5333f523204a3a796b20c7ff219283 100644 --- a/core/src/main/resources/lib/form/descriptorList.jelly +++ b/core/src/main/resources/lib/form/descriptorList.jelly @@ -67,7 +67,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly b/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly index aad0a87e5161d71d3cb99f8b05fe1c3d2cf9cb64..9004073739b52a47694d953223746a9da87bf6df 100644 --- a/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly +++ b/core/src/main/resources/lib/form/dropdownDescriptorSelector.jelly @@ -42,6 +42,11 @@ THE SOFTWARE. If specified, this will be chosen as the default value in case the current selection is null. The default can be an specific instance or a descriptor e.g. ${descriptor.defaultSettingsProvider} or ${descriptor.defaultSettingsProvider.descriptor}. In the later case, the from input fields will be empty. + + Config fragments from descriptors are rendered lazily by default, which means + variables seen in the caller aren't visible to them. This attribute allows you + to nominate additional variables and their values to be captured for descriptors. + @@ -51,13 +56,14 @@ THE SOFTWARE. + + lazy="descriptor,it,${capture}"> - + diff --git a/core/src/main/resources/lib/form/enum.jelly b/core/src/main/resources/lib/form/enum.jelly index 667f0c10d2556da9cd81bf1f645b9a9d9044e77f..9cfb41829cdf62810b5cc519491bca06b2ed3f75 100644 --- a/core/src/main/resources/lib/form/enum.jelly +++ b/core/src/main/resources/lib/form/enum.jelly @@ -32,10 +32,13 @@ THE SOFTWARE. Used for databinding. TBD. + + The name of the enum to set as default value for the first configuration. + + class="radio-block-control block-control" checked="${checked?'true':null}" /> ${title} @@ -69,5 +69,5 @@ THE SOFTWARE. - +
    diff --git a/core/src/main/resources/lib/form/repeatableDeleteButton.jelly b/core/src/main/resources/lib/form/repeatableDeleteButton.jelly index e82b2b59b57ccd89116377617853bb635e32b381..9e676217b25fafffc316f6a3ffa54b8d304e2725 100644 --- a/core/src/main/resources/lib/form/repeatableDeleteButton.jelly +++ b/core/src/main/resources/lib/form/repeatableDeleteButton.jelly @@ -32,5 +32,5 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/form/repeatableDeleteButton_bg.properties b/core/src/main/resources/lib/form/repeatableDeleteButton_bg.properties index e2dcf86ecc41611377103a0153cd3b13d9f6f122..fd4cf636f2dfad49b014fcda2a739990e8b8f764 100644 --- a/core/src/main/resources/lib/form/repeatableDeleteButton_bg.properties +++ b/core/src/main/resources/lib/form/repeatableDeleteButton_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Delete=\u0418\u0437\u0442\u0440\u0438\u0439 +Delete=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/form/repeatableDeleteButton_sr.properties b/core/src/main/resources/lib/form/repeatableDeleteButton_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..0038ea61baf3efe147225da2f99a9bab2842bf68 --- /dev/null +++ b/core/src/main/resources/lib/form/repeatableDeleteButton_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Delete=\u0423\u043A\u043B\u043E\u043D\u0438 diff --git a/core/src/main/resources/lib/form/repeatable_bg.properties b/core/src/main/resources/lib/form/repeatable_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..563a90bfc34e9e3778ce9c7f2e40370680c75a04 --- /dev/null +++ b/core/src/main/resources/lib/form/repeatable_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 diff --git a/core/src/main/resources/lib/form/repeatable_sr.properties b/core/src/main/resources/lib/form/repeatable_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2ab9ef08a9f1f5a1f2ba06de2bd4ddc3b01b6ee4 --- /dev/null +++ b/core/src/main/resources/lib/form/repeatable_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Add=\u0414\u043E\u0434\u0430\u0458 diff --git a/core/src/main/resources/lib/form/rowSet.jelly b/core/src/main/resources/lib/form/rowSet.jelly index 19dd716b870f3364b78aa5f6226d03d8d8068abb..9b1746395b505cd2ec15c7b4adbcd10f8e8ec981 100644 --- a/core/src/main/resources/lib/form/rowSet.jelly +++ b/core/src/main/resources/lib/form/rowSet.jelly @@ -43,9 +43,9 @@ THE SOFTWARE. - + - + \ No newline at end of file diff --git a/core/src/main/resources/lib/form/select/select.js b/core/src/main/resources/lib/form/select/select.js index 6ea7a1e4c6796413c3a3e4233f70c0db479df9d3..0f87d0bbf66e15b794121272edc70892a0f7cee3 100644 --- a/core/src/main/resources/lib/form/select/select.js +++ b/core/src/main/resources/lib/form/select/select.js @@ -41,6 +41,22 @@ function updateListBox(listBox,url,config) { } Behaviour.specify("SELECT.select", 'select', 1000, function(e) { + + function hasChanged(selectEl, originalValue) { + // seems like a race condition allows this to fire before the 'selectEl' is defined. If that happens, exit.. + if(!selectEl || !selectEl.options || !selectEl.options.length > 0) + return false; + var firstValue = selectEl.options[0].value; + var selectedValue = selectEl.value; + if (originalValue == "" && selectedValue == firstValue) { + // There was no value pre-selected but after the call to updateListBox the first value is selected by + // default. This must not be considered a change. + return false; + } else { + return originalValue != selectedValue; + } + }; + // controls that this SELECT box depends on refillOnChange(e,function(params) { var value = e.value; @@ -60,7 +76,9 @@ Behaviour.specify("SELECT.select", 'select', 1000, function(e) { fireEvent(e,"filled"); // let other interested parties know that the items have changed // if the update changed the current selection, others listening to this control needs to be notified. - if (e.value!=value) fireEvent(e,"change"); + if (hasChanged(e, value)) { + fireEvent(e,"change"); + } } }); }); diff --git a/core/src/main/resources/lib/form/serverTcpPort_sr.properties b/core/src/main/resources/lib/form/serverTcpPort_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..132f0a20abbd29524da4e5c394149b2e9e81d654 --- /dev/null +++ b/core/src/main/resources/lib/form/serverTcpPort_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Fixed=\u0421\u0442\u0430\u0442\u0438\u0447\u043A\u0438 +Random=\u0421\u043B\u0443\u0447\u0430\u0458\u043Do +Disable=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438 \ No newline at end of file diff --git a/core/src/main/resources/lib/form/slave-mode.jelly b/core/src/main/resources/lib/form/slave-mode.jelly index da161ce1082c095154efc7778a7c4ce11dfb635b..61c8edc299a9ad6a59b2f34de1e909c26242abd6 100644 --- a/core/src/main/resources/lib/form/slave-mode.jelly +++ b/core/src/main/resources/lib/form/slave-mode.jelly @@ -26,7 +26,7 @@ THE SOFTWARE. - listbox for choosing the slave's usage. + listbox for choosing the agent's usage. Name of the <select> element. diff --git a/core/src/main/resources/lib/form/slave-mode_bg.properties b/core/src/main/resources/lib/form/slave-mode_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..fe5c92d5b6821390237982c5b01a2c4da8dda59b --- /dev/null +++ b/core/src/main/resources/lib/form/slave-mode_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Usage=\ + \u0423\u043f\u043e\u0442\u0440\u0435\u0431\u0430 diff --git a/core/src/main/resources/lib/form/slave-mode_sr.properties b/core/src/main/resources/lib/form/slave-mode_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4ed411d3065a073de6516ab26102299a1d1ea3df --- /dev/null +++ b/core/src/main/resources/lib/form/slave-mode_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Usage=\u0423\u043F\u043E\u0442\u0440\u0435\u0431\u0430 diff --git a/core/src/main/resources/lib/form/textarea.jelly b/core/src/main/resources/lib/form/textarea.jelly index 1015c6ed34987730217754c3707f1a61e9442c91..76bf19b644c348207f6f3b984920c9a2475c4513 100644 --- a/core/src/main/resources/lib/form/textarea.jelly +++ b/core/src/main/resources/lib/form/textarea.jelly @@ -89,6 +89,7 @@ THE SOFTWARE. readonly="${attrs.readonly}" codemirror-mode="${attrs['codemirror-mode']}" codemirror-config="${attrs['codemirror-config']}"> + diff --git a/core/src/main/resources/lib/form/textarea/textarea.css b/core/src/main/resources/lib/form/textarea/textarea.css new file mode 100644 index 0000000000000000000000000000000000000000..71300ae0e3c422c7172c4dcf1f54b9f58846c898 --- /dev/null +++ b/core/src/main/resources/lib/form/textarea/textarea.css @@ -0,0 +1,5 @@ +td.setting-main .CodeMirror { + display: table; + table-layout: fixed; + width: 100%; +} \ No newline at end of file diff --git a/core/src/main/resources/lib/form/textarea/textarea.js b/core/src/main/resources/lib/form/textarea/textarea.js index f1c1b2238fe8f6b9926f5b1a10355d85aa349d08..d1f89de8f2c21b85c20d0bfe1d3c03a44b9ed48c 100644 --- a/core/src/main/resources/lib/form/textarea/textarea.js +++ b/core/src/main/resources/lib/form/textarea/textarea.js @@ -2,13 +2,13 @@ Behaviour.specify("TEXTAREA.codemirror", 'textarea', 0, function(e) { //ensure, that textarea is visible, when obtaining its height, see JENKINS-25455 function getTextareaHeight() { var p = e.parentNode.parentNode; //first parent is CodeMirror div, second is actual element which needs to be visible - var display = p.style.display; + var display = p.style.display; p.style.display = ""; var h = e.clientHeight; p.style.display = display; return h; } - + var h = e.clientHeight || getTextareaHeight(); var config = e.getAttribute("codemirror-config"); config += (config ? ", " : " ") + "onBlur: function(editor){editor.save()}"; @@ -27,16 +27,10 @@ Behaviour.specify("TEXTAREA.codemirror", 'textarea', 0, function(e) { // the form needs to be populated before the "Apply" button if(e.up('form')) { // Protect against undefined element - Element.on(e.up('form'),"jenkins:apply", function() { - e.value = codemirror.getValue() - }) - } - - //refresh CM when there are some layout updates - function refreshCM() { - codemirror.refresh(); + Element.on(e.up('form'),"jenkins:apply", function() { + e.value = codemirror.getValue() + }) } - layoutUpdateCallback.add(refreshCM); }); Behaviour.specify("DIV.textarea-preview-container", 'textarea', 100, function (e) { diff --git a/core/src/main/resources/lib/form/textarea_bg.properties b/core/src/main/resources/lib/form/textarea_bg.properties index 7100e52680a6eb3e1a89a2e8b5038429d8987c0e..3bee23c929c0c55b2f9aa324a55e2779cbd2d0d0 100644 --- a/core/src/main/resources/lib/form/textarea_bg.properties +++ b/core/src/main/resources/lib/form/textarea_bg.properties @@ -1,4 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Hide\ preview=\u0421\u043A\u0440\u0438\u0432\u0430\u043D\u0435 \u043D\u0430 \u043F\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043B\u0435\u043D \u043F\u0440\u0435\u0433\u043B\u0435\u0434 -Preview=\u041F\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043B\u0435\u043D \u043F\u0440\u0435\u0433\u043B\u0435\u0434 +Hide\ preview=\ + \u0421\u043a\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0433\u043b\u0435\u0434\u0430 +Preview=\ + \u041f\u0440\u0435\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/lib/form/textarea_sr.properties b/core/src/main/resources/lib/form/textarea_sr.properties index ac88bf0154fb3607f5f5ef569cb0738c9ca3e97a..632e5095701c94f16ab894785283fcf385184ae3 100644 --- a/core/src/main/resources/lib/form/textarea_sr.properties +++ b/core/src/main/resources/lib/form/textarea_sr.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Hide\ preview=Ukloni prikaz -Preview=Prikazi +Preview=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 +Hide\ preview=\u0421\u043A\u043B\u043E\u043D\u0438 \u043F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/lib/hudson/artifactList_bg.properties b/core/src/main/resources/lib/hudson/artifactList_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..4b4d734c1d11bedf3506fb8017872ef102fc0791 --- /dev/null +++ b/core/src/main/resources/lib/hudson/artifactList_bg.properties @@ -0,0 +1,30 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +view=\ + \u041f\u0440\u0435\u0433\u043b\u0435\u0434 +Expand\ all=\ + \u0420\u0430\u0437\u0448\u0438\u0440\u044f\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u043e +Collapse\ all=\ + \u0421\u0432\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u0432\u0441\u0438\u0447\u043a\u043e +View=\ + \u041f\u0440\u0435\u0433\u043b\u0435\u0434 diff --git a/core/src/main/resources/lib/hudson/artifactList_sr.properties b/core/src/main/resources/lib/hudson/artifactList_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2d329d4e88985ad4c5dafcb94e8023579a3cc3dc --- /dev/null +++ b/core/src/main/resources/lib/hudson/artifactList_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +view=\u043F\u0440\u0435\u0433\u043B\u0435\u0434 +Expand\ all=\u0420\u0430\u0448\u0438\u0440\u0438 \u0441\u0432\u0435 +Collapse\ all=\u0421\u043C\u0430\u045A\u0438 \u0441\u0432\u0435 +View=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 diff --git a/core/src/main/resources/lib/hudson/ballColorTd.jelly b/core/src/main/resources/lib/hudson/ballColorTd.jelly index 9889dbaf59bb82365c312650ce0d29835710fb9f..a10127a648fce42bee7be24082845a1193c8c534 100644 --- a/core/src/main/resources/lib/hudson/ballColorTd.jelly +++ b/core/src/main/resources/lib/hudson/ballColorTd.jelly @@ -44,8 +44,15 @@ THE SOFTWARE. - - + + + + + + + + + @@ -71,7 +78,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/hudson/buildCaption.jelly b/core/src/main/resources/lib/hudson/buildCaption.jelly index 80478e98d12cba4b477f1e31dd0336f16673961a..73610d33f1ecedea04334484a6ba8434914f1e47 100644 --- a/core/src/main/resources/lib/hudson/buildCaption.jelly +++ b/core/src/main/resources/lib/hudson/buildCaption.jelly @@ -37,7 +37,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/hudson/buildCaption.properties b/core/src/main/resources/lib/hudson/buildCaption.properties new file mode 100644 index 0000000000000000000000000000000000000000..6aa3af4cc19b3750c49d1c803ab7b18c9f7551c5 --- /dev/null +++ b/core/src/main/resources/lib/hudson/buildCaption.properties @@ -0,0 +1 @@ +confirm=Are you sure you want to abort {0}? diff --git a/core/src/main/resources/lib/hudson/buildCaption_bg.properties b/core/src/main/resources/lib/hudson/buildCaption_bg.properties index ba4662f3162c91a8d7791816affc607049316476..b0581b5f9b58679e7be6c9216068adc1edcad6cf 100644 --- a/core/src/main/resources/lib/hudson/buildCaption_bg.properties +++ b/core/src/main/resources/lib/hudson/buildCaption_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Progress=\u041F\u0440\u043E\u0433\u0440\u0435\u0441 -cancel=\u043E\u0442\u043C\u044F\u043D\u0430 +Progress=\ + \u041d\u0430\u043f\u0440\u0435\u0434\u044a\u043a +cancel=\ + \u041e\u0442\u043c\u044f\u043d\u0430 diff --git a/core/src/main/resources/lib/hudson/buildCaption_sr.properties b/core/src/main/resources/lib/hudson/buildCaption_sr.properties index 566efd02da66541ff42d66ec12c4dfb21231e488..a702f8f59f52eff50003c4f54ee7d2c7075157d1 100644 --- a/core/src/main/resources/lib/hudson/buildCaption_sr.properties +++ b/core/src/main/resources/lib/hudson/buildCaption_sr.properties @@ -1,4 +1,5 @@ # This file is under the MIT License by authors -Progress=Progres -cancel=Prekini +Progress=\u041F\u0440\u043E\u0433\u0440\u0435\u0441 +cancel=\u041E\u0442\u043A\u0430\u0436\u0438 +confirm=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043E\u0434\u043A\u0430\u0436\u0435\u0442\u0435 {0}? diff --git a/core/src/main/resources/lib/hudson/buildHealth_bg.properties b/core/src/main/resources/lib/hudson/buildHealth_bg.properties index bb5e44bfeb446c9614a9c6db69bab459d9e32322..eb308c8baf77092c36fc469c2c61f51590b5da70 100644 --- a/core/src/main/resources/lib/hudson/buildHealth_bg.properties +++ b/core/src/main/resources/lib/hudson/buildHealth_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 +Description=\ + \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 diff --git a/core/src/main/resources/lib/hudson/buildHealth_sr.properties b/core/src/main/resources/lib/hudson/buildHealth_sr.properties index 49ee343c9b9d4f1e7a2de380c4a525242f8bee87..c55807b8b0ec9c4a7013dd0c3801a8c6226633bb 100644 --- a/core/src/main/resources/lib/hudson/buildHealth_sr.properties +++ b/core/src/main/resources/lib/hudson/buildHealth_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Description=Opis +Description=\u041E\u043F\u0438\u0441 diff --git a/core/src/main/resources/lib/hudson/buildListTable.jelly b/core/src/main/resources/lib/hudson/buildListTable.jelly index 80cb00dad047c42afeae97db8ebd5a3bdd1a79b0..9465606ddbc95c56e1aeb855dd23f7f52be54b99 100644 --- a/core/src/main/resources/lib/hudson/buildListTable.jelly +++ b/core/src/main/resources/lib/hudson/buildListTable.jelly @@ -47,7 +47,7 @@ THE SOFTWARE. insert('\u00A0'). insert(new Element('a', {href: '${rootURL}/' + e.url, 'class': 'model-link inside'}). update(e.displayName.escapeHTML()))); - tr.insert(new Element('td', {data: e.timestampString2, tooltip: '${%Click to center timeline on event}', onclick: 'javascript:tl.getBand(0).scrollToCenter(Timeline.DateTime.parseGregorianDateTime("' + e.timestampString2 + '"))'}). + tr.insert(new Element('td', {data: e.timestampString2, tooltip: '${%Click to center timeline on event}', onclick: 'javascript:tl.getBand(0).scrollToCenter(Timeline.DateTime.parseGregorianDateTime("' + e.timestampString3 + '"))'}). update(e.timestampString.escapeHTML())); tr.insert(new Element('td', {style: e.buildStatusSummaryWorse ? 'color: red' : ''}). update(e.buildStatusSummaryMessage.escapeHTML())); diff --git a/core/src/main/resources/lib/hudson/buildListTable_bg.properties b/core/src/main/resources/lib/hudson/buildListTable_bg.properties index 7492fe105a719d0054863fa40d45f4598d987c4e..b55179e6f1b796b6ed82beeebceb4013fd9b27dd 100644 --- a/core/src/main/resources/lib/hudson/buildListTable_bg.properties +++ b/core/src/main/resources/lib/hudson/buildListTable_bg.properties @@ -1,7 +1,33 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Build=\u0411\u0438\u043B\u0434 -Click\ to\ center\ timeline\ on\ event=\u041D\u0430\u0442\u0438\u0441\u043D\u0438 \u0437\u0430 \u043F\u043E\u0437\u0438\u0446\u0438\u043E\u043D\u0438\u0440\u0430\u043D\u0435 \u043D\u0430 \u0442\u0430\u0439\u043C\u043B\u0430\u0439\u043D\u0430 \u0432\u044A\u0440\u0445\u0443 \u043C\u043E\u043C\u0435\u043D\u0442 -Console\ output=\u041A\u043E\u043D\u0437\u043E\u043B\u0435\u043D \u043B\u043E\u0433 -Status=\u0421\u0442\u0430\u0442\u0443\u0441 -Time\ Since=\u0412\u0440\u0435\u043C\u0435 \u043E\u0442 +Build=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Click\ to\ center\ timeline\ on\ event=\ + \u041c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0441\u0435 \u043f\u0440\u0438\u0434\u0432\u0438\u0436\u0438\u0442\u0435 \u043a\u044a\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u043c\u043e\u043c\u0435\u043d\u0442 \u043a\u0430\u0442\u043e \u0433\u043e \u043d\u0430\u0442\u0438\u0441\u043d\u0435\u0442\u0435 \u0441 \u0431\u0443\u0442\u043e\u043d\u0430 \u043d\u0430\ + \u043c\u0438\u0448\u043a\u0430\u0442\u0430 +Console\ output=\ + \u0418\u0437\u0445\u043e\u0434 \u043d\u0430 \u043a\u043e\u043d\u0437\u043e\u043b\u0430\u0442\u0430 +Status=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 +Time\ Since=\ + \u0412\u0440\u0435\u043c\u0435 \u043e\u0442 diff --git a/core/src/main/resources/lib/hudson/buildListTable_pl.properties b/core/src/main/resources/lib/hudson/buildListTable_pl.properties index c4a6dfc08ed76cdd60eb6e77b489c9da576eff03..ef2f307708a2cebe2e72b9fe2025aae80b6422e8 100644 --- a/core/src/main/resources/lib/hudson/buildListTable_pl.properties +++ b/core/src/main/resources/lib/hudson/buildListTable_pl.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build=Kompilacja +Build=Zadanie Click\ to\ center\ timeline\ on\ event=Kliknij aby wycentrowa\u0107 o\u015B czasu na zdarzeniu -Console\ output=Wynik consoli +Console\ output=Logi konsoli Time\ Since=Czasu temu diff --git a/core/src/main/resources/lib/hudson/buildListTable_sr.properties b/core/src/main/resources/lib/hudson/buildListTable_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..afee06dcd514bac221c6c57c1a05af32629cb0c5 --- /dev/null +++ b/core/src/main/resources/lib/hudson/buildListTable_sr.properties @@ -0,0 +1,7 @@ +# This file is under the MIT License by authors + +Click\ to\ center\ timeline\ on\ event=\u041A\u043B\u0438\u043A\u043D\u0438\u0442\u0435 \u0434\u0430 \u0446\u0435\u043D\u0442\u0440\u0438\u0440\u0430\u0442\u0435 \u0432\u0440\u0435\u043C\u0435\u043D\u0441\u043A\u0443 \u0442\u0440\u0430\u043A\u0443 \u043D\u0430 \u043E\u0434\u0440\u0435\u0452\u0435\u043D\u0438 \u0434\u043E\u0433\u0430\u0452\u0430\u0458. +Console\ output=\u0418\u0441\u0445\u043E\u0434 \u0438\u0437 \u043A\u043E\u043D\u0437\u043E\u043B\u0435 +Build=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Time\ Since=\u0412\u0440\u0435\u043C\u0435 \u043E\u0434 +Status=\u0421\u0442\u0430\u045A\u0435 diff --git a/core/src/main/resources/lib/hudson/buildProgressBar_bg.properties b/core/src/main/resources/lib/hudson/buildProgressBar_bg.properties index ea890b6b2bcf60798898fde0890346e55aa19c64..4a96c80da8b2a251f205213358bdeb04e10b2b4c 100644 --- a/core/src/main/resources/lib/hudson/buildProgressBar_bg.properties +++ b/core/src/main/resources/lib/hudson/buildProgressBar_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -text=\u041D\u0430\u0447\u0430\u043B\u043E \u043F\u0440\u0435\u0434\u0438 {0}
    \u041E\u0441\u0442\u0430\u0432\u0430\u0449\u043E \u0432\u0440\u0435\u043C\u0435: {1} +text=\ + \u041d\u0430\u0447\u0430\u043b\u043e \u043f\u0440\u0435\u0434\u0438 {0}
    \u041e\u0441\u0442\u0430\u0432\u0430\u0449\u043e \u0432\u0440\u0435\u043c\u0435: {1} diff --git a/core/src/main/resources/lib/hudson/buildProgressBar_sr.properties b/core/src/main/resources/lib/hudson/buildProgressBar_sr.properties index cd6aa2f3b6df7fa7a9c5c6d88b6578077e62389d..77cb22b833bc93a681bea6fc0e151d91a1480eef 100644 --- a/core/src/main/resources/lib/hudson/buildProgressBar_sr.properties +++ b/core/src/main/resources/lib/hudson/buildProgressBar_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -text=Zapo\u010Deto od {0}
    O\u010Dekivano preostalo vreme: {1} +text=\u0417\u0430\u043F\u043E\u0447\u0435\u0442\u043E \u043F\u0440\u0435 {0}
    \u041E\u0447\u0435\u043A\u0438\u0432\u0430\u043D\u043E \u043F\u0440\u0435\u043E\u0441\u0442\u0430\u043B\u043E \u0432\u0440\u0435\u043C\u0435: {1} \ No newline at end of file diff --git a/core/src/main/resources/lib/hudson/editableDescription_bg.properties b/core/src/main/resources/lib/hudson/editableDescription_bg.properties index f6d676ecda8871093bf328e62483f5ef48592ed6..80fb8041a57439a518586faa1347a8f6efa7e344 100644 --- a/core/src/main/resources/lib/hudson/editableDescription_bg.properties +++ b/core/src/main/resources/lib/hudson/editableDescription_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -add\ description=\u0434\u043E\u0431\u0430\u0432\u044F\u043D\u0435 \u043D\u0430 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 -edit\ description=\u043F\u0440\u043E\u043C\u0435\u043D\u0438 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u0442\u043E +add\ description=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 +edit\ description=\ + \u041f\u0440\u043e\u043c\u044f\u043d\u0430 \u043d\u0430 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 diff --git a/core/src/main/resources/lib/hudson/editableDescription_sr.properties b/core/src/main/resources/lib/hudson/editableDescription_sr.properties index 35b19cb549f4f46c69946d9e0b2efeacc9bf04c8..75a9a5080e84a426026f8296b04dd26cf5d153f2 100644 --- a/core/src/main/resources/lib/hudson/editableDescription_sr.properties +++ b/core/src/main/resources/lib/hudson/editableDescription_sr.properties @@ -1,3 +1,4 @@ # This file is under the MIT License by authors -add\ description=dodaj opis +add\ description=\u0434\u043E\u0434\u0430\u0458 \u043E\u043F\u0438\u0441 +edit\ description=\u0443\u0440\u0435\u0434\u0438 \u043E\u043F\u0438\u0441 diff --git a/core/src/main/resources/lib/hudson/executors.jelly b/core/src/main/resources/lib/hudson/executors.jelly index 532720cd85815c32b5174308feabe38330fbaebc..86f12dffc4969c9c836f59c621b0108f21cb8221 100644 --- a/core/src/main/resources/lib/hudson/executors.jelly +++ b/core/src/main/resources/lib/hudson/executors.jelly @@ -34,7 +34,7 @@ THE SOFTWARE. - ${title} + ${title} (${%offline}) (${%suspended}) @@ -45,15 +45,6 @@ THE SOFTWARE. ${name} - - - -
    ${%Dead} (!)
    -
    - - - -
    @@ -119,7 +110,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/hudson/executors.properties b/core/src/main/resources/lib/hudson/executors.properties index 76d77a195cdcf13709955ce7994004d210b73a99..3d8ebc248ea37a6b9688d5221777e9c9d4a8aec7 100644 --- a/core/src/main/resources/lib/hudson/executors.properties +++ b/core/src/main/resources/lib/hudson/executors.properties @@ -1 +1,2 @@ -Computers=master{0,choice,0#|1# + {0,number} computer ({1} of {2} executors)|1< + {0,number} computers ({1} of {2} executors)} \ No newline at end of file +Computers=master{0,choice,0#|1# + {0,number} computer ({1} of {2} executors)|1< + {0,number} computers ({1} of {2} executors)} +confirm=Are you sure you want to abort {0}? diff --git a/core/src/main/resources/lib/hudson/executors_bg.properties b/core/src/main/resources/lib/hudson/executors_bg.properties index fc51b26376bbcfd56127bbc1a5cd00f3ca655fcd..d55c9f8e4c0ff75c78caebe5f2e89ade0ca2e55c 100644 --- a/core/src/main/resources/lib/hudson/executors_bg.properties +++ b/core/src/main/resources/lib/hudson/executors_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,10 +20,24 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ Executor\ Status=\u0421\u0442\u0430\u0442\u0443\u0441 \u043D\u0430 \u0438\u0437\u043F\u044A\u043B\u043D\u0438\u0442\u0435\u043B\u044F -Building=\u0411\u0438\u043B\u0434\u0432\u0430\u043D\u0435 \u043D\u0430 -Idle=\u0421\u0432\u043E\u0431\u043E\u0434\u0435\u043D -Master=\u0413\u043B\u0430\u0432\u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0430 -Status=\u0421\u044A\u0441\u0442\u043E\u044F\u043D\u0438\u0435 -offline=\u043E\u0444\u043B\u0430\u0439\u043D -terminate\ this\ build=\u043F\u0440\u0435\u043A\u0440\u0430\u0442\u0438 \u0431\u0438\u043B\u0434\u0430 +Build\ Executor\ Status=\ + \u0421\u044a\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440\u0430 +Idle=\ + \u0421\u0432\u043e\u0431\u043e\u0434\u0435\u043d +offline=\ + \u0418\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f +terminate\ this\ build=\ + \u0421\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +Pending=\ + \u041f\u0440\u0435\u0434\u0441\u0442\u043e\u0438 +suspended=\ + \u041d\u0430 \u043f\u0430\u0443\u0437\u0430 +Dead=\ + \u0423\u043c\u0440\u044f\u043b +Unknown\ Task=\ + \u041d\u0435\u043f\u043e\u0437\u043d\u0430\u0442\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 +Offline=\ + \u0418\u0437\u0432\u044a\u043d \u043b\u0438\u043d\u0438\u044f +# master{0,choice,0#|1# + {0,number} computer ({1} of {2} executors)|1< + {0,number} computers ({1} of {2} executors)} +Computers=\ + \u043e\u0441\u043d\u043e\u0432\u0435\u043d{0,choice,0#|1# + {0,number} \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 ({1} \u043e\u0442 {2} \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u0438)|1< + {0,number} \u043a\u043e\u043c\u043f\u044e\u0442\u0440\u0438 ({1} \u043e\u0442 {2} \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u0438)} diff --git a/core/src/main/resources/lib/hudson/executors_pl.properties b/core/src/main/resources/lib/hudson/executors_pl.properties index 732e8b302d41fe6d5cdb97fe714d8bd75c1bac54..015941013b35fbd7a3bea539c00fc25eb405090b 100644 --- a/core/src/main/resources/lib/hudson/executors_pl.properties +++ b/core/src/main/resources/lib/hudson/executors_pl.properties @@ -20,10 +20,10 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ Executor\ Status=Stan Wykonawcy Zada\u0144 -Building=Budynek -Dead=Pad\u0142 +Build\ Executor\ Status=Status wykonawc\u00F3w zada\u0144 +Building=Buduje +Dead=Niedost\u0119pny Idle=Bezczynny Unknown\ Task=Nieznane zadanie offline=roz\u0142\u0105czony -terminate\ this\ build=terminuj ten build +terminate\ this\ build=przerwij to zadanie diff --git a/core/src/main/resources/lib/hudson/executors_ro.properties b/core/src/main/resources/lib/hudson/executors_ro.properties index dc72abc1e0ce981dd4ea5dde3d82b1cfb6b2fd73..452240522a8fb65e930307dd635e08b18228fdd0 100644 --- a/core/src/main/resources/lib/hudson/executors_ro.properties +++ b/core/src/main/resources/lib/hudson/executors_ro.properties @@ -22,12 +22,8 @@ Build\ Executor\ Status=Starea builder-ului Executant Idle=\u00CEn a\u0219teptare -(need to specify the context) -(need to specify the context) -(need to specify the context) +# (need to specify the context) Status=Stare offline=oprit terminate\ this\ build=opreste build-ul -(i think in Romania build is called build) -(i think in Romania build is called build) -(i think in Romania build is called build) +# (i think in Romania build is called build) diff --git a/core/src/main/resources/lib/hudson/executors_sr.properties b/core/src/main/resources/lib/hudson/executors_sr.properties index 86e9d7b4e51d1fb7765c4dd8351081e8d1f45f57..c59e49e581071ce8a3f35eb65ba39be67df12831 100644 --- a/core/src/main/resources/lib/hudson/executors_sr.properties +++ b/core/src/main/resources/lib/hudson/executors_sr.properties @@ -20,8 +20,18 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ Executor\ Status=Status Izvr\u0161itelja Gradnje -Building=Izgradnja -Idle=mirovanje +Build\ Executor\ Status=\u0421\u0442\u0430\u045A\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Building=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Idle=\u0421\u043B\u043E\u0432\u043E\u0434\u043D\u043E Status=\u0421\u0442\u0430\u045A\u0435 -terminate\ this\ build=okon\u010Daj ovu gradnju +terminate\ this\ build=\u041E\u043A\u043E\u043D\u0447\u0430\u0458 \u043E\u0432\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 +offline=\u0412\u0430\u043D \u043C\u0440\u0435\u0436\u0435 +suspended=\u0441\u0443\u0441\u043F\u0435\u043D\u0434\u043E\u0432\u0430\u043D +Offline=\u0412\u0430\u043D \u043C\u0440\u0435\u0436\u0435 +Pending=\u0427\u0435\u043A\u0430\u045A\u0435 +Unknown\ Task=\u041D\u0435\u043F\u043E\u0437\u043D\u0430\u0442\u0438 \u0437\u0430\u0434\u0430\u0442\u0430\u043A +confirm=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043E\u0442\u043A\u0430\u0436\u0435\u0442\u0435 {0}? +Computers=\ + \u043E\u0441\u043D\u043E\u0432\u043D\u043E{0,choice,0#|1# + {0,number} \u0440\u0430\u0447\u0443\u043D\u0430\u0440 ({1} \u043E\u0434 {2} \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430)|1< + {0,number} \u0440\u0430\u0447\u0443\u043D\u0430\u0440\u0430 ({1} \u043E\u0434 {2} \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0435\u0459\u0430)} +Master= +Dead=\u041C\u0440\u0442\u0432\u043E diff --git a/core/src/main/resources/lib/hudson/executors_sv_SE.properties b/core/src/main/resources/lib/hudson/executors_sv_SE.properties index 28c939ae10c3ab4791da247b201949ff03a70bd2..ff930c402cc7f2116fa1e5e6e6d75947ddb0c4cd 100644 --- a/core/src/main/resources/lib/hudson/executors_sv_SE.properties +++ b/core/src/main/resources/lib/hudson/executors_sv_SE.properties @@ -24,6 +24,6 @@ Build\ Executor\ Status=Status f\u00F6r Byggare Building=Bygger Idle=V\u00E4ntande Offline=Offline -Unknown\ Task=\u00D6kand uppgift +Unknown\ Task=Ok\u00E4nd uppgift offline=ej tillg\u00E4nglig terminate\ this\ build=avbryt detta bygge diff --git a/core/src/main/resources/lib/hudson/iconSize_bg.properties b/core/src/main/resources/lib/hudson/iconSize_bg.properties index 95f5cae9f7c0aa9b94f24df1be69b99b5bcef73a..1632b3c40cbdbf05dfb4b168db83524bc33815d8 100644 --- a/core/src/main/resources/lib/hudson/iconSize_bg.properties +++ b/core/src/main/resources/lib/hudson/iconSize_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Icon=\u0418\u043A\u043E\u043D\u0430 +Icon=\ + \u0418\u043a\u043e\u043d\u0430 diff --git a/core/src/main/resources/lib/hudson/iconSize_sr.properties b/core/src/main/resources/lib/hudson/iconSize_sr.properties index 908c440494e8eaf61fb64442f96e7e42343b42ea..45ad05ff2e3e43cd1ca2a7694e9333d56eb73f04 100644 --- a/core/src/main/resources/lib/hudson/iconSize_sr.properties +++ b/core/src/main/resources/lib/hudson/iconSize_sr.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Icon=ikonica +Icon=\u0418\u043A\u043E\u043D\u0438\u0446\u0430 diff --git a/core/src/main/resources/lib/hudson/listScmBrowsers_bg.properties b/core/src/main/resources/lib/hudson/listScmBrowsers_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..6c9dcba310185ac39becc0c055ca3e4331ce9526 --- /dev/null +++ b/core/src/main/resources/lib/hudson/listScmBrowsers_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Repository\ browser=\ + \u0420\u0430\u0437\u0433\u043b\u0435\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 +Auto=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e diff --git a/core/src/main/resources/lib/hudson/listScmBrowsers_sr.properties b/core/src/main/resources/lib/hudson/listScmBrowsers_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1ab483f63439419c0ce3ca7d98b656d2ae449710 --- /dev/null +++ b/core/src/main/resources/lib/hudson/listScmBrowsers_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Repository\ browser=\u041F\u0440\u0435\u0433\u043B\u0435\u0434\u0430\u0447 \u0441\u043F\u0440\u0435\u043C\u0438\u0448\u0442\u0430 +Auto=\u0410\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438 diff --git a/core/src/main/resources/lib/hudson/newFromList/form_bg.properties b/core/src/main/resources/lib/hudson/newFromList/form_bg.properties index 176a3de3476d5b14519fd063bd3dfb685f8da351..e1bef929104882e68b0ae1f8fbc564068e89cb48 100644 --- a/core/src/main/resources/lib/hudson/newFromList/form_bg.properties +++ b/core/src/main/resources/lib/hudson/newFromList/form_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Copy\ from=\u041A\u043E\u043F\u0438\u0440\u0430\u0439 \u043E\u0442 +Copy\ from=\ + \u041a\u043e\u043f\u0438\u0440\u0430\u043d\u0435 \u043e\u0442 diff --git a/core/src/main/resources/lib/hudson/newFromList/form_sr.properties b/core/src/main/resources/lib/hudson/newFromList/form_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..6190adbdbb8f60154392518402dd38e58ea86a45 --- /dev/null +++ b/core/src/main/resources/lib/hudson/newFromList/form_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Copy\ from=\u0418\u0437\u043A\u043E\u043F\u0438\u0440\u0430\u0458 \u043E\u0434 diff --git a/core/src/main/resources/lib/hudson/node_bg.properties b/core/src/main/resources/lib/hudson/node_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..1b8e9a626e6e635d934e463aaa164f3379d66a24 --- /dev/null +++ b/core/src/main/resources/lib/hudson/node_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +master=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0432\u0430\u0449 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 diff --git a/core/src/main/resources/lib/hudson/node_sr.properties b/core/src/main/resources/lib/hudson/node_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e2aa68159222b3094f293f7e65b93e9da4927e0d --- /dev/null +++ b/core/src/main/resources/lib/hudson/node_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +master=\u043C\u0430\u0441\u0442\u0435\u0440 diff --git a/core/src/main/resources/lib/hudson/project/build-permalink_bg.properties b/core/src/main/resources/lib/hudson/project/build-permalink_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..35b83c4de8b82f7b0bf54968678fa44f81f339a4 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/build-permalink_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# {0} (#{1}), {2} ago +format=\ + {0} (\u2116\u200a{1}), \u043f\u0440\u0435\u0434\u0438 {2} diff --git a/core/src/main/resources/lib/hudson/project/build-permalink_lt.properties b/core/src/main/resources/lib/hudson/project/build-permalink_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..0a3cb61fa532f15049ad893c86d37d3da11dd9fb --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/build-permalink_lt.properties @@ -0,0 +1 @@ +format={0} (#{1}), prie\u0161 {2} diff --git a/core/src/main/resources/lib/hudson/project/build-permalink_sr.properties b/core/src/main/resources/lib/hudson/project/build-permalink_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..05a61a106e178e866106ab86f11de3f3c5f90922 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/build-permalink_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +format={0} (#{1}), \u043F\u0440\u0435 {2} diff --git a/core/src/main/resources/lib/hudson/project/config-assignedLabel.jelly b/core/src/main/resources/lib/hudson/project/config-assignedLabel.jelly index 9959f6d18d119523d73dc491e08e460ca6650ed0..d242e803f909832e2a30a11e2cad9ab41b0eaa4d 100644 --- a/core/src/main/resources/lib/hudson/project/config-assignedLabel.jelly +++ b/core/src/main/resources/lib/hudson/project/config-assignedLabel.jelly @@ -27,7 +27,7 @@ THE SOFTWARE. --> - + diff --git a/core/src/main/resources/lib/hudson/project/config-assignedLabel_bg.properties b/core/src/main/resources/lib/hudson/project/config-assignedLabel_bg.properties index ad363cc302056d3e273ea1bf73de44dedb77cbf9..3506632465f19723e128aecb1481d28856dba146 100644 --- a/core/src/main/resources/lib/hudson/project/config-assignedLabel_bg.properties +++ b/core/src/main/resources/lib/hudson/project/config-assignedLabel_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Restrict\ where\ this\ project\ can\ be\ run=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0438 \u043A\u044A\u0434\u0435 \u0434\u0430 \u0441\u0435 \u043F\u0443\u0441\u043A\u0430 \u0442\u043E\u0437\u0438 \u043F\u0440\u043E\u0435\u043A\u0442 +Restrict\ where\ this\ project\ can\ be\ run=\ + \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0430\u0432\u0430\u043d\u0435 \u043a\u044a\u0434\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 +Label\ Expression=\ + \u0418\u0437\u0440\u0430\u0437 \u0441 \u0435\u0442\u0438\u043a\u0435\u0442\u0438 diff --git a/core/src/main/resources/lib/hudson/project/config-assignedLabel_lt.properties b/core/src/main/resources/lib/hudson/project/config-assignedLabel_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..8c4ddda52c8a0c06b9fac3cbc88abb2f38aa8549 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-assignedLabel_lt.properties @@ -0,0 +1 @@ +Restrict\ where\ this\ project\ can\ be\ run=Apriboti, kur gali b\u016bti vykdomas \u0161is darbas diff --git a/core/src/main/resources/lib/hudson/project/config-assignedLabel_sr.properties b/core/src/main/resources/lib/hudson/project/config-assignedLabel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..5325e0a53ac556c0bf6a1481a17d4a58b693206d --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-assignedLabel_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Restrict\ where\ this\ project\ can\ be\ run=\u041E\u0433\u0440\u0430\u043D\u0438\u0447\u0438 \u0433\u0434\u0435 \u0441\u0435 \u043C\u043E\u0436\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u043A\u0430\u0442 +Label\ Expression=\u0418\u0437\u0440\u0430\u0437 \u043D\u0430 \u043B\u0430\u0431\u0435\u043B\u0438 +Tie\ this\ project\ to\ a\ node=\u041F\u043E\u0432\u0435\u0436\u0438 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u0441\u0430 \u043C\u0430\u0448\u0438\u043D\u043E\u043C diff --git a/core/src/main/resources/lib/hudson/project/config-blockWhenDownstreamBuilding_bg.properties b/core/src/main/resources/lib/hudson/project/config-blockWhenDownstreamBuilding_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..dcfe14f9f217ea467fbde7626f5d6f146c25ae53 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-blockWhenDownstreamBuilding_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Block\ build\ when\ downstream\ project\ is\ building=\ + \u041d\u0435\u0434\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043f\u0440\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0432\u0430\u0449 \u043f\u0440\u043e\u0435\u043a\u0442 diff --git a/core/src/main/resources/lib/hudson/project/config-blockWhenDownstreamBuilding_sr.properties b/core/src/main/resources/lib/hudson/project/config-blockWhenDownstreamBuilding_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..467994cca7bf80eb3df1919fda49a69525ea2b8e --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-blockWhenDownstreamBuilding_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Block\ build\ when\ downstream\ project\ is\ building=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u0430\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0434\u043E\u043A \u0441\u0435 \u0433\u0440\u0430\u0434\u0438 \u0437\u0430\u0432\u0438\u0441\u043D\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 diff --git a/core/src/main/resources/lib/hudson/project/config-blockWhenUpstreamBuilding_bg.properties b/core/src/main/resources/lib/hudson/project/config-blockWhenUpstreamBuilding_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..8bdeebb48e4bbc268fab79f7e05d01f17db20cff --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-blockWhenUpstreamBuilding_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Block\ build\ when\ upstream\ project\ is\ building=\ + \u041d\u0435\u0434\u043e\u043f\u0443\u0441\u043a\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043f\u0440\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 \u043d\u0430 \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0430\u0449 \u043f\u0440\u043e\u0435\u043a\u0442 diff --git a/core/src/main/resources/lib/hudson/project/config-blockWhenUpstreamBuilding_sr.properties b/core/src/main/resources/lib/hudson/project/config-blockWhenUpstreamBuilding_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..07c76a702ce34c43b09e1fd93c583e5c08416ce3 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-blockWhenUpstreamBuilding_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Block\ build\ when\ upstream\ project\ is\ building=\u0417\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u0430\u0458 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 \u0434\u043E\u043A \u0441\u0435 \u0433\u0440\u0430\u0434\u0438 upstream \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 diff --git a/core/src/main/resources/lib/hudson/project/config-buildWrappers_bg.properties b/core/src/main/resources/lib/hudson/project/config-buildWrappers_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..5747360b52719d536917dfe014421160273ccbc0 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-buildWrappers_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Build\ Environment=\ + \u0421\u0440\u0435\u0434\u0430 \u043f\u0440\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-buildWrappers_lt.properties b/core/src/main/resources/lib/hudson/project/config-buildWrappers_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..3d0f674c759a6dbdcd0f94e712125b640ab29cfd --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-buildWrappers_lt.properties @@ -0,0 +1 @@ +Build\ Environment=Vykdymo aplinka diff --git a/core/src/main/resources/lib/hudson/project/config-buildWrappers_sr.properties b/core/src/main/resources/lib/hudson/project/config-buildWrappers_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4a8151f6f405489ae56ba577fce94513893e536c --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-buildWrappers_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Build\ Environment=\u041E\u043A\u043E\u043B\u0438\u043D\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-builders_bg.properties b/core/src/main/resources/lib/hudson/project/config-builders_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..28548758230c8b7b8fe597db11876beb0e324ce0 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-builders_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add\ build\ step=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0441\u0442\u044a\u043f\u043a\u0430 \u043f\u0440\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Build=\ + \u0418\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-builders_pl.properties b/core/src/main/resources/lib/hudson/project/config-builders_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..2f4402e55bc01415370b7acac84e892564b13543 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-builders_pl.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Build=Budowanie +Add\ build\ step=Dodaj krok budowania diff --git a/core/src/main/resources/lib/hudson/project/config-builders_sr.properties b/core/src/main/resources/lib/hudson/project/config-builders_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1d0c2302bcdd78a245b2a43e3d1eb0ead2778698 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-builders_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Build=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Add\ build\ step=\u0414\u043E\u0434\u0430\u0458 \u043A\u043E\u0440\u0430\u043A \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0438 diff --git a/core/src/main/resources/lib/hudson/project/config-concurrentBuild_bg.properties b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..56051466868984febf038bbb1a6ad8e35adc5b7a --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_bg.properties @@ -0,0 +1,25 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# Execute concurrent builds if necessary +title.concurrentbuilds=\ + \u041f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442 \u0435\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u044f\u043a\u043e\u043b\u043a\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f diff --git a/core/src/main/resources/lib/hudson/project/config-concurrentBuild_lt.properties b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..18a3c530ccba3b83ac5d891ec644f39698d904ef --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_lt.properties @@ -0,0 +1 @@ +title.concurrentbuilds=Prireikus vykdyti paraleliai diff --git a/core/src/main/resources/lib/hudson/project/config-concurrentBuild_pl.properties b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_pl.properties index 14f974c09606df21200332686487d7fe982eb348..408c25f9e59dc343725722d79a8c07303ff9b6e2 100644 --- a/core/src/main/resources/lib/hudson/project/config-concurrentBuild_pl.properties +++ b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_pl.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -title.concurrentbuilds=Wykonuj buildy wsp\u00F3\u0142bie\u017Cnie, je\u015Bli zajdzie potrzeba +title.concurrentbuilds=Wykonuj zadania wsp\u00F3\u0142bie\u017Cnie, je\u015Bli zajdzie potrzeba diff --git a/core/src/main/resources/lib/hudson/project/config-concurrentBuild_sr.properties b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..7a677c66de69e2e445239b6b550368d40ee0705c --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-concurrentBuild_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +title.concurrentbuilds=\u0418\u0437\u0432\u0440\u045A\u0438 \u043F\u0430\u0440\u0430\u043B\u0435\u043B\u043D\u043E \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0430\u043A\u043E \u0431\u0443\u0434\u0435 \u0431\u0438\u043B\u043E \u043F\u043E\u0442\u0440\u0435\u0431\u043D\u043E diff --git a/core/src/main/resources/lib/hudson/project/config-customWorkspace_bg.properties b/core/src/main/resources/lib/hudson/project/config-customWorkspace_bg.properties index 3fa45a7e9b6771d35f0a6ddc5f0b248dc6a68054..118aec86f5ec09ee178dec396f119827dcbb8a7d 100644 --- a/core/src/main/resources/lib/hudson/project/config-customWorkspace_bg.properties +++ b/core/src/main/resources/lib/hudson/project/config-customWorkspace_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Directory=\u041F\u0430\u043F\u043A\u0430 -Use\ custom\ workspace=\u0418\u0437\u043F\u043E\u043B\u0437\u0432\u0430\u0439 \u0434\u0440\u0443\u0433\u0430 \u0440\u0430\u0431\u043E\u0442\u043D\u0430 \u043F\u0430\u043F\u043A\u0430 +Directory=\ + \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f +Use\ custom\ workspace=\ + \u0414\u0440\u0443\u0433\u0430 \u0440\u0430\u0431\u043e\u0442\u043d\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f diff --git a/core/src/main/resources/lib/hudson/project/config-customWorkspace_ja.properties b/core/src/main/resources/lib/hudson/project/config-customWorkspace_ja.properties index 5597e2694f443999af8906582b4911825b1be58c..0737289e39ba14d5273e65a7d4edee42a9edea83 100644 --- a/core/src/main/resources/lib/hudson/project/config-customWorkspace_ja.properties +++ b/core/src/main/resources/lib/hudson/project/config-customWorkspace_ja.properties @@ -1,24 +1,24 @@ -# The MIT License -# -# Copyright (c) 2004-2012, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. - -Use\ custom\ workspace=\u30ab\u30b9\u30bf\u30e0\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3092\u4f7f\u7528 +# The MIT License +# +# Copyright (c) 2004-2012, Sun Microsystems, Inc., Kohsuke Kawaguchi, Seiji Sogabe +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Use\ custom\ workspace=\u30ab\u30b9\u30bf\u30e0\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u3092\u4f7f\u7528 Directory=\u30c7\u30a3\u30ec\u30af\u30c8\u30ea \ No newline at end of file diff --git a/core/src/main/resources/lib/hudson/project/config-customWorkspace_lt.properties b/core/src/main/resources/lib/hudson/project/config-customWorkspace_lt.properties index af73618c5326b8fc6c34f5fa8216b8a430e9757c..246e175955d3506eceb4c5dd17d7c08c582e9a8e 100644 --- a/core/src/main/resources/lib/hudson/project/config-customWorkspace_lt.properties +++ b/core/src/main/resources/lib/hudson/project/config-customWorkspace_lt.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors - +Use\ custom\ workspace=Naudoti savo darbo aplink\u0105 Directory=Aplankas diff --git a/core/src/main/resources/lib/hudson/project/config-customWorkspace_sr.properties b/core/src/main/resources/lib/hudson/project/config-customWorkspace_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..f5857ad05b57a83fd1fb7b0820be4c606a86436c --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-customWorkspace_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Use\ custom\ workspace=\u041A\u043E\u0440\u0438\u0441\u0442\u0438 \u043F\u043E\u0440\u0443\u0447\u0435\u043D\u0438 \u0440\u0430\u0434\u043D\u0438 \u043F\u0440\u043E\u0441\u0442\u043E\u0440 +Directory=\u0414\u0438\u0440\u0435\u043A\u0442\u043E\u0440\u0438\u0458\u0443\u043C diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild.jelly b/core/src/main/resources/lib/hudson/project/config-disableBuild.jelly index 12738ee939e5b606a8ef5c88bec620c01eb970b0..024974a087d912f1a13ecd176b067c0d77a51495 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild.jelly +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild.jelly @@ -23,10 +23,10 @@ THE SOFTWARE. --> - - \ No newline at end of file + diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_bg.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_bg.properties index 8717d41f6d8360fdc86285aa015592e6c354dcb9..d640e48256c63230aec76103e8c680c4c71bdfec 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_bg.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=\u0417\u0430\u043C\u0440\u0430\u0437\u0438 \u0431\u0438\u043B\u0434\u0430 +Disable\ this\ project=\ + \u0418\u0437\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435 \u043d\u0430 \u0442\u043e\u0437\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 +Disable\ Build=\ + \u0421\u043f\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435\u0442\u043e +No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\ + \u0414\u043e \u0432\u043a\u043b\u044e\u0447\u0432\u0430\u043d\u0435\u0442\u043e \u043d\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_da.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_da.properties index a3677c10af2dc6cf3d518a6e0d7bca568e90a15a..66d121002c8f6e488918451c3eacb9cc9024162e 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_da.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_da.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Sl\u00e5 Byg Fra +Disable\ this\ project=Sl\u00e5 Byg Fra No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Der vil ikke blive udf\u00f8rt flere byg f\u00f8r projektet bliver sl\u00e5et til igen. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_de.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_de.properties index 37ac915fb45691f6929fee157d6adaeae0995fa6..22469017873cef5ea3376fc12013cd3dccd952e7 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_de.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_de.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Projekt deaktivieren +Disable\ this\ project=Projekt deaktivieren No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Es werden keine weiteren Builds ausgefhrt, bis das Projekt wieder reaktiviert wird. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_es.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_es.properties index 9005dc80a70edc71a5e4b6cb4a7efeb392b7d7b5..5e658f9de1e4446c6789f0eeb1517e064dc96a54 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_es.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_es.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Desactivar la ejecucin +Disable\ this\ project=Desactivar la ejecucin No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=No se ejecutar nuevamente hasta que el proyecto sea reactivado. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_fr.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_fr.properties index 8154a99aabdfb908494cca7e2ea25ccc583f6aa7..11facdcf214cc1e5903dc8465a28ba3dd1d74626 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_fr.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_fr.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=D\u00e9sactiver le projet +Disable\ this\ project=D\u00e9sactiver le projet No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Aucun nouveau build ne sera ex\u00e9cut\u00e9 jusqu''\u00e0 ce que le projet soit r\u00e9activ\u00e9. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_he.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_he.properties index effaf6d86e16764c70d9656f51e59b7381379914..0abc35b1bd68099b43f51325af99fdc4dc481248 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_he.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_he.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Disable\ Build=\u05E9\u05EA\u05E7 \u05D1\u05E0\u05D9\u05D4 +Disable\ this\ project=\u05E9\u05EA\u05E7 \u05D1\u05E0\u05D9\u05D4 No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u05D1\u05E0\u05D9\u05D5\u05EA \u05D7\u05D3\u05E9\u05D5\u05EA \u05DC\u05D0 \u05D9\u05D5\u05E4\u05E2\u05DC\u05D5 \u05E2\u05D3 \u05E9\u05D1\u05E0\u05D9\u05D4 \u05D6\u05D5 \u05EA\u05D0\u05D5\u05E4\u05E9\u05E8 \u05D1\u05E9\u05E0\u05D9\u05EA diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_hu.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_hu.properties index d2fb9342e74d5d1548b9b1cb11fb7af0b14dbec2..57047b4d70e16814d44bcb56720bd05a9d1646e5 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_hu.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_hu.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Disable\ Build=\u00C9p\u00EDt\u00E9s tilt\u00E1sa +Disable\ this\ project=\u00C9p\u00EDt\u00E9s tilt\u00E1sa No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=A projekt \u00FAjraenged\u00E9lyez\u00E9s\u00E9ig nem lesz \u00FAj ford\u00EDt\u00E1s elind\u00EDtva. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_it.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_it.properties index 43b7b20a6e610e3d787983361e341c31d347db69..d03554a8cfdaa0ad81413f436d23a097b2f75a3f 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_it.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_it.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Disabilita Build +Disable\ this\ project=Disabilita Build No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Non saranno effettuate nuove build finch\u00E8 questo progetto non sar\u00E0 riattivato. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_ja.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_ja.properties index 7828ac92cef8d0431be721b356cc2b4fe982b5d9..c04759fdc00d20c3c4817b40df0f6e25a15029e6 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_ja.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_ja.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=\u30d3\u30eb\u30c9\u7121\u52b9\u5316 +Disable\ this\ project=\u30d3\u30eb\u30c9\u7121\u52b9\u5316 No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u304c\u518d\u3073\u6709\u52b9\u5316\u3055\u308c\u308b\u307e\u3067\u65b0\u3057\u3044\u30d3\u30eb\u30c9\u306f\u884c\u308f\u308c\u306a\u304f\u306a\u308a\u307e\u3059 diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_ko.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_ko.properties index 5f0373ef610e4b9609acb9825f7397d844e495e7..355ef2daeaa2748304ee2c5a56ef8f98ef2cf995 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_ko.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_ko.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=\uBE4C\uB4DC \uC548\uD568 +Disable\ this\ project=\uBE4C\uB4DC \uC548\uD568 No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\uD504\uB85C\uC81D\uD2B8\uAC00 \uB2E4\uC2DC \uBE4C\uB4DC\uB97C \uD560 \uB54C\uAE4C\uC9C0 \uC0C8\uB85C\uC6B4 \uBE4C\uB4DC\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_lt.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_lt.properties index 87f83496b04c375a765830a38a4346c410c4af04..d75e08fca739ffcded693c08c3e2642adaf3a980 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_lt.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_lt.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors - -Disable\ Build=I\u0161jungti darb\u0105 +No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Darbas nebus vykdomas, kol nebus v\u0117l \u012fjungtas. +Disable\ this\ project=I\u0161jungti darb\u0105 diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_nb_NO.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_nb_NO.properties index a46d1293e1be50e24ad2fbbd05e5d6951ca97d1c..05e1045842d0a9b3bb23731afb1a16d2afc073f5 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_nb_NO.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_nb_NO.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Deaktiver bygg +Disable\ this\ project=Deaktiver bygg No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Ingen nye builds blir utf\u00F8rt f\u00F8r prosjektet er reaktivert. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_nl.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_nl.properties index 7364856e7cdbb7562f9c55c72c5ae527c76aee1a..8c6de81a117c70c5ea5eb5cf8ef1c20d3295a3bc 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_nl.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_nl.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Bouwen deactiveren +Disable\ this\ project=Bouwen deactiveren No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Er zullen geen nieuwe bouwpogingen uitgevoerd worden tot het project opnieuw geactiveerd wordt. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_pl.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_pl.properties index d1237e44e8518fc732e85b11ac1f20080e41e302..dbf0f019a5fbe15c5af325b77aa3ab6f35bcc41d 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_pl.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_pl.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Disable\ Build=Zablokuj build -No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Nowe buildy nie b\u0119d\u0105 wykonywane dop\u00F3ki projekt nie b\u0119dzie odblokowany +Disable\ this\ project=Zablokuj zadania +No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Nowe zadania nie b\u0119d\u0105 wykonywane dop\u00F3ki projekt nie b\u0119dzie odblokowany diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_pt_BR.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_pt_BR.properties index 9a7714e94512aed6a1607e7f963d37533058ac25..dc0d7e5c8b9d4fe4a2e13054b7c996645dd2e05f 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_pt_BR.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_pt_BR.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Desabilitar builds +Disable\ this\ project=Desabilitar builds No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Nenhum novo build ser\u00e1 executado at\u00e9 que este projeto seja habilitado novamente. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_ro.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_ro.properties index 580183571c70cffdae411e4f5d845ef37f799629..1b9a9a3661a28fc836204605dae1f3def45b28a1 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_ro.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_ro.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Disable\ Build=Dezactiveaza Build +Disable\ this\ project=Dezactiveaza Build No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Nici un build nou nu va fi executat pana cand proiectul nu va fi re-activat. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_ru.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_ru.properties index b05d70af55163bd9fcb1ecc38f04cd7f465d13fe..0ec634790b6b10d5f7875512eb902fea857f9363 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_ru.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_ru.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0438 +Disable\ this\ project=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u0431\u043e\u0440\u043a\u0438 No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u041d\u043e\u0432\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e\u043a\u0430 \u043e\u043f\u0446\u0438\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_sk.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_sk.properties index 1898b3d0da7e2b46edd5c8be934f29cb25402bb5..315b7a2623a9df12f84a7805019c4c97db19ac45 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_sk.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_sk.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Disable\ Build=Zak\u00E1\u017E zostavenie +Disable\ this\ project=Zak\u00E1\u017E zostavenie No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Nebud\u00FA sa da\u0165 sp\u00FA\u0161\u0165a\u0165 nov\u00E9 zostavenia, k\u00FDm sa projekt znova nepovol\u00ED. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_sr.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a1eb33cb22c9a35496893aae5ee49b3421a58fb1 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Disable\ this\ project=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438 \u043E\u0432\u0430\u0458 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +Disable\ Build=\u041E\u043D\u0435\u043C\u043E\u0433\u0443\u045B\u0438 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 +No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u041D\u043E\u0432\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u043D\u0435\u045B\u0435 \u0431\u0438\u0442\u0438 \u0438\u0437\u0432\u0440\u0448\u0438\u0432\u0430\u043D\u0430 \u0434\u043E\u043A \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442 \u043D\u0438\u0458\u0435 \u043F\u043E\u043D\u043E\u0432\u043E \u043E\u043C\u043E\u0433\u0443\u045B\u0435\u043D. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_sv_SE.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_sv_SE.properties index 9036e3e948c16c0261347e749a3cb3c4adba7629..dbe3eaddafcb96341a52faf491356867cacf6c43 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_sv_SE.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_sv_SE.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Inaktivera bygge +Disable\ this\ project=Inaktivera bygge No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Inga nya byggen utf\u00F6rs f\u00F6rr\u00E4n projektet aktiveras igen. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_tr.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_tr.properties index d4d53140f7410795b08ed949395b2402da359acb..15a58e51c62a81398011913ae7e54c4632e5aba7 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_tr.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_tr.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=Yap\u0131land\u0131rmay\u0131 devre d\u0131\u015f\u0131 b\u0131rak +Disable\ this\ project=Yap\u0131land\u0131rmay\u0131 devre d\u0131\u015f\u0131 b\u0131rak No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=Proje yeniden devreye al\u0131nana kadar yeni yap\u0131land\u0131rma \u00e7al\u0131\u015ft\u0131r\u0131lmayacakt\u0131r. diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_uk.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_uk.properties index f115b9e5f6ab39dfbfe1fc633518c2e718ef2439..7e01441537a6758d9d39042ace913534fc11d3b8 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_uk.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_uk.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Disable\ Build=\u0414\u0435\u0430\u043A\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 \u0431\u0456\u043B\u0434 +Disable\ this\ project=\u0414\u0435\u0430\u043A\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 \u0431\u0456\u043B\u0434 No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u041D\u0435 \u0431\u0443\u0434\u0443\u0432\u0430\u0442\u0438 \u0434\u043E\u043A\u0438 \u043F\u0440\u043E\u0435\u043A\u0442 \u043D\u0435 \u0434\u043E\u0437\u0432\u043E\u043B\u044F\u0442\u044C diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_CN.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_CN.properties index 2628879777994c3cee928cd1424988d4bfc8f078..a7293c119bc74643869bc88c3cbea4fc727549df 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_CN.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_CN.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=\u5173\u95ED\u6784\u5EFA +Disable\ this\ project=\u5173\u95ED\u6784\u5EFA No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u91CD\u65B0\u5F00\u542F\u6784\u5EFA\u524D\u4E0D\u5141\u8BB8\u8FDB\u884C\u65B0\u7684\u6784\u5EFA diff --git a/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_TW.properties b/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_TW.properties index f5715d18262d6c0602bcb5400c6e2a77fb95bd42..e929ce787ae68bcc4a2d96ee2de6eb7ba7dbffd9 100644 --- a/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_TW.properties +++ b/core/src/main/resources/lib/hudson/project/config-disableBuild_zh_TW.properties @@ -21,5 +21,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Disable\ Build=\u505C\u7528Build +Disable\ this\ project=\u505C\u7528Build No\ new\ builds\ will\ be\ executed\ until\ the\ project\ is\ re-enabled.=\u5728\u5C08\u6848\u88AB\u91CD\u65B0\u555F\u7528\u524D\u5C07\u4E0D\u518D\u57F7\u884C\u65B0\u7684\u5EFA\u69CB diff --git a/core/src/main/resources/lib/hudson/project/config-publishers2_bg.properties b/core/src/main/resources/lib/hudson/project/config-publishers2_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..72e7b5b91e54a4b3a82eba0eab0da5ee60c49e44 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-publishers2_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Add\ post-build\ action=\ + \u0414\u043e\u0431\u0430\u0432\u044f\u043d\u0435 \u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441\u043b\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Post-build\ Actions=\ + \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043b\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-publishers2_de.properties b/core/src/main/resources/lib/hudson/project/config-publishers2_de.properties index e078564074ac4aaf7d815a17a4ebb442b8c38f23..0fbb6ddfcd595a38a906e3a5036dedbedf320dfe 100644 --- a/core/src/main/resources/lib/hudson/project/config-publishers2_de.properties +++ b/core/src/main/resources/lib/hudson/project/config-publishers2_de.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Add\ post-build\ action=Post-Build-Schritt hinzuf\u00FCgen +Add\ post-build\ action=Post-Build-Aktion hinzuf\u00FCgen Post-build\ Actions=Post-Build-Aktionen diff --git a/core/src/main/resources/lib/hudson/project/config-publishers2_pl.properties b/core/src/main/resources/lib/hudson/project/config-publishers2_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..8023115a6b1f9eb786abbd0f37740c85eb3a89a8 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-publishers2_pl.properties @@ -0,0 +1,23 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Add\ post-build\ action=Dodaj akcje po budowaniu +Post-build\ Actions=Akcje po budowaniu diff --git a/core/src/main/resources/lib/hudson/project/config-publishers2_sr.properties b/core/src/main/resources/lib/hudson/project/config-publishers2_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..fb799a8a9e13266265c8b679d86f8799e154b98b --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-publishers2_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Post-build\ Actions=\u0410\u043A\u0446\u0438\u0458\u0435 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 +Add\ post-build\ action=\u0414\u043E\u0434\u0430\u0458 \u0430\u043A\u0446\u0438\u0458\u0443 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-publishers_bg.properties b/core/src/main/resources/lib/hudson/project/config-publishers_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..c2c5d37272920d4905295c2b17a135fd0307ed82 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-publishers_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Post-build\ Actions=\ + \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043b\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-publishers_sr.properties b/core/src/main/resources/lib/hudson/project/config-publishers_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4d777bfe2cb6108d7b7e484dc0f2adf458e4a695 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-publishers_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Post-build\ Actions=\u0410\u043A\u0446\u0438\u0458\u0435 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-quietPeriod_bg.properties b/core/src/main/resources/lib/hudson/project/config-quietPeriod_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..e9307063ae08af48153d01a6043f9df02ef56447 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-quietPeriod_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Quiet\ period=\ + \u0422\u0438\u0445 \u043f\u0435\u0440\u0438\u043e\u0434 +Number\ of\ seconds=\ + \u0421\u0435\u043a\u0443\u043d\u0434\u0438 diff --git a/core/src/main/resources/lib/hudson/project/config-quietPeriod_sr.properties b/core/src/main/resources/lib/hudson/project/config-quietPeriod_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d48d4a3d1c4aa1f93a1fe4f58a76786212556bfa --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-quietPeriod_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Number\ of\ seconds=\u0412\u0440\u043E\u0458 \u0441\u0435\u043A\u0443\u043D\u0434\u0438 +Quiet\ period=\u041F\u0435\u0440\u0438\u043E\u0434 \u0442\u0438\u0448\u0438\u043D\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-retryCount_bg.properties b/core/src/main/resources/lib/hudson/project/config-retryCount_bg.properties index fc4a87cd1f18c182bddbeac84fd1f676e80cc033..22c0ea5f8dee5f4df09e7d8e21c5ac1adad69722 100644 --- a/core/src/main/resources/lib/hudson/project/config-retryCount_bg.properties +++ b/core/src/main/resources/lib/hudson/project/config-retryCount_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Retry\ Count=\u0411\u0440\u043E\u0439 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u0438 \u043E\u043F\u0438\u0442\u0438 +Retry\ Count=\ + \u0411\u0440\u043e\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438 \u043e\u043f\u0438\u0442\u0438 +SCM\ checkout\ retry\ count=\ + \u0411\u0440\u043e\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u0438 \u043e\u043f\u0438\u0442\u0438 \u0437\u0430 \u0438\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435 \u043e\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-retryCount_lt.properties b/core/src/main/resources/lib/hudson/project/config-retryCount_lt.properties index 5c022d60b038280f2f884451737295e5a55f05d7..bf22b6ed09ed48a616737124dbfea1e4f22e6414 100644 --- a/core/src/main/resources/lib/hudson/project/config-retryCount_lt.properties +++ b/core/src/main/resources/lib/hudson/project/config-retryCount_lt.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors - -Retry\ Count=Pakartojim\u0173 skai\u010Dius +SCM\ checkout\ retry\ count=SCM i\u0161traukimo pakartojim\u0173 skai\u010dius +Retry\ Count=Pakartojim\u0173 skai\u010dius diff --git a/core/src/main/resources/lib/hudson/project/config-retryCount_sr.properties b/core/src/main/resources/lib/hudson/project/config-retryCount_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..b4f7670b626eb1430dd448c2674db2f5793aa2e6 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-retryCount_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +SCM\ checkout\ retry\ count=\u0411\u0440\u043E\u0458 \u043F\u043E\u043A\u0443\u0448\u0430\u0458\u0430 \u043F\u0440\u0435\u0443\u0437\u0438\u043C\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +Retry\ Count=\u0411\u0440\u043E\u0458 \u043F\u043E\u043A\u0443\u0448\u0430\u0458\u0430 diff --git a/core/src/main/resources/lib/hudson/project/config-scm.jelly b/core/src/main/resources/lib/hudson/project/config-scm.jelly index 6874bb2dfb9105526635d239d5b43bdb0214b177..0d3eb3bf1f022ee5b8c898dfc2affd44749dbf92 100644 --- a/core/src/main/resources/lib/hudson/project/config-scm.jelly +++ b/core/src/main/resources/lib/hudson/project/config-scm.jelly @@ -26,14 +26,14 @@ THE SOFTWARE. - - - + + - - + + - + + diff --git a/core/src/main/resources/lib/hudson/project/config-scm_bg.properties b/core/src/main/resources/lib/hudson/project/config-scm_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..e642c0123d8fa575633949eeab2366b1f63b6a61 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-scm_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +SCM\ Checkout\ Strategy=\ + \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0437\u0430 \u0438\u0437\u0442\u0435\u0433\u043b\u044f\u043d\u0435 \u043d\u0430 \u043a\u043e\u0434\u0430 \u043e\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0442\u0430 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 +Advanced\ Source\ Code\ Management=\ + \u0414\u043e\u043f\u044a\u043b\u043d\u0438\u0442\u0435\u043b\u043d\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0437\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u043d\u0430 \u043a\u043e\u0434\u0430 +Source\ Code\ Management=\ + \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430 \u043d\u0430 \u0432\u0435\u0440\u0441\u0438\u0438\u0442\u0435 \u043d\u0430 \u043a\u043e\u0434\u0430 diff --git a/core/src/main/resources/lib/hudson/project/config-scm_pl.properties b/core/src/main/resources/lib/hudson/project/config-scm_pl.properties index e0d39300b5a45dbbb254b7774240f4460b05a422..b8de9075d4ca265057e14a56ada57afd979b0bb5 100644 --- a/core/src/main/resources/lib/hudson/project/config-scm_pl.properties +++ b/core/src/main/resources/lib/hudson/project/config-scm_pl.properties @@ -1,3 +1,3 @@ # This file is under the MIT License by authors -Source\ Code\ Management=Repozytorium kodu \u017Ar\u00F3d\u0142owego +Source\ Code\ Management=Repozytorium kodu diff --git a/core/src/main/resources/lib/hudson/project/config-scm_sr.properties b/core/src/main/resources/lib/hudson/project/config-scm_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4d1d943b752cc7180ca94b035fb22d5e8c8e0929 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-scm_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Advanced\ Source\ Code\ Management=\u041D\u0430\u043F\u0440\u0435\u0434\u043D\u043E \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0435 \u0438\u0437\u0432\u043E\u0440\u043D\u0438\u043C \u043A\u043E\u0434\u043E\u043C +SCM\ Checkout\ Strategy=\u0428\u0430\u0431\u043B\u043E\u043D \u043F\u0440\u0435\u0434\u0443\u0437\u0438\u043C\u0430\u045A\u0430 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 +Source\ Code\ Management=\u0421\u0438\u0441\u0442\u0435\u043C \u0443\u043F\u0440\u0430\u0432\u0459\u0430\u045A\u0430 \u0438\u0437\u0432\u043E\u0440\u043D\u043E\u0433 \u043A\u043E\u0434\u0430 diff --git a/core/src/main/resources/lib/hudson/project/config-trigger_bg.properties b/core/src/main/resources/lib/hudson/project/config-trigger_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..85105bf429c7f5edff6a89a281af634e6c68bfd5 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-trigger_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Build\ Triggers=\ + \u0421\u043f\u0443\u0441\u044a\u0446\u0438 \u043d\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f\u0442\u0430 diff --git a/core/src/main/resources/lib/hudson/project/config-trigger_lt.properties b/core/src/main/resources/lib/hudson/project/config-trigger_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..8f00928b46ff32aaea0620020281d0ab63501774 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-trigger_lt.properties @@ -0,0 +1 @@ +Build\ Triggers=K\u016brimo i\u0161\u0161auk\u0117jai diff --git a/core/src/main/resources/lib/hudson/project/config-trigger_pl.properties b/core/src/main/resources/lib/hudson/project/config-trigger_pl.properties new file mode 100644 index 0000000000000000000000000000000000000000..f1fcb581d40ccf5caf25a0580b98c55f7a12b80c --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-trigger_pl.properties @@ -0,0 +1,22 @@ +# The MIT License +# +# Copyright (c) 2016, Damian Szczepanik +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +Build\ Triggers=Wyzwalacze budowania diff --git a/core/src/main/resources/lib/hudson/project/config-trigger_sr.properties b/core/src/main/resources/lib/hudson/project/config-trigger_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..aae2ee44edaea15d0a9af27c3a7f2063ae614c77 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-trigger_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Build\ Triggers=\u041F\u043E\u043A\u0440\u0435\u0442\u0430\u045A\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/lib/hudson/project/config-upstream-pseudo-trigger_lt.properties b/core/src/main/resources/lib/hudson/project/config-upstream-pseudo-trigger_lt.properties new file mode 100644 index 0000000000000000000000000000000000000000..9e588bad1cdd929a94257ae0a0fa7e4ce053f73b --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-upstream-pseudo-trigger_lt.properties @@ -0,0 +1,4 @@ +Build\ after\ other\ projects\ are\ built=Vykdyti po to, kai \u012fvykdyti kiti darbai. +Project\ names=Projekto pavadinimas +Projects\ names=Projekt\u0173 pavadinimai +Multiple\ projects\ can\ be\ specified\ like\ 'abc,\ def'=Galima nurodyti kelis projektus, pvz. \u201eabc, def\u201c. diff --git a/core/src/main/resources/lib/hudson/project/config-upstream-pseudo-trigger_sr.properties b/core/src/main/resources/lib/hudson/project/config-upstream-pseudo-trigger_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..2226c3544076098d8f001e1dc8358228f645b757 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/config-upstream-pseudo-trigger_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Project\ names=\u0418\u043C\u0435\u043D\u0430 \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0430 +Build\ after\ other\ projects\ are\ built=\u0418\u0437\u0433\u0440\u0430\u0434\u0438 \u043F\u043E\u0441\u043B\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442\u0430 +Multiple\ projects\ can\ be\ specified\ like\ 'abc,\ def'=\u0412\u0438\u0448\u0435 \u043F\u0440\u043E\u0458\u0435\u043A\u0430\u0442\u0430 \u043C\u043E\u0433\u0443 \u0441\u0435 \u043D\u0430\u0432\u0435\u0441\u0442\u0438 '\u0430\u0431\u0432,\u0433\u0434\u0435' diff --git a/core/src/main/resources/lib/hudson/project/configurable.jelly b/core/src/main/resources/lib/hudson/project/configurable.jelly index c58263ce8cda2242a2a547ee4ff63dabd63eda9c..435a804ab6bcbae4afe1010880039691215b118c 100644 --- a/core/src/main/resources/lib/hudson/project/configurable.jelly +++ b/core/src/main/resources/lib/hudson/project/configurable.jelly @@ -39,10 +39,10 @@ THE SOFTWARE. - + - + diff --git a/core/src/main/resources/lib/hudson/project/configurable_bg.properties b/core/src/main/resources/lib/hudson/project/configurable_bg.properties index 10ba94dfd7f71fd29d0a0a85a5b9541db08e7d6f..8ee8ca8a7f0055ea09a8e0a9228af0257c6c223f 100644 --- a/core/src/main/resources/lib/hudson/project/configurable_bg.properties +++ b/core/src/main/resources/lib/hudson/project/configurable_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright 2014 Jesse Glick. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ scheduled=\u041d\u0430\u0441\u0440\u043e\u0447\u0435\u043d \u0431\u0438\u043b\u0434 -Configure=\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u0430\u0439 -delete=\u0418\u0437\u0442\u0440\u0438\u0439 {0} -delete.confirm=\u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 {0} \u2018{1}\u2019? +Build\ scheduled=\ + \u041d\u0430\u0441\u0440\u043e\u0447\u0435\u043d\u043e \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0435 +Configure=\ + \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0432\u0430\u043d\u0435 +delete=\ + \u0418\u0437\u0442\u0440\u0438\u0432\u0430\u043d\u0435 \u043d\u0430 \u201e{0}\u201c +delete.confirm=\ + \u0421\u0438\u0433\u0443\u0440\u043d\u0438 \u043b\u0438 \u0441\u0442\u0435, \u0447\u0435 \u0438\u0441\u043a\u0430\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 {0} \u201e{1}\u201c? +View\ Configuration=\ + \u041f\u0440\u0435\u0433\u043b\u0435\u0434 \u043d\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438\u0442\u0435 diff --git a/core/src/main/resources/lib/hudson/project/configurable_de.properties b/core/src/main/resources/lib/hudson/project/configurable_de.properties index a883c645d9c78050bca9e17e9ee5756ff07f0d45..11f98e048f1789968b27f348d62549cffcbfa380 100644 --- a/core/src/main/resources/lib/hudson/project/configurable_de.properties +++ b/core/src/main/resources/lib/hudson/project/configurable_de.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -delete={0} L\u00f6schen +delete={0} l\u00f6schen Configure=Konfigurieren View\ Configuration=Konfiguration anzeigen Build\ scheduled=Build geplant diff --git a/core/src/main/resources/lib/hudson/project/configurable_pl.properties b/core/src/main/resources/lib/hudson/project/configurable_pl.properties index e93f340c5d8544b449c1a4f30609791eea563481..1e4c17522cdbad6206160841f9fca575821dc82f 100644 --- a/core/src/main/resources/lib/hudson/project/configurable_pl.properties +++ b/core/src/main/resources/lib/hudson/project/configurable_pl.properties @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ scheduled=Kompilacja zaplanowana +Build\ scheduled=Zadanie zaplanowano Configure=Konfiguruj View\ Configuration=Podgl\u0105d konfiguracji delete=Usu\u0144 {0} diff --git a/core/src/main/resources/lib/hudson/project/configurable_pt_BR.properties b/core/src/main/resources/lib/hudson/project/configurable_pt_BR.properties index d56206fcc2f809c80c467c6bed4208ee475a8faa..c5f0fa1a5d31f79e036723028fbfbe4a1fed3754 100644 --- a/core/src/main/resources/lib/hudson/project/configurable_pt_BR.properties +++ b/core/src/main/resources/lib/hudson/project/configurable_pt_BR.properties @@ -24,4 +24,4 @@ Build\ scheduled=build agendada delete=Excluir {0} Configure=Configurar View\ Configuration= Configurar a view -delete.confirm=Quer mesmo remover {0} '{1}'? +delete.confirm=Quer mesmo remover {0} ''{1}''? diff --git a/core/src/main/resources/lib/hudson/project/configurable_sr.properties b/core/src/main/resources/lib/hudson/project/configurable_sr.properties index 2b7db5910fcd4894cb9c2b2dd4f9f39af9b38ce7..436d9791d655b94302b73fdae0654a8546811a3b 100644 --- a/core/src/main/resources/lib/hudson/project/configurable_sr.properties +++ b/core/src/main/resources/lib/hudson/project/configurable_sr.properties @@ -20,7 +20,8 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ scheduled=Build je zakazan -Configure=Podesavana -delete=Obrisi {0} -delete.confirm=Da li \u017eeli\u0161 da obri\u0161e\u0161 {0} \u2018{1}\u2019? +Build\ scheduled=\u0418\u0437\u0433\u0440\u0430\u0434\u045A\u0430 \u0437\u0430\u043A\u0430\u0437\u0430\u043D\u0430 +Configure=\u041F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 +delete=\u0423\u043A\u043B\u043E\u043D\u0438 {0} +delete.confirm=\u0414\u0430 \u043B\u0438 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u0443\u043A\u043B\u043E\u043D\u0438\u0442\u0435 {0} \u2018{1}\u2019? +View\ Configuration=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u043F\u043E\u0434\u0435\u0448\u0430\u0432\u0430\u045A\u0430 diff --git a/core/src/main/resources/lib/hudson/project/console-link_bg.properties b/core/src/main/resources/lib/hudson/project/console-link_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..aa1d9fee7ffe368213075bcb9adf5de85bfd625c --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/console-link_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Console\ Output=\ + \u0418\u0437\u0445\u043e\u0434 \u043d\u0430 \u043a\u043e\u043d\u0437\u043e\u043b\u0430\u0442\u0430 +View\ as\ plain\ text=\ + \u0422\u0435\u043a\u0441\u0442\u043e\u0432 \u0444\u043e\u0440\u043c\u0430\u0442 diff --git a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_pt.properties b/core/src/main/resources/lib/hudson/project/console-link_de.properties similarity index 90% rename from test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_pt.properties rename to core/src/main/resources/lib/hudson/project/console-link_de.properties index ccd0ece5e40ded27fa163c8a384ef77d6f2c866a..b5a025f711711b8a26eb976e72c84ecc47cdf87a 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_pt.properties +++ b/core/src/main/resources/lib/hudson/project/console-link_de.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Copyright (c) 2016 # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Save=Gravar +View\ as\ plain\ text=Als unformatierten Text anzeigen +Console\ Output=Konsolenausgabe diff --git a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_es.properties b/core/src/main/resources/lib/hudson/project/console-link_pl.properties similarity index 90% rename from test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_es.properties rename to core/src/main/resources/lib/hudson/project/console-link_pl.properties index 14e5ddf52195242740774afba3901620ad541ea4..eddb13b42f41cbba27670d3495b74745cddae54b 100644 --- a/test/src/main/resources/org/jvnet/hudson/test/ComputerConnectorTester/configure_es.properties +++ b/core/src/main/resources/lib/hudson/project/console-link_pl.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-, Kohsuke Kawaguchi, Sun Microsystems, Inc., and a number of other of contributers +# Copyright (c) 2016, Damian Szczepanik # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,4 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Save=Guardar +View\ as\ plain\ text=Jako niesformatowany tekst +Console\ Output=Logi konsoli diff --git a/core/src/main/resources/lib/hudson/project/console-link_sr.properties b/core/src/main/resources/lib/hudson/project/console-link_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a58b54d29de39112121908c70f30b47c33ce5d98 --- /dev/null +++ b/core/src/main/resources/lib/hudson/project/console-link_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +View\ as\ plain\ text=\u041F\u0440\u0435\u0433\u043B\u0435\u0434 \u043E\u0431\u0438\u0447\u043D\u043E\u0433 \u0442\u0435\u043A\u0441\u0442\u0430 +Console\ Output=\u0418\u0441\u0445\u043E\u0434 \u0438\u0437 \u043A\u043E\u043D\u0437\u043E\u043B\u0435 diff --git a/core/src/main/resources/lib/hudson/project/upstream-downstream_bg.properties b/core/src/main/resources/lib/hudson/project/upstream-downstream_bg.properties index 50d2fd145e3b433e01d5beccd0075d90370d9bb0..fb46cd90ef8af4264bf39feb6f2360e0128782d6 100644 --- a/core/src/main/resources/lib/hudson/project/upstream-downstream_bg.properties +++ b/core/src/main/resources/lib/hudson/project/upstream-downstream_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Downstream\ Projects=\u041F\u043E\u0441\u043B\u0435\u0434\u0432\u0430\u0449\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0438 -Upstream\ Projects=\u041F\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0430\u0449\u0438 \u043F\u0440\u043E\u0435\u043A\u0442\u0438 +Downstream\ Projects=\u041f\u043e\u0441\u043b\u0435\u0434\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438 +Upstream\ Projects=\u041f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0430\u0449\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438 diff --git a/core/src/main/resources/lib/hudson/project/upstream-downstream_pl.properties b/core/src/main/resources/lib/hudson/project/upstream-downstream_pl.properties index e245fd0b97b9bae3cd97bd8e32a42cb3e71afe69..f995f201826c4563f3fcae6e934ead458621d049 100644 --- a/core/src/main/resources/lib/hudson/project/upstream-downstream_pl.properties +++ b/core/src/main/resources/lib/hudson/project/upstream-downstream_pl.properties @@ -20,5 +20,5 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Downstream\ Projects=Projekty mniej wa\u017Cne -Upstream\ Projects=Projekty wa\u017Cniejsze +Downstream\ Projects=Nast\u0119pne zale\u017Cne projekty +Upstream\ Projects=Poprzednie zale\u017Cne projekty diff --git a/core/src/main/resources/lib/hudson/project/upstream-downstream_sr.properties b/core/src/main/resources/lib/hudson/project/upstream-downstream_sr.properties index ae9d077e7b6c4343776b53f4654399d8f9982abc..3ce2c7835bfe1d1b18acd4ef308123bea81fac9b 100644 --- a/core/src/main/resources/lib/hudson/project/upstream-downstream_sr.properties +++ b/core/src/main/resources/lib/hudson/project/upstream-downstream_sr.properties @@ -1,4 +1,4 @@ # This file is under the MIT License by authors -Downstream\ Projects=Downstream projekti -Upstream\ Projects=Upstream projekti +Downstream\ Projects=Downstream \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 +Upstream\ Projects=Upstream \u043F\u0440\u043E\u0458\u0435\u043A\u0442\u0438 \ No newline at end of file diff --git a/core/src/main/resources/lib/hudson/propertyTable_bg.properties b/core/src/main/resources/lib/hudson/propertyTable_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..b8665be7b30a56e5fce604eddedd1e4f44c10677 --- /dev/null +++ b/core/src/main/resources/lib/hudson/propertyTable_bg.properties @@ -0,0 +1,26 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Name=\ + \u0418\u043c\u0435 +Value=\ + \u0421\u0442\u043e\u0439\u043d\u043e\u0441\u0442 diff --git a/core/src/main/resources/lib/hudson/propertyTable_sr.properties b/core/src/main/resources/lib/hudson/propertyTable_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..77ff4ea72af107982832d46040af776265661c2f --- /dev/null +++ b/core/src/main/resources/lib/hudson/propertyTable_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Value=\u0412\u0440\u0435\u0434\u043D\u043E\u0441\u0442 diff --git a/core/src/main/resources/lib/hudson/queue.jelly b/core/src/main/resources/lib/hudson/queue.jelly index 2a48bf96a8d48ecbbcc6f559fd55fbee4421c310..d66122f799ac660ac13e3348a4110331b93414f4 100644 --- a/core/src/main/resources/lib/hudson/queue.jelly +++ b/core/src/main/resources/lib/hudson/queue.jelly @@ -28,7 +28,7 @@ THE SOFTWARE. Displays the build queue as <l:pane> - Queue items to be displayed. Normally you should specify ${app.queue.approximateItemsQuickly}, + Queue items to be displayed. Normally you should specify ${app.queue.items}, but for example you can specify a sublist after some filtering to narrow down the list. @@ -91,7 +91,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/hudson/queue.properties b/core/src/main/resources/lib/hudson/queue.properties index d7b2a594e5da78f87dd5113b5f51cd25ee5ab8df..fc5be8a60a9e39d2b69156e9d706a6198235d153 100644 --- a/core/src/main/resources/lib/hudson/queue.properties +++ b/core/src/main/resources/lib/hudson/queue.properties @@ -1,3 +1,4 @@ Build\ Queue=Build Queue{0,choice,0#|0< ({0,number})} Filtered\ Build\ Queue=Filtered Build Queue{0,choice,0#|0< ({0,number})} -WaitingFor=Waiting for {0} \ No newline at end of file +WaitingFor=Waiting for {0} +confirm=Are you sure you want to cancel the queued run of {0}? diff --git a/core/src/main/resources/lib/hudson/queue_bg.properties b/core/src/main/resources/lib/hudson/queue_bg.properties index db5ba93fc825f80b2ee975a8e94a1ca4eee6b179..7aab265248af9c2c187ff5032b948884a1e6a91e 100644 --- a/core/src/main/resources/lib/hudson/queue_bg.properties +++ b/core/src/main/resources/lib/hudson/queue_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,17 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ Queue=\u041E\u043F\u0430\u0448\u043A\u0430 \u0437\u0430 \u0438\u0437\u043F\u044A\u043B\u043D\u0435\u043D\u0438\u0435{0,choice,0#|0< ({0,number})} -Jenkins\ is\ going\ to\ shut\ down.\ No\ further\ builds\ will\ be\ performed.=Jenkins \u0449\u0435 \u0441\u0435 \u0438\u0437\u043A\u043B\u044E\u0447\u0438. \u0414\u043E\u0431\u0430\u0432\u0435\u043D\u0438\u0442\u0435 \u0431\u0438\u043B\u0434\u043E\u0432\u0435 \u043D\u044F\u043C\u0430 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043F\u044A\u043B\u043D\u044F\u0442 -No\ builds\ in\ the\ queue.=\u041D\u044F\u043C\u0430 \u043A\u043E\u043C\u043F\u0438\u043B\u0430\u0446\u0438\u0438 \u0432 \u043E\u043F\u0430\u0448\u043A\u0430\u0442\u0430 -cancel=\u043E\u0442\u043A\u0430\u0437 +Build\ Queue=\ + \u041e\u043f\u0430\u0448\u043a\u0430 \u0437\u0430 \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435{0,choice,0#|0< ({0,number})} +Jenkins\ is\ going\ to\ shut\ down.\ No\ further\ builds\ will\ be\ performed.=\ + Jenkins \u0449\u0435 \u0441\u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0438. \u041d\u044f\u043c\u0430 \u0434\u0430 \u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0438\u0440\u0430\u0442 \u043d\u043e\u0432\u0438 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f. +No\ builds\ in\ the\ queue.=\ + \u041d\u044f\u043c\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f \u0432 \u043e\u043f\u0430\u0448\u043a\u0430\u0442\u0430. +cancel=\ + \u041e\u0442\u043c\u044f\u043d\u0430 +Unknown\ Task=\ + \u041d\u0435\u043f\u043e\u0437\u043d\u0430\u0442\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 +WaitingFor=\ + \u0418\u0437\u0447\u0430\u043a\u0432\u0430\u043d\u0435 \u043d\u0430 {0} +Filtered\ Build\ Queue=\ + \u0424\u0438\u043b\u0442\u0440\u0438\u0440\u0430\u043d\u0430 \u043e\u043f\u0430\u0448\u043a\u0430 \u0437\u0430 \u0438\u0437\u0433\u0440\u0430\u0436\u0434\u0430\u043d\u0438\u044f {0,choice,0#|0< ({0,number})} diff --git a/core/src/main/resources/lib/hudson/queue_pl.properties b/core/src/main/resources/lib/hudson/queue_pl.properties index 8d0ebf21913a08bd2479932b35017c4e1fc1d3b8..a326a1933ff7d8323cdf110cd0b34dfd74ea468a 100644 --- a/core/src/main/resources/lib/hudson/queue_pl.properties +++ b/core/src/main/resources/lib/hudson/queue_pl.properties @@ -20,9 +20,9 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Build\ Queue=Kolejka Budowania{0,choice,0#|0< ({0,number})} +Build\ Queue=Kolejka zada\u0144{0,choice,0#|0< ({0,number})} Jenkins\ is\ going\ to\ shut\ down.\ No\ further\ builds\ will\ be\ performed.=Jenkins przygotowuje si\u0119 do wy\u0142\u0105czenia. Uruchamianie nast\u0119pnych kompilacji zosta\u0142o wstrzymane. -No\ builds\ in\ the\ queue.=Nie ma build\u00F3w w kolejce +No\ builds\ in\ the\ queue.=Nie ma zada\u0144 w kolejce WaitingFor=Czeka na {0} WaitingSince=Oczekiwanie od {0} cancel=anuluj diff --git a/core/src/main/resources/lib/hudson/queue_sr.properties b/core/src/main/resources/lib/hudson/queue_sr.properties index 6e99e6d2278417c39386ad69c0be7907c2efde0f..e9d9219566b5a8da5f74bd1717ccd8e4cabd829b 100644 --- a/core/src/main/resources/lib/hudson/queue_sr.properties +++ b/core/src/main/resources/lib/hudson/queue_sr.properties @@ -1,6 +1,13 @@ # This file is under the MIT License by authors -Build\ Queue=Red Gradnje{0,choice,0#|0< ({0,number})} -No\ builds\ in\ the\ queue.=Nema zakazanih procesa -WaitingFor=\u010Ceka se {0} -WaitingSince=\u010Ceka od {0} +Build\ Queue= +No\ builds\ in\ the\ queue.=\u041D\u0435\u043C\u0430 \u0437\u0430\u043A\u0430\u0437\u0430\u043D\u0438\u0445 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +WaitingFor=\u0427\u0435\u043A\u0430 \u0441\u0435 {0} +WaitingSince=\u0427\u0435\u043A\u0430 \u043E\u0434 {0} +Filtered\ Build\ Queue=\u041F\u0440\u043E\u0444\u0438\u043B\u0442\u0440\u0438\u0440\u0430\u043D \u0440\u0435\u0434 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +Jenkins\ is\ going\ to\ shut\ down.\ No\ further\ builds\ will\ be\ performed.=Jenkins \u045B\u0435 \u0431\u0438\u0442\u0438 \u0443\u0433\u0430\u0448\u0435\u043D. \u0414\u043E\u0434\u0430\u0442\u043D\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 \u0441\u0435 \u043D\u0435\u045B\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438. +cancel=\u043E\u0442\u043A\u0430\u0436\u0438 +Unknown\ Task=\u041D\u0435\u043F\u043E\u0437\u043D\u0430\u0442\u0430 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0430 +confirm=\u0414\u0430 \u043B\u0438 \u0441\u0442\u0435 \u0441\u0438\u0433\u0443\u0440\u043D\u0438 \u0434\u0430 \u0436\u0435\u043B\u0438\u0442\u0435 \u0434\u0430 \u043E\u0442\u043A\u0430\u0436\u0435\u0442\u0435 \u0437\u0430\u043A\u0430\u0442\u0430\u043D\u0443 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0443 {0}?\ +Are you sure you want to cancel the queued run of {0}? +appears\ to\ be\ stuck=\u0458\u0435 \u0437\u0430\u0433\u043B\u0430\u0432\u0459\u0435\u043D\u043E diff --git a/core/src/main/resources/lib/hudson/queue_sv_SE.properties b/core/src/main/resources/lib/hudson/queue_sv_SE.properties index ee4967d15d5f0efc15dfb07ad974618358d1a423..55c9f582a4672057e75aee63ad784f36f6a0794a 100644 --- a/core/src/main/resources/lib/hudson/queue_sv_SE.properties +++ b/core/src/main/resources/lib/hudson/queue_sv_SE.properties @@ -23,7 +23,7 @@ Build\ Queue=Jobbk\u00F6{0,choice,0#|0< ({0,number})} Jenkins\ is\ going\ to\ shut\ down.\ No\ further\ builds\ will\ be\ performed.=Jenkins h\u00E5ller p\u00E5 att avslutas. Inga nya byggen kommer att utf\u00F6ras. No\ builds\ in\ the\ queue.=Inga k\u00F6ade byggen. -Unknown\ Task=\u00D6kand uppgift +Unknown\ Task=Ok\u00E4nd uppgift WaitingFor=V\u00E4ntar p\u00E5 {0} WaitingSince=V\u00E4ntar {0} cancel=avbryt diff --git a/core/src/main/resources/lib/hudson/rssBar_bg.properties b/core/src/main/resources/lib/hudson/rssBar_bg.properties index b95d4f1bd8d4d05e3912c166210965a55152c949..1682c0cf4c5b42baab36bd0df4f4fad4481e72a9 100644 --- a/core/src/main/resources/lib/hudson/rssBar_bg.properties +++ b/core/src/main/resources/lib/hudson/rssBar_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,7 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Legend=\u041B\u0435\u0433\u0435\u043D\u0434\u0430 -for\ all=\u0437\u0430 \u0432\u0441\u0438\u0447\u043A\u0438 -for\ failures=\u0437\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0438\u0442\u0435 -for\ just\ latest\ builds=\u0441\u0430\u043C\u043E \u0437\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0442\u0435 +Legend=\ + \u041b\u0435\u0433\u0435\u043d\u0434\u0430 +for\ all=\ + \u0417\u0430 \u0432\u0441\u0438\u0447\u043a\u0438 +for\ failures=\ + \u0417\u0430 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u0438\u0442\u0435 +for\ just\ latest\ builds=\ + \u0421\u0430\u043c\u043e \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0442\u0435 diff --git a/core/src/main/resources/lib/hudson/rssBar_sr.properties b/core/src/main/resources/lib/hudson/rssBar_sr.properties index 00ddfd30a332049408c593c405279f6f5212ed73..09b57a4dcc61399e2bf00cff2e60b85e1317916b 100644 --- a/core/src/main/resources/lib/hudson/rssBar_sr.properties +++ b/core/src/main/resources/lib/hudson/rssBar_sr.properties @@ -1,6 +1,6 @@ # This file is under the MIT License by authors -Legend=Legenda -for\ all=za sve -for\ failures=za neuspe\u0161ne -for\ just\ latest\ builds=samo za najnovije gradnje +Legend=\u041B\u0435\u0433\u0435\u043D\u0434\u0430 +for\ all=\u0437\u0430 \u0441\u0432\u0435 +for\ failures=\u0437\u0430 \u043D\u0435\u0443\u0441\u043F\u0435\u0448\u043D\u0435 +for\ just\ latest\ builds=\u0441\u0430\u043C\u043E \u0437\u0430 \u043D\u0430\u0458\u043D\u043E\u0432\u0438\u0458\u0435 \u0438\u0437\u0433\u0440\u0430\u0434\u045A\u0435 diff --git a/core/src/main/resources/lib/hudson/scriptConsole.jelly b/core/src/main/resources/lib/hudson/scriptConsole.jelly index bf2195db5b53b79b0867dd2b9a108f1e96133235..a0d24b32e0f77da0210d168222784c15ad9d8aa4 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole.jelly +++ b/core/src/main/resources/lib/hudson/scriptConsole.jelly @@ -26,12 +26,20 @@ THE SOFTWARE. Called from doScript() to display the execution result and the form. --> - + -

    ${%Script Console}

    + + + + + + + + +

    ${%Script Console}

    @@ -58,7 +66,7 @@ THE SOFTWARE.
    - ${%It is not possible to run scripts when slave is offline.} + ${%It is not possible to run scripts when agent is offline.} diff --git a/core/src/main/resources/lib/hudson/scriptConsole.properties b/core/src/main/resources/lib/hudson/scriptConsole.properties index 518475dc89de11dad1d2a77774e0af89b2a4f5c0..69c972a938fdaec0a663588b57b826995f32c8ee 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole.properties @@ -21,7 +21,7 @@ # THE SOFTWARE. description=\ - Type in an arbitrary Groovy script and \ + Type in an arbitrary Groovy script and \ execute it on the server. Useful for trouble-shooting and diagnostics. \ Use the \u2018println\u2019 command to see the output (if you use System.out, \ it will go to the server\u2019s stdout, which is harder to see.) Example: diff --git a/core/src/main/resources/lib/hudson/scriptConsole_bg.properties b/core/src/main/resources/lib/hudson/scriptConsole_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..b271dfcbf903b696aa84e42e1eef91e4066f8061 --- /dev/null +++ b/core/src/main/resources/lib/hudson/scriptConsole_bg.properties @@ -0,0 +1,48 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Result=\ + \u0420\u0435\u0437\u0443\u043b\u0442\u0430\u0442 +Script\ Console=\ + \u041a\u043e\u043d\u0437\u043e\u043b\u0430 \u0437\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435 +# \ +# All the classes from all the plugins are visible. jenkins.*, jenkins.model.*, hudson.*, and hudson.model.* are pre-imported. +description2=\ + \u0412\u0441\u0438\u0447\u043a\u0438 \u043a\u043b\u0430\u0441\u043e\u0432\u0435 \u043e\u0442 \u0432\u0441\u0438\u0447\u043a\u0438 \u043f\u0440\u0438\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u0430 \u0432\u0438\u0434\u0438\u043c\u0438. \u0421\u043b\u0435\u0434\u043d\u0438\u0442\u0435 \u043f\u0430\u043a\u0435\u0442\u0438 \u0441\u0430 \u0432\u043d\u0435\u0441\u0435\u043d\u0438:\ + jenkins.*, jenkins.model.*, hudson.* \u0438\ + hudson.model.* +It\ is\ not\ possible\ to\ run\ scripts\ when\ slave\ is\ offline.=\ + \u041a\u043e\u0433\u0430\u0442\u043e \u043f\u043e\u0434\u0447\u0438\u043d\u0435\u043d\u0438\u044f\u0442 \u043a\u043e\u043c\u043f\u044e\u0442\u044a\u0440 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435. +# \ +# Type in an arbitrary Groovy script and \ +# execute it on the server. Useful for trouble-shooting and diagnostics. \ +# Use the \u2018println\u2019 command to see the output (if you use System.out, \ +# it will go to the server\u2019s stdout, which is harder to see.) Example: +description=\ + \u0412\u044a\u0432\u0435\u0434\u0435\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u0435\u043d \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 Groovy\ + \u0438 \u0433\u043e \u0438\u0437\u043f\u044a\u043b\u043d\u0435\u0442\u0435 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430. \u041f\u043e\u043b\u0435\u0437\u043d\u043e \u0435 \u0437\u0430 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u0438 \u043a\u043e\u0440\u0438\u0433\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0438.\ + \u0417\u0430 \u0434\u0430 \u0438\u0437\u0432\u0435\u0434\u0435\u0442\u0435 \u0434\u0430\u043d\u043d\u0438 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430\u0439\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u0442\u0430 \u201eprintln\u201c. (System.out\ + \u043e\u0442\u0438\u0432\u0430 \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0438\u044f \u0438\u0437\u0445\u043e\u0434 \u043d\u0430 \u0441\u044a\u0440\u0432\u044a\u0440\u0430, \u043a\u043e\u0435\u0442\u043e \u0441\u0435 \u0441\u043b\u0435\u0434\u0438 \u043f\u043e-\u0442\u0440\u0443\u0434\u043d\u043e.) \u041f\u0440\u0438\u043c\u0435\u0440: +Run=\ + \u0418\u0437\u043f\u044a\u043b\u043d\u0435\u043d\u0438\u0435 +It\ is\ not\ possible\ to\ run\ scripts\ when\ agent\ is\ offline.=\ + \u041a\u043e\u0433\u0430\u0442\u043e \u0430\u0433\u0435\u043d\u0442\u044a\u0442 \u043d\u0435 \u0435 \u043d\u0430 \u043b\u0438\u043d\u0438\u044f, \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u044a\u043b\u043d\u044f\u0432\u0430\u0442 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u0435. diff --git a/core/src/main/resources/lib/hudson/scriptConsole_da.properties b/core/src/main/resources/lib/hudson/scriptConsole_da.properties index 4593448d0097efb52f5803bb662db0de579df4a2..cf1afc4cbb27ea09e217b166ddddc0955dc3e17d 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_da.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_da.properties @@ -23,7 +23,7 @@ Result=Resultat Run=K\u00f8r Script\ Console=Skriptkonsol -description=Indtast et Groovyskript og \ +description=Indtast et Groovyskript og \ k\u00f8r det p\u00e5 serveren. Nyttigt til fejlfinding og diagnostik. \ Benyt ''println'' kommandoen for at se output (hvis du bruger System.out, \ vil output g\u00e5 til serverens stdout, hvilket kan v\u00e6re sv\u00e6rere at finde.) Eksempel: diff --git a/core/src/main/resources/lib/hudson/scriptConsole_de.properties b/core/src/main/resources/lib/hudson/scriptConsole_de.properties index 488a8941a9f57884b3cdb9a8ef6d5a754461631a..df68cd002f6b4f94ef4ac3cd284f148e66b98acd 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_de.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_de.properties @@ -23,7 +23,7 @@ Script\ Console=Skript-Konsole Result=Ergebnis Run=Ausfhren -description=Geben Sie ein beliebiges Groovy-Skript \ +description=Geben Sie ein beliebiges Groovy-Skript \ ein und fhren Sie dieses auf dem Server aus. Dies ist ntzlich bei der Fehlersuche und zur Diagnostik. \ Verwenden Sie das ''println''-Kommando, um Ausgaben sichtbar zu machen (wenn Sie System.out \ verwenden, gehen die Ausgaben auf die Standardausgabe (STDOUT) des Servers, die schwieriger \ diff --git a/core/src/main/resources/lib/hudson/scriptConsole_es.properties b/core/src/main/resources/lib/hudson/scriptConsole_es.properties index 9531839f146aa3c72fd321e1850da9bf944f2148..d7df2acb0d19b25f4559adf848b7eb57f2f22b8c 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_es.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_es.properties @@ -21,7 +21,7 @@ # THE SOFTWARE. description=\ - Escribe un ''script'' Groovy script y \ + Escribe un ''script'' Groovy script y \ ejecutal en el servidor. Es til para depurar e investigar problemas. \ Usa ''println'' para ver la salida (si usas System.out, se escribir \ en la salida ''stdout'' del servidor, lo que es ms difcil de visualizar). Ejemplo: diff --git a/core/src/main/resources/lib/hudson/scriptConsole_fr.properties b/core/src/main/resources/lib/hudson/scriptConsole_fr.properties index ea256983eb4cae91b993f990e6c2746d677e5119..6f17fa4ae47f4488324ef3dc4f67402c5b048754 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_fr.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_fr.properties @@ -23,6 +23,6 @@ Script\ Console=Console de script Result=Rsultat Run=Excuter -description=Vous pouvez saisir ici un script Groovy quelconque pour l\u2019ex\u00E9cuter sur le serveur.
    Utile pour diagnostiquer et r\u00E9soudre des probl\u00E8mes.
    Utilisez la commande "println" pour voir la sortie (si vous utilisez System.out, cela ira vers la sortie standard du serveur, qui est plus complexe \u00E0 retrouver.)
    Par exemple : +description=Vous pouvez saisir ici un script Groovy quelconque pour l\u2019ex\u00E9cuter sur le serveur.
    Utile pour diagnostiquer et r\u00E9soudre des probl\u00E8mes.
    Utilisez la commande "println" pour voir la sortie (si vous utilisez System.out, cela ira vers la sortie standard du serveur, qui est plus complexe \u00E0 retrouver.)
    Par exemple : description2=Toutes les classes de tous les plugins sont visibles. jenkins.*, jenkins.model.*, hudson.*, et hudson.model.* sont pr\u00E9-import\u00E9es. diff --git a/core/src/main/resources/lib/hudson/scriptConsole_ja.properties b/core/src/main/resources/lib/hudson/scriptConsole_ja.properties index da54325180e398e7832f68436bdbb41e5b804530..136087823925c0b5dc5831f3c5ae9387f0d2cbf5 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_ja.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_ja.properties @@ -24,7 +24,7 @@ Script\ Console=\u30b9\u30af\u30ea\u30d7\u30c8\u30b3\u30f3\u30bd\u30fc\u30eb Run=\u5b9f\u884c Result=\u7d50\u679c description= \ - \u4efb\u610f\u306eGroovy\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u5165\u529b\u3057\u3066\u3001 \ + \u4efb\u610f\u306eGroovy\u30b9\u30af\u30ea\u30d7\u30c8\u3092\u5165\u529b\u3057\u3066\u3001 \ \u30b5\u30fc\u30d0\u30fc\u4e0a\u3067\u5b9f\u884c\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u30c8\u30e9\u30d6\u30eb\u30b7\u30e5\u30fc\u30c6\u30a3\u30f3\u30b0\u3084\u8a3a\u65ad\u306b\u4fbf\u5229\u3067\u3059\u3002 \ \u51fa\u529b\u3092\u898b\u308b\u306b\u306f''println''\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3057\u307e\u3059 \ (System.out\u3092\u4f7f\u7528\u3059\u308b\u3068\u30b5\u30fc\u30d0\u30fc\u306e\u6a19\u6e96\u51fa\u529b\u306b\u51fa\u529b\u3055\u308c\u307e\u3059\u304c\u3001\u898b\u306b\u304f\u3044\u3067\u3059\uff09\u3002\u4f8b: diff --git a/core/src/main/resources/lib/hudson/scriptConsole_ko.properties b/core/src/main/resources/lib/hudson/scriptConsole_ko.properties index 6e8c7a8bf99564a58757d95f367e7a2e5626bfa9..523c9f712664aeec1069dc144ab788c2f4c76aa9 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_ko.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_ko.properties @@ -23,7 +23,7 @@ Result=\uACB0\uACFC Run=\uC2E4\uD589 Script\ Console=\uC2A4\uD06C\uB9BD\uD2B8 \uCF58\uC194 -description=\uC784\uC758\uC758 Groovy\uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC785\uB825\uD558\uC5EC \uC11C\uBC84\uC5D0\uC11C \uC2E4\uD589\uD569\uB2C8\uB2E4.
    \uBB38\uC81C\uD574\uACB0\uACFC \uC9C4\uB2E8\uC2DC\uC5D0 \uC720\uC6A9\uD569\uB2C8\uB2E4. \uCD9C\uB825\uBB3C\uC744 \uBCF4\uB824\uBA74 ''println'' \uBA85\uB839\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.
    (System.out\uB97C \uC0AC\uC6A9\uD558\uBA74 \uC11C\uBC84\uC758 \uD45C\uC900\uCD9C\uB825\uC73C\uB85C \uBCF4\uB0B4\uC9C0\uACE0, \uAC00\uB3C5\uC131\uC774 \uB5A8\uC5B4\uC9D1\uB2C8\uB2E4.)

    +description=\uC784\uC758\uC758 Groovy\uC2A4\uD06C\uB9BD\uD2B8\uB97C \uC785\uB825\uD558\uC5EC \uC11C\uBC84\uC5D0\uC11C \uC2E4\uD589\uD569\uB2C8\uB2E4.
    \uBB38\uC81C\uD574\uACB0\uACFC \uC9C4\uB2E8\uC2DC\uC5D0 \uC720\uC6A9\uD569\uB2C8\uB2E4. \uCD9C\uB825\uBB3C\uC744 \uBCF4\uB824\uBA74 ''println'' \uBA85\uB839\uC744 \uC0AC\uC6A9\uD558\uC138\uC694.
    (System.out\uB97C \uC0AC\uC6A9\uD558\uBA74 \uC11C\uBC84\uC758 \uD45C\uC900\uCD9C\uB825\uC73C\uB85C \uBCF4\uB0B4\uC9C0\uACE0, \uAC00\uB3C5\uC131\uC774 \uB5A8\uC5B4\uC9D1\uB2C8\uB2E4.)

    \uC608\uC81C:
    \uC608\uC81C:
    diff --git a/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties b/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties index 524bfd281b04bcbc999f65e475169931db5f6b0e..ef03bcb2ec48b0841d7a5c0b127aad22d237b103 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_nb_NO.properties @@ -22,7 +22,7 @@ Run=Kj\u00F8r Script\ Console=Skript-konsoll -description=Skriv inn et vilk\u00E5rlig Groovy script og kj\u00F8r det p\u00E5 serveren. Nyttig i forbindelse med feils\u00F8king og diagnostisering. Bruke "println"-kommandoen for \u00E5 se utdataene. (Hvis du bruker System.out havner det i serverens STDOUT, som er vanskeligere \u00E5 se. +description=Skriv inn et vilk\u00E5rlig Groovy script og kj\u00F8r det p\u00E5 serveren. Nyttig i forbindelse med feils\u00F8king og diagnostisering. Bruke "println"-kommandoen for \u00E5 se utdataene. (Hvis du bruker System.out havner det i serverens STDOUT, som er vanskeligere \u00E5 se. Eksempel: println(hudson.model.Hudson.instance.pluginManager.plugins) diff --git a/core/src/main/resources/lib/hudson/scriptConsole_nl.properties b/core/src/main/resources/lib/hudson/scriptConsole_nl.properties index 68b9130c6f38bdc9358edfbc6dd749b512814afd..263f9a0fa13106c6892d0c865c13d1fb72814e85 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_nl.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_nl.properties @@ -23,4 +23,4 @@ Script\ Console=Scriptconsole Run=Voer uit Result=Resultaat -description=Geef een willekeurig Groovy script in en voer het uit op de server. Dit is nuttig voor troubleshooting en het stellen van diagnoses. Gebruik het "println"-commando om uitvoer te zien (wanneer je System.out gebruikt, gaat de uitvoer naar de stdout van de server, en deze is moeilijker te bekijken.) Bijvoorbeeld: +description=Geef een willekeurig Groovy script in en voer het uit op de server. Dit is nuttig voor troubleshooting en het stellen van diagnoses. Gebruik het "println"-commando om uitvoer te zien (wanneer je System.out gebruikt, gaat de uitvoer naar de stdout van de server, en deze is moeilijker te bekijken.) Bijvoorbeeld: diff --git a/core/src/main/resources/lib/hudson/scriptConsole_pl.properties b/core/src/main/resources/lib/hudson/scriptConsole_pl.properties index bb22871fb60c8cdc83a960cc33d42088efaf4e0c..666edf81bf48ab405d1f4f0c086d248483ea1c0a 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_pl.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_pl.properties @@ -3,6 +3,6 @@ Result=Rezultat Run=Wykonaj Script\ Console=Konsola Skrypt\u00F3w -description=Wpisz skrypt Groovy script i wykonaj go na serwerze. U\u017Cyteczne w przypadku problem\u00F3w i diagnostyki. U\u017Cyj komendy ''''println'''' aby zobaczy\u0107 wynik (je\u015Bli u\u017Cyjesz System.out, wynik b\u0119dzie trudniejszy do znalezienia). Przyk\u0142ad: +description=Wpisz skrypt Groovy script i wykonaj go na serwerze. U\u017Cyteczne w przypadku problem\u00F3w i diagnostyki. U\u017Cyj komendy ''''println'''' aby zobaczy\u0107 wynik (je\u015Bli u\u017Cyjesz System.out, wynik b\u0119dzie trudniejszy do znalezienia). Przyk\u0142ad: description2=Wszystkie klasy ze wszystkich dodatk\u00F3w s\u0105 widoczne. jenkins.*, jenkins.model.*, hudson.*, i hudson.model.* s\u0105 wst\u0119pnie zaimportowane. diff --git a/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties b/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties index 04f4d0a53fefb54995b5cb970922eb1c7e3bbab3..9013530e50cded5a22648686010f78becd0dfd61 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_pt_BR.properties @@ -23,11 +23,11 @@ Script\ Console=Console de script Run=Executar Result=Resultado -# Type in an arbitrary Groovy script and \ +# Type in an arbitrary Groovy script and \ # execute it on the server. Useful for trouble-shooting and diagnostics. \ # Use the ''println'' command to see the output (if you use System.out, \ # it will go to the server''s stdout, which is harder to see.) Example: -description=Digite um comando Groovy script qualquer e \ +description=Digite um comando Groovy script qualquer e \ execute-o no servidor. \u00DAtil para resolu\u00E7\u00E3o de problemas e diagn\u00F3sticos. \ Use o comando "println" para ver a sa\u00EDda (se voc\u00EA usa System.out, \ ele ir\u00E1 para o log do servidor, que \u00E9 mais dif\u00EDcil de ver). Exemplo: diff --git a/core/src/main/resources/lib/hudson/scriptConsole_ru.properties b/core/src/main/resources/lib/hudson/scriptConsole_ru.properties index 7149e33861877cd25df954871a983c3db1b89e72..b0b68ceaf595a26195f2a3f49e090406ea539d34 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_ru.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_ru.properties @@ -23,5 +23,5 @@ Script\ Console=\u041a\u043e\u043d\u0441\u043e\u043b\u044c Result=\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 Run=\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c -description=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 Groovy \u0441\u043A\u0440\u0438\u043F\u0442 \u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0435\u0433\u043E \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041F\u043E\u043B\u0435\u0437\u043D\u043E \u043F\u0440\u0438 \u0443\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0438 \u043D\u0435\u043F\u043E\u043B\u0430\u0434\u043E\u043A \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u0438. \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 "println" \u0434\u043B\u044F \u043F\u0435\u0447\u0430\u0442\u0438 \u0432 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u044B\u0439 \u0432\u044B\u0432\u043E\u0434 (\u0435\u0441\u043B\u0438 \u0432\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435\u0441\u044C System.out, \u0442\u043E \u0432\u044B\u0432\u043E\u0434 \u043F\u043E\u0439\u0434\u0451\u0442 \u0432 stdout \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u043B\u043E\u0436\u043D\u0435\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044C). \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: +description=\u0412\u0432\u0435\u0434\u0438\u0442\u0435 Groovy \u0441\u043A\u0440\u0438\u043F\u0442 \u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u0435\u0433\u043E \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041F\u043E\u043B\u0435\u0437\u043D\u043E \u043F\u0440\u0438 \u0443\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u0438 \u043D\u0435\u043F\u043E\u043B\u0430\u0434\u043E\u043A \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u0438. \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0439\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 "println" \u0434\u043B\u044F \u043F\u0435\u0447\u0430\u0442\u0438 \u0432 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u044B\u0439 \u0432\u044B\u0432\u043E\u0434 (\u0435\u0441\u043B\u0438 \u0432\u044B \u0432\u043E\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u0442\u0435\u0441\u044C System.out, \u0442\u043E \u0432\u044B\u0432\u043E\u0434 \u043F\u043E\u0439\u0434\u0451\u0442 \u0432 stdout \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u043B\u043E\u0436\u043D\u0435\u0435 \u0443\u0432\u0438\u0434\u0435\u0442\u044C). \u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440: description2=\u0412\u0441\u0435 \u043A\u043B\u0430\u0441\u0441\u044B \u0438\u0437 \u0432\u0441\u0435\u0445 \u043F\u043B\u0430\u0433\u0438\u043D\u043E\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B. jenkins.*, jenkins.model.*, hudson.* \u0438 hudson.model.* \u0443\u0436\u0435 \u0438\u043C\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u044B \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E. diff --git a/core/src/main/resources/lib/hudson/scriptConsole_sr.properties b/core/src/main/resources/lib/hudson/scriptConsole_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..d460d45ff9f8979866a08e2d02526b4786875f97 --- /dev/null +++ b/core/src/main/resources/lib/hudson/scriptConsole_sr.properties @@ -0,0 +1,13 @@ +# This file is under the MIT License by authors + +Script\ Console=\u041A\u043E\u043D\u0437\u043E\u043B\u0430 +description=\ + \u0423\u043D\u0435\u0441\u0438\u0442\u0435 \u0430\u0440\u0431\u0438\u0442\u0440\u0430\u0440\u043D\u0438 Groovy \u0441\u043A\u0440\u0443\u043F\u0442\u0443 \u0438 \ + \u0438\u0437\u0432\u0440\u0448\u0438 \u0458\u0435 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0443. \u041A\u043E\u0440\u0438\u0441\u043D\u043E \u043A\u043E\u0434 \u0440\u0435\u0448\u0430\u0432\u0430\u045A\u0435 \u043F\u0440\u043E\u0431\u043B\u0435\u043C\u0430 \u0438 \u0434\u0438\u0430\u0433\u043D\u043E\u0441\u0442\u0438\u043A\u043E\u043C. \ + \u041A\u043E\u0440\u0438\u0441\u0442\u0438\u0442\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u0443 \u2018println\u2019 \u0434\u0430 \u0432\u0438\u0434\u0438\u0442\u0435 \u0438\u0441\u0445\u043E\u0434 (\u0431\u0438\u045B\u0435 \u043F\u0440\u0435\u0443\u0441\u043C\u0435\u0440\u0435\u043D\u043E \ + System.out \u043F\u0440\u0435\u043C\u0430 stdout \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0448\u0442\u043E \u0441\u0435 \u0442\u0435\u0436\u0435 \u0447\u0438\u0442\u0430.) \u041F\u0440\u0438\u043C\u0435\u0440: +description2=\ + \u0421\u0432\u0435 \u043A\u043B\u0430\u0441\u0435 \u0441\u0430 \u0441\u0432\u0438\u0445 \u043C\u043E\u0434\u0443\u043B\u0430 \u0441\u0443 \u0432\u0438\u0434\u0459\u0438\u0432\u0438. jenkins.*, jenkins.model.*, hudson.*, and hudson.model.* \u0441\u0443 \u043F\u0440\u0435\u0442\u0445\u043E\u0434\u043D\u043E \u0443\u0447\u0438\u0442\u0430\u043D\u0430. +Run=\u0418\u0437\u0432\u0440\u0448\u0438 +Result=\u0420\u0435\u0437\u0443\u043B\u0442\u0430\u0442 +It\ is\ not\ possible\ to\ run\ scripts\ when\ agent\ is\ offline.=\u041D\u0438\u0458\u0435 \u043C\u043E\u0433\u0443\u045B\u0435 \u0438\u0437\u0432\u0440\u0448\u0438\u0442\u0438 \u0441\u043A\u0438\u043F\u0442\u043E\u0432\u0435 \u043A\u0430\u0434\u0430 \u0430\u0433\u0435\u043D\u0442 \u043D\u0438\u0458\u0435 \u043F\u043E\u0432\u0435\u0437\u0430\u043D. diff --git a/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties b/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties index 1710048f28de0d73f0176ab068bf6cdb5066af83..eb6893c691d2421dfd1f5baaed2a35b10ab60836 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_sv_SE.properties @@ -23,5 +23,5 @@ Result=Resultat Run=K\u00F6r Script\ Console=Skriptkonsoll -description=Skriv in ett godtyckligt Groovy skript och k\u00F6r den p\u00E5 noden. Detta \u00E4r anv\u00E4ndbart vid fels\u00F6kning och diagnostik. Anv\u00E4nd''''println''''kommandot f\u00F6r att se resultatet (om du anv\u00E4nder System.out kommer det att g\u00E5 till serverns standard ut, som \u00E4r sv\u00E5rare att se.) Exempel: +description=Skriv in ett godtyckligt Groovy skript och k\u00F6r den p\u00E5 noden. Detta \u00E4r anv\u00E4ndbart vid fels\u00F6kning och diagnostik. Anv\u00E4nd''''println''''kommandot f\u00F6r att se resultatet (om du anv\u00E4nder System.out kommer det att g\u00E5 till serverns standard ut, som \u00E4r sv\u00E5rare att se.) Exempel: description2=Alla klasser fr\u00E5n pluginet \u00E4r synliga. jenkins.*, jenkins.model.*, hudson.*, and hudson.model.* are pre-imported. diff --git a/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties b/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties index 0a474875c71bbe6a9b154497d4a52ab7f101d52c..6e968873db38ed5d3866bd92f96c5351a7c6b9b0 100644 --- a/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties +++ b/core/src/main/resources/lib/hudson/scriptConsole_zh_TW.properties @@ -23,7 +23,7 @@ Script\ Console=Script \u4e3b\u63a7\u53f0 description=\ - \u8f38\u5165\u4efb\u610f\u7684 Groovy Script\uff0c\u5728\u4f3a\u670d\u5668\u4e0a\u57f7\u884c\u3002\ + \u8f38\u5165\u4efb\u610f\u7684 Groovy Script\uff0c\u5728\u4f3a\u670d\u5668\u4e0a\u57f7\u884c\u3002\ \u7591\u96e3\u6392\u89e3\u6216\u8a3a\u65b7\u6642\u5f88\u6709\u7528\u3002\u4f7f\u7528 "println" \u6307\u4ee4\u53ef\u4ee5\u770b\u5230\u8f38\u51fa\u7d50\u679c \ (\u5982\u679c\u60a8\u4f7f\u7528 System.out\uff0c\u5c07\u8f38\u51fa\u5230\u4f3a\u670d\u5668\u4e0a\u7684 stdout\uff0c\u6703\u6bd4\u8f03\u96e3\u770b\u5230)\u3002\u7bc4\u4f8b: description2=\u6240\u6709\u5916\u639B\u7A0B\u5F0F\u7684 class \u90FD\u53EF\u4EE5\u4F7F\u7528\u3002\u5DF2\u9810\u5148 import \u4E86 jenkins.*, jenkins.model.*, hudson.* \u53CA hudson.model.* \u7B49 package\u3002 diff --git a/core/src/main/resources/lib/hudson/thirdPartyLicenses_bg.properties b/core/src/main/resources/lib/hudson/thirdPartyLicenses_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..b0d6ce3e078b6bdd1e2f6161b6db7fd6096230f3 --- /dev/null +++ b/core/src/main/resources/lib/hudson/thirdPartyLicenses_bg.properties @@ -0,0 +1,28 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Name=\ + \u0418\u043c\u0435 +License=\ + \u041b\u0438\u0446\u0435\u043d\u0437 +Maven\ ID=\ + \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0432 Maven diff --git a/core/src/main/resources/lib/hudson/thirdPartyLicenses_sr.properties b/core/src/main/resources/lib/hudson/thirdPartyLicenses_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..4b3e12ab10b7d25e2ca5502f9452407ec0b20c8a --- /dev/null +++ b/core/src/main/resources/lib/hudson/thirdPartyLicenses_sr.properties @@ -0,0 +1,5 @@ +# This file is under the MIT License by authors + +Name=\u0418\u043C\u0435 +Maven\ ID=\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0437\u0430 Maven +License=\u041B\u0438\u0446\u0435\u043D\u0446\u0430 diff --git a/core/src/main/resources/lib/layout/breadcrumbBar_bg.properties b/core/src/main/resources/lib/layout/breadcrumbBar_bg.properties index 238e217be205d06aa72419a469c891a95e3e28ff..0196e2201b282d51da2ec7a6853334ae5d15fd7e 100644 --- a/core/src/main/resources/lib/layout/breadcrumbBar_bg.properties +++ b/core/src/main/resources/lib/layout/breadcrumbBar_bg.properties @@ -1,4 +1,26 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -DISABLE\ AUTO\ REFRESH=\u0417\u0430\u0431\u0440\u0430\u043D\u0438 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u043D\u043E \u043F\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043D\u0435 -ENABLE\ AUTO\ REFRESH=\u0420\u0410\u0417\u0420\u0415\u0428\u0418 \u0410\u0412\u0422\u041E\u041C\u0410\u0422\u0418\u0427\u041D\u041E \u041F\u0420\u0415\u0417\u0410\u0420\u0415\u0416\u0414\u0410\u041D\u0415 +DISABLE\ AUTO\ REFRESH=\ + \u0411\u0435\u0437 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 +ENABLE\ AUTO\ REFRESH=\ + \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0437\u0430\u0440\u0435\u0436\u0434\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/layout/breadcrumbBar_lt.properties b/core/src/main/resources/lib/layout/breadcrumbBar_lt.properties index 7eef78362b796fb2905db1a60b8f30946d66b510..b326584542417458498b2909bc9494fe1ab5344b 100644 --- a/core/src/main/resources/lib/layout/breadcrumbBar_lt.properties +++ b/core/src/main/resources/lib/layout/breadcrumbBar_lt.properties @@ -1,4 +1,6 @@ # This file is under the MIT License by authors -DISABLE\ AUTO\ REFRESH=SUSTABDYTI AUTOMATIN\u012E ATNAUJINIM\u0104 -ENABLE\ AUTO\ REFRESH=\u012Ejunkti automatin\u012F perkrovim\u0105 +# /jenkins-core/src/main/resources/lib/layout/breadcrumbBar_lt.properties + +DISABLE\ AUTO\ REFRESH=I\u0160JUNGTI automatin\u012F puslapio atnaujinim\u0105 +ENABLE\ AUTO\ REFRESH=\u012EJUNGTI automatin\u012F puslapio atnaujinim\u0105 diff --git a/core/src/main/resources/lib/layout/breadcrumbBar_sr.properties b/core/src/main/resources/lib/layout/breadcrumbBar_sr.properties index dc5c69d85d53cb0c16724f90c61a4c6525ece855..b09138e3cef6c6fdb3964674fc6795d61d5fbd4d 100644 --- a/core/src/main/resources/lib/layout/breadcrumbBar_sr.properties +++ b/core/src/main/resources/lib/layout/breadcrumbBar_sr.properties @@ -1,3 +1,4 @@ # This file is under the MIT License by authors -ENABLE\ AUTO\ REFRESH=UKLJU\u010CI AUTOMATSKI OSVE\u017DAVANJE +ENABLE\ AUTO\ REFRESH=\u0421\u0430 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u0438\u043C \u043E\u0441\u0432\u0435\u0436\u0438\u0432\u0430\u045A\u0435\u043C +DISABLE\ AUTO\ REFRESH=\u0411\u0435\u0437 \u0430\u0443\u0442\u043E\u043C\u0430\u0442\u0441\u043A\u043E\u0433 \u043E\u0441\u0432\u0435\u0436\u0438\u0432\u0430\u045A\u0435\u043C \ No newline at end of file diff --git a/core/src/main/resources/lib/layout/breadcrumbs.js b/core/src/main/resources/lib/layout/breadcrumbs.js index 90b019f620e75fe6c45bb387d6dde206d9b88df9..adbebc84356b562f30114356df9c1036c4e3ac52 100644 --- a/core/src/main/resources/lib/layout/breadcrumbs.js +++ b/core/src/main/resources/lib/layout/breadcrumbs.js @@ -61,6 +61,9 @@ var breadcrumbs = (function() { var form = document.createElement('form'); form.setAttribute('method', cfg.post ? 'POST' : 'GET'); form.setAttribute('action', cfg.url); + if (cfg.post) { + crumb.appendToForm(form); + } document.body.appendChild(form); form.submit(); } diff --git a/core/src/main/resources/lib/layout/copyButton/clipboard.png b/core/src/main/resources/lib/layout/copyButton/clipboard.png index 24588a3a4d2356be517b0e066a489284f0326842..030b7bede28005abd89c66afb099ef24894ea187 100644 Binary files a/core/src/main/resources/lib/layout/copyButton/clipboard.png and b/core/src/main/resources/lib/layout/copyButton/clipboard.png differ diff --git a/core/src/main/resources/lib/layout/css.jelly b/core/src/main/resources/lib/layout/css.jelly new file mode 100644 index 0000000000000000000000000000000000000000..a15d383023553d9e6be6dc9aca010557b98948ff --- /dev/null +++ b/core/src/main/resources/lib/layout/css.jelly @@ -0,0 +1,37 @@ + + + + + + Client-side CSS loading tag. Similar to adjunct, but driven from the client. See page-init.js. + + @since 2.0 + + CSS source path (relative to Jenkins). + + + +
    + \ No newline at end of file diff --git a/core/src/main/resources/lib/layout/html.jelly b/core/src/main/resources/lib/layout/html.jelly new file mode 100644 index 0000000000000000000000000000000000000000..4e47688f15e77423c14bc413cdb9b5b0494f1c26 --- /dev/null +++ b/core/src/main/resources/lib/layout/html.jelly @@ -0,0 +1,171 @@ + + + + + Outer-most tag for a normal (non-AJAX) HTML rendering. + This is used with nested <header>, <side-panel>, and <main-panel> + to form Jenkins's basic HTML layout. + + + Title of the HTML page. Rendered into <title> tag. + + + If non-null and not "false", auto refresh is disabled on this page. + This is necessary for pages that include forms. + + + specify path that starts from "/" for loading additional CSS stylesheet. + path is interprted as relative to the context root. e.g., + + {noformat}<l:layout css="/plugin/mysuperplugin/css/myneatstyle.css">{noformat} + + This was originally added to allow plugins to load their stylesheets, but + *the use of thie attribute is discouraged now.* + plugins should now do so by inserting <style> elements and/or <script> elements + in <l:header/> tag. + + + If given, this page is only made available to users that has the specified permission. + (The permission will be checked against the "it" object.) + + + + + + + + +${h.initPageVariables(context)} + + + + + + + ${h.advertiseHeaders(response)} + + + + + + + + + + ${h.checkPermission(it,permission)} + + + + + + ${h.appendIfNotNull(title, ' [Jenkins]', 'Jenkins')} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -103,8 +111,7 @@ ${h.initPageVariables(context)} - -
    + + +
    + +
    +
    +
    + + +
    +
    -
    -
    - - +
    - + + diff --git a/core/src/main/resources/lib/layout/layout_bg.properties b/core/src/main/resources/lib/layout/layout_bg.properties index 736baeac693368c2c3ab6e26f36aefb8480f2f8d..43583498cd6e9a7de4c769d4cec88ed301e3973d 100644 --- a/core/src/main/resources/lib/layout/layout_bg.properties +++ b/core/src/main/resources/lib/layout/layout_bg.properties @@ -1,6 +1,6 @@ # The MIT License # -# Copyright (c) 2004-2010, Sun Microsystems, Inc. +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -20,6 +20,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Page\ generated=\u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430\u0442\u0430 \u0435 \u0441\u044A\u0437\u0434\u0430\u0434\u0435\u043D\u0430 -logout=\u0438\u0437\u0445\u043E\u0434 -search=\u0442\u044A\u0440\u0441\u0435\u043D\u0435 +Page\ generated=\ + \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0435\u043d\u0430 +logout=\ + \u0418\u0437\u0445\u043e\u0434 +search=\ + \u0422\u044a\u0440\u0441\u0435\u043d\u0435 +searchBox.url=\ + http://wiki.jenkins-ci.org/display/JENKINS/Search+Box diff --git a/core/src/main/resources/lib/layout/layout_sr.properties b/core/src/main/resources/lib/layout/layout_sr.properties index 43e466ad988ca44352950c015ffc40f4e0b0646b..bcf87ace3da823770b116d98d4250992c5beff3d 100644 --- a/core/src/main/resources/lib/layout/layout_sr.properties +++ b/core/src/main/resources/lib/layout/layout_sr.properties @@ -20,6 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -Page\ generated=Izgenerirana stranica -logout=Odlogiraj se -search=Tra\u017Ei +Page\ generated=\u0418\u0437\u0433\u0435\u043D\u0435\u0440\u0438\u0441\u0430\u043D\u0430 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 +logout=\u041E\u0434\u0458\u0430\u0432\u0438 \u0441\u0435 +search=\u041F\u0440\u0435\u0442\u0440\u0430\u0433\u0430 +searchBox.url=http://wiki.jenkins-ci.org/display/JENKINS/Search+Box diff --git a/core/src/main/resources/lib/layout/main-panel_bg.properties b/core/src/main/resources/lib/layout/main-panel_bg.properties index 04ae4e727cf76feeb065699a1285dca086f901bc..db466dc7d601a42b714c3e863babf565e37ccc42 100644 --- a/core/src/main/resources/lib/layout/main-panel_bg.properties +++ b/core/src/main/resources/lib/layout/main-panel_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -Jenkins\ is\ going\ to\ shut\ down=Jenkins \u0449\u0435 \u0441\u0435 \u0438\u0437\u043A\u043B\u044E\u0447\u0438 +Jenkins\ is\ going\ to\ shut\ down=\ + Jenkins \u0449\u0435 \u0441\u0435 \u0438\u0437\u043a\u043b\u044e\u0447\u0438 diff --git a/core/src/main/resources/lib/layout/main-panel_sr.properties b/core/src/main/resources/lib/layout/main-panel_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..394a52ebe5d4571c610b2a63c63bad855c1f2fe9 --- /dev/null +++ b/core/src/main/resources/lib/layout/main-panel_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Jenkins\ is\ going\ to\ shut\ down=Jenkins \u045B\u0435 \u0441\u0435 \u0443\u0433\u0430\u0441\u0438\u0442\u0438 diff --git a/core/src/main/resources/lib/layout/menu_down_arrow.png b/core/src/main/resources/lib/layout/menu_down_arrow.png index 9c194586b4dd0f5ef71619c5f3e438e6e9835b02..2b58e71b83fd78d0860f33cf9dcda0ec8926ff60 100644 Binary files a/core/src/main/resources/lib/layout/menu_down_arrow.png and b/core/src/main/resources/lib/layout/menu_down_arrow.png differ diff --git a/core/src/main/resources/lib/layout/menu_down_arrow2.png b/core/src/main/resources/lib/layout/menu_down_arrow2.png index 572afe828a019cdbc4bda82048261e62266df7d2..173fd0736bacd4d43a06646ad11e5af0658b8782 100644 Binary files a/core/src/main/resources/lib/layout/menu_down_arrow2.png and b/core/src/main/resources/lib/layout/menu_down_arrow2.png differ diff --git a/core/src/main/resources/lib/layout/menu_right_arrow.png b/core/src/main/resources/lib/layout/menu_right_arrow.png index 71b521ea567144016ad7b4913cdc761f2018d0d3..cdb3351f4ae37bbffb7aaca4ee86eac9cf5d0fef 100644 Binary files a/core/src/main/resources/lib/layout/menu_right_arrow.png and b/core/src/main/resources/lib/layout/menu_right_arrow.png differ diff --git a/core/src/main/resources/lib/layout/menu_right_arrow2.png b/core/src/main/resources/lib/layout/menu_right_arrow2.png index bd96028529c21ca10b09ca8960a78f7b632bdde2..dcf8ac52b2ea70c23dacb3c9e681acc9f7ee460e 100644 Binary files a/core/src/main/resources/lib/layout/menu_right_arrow2.png and b/core/src/main/resources/lib/layout/menu_right_arrow2.png differ diff --git a/core/src/main/resources/lib/layout/pane.jelly b/core/src/main/resources/lib/layout/pane.jelly index 38d7e767b9e486b898fb829fdbf2e72c2804737b..5c8f19f41eb54938cb1d2d1df10d0a3a15fb1c7d 100644 --- a/core/src/main/resources/lib/layout/pane.jelly +++ b/core/src/main/resources/lib/layout/pane.jelly @@ -48,19 +48,20 @@ THE SOFTWARE. Footer of the box. Can include HTML. -
    + +
    - +
    ${attrs.collapsedText}
    diff --git a/core/src/main/resources/lib/layout/pane_bg.properties b/core/src/main/resources/lib/layout/pane_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..a4d036f3c13e9b62a0d6184c68d8753013497d92 --- /dev/null +++ b/core/src/main/resources/lib/layout/pane_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +expand=\ + \u0420\u0430\u0437\u0448\u0438\u0440\u044f\u0432\u0430\u043d\u0435 diff --git a/core/src/main/resources/lib/layout/pane_sr.properties b/core/src/main/resources/lib/layout/pane_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..a0e25a9d4b63f60cf8ab0f094a772046b1314727 --- /dev/null +++ b/core/src/main/resources/lib/layout/pane_sr.properties @@ -0,0 +1,4 @@ +# This file is under the MIT License by authors + +expand=\u0420\u0430\u0448\u0438\u0440\u0438 +collapse=\u0421\u043C\u0430\u045A\u0438 diff --git a/core/src/main/resources/lib/layout/progressiveRendering_bg.properties b/core/src/main/resources/lib/layout/progressiveRendering_bg.properties index f673142d53c864fbbbce6742ab607939b009b1d0..fc5d5fa866c5b43b2b8d7b4fbad46addcf172490 100644 --- a/core/src/main/resources/lib/layout/progressiveRendering_bg.properties +++ b/core/src/main/resources/lib/layout/progressiveRendering_bg.properties @@ -1,3 +1,24 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -progressMessage=\u0418\u0437\u0447\u0438\u0441\u043B\u044F\u0432\u0430 \u0441\u0435. +progressMessage=\ + \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u2026 diff --git a/core/src/main/resources/lib/layout/progressiveRendering_sr.properties b/core/src/main/resources/lib/layout/progressiveRendering_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..261504a0eeb766a4f19944e18f86d387b60d8b99 --- /dev/null +++ b/core/src/main/resources/lib/layout/progressiveRendering_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +progressMessage=\u041E\u0431\u0440\u0430\u0434\u0430\u045A\u0435... diff --git a/core/src/main/resources/lib/layout/side-panel.jelly b/core/src/main/resources/lib/layout/side-panel.jelly index fd203550fe22c4bd03b0821c8e12b7bf9b434089..26b8afa3b647a08963fd9ac5d96f2aeb66ecd8ba 100644 --- a/core/src/main/resources/lib/layout/side-panel.jelly +++ b/core/src/main/resources/lib/layout/side-panel.jelly @@ -23,8 +23,13 @@ THE SOFTWARE. --> - + + + Generates a left side content as part of a Jenkins page. Typically known as two-column or left-side + main-content layouts + + + \ No newline at end of file diff --git a/core/src/main/resources/lib/layout/stopButton.jelly b/core/src/main/resources/lib/layout/stopButton.jelly index 4d19c004f4644382e463f2d5c2f236be0bd195df..4fc6b6a127f61cd0a9d83c28ef42681efb90c3bd 100644 --- a/core/src/main/resources/lib/layout/stopButton.jelly +++ b/core/src/main/resources/lib/layout/stopButton.jelly @@ -33,8 +33,20 @@ THE SOFTWARE. Alt text for image. + + If defined, the user will be asked for confirmation first, and the value will be used as question. + - - - + + + + + + + + + + + + diff --git a/core/src/main/resources/lib/layout/tab.jelly b/core/src/main/resources/lib/layout/tab.jelly index 291661be911a35b7d28e2d71e43d0b771eb30481..9e8bebf6b90e4761a2cae37283119418a3cf4c5e 100644 --- a/core/src/main/resources/lib/layout/tab.jelly +++ b/core/src/main/resources/lib/layout/tab.jelly @@ -22,24 +22,32 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - - -
    + + + + The name of the tab + + + The url of the tab + + + Whether the tab is active or not + + + The title of the tab + + + diff --git a/core/src/main/resources/lib/layout/taglib b/core/src/main/resources/lib/layout/taglib index 676b74139f04800cb0a489eb3e6d2964b0b9e0c2..f4ed5725589bac6108360e0ce1369057a3832066 100644 --- a/core/src/main/resources/lib/layout/taglib +++ b/core/src/main/resources/lib/layout/taglib @@ -1 +1 @@ -Tag library that defines the basic layout of Hudson pages. \ No newline at end of file +Tag library that defines the basic layouts of Jenkins pages. \ No newline at end of file diff --git a/core/src/main/resources/lib/layout/task.jelly b/core/src/main/resources/lib/layout/task.jelly index d120faa49572033b59de4bc85ed5461f3ff81507..54d95993cefd3d23ac7971a3227b2bcf9995ab1e 100644 --- a/core/src/main/resources/lib/layout/task.jelly +++ b/core/src/main/resources/lib/layout/task.jelly @@ -167,7 +167,7 @@ THE SOFTWARE. - + @@ -179,7 +179,7 @@ THE SOFTWARE. - + diff --git a/core/src/main/resources/lib/layout/task_bg.properties b/core/src/main/resources/lib/layout/task_bg.properties new file mode 100644 index 0000000000000000000000000000000000000000..217911364ea29e35ea46cdeb51490ed875b4da0d --- /dev/null +++ b/core/src/main/resources/lib/layout/task_bg.properties @@ -0,0 +1,24 @@ +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +Done.=\ + \u0413\u043e\u0442\u043e\u0432\u043e. diff --git a/core/src/main/resources/lib/layout/task_sr.properties b/core/src/main/resources/lib/layout/task_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..615977c3700fb9374a15ef5f88b64b5664000d94 --- /dev/null +++ b/core/src/main/resources/lib/layout/task_sr.properties @@ -0,0 +1,3 @@ +# This file is under the MIT License by authors + +Done.=\u0413\u043E\u0442\u043E\u0432\u043E. diff --git a/core/src/main/resources/lib/test/bar_bg.properties b/core/src/main/resources/lib/test/bar_bg.properties index 478b1f0a3c8fc4fb4da66a44efd65323de3b1b87..392d8b3a084910fee60577df60ea40250fca8eb8 100644 --- a/core/src/main/resources/lib/test/bar_bg.properties +++ b/core/src/main/resources/lib/test/bar_bg.properties @@ -1,4 +1,30 @@ -# This file is under the MIT License by authors +# The MIT License +# +# Bulgarian translation: Copyright (c) 2015, 2016, Alexander Shopov +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. -failures=\u0433\u0440\u0435\u0448\u043A\u0438 -tests=\u0442\u0435\u0441\u0442\u043E\u0432\u0435 +failures=\ + {0} \u0433\u0440\u0435\u0448\u043a\u0438 +skipped=\ + {0} \u043f\u0440\u043e\u043f\u0443\u0441\u043d\u0430\u0442\u0438 +tests=\ + {0} \u0442\u0435\u0441\u0442\u0430 +No\ tests=\ + \u041d\u044f\u043c\u0430 \u0442\u0435\u0441\u0442\u043e\u0432\u0435 diff --git a/core/src/main/resources/lib/test/bar_pl.properties b/core/src/main/resources/lib/test/bar_pl.properties index 53c588e3084303c915308051865034085fd0bac8..66225c24df89ccc4e476c29cd742f42c238ec4cc 100644 --- a/core/src/main/resources/lib/test/bar_pl.properties +++ b/core/src/main/resources/lib/test/bar_pl.properties @@ -20,6 +20,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -failures={0} pora\u017Cek +failures={0} b\u0142\u0119d\u00F3w skipped={0} pomini\u0119tych tests={0} test\u00F3w diff --git a/core/src/main/resources/lib/test/bar_sr.properties b/core/src/main/resources/lib/test/bar_sr.properties new file mode 100644 index 0000000000000000000000000000000000000000..9413a8e3629e1ed93d22f9242313ca55a71fc829 --- /dev/null +++ b/core/src/main/resources/lib/test/bar_sr.properties @@ -0,0 +1,6 @@ +# This file is under the MIT License by authors + +No\ tests=\u041D\u0435\u043C\u0430 \u0442\u0435\u0441\u0442\u043E\u0432\u0430 +failures={0} \u0433\u0440\u0435\u0448\u043A\u0430 +skipped={0} \u043F\u0440\u0435\u0441\u043A\u043E\u0447\u0435\u043D\u043E +tests={0} \u0442\u0435\u0441\u0442\u043E\u0432(\u0430) diff --git a/core/src/main/resources/windows-service/jenkins.exe.config b/core/src/main/resources/windows-service/jenkins.exe.config index 1b2af154e356493c49c42feeb40a3439232ee55d..b82788e9ace616eb019d8e33b997ae8e7f95cf15 100644 --- a/core/src/main/resources/windows-service/jenkins.exe.config +++ b/core/src/main/resources/windows-service/jenkins.exe.config @@ -1,6 +1,11 @@ - + + + + + + \ No newline at end of file diff --git a/core/src/main/resources/windows-service/jenkins.xml b/core/src/main/resources/windows-service/jenkins.xml index 6e151b36ddc5dae3058d63f20820ecc7f8ca78e0..2bc1e79c4ec71363449c68fb964e57e486c521db 100644 --- a/core/src/main/resources/windows-service/jenkins.xml +++ b/core/src/main/resources/windows-service/jenkins.xml @@ -1,50 +1,50 @@ - - - - - jenkins - Jenkins - This service runs Jenkins continuous integration system. - - - java - -Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 - - rotate - - - + + + + + jenkins + Jenkins + This service runs Jenkins continuous integration system. + + + java + -Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=8080 --webroot="%BASE%\war" + + rotate + + + diff --git a/core/src/site/markdown/index.md b/core/src/site/markdown/index.md index 40ee40c80bd9b53c0b59e3d9487d09a69415393e..a915159a0081663e3dfc70fed7e14048092120a4 100644 --- a/core/src/site/markdown/index.md +++ b/core/src/site/markdown/index.md @@ -1 +1 @@ -Collection of Maven auto-generated reports. The primary interest is probably [Jelly tag libary reference](jelly-taglib-ref.html). +Collection of Maven auto-generated reports. The primary interest is probably [Jelly tag library reference](jelly-taglib-ref.html). diff --git a/core/src/test/groovy/hudson/util/SecretTest.groovy b/core/src/test/groovy/hudson/util/SecretTest.groovy index e6532dd8f94bbf8d4e7d1a440260bc146095db8f..f7a0ba3ad00a194c86fd1e7b7ca12b10e5512b08 100644 --- a/core/src/test/groovy/hudson/util/SecretTest.groovy +++ b/core/src/test/groovy/hudson/util/SecretTest.groovy @@ -26,9 +26,11 @@ package hudson.util import com.trilead.ssh2.crypto.Base64; import jenkins.model.Jenkins import jenkins.security.ConfidentialStoreRule; +import org.apache.commons.lang.RandomStringUtils; import org.junit.Rule import org.junit.Test +import java.util.Random; import javax.crypto.Cipher; /** @@ -54,6 +56,17 @@ public class SecretTest { assert secret==Secret.fromString(secret.encryptedValue); } + @Test + void testEncryptedValuePattern() { + for (int i = 1; i < 100; i++) { + String plaintext = RandomStringUtils.random(new Random().nextInt(i)); + String ciphertext = Secret.fromString(plaintext).getEncryptedValue(); + //println "${plaintext} → ${ciphertext}" + assert Secret.ENCRYPTED_VALUE_PATTERN.matcher(ciphertext).matches(); + } + assert !Secret.ENCRYPTED_VALUE_PATTERN.matcher("hello world").matches(); + } + @Test void testDecrypt() { assert "abc"==Secret.toString(Secret.fromString("abc")) diff --git a/core/src/test/java/hudson/BulkChangeTest.java b/core/src/test/java/hudson/BulkChangeTest.java index 7fe79c8383eca962ac70929046f793c9b559cb1c..7e93dc4e097da6708374ce4fc6a3675c59fca928 100644 --- a/core/src/test/java/hudson/BulkChangeTest.java +++ b/core/src/test/java/hudson/BulkChangeTest.java @@ -98,10 +98,10 @@ public class BulkChangeTest { @Test public void nestedBulkChange() throws Exception { Point pt = new Point(); - Point _ = new Point(); + Point pt2 = new Point(); BulkChange bc1 = new BulkChange(pt); try { - BulkChange bc2 = new BulkChange(_); + BulkChange bc2 = new BulkChange(pt2); try { BulkChange bc3 = new BulkChange(pt); try { diff --git a/core/src/test/java/hudson/ClassicPluginStrategyTest.java b/core/src/test/java/hudson/ClassicPluginStrategyTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bb19c5f81bf54b38278d9d2c65e865488aa11ca4 --- /dev/null +++ b/core/src/test/java/hudson/ClassicPluginStrategyTest.java @@ -0,0 +1,69 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson; + +import hudson.util.VersionNumber; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +import static hudson.ClassicPluginStrategy.DetachedPlugin; + +/** + * @author tom.fennelly@gmail.com + */ +public class ClassicPluginStrategyTest { + + @Test + public void test_getDetachedPlugins() { + List list = ClassicPluginStrategy.getDetachedPlugins(new VersionNumber("1.296")); + + Assert.assertTrue(list.size() >= 14); // There were 14 at the time of writing this test + Assert.assertNotNull(findPlugin("maven-plugin", list)); + Assert.assertNotNull(findPlugin("subversion", list)); + + // Narrow the list to since "1.310" (the subversion detach version). + list = ClassicPluginStrategy.getDetachedPlugins(new VersionNumber("1.310")); + // Maven should no longer be in the list, but subversion should. + Assert.assertNull(findPlugin("maven-plugin", list)); + Assert.assertNotNull(findPlugin("subversion", list)); + + // Narrow the list to since "1.311" (after the subversion detach version). + list = ClassicPluginStrategy.getDetachedPlugins(new VersionNumber("1.311")); + // Neither Maven or subversion should be in the list. + Assert.assertNull(findPlugin("maven-plugin", list)); + Assert.assertNull(findPlugin("subversion", list)); + } + + private DetachedPlugin findPlugin(String shortName, List list) { + for (DetachedPlugin detachedPlugin : list) { + if (detachedPlugin.getShortName().equals(shortName)) { + return detachedPlugin; + } + } + + return null; + } +} diff --git a/core/src/test/java/hudson/FilePathTest.java b/core/src/test/java/hudson/FilePathTest.java index 801e184906a8d7ee1582cd0551132c0f7fc363f5..7b515ec2131692895f9c8f266ef732142137c377 100644 --- a/core/src/test/java/hudson/FilePathTest.java +++ b/core/src/test/java/hudson/FilePathTest.java @@ -38,9 +38,11 @@ import java.io.OutputStream; import java.io.RandomAccessFile; import java.net.ConnectException; import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -58,10 +60,12 @@ import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Chmod; import static org.junit.Assert.*; import static org.junit.Assume.assumeTrue; +import static org.junit.Assume.assumeFalse; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; + import org.jvnet.hudson.test.Issue; import org.mockito.Mockito; import static org.mockito.Mockito.*; @@ -340,7 +344,7 @@ public class FilePathTest { } /** - * Checks that big files (>8GB) can be archived and then unpacked. + * Checks that big files (greater than 8GB) can be archived and then unpacked. * This test is disabled by default due the impact on RAM. * The actual file size limit is 8589934591 bytes. * @throws Exception test failure @@ -371,7 +375,7 @@ public class FilePathTest { // Decompress FilePath outDir = new FilePath(temp.newFolder(filePrefix + "_out")); final FilePath outFile = outDir.child(tempFile.getName()); - tmpDirPath.child( filePrefix + ".tar").untar(outDir, TarCompression.NONE); + tmpDirPath.child(tarFile.getName()).untar(outDir, TarCompression.NONE); assertEquals("Result file after the roundtrip differs from the initial file", new FilePath(tempFile).digest(), outFile.digest()); } @@ -464,7 +468,7 @@ public class FilePathTest { } @Test public void symlinkInTar() throws Exception { - if (Functions.isWindows()) return; // can't test on Windows + assumeFalse("can't test on Windows", Functions.isWindows()); FilePath tmp = new FilePath(temp.getRoot()); FilePath in = tmp.child("in"); @@ -538,6 +542,25 @@ public class FilePathTest { // good } } + + @Issue("JENKINS-5253") + public void testValidateCaseSensitivity() throws Exception { + File tmp = Util.createTempDir(); + try { + FilePath d = new FilePath(channels.french, tmp.getPath()); + d.child("d1/d2/d3").mkdirs(); + d.child("d1/d2/d3/f.txt").touch(0); + d.child("d1/d2/d3/f.html").touch(0); + d.child("d1/d2/f.txt").touch(0); + + assertEquals(null, d.validateAntFileMask("**/d1/**/f.*", FilePath.VALIDATE_ANT_FILE_MASK_BOUND, true)); + assertEquals(null, d.validateAntFileMask("**/d1/**/f.*", FilePath.VALIDATE_ANT_FILE_MASK_BOUND, false)); + assertEquals(Messages.FilePath_validateAntFileMask_matchWithCaseInsensitive("**/D1/**/F.*"), d.validateAntFileMask("**/D1/**/F.*", FilePath.VALIDATE_ANT_FILE_MASK_BOUND, true)); + assertEquals(null, d.validateAntFileMask("**/D1/**/F.*", FilePath.VALIDATE_ANT_FILE_MASK_BOUND, false)); + } finally { + Util.deleteRecursive(tmp); + } + } @Issue("JENKINS-15418") @Test public void deleteLongPathOnWindows() throws Exception { @@ -616,6 +639,28 @@ public class FilePathTest { assertTrue(log, log.contains("504 Gateway Timeout")); } + @Issue("JENKINS-23507") + @Test public void installIfNecessaryFollowsRedirects() throws Exception{ + File tmp = temp.getRoot(); + final FilePath d = new FilePath(tmp); + FilePath.UrlFactory urlFactory = mock(FilePath.UrlFactory.class); + d.setUrlFactory(urlFactory); + final HttpURLConnection con = mock(HttpURLConnection.class); + final HttpURLConnection con2 = mock(HttpURLConnection.class); + final URL url = someUrlToZipFile(con); + when(con.getResponseCode()).thenReturn(HttpURLConnection.HTTP_MOVED_TEMP); + URL url2 = someUrlToZipFile(con2); + String someUrl = url2.toExternalForm(); + when(con.getHeaderField("Location")).thenReturn(someUrl); + when(urlFactory.newURL(someUrl)).thenReturn(url2); + when(con2.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK); + when(con2.getInputStream()).thenReturn(someZippedContent()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + String message = "going ahead"; + assertTrue(d.installIfNecessaryFrom(url, new StreamTaskListener(baos), message)); + } + private URL someUrlToZipFile(final URLConnection con) throws IOException { final URLStreamHandler urlHandler = new URLStreamHandler() { @@ -659,4 +704,35 @@ public class FilePathTest { // test conflict subdir src.moveAllChildrenTo(dst); } + + @Issue("JENKINS-10629") + @Test + public void testEOFbrokenFlush() throws IOException, InterruptedException { + final File srcFolder = temp.newFolder("src"); + // simulate magic structure with magic sizes: + // |- dir/pom.xml (2049) + // |- pom.xml (2049) + // \- small.tar (1537) + final File smallTar = new File(srcFolder, "small.tar"); + givenSomeContentInFile(smallTar, 1537); + final File dir = new File(srcFolder, "dir"); + dir.mkdirs(); + final File pomFile = new File(dir, "pom.xml"); + givenSomeContentInFile(pomFile, 2049); + FileUtils.copyFileToDirectory(pomFile, srcFolder); + + final File archive = temp.newFile("archive.tar"); + + // Compress archive + final FilePath tmpDirPath = new FilePath(srcFolder); + int tarred = tmpDirPath.tar(new FileOutputStream(archive), "**"); + assertEquals("One file should have been compressed", 3, tarred); + + // Decompress + final File dstFolder = temp.newFolder("dst"); + dstFolder.mkdirs(); + FilePath outDir = new FilePath(dstFolder); + // and now fail when flush is bad! + tmpDirPath.child("../" + archive.getName()).untar(outDir, TarCompression.NONE); + } } diff --git a/core/src/test/java/hudson/LauncherTest.java b/core/src/test/java/hudson/LauncherTest.java index 84dde944f3ccb4c1b357c333dbeaa4116b9297b6..62ff200e96a1b158c5005ffcbb9e6d2fb7f87c11 100644 --- a/core/src/test/java/hudson/LauncherTest.java +++ b/core/src/test/java/hudson/LauncherTest.java @@ -34,6 +34,8 @@ import java.io.File; import jenkins.security.MasterToSlaveCallable; import org.apache.commons.io.FileUtils; import static org.junit.Assert.*; + +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -46,10 +48,7 @@ public class LauncherTest { @Issue("JENKINS-4611") @Test public void remoteKill() throws Exception { - if (File.pathSeparatorChar != ':') { - System.err.println("Skipping, currently Unix-specific test"); - return; - } + Assume.assumeFalse("Skipping, currently Unix-specific test", Functions.isWindows()); File tmp = temp.newFile(); diff --git a/core/src/test/java/hudson/PluginManagerTest.java b/core/src/test/java/hudson/PluginManagerTest.java index da8e6a5a8896c13ec255894ef04bde3d66d719c8..483eaa467860eeaae6af9d3bd8e0173e9edaba7e 100644 --- a/core/src/test/java/hudson/PluginManagerTest.java +++ b/core/src/test/java/hudson/PluginManagerTest.java @@ -24,17 +24,33 @@ package hudson; +import java.io.File; +import java.io.FileOutputStream; import org.apache.tools.ant.filters.StringInputStream; import org.junit.Test; import org.xml.sax.SAXException; import java.io.IOException; +import java.io.InputStream; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.jar.Attributes; +import java.util.jar.Manifest; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; +import org.apache.commons.io.FileUtils; +import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.core.IsInstanceOf.instanceOf; import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.*; import org.junit.Rule; import org.junit.rules.TemporaryFolder; import org.jvnet.hudson.test.Issue; - + +/** + * Tests of {@link PluginManager}. + */ public class PluginManagerTest { @Rule public TemporaryFolder tmp = new TemporaryFolder(); @@ -68,4 +84,86 @@ public class PluginManagerTest { assertThat(ex.getCause().getMessage(), containsString("Refusing to resolve entity with publicId(null) and systemId (file:///)")); } } + + @Test + public void shouldProperlyParseManifestFromJar() throws IOException { + File jar = createHpiWithManifest(); + final Manifest manifest = PluginManager.parsePluginManifest(jar.toURI().toURL()); + + assertThat("manifest should have been read from the sample", manifest, notNullValue()); + assertAttribute(manifest, "Created-By", "Apache Maven"); + assertAttribute(manifest, "Short-Name", "matrix-auth"); + + // Multi-line entries + assertAttribute(manifest, "Specification-Title", "Offers matrix-based security authorization strategies (global and per-project)."); + assertAttribute(manifest, "Url", "http://wiki.jenkins-ci.org/display/JENKINS/Matrix+Authorization+Strategy+Plugin"); + + // Empty field + assertAttribute(manifest, "Plugin-Developers", null); + } + + @Test + public void shouldProperlyRetrieveModificationDate() throws IOException { + File jar = createHpiWithManifest(); + URL url = toManifestUrl(jar); + assertThat("Manifest last modified date should be equal to the file date", + PluginManager.getModificationDate(url), + equalTo(jar.lastModified())); + } + + private static void assertAttribute(Manifest manifest, String attributeName, String value) throws AssertionError { + Attributes attributes = manifest.getMainAttributes(); + assertThat("Main attributes must not be empty", attributes, notNullValue()); + assertThat("Attribute '" + attributeName + "' does not match the sample", + attributes.getValue(attributeName), + equalTo(value)); + + } + + private static final String SAMPLE_MANIFEST_FILE = "Manifest-Version: 1.0\n" + + "Archiver-Version: Plexus Archiver\n" + + "Created-By: Apache Maven\n" + + "Built-By: jglick\n" + + "Build-Jdk: 1.8.0_92\n" + + "Extension-Name: matrix-auth\n" + + "Specification-Title: \n" + + " Offers matrix-based security \n" + + " authorization strate\n" + + " gies (global and per-project).\n" + + "Implementation-Title: matrix-auth\n" + + "Implementation-Version: 1.4\n" + + "Group-Id: org.jenkins-ci.plugins\n" + + "Short-Name: matrix-auth\n" + + "Long-Name: Matrix Authorization Strategy Plugin\n" + + "Url: http://wiki.jenkins-ci.org/display/JENKINS/Matrix+Authorization+S\n" + + " trategy+Plugin\n" + + "Plugin-Version: 1.4\n" + + "Hudson-Version: 1.609.1\n" + + "Jenkins-Version: 1.609.1\n" + + "Plugin-Dependencies: icon-shim:2.0.3,cloudbees-folder:5.2.2;resolution\n" + + " :=optional\n" + + "Plugin-Developers: "; + + private File createHpiWithManifest() throws IOException { + File newFolder = tmp.newFolder("myJar"); + String manifestPath = "META-INF/MANIFEST.MF"; + new File("META-INF").mkdir(); + FileUtils.write(new File(newFolder, manifestPath), SAMPLE_MANIFEST_FILE); + + final File f = new File(tmp.getRoot(), "my.hpi"); + try(ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f))) { + ZipEntry e = new ZipEntry(manifestPath); + out.putNextEntry(e); + byte[] data = SAMPLE_MANIFEST_FILE.getBytes(); + out.write(data, 0, data.length); + out.closeEntry(); + } + return f; + } + + + private URL toManifestUrl(File jarFile) throws MalformedURLException { + final String manifestPath = "META-INF/MANIFEST.MF"; + return new URL("jar:" + jarFile.toURI().toURL() + "!/" + manifestPath); + } } diff --git a/core/src/test/java/hudson/PluginWrapperTest.java b/core/src/test/java/hudson/PluginWrapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..56504cd0bd975b9434d966a07221e287bf726b69 --- /dev/null +++ b/core/src/test/java/hudson/PluginWrapperTest.java @@ -0,0 +1,183 @@ +package hudson; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import jenkins.model.Jenkins; +import org.junit.Before; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class PluginWrapperTest { + + @Before + public void before() throws Exception { + Jenkins.VERSION = "2.0"; // Some value needed - tests will overwrite if necessary + } + + @Test + public void dependencyTest() { + String version = "plugin:0.0.2"; + PluginWrapper.Dependency dependency = new PluginWrapper.Dependency(version); + assertEquals("plugin", dependency.shortName); + assertEquals("0.0.2", dependency.version); + assertEquals(false, dependency.optional); + } + + @Test + public void optionalDependencyTest() { + String version = "plugin:0.0.2;resolution:=optional"; + PluginWrapper.Dependency dependency = new PluginWrapper.Dependency(version); + assertEquals("plugin", dependency.shortName); + assertEquals("0.0.2", dependency.version); + assertEquals(true, dependency.optional); + } + + @Test + public void jenkinsCoreTooOld() throws Exception { + PluginWrapper pw = pluginWrapper("fake").requiredCoreVersion("3.0").buildLoaded(); + try { + pw.resolvePluginDependencies(); + fail(); + } catch (IOException ex) { + assertContians(ex, "fake v42 failed to load", "update Jenkins from v2.0 to v3.0"); + } + } + + @Test + public void dependencyNotInstalled() throws Exception { + PluginWrapper pw = pluginWrapper("dependee").deps("dependency:42").buildLoaded(); + try { + pw.resolvePluginDependencies(); + fail(); + } catch (IOException ex) { + assertContians(ex, "dependee v42 failed to load", "dependency v42 is missing. To fix, install v42 or later"); + } + } + + @Test + public void dependencyOutdated() throws Exception { + pluginWrapper("dependency").version("3").buildLoaded(); + PluginWrapper pw = pluginWrapper("dependee").deps("dependency:5").buildLoaded(); + try { + pw.resolvePluginDependencies(); + fail(); + } catch (IOException ex) { + assertContians(ex, "dependee v42 failed to load", "dependency v3 is older than required. To fix, install v5 or later"); + } + } + + @Test + public void dependencyFailedToLoad() throws Exception { + pluginWrapper("dependency").version("5").buildFailed(); + PluginWrapper pw = pluginWrapper("dependee").deps("dependency:3").buildLoaded(); + try { + pw.resolvePluginDependencies(); + fail(); + } catch (IOException ex) { + assertContians(ex, "dependee v42 failed to load", "dependency v5 failed to load. Fix this plugin first"); + } + } + + private void assertContians(Throwable ex, String... patterns) { + String msg = ex.getMessage(); + for (String pattern : patterns) { + assertThat(msg, containsString(pattern)); + } + } + + private PluginWrapperBuilder pluginWrapper(String name) { + return new PluginWrapperBuilder(name); + } + + // per test + private final HashMap plugins = new HashMap<>(); + private final PluginManager pm = mock(PluginManager.class); + { + when(pm.getPlugin(any(String.class))).thenAnswer(new Answer() { + @Override public PluginWrapper answer(InvocationOnMock invocation) throws Throwable { + return plugins.get(invocation.getArguments()[0]); + } + }); + } + private final class PluginWrapperBuilder { + private String name; + private String version = "42"; + private String requiredCoreVersion = "1.0"; + private List deps = new ArrayList<>(); + private List optDeps = new ArrayList<>(); + + private PluginWrapperBuilder(String name) { + this.name = name; + } + + public PluginWrapperBuilder version(String version) { + this.version = version; + return this; + } + + public PluginWrapperBuilder requiredCoreVersion(String requiredCoreVersion) { + this.requiredCoreVersion = requiredCoreVersion; + return this; + } + + public PluginWrapperBuilder deps(String... deps) { + for (String dep: deps) { + this.deps.add(new PluginWrapper.Dependency(dep)); + } + return this; + } + + public PluginWrapperBuilder optDeps(String... optDeps) { + for (String dep: optDeps) { + this.optDeps.add(new PluginWrapper.Dependency(dep)); + } + return this; + } + + private PluginWrapper buildLoaded() { + PluginWrapper pw = build(); + plugins.put(name, pw); + return pw; + } + + private PluginWrapper buildFailed() { + PluginWrapper pw = build(); + PluginWrapper.NOTICE.addPlugin(pw); + return pw; + } + + private PluginWrapper build() { + Manifest manifest = mock(Manifest.class); + Attributes attributes = new Attributes(); + attributes.put(new Attributes.Name("Short-Name"), name); + attributes.put(new Attributes.Name("Jenkins-Version"), requiredCoreVersion); + attributes.put(new Attributes.Name("Plugin-Version"), version); + when(manifest.getMainAttributes()).thenReturn(attributes); + return new PluginWrapper( + pm, + new File("/tmp/" + name + ".jpi"), + manifest, + null, + null, + new File("/tmp/" + name + ".jpi.disabled"), + deps, + optDeps + ); + } + } +} diff --git a/core/src/test/java/hudson/RemoveWindowsDirectoryJunctionTest.java b/core/src/test/java/hudson/RemoveWindowsDirectoryJunctionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..cd631503c31e8998983b5bfa4175bfdb74a28d8a --- /dev/null +++ b/core/src/test/java/hudson/RemoveWindowsDirectoryJunctionTest.java @@ -0,0 +1,48 @@ +/* + * + */ +package hudson; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; + +import java.io.File; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.jvnet.hudson.test.Issue; + +public class RemoveWindowsDirectoryJunctionTest { + @Rule + public TemporaryFolder tmp = new TemporaryFolder(); + + @Before + public void windowsOnly() { + assumeTrue(Functions.isWindows()); + } + + @Test + @Issue("JENKINS-2995") + public void testJunctionIsRemovedButNotContents() throws Exception { + File subdir1 = tmp.newFolder("notJunction"); + File f1 = new File(subdir1, "testfile1.txt"); + assertTrue("Unable to create temporary file in notJunction directory", f1.createNewFile()); + File j1 = makeJunction(tmp.getRoot(), subdir1); + Util.deleteRecursive(j1); + assertFalse("Windows Junction should have been removed", j1.exists()); + assertTrue("Contents of Windows Junction should not be removed", f1.exists()); + } + + private File makeJunction(File baseDir, File pointToDir) throws Exception { + File junc = new File(baseDir, "test Junction"); + String cmd = "mklink /J \"" + junc.getPath() + "\" \"" + pointToDir.getPath() + "\""; + ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C", cmd); + pb.inheritIO(); + Process p = pb.start(); + assertEquals("Running mklink failed (cmd=" + cmd + ")", 0, p.waitFor()); + return junc; + } +} diff --git a/core/src/test/java/hudson/UtilTest.java b/core/src/test/java/hudson/UtilTest.java index 5be69d004b2c0c367562969bcc6b2dab5b8f58e6..fe44a9630ce85b54e51d393d417be0300b249f8d 100644 --- a/core/src/test/java/hudson/UtilTest.java +++ b/core/src/test/java/hudson/UtilTest.java @@ -24,17 +24,27 @@ */ package hudson; +import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Locale; import java.util.Properties; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicReference; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.hasItem; +import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.*; +import org.apache.commons.io.FileUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; import org.junit.Assume; @@ -42,12 +52,13 @@ import org.junit.Test; import org.jvnet.hudson.test.Issue; import hudson.util.StreamTaskListener; -import java.io.FileOutputStream; -import java.io.OutputStream; + import org.junit.Rule; import org.junit.internal.AssumptionViolatedException; import org.junit.rules.TemporaryFolder; +import com.google.common.collect.Lists; + /** * @author Kohsuke Kawaguchi */ @@ -248,7 +259,17 @@ public class UtilTest { } } - @Test public void deleteFile() throws Exception { + @Test + public void testDeleteFile() throws Exception { + File f = tmp.newFile(); + // Test: File is deleted + mkfiles(f); + Util.deleteFile(f); + assertFalse("f exists after calling Util.deleteFile", f.exists()); + } + + @Test + public void testDeleteFile_onWindows() throws Exception { Assume.assumeTrue(Functions.isWindows()); Class c; try { @@ -256,23 +277,245 @@ public class UtilTest { } catch (ClassNotFoundException x) { throw new AssumptionViolatedException("prior to JDK 7", x); } - File d = tmp.getRoot(); + final int defaultDeletionMax = Util.DELETION_MAX; try { - File f = new File(d, "f"); - OutputStream os = new FileOutputStream(f); + File f = tmp.newFile(); + // Test: If we cannot delete a file, we throw explaining why + mkfiles(f); + lockFileForDeletion(f); + Util.DELETION_MAX = 1; try { Util.deleteFile(f); fail("should not have been deletable"); } catch (IOException x) { - assertEquals(c, x.getClass()); - } finally { - os.close(); + assertThat(calcExceptionHierarchy(x), hasItem(c)); + assertThat(x.getMessage(), containsString(f.getPath())); } } finally { - Util.deleteRecursive(d); + Util.DELETION_MAX = defaultDeletionMax; + unlockFilesForDeletion(); + } + } + + @Test + public void testDeleteContentsRecursive() throws Exception { + final File dir = tmp.newFolder(); + final File d1 = new File(dir, "d1"); + final File d2 = new File(dir, "d2"); + final File f1 = new File(dir, "f1"); + final File d1f1 = new File(d1, "d1f1"); + final File d2f2 = new File(d2, "d1f2"); + // Test: Files and directories are deleted + mkdirs(dir, d1, d2); + mkfiles(f1, d1f1, d2f2); + Util.deleteContentsRecursive(dir); + assertTrue("dir exists", dir.exists()); + assertFalse("d1 exists", d1.exists()); + assertFalse("d2 exists", d2.exists()); + assertFalse("f1 exists", f1.exists()); + } + + @Test + public void testDeleteContentsRecursive_onWindows() throws Exception { + Assume.assumeTrue(Functions.isWindows()); + final File dir = tmp.newFolder(); + final File d1 = new File(dir, "d1"); + final File d2 = new File(dir, "d2"); + final File f1 = new File(dir, "f1"); + final File d1f1 = new File(d1, "d1f1"); + final File d2f2 = new File(d2, "d1f2"); + final int defaultDeletionMax = Util.DELETION_MAX; + final int defaultDeletionWait = Util.WAIT_BETWEEN_DELETION_RETRIES; + final boolean defaultDeletionGC = Util.GC_AFTER_FAILED_DELETE; + try { + // Test: If we cannot delete a file, we throw + // but still deletes everything it can + // even if we are not retrying deletes. + mkdirs(dir, d1, d2); + mkfiles(f1, d1f1, d2f2); + lockFileForDeletion(d1f1); + Util.GC_AFTER_FAILED_DELETE = false; + Util.DELETION_MAX = 2; + Util.WAIT_BETWEEN_DELETION_RETRIES = 0; + try { + Util.deleteContentsRecursive(dir); + fail("Expected IOException"); + } catch (IOException x) { + assertFalse("d2 should not exist", d2.exists()); + assertFalse("f1 should not exist", f1.exists()); + assertFalse("d1f2 should not exist", d2f2.exists()); + assertThat(x.getMessage(), containsString(dir.getPath())); + assertThat(x.getMessage(), allOf(not(containsString("interrupted")), containsString("Tried 2 times (of a maximum of 2)."), not(containsString("garbage-collecting")), not(containsString("wait")))); + } + } finally { + Util.DELETION_MAX = defaultDeletionMax; + Util.WAIT_BETWEEN_DELETION_RETRIES = defaultDeletionWait; + Util.GC_AFTER_FAILED_DELETE = defaultDeletionGC; + unlockFilesForDeletion(); + } + } + + @Test + public void testDeleteRecursive() throws Exception { + final File dir = tmp.newFolder(); + final File d1 = new File(dir, "d1"); + final File d2 = new File(dir, "d2"); + final File f1 = new File(dir, "f1"); + final File d1f1 = new File(d1, "d1f1"); + final File d2f2 = new File(d2, "d1f2"); + // Test: Files and directories are deleted + mkdirs(dir, d1, d2); + mkfiles(f1, d1f1, d2f2); + Util.deleteRecursive(dir); + assertFalse("dir exists", dir.exists()); + } + + @Test + public void testDeleteRecursive_onWindows() throws Exception { + Assume.assumeTrue(Functions.isWindows()); + final File dir = tmp.newFolder(); + final File d1 = new File(dir, "d1"); + final File d2 = new File(dir, "d2"); + final File f1 = new File(dir, "f1"); + final File d1f1 = new File(d1, "d1f1"); + final File d2f2 = new File(d2, "d1f2"); + final int defaultDeletionMax = Util.DELETION_MAX; + final int defaultDeletionWait = Util.WAIT_BETWEEN_DELETION_RETRIES; + final boolean defaultDeletionGC = Util.GC_AFTER_FAILED_DELETE; + try { + // Test: If we cannot delete a file, we throw + // but still deletes everything it can + // even if we are not retrying deletes. + // (And when we are not retrying deletes, + // we do not do the "between retries" delay) + mkdirs(dir, d1, d2); + mkfiles(f1, d1f1, d2f2); + lockFileForDeletion(d1f1); + Util.GC_AFTER_FAILED_DELETE = false; + Util.DELETION_MAX = 1; + Util.WAIT_BETWEEN_DELETION_RETRIES = 10000; // long enough to notice + long timeWhenDeletionStarted = System.currentTimeMillis(); + try { + Util.deleteRecursive(dir); + fail("Expected IOException"); + } catch (IOException x) { + long timeWhenDeletionEnded = System.currentTimeMillis(); + assertTrue("dir exists", dir.exists()); + assertTrue("d1 exists", d1.exists()); + assertTrue("d1f1 exists", d1f1.exists()); + assertFalse("d2 should not exist", d2.exists()); + assertFalse("f1 should not exist", f1.exists()); + assertFalse("d1f2 should not exist", d2f2.exists()); + assertThat(x.getMessage(), containsString(dir.getPath())); + assertThat(x.getMessage(), allOf(not(containsString("interrupted")), not(containsString("maximum of")), not(containsString("garbage-collecting")))); + long actualTimeSpentDeleting = timeWhenDeletionEnded - timeWhenDeletionStarted; + assertTrue("did not wait - took " + actualTimeSpentDeleting + "ms", actualTimeSpentDeleting<1000L); + } + unlockFileForDeletion(d1f1); + // Deletes get retried if they fail 1st time around, + // allowing the operation to succeed on subsequent attempts. + // Note: This is what bug JENKINS-15331 is all about. + mkdirs(dir, d1, d2); + mkfiles(f1, d1f1, d2f2); + lockFileForDeletion(d2f2); + Util.DELETION_MAX=4; + Util.WAIT_BETWEEN_DELETION_RETRIES = 100; + Thread unlockAfterDelay = new Thread("unlockFileAfterDelay") { + public void run() { + try { + Thread.sleep(Util.WAIT_BETWEEN_DELETION_RETRIES); + unlockFileForDeletion(d2f2); + } catch( Exception x ) { /* ignored */ } + } + }; + unlockAfterDelay.start(); + Util.deleteRecursive(dir); + assertFalse("dir should have been deleted", dir.exists()); + unlockAfterDelay.join(); + // An interrupt aborts the delete and makes it fail, even + // if we had been told to retry a lot. + mkdirs(dir, d1, d2); + mkfiles(f1, d1f1, d2f2); + lockFileForDeletion(d1f1); + Util.DELETION_MAX=10; + Util.WAIT_BETWEEN_DELETION_RETRIES = -1000; + Util.GC_AFTER_FAILED_DELETE = true; + final AtomicReference thrown = new AtomicReference(); + Thread deleteToBeInterupted = new Thread("deleteToBeInterupted") { + public void run() { + try { Util.deleteRecursive(dir); } + catch( Throwable x ) { thrown.set(x); } + } + }; + deleteToBeInterupted.start(); + deleteToBeInterupted.interrupt(); + deleteToBeInterupted.join(500); + assertFalse("deletion stopped", deleteToBeInterupted.isAlive()); + assertTrue("d1f1 still exists", d1f1.exists()); + unlockFileForDeletion(d1f1); + Throwable deletionInterruptedEx = thrown.get(); + assertThat(deletionInterruptedEx, instanceOf(IOException.class)); + assertThat(deletionInterruptedEx.getMessage(), allOf(containsString("interrupted"), containsString("maximum of " + Util.DELETION_MAX), containsString("garbage-collecting"))); + } finally { + Util.DELETION_MAX = defaultDeletionMax; + Util.WAIT_BETWEEN_DELETION_RETRIES = defaultDeletionWait; + Util.GC_AFTER_FAILED_DELETE = defaultDeletionGC; + unlockFilesForDeletion(); + } + } + + /** Creates multiple directories. */ + private static void mkdirs(File... dirs) { + for( File d : dirs ) { + d.mkdir(); + assertTrue(d.getPath(), d.isDirectory()); + } + } + + /** Creates multiple files, each containing their filename as text content. */ + private static void mkfiles(File... files) throws IOException { + for( File f : files ) + FileUtils.write(f, f.getName()); + } + + /** Means of unlocking all the files we have locked, indexed by {@link File}. */ + private final Map> unlockFileCallables = new HashMap>(); + + /** Prevents a file from being deleted, so we can stress the deletion code's retries. */ + private void lockFileForDeletion(File f) throws IOException, InterruptedException { + assert !unlockFileCallables.containsKey(f) : f + " is already locked." ; + // Limitation: Only works on Windows. On unix we can delete anything we can create. + // On unix, can't use "chmod a-w" on the dir as the code-under-test undoes that. + // On unix, can't use "chattr +i" because that needs root. + // On unix, can't use "chattr +u" because ext fs ignores it. + // On Windows, we can't delete files that are open for reading, so we use that. + assert Functions.isWindows(); + final InputStream s = new FileInputStream(f); + unlockFileCallables.put(f, new Callable() { + public Void call() throws IOException { s.close(); return null; }; + }); + } + + /** Undoes a call to {@link #lockFileForDeletion(File)}. */ + private void unlockFileForDeletion(File f) throws Exception { + unlockFileCallables.remove(f).call(); + } + + /** Undoes all calls to {@link #lockFileForDeletion(File)}. */ + private void unlockFilesForDeletion() throws Exception { + while( !unlockFileCallables.isEmpty() ) { + unlockFileForDeletion(unlockFileCallables.keySet().iterator().next()); } } + /** Returns all classes in the exception hierarchy. */ + private static Iterable> calcExceptionHierarchy(Throwable t) { + final List> result = Lists.newArrayList(); + for( ; t!=null ; t = t.getCause()) + result.add(t.getClass()); + return result; + } + @Test public void testHtmlEscape() { assertEquals("
    ", Util.escape("\n")); @@ -344,6 +587,26 @@ public class UtilTest { assertFalse(Util.isAbsoluteUri("foo/bar")); } + @Test + @Issue("SECURITY-276") + public void testIsSafeToRedirectTo() { + assertFalse(Util.isSafeToRedirectTo("http://foobar/")); + assertFalse(Util.isSafeToRedirectTo("mailto:kk@kohsuke.org")); + assertFalse(Util.isSafeToRedirectTo("d123://test/")); + assertFalse(Util.isSafeToRedirectTo("//google.com")); + + assertTrue(Util.isSafeToRedirectTo("foo/bar/abc:def")); + assertTrue(Util.isSafeToRedirectTo("foo?abc:def")); + assertTrue(Util.isSafeToRedirectTo("foo#abc:def")); + assertTrue(Util.isSafeToRedirectTo("foo/bar")); + assertTrue(Util.isSafeToRedirectTo("/")); + assertTrue(Util.isSafeToRedirectTo("/foo")); + assertTrue(Util.isSafeToRedirectTo("..")); + assertTrue(Util.isSafeToRedirectTo("../..")); + assertTrue(Util.isSafeToRedirectTo("/#foo")); + assertTrue(Util.isSafeToRedirectTo("/?foo")); + } + @Test public void loadProperties() throws IOException { diff --git a/core/src/test/java/hudson/cli/ListJobsCommandTest.java b/core/src/test/java/hudson/cli/ListJobsCommandTest.java index 51b4cd980cb1b1cc2783a46fbebc0f9025fba447..a08935c8556ce3b47de8365c96ba3d47b1d993c4 100644 --- a/core/src/test/java/hudson/cli/ListJobsCommandTest.java +++ b/core/src/test/java/hudson/cli/ListJobsCommandTest.java @@ -4,6 +4,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.fail; import static org.powermock.api.mockito.PowerMockito.mock; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.when; @@ -50,6 +51,7 @@ public class ListJobsCommandTest { jenkins = mock(Jenkins.class); mockStatic(Jenkins.class); when(Jenkins.getInstance()).thenReturn(jenkins); + when(Jenkins.getActiveInstance()).thenReturn(jenkins); command = mock(ListJobsCommand.class, Mockito.CALLS_REAL_METHODS); command.stdout = new PrintStream(stdout); command.stderr = new PrintStream(stderr); @@ -61,9 +63,13 @@ public class ListJobsCommandTest { when(jenkins.getView("NoSuchViewOrItemGroup")).thenReturn(null); when(jenkins.getItemByFullName("NoSuchViewOrItemGroup")).thenReturn(null); - assertThat(runWith("NoSuchViewOrItemGroup"), equalTo(-1)); + try { + runWith("NoSuchViewOrItemGroup"); + fail("Exception should be thrown in the previous call."); + } catch (IllegalArgumentException e) { // Expected + assertThat(e.getMessage(), containsString("No view or item group with the given name 'NoSuchViewOrItemGroup' found.")); + } assertThat(stdout, is(empty())); - assertThat(stderr.toString(), containsString("No view or item group with the given name found")); } /* diff --git a/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java b/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java index 98b29e2e1d77ae77807c0d72210f3dfd1e70a5f1..1f17d89d771c58d7cb93f0dc20477cc2bd083fd1 100644 --- a/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java +++ b/core/src/test/java/hudson/cli/handlers/ViewOptionHandlerTest.java @@ -27,7 +27,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; import hudson.model.ViewGroup; @@ -81,6 +80,7 @@ public class ViewOptionHandlerTest { PowerMockito.mockStatic(Jenkins.class); PowerMockito.when(Jenkins.getInstance()).thenReturn(jenkins); + PowerMockito.when(Jenkins.getActiveInstance()).thenReturn(jenkins); when(jenkins.getView("outer")).thenReturn(outer); when(jenkins.getDisplayName()).thenReturn("Jenkins"); } @@ -117,7 +117,7 @@ public class ViewOptionHandlerTest { assertEquals( "No view named missing_view inside view Jenkins", - parseFailedWith(CmdLineException.class, "missing_view") + parseFailedWith(IllegalArgumentException.class, "missing_view") ); verifyZeroInteractions(setter); @@ -127,7 +127,7 @@ public class ViewOptionHandlerTest { assertEquals( "No view named missing_view inside view outer", - parseFailedWith(CmdLineException.class, "outer/missing_view") + parseFailedWith(IllegalArgumentException.class, "outer/missing_view") ); verifyZeroInteractions(setter); @@ -137,7 +137,7 @@ public class ViewOptionHandlerTest { assertEquals( "No view named missing_view inside view nested", - parseFailedWith(CmdLineException.class, "outer/nested/missing_view") + parseFailedWith(IllegalArgumentException.class, "outer/nested/missing_view") ); verifyZeroInteractions(setter); @@ -147,20 +147,46 @@ public class ViewOptionHandlerTest { assertEquals( "inner view can not contain views", - parseFailedWith(CmdLineException.class, "outer/nested/inner/missing") + parseFailedWith(IllegalStateException.class, "outer/nested/inner/missing") ); verifyZeroInteractions(setter); } + @Test public void reportEmptyViewNameRequestAsNull() throws Exception { + assertEquals(handler.getView(""), null); + verifyZeroInteractions(setter); + } + + @Test public void reportViewSpaceNameRequestAsIAE() throws Exception { + try { + assertEquals(handler.getView(" "), null); + fail("No exception thrown. Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + assertEquals("No view named inside view Jenkins", e.getMessage()); + verifyZeroInteractions(setter); + } + } + + @Test public void reportNullViewAsNPE() throws Exception { + try { + handler.getView(null); + fail("No exception thrown. Expected NullPointerException"); + } catch (NullPointerException e) { + verifyZeroInteractions(setter); + } + } + @Test public void refuseToReadOuterView() throws Exception { denyAccessOn(outer); - parseFailedWith(AccessDeniedException.class, "outer/nested/inner"); + assertEquals( + "Access denied for: outer", + parseFailedWith(AccessDeniedException.class, "outer/nested/inner") + ); verify(outer).checkPermission(View.READ); - verifyNoMoreInteractions(outer); verifyZeroInteractions(nested); verifyZeroInteractions(inner); @@ -171,10 +197,12 @@ public class ViewOptionHandlerTest { denyAccessOn(nested); - parseFailedWith(AccessDeniedException.class, "outer/nested/inner"); + assertEquals( + "Access denied for: nested", + parseFailedWith(AccessDeniedException.class, "outer/nested/inner") + ); verify(nested).checkPermission(View.READ); - verifyNoMoreInteractions(nested); verifyZeroInteractions(inner); verifyZeroInteractions(setter); @@ -184,17 +212,20 @@ public class ViewOptionHandlerTest { denyAccessOn(inner); - parseFailedWith(AccessDeniedException.class, "outer/nested/inner"); + assertEquals( + "Access denied for: inner", + parseFailedWith(AccessDeniedException.class, "outer/nested/inner") + ); verify(inner).checkPermission(View.READ); - verifyNoMoreInteractions(inner); verifyZeroInteractions(setter); } private void denyAccessOn(View view) { - doThrow(new AccessDeniedException(null)).when(view).checkPermission(View.READ); + final AccessDeniedException ex = new AccessDeniedException("Access denied for: " + view.getViewName()); + doThrow(ex).when(view).checkPermission(View.READ); } private String parseFailedWith(Class type, final String... params) throws Exception { diff --git a/core/src/test/java/hudson/model/ActionableTest.java b/core/src/test/java/hudson/model/ActionableTest.java index 4f454050808d63d215070cfc3e949ae80b0e0a51..550a8853969d9bcd596fe12803430332b60aa9e2 100644 --- a/core/src/test/java/hudson/model/ActionableTest.java +++ b/core/src/test/java/hudson/model/ActionableTest.java @@ -24,18 +24,26 @@ package hudson.model; +import java.util.ArrayList; import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; + +import java.util.Collections; +import java.util.List; + +import org.junit.Assert; import org.junit.Test; +import org.jvnet.hudson.test.Issue; public class ActionableTest { + private Actionable thing = new ActionableImpl(); + @SuppressWarnings("deprecation") - @Test public void replaceAction() { - Actionable thing = new Actionable() { - @Override public String getDisplayName() {return null;} - @Override public String getSearchUrl() {return null;} - }; + @Test + public void replaceAction() { CauseAction a1 = new CauseAction(); ParametersAction a2 = new ParametersAction(); thing.addAction(a1); @@ -45,4 +53,168 @@ public class ActionableTest { assertEquals(Arrays.asList(a2, a3), thing.getActions()); } + static class ActionableOverride extends Actionable { + ArrayList specialActions = new ArrayList(); + + @Override + public String getDisplayName() { + return "nope"; + } + + @Override + public String getSearchUrl() { + return "morenope"; + } + + @Override + public List getActions() { + return specialActions; + } + } + + @SuppressWarnings("deprecation") + @Issue("JENKINS-39555") + @Test + public void testExtensionOverrides() throws Exception { + ActionableOverride myOverridden = new ActionableOverride(); + InvisibleAction invis = new InvisibleAction() { + }; + myOverridden.addAction(invis); + Assert.assertArrayEquals(new Object[]{invis}, myOverridden.specialActions.toArray()); + Assert.assertArrayEquals(new Object[]{invis}, myOverridden.getActions().toArray()); + + myOverridden.getActions().remove(invis); + Assert.assertArrayEquals(new Object[]{}, myOverridden.specialActions.toArray()); + Assert.assertArrayEquals(new Object[]{}, myOverridden.getActions().toArray()); + + myOverridden.addAction(invis); + myOverridden.removeAction(invis); + Assert.assertArrayEquals(new Object[]{}, myOverridden.specialActions.toArray()); + Assert.assertArrayEquals(new Object[]{}, myOverridden.getActions().toArray()); + + InvisibleAction invis2 = new InvisibleAction() {}; + myOverridden.addOrReplaceAction(invis2); + Assert.assertArrayEquals(new Object[]{invis2}, myOverridden.specialActions.toArray()); + Assert.assertArrayEquals(new Object[]{invis2}, myOverridden.getActions().toArray()); + + myOverridden.addOrReplaceAction(invis); + myOverridden.addOrReplaceAction(invis); + Assert.assertArrayEquals(new Object[]{invis2, invis}, myOverridden.specialActions.toArray()); + Assert.assertArrayEquals(new Object[]{invis2, invis}, myOverridden.getActions().toArray()); + } + + @SuppressWarnings("deprecation") + @Test + public void addOrReplaceAction() { + CauseAction a1 = new CauseAction(); + ParametersAction a2 = new ParametersAction(); + thing.addAction(a1); + thing.addAction(a2); + CauseAction a3 = new CauseAction(); + assertTrue(thing.addOrReplaceAction(a3)); + assertEquals(Arrays.asList(a2, a3), thing.getActions()); + assertFalse(thing.addOrReplaceAction(a3)); + assertEquals(Arrays.asList(a2, a3), thing.getActions()); + thing.addAction(a1); + assertEquals(Arrays.asList(a2, a3, a1), thing.getActions()); + assertTrue(thing.addOrReplaceAction(a3)); + assertEquals(Arrays.asList(a2, a3), thing.getActions()); + } + + @SuppressWarnings("deprecation") + @Test + public void replaceActions() { + CauseAction a1 = new CauseAction(); + ParametersAction a2 = new ParametersAction(); + thing.addAction(a1); + thing.addAction(a2); + CauseAction a3 = new CauseAction(); + assertTrue(thing.replaceActions(CauseAction.class, a3)); + assertEquals(Arrays.asList(a2, a3), thing.getActions()); + assertFalse(thing.replaceActions(CauseAction.class, a3)); + assertEquals(Arrays.asList(a2, a3), thing.getActions()); + } + + @SuppressWarnings("deprecation") + @Test + public void removeAction() { + CauseAction a1 = new CauseAction(); + ParametersAction a2 = new ParametersAction(); + thing.addAction(a1); + thing.addAction(a2); + assertEquals(Arrays.asList(a1, a2), thing.getActions()); + assertThat(thing.removeAction(a1), is(true)); + assertEquals(Arrays.asList(a2), thing.getActions()); + assertThat(thing.removeAction(a1), is(false)); + assertEquals(Arrays.asList(a2), thing.getActions()); + assertThat(thing.removeAction(null), is(false)); + assertEquals(Arrays.asList(a2), thing.getActions()); + } + + @SuppressWarnings("deprecation") + @Test + public void removeActions() { + CauseAction a1 = new CauseAction(); + ParametersAction a2 = new ParametersAction(); + thing.addAction(a1); + thing.addAction(a2); + assertEquals(Arrays.asList(a1, a2), thing.getActions()); + assertThat(thing.removeActions(CauseAction.class), is(true)); + assertEquals(Arrays.asList(a2), thing.getActions()); + assertThat(thing.removeActions(CauseAction.class), is(false)); + assertEquals(Arrays.asList(a2), thing.getActions()); + } + + @SuppressWarnings("deprecation") + @Test + public void addAction() { + CauseAction a1 = new CauseAction(); + ParametersAction a2 = new ParametersAction(); + assertEquals(Collections.emptyList(), thing.getActions()); + thing.addAction(a1); + assertEquals(Collections.singletonList(a1), thing.getActions()); + thing.addAction(a2); + assertEquals(Arrays.asList(a1, a2), thing.getActions()); + } + + @Test(expected = IllegalArgumentException.class) + public void addAction_null() { + thing.addAction(null); + } + + @Test(expected = IllegalArgumentException.class) + public void replaceAction_null() { + thing.replaceAction(null); + } + + @Test(expected = IllegalArgumentException.class) + public void replaceActions_null() { + thing.replaceActions(CauseAction.class, null); + } + + @Test(expected = IllegalArgumentException.class) + public void replaceActions_null_null() { + thing.replaceActions(null, null); + } + + @Test(expected = IllegalArgumentException.class) + public void addOrReplaceAction_null() { + thing.addOrReplaceAction(null); + } + + @Test + public void removeAction_null() { + assertFalse(thing.removeAction(null)); + } + + @Test(expected = IllegalArgumentException.class) + public void removeActions_null() { + thing.removeActions(null); + } + + private static class ActionableImpl extends Actionable { + @Override public String getDisplayName() {return null;} + + @Override public String getSearchUrl() {return null;} + } } diff --git a/core/src/test/java/hudson/model/ChoiceParameterDefinitionTest.java b/core/src/test/java/hudson/model/ChoiceParameterDefinitionTest.java index 74ac53e23826dc61b36757c35f6d33757cee57f9..0414e8a784cdd95a5887c8d9cbd6478127a2c378 100644 --- a/core/src/test/java/hudson/model/ChoiceParameterDefinitionTest.java +++ b/core/src/test/java/hudson/model/ChoiceParameterDefinitionTest.java @@ -1,7 +1,6 @@ package hudson.model; import hudson.util.FormValidation; -import jenkins.model.Jenkins; import org.junit.Test; import static org.junit.Assert.assertEquals; diff --git a/core/src/test/java/hudson/model/FileParameterValueTest.java b/core/src/test/java/hudson/model/FileParameterValueTest.java index 06dfe70842150a66aaf1c7dbed14b6b7f2513f85..13f6e339dad982146811cc4f31367d27891aca38 100644 --- a/core/src/test/java/hudson/model/FileParameterValueTest.java +++ b/core/src/test/java/hudson/model/FileParameterValueTest.java @@ -33,7 +33,7 @@ import org.jvnet.hudson.test.Issue; /** * Test for {@link FileParameterValue}. - * @author Oleg Nenashev + * @author Oleg Nenashev */ public class FileParameterValueTest { diff --git a/core/src/test/java/hudson/model/FingerprintTest.java b/core/src/test/java/hudson/model/FingerprintTest.java index fa77da0364cdaf3b45019b04c91124941b1d9b8b..6f0d117847b60b264b4729d8fd0254601ff9de49 100644 --- a/core/src/test/java/hudson/model/FingerprintTest.java +++ b/core/src/test/java/hudson/model/FingerprintTest.java @@ -27,6 +27,9 @@ import hudson.Util; import hudson.model.Fingerprint.RangeSet; import java.io.File; import jenkins.model.FingerprintFacet; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.*; import org.junit.Rule; import org.junit.Test; @@ -259,4 +262,274 @@ public class FingerprintTest { } } + @Test public void fromString() throws Exception { + // + // Single + // + // Numbers + assertThat(RangeSet.fromString("1", true).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("1", false).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("+1", true).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("+1", false).toString(), equalTo("[1,2)")); + // Zero + assertThat(RangeSet.fromString("0", true).toString(), equalTo("[0,1)")); + assertThat(RangeSet.fromString("0", false).toString(), equalTo("[0,1)")); + assertThat(RangeSet.fromString("+0", true).toString(), equalTo("[0,1)")); + assertThat(RangeSet.fromString("+0", false).toString(), equalTo("[0,1)")); + // Negative number + assertThat(RangeSet.fromString("-1", true).toString(), equalTo("")); + assertThat(expectIAE("-1", "Unable to parse '-1', expected string with a range M-N"), is(true)); + // Exceeded int number + assertThat(RangeSet.fromString("2147483648", true).toString(), equalTo("")); + assertThat(expectIAE("2147483648", "Unable to parse '2147483648', expected number"), is(true)); + // Invalid number + assertThat(RangeSet.fromString("1a", true).toString(), equalTo("")); + assertThat(expectIAE("1a", "Unable to parse '1a', expected number"), is(true)); + assertThat(RangeSet.fromString("aa", true).toString(), equalTo("")); + assertThat(expectIAE("aa", "Unable to parse 'aa', expected number"), is(true)); + //Empty + assertThat(RangeSet.fromString("", true).toString(), equalTo("")); + assertThat(RangeSet.fromString("", false).toString(), equalTo("")); + //Space + assertThat(RangeSet.fromString(" ", true).toString(), equalTo("")); + assertThat(expectIAE(" ", "Unable to parse ' ', expected number"), is(true)); + // Comma + assertThat(RangeSet.fromString(",", true).toString(), equalTo("")); + assertThat(RangeSet.fromString(",", false).toString(), equalTo("")); + // Hyphen + assertThat(RangeSet.fromString("-", true).toString(), equalTo("")); + assertThat(expectIAE("-", "Unable to parse '-', expected string with a range M-N"), is(true)); + + // + // Multiple numbers + // + // Numbers + assertThat(RangeSet.fromString("1,2", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(RangeSet.fromString("1,2", false).toString(), equalTo("[1,2),[2,3)")); + assertThat(RangeSet.fromString("1,+2,5", true).toString(), equalTo("[1,2),[2,3),[5,6)")); + assertThat(RangeSet.fromString("1,+2,5", false).toString(), equalTo("[1,2),[2,3),[5,6)")); + assertThat(RangeSet.fromString("1,1", true).toString(), equalTo("[1,2),[1,2)")); + assertThat(RangeSet.fromString("1,1", false).toString(), equalTo("[1,2),[1,2)")); + // Zero + assertThat(RangeSet.fromString("0,1,2", true).toString(), equalTo("[0,1),[1,2),[2,3)")); + assertThat(RangeSet.fromString("0,1,2", false).toString(), equalTo("[0,1),[1,2),[2,3)")); + assertThat(RangeSet.fromString("1,0,2", true).toString(), equalTo("[1,2),[0,1),[2,3)")); + assertThat(RangeSet.fromString("1,0,2", false).toString(), equalTo("[1,2),[0,1),[2,3)")); + assertThat(RangeSet.fromString("1,2,0", true).toString(), equalTo("[1,2),[2,3),[0,1)")); + assertThat(RangeSet.fromString("1,2,0", false).toString(), equalTo("[1,2),[2,3),[0,1)")); + // Negative number + assertThat(RangeSet.fromString("-1,2,3", true).toString(), equalTo("[2,3),[3,4)")); + assertThat(expectIAE("-1,2,3", "Unable to parse '-1,2,3', expected string with a range M-N"), is(true)); + assertThat(RangeSet.fromString("1,-2,3", true).toString(), equalTo("[1,2),[3,4)")); + assertThat(expectIAE("1,-2,3", "Unable to parse '1,-2,3', expected string with a range M-N"), is(true)); + assertThat(RangeSet.fromString("1,2,-3", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,2,-3", "Unable to parse '1,2,-3', expected string with a range M-N"), is(true)); + // Exceeded int number + assertThat(RangeSet.fromString("2147483648,2,3", true).toString(), equalTo("[2,3),[3,4)")); + assertThat(expectIAE("2147483648,1,2", "Unable to parse '2147483648,1,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,2147483648,3", true).toString(), equalTo("[1,2),[3,4)")); + assertThat(expectIAE("1,2147483648,2", "Unable to parse '1,2147483648,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,2,2147483648", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,2,2147483648", "Unable to parse '1,2,2147483648', expected number"), is(true)); + // Invalid number + assertThat(RangeSet.fromString("1a,2,3", true).toString(), equalTo("[2,3),[3,4)")); + assertThat(expectIAE("1a,1,2", "Unable to parse '1a,1,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,2a,3", true).toString(), equalTo("[1,2),[3,4)")); + assertThat(expectIAE("1,2a,2", "Unable to parse '1,2a,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,2,3a", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,2,3a", "Unable to parse '1,2,3a', expected number"), is(true)); + assertThat(RangeSet.fromString("aa,2,3", true).toString(), equalTo("[2,3),[3,4)")); + assertThat(expectIAE("aa,1,2", "Unable to parse 'aa,1,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,aa,3", true).toString(), equalTo("[1,2),[3,4)")); + assertThat(expectIAE("1,aa,2", "Unable to parse '1,aa,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,2,aa", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,2,aa", "Unable to parse '1,2,aa', expected number"), is(true)); + //Empty + assertThat(RangeSet.fromString(",1,2", true).toString(), equalTo("")); + assertThat(expectIAE(",1,2", "Unable to parse ',1,2', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("1,,2", true).toString(), equalTo("")); + assertThat(expectIAE("1,,2", "Unable to parse '1,,2', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("1,2,", true).toString(), equalTo("")); + assertThat(expectIAE("1,2,", "Unable to parse '1,2,', expected correct notation M,N or M-N"), is(true)); + // Space + assertThat(RangeSet.fromString(" ,1,2", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE(" ,1,2", "Unable to parse ' ,1,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1, ,2", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1, ,2", "Unable to parse '1, ,2', expected number"), is(true)); + assertThat(RangeSet.fromString("1,2, ", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,2, ", "Unable to parse '1,2, ', expected number"), is(true)); + // Comma + assertThat(RangeSet.fromString(",,1,2", true).toString(), equalTo("")); + assertThat(expectIAE(",,1,2", "Unable to parse ',,1,2', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("1,,,2", true).toString(), equalTo("")); + assertThat(expectIAE("1,,,2", "Unable to parse '1,,,2', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("1,2,,", true).toString(), equalTo("")); + assertThat(expectIAE("1,2,,", "Unable to parse '1,2,,', expected correct notation M,N or M-N"), is(true)); + // Hyphen + assertThat(RangeSet.fromString("-,1,2", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("-,1,2", "Unable to parse '-,1,2', expected string with a range M-N"), is(true)); + assertThat(RangeSet.fromString("1,-,2", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,-,2", "Unable to parse '1,-,2', expected string with a range M-N"), is(true)); + assertThat(RangeSet.fromString("1,2,-", true).toString(), equalTo("[1,2),[2,3)")); + assertThat(expectIAE("1,2,-", "Unable to parse '1,2,-', expected string with a range M-N"), is(true)); + + // + // Single range + // + // Numbers + assertThat(RangeSet.fromString("1-2", true).toString(), equalTo("[1,3)")); + assertThat(RangeSet.fromString("1-2", false).toString(), equalTo("[1,3)")); + assertThat(RangeSet.fromString("+1-+2", true).toString(), equalTo("[1,3)")); + assertThat(RangeSet.fromString("+1-+2", false).toString(), equalTo("[1,3)")); + assertThat(RangeSet.fromString("1-1", true).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("1-1", false).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("+1-+1", true).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("+1-+1", false).toString(), equalTo("[1,2)")); + assertThat(RangeSet.fromString("1-4", true).toString(), equalTo("[1,5)")); + assertThat(RangeSet.fromString("1-4", false).toString(), equalTo("[1,5)")); + assertThat(RangeSet.fromString("+1-+4", true).toString(), equalTo("[1,5)")); + assertThat(RangeSet.fromString("+1-+4", false).toString(), equalTo("[1,5)")); + //Zero + assertThat(RangeSet.fromString("0-1", true).toString(), equalTo("[0,2)")); + assertThat(RangeSet.fromString("0-1", false).toString(), equalTo("[0,2)")); + assertThat(RangeSet.fromString("+0-+1", true).toString(), equalTo("[0,2)")); + assertThat(RangeSet.fromString("+0-+1", false).toString(), equalTo("[0,2)")); + assertThat(RangeSet.fromString("0-2", true).toString(), equalTo("[0,3)")); + assertThat(RangeSet.fromString("0-2", false).toString(), equalTo("[0,3)")); + assertThat(RangeSet.fromString("+0-+2", true).toString(), equalTo("[0,3)")); + assertThat(RangeSet.fromString("+0-+2", false).toString(), equalTo("[0,3)")); + assertThat(RangeSet.fromString("0--1", true).toString(), equalTo("")); + assertThat(expectIAE("0--1", "Unable to parse '0--1', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("+0--1", true).toString(), equalTo("")); + assertThat(expectIAE("+0--1", "Unable to parse '+0--1', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("0--2", true).toString(), equalTo("")); + assertThat(expectIAE("0--2", "Unable to parse '0--2', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("+0--2", true).toString(), equalTo("")); + assertThat(expectIAE("+0--2", "Unable to parse '+0--2', expected correct notation M,N or M-N"), is(true)); + assertThat(RangeSet.fromString("1-0", true).toString(), equalTo("")); + assertThat(expectIAE("1-0", "Unable to parse '1-0', expected string with a range M-N where MNicolas De Loof + * @author: Nicolas De Loof */ public class ItemsTest { @@ -44,6 +41,27 @@ public class ItemsTest { assertEquals("foo/bar", Items.getCanonicalName(foo, "./bar")); assertEquals("foo/bar/baz/qux", Items.getCanonicalName(foo_bar, "baz/qux")); assertEquals("foo/baz/qux", Items.getCanonicalName(foo_bar, "../baz/qux")); + + try { + Items.getCanonicalName(root, ".."); + fail(); + } catch (IllegalArgumentException ex) { + assertEquals("Illegal relative path '..' within context ''", ex.getMessage()); + } + + try { + Items.getCanonicalName(foo, "../.."); + fail(); + } catch (IllegalArgumentException ex) { + assertEquals("Illegal relative path '../..' within context 'foo'", ex.getMessage()); + } + + try { + Items.getCanonicalName(root, "foo/../.."); + fail(); + } catch (IllegalArgumentException ex) { + assertEquals("Illegal relative path 'foo/../..' within context ''", ex.getMessage()); + } } @Test diff --git a/core/src/test/java/hudson/model/ListViewTest.java b/core/src/test/java/hudson/model/ListViewTest.java index 7de805913b5d3c324e70a40ae3ba2cb624a4f827..f184aac9a24679d1404133cf841094512ba16391 100644 --- a/core/src/test/java/hudson/model/ListViewTest.java +++ b/core/src/test/java/hudson/model/ListViewTest.java @@ -30,7 +30,7 @@ public class ListViewTest { mockStatic(Items.class); mockStatic(ListViewColumn.class); List columns = Collections.emptyList(); - when(ListViewColumn.createDefaultInitialColumnList()).thenReturn(columns); + when(ListViewColumn.createDefaultInitialColumnList(ListView.class)).thenReturn(columns); ViewGroup owner = mock(ViewGroup.class); ItemGroup itemGroupOwner = mock(ItemGroup.class); when(owner.getItemGroup()).thenReturn(itemGroupOwner); @@ -49,7 +49,7 @@ public class ListViewTest { mockStatic(Items.class); mockStatic(ListViewColumn.class); List columns = Collections.emptyList(); - when(ListViewColumn.createDefaultInitialColumnList()).thenReturn(columns); + when(ListViewColumn.createDefaultInitialColumnList(ListView.class)).thenReturn(columns); ViewGroup owner = mock(ViewGroup.class); ItemGroup ig = mock(ItemGroup.class); when(owner.getItemGroup()).thenReturn(ig); diff --git a/test/src/main/java/org/jvnet/hudson/test/FailureBuilder.java b/core/src/test/java/hudson/model/MockItem.java similarity index 57% rename from test/src/main/java/org/jvnet/hudson/test/FailureBuilder.java rename to core/src/test/java/hudson/model/MockItem.java index 7caa45305c7a89cf242159c2d1158e937b9ccd50..f0b244be7e42ca975de6bbfc963ad12358bd90f5 100644 --- a/test/src/main/java/org/jvnet/hudson/test/FailureBuilder.java +++ b/core/src/test/java/hudson/model/MockItem.java @@ -1,18 +1,18 @@ /* * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * + * Copyright (c) 2013-2015, CloudBees, Inc. + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,32 +21,46 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; +package hudson.model; -import hudson.Extension; -import hudson.model.Descriptor; -import hudson.model.Result; -import hudson.tasks.Builder; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerRequest; +import hudson.model.queue.CauseOfBlockage; + +import java.util.Collections; +import java.util.List; /** - * Mock {@link Builder} that always cause a build to fail. - * - * @author Kohsuke Kawaguchi + * @author tom.fennelly@gmail.com */ -public class FailureBuilder extends MockBuilder { - public FailureBuilder() { - super(Result.FAILURE); +public class MockItem extends Queue.Item { + + public MockItem(long id) { + super(null, Collections.emptyList(), id, null); + } + + public MockItem(Queue.Task task, List actions, long id) { + super(task, actions, id, null); + } + + /** + * Override as needed. + */ + @Override + public CauseOfBlockage getCauseOfBlockage() { + return null; + } + + /** + * Override as needed. + */ + @Override + void enter(Queue q) { } - @Extension - public static final class DescriptorImpl extends Descriptor { - public String getDisplayName() { - return "Always fail"; - } - public FailureBuilder newInstance(StaplerRequest req, JSONObject data) { - return new FailureBuilder(); - } + /** + * Override as needed. + */ + @Override + boolean leave(Queue q) { + return true; } } diff --git a/core/src/test/java/hudson/model/ParametersActionTest.java b/core/src/test/java/hudson/model/ParametersActionTest.java index 8b96940a7bcac56d4420e32bd3c8518eb77a45b5..d9b6e63e690ac33965ff51c3a5564d88017ca02a 100644 --- a/core/src/test/java/hudson/model/ParametersActionTest.java +++ b/core/src/test/java/hudson/model/ParametersActionTest.java @@ -89,7 +89,7 @@ public class ParametersActionTest { @Test @Issue("JENKINS-15094") - public void checkNullParamaterValues() { + public void checkNullParameterValues() { SubTask subtask = mock(SubTask.class); Build build = mock(Build.class); diff --git a/core/src/test/java/hudson/model/RunTest.java b/core/src/test/java/hudson/model/RunTest.java index ef4d51e514361461a3ced22e6e6578ab91c170ca..58ce9a5b6ebbf20dbe3692048cca3906afdae807 100644 --- a/core/src/test/java/hudson/model/RunTest.java +++ b/core/src/test/java/hudson/model/RunTest.java @@ -159,7 +159,7 @@ public class RunTest { Job j = Mockito.mock(Job.class); File tempBuildDir = tmp.newFolder(); Mockito.when(j.getBuildDir()).thenReturn(tempBuildDir); - Run r = new Run(j, 0) {}; + Run, ? extends Run> r = new Run(j, 0) {}; File f = r.getLogFile(); f.getParentFile().mkdirs(); PrintWriter w = new PrintWriter(f, "utf-8"); @@ -169,4 +169,46 @@ public class RunTest { assertTrue(logLines.isEmpty()); } + @Test + public void getLogReturnsAnRightOrder() throws Exception { + Job j = Mockito.mock(Job.class); + File tempBuildDir = tmp.newFolder(); + Mockito.when(j.getBuildDir()).thenReturn(tempBuildDir); + Run, ? extends Run> r = new Run(j, 0) {}; + File f = r.getLogFile(); + f.getParentFile().mkdirs(); + PrintWriter w = new PrintWriter(f, "utf-8"); + for (int i = 0; i < 20; i++) { + w.println("dummy" + i); + } + + w.close(); + List logLines = r.getLog(10); + assertFalse(logLines.isEmpty()); + + for (int i = 1; i < 10; i++) { + assertEquals("dummy" + (10+i), logLines.get(i)); + } + assertEquals("[...truncated 68 B...]", logLines.get(0)); + } + + @Test + public void getLogReturnsAllLines() throws Exception { + Job j = Mockito.mock(Job.class); + File tempBuildDir = tmp.newFolder(); + Mockito.when(j.getBuildDir()).thenReturn(tempBuildDir); + Run, ? extends Run> r = new Run(j, 0) {}; + File f = r.getLogFile(); + f.getParentFile().mkdirs(); + PrintWriter w = new PrintWriter(f, "utf-8"); + w.print("a1\nb2\n\nc3"); + w.close(); + List logLines = r.getLog(10); + assertFalse(logLines.isEmpty()); + + assertEquals("a1", logLines.get(0)); + assertEquals("b2", logLines.get(1)); + assertEquals("", logLines.get(2)); + assertEquals("c3", logLines.get(3)); + } } diff --git a/core/src/test/java/hudson/model/UpdateCenterTest.java b/core/src/test/java/hudson/model/UpdateCenterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5d21e77b3f523720237c9c250370da9149a33fbb --- /dev/null +++ b/core/src/test/java/hudson/model/UpdateCenterTest.java @@ -0,0 +1,44 @@ +package hudson.model; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class UpdateCenterTest { + + @Test + public void toUpdateCenterCheckUrl_http_noQuery() throws Exception { + assertThat(UpdateCenter.UpdateCenterConfiguration.toUpdateCenterCheckUrl( + "http://updates.jenkins-ci.org/update-center.json").toExternalForm(), + is("http://updates.jenkins-ci.org/update-center.json?uctest")); + } + + @Test + public void toUpdateCenterCheckUrl_https_noQuery() throws Exception { + assertThat(UpdateCenter.UpdateCenterConfiguration.toUpdateCenterCheckUrl( + "https://updates.jenkins-ci.org/update-center.json").toExternalForm(), + is("https://updates.jenkins-ci.org/update-center.json?uctest")); + } + + @Test + public void toUpdateCenterCheckUrl_http_query() throws Exception { + assertThat(UpdateCenter.UpdateCenterConfiguration.toUpdateCenterCheckUrl( + "http://updates.jenkins-ci.org/update-center.json?version=2.7").toExternalForm(), + is("http://updates.jenkins-ci.org/update-center.json?version=2.7&uctest")); + } + + @Test + public void toUpdateCenterCheckUrl_https_query() throws Exception { + assertThat(UpdateCenter.UpdateCenterConfiguration.toUpdateCenterCheckUrl( + "https://updates.jenkins-ci.org/update-center.json?version=2.7").toExternalForm(), + is("https://updates.jenkins-ci.org/update-center.json?version=2.7&uctest")); + } + + @Test + public void toUpdateCenterCheckUrl_file() throws Exception { + assertThat(UpdateCenter.UpdateCenterConfiguration.toUpdateCenterCheckUrl( + "file://./foo.jar!update-center.json").toExternalForm(), + is("file://./foo.jar!update-center.json")); + } +} diff --git a/core/src/test/java/hudson/model/UserTest.java b/core/src/test/java/hudson/model/UserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f652bb0c4329ea6f48fb3c45bdec17a0755c8305 --- /dev/null +++ b/core/src/test/java/hudson/model/UserTest.java @@ -0,0 +1,73 @@ +package hudson.model; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertThat; +import org.junit.Test; +import org.jvnet.hudson.test.Issue; + +/* + * The MIT License + * + * Copyright (c) 2016 Oleg Nenashev. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * Unit tests for the {@link User} class. + * @author Oleg Nenashev + */ +public class UserTest { + + @Test + @Issue("JENKINS-33600") + public void blankIdsOrFullNamesShouldNotBeAllowed() { + assertThat("Null user IDs should not be allowed", User.isIdOrFullnameAllowed(null), is(false)); + assertThat("Empty user IDs should not be allowed", User.isIdOrFullnameAllowed(""), is(false)); + assertThat("Blank user IDs should not be allowed", User.isIdOrFullnameAllowed(" "), is(false)); + } + + @Test + @Issue("JENKINS-35967") + public void shoudNotAllowIllegalRestrictedNamesInWrongCase() { + assertIdOrFullNameNotAllowed("system"); + assertIdOrFullNameNotAllowed("System"); + assertIdOrFullNameNotAllowed("SYSTEM"); + assertIdOrFullNameNotAllowed("syStem"); + assertIdOrFullNameNotAllowed("sYstEm"); + } + + @Test + @Issue("JENKINS-35967") + public void shoudNotAllowIllegalRestrictedNamesEvenIfTrimmed() { + for (String username : User.getIllegalPersistedUsernames()) { + assertIdOrFullNameNotAllowed(username); + assertIdOrFullNameNotAllowed(" " + username); + assertIdOrFullNameNotAllowed(username + " "); + assertIdOrFullNameNotAllowed(" " + username + " "); + assertIdOrFullNameNotAllowed("\t" + username + "\t"); + } + } + + private void assertIdOrFullNameNotAllowed(String id) { + assertThat("User ID or full name '" + id + "' should not be allowed", + User.isIdOrFullnameAllowed(id), is(false)); + } + +} diff --git a/core/src/test/java/hudson/os/DCOMSandbox.java b/core/src/test/java/hudson/os/DCOMSandbox.java index 4c1bcdd4bd76ce08e476dd8867509bda201befe1..569944d5ba1f8bd598d27a4756cbf2a3d1e359e7 100644 --- a/core/src/test/java/hudson/os/DCOMSandbox.java +++ b/core/src/test/java/hudson/os/DCOMSandbox.java @@ -14,14 +14,14 @@ import java.util.Properties; * creating an instance. * *

    - * It turns out that the bogus credential works with ServerAlive. The protocol specification - * + * It turns out that the bogus credential works with ServerAlive. The + * protocol specification * explicitly says this RPC must not check the credential. * *

    * The feature in question of Windows is called "ForceGuest", and it's recorded in the registry at * HKLM\SYSTEM\CurrentControlSet\Control\LSA\forceguest (0=classic, 1=forceguest). - * + * KB 290403 * * @author Kohsuke Kawaguchi */ diff --git a/core/src/test/java/hudson/os/SUTester.java b/core/src/test/java/hudson/os/SUTester.java index c89d447c0ca26af384bffd7bfcb542aaccf88d9e..12d43f9787481433ceb30e658917067e5109be2a 100644 --- a/core/src/test/java/hudson/os/SUTester.java +++ b/core/src/test/java/hudson/os/SUTester.java @@ -1,6 +1,5 @@ package hudson.os; -import hudson.remoting.Callable; import hudson.util.StreamTaskListener; import jenkins.security.MasterToSlaveCallable; diff --git a/core/src/test/java/hudson/scheduler/CronTabTest.java b/core/src/test/java/hudson/scheduler/CronTabTest.java index 6ddf85912853977ecb0d715fe5c1bbf7daa7a790..e2acaf53ba33a0ad8cc4da2c1a42fa4052ec0202 100644 --- a/core/src/test/java/hudson/scheduler/CronTabTest.java +++ b/core/src/test/java/hudson/scheduler/CronTabTest.java @@ -27,7 +27,6 @@ import antlr.ANTLRException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.TimeZone; import java.util.GregorianCalendar; import java.util.Locale; diff --git a/core/src/test/java/hudson/slaves/CloudTest.java b/core/src/test/java/hudson/slaves/CloudTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bed5bad5f74a7aaaee7253003e6af08c08e17ffa --- /dev/null +++ b/core/src/test/java/hudson/slaves/CloudTest.java @@ -0,0 +1,26 @@ +package hudson.slaves; + +import static org.junit.Assert.*; + +import hudson.model.Computer; +import hudson.security.Permission; +import hudson.security.SidACL; +import jenkins.model.Jenkins; +import org.acegisecurity.acls.sid.Sid; +import org.junit.Test; + +public class CloudTest { + + @Test + public void provisionPermissionShouldBeIndependentFromAdminister() throws Exception { + SidACL acl = new SidACL() { + @Override protected Boolean hasPermission(Sid p, Permission permission) { + return permission == Cloud.PROVISION; + } + }; + + assertTrue(acl.hasPermission(Jenkins.ANONYMOUS, Cloud.PROVISION)); + assertFalse(acl.hasPermission(Jenkins.ANONYMOUS, Jenkins.ADMINISTER)); + assertEquals(Cloud.PROVISION, Computer.PERMISSIONS.find("Provision")); + } +} diff --git a/core/src/test/java/hudson/slaves/ComputerLauncherTest.java b/core/src/test/java/hudson/slaves/ComputerLauncherTest.java index d1533420de65ac66348c230e40c6d708e4e44569..56ea7bfa61a9fdb41090ff9ff37e7250cf625b07 100644 --- a/core/src/test/java/hudson/slaves/ComputerLauncherTest.java +++ b/core/src/test/java/hudson/slaves/ComputerLauncherTest.java @@ -24,17 +24,16 @@ package hudson.slaves; -import edu.umd.cs.findbugs.annotations.SuppressWarnings; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.PrintStream; import java.io.StringReader; + import org.apache.commons.io.output.NullOutputStream; import org.junit.Test; import static org.junit.Assert.*; -@SuppressWarnings("DM_DEFAULT_ENCODING") public class ComputerLauncherTest { @Test public void jdk7() throws IOException { diff --git a/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java b/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5d47c1a2af063904de2b1fd059bf313e88f63ae9 --- /dev/null +++ b/core/src/test/java/hudson/slaves/DelegatingComputerLauncherTest.java @@ -0,0 +1,71 @@ +package hudson.slaves; + +import hudson.DescriptorExtensionList; +import hudson.model.Descriptor; +import jenkins.model.Jenkins; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; + +import static org.junit.Assert.*; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.powermock.api.mockito.PowerMockito.mock; +import static org.powermock.api.mockito.PowerMockito.when; + +/** + * @author peppelan + */ +@RunWith(PowerMockRunner.class) +public class DelegatingComputerLauncherTest { + + public static class DummyOne extends DelegatingComputerLauncher { + + public DummyOne() { + super(null); + } + + public static class DummyOneDescriptor extends DescriptorImpl { + } + } + + + public static class DummyTwo extends DelegatingComputerLauncher { + + public DummyTwo() { + super(null); + } + + public static class DummyTwoDescriptor extends DescriptorImpl { + } + } + + // Ensure that by default a DelegatingComputerLauncher subclass doesn't advertise the option to delegate another + // DelegatingComputerLauncher + @Test + @PrepareForTest(Jenkins.class) + public void testRecursionAvoidance() { + PowerMockito.mockStatic(Jenkins.class); + Jenkins mockJenkins = mock(Jenkins.class); + PowerMockito.when(Jenkins.getInstance()).thenReturn(mockJenkins); + + DescriptorExtensionList> mockList = + mock(DescriptorExtensionList.class); + doReturn(mockList).when(mockJenkins).getDescriptorList(eq(ComputerLauncher.class)); + ArrayList> returnedList = new ArrayList<>(); + + returnedList.add(new DummyOne.DummyOneDescriptor()); + returnedList.add(new DummyTwo.DummyTwoDescriptor()); + + when(mockList.iterator()).thenReturn(returnedList.iterator()); + + assertTrue("DelegatingComputerLauncher should filter out other DelegatingComputerLauncher instances " + + "from its descriptor's getApplicableDescriptors() method", + new DummyTwo.DummyTwoDescriptor().applicableDescriptors(null, new DumbSlave.DescriptorImpl()).isEmpty()); + } + +} diff --git a/core/src/test/java/hudson/triggers/SCMTriggerTest.java b/core/src/test/java/hudson/triggers/SCMTriggerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..42e1a121bb6dd4223058ace1ef34f380c0beb830 --- /dev/null +++ b/core/src/test/java/hudson/triggers/SCMTriggerTest.java @@ -0,0 +1,42 @@ +/* + * The MIT License + * + * Copyright (c) 2015 Kanstantsin Shautsou + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.triggers; + +import org.junit.Test; +import org.jvnet.hudson.test.Issue; + +/** + * @author Kanstantsin Shautsou + */ +public class SCMTriggerTest { + @Issue({"JENKINS-29790", "JENKINS-29945"}) + @Test + public void testNoNPE() throws Exception { + final SCMTrigger scmTrigger = new SCMTrigger(""); + + scmTrigger.run(); + scmTrigger.run(null); + scmTrigger.getProjectActions(); + } +} diff --git a/test/src/main/java/org/jvnet/hudson/test/LenientRunnable.java b/core/src/test/java/hudson/triggers/TimerTriggerTest.java similarity index 75% rename from test/src/main/java/org/jvnet/hudson/test/LenientRunnable.java rename to core/src/test/java/hudson/triggers/TimerTriggerTest.java index a4ff4d0930d6e1d89315e1368eb02cd379dbd53a..ef6edf44004a290d86ab3502ff2ffb0b2dc08ceb 100644 --- a/test/src/main/java/org/jvnet/hudson/test/LenientRunnable.java +++ b/core/src/test/java/hudson/triggers/TimerTriggerTest.java @@ -1,18 +1,18 @@ /* * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * + * + * Copyright (c) 2015 Kanstantsin Shautsou + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -21,13 +21,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -package org.jvnet.hudson.test; +package hudson.triggers; + +import antlr.ANTLRException; +import org.junit.Test; +import org.jvnet.hudson.test.Issue; /** - * Like {@link Runnable} but can throw any exception. - * - * @author Kohsuke Kawaguchi + * @author Kanstantsin Shautsou */ -public interface LenientRunnable { - void run() throws Exception; +public class TimerTriggerTest { + @Issue("JENKINS-29790") + @Test + public void testNoNPE() throws ANTLRException { + new TimerTrigger("").run(); + } } diff --git a/core/src/test/java/hudson/util/ArgumentListBuilderTest.java b/core/src/test/java/hudson/util/ArgumentListBuilderTest.java index 8bef4df9fdfcb2a064b8f389ab1a9274dbdd2b9f..e3fb261abc27494b8ce7504d44fe4565becc56b5 100644 --- a/core/src/test/java/hudson/util/ArgumentListBuilderTest.java +++ b/core/src/test/java/hudson/util/ArgumentListBuilderTest.java @@ -31,7 +31,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; + +import org.junit.Ignore; import org.junit.Test; +import org.jvnet.hudson.test.Issue; public class ArgumentListBuilderTest { @@ -41,7 +44,7 @@ public class ArgumentListBuilderTest { builder.add("arg"); builder.add("other", "arguments"); - assertFalse("There shouldnt be any masked arguments", builder.hasMaskedArguments()); + assertFalse("There should not be any masked arguments", builder.hasMaskedArguments()); boolean[] array = builder.toMaskArray(); assertNotNull("The mask array should not be null", array); assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false })); @@ -101,28 +104,51 @@ public class ArgumentListBuilderTest { @Test public void testToWindowsCommand() { - ArgumentListBuilder builder = new ArgumentListBuilder( - "ant.bat", "-Dfoo1=abc", // nothing special, no quotes - "-Dfoo2=foo bar", "-Dfoo3=/u*r", "-Dfoo4=/us?", // add quotes - "-Dfoo10=bar,baz", - "-Dfoo5=foo;bar^baz", "-Dfoo6=&here;", // add quotes - "-Dfoo7=foo|bar\"baz", // add quotes and "" for " - "-Dfoo8=% %QED% %comspec% %-%(%.%", // add quotes, and extra quotes for %Q and %c - "-Dfoo9=%'''%%@%"); // no quotes as none of the % are followed by a letter + ArgumentListBuilder builder = new ArgumentListBuilder(). + add("ant.bat").add("-Dfoo1=abc"). // nothing special, no quotes + add("-Dfoo2=foo bar").add("-Dfoo3=/u*r").add("-Dfoo4=/us?"). // add quotes + add("-Dfoo10=bar,baz"). + add("-Dfoo5=foo;bar^baz").add("-Dfoo6=&here;"). // add quotes + add("-Dfoo7=foo|bar\"baz"). // add quotes and "" for " + add("-Dfoo8=% %QED% %comspec% %-%(%.%"). // add quotes, and extra quotes for %Q and %c + add("-Dfoo9=%'''%%@%"); // no quotes as none of the % are followed by a letter // By default, does not escape %VAR% assertThat(builder.toWindowsCommand().toCommandArray(), is(new String[] { "cmd.exe", "/C", - "\"ant.bat -Dfoo1=abc \"-Dfoo2=foo bar\"" - + " \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\"" - + " \"-Dfoo6=&here;\" \"-Dfoo7=foo|bar\"\"baz\"" - + " \"-Dfoo8=% %QED% %comspec% %-%(%.%\"" - + " -Dfoo9=%'''%%@% && exit %%ERRORLEVEL%%\"" })); + "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"", + "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=&here;\"", + "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %QED% %comspec% %-%(%.%\"", + "-Dfoo9=%'''%%@%", "&&", "exit", "%%ERRORLEVEL%%\"" })); // Pass flag to escape %VAR% assertThat(builder.toWindowsCommand(true).toCommandArray(), is(new String[] { "cmd.exe", "/C", - "\"ant.bat -Dfoo1=abc \"-Dfoo2=foo bar\"" - + " \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\"" - + " \"-Dfoo6=&here;\" \"-Dfoo7=foo|bar\"\"baz\"" - + " \"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"" - + " -Dfoo9=%'''%%@% && exit %%ERRORLEVEL%%\"" })); + "\"ant.bat", "-Dfoo1=abc", "\"-Dfoo2=foo bar\"", "\"-Dfoo3=/u*r\"", "\"-Dfoo4=/us?\"", + "\"-Dfoo10=bar,baz\"", "\"-Dfoo5=foo;bar^baz\"", "\"-Dfoo6=&here;\"", + "\"-Dfoo7=foo|bar\"\"baz\"", "\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"", + "-Dfoo9=%'''%%@%", "&&", "exit", "%%ERRORLEVEL%%\"" })); + // Try to hide password + builder.add("-Dpassword=hidden", true); + // By default, does not escape %VAR% + assertThat(builder.toWindowsCommand().toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=&here;\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %QED% %comspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\"" )); + // Pass flag to escape %VAR% + assertThat(builder.toWindowsCommand(true).toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=&here;\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\"")); + } + + @Test + @Ignore("It's only for reproduce JENKINS-28790 issue. It's added to testToWindowsCommand") + @Issue("JENKINS-28790") + public void testToWindowsCommandMasked() { + ArgumentListBuilder builder = new ArgumentListBuilder(). + add("ant.bat").add("-Dfoo1=abc"). // nothing special, no quotes + add("-Dfoo2=foo bar").add("-Dfoo3=/u*r").add("-Dfoo4=/us?"). // add quotes + add("-Dfoo10=bar,baz"). + add("-Dfoo5=foo;bar^baz").add("-Dfoo6=&here;"). // add quotes + add("-Dfoo7=foo|bar\"baz"). // add quotes and "" for " + add("-Dfoo8=% %QED% %comspec% %-%(%.%"). // add quotes, and extra quotes for %Q and %c + add("-Dfoo9=%'''%%@%"). // no quotes as none of the % are followed by a letter + add("-Dpassword=hidden", true); + // By default, does not escape %VAR% + assertThat(builder.toWindowsCommand().toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=&here;\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %QED% %comspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\"" )); + // Pass flag to escape %VAR% + assertThat(builder.toWindowsCommand(true).toString(), is("cmd.exe /C \"ant.bat -Dfoo1=abc \"\"-Dfoo2=foo bar\"\" \"-Dfoo3=/u*r\" \"-Dfoo4=/us?\" \"-Dfoo10=bar,baz\" \"-Dfoo5=foo;bar^baz\" \"-Dfoo6=&here;\" \"-Dfoo7=foo|bar\"\"baz\" \"\"-Dfoo8=% %\"Q\"ED% %\"c\"omspec% %-%(%.%\"\" -Dfoo9=%'''%%@% ****** && exit %%ERRORLEVEL%%\"")); } @Test @@ -166,7 +192,7 @@ public class ArgumentListBuilderTest { ArgumentListBuilder builder = new ArgumentListBuilder(); builder.addKeyValuePairs(null, KEY_VALUES); - assertFalse("There shouldnt be any masked arguments", builder.hasMaskedArguments()); + assertFalse("There should not be any masked arguments", builder.hasMaskedArguments()); boolean[] array = builder.toMaskArray(); assertNotNull("The mask array should not be null", array); assertThat("The mask array was incorrect", array, is(new boolean[] { false, false, false })); diff --git a/core/src/test/java/hudson/util/IsOverriddenTest.java b/core/src/test/java/hudson/util/IsOverriddenTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8877d6ee416b5d4a5eb330adce92ce6b77e13ae3 --- /dev/null +++ b/core/src/test/java/hudson/util/IsOverriddenTest.java @@ -0,0 +1,80 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util; + +import org.junit.Test; +import static org.junit.Assert.*; + +import hudson.Util; + +/** + * Test for {@link Util.isOverridden} method. + */ +public class IsOverriddenTest { + + /** + * Test that a method is found by isOverridden even when it is inherited from an intermediate class. + */ + @Test + public void isOverriddenTest() { + assertTrue(Util.isOverridden(Base.class, Derived.class, "method")); + assertTrue(Util.isOverridden(Base.class, Intermediate.class, "method")); + assertFalse(Util.isOverridden(Base.class, Base.class, "method")); + assertTrue(Util.isOverridden(Base.class, Intermediate.class, "setX", Object.class)); + assertTrue(Util.isOverridden(Base.class, Intermediate.class, "getX")); + } + + /** + * Negative test. + * Trying to check for a method which does not exist in the hierarchy, + */ + @Test(expected = IllegalArgumentException.class) + public void isOverriddenNegativeTest() { + Util.isOverridden(Base.class, Derived.class, "method2"); + } + + /** + * Do not inspect private methods. + */ + @Test(expected = IllegalArgumentException.class) + public void avoidPrivateMethodsInspection() { + Util.isOverridden(Base.class, Intermediate.class, "aPrivateMethod"); + } + + public abstract class Base { + protected abstract void method(); + private void aPrivateMethod() {} + public void setX(T t) {} + public T getX() { return null; } + } + public abstract class Intermediate extends Base { + protected void method() {} + private void aPrivateMethod() {} + public void setX(Integer i) {} + public Integer getX() { return 0; } + } + public class Derived extends Intermediate {} + +} + diff --git a/core/src/test/java/hudson/util/JSONObjectResponseTest.java b/core/src/test/java/hudson/util/JSONObjectResponseTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f84b574bfb23a3efb4a8d3108b2fa7ea12d1e8eb --- /dev/null +++ b/core/src/test/java/hudson/util/JSONObjectResponseTest.java @@ -0,0 +1,56 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util; + +import net.sf.json.JSONObject; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author tom.fennelly@gmail.com + */ +public class JSONObjectResponseTest { + + @Test + public void test() { + Map data = new HashMap<>(); + + data.put("val_1", "1"); + + HttpResponses.JSONObjectResponse response = new HttpResponses.JSONObjectResponse(data); + JSONObject payload = response.getJsonObject(); + + Assert.assertEquals("ok", payload.getString("status")); + JSONObject payloadData = payload.getJSONObject("data"); + Assert.assertEquals("1", payloadData.getString("val_1")); + + // change it to an error + response.error("a message"); + Assert.assertEquals("error", payload.getString("status")); + Assert.assertEquals("a message", payload.getString("message")); + } +} diff --git a/core/src/test/java/hudson/util/MultipartFormDataParserTest.java b/core/src/test/java/hudson/util/MultipartFormDataParserTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3cf0de27f9ee65cf7b757bdc80637357a7948a87 --- /dev/null +++ b/core/src/test/java/hudson/util/MultipartFormDataParserTest.java @@ -0,0 +1,43 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author tom.fennelly@gmail.com + */ +public class MultipartFormDataParserTest { + + @Test + public void testIsMultipart() throws Exception { + Assert.assertFalse("Wrongly identified \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm(null)); + Assert.assertFalse("Wrongly identified \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("blah")); + + Assert.assertTrue("Failed to identify \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("multipart/form-data")); + Assert.assertTrue("Failed to identify \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("multipart/form-data;")); + Assert.assertTrue("Failed to identify \"multipart/form-data\"", MultipartFormDataParser.isMultiPartForm("multipart/form-data; boundary=----WebKitFormBoundary8OOwv1Xp4c5XkBmD")); + } +} diff --git a/core/src/test/java/hudson/util/ProcessTreeTest.java b/core/src/test/java/hudson/util/ProcessTreeTest.java index f3d5d3e6f2bf882910211d829ff61a727dd2365a..d4c8fed7de008609d7443d0b4f2b0910d1d13a16 100644 --- a/core/src/test/java/hudson/util/ProcessTreeTest.java +++ b/core/src/test/java/hudson/util/ProcessTreeTest.java @@ -8,6 +8,8 @@ import java.io.IOException; import java.io.Serializable; import jenkins.security.MasterToSlaveCallable; import static org.junit.Assert.*; + +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; @@ -26,9 +28,7 @@ public class ProcessTreeTest { } @Test public void remoting() throws Exception { - // on some platforms where we fail to list any processes, this test will just not work - if (ProcessTree.get()==ProcessTree.DEFAULT) - return; + Assume.assumeFalse("on some platforms where we fail to list any processes", ProcessTree.get()==ProcessTree.DEFAULT); Tag t = channels.french.call(new MyCallable()); diff --git a/core/src/test/java/hudson/util/XStream2Test.java b/core/src/test/java/hudson/util/XStream2Test.java index ed29c8c8f21feddc07f316df8dfa8138fc5820f3..aeb781f6725f722f966c81734c5921ec09de583f 100644 --- a/core/src/test/java/hudson/util/XStream2Test.java +++ b/core/src/test/java/hudson/util/XStream2Test.java @@ -272,37 +272,6 @@ public class XStream2Test { ConcurrentHashMap m = new ConcurrentHashMap(); } - /** - * Tests that ConcurrentHashMap is serialized into a more compact format, - * but still can deserialize to older, verbose format. - */ - @Test - public void concurrentHashMapSerialization() throws Exception { - Foo2 foo = new Foo2(); - foo.m.put("abc","def"); - foo.m.put("ghi","jkl"); - File v = File.createTempFile("hashmap", "xml"); - try { - new XmlFile(v).write(foo); - - // should serialize like map - String xml = FileUtils.readFileToString(v); - assertFalse(xml.contains("java.util.concurrent")); - //System.out.println(xml); - Foo2 deserialized = (Foo2) new XStream2().fromXML(xml); - assertEquals(2,deserialized.m.size()); - assertEquals("def", deserialized.m.get("abc")); - assertEquals("jkl", deserialized.m.get("ghi")); - } finally { - v.delete(); - } - - // should be able to read in old data just fine - Foo2 map = (Foo2) new XStream2().fromXML(getClass().getResourceAsStream("old-concurrentHashMap.xml")); - assertEquals(1,map.m.size()); - assertEquals("def",map.m.get("abc")); - } - @Issue("SECURITY-105") @Test public void dynamicProxyBlocked() { diff --git a/core/src/test/java/hudson/util/io/TarArchiverTest.java b/core/src/test/java/hudson/util/io/TarArchiverTest.java index e063e784a02fd89ffcd324d5bfbc3e750d73720e..c85935de33ba59f0793bfdb827d504270f79bf1a 100644 --- a/core/src/test/java/hudson/util/io/TarArchiverTest.java +++ b/core/src/test/java/hudson/util/io/TarArchiverTest.java @@ -32,7 +32,10 @@ import hudson.util.NullStream; import hudson.util.StreamTaskListener; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Arrays; import static org.junit.Assert.*; +import org.junit.Assume; import static org.junit.Assume.*; import org.junit.Rule; import org.junit.Test; @@ -76,7 +79,7 @@ public class TarArchiverTest { e.mkdirs(); // extract via the tar command - assertEquals(0, new LocalLauncher(new StreamTaskListener(System.out)).launch().cmds("tar", "xvpf", tar.getAbsolutePath()).pwd(e).join()); + run(e, "tar", "xvpf", tar.getAbsolutePath()); assertEquals(0100755,e.child("a.txt").mode()); assertEquals(dirMode,e.child("subdir").mode()); @@ -85,7 +88,7 @@ public class TarArchiverTest { // extract via the zip command e.deleteContents(); - assertEquals(0, new LocalLauncher(new StreamTaskListener(System.out)).launch().cmds("unzip", zip.getAbsolutePath()).pwd(e).join()); + run(e, "unzip", zip.getAbsolutePath()); e = e.listDirectories().get(0); assertEquals(0100755, e.child("a.txt").mode()); @@ -98,6 +101,14 @@ public class TarArchiverTest { } } + private static void run(FilePath dir, String... cmds) throws InterruptedException { + try { + assertEquals(0, new LocalLauncher(StreamTaskListener.fromStdout()).launch().cmds(cmds).pwd(dir).join()); + } catch (IOException x) { // perhaps restrict to x.message.contains("Cannot run program")? or "error=2, No such file or directory"? + Assume.assumeNoException("failed to run " + Arrays.toString(cmds), x); + } + } + @Issue("JENKINS-14922") @Test public void brokenSymlinks() throws Exception { assumeTrue(!Functions.isWindows()); @@ -105,5 +116,56 @@ public class TarArchiverTest { Util.createSymlink(dir, "nonexistent", "link", TaskListener.NULL); new FilePath(dir).tar(new NullStream(), "**"); } + + + /** + * Test backing up an open file + */ + + @Issue("JENKINS-20187") + @Test public void growingFileTar() throws Exception { + File file=new File(tmp.getRoot(),"growing.file"); + GrowingFileRunnable runnable1 = new GrowingFileRunnable(file); + Thread t1 = new Thread(runnable1); + t1.start(); + + new FilePath(tmp.getRoot()).tar(new NullStream(), "**"); + + runnable1.doFinish(); + t1.join(); + } + + private class GrowingFileRunnable implements Runnable { + private boolean finish = false; + private Exception ex = null; + private File file; + + public GrowingFileRunnable(File file) { + this.file = file; + } + + @Override + public void run() { + File openFile = file; + try { + openFile.createNewFile(); + FileOutputStream fos = new FileOutputStream(openFile); + for (int i = 0; !finish && i < 5000000; i++) { // limit the max size, just in case. + fos.write(0); + // Thread.sleep(5); + } + fos.close(); + } catch (Exception e) { + ex = e; + } + } + + public void doFinish() throws Exception { + finish = true; + if (ex != null) { + throw ex; + } + } + }; } diff --git a/core/src/test/java/jenkins/model/JDKNameTest.java b/core/src/test/java/jenkins/model/JDKNameTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e2474910550402989fc7307357cd401ceec196b3 --- /dev/null +++ b/core/src/test/java/jenkins/model/JDKNameTest.java @@ -0,0 +1,57 @@ +/* + * The MIT License + * + * Copyright (c) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.model; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import hudson.model.JDK; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; + +@RunWith(PowerMockRunner.class) +public class JDKNameTest { + @Test + public void nullIsDefaultName() { + assertThat(JDK.isDefaultName(null), is(true)); + } + + @Test + public void recognizeOldDefaultName() { + // DEFAULT_NAME took this value prior to 1.598. + assertThat(JDK.isDefaultName("(Default)"), is(true)); + } + + @Test + public void recognizeDefaultName() { + assertThat(JDK.isDefaultName(JDK.DEFAULT_NAME), is(true)); + } + + @Test + public void othernameNotDefault() { + assertThat(JDK.isDefaultName("I'm a customized name"), is(false)); + } + +} diff --git a/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java b/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java index bc9c3ffecc9816402da4a1e5e801b733abffc24e..8d5dd3b08d3c9130c7c51d4aacacc76a6a90e168 100644 --- a/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java +++ b/core/src/test/java/jenkins/model/JenkinsLocationConfigurationTest.java @@ -23,17 +23,14 @@ */ package jenkins.model; -import java.io.IOException; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.jvnet.hudson.test.Issue; -import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import static org.powermock.api.mockito.PowerMockito.mock; -import static org.powermock.api.mockito.PowerMockito.when; /** * Tests for {@link JenkinsLocationConfiguration}. diff --git a/core/src/test/java/jenkins/model/RunIdMigratorTest.java b/core/src/test/java/jenkins/model/RunIdMigratorTest.java index fb9805db779d2ea24e2f7e53b1040cf222875e35..f51d0299b8c0db66c4a9511680368aad439c77de 100644 --- a/core/src/test/java/jenkins/model/RunIdMigratorTest.java +++ b/core/src/test/java/jenkins/model/RunIdMigratorTest.java @@ -52,6 +52,7 @@ public class RunIdMigratorTest { TimeZone.setDefault(TimeZone.getTimeZone("EST")); } + // TODO could use LoggerRule only if it were extracted to an independent library @BeforeClass public static void logging() { RunIdMigrator.LOGGER.setLevel(Level.ALL); Handler handler = new ConsoleHandler(); @@ -128,6 +129,26 @@ public class RunIdMigratorTest { assertEquals("{1=→2014-01-02_03-04-05, 2014-01-02_03-04-05={build.xml='\n\n ok\n 1\n ok\n'}}", summarize()); } + @Test public void reverseMatrixAfterNewBuilds() throws Exception { + File root = dir; + dir = new File(dir, "jobs/someproject/Environment=prod/builds"); + write("1/build.xml", "\n\n ok\n 1388649845000\n ok\n"); + write("legacyIds", ""); + assertEquals("{1={build.xml='\n\n ok\n 1388649845000\n ok\n'}, legacyIds=''}", summarize()); + RunIdMigrator.main(root.getAbsolutePath()); + assertEquals("{1=→2014-01-02_03-04-05, 2014-01-02_03-04-05={build.xml='\n\n ok\n 1\n ok\n'}}", summarize()); + } + + @Test public void reverseMavenAfterNewBuilds() throws Exception { + File root = dir; + dir = new File(dir, "jobs/someproject/test$test/builds"); + write("1/build.xml", "\n\n ok\n 1388649845000\n ok\n"); + write("legacyIds", ""); + assertEquals("{1={build.xml='\n\n ok\n 1388649845000\n ok\n'}, legacyIds=''}", summarize()); + RunIdMigrator.main(root.getAbsolutePath()); + assertEquals("{1=→2014-01-02_03-04-05, 2014-01-02_03-04-05={build.xml='\n\n ok\n 1\n ok\n'}}", summarize()); + } + // TODO test sane recovery from various error conditions private void write(String file, String text) throws Exception { diff --git a/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java b/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java index 88ca41c5d18ae619ce5f4731f8bc93a3cf07339a..4167f668a734b142356bd2288fff3fb1561c5ebd 100644 --- a/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java +++ b/core/src/test/java/jenkins/model/lazy/AbstractLazyLoadRunMapTest.java @@ -23,6 +23,7 @@ */ package jenkins.model.lazy; +import java.io.File; import static org.junit.Assert.*; import jenkins.model.lazy.AbstractLazyLoadRunMap.Direction; @@ -31,13 +32,19 @@ import org.junit.Rule; import org.junit.Test; import java.io.IOException; +import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; import java.util.Set; import java.util.SortedMap; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; +import jenkins.util.Timer; import org.junit.BeforeClass; import org.jvnet.hudson.test.Issue; @@ -72,6 +79,29 @@ public class AbstractLazyLoadRunMapTest { } }; + private final Map slowBuilderStartSemaphores = new HashMap<>(); + private final Map slowBuilderEndSemaphores = new HashMap<>(); + private final Map slowBuilderLoadCount = new HashMap<>(); + @Rule + public FakeMapBuilder slowBuilder = new FakeMapBuilder() { + @Override + public FakeMap make() { + return new FakeMap(getDir()) { + @Override + protected Build retrieve(File dir) throws IOException { + Build b = super.retrieve(dir); + slowBuilderStartSemaphores.get(b.n).release(); + try { + slowBuilderEndSemaphores.get(b.n).acquire(); + } catch (InterruptedException x) { + throw new IOException(x); + } + slowBuilderLoadCount.get(b.n).incrementAndGet(); + return b; + } + }; + } + }; @BeforeClass public static void setUpClass() { @@ -358,4 +388,36 @@ public class AbstractLazyLoadRunMapTest { assertTrue(a.entrySet().contains(e)); } } + + @Issue("JENKINS-22767") + @Test + public void slowRetrieve() throws Exception { + for (int i = 1; i <= 3; i++) { + slowBuilder.add(i); + slowBuilderStartSemaphores.put(i, new Semaphore(0)); + slowBuilderEndSemaphores.put(i, new Semaphore(0)); + slowBuilderLoadCount.put(i, new AtomicInteger()); + } + final FakeMap m = slowBuilder.make(); + Future firstLoad = Timer.get().submit(new Callable() { + @Override + public Build call() throws Exception { + return m.getByNumber(2); + } + }); + Future secondLoad = Timer.get().submit(new Callable() { + @Override + public Build call() throws Exception { + return m.getByNumber(2); + } + }); + slowBuilderStartSemaphores.get(2).acquire(1); + // now one of them is inside retrieve(…); the other is waiting for the lock + slowBuilderEndSemaphores.get(2).release(2); // allow both to proceed + Build first = firstLoad.get(); + Build second = secondLoad.get(); + assertEquals(1, slowBuilderLoadCount.get(2).get()); + assertSame(second, first); + } + } diff --git a/core/src/test/java/jenkins/model/lazy/SortedIntListTest.java b/core/src/test/java/jenkins/model/lazy/SortedIntListTest.java index 2146852a5f90d9d0395d4cdac1cf59d089362a4f..9748aeaa188118e31edb434fb168ccbbb970a10b 100644 --- a/core/src/test/java/jenkins/model/lazy/SortedIntListTest.java +++ b/core/src/test/java/jenkins/model/lazy/SortedIntListTest.java @@ -34,4 +34,15 @@ public class SortedIntListTest { assertFalse(l.isInRange(3)); } + @Test public void max() { + SortedIntList l = new SortedIntList(5); + assertEquals(0, l.max()); + l.add(1); + assertEquals(1, l.max()); + l.add(5); + assertEquals(5, l.max()); + l.add(10); + assertEquals(10, l.max()); + } + } diff --git a/core/src/test/java/jenkins/slaves/DefaultJnlpSlaveReceiverTest.java b/core/src/test/java/jenkins/slaves/DefaultJnlpSlaveReceiverTest.java deleted file mode 100644 index 9cc6425d34b11b1017b8291896b5df2705d6b273..0000000000000000000000000000000000000000 --- a/core/src/test/java/jenkins/slaves/DefaultJnlpSlaveReceiverTest.java +++ /dev/null @@ -1,142 +0,0 @@ -package jenkins.slaves; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; -import static org.powermock.api.mockito.PowerMockito.mockStatic; - -import hudson.TcpSlaveAgentListener.ConnectionFromCurrentPeer; -import hudson.remoting.Channel; -import hudson.slaves.SlaveComputer; -import jenkins.model.Jenkins; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -@RunWith(PowerMockRunner.class) -@PrepareForTest(Jenkins.class) -public class DefaultJnlpSlaveReceiverTest { - - @Mock private Jenkins mockJenkins; - @Mock private SlaveComputer mockComputer; - @Mock private Channel mockChannel; - @Mock private JnlpSlaveAgentProtocol2.Handler mockHandshake; - @Mock private Future mockFuture; - - private DefaultJnlpSlaveReceiver receiver; - - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mockStatic(Jenkins.class); - when(Jenkins.getInstance()).thenReturn(mockJenkins); - - receiver = new DefaultJnlpSlaveReceiver(); - } - - @Test - public void testHandle() throws Exception { - when(mockJenkins.getComputer("node")).thenReturn(mockComputer); - when(mockComputer.getChannel()).thenReturn(null); - when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie"); - when(mockHandshake.jnlpConnect(mockComputer)).thenReturn(mockChannel); - - assertTrue(receiver.handle("node", mockHandshake)); - verify(mockHandshake).success(any(Properties.class)); - verify(mockChannel).setProperty(any(String.class), any(String.class)); - } - - @Test - public void testHandleWithInvalidNode() throws Exception { - when(mockJenkins.getComputer("bogus-node")).thenReturn(null); - - assertFalse(receiver.handle("bogus-node", mockHandshake)); - } - - @Test - public void testHandleTakeover() throws Exception { - when(mockJenkins.getComputer("node")).thenReturn(mockComputer); - when(mockComputer.getChannel()).thenReturn(mockChannel); - when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("some cookie"); - when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie"); - when(mockComputer.disconnect(any(ConnectionFromCurrentPeer.class))).thenReturn(mockFuture); - when(mockHandshake.jnlpConnect(mockComputer)).thenReturn(mockChannel); - - assertTrue(receiver.handle("node", mockHandshake)); - verify(mockFuture).get(15, TimeUnit.SECONDS); - verify(mockHandshake).success(any(Properties.class)); - verify(mockChannel).setProperty(any(String.class), any(String.class)); - } - - @Test - public void testHandleTakeoverFailedDisconnect() throws Exception { - when(mockJenkins.getComputer("node")).thenReturn(mockComputer); - when(mockComputer.getChannel()).thenReturn(mockChannel); - when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("some cookie"); - when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie"); - when(mockComputer.disconnect(any(ConnectionFromCurrentPeer.class))).thenReturn(mockFuture); - when(mockFuture.get(15, TimeUnit.SECONDS)).thenThrow(new ExecutionException(null)); - - try { - receiver.handle("node", mockHandshake); - fail(); - } catch (IOException e) { - // good - } - } - - @Test - public void testHandleTakeoverTimedOut() throws Exception { - when(mockJenkins.getComputer("node")).thenReturn(mockComputer); - when(mockComputer.getChannel()).thenReturn(mockChannel); - when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("some cookie"); - when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie"); - when(mockComputer.disconnect(any(ConnectionFromCurrentPeer.class))).thenReturn(mockFuture); - when(mockFuture.get(15, TimeUnit.SECONDS)).thenThrow(new TimeoutException()); - - try { - receiver.handle("node", mockHandshake); - fail(); - } catch (IOException e) { - // good - } - } - - @Test - public void testHandleAttemptTakeoverWithNullCookie() throws Exception { - when(mockJenkins.getComputer("node")).thenReturn(mockComputer); - when(mockComputer.getChannel()).thenReturn(mockChannel); - when(mockHandshake.getRequestProperty(any(String.class))).thenReturn(null); - when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie"); - - assertTrue(receiver.handle("node", mockHandshake)); - verify(mockHandshake).error(any(String.class)); - } - - @Test - public void testHandleAttemptTakeoverWithInvalidCookie() throws Exception { - when(mockJenkins.getComputer("node")).thenReturn(mockComputer); - when(mockComputer.getChannel()).thenReturn(mockChannel); - when(mockHandshake.getRequestProperty(any(String.class))).thenReturn("bogus cookie"); - when(mockChannel.getProperty(any(String.class))).thenReturn("some cookie"); - - assertTrue(receiver.handle("node", mockHandshake)); - verify(mockHandshake).error(any(String.class)); - } -} diff --git a/core/src/test/java/jenkins/triggers/SCMTriggerItemTest.java b/core/src/test/java/jenkins/triggers/SCMTriggerItemTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e45c5263ffc6007f32f8b30b7bc8bec7a8dcec39 --- /dev/null +++ b/core/src/test/java/jenkins/triggers/SCMTriggerItemTest.java @@ -0,0 +1,40 @@ +package jenkins.triggers; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.verify; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.jvnet.hudson.test.Issue; +import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import hudson.model.Item; +import hudson.model.SCMedItem; +import hudson.model.TaskListener; +import jenkins.scm.SCMDecisionHandler; + +@SuppressWarnings("deprecation") +@RunWith(PowerMockRunner.class) +public class SCMTriggerItemTest { + + @Test + @Issue("JENKINS-36232") + @PrepareForTest(SCMDecisionHandler.class) + public void noVetoDelegatesPollingToAnSCMedItem() { + // given + PowerMockito.mockStatic(SCMDecisionHandler.class); + PowerMockito.when(SCMDecisionHandler.firstShouldPollVeto(any(Item.class))).thenReturn(null); + SCMedItem scMedItem = Mockito.mock(SCMedItem.class); + TaskListener listener = Mockito.mock(TaskListener.class); + + // when + SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(scMedItem).poll(listener); + + // then + verify(scMedItem).poll(listener); + } + +} diff --git a/core/src/test/java/jenkins/util/JenkinsJVMTest.java b/core/src/test/java/jenkins/util/JenkinsJVMTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8921deb661e8ddb4c25625bcd6d01894b24a8736 --- /dev/null +++ b/core/src/test/java/jenkins/util/JenkinsJVMTest.java @@ -0,0 +1,36 @@ +package jenkins.util; + +import org.junit.Test; + +public class JenkinsJVMTest { + + @Test + public void checkNotJenkinsJVM_WhenNotInAJenkinsJVM() { + JenkinsJVM.checkNotJenkinsJVM(); + } + + @Test(expected = IllegalStateException.class) + public void checkJenkinsJVM_WhenNotInAJenkinsJVM() { + JenkinsJVM.checkJenkinsJVM(); + } + + @Test(expected = IllegalStateException.class) + public void checkNotJenkinsJVM_WhenInAJenkinsJVM() { + JenkinsJVM.setJenkinsJVM(true); + try { + JenkinsJVM.checkNotJenkinsJVM(); + } finally { + JenkinsJVM.setJenkinsJVM(false); + } + } + + @Test + public void checkJenkinsJVM_WhenInAJenkinsJVM() { + JenkinsJVM.setJenkinsJVM(true); + try { + JenkinsJVM.checkJenkinsJVM(); + } finally { + JenkinsJVM.setJenkinsJVM(false); + } + } +} diff --git a/core/src/test/java/jenkins/util/ResourceBundleUtilTest.java b/core/src/test/java/jenkins/util/ResourceBundleUtilTest.java new file mode 100644 index 0000000000000000000000000000000000000000..1e8c24b56946e51ad0d80afdf1a9b442e2642c17 --- /dev/null +++ b/core/src/test/java/jenkins/util/ResourceBundleUtilTest.java @@ -0,0 +1,69 @@ +/* + * The MIT License + * + * Copyright (c) 2015, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.util; + +import net.sf.json.JSONObject; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Locale; +import java.util.MissingResourceException; + +/** + * @author tom.fennelly@gmail.com + */ +public class ResourceBundleUtilTest { + + /** + * Test resource bundle loading for a defined locale. + */ + @Test + public void test_known_locale() { + JSONObject bundle = ResourceBundleUtil.getBundle("hudson.logging.Messages", Locale.GERMAN); + Assert.assertEquals("Initialisiere Log-Rekorder", bundle.getString("LogRecorderManager.init")); + bundle = ResourceBundleUtil.getBundle("hudson.logging.Messages", new Locale("pt")); + Assert.assertEquals("Inicializando registros de log", bundle.getString("LogRecorderManager.init")); + + // Test caching - should get the same bundle instance back... + Assert.assertTrue(ResourceBundleUtil.getBundle("hudson.logging.Messages", new Locale("pt")) == bundle); + } + + /** + * Test that we get the "default" bundle for an unknown locale. + */ + @Test + public void test_unknown_locale() { + JSONObject bundle = ResourceBundleUtil.getBundle("hudson.logging.Messages", new Locale("kok")); // konkani + Assert.assertEquals("Initialing log recorders", bundle.getString("LogRecorderManager.init")); + + } + + /** + * Test unknown bundle. + */ + @Test(expected = MissingResourceException.class) + public void test_unknown_bundle() { + ResourceBundleUtil.getBundle("hudson.blah.Whatever"); + } +} diff --git a/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java b/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java index 979a86cb2bafcf665dfc51c732365853a2290c8b..b32ed5a40f15fe005305f64de201a43c2b7d9900 100644 --- a/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java +++ b/core/src/test/java/jenkins/util/xstream/XStreamDOMTest.java @@ -83,12 +83,9 @@ public class XStreamDOMTest { @Test public void testUnmarshal() throws Exception { - InputStream is = XStreamDOMTest.class.getResourceAsStream("XStreamDOMTest.data1.xml"); Foo foo; - try { + try (InputStream is = XStreamDOMTest.class.getResourceAsStream("XStreamDOMTest.data1.xml")) { foo = (Foo) xs.fromXML(is); - } finally { - is.close(); } assertEquals("test1",foo.bar.getTagName()); assertEquals("value",foo.bar.getAttribute("key")); diff --git a/core/src/test/java/jenkins/widgets/HistoryPageFilterTest.java b/core/src/test/java/jenkins/widgets/HistoryPageFilterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f00969b769df4ae8b3629985529a7962d4a766b5 --- /dev/null +++ b/core/src/test/java/jenkins/widgets/HistoryPageFilterTest.java @@ -0,0 +1,376 @@ +/* + * The MIT License + * + * Copyright (c) 2013-2014, CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package jenkins.widgets; + +import hudson.model.Job; +import hudson.model.MockItem; +import hudson.model.ModelObject; +import hudson.model.Queue; +import hudson.model.Result; +import hudson.model.Run; +import jenkins.widgets.HistoryPageEntry; +import jenkins.widgets.HistoryPageFilter; +import org.junit.Assert; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * @author tom.fennelly@gmail.com + */ +public class HistoryPageFilterTest { + + /** + * No items. + */ + @Test + public void test_latest_empty_page() { + HistoryPageFilter historyPageFilter = newPage(5, null, null); + List itemList = new ArrayList<>(); + + historyPageFilter.add(itemList); + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(false, historyPageFilter.hasDownPage); + Assert.assertEquals(true, historyPageFilter.queueItems.isEmpty()); + Assert.assertEquals(true, historyPageFilter.runs.isEmpty()); + } + + /** + * Latest/top page where total number of items less than the max page size. + */ + @Test + public void test_latest_partial_page() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, null); + List runs = newRuns(1, 2); + List queueItems = newQueueItems(3, 4); + + historyPageFilter.add(runs, queueItems); + + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(false, historyPageFilter.hasDownPage); + Assert.assertEquals(2, historyPageFilter.queueItems.size()); + Assert.assertEquals(2, historyPageFilter.runs.size()); + + Assert.assertEquals(4, historyPageFilter.queueItems.get(0).getEntryId()); + Assert.assertEquals(4, historyPageFilter.newestOnPage); + Assert.assertEquals(3, historyPageFilter.queueItems.get(1).getEntryId()); + Assert.assertEquals(HistoryPageEntry.getEntryId(2), historyPageFilter.runs.get(0).getEntryId()); + Assert.assertEquals(HistoryPageEntry.getEntryId(1), historyPageFilter.runs.get(1).getEntryId()); + Assert.assertEquals(HistoryPageEntry.getEntryId(1), historyPageFilter.oldestOnPage); + } + + /** + * Latest/top page where total number of items greater than the max page size. + */ + @Test + public void test_latest_longer_list() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, null); + List runs = newRuns(1, 10); + List queueItems = newQueueItems(11, 12); + + historyPageFilter.add(runs, queueItems); + + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(2, historyPageFilter.queueItems.size()); + Assert.assertEquals(3, historyPageFilter.runs.size()); + + Assert.assertEquals(12, historyPageFilter.queueItems.get(0).getEntryId()); + Assert.assertEquals(12, historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(10), historyPageFilter.runs.get(0).getEntryId()); + } + + /** + * Test olderThan (page down) when set to id greater than newest (should never happen). Should be same as not + * specifying newerThan/olderThan. + */ + @Test + public void test_olderThan_gt_newest() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, 11L); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(10), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(6), historyPageFilter.oldestOnPage); + } + + /** + * Test olderThan (page down) when set to id less than the oldest (should never happen). Should just give an + * empty list of builds. + */ + @Test + public void test_olderThan_lt_oldest() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, 0L); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(true, historyPageFilter.hasUpPage); + Assert.assertEquals(false, historyPageFilter.hasDownPage); + Assert.assertEquals(0, historyPageFilter.runs.size()); + } + + /** + * Test olderThan (page down) when set to an id close to the oldest in the list (where + * there's less than a full page older than the supplied olderThan arg). + */ + @Test + public void test_olderThan_leaving_part_page() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, 4L); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(true, historyPageFilter.hasUpPage); + Assert.assertEquals(false, historyPageFilter.hasDownPage); + + // Should only be 3 runs on the page (oldest 3) + Assert.assertEquals(3, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(3), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(1), historyPageFilter.oldestOnPage); + } + + /** + * Test olderThan (page down) when set to an id in the middle. Should be a page up and a page down. + */ + @Test + public void test_olderThan_mid_page() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, 8L); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(true, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(7), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(3), historyPageFilter.oldestOnPage); + } + + /** + * Test newerThan (page up) when set to id greater than newest (should never happen). Should be an empty list. + */ + @Test + public void test_newerThan_gt_newest() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, 11L, null); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(0, historyPageFilter.runs.size()); + } + + /** + * Test newerThan (page up) when set to id less than the oldest (should never happen). Should give the oldest + * set of builds. + */ + @Test + public void test_newerThan_lt_oldest() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, 0L, null); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(true, historyPageFilter.hasUpPage); + Assert.assertEquals(false, historyPageFilter.hasDownPage); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(5), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(1), historyPageFilter.oldestOnPage); + } + + /** + * Test newerThan (page up) mid range nearer the oldest build in the list. + */ + @Test + public void test_newerThan_near_oldest() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, 3L, null); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(true, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(8), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(4), historyPageFilter.oldestOnPage); + } + + /** + * Test newerThan (page up) mid range nearer the newest build in the list. This works a little different + * in that it will put the 2 builds newer than newerThan on the page and then fill the remaining slots on the + * page with builds equal to and older i.e. it return the newest/latest builds. + */ + @Test + public void test_newerThan_near_newest() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, 8L, null); + List itemList = newRuns(1, 10); + + historyPageFilter.add(itemList); + + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(10), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(6), historyPageFilter.oldestOnPage); + } + + /** + * Test newerThan (page up) mid range when there are queued builds that are new enough to + * not show up. + */ + @Test + public void test_newerThan_doesntIncludeQueuedItems() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, 5L, null); + List runs = newRuns(1, 10); + List queueItems = newQueueItems(11, 12); + + historyPageFilter.add(runs, queueItems); + + Assert.assertEquals(true, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(0, historyPageFilter.queueItems.size()); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(10), historyPageFilter.runs.get(0).getEntryId()); + Assert.assertEquals(HistoryPageEntry.getEntryId(10), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(6), historyPageFilter.oldestOnPage); + } + + /** + * Test that later items in the list that are not needed for display are not evaluated at all (for performance). + */ + @Test + public void test_laterItemsNotEvaluated() throws IOException { + HistoryPageFilter historyPageFilter = newPage(5, null, null); + List itemList = newRuns(6, 10); + for (int queueId = 5; queueId >= 1; queueId--) { + itemList.add(new ExplodingMockRun(queueId)); + } + + historyPageFilter.add(itemList); + + Assert.assertEquals(false, historyPageFilter.hasUpPage); + Assert.assertEquals(true, historyPageFilter.hasDownPage); + Assert.assertEquals(5, historyPageFilter.runs.size()); + + Assert.assertEquals(HistoryPageEntry.getEntryId(10), historyPageFilter.newestOnPage); + Assert.assertEquals(HistoryPageEntry.getEntryId(6), historyPageFilter.oldestOnPage); + } + + private List newQueueItems(long startId, long endId) { + List items = new ArrayList<>(); + for (long queueId = startId; queueId <= endId; queueId++) { + items.add(new MockItem(queueId)); + } + return items; + } + + private List newRuns(long startId, long endId) throws IOException { + // Runs should be in reverse order, newest first. + List runs = new ArrayList<>(); + for (long queueId = endId; queueId >= startId; queueId--) { + runs.add(new MockRun(queueId)); + } + return runs; + } + + private HistoryPageFilter newPage(int maxEntries, Long newerThan, Long olderThan) { + HistoryPageFilter pageFilter = new HistoryPageFilter<>(maxEntries); + if (newerThan != null) { + pageFilter.setNewerThan(HistoryPageEntry.getEntryId(newerThan)); + } else if (olderThan != null) { + pageFilter.setOlderThan(HistoryPageEntry.getEntryId(olderThan)); + } + return pageFilter; + } + + @SuppressWarnings("unchecked") + private static class MockRun extends Run { + private final long queueId; + + public MockRun(long queueId) throws IOException { + super(Mockito.mock(Job.class)); + this.queueId = queueId; + } + + @Override + public int compareTo(Run o) { + return 0; + } + + @Override + public Result getResult() { + return result; + } + + @Override + public boolean isBuilding() { + return false; + } + + @Override + public long getQueueId() { + return queueId; + } + + @Override + public int getNumber() { + return (int) queueId; + } + } + + // A version of MockRun that will throw an exception if getQueueId or getNumber is called + private static class ExplodingMockRun extends MockRun { + public ExplodingMockRun(long queueId) throws IOException { + super(queueId); + } + + @Override + public long getQueueId() { + Assert.fail("Should not get called"); + return super.getQueueId(); + } + + @Override + public int getNumber() { + Assert.fail("Should not get called"); + return super.getNumber(); + } + } +} diff --git a/core/src/test/java/jenkins/xml/XMLUtilsTest.java b/core/src/test/java/jenkins/xml/XMLUtilsTest.java index b71700ba0d12d56a72426e5c6c5a918756d7c5bd..55b0d806bbb94c7d1b368628ec182c95488f25ab 100644 --- a/core/src/test/java/jenkins/xml/XMLUtilsTest.java +++ b/core/src/test/java/jenkins/xml/XMLUtilsTest.java @@ -26,17 +26,23 @@ package jenkins.xml; import jenkins.util.xml.XMLUtils; +import org.junit.Assert; import org.junit.Test; +import java.io.File; +import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; +import java.net.URL; import javax.xml.transform.TransformerException; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import javax.xml.xpath.XPathExpressionException; import static org.hamcrest.core.StringContains.containsString; import static org.junit.Assert.assertThat; import org.jvnet.hudson.test.Issue; +import org.xml.sax.SAXException; public class XMLUtilsTest { @@ -97,4 +103,33 @@ public class XMLUtilsTest { assertThat(stringWriter.toString(), containsString("&")); } + /** + * Tests getValue() directly. Tests the parse methods too (indirectly - yeah, a purest would have + * tests for each). + */ + @Test + public void testGetValue() throws XPathExpressionException, SAXException, IOException { + URL configUrl = getClass().getResource("/jenkins/xml/config.xml"); + File configFile = new File(configUrl.getFile()); + + Assert.assertEquals("1.480.1", XMLUtils.getValue("/hudson/version", configFile)); + Assert.assertEquals("", XMLUtils.getValue("/hudson/unknown-element", configFile)); + } + + @Test + public void testParse_with_XXE() throws IOException, XPathExpressionException { + try { + final String xml = "\n" + + "\n" + + " ]> " + + "&xxe;"; + + StringReader stringReader = new StringReader(xml); + XMLUtils.parse(stringReader); + Assert.fail("Expecting SAXException for XXE."); + } catch (SAXException e) { + assertThat(e.getMessage(), containsString("\"http://apache.org/xml/features/disallow-doctype-decl\"")); + } + } } diff --git a/core/src/test/resources/hudson/util/old-concurrentHashMap.xml b/core/src/test/resources/hudson/util/old-concurrentHashMap.xml deleted file mode 100644 index 14b7ef152cb5bfced0c241ac3f27a877cb567784..0000000000000000000000000000000000000000 --- a/core/src/test/resources/hudson/util/old-concurrentHashMap.xml +++ /dev/null @@ -1,225 +0,0 @@ - - - - - - 15 - 28 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - - - 0 - - - - - - - 0.75 - - - - abc - def - - - - - \ No newline at end of file diff --git a/core/src/test/resources/jenkins/xml/config.xml b/core/src/test/resources/jenkins/xml/config.xml new file mode 100644 index 0000000000000000000000000000000000000000..c3a76a6eef3b9b7d7952c57499ee5ebd5e900f47 --- /dev/null +++ b/core/src/test/resources/jenkins/xml/config.xml @@ -0,0 +1,8 @@ + + + + 1.480.1 + 2 + NORMAL + + \ No newline at end of file diff --git a/licenseCompleter.groovy b/licenseCompleter.groovy index 3db5130ae3c1a38a35506bc8216fed65a931108c..93b33219ca3c9cc86b14b610483262194549edb4 100644 --- a/licenseCompleter.groovy +++ b/licenseCompleter.groovy @@ -9,6 +9,7 @@ complete { def mitLicense = license("MIT License","http://www.opensource.org/licenses/mit-license.php") def bsdLicense = license("BSD License","http://opensource.org/licenses/BSD-2-Clause") def jenkinsLicense = license("MIT License","http://jenkins-ci.org/mit-license") + def ccby = license("Creative Commons Attribution License","http://creativecommons.org/licenses/by/2.5") match("asm:*") { @@ -85,6 +86,9 @@ complete { rewriteLicense([license("CDDL or GPL 2 with Classpath Exception",null)],cddl); } + match("net.jcip:jcip-annotations") { + rewriteLicense([],ccby) + } // // Choose from multi-licensed modules diff --git a/plugins/pom.xml b/plugins/pom.xml deleted file mode 100644 index 877cd8c61700a028b7e97020cea1dd5179427cce..0000000000000000000000000000000000000000 --- a/plugins/pom.xml +++ /dev/null @@ -1,359 +0,0 @@ - - - 4.0.0 - - - org.jenkins-ci - jenkins - 1.34 - - - - org.jenkins-ci.plugins - plugin - Jenkins plugin POM - 1.616-SNAPSHOT - pom - - - - scm:svn:https://svn.jenkins-ci.org/trunk/hudson/plugins/ - scm:svn:https://svn.jenkins-ci.org/trunk/hudson/plugins/ - https://svn.jenkins-ci.org/trunk/hudson/plugins/ - HEAD - - - - JIRA - http://issues.jenkins-ci.org/ - - - - UTF-8 - 2 - - - - - org.jenkins-ci.main - jenkins-war - war - 1.616-SNAPSHOT - test - - - org.jenkins-ci.main - jenkins-core - 1.616-SNAPSHOT - provided - - - org.jenkins-ci.main - jenkins-test-harness - 1.616-SNAPSHOT - test - - - - javax.servlet - servlet-api - 2.4 - provided - - - - org.codehaus.mojo - animal-sniffer-annotations - 1.9 - provided - true - - - - - - ${project.artifactId} - - - org.jenkins-ci.tools - maven-hpi-plugin - true - - true - /jenkins - - - - org.kohsuke.stapler - maven-stapler-plugin - - true - - - maven-release-plugin - - - deploy - - - - org.jvnet.localizer - maven-localizer-plugin - - - - - generate - - - Messages.properties - target/generated-sources/localizer - - - - - - maven-javadoc-plugin - - - - org.codehaus.gmaven - gmaven-plugin - - - - test-in-groovy - - - generateTestStubs - testCompile - - - - - - ant - ant - 1.6.5 - - - - - maven-surefire-plugin - 2.16 - - - - hudson.udp - 33849 - - - true - ${concurrency} - - - - com.cloudbees - maven-license-plugin - - - - - process - - prepare-package - - - target/${project.artifactId}/WEB-INF/licenses.xml - - if (e.value.packaging=="hpi") - plugins.add(e.key.id) - } - - // filter out dependencies that don't belong to this plugin - models.entrySet().removeAll(models.entrySet().findAll { e -> - def a = e.key; - - if (a.dependencyTrail.size()>0 && plugins.contains(a.dependencyTrail[1])) - return true; // ignore transitive dependencies through other plugins - - // if the dependency goes through jenkins core, we don't need to bundle it in the war - // because jenkins-core comes in the scope, I think this is a bug in Maven that it puts such - // dependencies into the artifact list. - if (a.dependencyTrail.find { trail -> trail.contains(":hudson-core:") || trail.contains(":jenkins-core:") }) - return true; - - return false; - }) - } - ]]> - - - - - - - - - - org.apache.maven.plugins - maven-eclipse-plugin - - target/eclipse-classes - - - org.eclipse.jdt.groovy.core.groovyNature - - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - [1.0,) - - display-info - - - - - - - - - org.codehaus.gmaven - gmaven-plugin - [1.0,) - - testCompile - generateTestStubs - - - - - - - - - - - - - org.codehaus.mojo - animal-sniffer-maven-plugin - 1.9 - - - - check - - test - - - - - - org.codehaus.mojo.signature - java15 - 1.0 - - - - - - - - org.kohsuke - wagon-gitsite - 0.3.5 - - - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - true - - - false - - - - - - - repo.jenkins-ci.org - http://repo.jenkins-ci.org/public/ - - true - - - false - - - - - - - github-pages - gitsite:git@github.com/jenkinsci/maven-site.git:plugin-parent - - - maven.jenkins-ci.org - http://maven.jenkins-ci.org:8081/content/repositories/snapshots - - - - - - all-tests - - - !test - - - - true - - - - diff --git a/pom.xml b/pom.xml index bcd0c38b6450577ba3b021a1ebb2a15987485682..410c7bf46af970613cb3ce49953b61cdfb6960a0 100644 --- a/pom.xml +++ b/pom.xml @@ -28,12 +28,12 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.34 + 1.36 org.jenkins-ci.main pom - 1.616-SNAPSHOT + 2.37-SNAPSHOT pom Jenkins main module @@ -52,7 +52,6 @@ THE SOFTWARE. war test cli - plugins @@ -67,10 +66,6 @@ THE SOFTWARE. github-pages gitsite:git@github.com/jenkinsci/maven-site.git:core - - maven.jenkins-ci.org - http://maven.jenkins-ci.org:8081/content/repositories/snapshots - @@ -97,13 +92,22 @@ THE SOFTWARE. jenkins-jira 1.7.7 - 2.7.1 + 2.14 1.4.1 + 0.11 ${skipTests} + 3.0.4 + true + 1.2 7 + + https://jenkins-ci.org/changelog + repo.jenkins-ci.org @@ -147,24 +151,24 @@ THE SOFTWARE. junit junit - 4.11 + 4.12 org.mockito mockito-core - 1.9.5 + 1.10.19 org.powermock powermock-module-junit4 - 1.5.6 + 1.6.2 org.powermock powermock-api-mockito - 1.5.6 + 1.6.2 @@ -176,7 +180,7 @@ THE SOFTWARE. org.jenkins-ci.main remoting - 2.51 + 3.2 @@ -188,7 +192,7 @@ THE SOFTWARE. com.google.inject guice - 4.0-beta + 4.0 @@ -216,6 +220,18 @@ THE SOFTWARE. commons-logging commons-logging 1.1.3 + provided + + + org.slf4j + log4j-over-slf4j + ${slf4jVersion} + + + log4j + log4j + 1.2.17 + provided org.samba.jcifs @@ -237,7 +253,7 @@ THE SOFTWARE. org.jenkins-ci test-annotations - 1.1 + ${test-annotations.version} test @@ -308,7 +324,17 @@ THE SOFTWARE. servlet-api 2.4 + + org.codehaus.gmaven.runtime + gmaven-runtime-2.0 + 1.5-jenkins-3 + + + + 2.0 + org.apache.maven.plugins @@ -342,7 +368,7 @@ THE SOFTWARE. org.apache.maven.plugins maven-javadoc-plugin - 2.8 + 2.10.3 org.apache.maven.plugins @@ -357,7 +383,7 @@ THE SOFTWARE. org.apache.maven.plugins maven-surefire-plugin - 2.16 + 2.19.1 -noverify @@ -442,7 +468,7 @@ THE SOFTWARE. org.jvnet.localizer maven-localizer-plugin - 1.23 + 1.24 UTF-8 @@ -475,7 +501,24 @@ THE SOFTWARE. org.codehaus.mojo findbugs-maven-plugin - 2.5.2 + ${findbugs-maven-plugin.version} + + Max + High + + ../src/findbugs/findbugs-excludes.xml + true + false + + + + findbugs + + check + + verify + + org.apache.maven.plugins @@ -486,7 +529,7 @@ THE SOFTWARE. org.jenkins-ci.tools maven-jenkins-dev-plugin - 8.1.4.v20120524-jenkins-1 + 9.2.15.v20160210-jenkins-1 org.jvnet.updatecenter2 @@ -496,12 +539,12 @@ THE SOFTWARE. org.jenkins-ci.tools maven-hpi-plugin - 1.110 + 1.120 org.apache.maven.plugins maven-site-plugin - 3.1 + 3.3 org.kohsuke @@ -553,7 +596,7 @@ THE SOFTWARE. org.codehaus.mojo animal-sniffer-maven-plugin - 1.9 + 1.15 @@ -658,6 +701,10 @@ THE SOFTWARE. org.sonatype.sisu:sisu-guice + log4j:log4j:*:jar:compile + log4j:log4j:*:jar:runtime + commons-logging:commons-logging:*:jar:compile + commons-logging:commons-logging:*:jar:runtime @@ -706,19 +753,9 @@ THE SOFTWARE. - - - 1.7 - - - - org.codehaus.gmaven.runtime - gmaven-runtime-1.7 - 1.3 - - + + @@ -757,18 +794,17 @@ THE SOFTWARE. metrics - + org.codehaus.mojo findbugs-maven-plugin - 2.5.2 High - + debug @@ -786,17 +822,24 @@ THE SOFTWARE. - org.jvnet.sorcerer + org.kohsuke.sorcerer maven-sorcerer-plugin - 0.8 + ${sorcerer.version} + + 1.${java.level} + - org.jvnet.sorcerer + org.kohsuke.sorcerer maven-sorcerer-plugin + ${sorcerer.version} + + 1.${java.level} + @@ -838,6 +881,12 @@ THE SOFTWARE. + + lts-release + + https://jenkins-ci.org/changelog-stable + + m2e diff --git a/core/src/findbugs-filter.xml b/src/findbugs/findbugs-excludes.xml similarity index 70% rename from core/src/findbugs-filter.xml rename to src/findbugs/findbugs-excludes.xml index 751d3fa8a5d470e36e579dd1169bcd88ea649507..781617524e5364995864c869f3568bdbb7467a51 100644 --- a/core/src/findbugs-filter.xml +++ b/src/findbugs/findbugs-excludes.xml @@ -4,17 +4,12 @@ + + + - - - - - - - - diff --git a/src/site/resources/jenkins_logo.png b/src/site/resources/jenkins_logo.png index 05de7d6b04c8a46367d8fc543ed48dca3def1a29..e647e5fe9ab4d9f4ab3c0fc1dcbac4e2457a0600 100644 Binary files a/src/site/resources/jenkins_logo.png and b/src/site/resources/jenkins_logo.png differ diff --git a/test/pom.xml b/test/pom.xml index 5519cefe13238933edfea870663d2d3ae19a15ad..674c7be7fd040b89afabbd8c33cd423113788100 100644 --- a/test/pom.xml +++ b/test/pom.xml @@ -28,19 +28,19 @@ THE SOFTWARE. org.jenkins-ci.main pom - 1.616-SNAPSHOT + 2.37-SNAPSHOT - jenkins-test-harness + test - Test harness for Jenkins and plugins - Unit test harness (src/main) and Unit tests for Jenkins core (src/test) + Tests for Jenkins core + Functional tests for Jenkins core 2 false - false + false @@ -62,23 +62,54 @@ THE SOFTWARE. ${project.groupId} - maven-plugin - ${maven-plugin.version} + jenkins-test-harness + 2.13 + test + + + ${project.groupId} + jenkins-war + + - org.jenkins-ci.plugins - ant - 1.2 + ${project.groupId} + jenkins-test-harness-tools + 2.0 + test + ${project.groupId} + maven-plugin + ${maven-plugin.version} + + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + + + + org.jenkins-ci + SECURITY-144-compat + + + commons-codec + commons-codec + + + + org.jenkins-ci.plugins subversion 1.45 - - - org.jenkins-ci.plugins - mailer - 1.10 + test org.jenkins-ci.plugins @@ -89,6 +120,7 @@ THE SOFTWARE. org.jenkins-ci.plugins antisamy-markup-formatter 1.0 + test org.jenkins-ci.plugins @@ -99,55 +131,35 @@ THE SOFTWARE. org.jenkins-ci.plugins junit 1.2-beta-4 + test - org.mortbay.jetty - jetty - 6.1.26 - - - org.jenkins-ci - test-annotations - 1.1 - compile - + org.jenkins-ci.plugins + structs + 1.2 + test org.jvnet.mock-javamail mock-javamail 1.7 - - junit - junit - org.hamcrest - hamcrest-library + hamcrest-core 1.3 - - org.jenkins-ci - htmlunit - 2.6-jenkins-6 + + xalan + xalan + 2.7.1 - xml-apis xml-apis - - xalan - xalan - 2.7.1 - - - org.jvnet.hudson - embedded-rhino-debugger - 1.2 - org.jvnet.hudson @@ -165,20 +177,27 @@ THE SOFTWARE. test - org.netbeans.modules - org-netbeans-insane - RELEASE72 - - - com.github.stephenc.findbugs - findbugs-annotations - 1.3.9-1 + org.reflections + reflections + 0.9.9 org.codehaus.geb geb-implicit-assertions 0.7.2 + + org.javassist + javassist + 3.19.0-GA + test + + + org.apache.commons + commons-collections4 + 4.0 + test + @@ -194,15 +213,14 @@ THE SOFTWARE. maven-surefire-plugin - ${jacocoSurefireArgs} -Dfile.encoding=UTF-8 -Xmx256m -XX:MaxPermSize=128m + ${jacocoSurefireArgs} -Dfile.encoding=UTF-8 -Xmx1g -XX:MaxPermSize=128m true ${mavenDebug} ${project.build.directory} - ${ignore.random.failures} - true + false ${concurrency} @@ -219,16 +237,6 @@ THE SOFTWARE. testCompile - - preset-packager - process-resources - - execute - - - ${pom.basedir}/src/main/preset-data/package.groovy - - @@ -242,15 +250,7 @@ THE SOFTWARE. ant-launcher 1.8.0 - - org.codehaus.gmaven.runtime - gmaven-runtime-2.0 - 1.5-jenkins-1 - - - 2.0 - @@ -271,6 +271,7 @@ THE SOFTWARE. true + 4 diff --git a/test/src/main/java/hudson/cli/CLICommandInvoker.java b/test/src/main/java/hudson/cli/CLICommandInvoker.java deleted file mode 100644 index ad8ac1f229a72aad2afbfb823d22c9664a576814..0000000000000000000000000000000000000000 --- a/test/src/main/java/hudson/cli/CLICommandInvoker.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * The MIT License - * - * Copyright 2013 Red Hat, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package hudson.cli; - -import hudson.Extension; -import hudson.model.User; -import hudson.security.ACL; -import hudson.security.Permission; -import hudson.security.GlobalMatrixAuthorizationStrategy; - -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.PrintStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -import jenkins.model.Jenkins; - -import org.hamcrest.Description; -import org.hamcrest.TypeSafeMatcher; -import org.jvnet.hudson.test.JenkinsRule; - -/** - * Helper class to invoke {@link CLICommand} and check the response. - * - * @author ogondza - */ -public class CLICommandInvoker { - - private static final String username = "user"; - private final JenkinsRule rule; - private final CLICommand command; - - private InputStream stdin; - private List args = Collections.emptyList(); - private List permissions = Collections.emptyList(); - private Locale locale = Locale.ENGLISH; - - public CLICommandInvoker(final JenkinsRule rule, final CLICommand command) { - - if (command.getClass().getAnnotation(Extension.class) == null) { - - throw new AssertionError(String.format( - "Command %s is missing @Extension annotation.", - command.getClass() - )); - } - - this.rule = rule; - this.command = command; - } - - public CLICommandInvoker(final JenkinsRule rule, final String command) { - this.rule = rule; - this.command = CLICommand.clone(command); - - if (this.command == null) throw new AssertionError("No such command: " + command); - } - - public CLICommandInvoker authorizedTo(final Permission... permissions) { - - this.permissions = Arrays.asList(permissions); - return this; - } - - public CLICommandInvoker withStdin(final InputStream stdin) { - - if (stdin == null) throw new NullPointerException("No stdin provided"); - - this.stdin = stdin; - return this; - } - - public CLICommandInvoker withArgs(final String... args) { - - this.args = Arrays.asList(args); - return this; - } - - public Result invokeWithArgs(final String... args) { - - return withArgs(args).invoke(); - } - - public Result invoke() { - - setAuth(); - - final ByteArrayOutputStream out = new ByteArrayOutputStream(); - final ByteArrayOutputStream err = new ByteArrayOutputStream(); - - final int returnCode = command.main( - args, locale, stdin, new PrintStream(out), new PrintStream(err) - ); - - return new Result(returnCode, out, err); - } - - private void setAuth() { - - if (permissions.isEmpty()) return; - - JenkinsRule.DummySecurityRealm realm = rule.createDummySecurityRealm(); - realm.addGroups(username, "group"); - rule.jenkins.setSecurityRealm(realm); - - GlobalMatrixAuthorizationStrategy auth = new GlobalMatrixAuthorizationStrategy(); - for(Permission p: permissions) { - p.setEnabled(true); - auth.add(p, username); - } - rule.jenkins.setAuthorizationStrategy(auth); - - command.setTransportAuth(user().impersonate()); - // Otherwise it is SYSTEM, which would be relevant for a command overriding main: - ACL.impersonate(Jenkins.ANONYMOUS); - } - - public User user() { - - return User.get(username); - } - - public static class Result { - - private final int result; - private final ByteArrayOutputStream out; - private final ByteArrayOutputStream err; - - private Result( - final int result, - final ByteArrayOutputStream out, - final ByteArrayOutputStream err - ) { - - this.result = result; - this.out = out; - this.err = err; - } - - public int returnCode() { - - return result; - } - - public String stdout() { - - return out.toString(); - } - - public String stderr() { - - return err.toString(); - } - - @Override - public String toString() { - - StringBuilder builder = new StringBuilder("CLI command exited with ").append(result); - String stdout = stdout(); - if (!"".equals(stdout)) { - builder.append("\nSTDOUT:\n").append(stdout); - } - String stderr = stderr(); - if (!"".equals(stderr)) { - builder.append("\nSTDERR:\n").append(stderr); - } - - return builder.toString(); - } - } - - public abstract static class Matcher extends TypeSafeMatcher { - - private final String description; - - private Matcher(String description) { - this.description = description; - } - - @Override - protected void describeMismatchSafely(Result result, Description description) { - description.appendText(result.toString()); - } - - public void describeTo(Description description) { - description.appendText(this.description); - } - - public static Matcher hasNoStandardOutput() { - return new Matcher("No standard output") { - @Override protected boolean matchesSafely(Result result) { - return "".equals(result.stdout()); - } - }; - } - - public static Matcher hasNoErrorOutput() { - return new Matcher("No error output") { - @Override protected boolean matchesSafely(Result result) { - return "".equals(result.stderr()); - } - }; - } - - public static Matcher succeeded() { - return new Matcher("Exited with 0 return code") { - @Override protected boolean matchesSafely(Result result) { - return result.result == 0; - } - }; - } - - public static Matcher succeededSilently() { - return new Matcher("Succeeded silently") { - @Override protected boolean matchesSafely(Result result) { - return result.result == 0 && "".equals(result.stderr()) && "".equals(result.stdout()); - } - }; - } - - public static Matcher failedWith(final long expectedCode) { - return new Matcher("Exited with " + expectedCode + " return code") { - @Override protected boolean matchesSafely(Result result) { - return result.result == expectedCode; - } - }; - } - } -} diff --git a/test/src/main/java/hudson/util/SecretHelper.java b/test/src/main/java/hudson/util/SecretHelper.java deleted file mode 100644 index b76b1f8be41cbbfe7ed76c91a86f950a2ddae0d3..0000000000000000000000000000000000000000 --- a/test/src/main/java/hudson/util/SecretHelper.java +++ /dev/null @@ -1,10 +0,0 @@ -package hudson.util; - -/** - * @author Kohsuke Kawaguchi - */ -public class SecretHelper { - public static void set(String s) { - Secret.SECRET = s; - } -} diff --git a/test/src/main/java/jenkins/model/JenkinsAdaptor.java b/test/src/main/java/jenkins/model/JenkinsAdaptor.java deleted file mode 100644 index efe14b9cb10a19483ada62fc5dc5aefd855b9e1c..0000000000000000000000000000000000000000 --- a/test/src/main/java/jenkins/model/JenkinsAdaptor.java +++ /dev/null @@ -1,11 +0,0 @@ -package jenkins.model; - -/** - * Access the package protected quiet period - */ -public class JenkinsAdaptor { - public static void setQuietPeriod(Jenkins jenkins, int quietPeriod) { - jenkins.quietPeriod = quietPeriod; - } - -} diff --git a/test/src/main/java/org/jvnet/hudson/test/BuildWatcher.java b/test/src/main/java/org/jvnet/hudson/test/BuildWatcher.java deleted file mode 100644 index 053c3cf467d10d21e2b15b499fab28918b73a7eb..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/BuildWatcher.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * The MIT License - * - * Copyright 2015 Jesse Glick. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package org.jvnet.hudson.test; - -import hudson.Extension; -import hudson.console.AnnotatedLargeText; -import hudson.console.LineTransformationOutputStream; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.model.listeners.RunListener; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.junit.rules.ExternalResource; - -/** - * Echoes build output to standard error as it arrives. - * Usage:

    {@code @ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();}
    - * Should work in combination with {@link JenkinsRule} or {@link RestartableJenkinsRule}. - * @see JenkinsRule#waitForCompletion - * @see JenkinsRule#waitForMessage - * @since 1.607 - */ -public final class BuildWatcher extends ExternalResource { - - private static boolean active; - private static final Map builds = new ConcurrentHashMap(); - - private Thread thread; - - @Override protected void before() throws Throwable { - active = true; - thread = new Thread("watching builds") { - @Override public void run() { - try { - while (active) { - for (RunningBuild build : builds.values()) { - build.copy(); - } - Thread.sleep(50); - } - } catch (InterruptedException x) { - // stopped - } - // last chance - for (RunningBuild build : builds.values()) { - build.copy(); - } - } - }; - thread.setDaemon(true); - thread.start(); - } - - @Override protected void after() { - active = false; - thread.interrupt(); - } - - @Extension public static final class Listener extends RunListener> { - - @Override public void onStarted(Run r, TaskListener listener) { - if (!active) { - return; - } - RunningBuild build = new RunningBuild(r); - RunningBuild orig = builds.put(r.getLogFile(), build); - if (orig != null) { - System.err.println(r + " was started twice?!"); - } - } - - @Override public void onFinalized(Run r) { - if (!active) { - return; - } - RunningBuild build = builds.remove(r.getLogFile()); - if (build != null) { - build.copy(); - } else { - System.err.println(r + " was finalized but not started?!"); - } - } - - } - - private static final class RunningBuild { - - private final AnnotatedLargeText log; - private final OutputStream sink; - private long pos; - - RunningBuild(Run r) { - log = r.getLogText(); - sink = new LogLinePrefixOutputFilter(System.err, "[" + r + "] "); - } - - synchronized void copy() { - try { - pos = log.writeLogTo(pos, sink); - // Note that !log.isComplete() after the initial call to copy, even if the build is complete, because Run.getLogText never calls markComplete! - // That is why Run.writeWholeLogTo calls getLogText repeatedly. - // Even if it did call markComplete this might not work from RestartableJenkinsRule since you would have a different Run object after the restart. - // Anyway we can just rely on onFinalized to let us know when to stop. - } catch (FileNotFoundException x) { - // build deleted or not started - } catch (Exception x) { - x.printStackTrace(); - } - } - - } - - // Copied from WorkflowRun. - private static final class LogLinePrefixOutputFilter extends LineTransformationOutputStream { - - private final PrintStream logger; - private final String prefix; - - LogLinePrefixOutputFilter(PrintStream logger, String prefix) { - this.logger = logger; - this.prefix = prefix; - } - - @Override protected void eol(byte[] b, int len) throws IOException { - logger.append(prefix); - logger.write(b, 0, len); - } - - } - -} diff --git a/test/src/main/java/org/jvnet/hudson/test/ChannelShutdownListener.java b/test/src/main/java/org/jvnet/hudson/test/ChannelShutdownListener.java deleted file mode 100644 index 935aeca28fdebc4f8823b03a0c1b00dd58310155..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/ChannelShutdownListener.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.jvnet.hudson.test; - -import hudson.Extension; -import hudson.model.Computer; -import hudson.model.TaskListener; -import hudson.remoting.Channel; -import hudson.remoting.VirtualChannel; -import hudson.slaves.ComputerListener; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * Runs at the end of the test to cleanup any live channels. - * -* @author Kohsuke Kawaguchi -*/ -@Extension -public class ChannelShutdownListener extends ComputerListener implements EndOfTestListener { - /** - * Remember channels that are created, to release them at the end. - */ - private List channels = new ArrayList(); - - @Override - public synchronized void onOnline(Computer c, TaskListener listener) throws IOException, InterruptedException { - VirtualChannel ch = c.getChannel(); - if (ch instanceof Channel) { - channels.add((Channel)ch); - } - } - - @Override - public synchronized void onTearDown() throws Exception { - for (Channel c : channels) - c.close(); - for (Channel c : channels) - c.join(); - channels.clear(); - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/ComputerConnectorTester.java b/test/src/main/java/org/jvnet/hudson/test/ComputerConnectorTester.java deleted file mode 100644 index d69d2279ff9d9c7bce71b857c3ec5d7fdd2e7151..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/ComputerConnectorTester.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010, InfraDNA, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import hudson.Extension; -import hudson.model.AbstractDescribableImpl; -import hudson.model.Descriptor; -import hudson.slaves.ComputerConnector; -import hudson.slaves.ComputerConnectorDescriptor; -import org.kohsuke.stapler.StaplerRequest; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.List; - -/** - * Test bed to verify the configuration roundtripness of the {@link ComputerConnector}. - * - * @author Kohsuke Kawaguchi - * @see HudsonTestCase#computerConnectorTester - */ -public class ComputerConnectorTester extends AbstractDescribableImpl { - public final HudsonTestCase testCase; - public ComputerConnector connector; - - public ComputerConnectorTester(HudsonTestCase testCase) { - this.testCase = testCase; - } - - public void doConfigSubmit(StaplerRequest req) throws IOException, ServletException { - connector = req.bindJSON(ComputerConnector.class, req.getSubmittedForm().getJSONObject("connector")); - } - - public List getConnectorDescriptors() { - return ComputerConnectorDescriptor.all(); - } - - @Extension - public static class DescriptorImpl extends Descriptor { - @Override - public String getDisplayName() { - return ""; - } - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/DefaultConstructorChecker.java b/test/src/main/java/org/jvnet/hudson/test/DefaultConstructorChecker.java deleted file mode 100644 index 9c862edc4773d6a89af2497dcc74a39b9d124130..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/DefaultConstructorChecker.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.jvnet.hudson.test; - -import junit.framework.TestCase; - -/** - * Tests that the specified class has the default constructor. - * - * @author Kohsuke Kawaguchi - */ -public class DefaultConstructorChecker extends TestCase { - private final Class clazz; - - public DefaultConstructorChecker(Class clazz) { - this.clazz = clazz; - setName(clazz.getName()+".verifyDefaultConstructor"); - } - - @Override - protected void runTest() throws Throwable { - try { - clazz.getConstructor(); - } catch (NoSuchMethodException e) { - throw new Error(clazz+" must have the default constructor",e); - } catch (SecurityException e) { - throw new Error(clazz+" must have the default constructor",e); - } - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/EndOfTestListener.java b/test/src/main/java/org/jvnet/hudson/test/EndOfTestListener.java deleted file mode 100644 index e6d9c143cfd99c3f15a0f99bf8bbe527e517d06f..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/EndOfTestListener.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.jvnet.hudson.test; - -import hudson.ExtensionPoint; - -/** - * Gets notified before the test completes to perform additional cleanup. - * - * @author Kohsuke Kawaguchi - * @since 1.520 - */ -public interface EndOfTestListener extends ExtensionPoint { - /** - * Called for clean up. - */ - void onTearDown() throws Exception; -} diff --git a/test/src/main/java/org/jvnet/hudson/test/ExtractChangeLogParser.java b/test/src/main/java/org/jvnet/hudson/test/ExtractChangeLogParser.java deleted file mode 100644 index a2bd723e6b4c72f028d1e30feaeb43a1fab43357..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/ExtractChangeLogParser.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import hudson.model.AbstractBuild; -import hudson.model.User; -import hudson.scm.ChangeLogParser; -import hudson.scm.ChangeLogSet; -import org.apache.commons.digester.Digester; -import org.kohsuke.stapler.export.Exported; -import org.kohsuke.stapler.export.ExportedBean; -import org.xml.sax.SAXException; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * @author Andrew Bayer - */ -public class ExtractChangeLogParser extends ChangeLogParser { - @SuppressWarnings("rawtypes") - @Override - public ExtractChangeLogSet parse(AbstractBuild build, File changeLogFile) throws IOException, SAXException { - if (changeLogFile.exists()) { - FileInputStream fis = new FileInputStream(changeLogFile); - ExtractChangeLogSet logSet = parse(build, fis); - fis.close(); - return logSet; - } else { - return new ExtractChangeLogSet(build, new ArrayList()); - } - } - - @SuppressWarnings("rawtypes") - public ExtractChangeLogSet parse(AbstractBuild build, InputStream changeLogStream) throws IOException, SAXException { - - ArrayList changeLog = new ArrayList(); - - Digester digester = new Digester(); - digester.setClassLoader(ExtractChangeLogSet.class.getClassLoader()); - digester.push(changeLog); - digester.addObjectCreate("*/extractChanges/entry", ExtractChangeLogEntry.class); - - digester.addBeanPropertySetter("*/extractChanges/entry/zipFile"); - - digester.addObjectCreate("*/extractChanges/entry/file", - FileInZip.class); - digester.addBeanPropertySetter("*/extractChanges/entry/file/fileName"); - digester.addSetNext("*/extractChanges/entry/file", "addFile"); - digester.addSetNext("*/extractChanges/entry", "add"); - - digester.parse(changeLogStream); - - return new ExtractChangeLogSet(build, changeLog); - } - - - @ExportedBean(defaultVisibility = 999) - public static class ExtractChangeLogEntry extends ChangeLogSet.Entry { - private List files = new ArrayList(); - private String zipFile; - - public ExtractChangeLogEntry() { - } - - public ExtractChangeLogEntry(String zipFile) { - this.zipFile = zipFile; - } - - public void setZipFile(String zipFile) { - this.zipFile = zipFile; - } - - @Exported - public String getZipFile() { - return zipFile; - } - - @Override - public void setParent(ChangeLogSet parent) { - super.setParent(parent); - } - - @Override - public Collection getAffectedPaths() { - Collection paths = new ArrayList(files.size()); - for (FileInZip file : files) { - paths.add(file.getFileName()); - } - return paths; - } - - @Override - @Exported - public User getAuthor() { - return User.get("testuser"); - } - - @Override - @Exported - public String getMsg() { - return "Extracted from " + zipFile; - } - - public void addFile(FileInZip fileName) { - files.add(fileName); - } - - public void addFiles(Collection fileNames) { - this.files.addAll(fileNames); - } - } - - @ExportedBean(defaultVisibility = 999) - public static class FileInZip { - private String fileName = ""; - - public FileInZip() { - } - - public FileInZip(String fileName) { - this.fileName = fileName; - } - - @Exported - public String getFileName() { - return fileName; - } - - public void setFileName(String fileName) { - this.fileName = fileName; - } - } - -} diff --git a/test/src/main/java/org/jvnet/hudson/test/ExtractResourceSCM.java b/test/src/main/java/org/jvnet/hudson/test/ExtractResourceSCM.java deleted file mode 100644 index 743eecde22a9f4d9469facabfc8b2b2472a63561..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/ExtractResourceSCM.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.scm.NullSCM; -import hudson.scm.SCM; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.net.URL; - -/** - * {@link SCM} useful for testing that extracts the given resource as a zip file. - * - * @author Kohsuke Kawaguchi - */ -public class ExtractResourceSCM extends NullSCM { - private final URL zip; - - private String parentFolder; - - /** - * - * @param zip - */ - public ExtractResourceSCM(URL zip) { - if(zip==null) - throw new IllegalArgumentException(); - this.zip = zip; - } - - /** - * with this constructor your zip can contains a folder - * more usefull to create a project test zip foo.zip foo - * @param zip - * @param parentFolder - */ - public ExtractResourceSCM(URL zip, String parentFolder) { - if(zip==null) - throw new IllegalArgumentException(); - this.zip = zip; - this.parentFolder = parentFolder; - } - - @Override - public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener, File changeLogFile) throws IOException, InterruptedException { - if (workspace.exists()) { - listener.getLogger().println("Deleting existing workspace " + workspace.getRemote()); - workspace.deleteRecursive(); - } - listener.getLogger().println("Staging "+zip); - workspace.unzipFrom(zip.openStream()); - if (parentFolder != null) { - FileUtils.copyDirectory( new File(workspace.getRemote() + "/" + parentFolder), new File( workspace.getRemote())); - } - return true; - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/ExtractResourceWithChangesSCM.java b/test/src/main/java/org/jvnet/hudson/test/ExtractResourceWithChangesSCM.java deleted file mode 100644 index cf2d9193fbf49b22912d391c0ad5eac5aaf32d84..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/ExtractResourceWithChangesSCM.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.Util; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.scm.ChangeLogParser; -import hudson.scm.NullSCM; -import hudson.scm.SCM; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.net.URL; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -/** - * {@link SCM} useful for testing that extracts the given resource as a zip file. - * - * @author Kohsuke Kawaguchi - */ -public class ExtractResourceWithChangesSCM extends NullSCM { - private final URL firstZip; - private final URL secondZip; - private final String moduleRoot; - - public ExtractResourceWithChangesSCM(URL firstZip, URL secondZip) { - if ((firstZip == null) || (secondZip == null)) - throw new IllegalArgumentException(); - this.firstZip = firstZip; - this.secondZip = secondZip; - this.moduleRoot = null; - } - - public ExtractResourceWithChangesSCM(URL firstZip, URL secondZip, String moduleRoot) { - if ((firstZip == null) || (secondZip == null)) - throw new IllegalArgumentException(); - this.firstZip = firstZip; - this.secondZip = secondZip; - this.moduleRoot = moduleRoot; - } - - @Override - public FilePath getModuleRoot(FilePath workspace) { - if (moduleRoot!=null) { - return workspace.child(moduleRoot); - } - return workspace; - } - - @Override - public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, BuildListener listener, File changeLogFile) throws IOException, InterruptedException { - if (workspace.exists()) { - listener.getLogger().println("Deleting existing workspace " + workspace.getRemote()); - workspace.deleteRecursive(); - } - listener.getLogger().println("Staging first zip: " + firstZip); - workspace.unzipFrom(firstZip.openStream()); - listener.getLogger().println("Staging second zip: " + secondZip); - workspace.unzipFrom(secondZip.openStream()); - - // Get list of files changed in secondZip. - ZipInputStream zip = new ZipInputStream(secondZip.openStream()); - ZipEntry e; - ExtractChangeLogParser.ExtractChangeLogEntry changeLog = new ExtractChangeLogParser.ExtractChangeLogEntry(secondZip.toString()); - - try { - while ((e = zip.getNextEntry()) != null) { - if (!e.isDirectory()) - changeLog.addFile(new ExtractChangeLogParser.FileInZip(e.getName())); - } - } - finally { - zip.close(); - } - saveToChangeLog(changeLogFile, changeLog); - - return true; - } - - @Override - public ChangeLogParser createChangeLogParser() { - return new ExtractChangeLogParser(); - } - - private static String escapeForXml(String string) { - return Util.xmlEscape(Util.fixNull(string)); - } - - public void saveToChangeLog(File changeLogFile, ExtractChangeLogParser.ExtractChangeLogEntry changeLog) throws IOException { - FileOutputStream outputStream = new FileOutputStream(changeLogFile); - - PrintStream stream = new PrintStream(outputStream, false, "UTF-8"); - - stream.println(""); - stream.println(""); - stream.println(""); - stream.println("" + escapeForXml(changeLog.getZipFile()) + ""); - - for (String fileName : changeLog.getAffectedPaths()) { - stream.println(""); - stream.println("" + escapeForXml(fileName) + ""); - stream.println(""); - } - - stream.println(""); - stream.println(""); - - stream.close(); - } - - /** - * Don't write 'this', so that subtypes can be implemented as anonymous class. - */ - private Object writeReplace() { return new Object(); } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/FakeChangeLogSCM.java b/test/src/main/java/org/jvnet/hudson/test/FakeChangeLogSCM.java deleted file mode 100644 index e569e35ac88f21683c28b35ed4e545f0ba64de4f..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/FakeChangeLogSCM.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2011, CloudBees, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.model.InvisibleAction; -import hudson.model.User; -import hudson.scm.ChangeLogParser; -import hudson.scm.ChangeLogSet; -import hudson.scm.ChangeLogSet.Entry; -import hudson.scm.NullSCM; -import hudson.scm.SCM; -import hudson.scm.SCMDescriptor; -import org.xml.sax.SAXException; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -/** - * Fake SCM implementation that can report arbitrary commits from arbitrary users. - * - * @author Kohsuke Kawaguchi - */ -public class FakeChangeLogSCM extends NullSCM { - - /** - * Changes to be reported in the next build. - */ - private List entries = new ArrayList(); - - public EntryImpl addChange() { - EntryImpl e = new EntryImpl(); - entries.add(e); - return e; - } - - @Override - public boolean checkout(AbstractBuild build, Launcher launcher, FilePath remoteDir, BuildListener listener, File changeLogFile) throws IOException, InterruptedException { - new FilePath(changeLogFile).touch(0); - build.addAction(new ChangelogAction(entries)); - entries = new ArrayList(); - return true; - } - - @Override - public ChangeLogParser createChangeLogParser() { - return new FakeChangeLogParser(); - } - - @Override public SCMDescriptor getDescriptor() { - return new SCMDescriptor(null) { - @Override public String getDisplayName() { - return ""; - } - }; - } - - public static class ChangelogAction extends InvisibleAction { - private final List entries; - - public ChangelogAction(List entries) { - this.entries = entries; - } - } - - public static class FakeChangeLogParser extends ChangeLogParser { - @SuppressWarnings("rawtypes") - @Override - public FakeChangeLogSet parse(AbstractBuild build, File changelogFile) throws IOException, SAXException { - return new FakeChangeLogSet(build, build.getAction(ChangelogAction.class).entries); - } - } - - public static class FakeChangeLogSet extends ChangeLogSet { - private List entries; - - public FakeChangeLogSet(AbstractBuild build, List entries) { - super(build); - this.entries = entries; - } - - @Override - public boolean isEmptySet() { - return entries.isEmpty(); - } - - public Iterator iterator() { - return entries.iterator(); - } - } - - public static class EntryImpl extends Entry { - private String msg = "some commit message"; - private String author = "someone"; - - public EntryImpl withAuthor(String author) { - this.author = author; - return this; - } - - public EntryImpl withMsg(String msg) { - this.msg = msg; - return this; - } - - @Override - public String getMsg() { - return msg; - } - - @Override - public User getAuthor() { - return User.get(author); - } - - @Override - public Collection getAffectedPaths() { - return Collections.singleton("path"); - } - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/FakeLauncher.java b/test/src/main/java/org/jvnet/hudson/test/FakeLauncher.java deleted file mode 100644 index 9ca68019d4991ee5172bcf51c57a951fb057e182..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/FakeLauncher.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.jvnet.hudson.test; - -import hudson.Launcher.ProcStarter; -import hudson.Proc; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * Fake a process launch. - * - * @author Kohsuke Kawaguchi - * @see PretendSlave - */ -public interface FakeLauncher { - /** - * Called whenever a {@link PretendSlave} is asked to fork a new process. - * - *

    - * The callee can inspect the {@link ProcStarter} object to determine what process is being launched, - * and if necessary, fake a process launch by either returning a valid {@link Proc} object, or let - * the normal process launch happen by returning null. - */ - Proc onLaunch(ProcStarter p) throws IOException; - - /** - * Fake {@link Proc} implementation that represents a completed process. - */ - class FinishedProc extends Proc { - public final int exitCode; - - public FinishedProc(int exitCode) { - this.exitCode = exitCode; - } - - @Override - public boolean isAlive() throws IOException, InterruptedException { - return false; - } - - @Override - public void kill() throws IOException, InterruptedException { - throw new UnsupportedOperationException(); - } - - @Override - public int join() throws IOException, InterruptedException { - return exitCode; - } - - @Override - public InputStream getStdout() { - // TODO - throw new UnsupportedOperationException(); - } - - @Override - public InputStream getStderr() { - // TODO - throw new UnsupportedOperationException(); - } - - @Override - public OutputStream getStdin() { - // TODO - throw new UnsupportedOperationException(); - } - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/GroovyHudsonTestCase.java b/test/src/main/java/org/jvnet/hudson/test/GroovyHudsonTestCase.java deleted file mode 100644 index 9e7a90d431c04b764e4fe1d6c4b069a5b021c6bf..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/GroovyHudsonTestCase.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.jvnet.hudson.test; - -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import groovy.lang.Closure; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.tasks.Builder; -import hudson.Launcher; - -import java.util.concurrent.Callable; -import java.io.IOException; - -/** - * {@link HudsonTestCase} with more convenience methods for Groovy. - * - * @author Kohsuke Kawaguchi - * @deprecated Use {@link GroovyJenkinsRule} instead. - */ -@Deprecated -public abstract class GroovyHudsonTestCase extends HudsonTestCase { - /** - * Executes the given closure on the server, in the context of an HTTP request. - * This is useful for testing some methods that require {@link StaplerRequest} and {@link StaplerResponse}. - * - *

    - * The closure will get the request and response as parameters. - */ - public Object executeOnServer(final Closure c) throws Exception { - return executeOnServer(new Callable() { - public Object call() throws Exception { - return c.call(); - } - }); - } - - /** - * Wraps a closure as a {@link Builder}. - */ - public Builder builder(final Closure c) { - return new TestBuilder() { - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - Object r = c.call(new Object[]{build,launcher,listener}); - if (r instanceof Boolean) return (Boolean)r; - return true; - } - }; - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/GroovyJenkinsRule.java b/test/src/main/java/org/jvnet/hudson/test/GroovyJenkinsRule.java deleted file mode 100644 index 3c20aa713577a9fcaefadf4140e26ccedd1bcecf..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/GroovyJenkinsRule.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * The MIT License - * - * Copyright 2013 Jesse Glick. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package org.jvnet.hudson.test; - -import groovy.lang.Closure; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.BuildListener; -import hudson.tasks.Builder; -import java.io.IOException; -import java.util.concurrent.Callable; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -/** - * {@link JenkinsRule} variant with special options for tests written in Groovy. - * @since 1.535 - */ -public class GroovyJenkinsRule extends JenkinsRule { - - /** - * Executes the given closure on the server, in the context of an HTTP request. - * This is useful for testing some methods that require {@link StaplerRequest} and {@link StaplerResponse}. - * - *

    - * The closure will get the request and response as parameters. - */ - public Object executeOnServer(final Closure c) throws Exception { - return executeOnServer(new Callable() { - @Override public Object call() throws Exception { - return c.call(); - } - }); - } - - /** - * Wraps a closure as a {@link Builder}. - */ - public Builder builder(final Closure c) { - return new TestBuilder() { - @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - Object r = c.call(new Object[] {build, launcher, listener}); - if (r instanceof Boolean) { - return (Boolean) r; - } - return true; - } - }; - } - -} diff --git a/test/src/main/java/org/jvnet/hudson/test/HudsonHomeLoader.java b/test/src/main/java/org/jvnet/hudson/test/HudsonHomeLoader.java deleted file mode 100644 index 303de9593ee947c6e02a5b71f55fc7bbeca4a978..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/HudsonHomeLoader.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import hudson.FilePath; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; - -/** - * Controls how a {@link HudsonTestCase} initializes JENKINS_HOME. - * - * @author Kohsuke Kawaguchi - */ -public interface HudsonHomeLoader { - /** - * Returns a directory to be used as JENKINS_HOME - * - * @throws Exception - * to cause a test to fail. - */ - File allocate() throws Exception; - - /** - * Allocates a new empty directory, meaning this will emulate the fresh Hudson installation. - */ - HudsonHomeLoader NEW = new HudsonHomeLoader() { - public File allocate() throws IOException { - return TestEnvironment.get().temporaryDirectoryAllocator.allocate(); - } - }; - - /** - * Allocates a new directory by copying from an existing directory, or unzipping from a zip file. - */ - final class CopyExisting implements HudsonHomeLoader { - private final URL source; - - /** - * Either a zip file or a directory that contains the home image. - */ - public CopyExisting(File source) throws MalformedURLException { - this(source.toURI().toURL()); - } - - /** - * Extracts from a zip file in the resource. - * - *

    - * This is useful in case you want to have a test data in the resources. - * Only file URL is supported. - */ - public CopyExisting(URL source) { - this.source = source; - } - - public File allocate() throws Exception { - File target = NEW.allocate(); - if(source.getProtocol().equals("file")) { - File src = new File(source.toURI()); - if(src.isDirectory()) - new FilePath(src).copyRecursiveTo("**/*",new FilePath(target)); - else - if(src.getName().endsWith(".zip")) - new FilePath(src).unzip(new FilePath(target)); - } else { - File tmp = File.createTempFile("hudson","zip"); - try { - FileUtils.copyURLToFile(source,tmp); - new FilePath(tmp).unzip(new FilePath(target)); - } finally { - tmp.delete(); - } - } - return target; - } - } - - /** - * Allocates a new directory by copying from a test resource - */ - final class Local implements HudsonHomeLoader { - private final Method testMethod; - - public Local(Method testMethod) { - this.testMethod = testMethod; - } - - public File allocate() throws Exception { - URL res = findDataResource(); - if(!res.getProtocol().equals("file")) - throw new AssertionError("Test data is not available in the file system: "+res); - // if we picked up a directory, it's one level above config.xml - File home = new File(res.toURI()); - if(!home.getName().endsWith(".zip")) - home = home.getParentFile(); - - return new CopyExisting(home).allocate(); - } - - private URL findDataResource() { - // first, check method specific resource - Class clazz = testMethod.getDeclaringClass(); - - for( String middle : new String[]{ '/'+testMethod.getName(), "" }) { - for( String suffix : SUFFIXES ) { - URL res = clazz.getResource(clazz.getSimpleName() + middle+suffix); - if(res!=null) return res; - } - } - - throw new AssertionError("No test resource was found for "+testMethod); - } - - private static final String[] SUFFIXES = {"/config.xml",".zip"}; - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java b/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java deleted file mode 100644 index 066ce52cea488a2dbc58ee8ed70bf54183759ffc..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/HudsonTestCase.java +++ /dev/null @@ -1,2061 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2011, Sun Microsystems, Inc., Kohsuke Kawaguchi, Erik Ramfelt, - * Yahoo! Inc., Tom Huybrechts, Olivier Lamy - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import com.gargoylesoftware.htmlunit.AlertHandler; -import com.gargoylesoftware.htmlunit.html.HtmlImage; -import com.google.inject.Injector; - -import hudson.ClassicPluginStrategy; -import hudson.CloseProofOutputStream; -import hudson.DNSMultiCast; -import hudson.DescriptorExtensionList; -import hudson.EnvVars; -import hudson.Extension; -import hudson.ExtensionList; -import hudson.FilePath; -import hudson.Functions; -import hudson.Functions.ThreadGroupMap; -import hudson.Launcher; -import hudson.Launcher.LocalLauncher; -import hudson.Main; -import hudson.PluginManager; -import hudson.Util; -import hudson.WebAppMain; -import hudson.matrix.MatrixBuild; -import hudson.matrix.MatrixProject; -import hudson.matrix.MatrixRun; -import hudson.maven.MavenBuild; -import hudson.maven.MavenEmbedder; -import hudson.maven.MavenEmbedderException; -import hudson.maven.MavenModule; -import hudson.maven.MavenModuleSet; -import hudson.maven.MavenModuleSetBuild; -import hudson.maven.MavenUtil; -import hudson.model.*; -import hudson.model.Executor; -import hudson.model.Node.Mode; -import hudson.model.Queue.Executable; -import hudson.os.PosixAPI; -import hudson.remoting.Which; -import hudson.security.ACL; -import hudson.security.AbstractPasswordBasedSecurityRealm; -import hudson.security.GroupDetails; -import hudson.security.SecurityRealm; -import hudson.security.csrf.CrumbIssuer; -import hudson.slaves.CommandLauncher; -import hudson.slaves.ComputerConnector; -import hudson.slaves.ComputerListener; -import hudson.slaves.DumbSlave; -import hudson.slaves.NodeProperty; -import hudson.slaves.RetentionStrategy; -import hudson.tasks.Ant; -import hudson.tasks.Ant.AntInstallation; -import hudson.tasks.BuildWrapper; -import hudson.tasks.BuildWrapperDescriptor; -import hudson.tasks.Builder; -import hudson.tasks.Mailer; -import hudson.tasks.Maven; -import hudson.tasks.Maven.MavenInstallation; -import hudson.tasks.Publisher; -import hudson.tools.ToolProperty; -import hudson.util.PersistedList; -import hudson.util.ReflectionUtils; -import hudson.util.StreamTaskListener; - -import java.beans.PropertyDescriptor; -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.annotation.Annotation; -import java.lang.management.ThreadInfo; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.net.URLClassLoader; -import java.net.URLConnection; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.concurrent.*; -import java.util.jar.Manifest; -import java.util.logging.Filter; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; - -import jenkins.model.Jenkins; -import jenkins.model.JenkinsAdaptor; -import junit.framework.TestCase; -import net.sf.json.JSONObject; -import net.sourceforge.htmlunit.corejs.javascript.Context; -import net.sourceforge.htmlunit.corejs.javascript.ContextFactory.Listener; - -import org.acegisecurity.AuthenticationException; -import org.acegisecurity.BadCredentialsException; -import org.acegisecurity.GrantedAuthority; -import org.acegisecurity.userdetails.UserDetails; -import org.acegisecurity.userdetails.UsernameNotFoundException; -import org.apache.commons.beanutils.PropertyUtils; -import org.apache.commons.httpclient.NameValuePair; -import org.apache.commons.io.FileUtils; -import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException; -import org.codehaus.plexus.component.repository.exception.ComponentLookupException; -import org.jvnet.hudson.test.HudsonHomeLoader.CopyExisting; -import org.jvnet.hudson.test.recipes.Recipe; -import org.jvnet.hudson.test.recipes.Recipe.Runner; -import org.jvnet.hudson.test.recipes.WithPlugin; -import org.jvnet.hudson.test.rhino.JavaScriptDebugger; -import org.kohsuke.stapler.ClassDescriptor; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.Dispatcher; -import org.kohsuke.stapler.MetaClass; -import org.kohsuke.stapler.MetaClassLoader; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import org.mortbay.jetty.MimeTypes; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.bio.SocketConnector; -import org.mortbay.jetty.security.HashUserRealm; -import org.mortbay.jetty.security.UserRealm; -import org.mortbay.jetty.webapp.Configuration; -import org.mortbay.jetty.webapp.WebAppContext; -import org.mortbay.jetty.webapp.WebXmlConfiguration; -import org.mozilla.javascript.tools.debugger.Dim; -import org.mozilla.javascript.tools.shell.Global; -import org.springframework.dao.DataAccessException; -import org.w3c.css.sac.CSSException; -import org.w3c.css.sac.CSSParseException; -import org.w3c.css.sac.ErrorHandler; -import org.xml.sax.SAXException; - -import com.gargoylesoftware.htmlunit.AjaxController; -import com.gargoylesoftware.htmlunit.BrowserVersion; -import com.gargoylesoftware.htmlunit.DefaultCssErrorHandler; -import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException; -import com.gargoylesoftware.htmlunit.Page; -import com.gargoylesoftware.htmlunit.WebRequestSettings; -import com.gargoylesoftware.htmlunit.html.DomNode; -import com.gargoylesoftware.htmlunit.html.HtmlButton; -import com.gargoylesoftware.htmlunit.html.HtmlElement; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlInput; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.gargoylesoftware.htmlunit.javascript.HtmlUnitContextFactory; -import com.gargoylesoftware.htmlunit.javascript.host.xml.XMLHttpRequest; -import com.gargoylesoftware.htmlunit.xml.XmlPage; - -import java.net.HttpURLConnection; - -import jenkins.model.JenkinsLocationConfiguration; - -/** - * Base class for all Jenkins test cases. - * - * @see Wiki article about unit testing in Hudson - * @author Kohsuke Kawaguchi - * @deprecated New code should use {@link JenkinsRule}. - */ -@Deprecated -@SuppressWarnings("rawtypes") -public abstract class HudsonTestCase extends TestCase implements RootAction { - /** - * Points to the same object as {@link #jenkins} does. - */ - public Hudson hudson; - - public Jenkins jenkins; - - protected final TestEnvironment env = new TestEnvironment(this); - protected HudsonHomeLoader homeLoader = HudsonHomeLoader.NEW; - /** - * TCP/IP port that the server is listening on. - */ - protected int localPort; - protected Server server; - - /** - * Where in the {@link Server} is Hudson deployed? - *

    - * Just like {@link ServletContext#getContextPath()}, starts with '/' but doesn't end with '/'. - */ - protected String contextPath = ""; - - /** - * {@link Runnable}s to be invoked at {@link #tearDown()}. - */ - protected List tearDowns = new ArrayList(); - - protected List recipes = new ArrayList(); - - /** - * Remember {@link WebClient}s that are created, to release them properly. - */ - private List clients = new ArrayList(); - - /** - * JavaScript "debugger" that provides you information about the JavaScript call stack - * and the current values of the local variables in those stack frame. - * - *

    - * Unlike Java debugger, which you as a human interfaces directly and interactively, - * this JavaScript debugger is to be interfaced by your program (or through the - * expression evaluation capability of your Java debugger.) - */ - protected JavaScriptDebugger jsDebugger = new JavaScriptDebugger(); - - /** - * If this test case has additional {@link WithPlugin} annotations, set to true. - * This will cause a fresh {@link PluginManager} to be created for this test. - * Leaving this to false enables the test harness to use a pre-loaded plugin manager, - * which runs faster. - * - * @deprecated - * Use {@link #pluginManager} - */ - public boolean useLocalPluginManager; - - /** - * Number of seconds until the test times out. - */ - public int timeout = Integer.getInteger("jenkins.test.timeout", 180); - - private volatile Timer timeoutTimer; - - /** - * Set the plugin manager to be passed to {@link Jenkins} constructor. - * - * For historical reasons, {@link #useLocalPluginManager}==true will take the precedence. - */ - private PluginManager pluginManager = TestPluginManager.INSTANCE; - - public ComputerConnectorTester computerConnectorTester = new ComputerConnectorTester(this); - - /** - * The directory where a war file gets exploded. - */ - protected File explodedWarDir; - - private boolean origDefaultUseCache = true; - - protected HudsonTestCase(String name) { - super(name); - } - - protected HudsonTestCase() { - } - - @Override - public void runBare() throws Throwable { - // override the thread name to make the thread dump more useful. - Thread t = Thread.currentThread(); - String o = getClass().getName()+'.'+t.getName(); - t.setName("Executing "+getName()); - try { - super.runBare(); - } finally { - t.setName(o); - } - } - - @Override - protected void setUp() throws Exception { - if(Functions.isWindows()) { - // JENKINS-4409. - // URLConnection caches handles to jar files by default, - // and it prevents delete temporary directories on Windows. - // Disables caching here. - // Though defaultUseCache is a static field, - // its setter and getter are provided as instance methods. - URLConnection aConnection = new File(".").toURI().toURL().openConnection(); - origDefaultUseCache = aConnection.getDefaultUseCaches(); - aConnection.setDefaultUseCaches(false); - } - - env.pin(); - recipe(); - for (Runner r : recipes) { - if (r instanceof WithoutJenkins.RunnerImpl) - return; // no setup - } - AbstractProject.WORKSPACE.toString(); - User.clear(); - - // just in case tearDown failed in the middle, make sure to really clean them up so that there's no left-over from earlier tests - ExtensionList.clearLegacyInstances(); - DescriptorExtensionList.clearLegacyInstances(); - - try { - jenkins = hudson = newHudson(); - } catch (Exception e) { - // if Jenkins instance fails to initialize, it leaves the instance field non-empty and break all the rest of the tests, so clean that up. - Field f = Jenkins.class.getDeclaredField("theInstance"); - f.setAccessible(true); - f.set(null,null); - throw e; - } - jenkins.setNoUsageStatistics(true); // collecting usage stats from tests are pointless. - - jenkins.setCrumbIssuer(new TestCrumbIssuer()); - - jenkins.servletContext.setAttribute("app", jenkins); - jenkins.servletContext.setAttribute("version","?"); - WebAppMain.installExpressionFactory(new ServletContextEvent(jenkins.servletContext)); - Mailer.descriptor().setHudsonUrl(getURL().toExternalForm()); // for compatibility only - JenkinsLocationConfiguration.get().setUrl(getURL().toString()); // in case we are using older mailer plugin - - // set a default JDK to be the one that the harness is using. - jenkins.getJDKs().add(new JDK("default",System.getProperty("java.home"))); - - configureUpdateCenter(); - - // expose the test instance as a part of URL tree. - // this allows tests to use a part of the URL space for itself. - jenkins.getActions().add(this); - - // cause all the descriptors to reload. - // ideally we'd like to reset them to properly emulate the behavior, but that's not possible. - for( Descriptor d : jenkins.getExtensionList(Descriptor.class) ) - d.load(); - - // allow the test class to inject Jenkins components - jenkins.lookup(Injector.class).injectMembers(this); - - setUpTimeout(); - } - - protected void setUpTimeout() { - if (timeout<=0) return; // no timeout - - final Thread testThread = Thread.currentThread(); - timeoutTimer = new Timer(); - timeoutTimer.schedule(new TimerTask() { - @Override - public void run() { - if (timeoutTimer!=null) { - LOGGER.warning(String.format("Test timed out (after %d seconds).", timeout)); - testThread.interrupt(); - } - } - }, TimeUnit.SECONDS.toMillis(timeout)); - } - - - /** - * Configures the update center setting for the test. - * By default, we load updates from local proxy to avoid network traffic as much as possible. - */ - protected void configureUpdateCenter() throws Exception { - final String updateCenterUrl = "http://localhost:"+ JavaNetReverseProxy.getInstance().localPort+"/update-center.json"; - - // don't waste bandwidth talking to the update center - DownloadService.neverUpdate = true; - UpdateSite.neverUpdate = true; - - PersistedList sites = jenkins.getUpdateCenter().getSites(); - sites.clear(); - sites.add(new UpdateSite("default", updateCenterUrl)); - } - - @Override - protected void tearDown() throws Exception { - try { - if (jenkins!=null) { - for (EndOfTestListener tl : jenkins.getExtensionList(EndOfTestListener.class)) - tl.onTearDown(); - } - - if (timeoutTimer!=null) { - timeoutTimer.cancel(); - timeoutTimer = null; - } - - // cancel pending asynchronous operations, although this doesn't really seem to be working - for (WebClient client : clients) { - // unload the page to cancel asynchronous operations - client.getPage("about:blank"); - client.closeAllWindows(); - } - clients.clear(); - } finally { - if (server!=null) - server.stop(); - for (LenientRunnable r : tearDowns) - r.run(); - - if (jenkins!=null) - jenkins.cleanUp(); - ExtensionList.clearLegacyInstances(); - DescriptorExtensionList.clearLegacyInstances(); - - try { - env.dispose(); - } catch (Exception x) { - x.printStackTrace(); - } - - // Jenkins creates ClassLoaders for plugins that hold on to file descriptors of its jar files, - // but because there's no explicit dispose method on ClassLoader, they won't get GC-ed until - // at some later point, leading to possible file descriptor overflow. So encourage GC now. - // see http://bugs.sun.com/view_bug.do?bug_id=4950148 - System.gc(); - - // restore defaultUseCache - if(Functions.isWindows()) { - URLConnection aConnection = new File(".").toURI().toURL().openConnection(); - aConnection.setDefaultUseCaches(origDefaultUseCache); - } - } - } - - @Override - protected void runTest() throws Throwable { - System.out.println("=== Starting "+ getClass().getSimpleName() + "." + getName()); - // so that test code has all the access to the system - ACL.impersonate(ACL.SYSTEM); - - try { - super.runTest(); - } catch (Throwable t) { - // allow the late attachment of a debugger in case of a failure. Useful - // for diagnosing a rare failure - try { - throw new BreakException(); - } catch (BreakException e) {} - - // dump threads - ThreadInfo[] threadInfos = Functions.getThreadInfos(); - ThreadGroupMap m = Functions.sortThreadsAndGetGroupMap(threadInfos); - for (ThreadInfo ti : threadInfos) { - System.err.println(Functions.dumpThreadInfo(ti, m)); - } - throw t; - } - } - - @SuppressWarnings("serial") - public static class BreakException extends Exception {} - - public String getIconFileName() { - return null; - } - - public String getDisplayName() { - return null; - } - - public String getUrlName() { - return "self"; - } - - /** - * Creates a new instance of {@link jenkins.model.Jenkins}. If the derived class wants to create it in a different way, - * you can override it. - */ - protected Hudson newHudson() throws Exception { - File home = homeLoader.allocate(); - for (Runner r : recipes) - r.decorateHome(this,home); - return new Hudson(home, createWebServer(), useLocalPluginManager ? null : pluginManager); - } - - /** - * Sets the {@link PluginManager} to be used when creating a new {@link Jenkins} instance. - * - * @param pluginManager - * null to let Jenkins create a new instance of default plugin manager, like it normally does when running as a webapp outside the test. - */ - public void setPluginManager(PluginManager pluginManager) { - this.useLocalPluginManager = false; - this.pluginManager = pluginManager; - if (jenkins !=null) - throw new IllegalStateException("Too late to override the plugin manager"); - } - - /** - * Prepares a webapp hosting environment to get {@link ServletContext} implementation - * that we need for testing. - */ - protected ServletContext createWebServer() throws Exception { - server = new Server(); - - explodedWarDir = WarExploder.getExplodedDir(); - WebAppContext context = new WebAppContext(explodedWarDir.getPath(), contextPath); - context.setClassLoader(getClass().getClassLoader()); - context.setConfigurations(new Configuration[]{new WebXmlConfiguration(), new NoListenerConfiguration()}); - server.setHandler(context); - context.setMimeTypes(MIME_TYPES); - - SocketConnector connector = new SocketConnector(); - connector.setHeaderBufferSize(12*1024); // use a bigger buffer as Stapler traces can get pretty large on deeply nested URL - - server.setThreadPool(new ThreadPoolImpl(new ThreadPoolExecutor(10, 10, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue(),new ThreadFactory() { - public Thread newThread(Runnable r) { - Thread t = new Thread(r); - t.setName("Jetty Thread Pool"); - return t; - } - }))); - server.addConnector(connector); - server.addUserRealm(configureUserRealm()); - server.start(); - - localPort = connector.getLocalPort(); - - return context.getServletContext(); - } - - /** - * Configures a security realm for a test. - */ - protected UserRealm configureUserRealm() { - HashUserRealm realm = new HashUserRealm(); - realm.setName("default"); // this is the magic realm name to make it effective on everywhere - realm.put("alice","alice"); - realm.put("bob","bob"); - realm.put("charlie","charlie"); - - realm.addUserToRole("alice","female"); - realm.addUserToRole("bob","male"); - realm.addUserToRole("charlie","male"); - - return realm; - } - - /** - * Returns the older default Maven, while still allowing specification of other bundled Mavens. - */ - protected MavenInstallation configureDefaultMaven() throws Exception { - return configureDefaultMaven("apache-maven-2.2.1", MavenInstallation.MAVEN_20); - } - - protected MavenInstallation configureMaven3() throws Exception { - MavenInstallation mvn = configureDefaultMaven("apache-maven-3.0.1", MavenInstallation.MAVEN_30); - - MavenInstallation m3 = new MavenInstallation("apache-maven-3.0.1",mvn.getHome(), NO_PROPERTIES); - jenkins.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(m3); - return m3; - } - - protected MavenInstallation configureMaven31() throws Exception { - MavenInstallation mvn = configureDefaultMaven("apache-maven-3.1.0", MavenInstallation.MAVEN_30); - - MavenInstallation m3 = new MavenInstallation("apache-maven-3.1.0",mvn.getHome(), NO_PROPERTIES); - jenkins.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(m3); - return m3; - } - - /** - * Locates Maven and configures that as the only Maven in the system. - */ - protected MavenInstallation configureDefaultMaven(String mavenVersion, int mavenReqVersion) throws Exception { - // Does it exists in the buildDirectory - i.e. already extracted from previous test? - // defined in jenkins-test-harness POM, but not plugins; TODO should not use relative paths as we do not know what CWD is - File buildDirectory = new File(System.getProperty("buildDirectory", "target")); - File mvnHome = new File(buildDirectory, mavenVersion); - if (mvnHome.exists()) { - MavenInstallation mavenInstallation = new MavenInstallation("default", mvnHome.getAbsolutePath(), NO_PROPERTIES); - jenkins.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(mavenInstallation); - return mavenInstallation; - } - - // Does maven.home point to a Maven installation which satisfies mavenReqVersion? - String home = System.getProperty("maven.home"); - if(home!=null) { - MavenInstallation mavenInstallation = new MavenInstallation("default",home, NO_PROPERTIES); - if (mavenInstallation.meetsMavenReqVersion(createLocalLauncher(), mavenReqVersion)) { - jenkins.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(mavenInstallation); - return mavenInstallation; - } - } - - // otherwise extract the copy we have. - // this happens when a test is invoked from an IDE, for example. - LOGGER.warning("Extracting a copy of Maven bundled in the test harness into " + mvnHome + ". " + - "To avoid a performance hit, set the system property 'maven.home' to point to a Maven2 installation."); - FilePath mvn = jenkins.getRootPath().createTempFile("maven", "zip"); - mvn.copyFrom(HudsonTestCase.class.getClassLoader().getResource(mavenVersion + "-bin.zip")); - mvn.unzip(new FilePath(buildDirectory)); - // TODO: switch to tar that preserves file permissions more easily - if(!Functions.isWindows()) { - PosixAPI.jnr().chmod(new File(mvnHome, "bin/mvn").getPath(), 0755); - } - - MavenInstallation mavenInstallation = new MavenInstallation("default", - mvnHome.getAbsolutePath(), NO_PROPERTIES); - jenkins.getDescriptorByType(Maven.DescriptorImpl.class).setInstallations(mavenInstallation); - return mavenInstallation; - } - - /** - * Extracts Ant and configures it. - */ - protected Ant.AntInstallation configureDefaultAnt() throws Exception { - Ant.AntInstallation antInstallation; - if (System.getenv("ANT_HOME") != null) { - antInstallation = new AntInstallation("default", System.getenv("ANT_HOME"), NO_PROPERTIES); - } else { - LOGGER.warning("Extracting a copy of Ant bundled in the test harness. " + - "To avoid a performance hit, set the environment variable ANT_HOME to point to an Ant installation."); - FilePath ant = jenkins.getRootPath().createTempFile("ant", "zip"); - ant.copyFrom(HudsonTestCase.class.getClassLoader().getResource("apache-ant-1.8.1-bin.zip")); - File antHome = createTmpDir(); - ant.unzip(new FilePath(antHome)); - // TODO: switch to tar that preserves file permissions more easily - if(!Functions.isWindows()) { - PosixAPI.jnr().chmod(new File(antHome,"apache-ant-1.8.1/bin/ant").getPath(),0755); - } - - antInstallation = new AntInstallation("default", new File(antHome,"apache-ant-1.8.1").getAbsolutePath(),NO_PROPERTIES); - } - jenkins.getDescriptorByType(Ant.DescriptorImpl.class).setInstallations(antInstallation); - return antInstallation; - } - -// -// Convenience methods -// - - protected FreeStyleProject createFreeStyleProject() throws IOException { - return createFreeStyleProject(createUniqueProjectName()); - } - - protected FreeStyleProject createFreeStyleProject(String name) throws IOException { - return jenkins.createProject(FreeStyleProject.class, name); - } - - protected MatrixProject createMatrixProject() throws IOException { - return createMatrixProject(createUniqueProjectName()); - } - - protected MatrixProject createMatrixProject(String name) throws IOException { - return jenkins.createProject(MatrixProject.class, name); - } - - /** - * Creates a empty Maven project with an unique name. - * - * @see #configureDefaultMaven() - */ - protected MavenModuleSet createMavenProject() throws IOException { - return createMavenProject(createUniqueProjectName()); - } - - /** - * Creates a empty Maven project with the given name. - * - * @see #configureDefaultMaven() - */ - protected MavenModuleSet createMavenProject(String name) throws IOException { - MavenModuleSet mavenModuleSet = jenkins.createProject(MavenModuleSet.class,name); - mavenModuleSet.setRunHeadless( true ); - return mavenModuleSet; - } - - protected String createUniqueProjectName() { - return "test"+ jenkins.getItems().size(); - } - - /** - * Creates {@link LocalLauncher}. Useful for launching processes. - */ - protected LocalLauncher createLocalLauncher() { - return new LocalLauncher(StreamTaskListener.fromStdout()); - } - - /** - * Allocates a new temporary directory for the duration of this test. - */ - public File createTmpDir() throws IOException { - return env.temporaryDirectoryAllocator.allocate(); - } - - public DumbSlave createSlave() throws Exception { - return createSlave("",null); - } - - /** - * Creates and launches a new slave on the local host. - */ - public DumbSlave createSlave(Label l) throws Exception { - return createSlave(l, null); - } - - /** - * Creates a test {@link SecurityRealm} that recognizes username==password as valid. - */ - public SecurityRealm createDummySecurityRealm() { - return new AbstractPasswordBasedSecurityRealm() { - @Override - protected UserDetails authenticate(String username, String password) throws AuthenticationException { - if (username.equals(password)) - return loadUserByUsername(username); - throw new BadCredentialsException(username); - } - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { - return new org.acegisecurity.userdetails.User(username,"",true,true,true,true,new GrantedAuthority[]{AUTHENTICATED_AUTHORITY}); - } - - @Override - public GroupDetails loadGroupByGroupname(String groupname) throws UsernameNotFoundException, DataAccessException { - throw new UsernameNotFoundException(groupname); - } - }; - } - - /** - * Returns the URL of the webapp top page. - * URL ends with '/'. - */ - public URL getURL() throws IOException { - return new URL("http://localhost:"+localPort+contextPath+"/"); - } - - public DumbSlave createSlave(EnvVars env) throws Exception { - return createSlave("",env); - } - - public DumbSlave createSlave(Label l, EnvVars env) throws Exception { - return createSlave(l==null ? null : l.getExpression(), env); - } - - /** - * Creates a slave with certain additional environment variables - */ - public DumbSlave createSlave(String labels, EnvVars env) throws Exception { - synchronized (jenkins) { - int sz = jenkins.getNodes().size(); - return createSlave("slave" + sz,labels,env); - } - } - - public DumbSlave createSlave(String nodeName, String labels, EnvVars env) throws Exception { - synchronized (jenkins) { - DumbSlave slave = new DumbSlave(nodeName, "dummy", - createTmpDir().getPath(), "1", Mode.NORMAL, labels==null?"":labels, createComputerLauncher(env), - RetentionStrategy.NOOP, Collections.>emptyList()); - jenkins.addNode(slave); - return slave; - } - } - - public PretendSlave createPretendSlave(FakeLauncher faker) throws Exception { - synchronized (jenkins) { - int sz = jenkins.getNodes().size(); - PretendSlave slave = new PretendSlave("slave" + sz, createTmpDir().getPath(), "", createComputerLauncher(null), faker); - jenkins.addNode(slave); - return slave; - } - } - - /** - * Creates a {@link CommandLauncher} for launching a slave locally. - * - * @param env - * Environment variables to add to the slave process. Can be null. - */ - public CommandLauncher createComputerLauncher(EnvVars env) throws URISyntaxException, MalformedURLException { - int sz = jenkins.getNodes().size(); - return new CommandLauncher( - String.format("\"%s/bin/java\" %s -jar \"%s\"", - System.getProperty("java.home"), - SLAVE_DEBUG_PORT>0 ? " -Xdebug -Xrunjdwp:transport=dt_socket,server=y,address="+(SLAVE_DEBUG_PORT+sz): "", - new File(jenkins.getJnlpJars("slave.jar").getURL().toURI()).getAbsolutePath()), - env); - } - - /** - * Create a new slave on the local host and wait for it to come onilne - * before returning. - */ - public DumbSlave createOnlineSlave() throws Exception { - return createOnlineSlave(null); - } - - /** - * Create a new slave on the local host and wait for it to come onilne - * before returning. - */ - public DumbSlave createOnlineSlave(Label l) throws Exception { - return createOnlineSlave(l, null); - } - - /** - * Create a new slave on the local host and wait for it to come online - * before returning - */ - @SuppressWarnings("deprecation") - public DumbSlave createOnlineSlave(Label l, EnvVars env) throws Exception { - final CountDownLatch latch = new CountDownLatch(1); - ComputerListener waiter = new ComputerListener() { - @Override - public void onOnline(Computer C, TaskListener t) { - latch.countDown(); - unregister(); - } - }; - waiter.register(); - - DumbSlave s = createSlave(l, env); - latch.await(); - - return s; - } - - /** - * Blocks until the ENTER key is hit. - * This is useful during debugging a test so that one can inspect the state of Jenkins through the web browser. - */ - public void interactiveBreak() throws Exception { - System.out.println("Jenkins is running at http://localhost:"+localPort+"/"); - new BufferedReader(new InputStreamReader(System.in)).readLine(); - } - - /** - * Returns the last item in the list. - */ - protected T last(List items) { - return items.get(items.size()-1); - } - - /** - * Pauses the execution until ENTER is hit in the console. - *

    - * This is often very useful so that you can interact with Hudson - * from an browser, while developing a test case. - */ - protected void pause() throws IOException { - new BufferedReader(new InputStreamReader(System.in)).readLine(); - } - - /** - * Performs a search from the search box. - */ - protected Page search(String q) throws Exception { - return new WebClient().search(q); - } - - /** - * Hits the Hudson system configuration and submits without any modification. - */ - protected void configRoundtrip() throws Exception { - submit(createWebClient().goTo("configure").getFormByName("config")); - } - - /** - * Loads a configuration page and submits it without any modifications, to - * perform a round-trip configuration test. - *

    - * See http://wiki.jenkins-ci.org/display/JENKINS/Unit+Test#UnitTest-Configurationroundtriptesting - */ - protected

    P configRoundtrip(P job) throws Exception { - submit(createWebClient().getPage(job,"configure").getFormByName("config")); - return job; - } - - protected

    P configRoundtrip(P job) throws Exception { - submit(createWebClient().getPage(job, "configure").getFormByName("config")); - return job; - } - - /** - * Performs a configuration round-trip testing for a builder. - */ - @SuppressWarnings("unchecked") - protected B configRoundtrip(B before) throws Exception { - FreeStyleProject p = createFreeStyleProject(); - p.getBuildersList().add(before); - configRoundtrip((Item)p); - return (B)p.getBuildersList().get(before.getClass()); - } - - /** - * Performs a configuration round-trip testing for a publisher. - */ - @SuppressWarnings("unchecked") - protected

    P configRoundtrip(P before) throws Exception { - FreeStyleProject p = createFreeStyleProject(); - p.getPublishersList().add(before); - configRoundtrip((Item) p); - return (P)p.getPublishersList().get(before.getClass()); - } - - @SuppressWarnings("unchecked") - protected C configRoundtrip(C before) throws Exception { - computerConnectorTester.connector = before; - submit(createWebClient().goTo("self/computerConnectorTester/configure").getFormByName("config")); - return (C)computerConnectorTester.connector; - } - - protected User configRoundtrip(User u) throws Exception { - submit(createWebClient().goTo(u.getUrl()+"/configure").getFormByName("config")); - return u; - } - - @SuppressWarnings("unchecked") - protected N configRoundtrip(N node) throws Exception { - submit(createWebClient().goTo("/computer/" + node.getNodeName() + "/configure").getFormByName("config")); - return (N) jenkins.getNode(node.getNodeName()); - } - - protected V configRoundtrip(V view) throws Exception { - submit(createWebClient().getPage(view, "configure").getFormByName("viewConfig")); - return view; - } - - - /** - * Asserts that the outcome of the build is a specific outcome. - */ - public R assertBuildStatus(Result status, R r) throws Exception { - if(status==r.getResult()) - return r; - - // dump the build output in failure message - String msg = "unexpected build status; build log was:\n------\n" + getLog(r) + "\n------\n"; - if(r instanceof MatrixBuild) { - MatrixBuild mb = (MatrixBuild)r; - for (MatrixRun mr : mb.getRuns()) { - msg+="--- "+mr.getParent().getCombination()+" ---\n"+getLog(mr)+"\n------\n"; - } - } - assertEquals(msg, status,r.getResult()); - return r; - } - - /** Determines whether the specified HTTP status code is generally "good" */ - public boolean isGoodHttpStatus(int status) { - if ((400 <= status) && (status <= 417)) { - return false; - } - if ((500 <= status) && (status <= 505)) { - return false; - } - return true; - } - - /** Assert that the specified page can be served with a "good" HTTP status, - * eg, the page is not missing and can be served without a server error - * @param page - */ - public void assertGoodStatus(Page page) { - assertTrue(isGoodHttpStatus(page.getWebResponse().getStatusCode())); - } - - - public R assertBuildStatusSuccess(R r) throws Exception { - assertBuildStatus(Result.SUCCESS, r); - return r; - } - - public R assertBuildStatusSuccess(Future r) throws Exception { - assertNotNull("build was actually scheduled", r); - return assertBuildStatusSuccess(r.get()); - } - - public ,R extends AbstractBuild> R buildAndAssertSuccess(J job) throws Exception { - return assertBuildStatusSuccess(job.scheduleBuild2(0)); - } - - /** - * Avoids need for cumbersome {@code this.buildAndAssertSuccess(...)} type hints under JDK 7 javac (and supposedly also IntelliJ). - */ - public FreeStyleBuild buildAndAssertSuccess(FreeStyleProject job) throws Exception { - return assertBuildStatusSuccess(job.scheduleBuild2(0)); - } - public MavenModuleSetBuild buildAndAssertSuccess(MavenModuleSet job) throws Exception { - return assertBuildStatusSuccess(job.scheduleBuild2(0)); - } - public MavenBuild buildAndAssertSuccess(MavenModule job) throws Exception { - return assertBuildStatusSuccess(job.scheduleBuild2(0)); - } - - /** - * Asserts that the console output of the build contains the given substring. - */ - public void assertLogContains(String substring, Run run) throws Exception { - String log = getLog(run); - assertTrue("Console output of "+run+" didn't contain "+substring+":\n"+log,log.contains(substring)); - } - - /** - * Asserts that the console output of the build does not contain the given substring. - */ - public void assertLogNotContains(String substring, Run run) throws Exception { - String log = getLog(run); - assertFalse("Console output of "+run+" contains "+substring+":\n"+log,log.contains(substring)); - } - - /** - * Get entire log file (this method is deprecated in hudson.model.Run, - * but in tests it is OK to load entire log). - */ - protected static String getLog(Run run) throws IOException { - return Util.loadFile(run.getLogFile(), run.getCharset()); - } - - /** - * Asserts that the XPath matches. - */ - public void assertXPath(HtmlPage page, String xpath) { - assertNotNull("There should be an object that matches XPath:" + xpath, - page.getDocumentElement().selectSingleNode(xpath)); - } - - /** Asserts that the XPath matches the contents of a DomNode page. This - * variant of assertXPath(HtmlPage page, String xpath) allows us to - * examine XmlPages. - * @param page - * @param xpath - */ - public void assertXPath(DomNode page, String xpath) { - List< ? extends Object> nodes = page.getByXPath(xpath); - assertFalse("There should be an object that matches XPath:" + xpath, nodes.isEmpty()); - } - - public void assertXPathValue(DomNode page, String xpath, String expectedValue) { - Object node = page.getFirstByXPath(xpath); - assertNotNull("no node found", node); - assertTrue("the found object was not a Node " + xpath, node instanceof org.w3c.dom.Node); - - org.w3c.dom.Node n = (org.w3c.dom.Node) node; - String textString = n.getTextContent(); - assertEquals("xpath value should match for " + xpath, expectedValue, textString); - } - - public void assertXPathValueContains(DomNode page, String xpath, String needle) { - Object node = page.getFirstByXPath(xpath); - assertNotNull("no node found", node); - assertTrue("the found object was not a Node " + xpath, node instanceof org.w3c.dom.Node); - - org.w3c.dom.Node n = (org.w3c.dom.Node) node; - String textString = n.getTextContent(); - assertTrue("needle found in haystack", textString.contains(needle)); - } - - public void assertXPathResultsContainText(DomNode page, String xpath, String needle) { - List nodes = page.getByXPath(xpath); - assertFalse("no nodes matching xpath found", nodes.isEmpty()); - boolean found = false; - for (Object o : nodes) { - if (o instanceof org.w3c.dom.Node) { - org.w3c.dom.Node n = (org.w3c.dom.Node) o; - String textString = n.getTextContent(); - if ((textString != null) && textString.contains(needle)) { - found = true; - break; - } - } - } - assertTrue("needle found in haystack", found); - } - - /** - * Makes sure that all the images in the page loads successfully. - * (By default, HtmlUnit doesn't load images.) - */ - public void assertAllImageLoadSuccessfully(HtmlPage p) { - for (HtmlImage img : p.selectNodes("//IMG")) { - try { - img.getHeight(); - } catch (IOException e) { - throw new Error("Failed to load "+img.getSrcAttribute(),e); - } - } - } - - - public void assertStringContains(String message, String haystack, String needle) { - assertTrue(message + " (seeking '" + needle + "')",haystack.contains(needle)); - } - - public void assertStringContains(String haystack, String needle) { - assertTrue("Could not find '" + needle + "'.",haystack.contains(needle)); - } - - /** - * Asserts that help files exist for the specified properties of the given instance. - * - * @param type - * The describable class type that should have the associated help files. - * @param properties - * ','-separated list of properties whose help files should exist. - */ - public void assertHelpExists(final Class type, final String properties) throws Exception { - executeOnServer(new Callable() { - public Object call() throws Exception { - Descriptor d = jenkins.getDescriptor(type); - WebClient wc = createWebClient(); - for (String property : listProperties(properties)) { - String url = d.getHelpFile(property); - assertNotNull("Help file for the property "+property+" is missing on "+type, url); - wc.goTo(url); // make sure it successfully loads - } - return null; - } - }); - } - - /** - * Tokenizes "foo,bar,zot,-bar" and returns "foo,zot" (the token that starts with '-' is handled as - * a cancellation. - */ - private List listProperties(String properties) { - List props = new ArrayList(Arrays.asList(properties.split(","))); - for (String p : props.toArray(new String[props.size()])) { - if (p.startsWith("-")) { - props.remove(p); - props.remove(p.substring(1)); - } - } - return props; - } - - /** - * Submits the form. - * - * Plain {@link HtmlForm#submit()} doesn't work correctly due to the use of YUI in Hudson. - */ - public HtmlPage submit(HtmlForm form) throws Exception { - return (HtmlPage)form.submit((HtmlButton)last(form.getHtmlElementsByTagName("button"))); - } - - /** - * Submits the form by clikcing the submit button of the given name. - * - * @param name - * This corresponds to the @name of <f:submit /> - */ - public HtmlPage submit(HtmlForm form, String name) throws Exception { - for( HtmlElement e : form.getHtmlElementsByTagName("button")) { - HtmlElement p = (HtmlElement)e.getParentNode().getParentNode(); - if(p.getAttribute("name").equals(name)) { - // To make YUI event handling work, this combo seems to be necessary - // the click will trigger _onClick in buton-*.js, but it doesn't submit the form - // (a comment alluding to this behavior can be seen in submitForm method) - // so to complete it, submit the form later. - // - // Just doing form.submit() doesn't work either, because it doesn't do - // the preparation work needed to pass along the name of the button that - // triggered a submission (more concretely, m_oSubmitTrigger is not set.) - ((HtmlButton)e).click(); - return (HtmlPage)form.submit((HtmlButton)e); - } - } - throw new AssertionError("No such submit button with the name "+name); - } - - protected HtmlInput findPreviousInputElement(HtmlElement current, String name) { - return (HtmlInput)current.selectSingleNode("(preceding::input[@name='_."+name+"'])[last()]"); - } - - protected HtmlButton getButtonByCaption(HtmlForm f, String s) { - for (HtmlElement b : f.getHtmlElementsByTagName("button")) { - if(b.getTextContent().trim().equals(s)) - return (HtmlButton)b; - } - return null; - } - - /** - * Creates a {@link TaskListener} connected to stdout. - */ - public TaskListener createTaskListener() { - return new StreamTaskListener(new CloseProofOutputStream(System.out)); - } - - /** - * Asserts that two JavaBeans are equal as far as the given list of properties are concerned. - * - *

    - * This method takes two objects that have properties (getXyz, isXyz, or just the public xyz field), - * and makes sure that the property values for each given property are equals (by using {@link #assertEquals(Object, Object)}) - * - *

    - * Property values can be null on both objects, and that is OK, but passing in a property that doesn't - * exist will fail an assertion. - * - *

    - * This method is very convenient for comparing a large number of properties on two objects, - * for example to verify that the configuration is identical after a config screen roundtrip. - * - * @param lhs - * One of the two objects to be compared. - * @param rhs - * The other object to be compared - * @param properties - * ','-separated list of property names that are compared. - * @since 1.297 - */ - public void assertEqualBeans(Object lhs, Object rhs, String properties) throws Exception { - assertNotNull("lhs is null",lhs); - assertNotNull("rhs is null",rhs); - for (String p : properties.split(",")) { - PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(lhs, p); - Object lp,rp; - if(pd==null) { - // field? - try { - Field f = lhs.getClass().getField(p); - lp = f.get(lhs); - rp = f.get(rhs); - } catch (NoSuchFieldException e) { - assertNotNull("No such property "+p+" on "+lhs.getClass(),pd); - return; - } - } else { - lp = PropertyUtils.getProperty(lhs, p); - rp = PropertyUtils.getProperty(rhs, p); - } - - if (lp!=null && rp!=null && lp.getClass().isArray() && rp.getClass().isArray()) { - // deep array equality comparison - int m = Array.getLength(lp); - int n = Array.getLength(rp); - assertEquals("Array length is different for property "+p, m,n); - for (int i=0; i primitiveProperties = new ArrayList(); - - String[] names = ClassDescriptor.loadParameterNames(lc); - Class[] types = lc.getParameterTypes(); - assertEquals(names.length,types.length); - for (int i=0; i lhs, List rhs) throws Exception { - assertEquals(lhs.size(), rhs.size()); - for (int i=0; i findDataBoundConstructor(Class c) { - for (Constructor m : c.getConstructors()) { - if (m.getAnnotation(DataBoundConstructor.class)!=null) - return m; - } - return null; - } - - /** - * Gets the descriptor instance of the current Hudson by its type. - */ - protected > T get(Class d) { - return jenkins.getDescriptorByType(d); - } - - - /** - * Returns true if Hudson is building something or going to build something. - */ - protected boolean isSomethingHappening() { - if (!jenkins.getQueue().isEmpty()) - return true; - for (Computer n : jenkins.getComputers()) - if (!n.isIdle()) - return true; - return false; - } - - /** - * Waits until Hudson finishes building everything, including those in the queue. - *

    - * This method uses a default time out to prevent infinite hang in the automated test execution environment. - */ - protected void waitUntilNoActivity() throws Exception { - waitUntilNoActivityUpTo(60*1000); - } - - /** - * Waits until Jenkins finishes building everything, including those builds in the queue, or fail the test - * if the specified timeout milliseconds is exceeded. - */ - protected void waitUntilNoActivityUpTo(int timeout) throws Exception { - long startTime = System.currentTimeMillis(); - int streak = 0; - - while (true) { - Thread.sleep(100); - if (isSomethingHappening()) - streak=0; - else - streak++; - - if (streak>2) // the system is quiet for a while - return; - - if (System.currentTimeMillis()-startTime > timeout) { - List building = new ArrayList(); - for (Computer c : jenkins.getComputers()) { - for (Executor e : c.getExecutors()) { - if (e.isBusy()) - building.add(e.getCurrentExecutable()); - } - } - throw new AssertionError(String.format("Jenkins is still doing something after %dms: queue=%s building=%s", - timeout, Arrays.asList(jenkins.getQueue().getItems()), building)); - } - } - } - - - -// -// recipe methods. Control the test environments. -// - - /** - * Called during the {@link #setUp()} to give a test case an opportunity to - * control the test environment in which Hudson is run. - * - *

    - * One could override this method and call a series of {@code withXXX} methods, - * or you can use the annotations with {@link Recipe} meta-annotation. - */ - protected void recipe() throws Exception { - recipeLoadCurrentPlugin(); - // look for recipe meta-annotation - try { - Method runMethod= getClass().getMethod(getName()); - for( final Annotation a : runMethod.getAnnotations() ) { - Recipe r = a.annotationType().getAnnotation(Recipe.class); - if(r==null) continue; - final Runner runner = r.value().newInstance(); - recipes.add(runner); - tearDowns.add(new LenientRunnable() { - public void run() throws Exception { - runner.tearDown(HudsonTestCase.this,a); - } - }); - runner.setup(this,a); - } - } catch (NoSuchMethodException e) { - // not a plain JUnit test. - } - } - - /** - * If this test harness is launched for a Jenkins plugin, locate the target/test-classes/the.jpl - * and add a recipe to install that to the new Jenkins. - * - *

    - * This file is created by maven-hpi-plugin at the testCompile phase when the current - * packaging is hpi. - */ - protected void recipeLoadCurrentPlugin() throws Exception { - final Enumeration jpls = getClass().getClassLoader().getResources("the.jpl"); - final Enumeration hpls = getClass().getClassLoader().getResources("the.hpl"); - - final List all = Collections.list(jpls); - all.addAll(Collections.list(hpls)); - - if(all.isEmpty()) return; // nope - - recipes.add(new Runner() { - @Override - public void decorateHome(HudsonTestCase testCase, File home) throws Exception { - - for (URL hpl : all) { - - // make the plugin itself available - Manifest m = new Manifest(hpl.openStream()); - String shortName = m.getMainAttributes().getValue("Short-Name"); - if(shortName==null) - throw new Error(hpl+" doesn't have the Short-Name attribute"); - FileUtils.copyURLToFile(hpl,new File(home,"plugins/"+shortName+".jpl")); - - // make dependency plugins available - // TODO: probably better to read POM, but where to read from? - // TODO: this doesn't handle transitive dependencies - - // Tom: plugins are now searched on the classpath first. They should be available on - // the compile or test classpath. As a backup, we do a best-effort lookup in the Maven repository - // For transitive dependencies, we could evaluate Plugin-Dependencies transitively. - - String dependencies = m.getMainAttributes().getValue("Plugin-Dependencies"); - if(dependencies!=null) { - MavenEmbedder embedder = MavenUtil.createEmbedder(new StreamTaskListener(System.out,Charset.defaultCharset()),(File)null,null); - for( String dep : dependencies.split(",")) { - String suffix = ";resolution:=optional"; - boolean optional = dep.endsWith(suffix); - if (optional) { - dep = dep.substring(0, dep.length() - suffix.length()); - } - String[] tokens = dep.split(":"); - String artifactId = tokens[0]; - String version = tokens[1]; - File dependencyJar=resolveDependencyJar(embedder,artifactId,version); - if (dependencyJar == null) { - if (optional) { - System.err.println("cannot resolve optional dependency " + dep + " of " + shortName + "; skipping"); - continue; - } - throw new IOException("Could not resolve " + dep); - } - - File dst = new File(home, "plugins/" + artifactId + ".jpi"); - if(!dst.exists() || dst.lastModified()!=dependencyJar.lastModified()) { - FileUtils.copyFile(dependencyJar, dst); - } - } - } - } - } - - private File resolveDependencyJar(MavenEmbedder embedder, String artifactId, String version) throws Exception { - // try to locate it from manifest - Enumeration manifests = getClass().getClassLoader().getResources("META-INF/MANIFEST.MF"); - while (manifests.hasMoreElements()) { - URL manifest = manifests.nextElement(); - InputStream is = manifest.openStream(); - Manifest m = new Manifest(is); - is.close(); - - if (artifactId.equals(m.getMainAttributes().getValue("Short-Name"))) - return Which.jarFile(manifest); - } - - // need to search multiple group IDs - // TODO: extend manifest to include groupID:artifactID:version - Exception resolutionError=null; - for (String groupId : new String[]{"org.jvnet.hudson.plugins","org.jvnet.hudson.main"}) { - - // first try to find it on the classpath. - // this takes advantage of Maven POM located in POM - URL dependencyPomResource = getClass().getResource("/META-INF/maven/"+groupId+"/"+artifactId+"/pom.xml"); - if (dependencyPomResource != null) { - // found it - return Which.jarFile(dependencyPomResource); - } else { - - try { - // currently the most of the plugins are still hpi - return resolvePluginFile(embedder, artifactId, version, groupId, "hpi"); - } catch(AbstractArtifactResolutionException x){ - try { - // but also try with the new jpi - return resolvePluginFile(embedder, artifactId, version, groupId, "jpi"); - } catch(AbstractArtifactResolutionException x2){ - // could be a wrong groupId - resolutionError = x; - } - } - - } - } - - throw new Exception("Failed to resolve plugin (tryied with types: 'jpi' and 'hpi'): "+artifactId+" version "+version, resolutionError); - } - - private File resolvePluginFile(MavenEmbedder embedder, String artifactId, String version, String groupId, String type) - throws MavenEmbedderException, ComponentLookupException, AbstractArtifactResolutionException { - final Artifact jpi = embedder.createArtifact(groupId, artifactId, version, "compile"/*doesn't matter*/, type); - embedder.resolve(jpi, Arrays.asList(embedder.createRepository("http://maven.glassfish.org/content/groups/public/","repo")),embedder.getLocalRepository()); - return jpi.getFile(); - - } - }); - } - - public HudsonTestCase withNewHome() { - return with(HudsonHomeLoader.NEW); - } - - public HudsonTestCase withExistingHome(File source) throws Exception { - return with(new CopyExisting(source)); - } - - /** - * Declares that this test case expects to start with one of the preset data sets. - * See {@code test/src/main/preset-data/} - * for available datasets and what they mean. - */ - public HudsonTestCase withPresetData(String name) { - name = "/" + name + ".zip"; - URL res = getClass().getResource(name); - if(res==null) throw new IllegalArgumentException("No such data set found: "+name); - - return with(new CopyExisting(res)); - } - - public HudsonTestCase with(HudsonHomeLoader homeLoader) { - this.homeLoader = homeLoader; - return this; - } - - - /** - * Executes the given closure on the server, by the servlet request handling thread, - * in the context of an HTTP request. - * - *

    - * In {@link HudsonTestCase}, a thread that's executing the test code is different from the thread - * that carries out HTTP requests made through {@link WebClient}. But sometimes you want to - * make assertions and other calls with side-effect from within the request handling thread. - * - *

    - * This method allows you to do just that. It is useful for testing some methods that - * require {@link StaplerRequest} and {@link StaplerResponse}, or getting the credential - * of the current user (via {@link jenkins.model.Jenkins#getAuthentication()}, and so on. - * - * @param c - * The closure to be executed on the server. - * @return - * The return value from the closure. - * @throws Exception - * If a closure throws any exception, that exception will be carried forward. - */ - public V executeOnServer(Callable c) throws Exception { - return createWebClient().executeOnServer(c); - } - - /** - * Sometimes a part of a test case may ends up creeping into the serialization tree of {@link Saveable#save()}, - * so detect that and flag that as an error. - */ - private Object writeReplace() { - throw new AssertionError("HudsonTestCase "+getName()+" is not supposed to be serialized"); - } - - /** - * This is to assist Groovy test clients who are incapable of instantiating the inner classes properly. - */ - public WebClient createWebClient() { - return new WebClient(); - } - - /** - * Extends {@link com.gargoylesoftware.htmlunit.WebClient} and provide convenience methods - * for accessing Hudson. - */ - public class WebClient extends com.gargoylesoftware.htmlunit.WebClient { - private static final long serialVersionUID = 5808915989048338267L; - - public WebClient() { - // default is IE6, but this causes 'n.doScroll('left')' to fail in event-debug.js:1907 as HtmlUnit doesn't implement such a method, - // so trying something else, until we discover another problem. - super(BrowserVersion.FIREFOX_2); - - setPageCreator(HudsonPageCreator.INSTANCE); - clients.add(this); - // make ajax calls run as post-action for predictable behaviors that simplify debugging - setAjaxController(new AjaxController() { - private static final long serialVersionUID = -5844060943564822678L; - public boolean processSynchron(HtmlPage page, WebRequestSettings settings, boolean async) { - return false; - } - }); - - setCssErrorHandler(new ErrorHandler() { - final ErrorHandler defaultHandler = new DefaultCssErrorHandler(); - - public void warning(CSSParseException exception) throws CSSException { - if (!ignore(exception)) - defaultHandler.warning(exception); - } - - public void error(CSSParseException exception) throws CSSException { - if (!ignore(exception)) - defaultHandler.error(exception); - } - - public void fatalError(CSSParseException exception) throws CSSException { - if (!ignore(exception)) - defaultHandler.fatalError(exception); - } - - private boolean ignore(CSSParseException e) { - return e.getURI().contains("/yui/"); - } - }); - - // if no other debugger is installed, install jsDebugger, - // so as not to interfere with the 'Dim' class. - getJavaScriptEngine().getContextFactory().addListener(new Listener() { - public void contextCreated(Context cx) { - if (cx.getDebugger() == null) - cx.setDebugger(jsDebugger, null); - } - - public void contextReleased(Context cx) { - } - }); - - setAlertHandler(new AlertHandler() { - public void handleAlert(Page page, String message) { - throw new AssertionError("Alert dialog poped up: "+message); - } - }); - - // avoid a hang by setting a time out. It should be long enough to prevent - // false-positive timeout on slow systems - setTimeout(60*1000); - } - - /** - * Logs in to Jenkins. - */ - public WebClient login(String username, String password) throws Exception { - HtmlPage page = goTo("/login"); - - HtmlForm form = page.getFormByName("login"); - form.getInputByName("j_username").setValueAttribute(username); - form.getInputByName("j_password").setValueAttribute(password); - form.submit(null); - return this; - } - - /** - * Logs in to Hudson, by using the user name as the password. - * - *

    - * See {@link HudsonTestCase#configureUserRealm()} for how the container is set up with the user names - * and passwords. All the test accounts have the same user name and password. - */ - public WebClient login(String username) throws Exception { - login(username,username); - return this; - } - - /** - * Executes the given closure on the server, by the servlet request handling thread, - * in the context of an HTTP request. - * - *

    - * In {@link HudsonTestCase}, a thread that's executing the test code is different from the thread - * that carries out HTTP requests made through {@link WebClient}. But sometimes you want to - * make assertions and other calls with side-effect from within the request handling thread. - * - *

    - * This method allows you to do just that. It is useful for testing some methods that - * require {@link StaplerRequest} and {@link StaplerResponse}, or getting the credential - * of the current user (via {@link jenkins.model.Jenkins#getAuthentication()}, and so on. - * - * @param c - * The closure to be executed on the server. - * @return - * The return value from the closure. - * @throws Exception - * If a closure throws any exception, that exception will be carried forward. - */ - public V executeOnServer(final Callable c) throws Exception { - final Exception[] t = new Exception[1]; - final List r = new ArrayList(1); // size 1 list - - ClosureExecuterAction cea = jenkins.getExtensionList(RootAction.class).get(ClosureExecuterAction.class); - UUID id = UUID.randomUUID(); - cea.add(id,new Runnable() { - public void run() { - try { - StaplerResponse rsp = Stapler.getCurrentResponse(); - rsp.setStatus(200); - rsp.setContentType("text/html"); - r.add(c.call()); - } catch (Exception e) { - t[0] = e; - } - } - }); - goTo("closures/?uuid="+id); - - if (t[0]!=null) - throw t[0]; - return r.get(0); - } - - public HtmlPage search(String q) throws IOException, SAXException { - HtmlPage top = goTo(""); - HtmlForm search = top.getFormByName("search"); - search.getInputByName("q").setValueAttribute(q); - return (HtmlPage)search.submit(null); - } - - /** - * Short for {@code getPage(r,"")}, to access the top page of a build. - */ - public HtmlPage getPage(Run r) throws IOException, SAXException { - return getPage(r,""); - } - - /** - * Accesses a page inside {@link Run}. - * - * @param relative - * Relative URL within the build URL, like "changes". Doesn't start with '/'. Can be empty. - */ - public HtmlPage getPage(Run r, String relative) throws IOException, SAXException { - return goTo(r.getUrl()+relative); - } - - public HtmlPage getPage(Item item) throws IOException, SAXException { - return getPage(item,""); - } - - public HtmlPage getPage(Item item, String relative) throws IOException, SAXException { - return goTo(item.getUrl()+relative); - } - - public HtmlPage getPage(Node item) throws IOException, SAXException { - return getPage(item,""); - } - - public HtmlPage getPage(Node item, String relative) throws IOException, SAXException { - return goTo(item.toComputer().getUrl()+relative); - } - - public HtmlPage getPage(View view) throws IOException, SAXException { - return goTo(view.getUrl()); - } - - public HtmlPage getPage(View view, String relative) throws IOException, SAXException { - return goTo(view.getUrl()+relative); - } - - /** - * @deprecated - * This method expects a full URL. This method is marked as deprecated to warn you - * that you probably should be using {@link #goTo(String)} method, which accepts - * a relative path within the Hudson being tested. (IOW, if you really need to hit - * a website on the internet, there's nothing wrong with using this method.) - */ - @SuppressWarnings("unchecked") - @Override - public Page getPage(String url) throws IOException, FailingHttpStatusCodeException { - return super.getPage(url); - } - - /** - * Requests a page within Hudson. - * - * @param relative - * Relative path within Hudson. Starts without '/'. - * For example, "job/test/" to go to a job top page. - */ - public HtmlPage goTo(String relative) throws IOException, SAXException { - Page p = goTo(relative, "text/html"); - if (p instanceof HtmlPage) { - return (HtmlPage) p; - } else { - throw new AssertionError("Expected text/html but instead the content type was "+p.getWebResponse().getContentType()); - } - } - - public Page goTo(String relative, String expectedContentType) throws IOException, SAXException { - while (relative.startsWith("/")) relative = relative.substring(1); - Page p; - try { - p = super.getPage(getContextPath() + relative); - } catch (IOException x) { - if (x.getCause() != null) { - x.getCause().printStackTrace(); - } - throw x; - } - assertEquals(expectedContentType,p.getWebResponse().getContentType()); - return p; - } - - /** Loads a page as XML. Useful for testing Hudson's xml api, in concert with - * assertXPath(DomNode page, String xpath) - * @param path the path part of the url to visit - * @return the XmlPage found at that url - * @throws IOException - * @throws SAXException - */ - public XmlPage goToXml(String path) throws IOException, SAXException { - Page page = goTo(path, "application/xml"); - if (page instanceof XmlPage) - return (XmlPage) page; - else - return null; - } - - /** - * Verify that the server rejects an attempt to load the given page. - * @param url a URL path (relative to Jenkins root) - * @param statusCode the expected failure code (such as {@link HttpURLConnection#HTTP_FORBIDDEN}) - * @since 1.502 - */ - public void assertFails(String url, int statusCode) throws Exception { - try { - fail(url + " should have been rejected but produced: " + super.getPage(getContextPath() + url).getWebResponse().getContentAsString()); - } catch (FailingHttpStatusCodeException x) { - assertEquals(statusCode, x.getStatusCode()); - } - } - - /** - * Returns the URL of the webapp top page. - * URL ends with '/'. - */ - public String getContextPath() throws IOException { - return getURL().toExternalForm(); - } - - /** - * Adds a security crumb to the quest - */ - public WebRequestSettings addCrumb(WebRequestSettings req) { - NameValuePair crumb[] = { new NameValuePair() }; - - crumb[0].setName(jenkins.getCrumbIssuer().getDescriptor().getCrumbRequestField()); - crumb[0].setValue(jenkins.getCrumbIssuer().getCrumb( null )); - - req.setRequestParameters(Arrays.asList( crumb )); - return req; - } - - /** - * Creates a URL with crumb parameters relative to {{@link #getContextPath()} - */ - public URL createCrumbedUrl(String relativePath) throws IOException { - CrumbIssuer issuer = jenkins.getCrumbIssuer(); - String crumbName = issuer.getDescriptor().getCrumbRequestField(); - String crumb = issuer.getCrumb(null); - - return new URL(getContextPath()+relativePath+"?"+crumbName+"="+crumb); - } - - /** - * Makes an HTTP request, process it with the given request handler, and returns the response. - */ - public HtmlPage eval(final Runnable requestHandler) throws IOException, SAXException { - ClosureExecuterAction cea = jenkins.getExtensionList(RootAction.class).get(ClosureExecuterAction.class); - UUID id = UUID.randomUUID(); - cea.add(id,requestHandler); - return goTo("closures/?uuid="+id); - } - - /** - * Starts an interactive JavaScript debugger, and break at the next JavaScript execution. - * - *

    - * This is useful during debugging a test so that you can step execute and inspect state of JavaScript. - * This will launch a Swing GUI, and the method returns immediately. - * - *

    - * Note that installing a debugger appears to make an execution of JavaScript substantially slower. - * - *

    - * TODO: because each script block evaluation in HtmlUnit is done in a separate Rhino context, - * if you step over from one script block, the debugger fails to kick in on the beginning of the next script block. - * This makes it difficult to set a break point on arbitrary script block in the HTML page. We need to fix this - * by tweaking {@link Dim.StackFrame#onLineChange(Context, int)}. - */ - public Dim interactiveJavaScriptDebugger() { - Global global = new Global(); - HtmlUnitContextFactory cf = getJavaScriptEngine().getContextFactory(); - global.init(cf); - - Dim dim = org.mozilla.javascript.tools.debugger.Main.mainEmbedded(cf, global, "Rhino debugger: " + getName()); - - // break on exceptions. this catch most of the errors - dim.setBreakOnExceptions(true); - - return dim; - } - } - - // needs to keep reference, or it gets GC-ed. - private static final Logger XML_HTTP_REQUEST_LOGGER = Logger.getLogger(XMLHttpRequest.class.getName()); - - static { - // screen scraping relies on locale being fixed. - Locale.setDefault(Locale.ENGLISH); - - {// enable debug assistance, since tests are often run from IDE - Dispatcher.TRACE = true; - MetaClass.NO_CACHE=true; - // load resources from the source dir. - File dir = new File("src/main/resources"); - if(dir.exists() && MetaClassLoader.debugLoader==null) - try { - MetaClassLoader.debugLoader = new MetaClassLoader( - new URLClassLoader(new URL[]{dir.toURI().toURL()})); - } catch (MalformedURLException e) { - throw new AssertionError(e); - } - } - - // suppress INFO output from Spring, which is verbose - Logger.getLogger("org.springframework").setLevel(Level.WARNING); - - // hudson-behavior.js relies on this to decide whether it's running unit tests. - Main.isUnitTest = true; - - // prototype.js calls this method all the time, so ignore this warning. - XML_HTTP_REQUEST_LOGGER.setFilter(new Filter() { - public boolean isLoggable(LogRecord record) { - return !record.getMessage().contains("XMLHttpRequest.getResponseHeader() was called before the response was available."); - } - }); - - // remove the upper bound of the POST data size in Jetty. - System.setProperty("org.mortbay.jetty.Request.maxFormContentSize","-1"); - } - - private static final Logger LOGGER = Logger.getLogger(HudsonTestCase.class.getName()); - - protected static final List> NO_PROPERTIES = Collections.>emptyList(); - - /** - * Specify this to a TCP/IP port number to have slaves started with the debugger. - */ - public static int SLAVE_DEBUG_PORT = Integer.getInteger(HudsonTestCase.class.getName()+".slaveDebugPort",-1); - - public static final MimeTypes MIME_TYPES = new MimeTypes(); - static { - MIME_TYPES.addMimeMapping("js","application/javascript"); - Functions.DEBUG_YUI = true; - - // during the unit test, predictably releasing classloader is important to avoid - // file descriptor leak. - ClassicPluginStrategy.useAntClassLoader = true; - - // DNS multicast support takes up a lot of time during tests, so just disable it altogether - // this also prevents tests from falsely advertising Hudson - DNSMultiCast.disabled = true; - - if (!Functions.isWindows()) { - try { - PosixAPI.jnr().unsetenv("MAVEN_OPTS"); - PosixAPI.jnr().unsetenv("MAVEN_DEBUG_OPTS"); - } catch (Exception e) { - LOGGER.log(Level.WARNING,"Failed to cancel out MAVEN_OPTS",e); - } - } - } - - public static class TestBuildWrapper extends BuildWrapper { - public Result buildResultInTearDown; - - @Override - public Environment setUp(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException { - return new BuildWrapper.Environment() { - @Override - public boolean tearDown(AbstractBuild build, BuildListener listener) throws IOException, InterruptedException { - buildResultInTearDown = build.getResult(); - return true; - } - }; - } - - @Extension - public static class TestBuildWrapperDescriptor extends BuildWrapperDescriptor { - @Override - public boolean isApplicable(AbstractProject project) { - return true; - } - - @Override - public BuildWrapper newInstance(StaplerRequest req, JSONObject formData) { - throw new UnsupportedOperationException(); - } - - @Override - public String getDisplayName() { - return this.getClass().getName(); - } - } - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/JavaNetReverseProxy.java b/test/src/main/java/org/jvnet/hudson/test/JavaNetReverseProxy.java deleted file mode 100644 index ccc3df518cdf17cff8d3b02fccdd669fef2850dc..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/JavaNetReverseProxy.java +++ /dev/null @@ -1,109 +0,0 @@ -package org.jvnet.hudson.test; - -import hudson.Util; -import hudson.util.IOUtils; -import org.apache.commons.io.FileUtils; -import org.mortbay.jetty.Server; -import org.mortbay.jetty.bio.SocketConnector; -import org.mortbay.jetty.handler.ContextHandlerCollection; -import org.mortbay.jetty.servlet.Context; -import org.mortbay.jetty.servlet.ServletHolder; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.IOException; -import java.net.URL; - -/** - * Acts as a reverse proxy, so that during a test we can avoid hitting updates.jenkins-ci.org. - * - *

    - * The contents are cached locally. - * - * @author Kohsuke Kawaguchi - */ -public class JavaNetReverseProxy extends HttpServlet { - private final Server server; - public final int localPort; - - private final File cacheFolder; - - public JavaNetReverseProxy(File cacheFolder) throws Exception { - this.cacheFolder = cacheFolder; - cacheFolder.mkdirs(); - - server = new Server(); - - ContextHandlerCollection contexts = new ContextHandlerCollection(); - server.setHandler(contexts); - - Context root = new Context(contexts, "/", Context.SESSIONS); - root.addServlet(new ServletHolder(this), "/"); - - SocketConnector connector = new SocketConnector(); - server.addConnector(connector); - server.start(); - - localPort = connector.getLocalPort(); - } - - public void stop() throws Exception { - server.stop(); - } - -// class Response { -// final URL url; -// final String contentType; -// final ByteArrayOutputStream data = new ByteArrayOutputStream(); -// -// Response(URL url) throws IOException { -// this.url = url; -// URLConnection con = url.openConnection(); -// contentType = con.getContentType(); -// IOUtils.copy(con.getInputStream(),data); -// } -// -// void reproduceTo(HttpServletResponse rsp) throws IOException { -// rsp.setContentType(contentType); -// data.writeTo(rsp.getOutputStream()); -// } -// } - - @Override - protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - String path = req.getServletPath(); - String d = Util.getDigestOf(path); - - File cache = new File(cacheFolder, d); - if(!cache.exists()) { - URL url = new URL("http://updates.jenkins-ci.org/" + path); - FileUtils.copyURLToFile(url,cache); - } - - resp.setContentType(getMimeType(path)); - IOUtils.copy(cache,resp.getOutputStream()); - } - - private String getMimeType(String path) { - int idx = path.indexOf('?'); - if(idx>=0) - path = path.substring(0,idx); - if(path.endsWith(".json")) return "text/javascript"; - return getServletContext().getMimeType(path); - } - - private static volatile JavaNetReverseProxy INSTANCE; - - /** - * Gets the default instance. - */ - public static synchronized JavaNetReverseProxy getInstance() throws Exception { - if(INSTANCE==null) - // TODO: think of a better location --- ideally inside the target/ dir so that clean would wipe them out - INSTANCE = new JavaNetReverseProxy(new File(new File(System.getProperty("java.io.tmpdir")),"jenkins-ci.org-cache2")); - return INSTANCE; - } -} diff --git a/test/src/main/java/org/jvnet/hudson/test/JellyTestSuiteBuilder.java b/test/src/main/java/org/jvnet/hudson/test/JellyTestSuiteBuilder.java deleted file mode 100644 index 3607273be4343ea147f4599200a3daf40cf1757f..0000000000000000000000000000000000000000 --- a/test/src/main/java/org/jvnet/hudson/test/JellyTestSuiteBuilder.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2004-2009, Sun Microsystems, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package org.jvnet.hudson.test; - -import junit.framework.TestCase; -import junit.framework.TestResult; -import junit.framework.TestSuite; -import org.apache.commons.io.FileUtils; -import org.dom4j.Document; -import org.dom4j.ProcessingInstruction; -import org.dom4j.io.SAXReader; -import org.jvnet.hudson.test.junit.GroupedTest; -import org.kohsuke.stapler.MetaClassLoader; -import org.kohsuke.stapler.jelly.JellyClassLoaderTearOff; - -import java.io.File; -import java.net.URL; -import java.util.Collection; -import java.util.Enumeration; -import java.util.concurrent.Callable; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; - -/** - * Builds up a {@link TestSuite} for performing static syntax checks on Jelly scripts. - * - * @author Kohsuke Kawaguchi - */ -public class JellyTestSuiteBuilder { - /** - * Given a jar file or a class file directory, recursively search all the Jelly files and build a {@link TestSuite} - * that performs static syntax checks. - */ - public static TestSuite build(File res, boolean requirePI) throws Exception { - TestSuite ts = new JellyTestSuite(); - - final JellyClassLoaderTearOff jct = new MetaClassLoader(JellyTestSuiteBuilder.class.getClassLoader()).loadTearOff(JellyClassLoaderTearOff.class); - - if (res.isDirectory()) { - for (final File jelly : (Collection )FileUtils.listFiles(res,new String[]{"jelly"},true)) - ts.addTest(new JellyCheck(jelly.toURI().toURL(), jelly.getAbsolutePath().substring((res.getAbsolutePath() + File.separator).length()), jct, requirePI)); - } - if (res.getName().endsWith(".jar")) { - String jarUrl = res.toURI().toURL().toExternalForm(); - JarFile jf = new JarFile(res); - Enumeration e = jf.entries(); - while (e.hasMoreElements()) { - JarEntry ent = e.nextElement(); - if (ent.getName().endsWith(".jelly")) - ts.addTest(new JellyCheck(new URL("jar:"+jarUrl+"!/"+ent.getName()), ent.getName(), jct, requirePI)); - } - jf.close(); - } - return ts; - } - - private static class JellyCheck extends TestCase { - private final URL jelly; - private final JellyClassLoaderTearOff jct; - private final boolean requirePI; - - JellyCheck(URL jelly, String name, JellyClassLoaderTearOff jct, boolean requirePI) { - super(name); - this.jelly = jelly; - this.jct = jct; - this.requirePI = requirePI; - } - - @Override - protected void runTest() throws Exception { - jct.createContext().compileScript(jelly); - Document dom = new SAXReader().read(jelly); - checkLabelFor(dom); - if (requirePI) { - ProcessingInstruction pi = dom.processingInstruction("jelly"); - if (pi==null || !pi.getText().contains("escape-by-default")) - throw new AssertionError(" is missing in "+jelly); - - } - // TODO: what else can we check statically? use of taglibs? - } - - /** - * Makes sure that <label for=...> is not used inside config.jelly nor global.jelly - */ - private void checkLabelFor(Document dom) { - if (isConfigJelly() || isGlobalJelly()) { - if (!dom.selectNodes("//label[@for]").isEmpty()) - throw new AssertionError("