Skip to content

Commit cb1ab25

Browse files
committed
Merge pull request #1253 from StackStorm/0.8.2
[DONT MERGE] Changes for v0.8.2 release
2 parents d82c048 + 1a1d966 commit cb1ab25

File tree

12 files changed

+113
-22
lines changed

12 files changed

+113
-22
lines changed

CHANGELOG.rst

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
Changelog
22
=========
33

4-
v0.8.1 - March 6, 2015
4+
v0.8.2 - March 10, 2015
5+
-----------------------
6+
7+
* Fix a bug with python-runner actions sometimes not correctly reporting the action's ``stdout``.
8+
(bug-fix)
9+
* Fix a bug in the ``run-remote-script`` runner - the runner ignored environment variables and
10+
authentication settings which were supplied to the action as parameters. (bug-fix)
11+
12+
v0.8.1 - March 10, 2015
513
-----------------------
614

715
Docs: http://docs.stackstorm.com/0.8/

docs/source/install/deb.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ The easiest way to install these is to use the requirements.txt file from the |s
2323

2424
::
2525

26-
curl -q -k -O https://ops.stackstorm.net/releases/st2/0.8.1/requirements.txt
26+
curl -q -k -O https://ops.stackstorm.net/releases/st2/0.8.2/requirements.txt
2727
pip install -r requirements.txt
2828

2929
RabbitMQ
@@ -69,7 +69,7 @@ The format of the DEB packages is like this: <component>_<version>-<build>_amd64
6969
You can download the packages from this URL:
7070
::
7171

72-
https://ops.stackstorm.net/releases/st2/0.8.1/debs/current/
72+
https://ops.stackstorm.net/releases/st2/0.8.2/debs/current/
7373

7474
--------------
7575

docs/source/install/rpm.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ The format of the RPM packages is like this: <component>-<version>-<build>.noarc
8989
You can download the packages from this URL:
9090
::
9191

92-
https://ops.stackstorm.net/releases/st2/0.8.1/rpms/current/
92+
https://ops.stackstorm.net/releases/st2/0.8.2/rpms/current/
9393

9494
--------------
9595

st2actions/st2actions/runners/pythonrunner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ def run(self, action_parameters):
158158
split = stdout.split(ACTION_OUTPUT_RESULT_DELIMITER)
159159
assert len(split) == 3
160160
result = split[1].strip()
161-
stdout = split[0] = split[2]
161+
stdout = split[0] + split[2]
162162
else:
163163
result = None
164164

st2actions/tests/unit/test_fabricrunner.py

+26
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
import st2tests.config as tests_config
1818
tests_config.parse_args()
1919

20+
import mock
2021
from unittest2 import TestCase
2122

2223
from st2actions.runners.fabricrunner import get_runner
2324
from st2actions.runners.fabricrunner import FabricRunner
2425
from st2common.constants.action import LIVEACTION_STATUS_SUCCEEDED, LIVEACTION_STATUS_FAILED
2526
from st2common.models.system.action import RemoteScriptAction
27+
from st2common.models.system.action import FabricRemoteScriptAction
2628

2729

2830
class FabricRunnerTestCase(TestCase):
@@ -141,3 +143,27 @@ def test_parameter_formatting(self):
141143
remote_dir='/tmp',
142144
named_args=named_args, positional_args=None)
143145
self.assertEqual(action.command, '/tmp/test.py --foo1=bar1 --foo2=bar2 --foo3')
146+
147+
148+
class FabricRemoteScriptActionTestCase(TestCase):
149+
150+
@mock.patch('st2common.models.system.action.run')
151+
@mock.patch('st2common.models.system.action.put')
152+
@mock.patch('st2common.models.system.action.shell_env')
153+
@mock.patch('st2common.models.system.action.settings')
154+
def test_settings_are_used(self, mock_settings, mock_shell_env, mock_put, mock_run):
155+
# Test that the remote script action uses fabric environment and authentication settings
156+
named_args = {}
157+
action = FabricRemoteScriptAction(name='foo', action_exec_id='dummy',
158+
script_local_path_abs='test.py',
159+
script_local_libs_path_abs='/',
160+
remote_dir='/tmp',
161+
named_args=named_args, positional_args=None)
162+
163+
task = action.get_fabric_task()
164+
165+
self.assertEqual(mock_settings.call_count, 0)
166+
self.assertEqual(mock_shell_env.call_count, 0)
167+
task.run()
168+
self.assertEqual(mock_settings.call_count, 1)
169+
self.assertEqual(mock_shell_env.call_count, 1)

st2actions/tests/unit/test_pythonrunner.py

+47
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from st2actions.runners import pythonrunner
2222
from st2actions.container import service
23+
from st2common.constants.action import ACTION_OUTPUT_RESULT_DELIMITER
2324
from st2common.constants.action import LIVEACTION_STATUS_SUCCEEDED, LIVEACTION_STATUS_FAILED
2425
from st2common.constants.pack import SYSTEM_PACK_NAME
2526
import st2tests.base as tests_base
@@ -111,6 +112,52 @@ def test_action_with_user_supplied_env_vars(self, mock_popen):
111112
else:
112113
self.assertEqual(actual_env[key], value)
113114

115+
@mock.patch('st2actions.runners.pythonrunner.subprocess.Popen')
116+
def test_stdout_interception_and_parsing(self, mock_popen):
117+
values = {'delimiter': ACTION_OUTPUT_RESULT_DELIMITER}
118+
119+
# No output to stdout and no result (implicit None)
120+
mock_stdout = '%(delimiter)sNone%(delimiter)s' % values
121+
mock_stderr = 'foo stderr'
122+
mock_process = mock.Mock()
123+
mock_process.communicate.return_value = (mock_stdout, mock_stderr)
124+
mock_process.returncode = 0
125+
mock_popen.return_value = mock_process
126+
127+
runner = pythonrunner.get_runner()
128+
runner.action = self._get_mock_action_obj()
129+
runner.runner_parameters = {}
130+
runner.entry_point = PACAL_ROW_ACTION_PATH
131+
runner.container_service = service.RunnerContainerService()
132+
runner.pre_run()
133+
(_, output, _) = runner.run({'row_index': 4})
134+
135+
self.assertEqual(output['stdout'], '')
136+
self.assertEqual(output['stderr'], mock_stderr)
137+
self.assertEqual(output['result'], 'None')
138+
self.assertEqual(output['exit_code'], 0)
139+
140+
# Output to stdout and no result (implicit None)
141+
mock_stdout = 'pre result%(delimiter)sNone%(delimiter)spost result' % values
142+
mock_stderr = 'foo stderr'
143+
mock_process = mock.Mock()
144+
mock_process.communicate.return_value = (mock_stdout, mock_stderr)
145+
mock_process.returncode = 0
146+
mock_popen.return_value = mock_process
147+
148+
runner = pythonrunner.get_runner()
149+
runner.action = self._get_mock_action_obj()
150+
runner.runner_parameters = {}
151+
runner.entry_point = PACAL_ROW_ACTION_PATH
152+
runner.container_service = service.RunnerContainerService()
153+
runner.pre_run()
154+
(_, output, _) = runner.run({'row_index': 4})
155+
156+
self.assertEqual(output['stdout'], 'pre resultpost result')
157+
self.assertEqual(output['stderr'], mock_stderr)
158+
self.assertEqual(output['result'], 'None')
159+
self.assertEqual(output['exit_code'], 0)
160+
114161
def _get_mock_action_obj(self):
115162
"""
116163
Return mock action object.

st2client/st2client/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
__version__ = '0.8.1'
16+
__version__ = '0.8.2'

st2common/st2common/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16-
__version__ = '0.8.1'
16+
__version__ = '0.8.2'

st2common/st2common/models/system/action.py

+22-13
Original file line numberDiff line numberDiff line change
@@ -408,17 +408,6 @@ def _sudo(self):
408408

409409
return jsonify.json_loads(result, FabricRemoteAction.KEYS_TO_TRANSFORM)
410410

411-
def _cleanup(self, settings):
412-
"""
413-
Clean function which is ran after executing a fabric command.
414-
415-
:param settings: Fabric settings.
416-
"""
417-
temporary_key_file_path = settings.get('key_filename', None)
418-
419-
if temporary_key_file_path:
420-
self._remove_private_key_file(file_path=temporary_key_file_path)
421-
422411
def _get_settings(self):
423412
"""
424413
Retrieve settings used for the fabric command execution.
@@ -447,6 +436,17 @@ def _get_env_vars(self):
447436
env_vars = self.env_vars or {}
448437
return env_vars
449438

439+
def _cleanup(self, settings):
440+
"""
441+
Clean function which is ran after executing a fabric command.
442+
443+
:param settings: Fabric settings.
444+
"""
445+
temporary_key_file_path = settings.get('key_filename', None)
446+
447+
if temporary_key_file_path:
448+
self._remove_private_key_file(file_path=temporary_key_file_path)
449+
450450
def _write_private_key(self, private_key_material):
451451
"""
452452
Write private key to a temporary file and return path to the file.
@@ -477,12 +477,20 @@ def get_fabric_task(self):
477477
return self._get_script_action_method()
478478

479479
def _get_script_action_method(self):
480-
task = WrappedCallableTask(self._run_script, name=self.name, alias=self.action_exec_id,
481-
parallel=self.parallel, sudo=self.sudo)
480+
task = WrappedCallableTask(self._run_script_with_settings, name=self.name,
481+
alias=self.action_exec_id, parallel=self.parallel,
482+
sudo=self.sudo)
482483
task.parallel = self.parallel
483484
task.serial = not self.parallel
484485
return task
485486

487+
def _run_script_with_settings(self):
488+
fabric_env_vars = self.env_vars
489+
fabric_settings = self._get_settings()
490+
491+
with shell_env(**fabric_env_vars), settings(**fabric_settings):
492+
return self._run_script()
493+
486494
def _run_script(self):
487495
try:
488496
self._execute_remote_command('mkdir %s' % self.remote_dir)
@@ -511,6 +519,7 @@ def _run_script(self):
511519
except Exception:
512520
LOG.exception('Failed executing remote action.')
513521
result = self._get_error_result()
522+
514523
return result
515524

516525
def _get_command_string(self, cmd, args):

st2common/tests/unit/test_action_system_models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def test_fabric_remote_script_action_method(self):
9292
self.assertEqual(remote_action.get_on_behalf_user(), 'stan')
9393
fabric_task = remote_action.get_fabric_task()
9494
self.assertTrue(fabric_task is not None)
95-
self.assertTrue(fabric_task.wrapped == remote_action._run_script)
95+
self.assertTrue(fabric_task.wrapped == remote_action._run_script_with_settings)
9696

9797
def test_remote_dir_script_action_method_default(self):
9898
remote_action = FabricRemoteScriptAction('foo', 'foo-id', '/tmp/st2.py',

st2reactor/packaging/rpm/st2reactor-rhel6.spec

+1
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ install -m755 bin/rule_tester %{buildroot}/usr/bin/rule_tester
3636
/usr/local/lib/python2.7/site-packages/st2reactor*
3737
/usr/bin/sensor_container
3838
/usr/bin/rules_engine
39+
/usr/bin/rule_tester
3940
/etc/st2reactor*

tools/st2_deploy.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ function version_ge() { test "$(echo "$@" | tr " " "\n" | sort -V | tail -n 1)"
44

55
if [ -z $1 ]
66
then
7-
VER='0.8.1'
7+
VER='0.8.2'
88
elif [[ "$1" == "latest" ]]; then
99
VER='0.9dev'
1010
else

0 commit comments

Comments
 (0)