Salt: `qvm.exists` as a state requisite (`unless`) howto?

In my salted setup I am trying to use (on dom0) unless analogous to what is shown for file.file_exists in the salt documentation:

# Ensure presence of dedicated named dispVM - not currently achievable using the qvm.vm state 20240108
Ensure presence of dedicated named dispVM:
  cmd.run:
    - name: qvm-create --class DispVM --template={{ dflt_dvm_tmplt }} --label red named-{{ dflt_dvm_tmplt }}
    - unless:
      - fun:  qvm.exists
        name: named-{{ dflt_dvm_tmplt }}

This, however, produces an error, that culminates in

KeyError: 'qvm.exists'

Any pointers on what’s wrong and how to fix that?

1 Like

Because it invokes qvm-create, I assume this state is applied in dom0?

If that’s the case, I would expect the qvm.exists function to be found… so I don’t know.

Side note: Given the error message, I’m pretty sure it doesn’t matter, but you’ve got a double space in the -fun: qvm.exists line.

Sorry I should have mentioned it from the start, but yes, this is run in dom0. Fixed above.

The double space is for esthetic reasons and indeed tests as irrelevant.

1 Like

In this particular example, you could use the command qvm.present directly instead of cmd.run. It will automatically detect the qube’s presence and not create it twice if it’s already there.

Edit: as for the unless requisite, it only accepts commands that you can use on the command line as arguments, such as qvm-ls. Correction: it also accepts modules, see unman’s answer below.

Unless is fine. But you have to use a module that actually exists.
This is what the error message is telling you.

What you are probably looking for is qvm.check:

    - unless:
      - fun: qvm.check
        args:
          - named-{{ dflt_dvm_tmplt }}
          - exists

but far better is to use qvm.present instead of that call to cmd.run
qvm.present only creates qube if it is missing.

1 Like

Thank you! for that solution! Where would I look up what module any call lets say from this list actually belongs (for future reference)?

And: My infrastructure uses a looped state like this

Assure presence of {{ ca }}:
  qvm.vm:
    - name: {{ ca }}
    - present:
      - template: {{ cstm_appvms[ca]['template']|default(dflt_tmplt) }}
      - label:    {{ cstm_appvms[ca]['label']|default(dflt_lbl) }}
    - features:
      - set:
	    - appmenus-dispvm:	{{ cstm_appvms[ca]['appmenus-dispvm']|default('0') }}
        - menu-items:           {{ cstm_appvms[ca]['menu-items']|default(dflt_menu_items) }}
        - provides_network:     {{ cstm_appvms[ca]['provides_network']|default('False') }}
        - template_for_dispvms: {{ cstm_appvms[ca]['template_for_dispvms']|default('False') }}

I was unable to get that construct to accept any --class DispVM equivalent that I require to create the named dispVM using the cmd.run call above - how would that work? I’m more than happy to (re)integrate the generation of the named dispVM back into the general solution…

Those are states - the modules can be found in the repository you linked under
_modules, and in dom0 under /srv/salt/_modules/ext_module_qvm.py

For a disposable you need to specify the disposable template as value
for template - then:

testit:
  qvm.vm:
    - name: test-disp
    - present:
      - class: DispVM
      - template: test
      - label: purple

where test is a disposable template

1 Like

This is driving me crazy. Why is this not working?

Shutdown built-dvm:
  cmd.run:
    - name:   qvm-run-vm {{ build_dvm }} -- sudo shutdown now
    - unless:
      - fun: qvm.halted
        args: 
          - {{ build_dvm }}

As far as I can tell, the qvm.halted bit is a module equivalent to what @unman is using above…

I apologize for reopening this and will move to a dedicated post.