Commit afed8dd7 authored by Jérome Perrin's avatar Jérome Perrin

console: support new `slapos console script.py` invocation

To execute a slapconsole script, we could only do:
`slapos console < script.py`
but this does not stop in case of error

or
 `echo 'execfile("script.py")' | slapos console`
but this is too complicated.

Extend this API so that we can simply use

`slapos console script.py`

inspired by `python script.py`
parent 1c5e918a
......@@ -79,6 +79,9 @@ class ConsoleCommand(ClientConfigCommand):
action='store_true',
help='Use plain Python shell')
shell.add_argument('script_file', nargs='?',
help='Script to run')
return ap
def take_action(self, args):
......@@ -86,6 +89,9 @@ class ConsoleCommand(ClientConfigCommand):
conf = ClientConfig(args, configp)
local = init(conf, self.app.log)
if args.script_file:
return execfile(args.script_file, globals(), local)
  • @jerome, FYI quick bugreport about slapos console script.py: If the script defines functions inside, then both request and supply become not available to that functions:

    #!/usr/bin/env -S slapos console
    """request fluentds for 1) sensor, and 2) IoT gw  to simulate Wendelin Learning Track Lecture 4.3"""
    
    fluentd="/srv/slapgrid/slappart31/srv/project/slapos/software/fluentd/software.cfg"
    
    
    cfg_gw = """
    ...
    """
    
    # frequest requests fluentd instance named as specied and configured according to conf_text.
    def frequest(name, conf_text):
        request(fluentd, name, filter_kw={"computer_guid": "slaprunner"},
                partition_parameter_kw={"conf_text": conf_text})
    
    frequest("tut-fluentd-gw", cfg_gw)
    #frequest("tut-fluentd-sensor", ...)
    slapuser31@rapidspace-hosting-000:~/srv/project$ slapos console krequest-fluentd.py 
    2022-12-19 08:41:30 slapos[33863] ERROR name 'request' is not defined
    Traceback (most recent call last):
      File "/opt/slapos/eggs/slapos.core-1.8.5-py3.7.egg/slapos/cli/entry.py", line 305, in run_subcommand
        result = cmd.run(parsed_args)
      File "/opt/slapos/eggs/slapos.core-1.8.5-py3.7.egg/slapos/cli/command.py", line 56, in run
        return self.take_action(parsed_args)
      File "/opt/slapos/eggs/slapos.core-1.8.5-py3.7.egg/slapos/cli/console.py", line 98, in take_action
        return exec_(code, globals(), local)
      File "krequest-fluentd.py", line 36, in <module>
        frequest("tut-fluentd-gw", cfg_gw)
      File "krequest-fluentd.py", line 33, in frequest
        request(fluentd, name, filter_kw={"computer_guid": "slaprunner"},
    NameError: name 'request' is not defined

    and even if I workaround that via def frequest(..., request=request), then all the global-to-that-script.py variables are also unavailable to that function too:

    slapuser31@rapidspace-hosting-000:~/srv/project$ slapos console krequest-fluentd.py 
    2022-12-19 08:45:36 slapos[6973] ERROR name 'fluentd' is not defined
    Traceback (most recent call last):
      File "/opt/slapos/eggs/slapos.core-1.8.5-py3.7.egg/slapos/cli/entry.py", line 305, in run_subcommand
        result = cmd.run(parsed_args)
      File "/opt/slapos/eggs/slapos.core-1.8.5-py3.7.egg/slapos/cli/command.py", line 56, in run
        return self.take_action(parsed_args)
      File "/opt/slapos/eggs/slapos.core-1.8.5-py3.7.egg/slapos/cli/console.py", line 98, in take_action
        return exec_(code, globals(), local)
      File "krequest-fluentd.py", line 36, in <module>
        frequest("tut-fluentd-gw", cfg_gw)
      File "krequest-fluentd.py", line 33, in frequest
        request(fluentd, name, filter_kw={"computer_guid": "slaprunner"},
    NameError: name 'fluentd' is not defined

    Offhand I would say changing exec(script_py, globals(), local) -> exec(script_py, local, local) might fix this.

  • ah yes, there was something wrong here. I noticed this too sometimes ago but never found the time to investigate. That fix you suggest seems good, can you please take a look at !469 (merged) here I integrate your fix with a quick test to reproduce the issue

Please register or sign in to reply
if not any([args.python, args.ipython, args.bpython]):
args.ipython = True
......
......@@ -191,3 +191,20 @@ master_url=null
self.mock_request.assert_called_once_with('software_release', 'instance')
self.assertIn('parameter_value', app_stdout.getvalue())
def test_console_script(self):
with tempfile.NamedTemporaryFile() as script:
script.write(
"""print request('software_release', 'instance').getInstanceParameterDict()['parameter_name']\n""")
script.flush()
app = slapos.cli.entry.SlapOSApp()
saved_stdout = sys.stdout
try:
sys.stdout = app_stdout = StringIO.StringIO()
app.run(('console', '--cfg', self.config_file.name, script.name))
finally:
sys.stdout = saved_stdout
self.mock_request.assert_called_once_with('software_release', 'instance')
self.assertIn('parameter_value', app_stdout.getvalue())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment