From 6e3daab97d85bfebac75d00d81f7da4b630c9053 Mon Sep 17 00:00:00 2001 From: Khai Do Date: Mon, 22 Jun 2015 22:13:16 -0400 Subject: [PATCH] Support scriptText api to execute groovy scripts on the server Jenkins features a nice script console[1] which allows users to remotely run arbitrary groovy scripts on the Jenkins master. Examples: $ curl -d 'script=println("hello world")' -X POST http://localhost:8080/scriptText hello world $ curl -d 'script=println(Jenkins.instance.pluginManager.plugins)' -X POST http://localhost:8080/scriptText [Plugin:windows-slaves, Plugin:ssh-slaves, Plugin:translation, Plugin:cvs, Plugin:nodelabelparameter, Plugin:external-monitor-job, Plugin:subversion, Plugin:ssh-credentials, Plugin:token-macro, Plugin:ant, Plugin:ldap, Plugin:credentials, Plugin:matrix-auth, Plugin:matrix-project, Plugin:mailer, Plugin:jquery, Plugin:maven-plugin, Plugin:pam-auth] [1] https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console Change-Id: Ia4fbfca970165d890d7e076f47ddcde7633afa9b --- jenkins/__init__.py | 19 +++++++++++++++++++ tests/test_jenkins.py | 11 +++++++++++ 2 files changed, 30 insertions(+) diff --git a/jenkins/__init__.py b/jenkins/__init__.py index aa5ffce..d68ff9b 100644 --- a/jenkins/__init__.py +++ b/jenkins/__init__.py @@ -94,6 +94,7 @@ VIEW_NAME = 'view/%(name)s/api/json?tree=name' CREATE_VIEW = 'createView?name=%(name)s' CONFIG_VIEW = 'view/%(name)s/config.xml' DELETE_VIEW = 'view/%(name)s/doDelete' +SCRIPT_TEXT = 'scriptText' # for testing only EMPTY_CONFIG_XML = ''' @@ -679,6 +680,24 @@ class Jenkins(object): return self.jenkins_open(Request( self.build_job_url(name, parameters, token), b'')) + def run_script(self, script): + '''Execute a groovy script on the jenkins master. + + :param script: The groovy script, ``string`` + :returns: The result of the script run. + + Example:: + >>> j = Jenkins() + >>> info = j.run_script("println(Jenkins.instance.pluginManager.plugins)") + >>> print(info) + u'[Plugin:windows-slaves, Plugin:ssh-slaves, Plugin:translation, + Plugin:cvs, Plugin:nodelabelparameter, Plugin:external-monitor-job, + Plugin:mailer, Plugin:jquery, Plugin:antisamy-markup-formatter, + Plugin:maven-plugin, Plugin:pam-auth]' + ''' + return self.jenkins_open(Request(self.server + SCRIPT_TEXT, + "script=".encode('utf-8') + script.encode('utf-8'))) + def stop_build(self, name, number): '''Stop a running Jenkins build. diff --git a/tests/test_jenkins.py b/tests/test_jenkins.py index b6c6698..2931357 100644 --- a/tests/test_jenkins.py +++ b/tests/test_jenkins.py @@ -450,6 +450,17 @@ class JenkinsTest(unittest.TestCase): self.assertEqual(build_info, {'foo': 'bar'}) self._check_requests(jenkins_mock.call_args_list) + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_run_script(self, jenkins_mock): + j = jenkins.Jenkins('http://example.com/', 'test', 'test') + + j.run_script(u'println(\"Hello World!\")') + + self.assertEqual( + jenkins_mock.call_args[0][0].get_full_url(), + u'http://example.com/scriptText') + self._check_requests(jenkins_mock.call_args_list) + @patch.object(jenkins.Jenkins, 'jenkins_open') def test_stop_build(self, jenkins_mock): j = jenkins.Jenkins('http://example.com/', 'test', 'test')