This commit adds a Run() class that can invoke Python's Popen
command.  This class provides a static method, run(), that will
execute the command via Python's subprocess module.

Example usages:
  # delete foo.conf
  Run.run(['rm', '-f', '/tmp/foo.conf'])

  # Use cgset to set SomeCgroup's cpu.shares to 500
  cmd = ['cgset', '-r', 'cpu.shares=500', 'SomeCgroup']
  Run.run(cmd)

  # get info on current user
  Run.run('id')

  # write to a file.  Note that this must be run in a shell
  Run.run(['echo', 'some data', '>>', 'some_file'], shell_bool=True)

Example output:

  Jun 27 12:34:18: DEBUG: run:
          command = sudo lxc-info --config=lxc.rootfs -n test_libcg
          ret = 0
          stdout = lxc.rootfs = /container/test_libcg/rootfs
          stderr =

  Jun 27 12:34:18: DEBUG: run:
          command = sudo lxc-attach -n test_libcg -- 
/libcg/src/tools/.libs/cgget -n -v -r cpu.shares 001cgget
          ret = 0
          stdout = 512
          stderr =

If the command fails, Run.run() throws a RunError exception which
contains the return code, stdout, and stderr from the command.

Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com>
Reviewed-by: Dhaval Giani <dhaval.gi...@oracle.com>
---
 tests/ftests/run.py | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)
 create mode 100644 tests/ftests/run.py

diff --git a/tests/ftests/run.py b/tests/ftests/run.py
new file mode 100644
index 0000000..80e5221
--- /dev/null
+++ b/tests/ftests/run.py
@@ -0,0 +1,74 @@
+#
+# Run class for the libcgroup functional tests
+#
+# Copyright (c) 2019 Oracle and/or its affiliates.  All rights reserved.
+# Author: Tom Hromatka <tom.hroma...@oracle.com>
+#
+
+#
+# This library is free software; you can redistribute it and/or modify it
+# under the terms of version 2.1 of the GNU Lesser General Public License as
+# published by the Free Software Foundation.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, see <http://www.gnu.org/licenses>.
+#
+
+from log import Log
+import subprocess
+import time
+
+class Run(object):
+    @staticmethod
+    def run(command, shell_bool=False):
+        if shell_bool:
+            if isinstance(command, str):
+                # nothing to do.  command is already formatted as a string
+                pass
+            elif isinstance(command, list):
+                command = ' '.join(command)
+            else:
+                raise ValueError('Unsupported command type')
+
+        subproc = subprocess.Popen(command, shell=shell_bool,
+                                   stdout=subprocess.PIPE,
+                                   stderr=subprocess.PIPE)
+        out, err = subproc.communicate()
+        ret = subproc.returncode
+
+        out = out.strip()
+        err = err.strip()
+
+        if shell_bool:
+            Log.log_debug(
+                "run:\n\tcommand = {}\n\tret = {}\n\tstdout = {}\n\tstderr = 
{}".format(
+                command, ret, out, err))
+        else:
+            Log.log_debug(
+                "run:\n\tcommand = {}\n\tret = {}\n\tstdout = {}\n\tstderr = 
{}".format(
+                ''.join(command), ret, out, err))
+
+        if ret != 0:
+            raise RunError("Command '{}' failed".format(''.join(command),
+                           command, ret, out, err))
+
+        return out
+
+class RunError(Exception):
+    def __init__(self, message, command, ret, stdout, stderr):
+        super(RunError, self).__init__(message)
+
+        self.command = command
+        self.ret = ret
+        self.stdout = stdout
+        self.stderr = stderr
+
+    def __str__(self):
+        out_str = "RunError:\n\tmessage = {}\n\tret = {}".format(self.message, 
self.ret)
+        out_str += "\n\tstdout = {}\n\tstderr = {}".format(self.stdout, 
self.stderr)
+        return out_str
-- 
1.8.3.1



_______________________________________________
Libcg-devel mailing list
Libcg-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libcg-devel

Reply via email to