summaryrefslogtreecommitdiff
path: root/tests/cloud_tests/util.py
diff options
context:
space:
mode:
authorChad Smith <chad.smith@canonical.com>2017-10-06 13:22:54 -0600
committerChad Smith <chad.smith@canonical.com>2017-10-06 13:22:54 -0600
commit9fd022780ae516df3499b17b2d69b72fc502917c (patch)
treebc33ac6296f374414ccb15dce233a4293b8633d3 /tests/cloud_tests/util.py
parent89630a6658c099d59f2766493a35c2ad266a8f42 (diff)
parent45d361cb0b7f5e4e7d79522bd285871898358623 (diff)
downloadvyos-cloud-init-9fd022780ae516df3499b17b2d69b72fc502917c.tar.gz
vyos-cloud-init-9fd022780ae516df3499b17b2d69b72fc502917c.zip
merge from master at 17.1-17-g45d361cb
Diffstat (limited to 'tests/cloud_tests/util.py')
-rw-r--r--tests/cloud_tests/util.py43
1 files changed, 43 insertions, 0 deletions
diff --git a/tests/cloud_tests/util.py b/tests/cloud_tests/util.py
index 2bbe21c7..4357fbb0 100644
--- a/tests/cloud_tests/util.py
+++ b/tests/cloud_tests/util.py
@@ -2,12 +2,14 @@
"""Utilities for re-use across integration tests."""
+import base64
import copy
import glob
import os
import random
import shutil
import string
+import subprocess
import tempfile
import yaml
@@ -242,6 +244,47 @@ def update_user_data(user_data, updates, dump_to_yaml=True):
if dump_to_yaml else user_data)
+def shell_safe(cmd):
+ """Produce string safe shell string.
+
+ Create a string that can be passed to:
+ set -- <string>
+ to produce the same array that cmd represents.
+
+ Internally we utilize 'getopt's ability/knowledge on how to quote
+ strings to be safe for shell. This implementation could be changed
+ to be pure python. It is just a matter of correctly escaping
+ or quoting characters like: ' " ^ & $ ; ( ) ...
+
+ @param cmd: command as a list
+ """
+ out = subprocess.check_output(
+ ["getopt", "--shell", "sh", "--options", "", "--", "--"] + list(cmd))
+ # out contains ' -- <data>\n'. drop the ' -- ' and the '\n'
+ return out[4:-1].decode()
+
+
+def shell_pack(cmd):
+ """Return a string that can shuffled through 'sh' and execute cmd.
+
+ In Python subprocess terms:
+ check_output(cmd) == check_output(shell_pack(cmd), shell=True)
+
+ @param cmd: list or string of command to pack up
+ """
+
+ if isinstance(cmd, str):
+ cmd = [cmd]
+ else:
+ cmd = list(cmd)
+
+ stuffed = shell_safe(cmd)
+ # for whatever reason b64encode returns bytes when it is clearly
+ # representable as a string by nature of being base64 encoded.
+ b64 = base64.b64encode(stuffed.encode()).decode()
+ return 'eval set -- "$(echo %s | base64 --decode)" && exec "$@"' % b64
+
+
class InTargetExecuteError(c_util.ProcessExecutionError):
"""Error type for in target commands that fail."""