19

I tried to add:

 mypack:
   pkg:
     - installed
     - pkgs:
       - mercurial
       - git
   cmd.run:
       - name: 'mkdir -p /opt/mypack'
   cmd.run: 'hg pull -u -R /opt/mypack || hg clone -R /opt https://...'
   cmd.run: 'ln -s /opt/mypack/etc/init.d/xxx /etc/init.d/xxx'

But for some reason this the state seems to execute/install but the commands are not executed, or at least not all of them.

I need a solution to run multiple commands and to fail the deployment if any of these fails.

I know that I could write a bash script and include this bash script, but I was looking for a solution that would work with only the YAML file.

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
sorin
  • 161,544
  • 178
  • 535
  • 806

4 Answers4

57

You want this:

cmd-test:
  cmd.run:
    - name: |
        mkdir /tmp/foo
        chown dan /tmp/foo
        chgrp www-data /tmp/foo
        chmod 2751 /tmp/foo
        touch /tmp/foo/bar

Or this, which I would prefer, where the script is downloaded from the master:

cmd-test:
  cmd.script:
    - source: salt://foo/bar.sh
    - cwd: /where/to/run
    - user: fred
Dan Garthwaite
  • 3,436
  • 4
  • 22
  • 32
  • One reason the second version is better is that the logs end up cleaner - otherwise the entire text of the embedded script appears (jammed onto one line) several times in the output log. – Steve Bennett Jul 24 '14 at 23:21
  • 2
    Thanks SteveBennett. I'm hoping @sorin would mark my answer as a solution. – Dan Garthwaite Jul 25 '14 at 13:24
  • 2
    Why I can't find a mention of `-name: |` in Salt's documentation? Not very googleable, ok. – giorgiosironi Dec 13 '17 at 16:45
  • 1
    @giorgiosironi That's a way in YAML to specify a multi-line inline value. You're not seeing it in Salt's docs because it's not specific to Salt. – Yobert Aug 14 '18 at 20:19
  • Caveat: what you probably want to do here is to place `&&` between commands so that execution is stopped on the first one that fails. – giorgiosironi Aug 15 '18 at 15:22
14

In addition to the above (better) suggestions, you can do this:

cmd-test:
  cmd.run:
    - names: 
      - mkdir -p /opt/mypack
      - hg pull -u -R /opt/mypack || hg clone -R /opt https://...
      - ln -s /opt/mypack/etc/init.d/xxx /etc/init.d/xxx

For reasons I don't understand yet (I'm a Salt novice), the names are iterated in reverse order, so the commands are executed backwards.

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • 6
    I don't think it's that they're in reverse order, just that the actual YAML ordering of items in a list is arbitrary, and you never know how it's going to see them – Thrill Science Jul 24 '14 at 19:15
  • 2
    @ThrillScience It's not YAML (lists are guaranteed to be ordered) but 'names' is special. It actually generates individual cmd.run states for each of the specified names. You can verify this by running `salt-call state.show_sls --out=yaml whatever`. See https://docs.saltstack.com/en/latest/ref/states/highstate.html#names-declaration The reversed state order was a 'names' implementation bug which I believe has been fixed. – notpeter Jul 12 '17 at 18:52
4

You can do as Dan pointed out, using the pipe or a cmd.script state. But it should be noted that you have some syntax problems in your original post. Each new state needs a name arg, you can't just put the command after the colon:

mypack:
  pkg:
    - installed
    - pkgs:
      - mercurial
      - git
  cmd.run:
    - name: 'my first command'
  cmd.run:
    - name: 'my second command'

However, that actually may fail as well, because I don't think you can put multiple of the same state underneath a single ID. So you may have to split them out like this:

first:
  cmd.run:
    - name: 'my first command'

second:
  cmd.run:
    - name: 'my second command'
Colton Myers
  • 1,321
  • 9
  • 12
  • Indeed, you're right: there is only one command allowed per id per YAML parsing as a dictionary, so one pkg and one cmd can coexist, but not two cmd. – Dereckson Nov 17 '17 at 01:56
0

As one of the users pointed out above, this works in proper order (salt 3000.2)


install_borg:
    cmd.run:
        - names: 
            - cd /tmp
            - wget https://github.com/borgbackup/borg/releases/download/1.1.15/borg-linux64
            - mv borg-linux64 /usr/local/bin/borg
            - chmod u+x /usr/local/bin/borg
            - chown root:root /usr/local/bin/borg
            - ln -s /usr/local/bin/borg /usr/bin/borg
        - unless: test -f /usr/bin/borg
perfecto25
  • 772
  • 9
  • 13