Uruchom zdalny skrypt / aplikację w trybie odłączonym w Ansible

8

Mam problem z uruchomieniem skryptu uruchamiania aplikacji „osobno” z podręcznika Ansible. Skrypt się uruchomi, ale nie mogę go dostać, aby się oderwać. Prawdopodobnie robię coś złego, ale co?

Oto mój odtwarzacz.

  1. Moja zdalna aplikacja Java w Test.java działa przez 10 sekund:

    class Test {
        public static void main(String[] args) {
            for (int I = 1; I <= 10; i++) {
                System.out.println("Hello world " + I);
    
                try { Thread.sleep(1000);
                } catch (Exception e) { System.out.println("Exception caught: " + e);
                }
    } } }

Kompilacja tego do Test.class (javac Test.java), a następnie uruchomienie tej klasy z „java Test” działa zgodnie z oczekiwaniami (daje 10 komunikatów wyjściowych, a następnie kończy działanie).

  1. Mój wykonywalny skrypt powłoki (jak w chmod 755) z uruchomioną aplikacją wygląda następująco:

    #!/bin/bash
    java Test &

Uruchamianie tego ręcznie jest również w pełni poprawne: aplikacja Java działa i generuje takie same standardowe dane wyjściowe w mojej konsoli, ale skrypt powłoki zakończył się i znów mam kontrolę nad moją sesją bash.

  1. Teraz, aby uruchomić go przez odpowiadający podręcznik z innego serwera. Próbowałem używać modułu „polecenie” i modułu „powłoka” na różne sposoby, ale bezskutecznie ...

    ---
    - hosts: vagrant1
      gather_facts: false
    
      tasks:
      - debug: msg="Running test app through Ansible shell module..."
    
      - name: Start application
        shell: "/tmp/test.sh"
        args:
          chdir: "/tmp"
          executable: "/bin/bash"
    
      - debug: msg="Running test app through Ansible command module..."
    
      - name: Start application
        command: "nohup /tmp/test.sh &"
        args:
          chdir: "/tmp"

Wszystko działa dobrze, tzn. Działa skrypt powłoki, aplikacja Java działa i działa (tzn. Działa przez 10 sekund, generuje dane wyjściowe i kończy pracę). Ale ansible-playbook działa do momentu zakończenia aplikacji Java, a następnie zwraca dane wyjściowe wygenerowanej aplikacji Java. Dlaczego po prostu nie odłączy skryptu powłoki i nie dokończy poradnika?

Wyjście z ansible-playbook to:

    monsterkill@monsterkill-ub-dt:~/playbooks$ ansible-playbook testrun.yaml -v

    PLAY [vagrant1] *************************************************************** 

    TASK: [debug msg="Running test app through Ansible shell module..."] ********** 
    ok: [vagrant1] => {
        "msg": "Running test app through Ansible shell module..."
    }

    TASK: [Start application] ***************************************************** 
    changed: [vagrant1] => {"changed": true, "cmd": " /tmp/test.sh ", "delta": "0:00:10.052927", "end": "2015-01-29 00:14:43.327418", "rc": 0, "start": "2015-01-29 00:14:33.274491", "stderr": "", "stdout": "Hello world 1\nHello world 2\nHello world 3\nHello world 4\nHello world 5\nHello world 6\nHello world 7\nHello world 8\nHello world 9\nHello world 10"}

    TASK: [debug msg="Running test app through Ansible command module..."] ******** 
    ok: [vagrant1] => {
        "msg": "Running test app through Ansible command module..."
    }

    TASK: [Start application] ***************************************************** 
    changed: [vagrant1] => {"changed": true, "cmd": ["nohup", "/tmp/test.sh", "&"], "delta": "0:00:10.045643", "end": "2015-01-29 00:14:53.557164", "rc": 0, "start": "2015-01-29 00:14:43.511521", "stderr": "nohup: ignoring input", "stdout": "Hello world 1\nHello world 2\nHello world 3\nHello world 4\nHello world 5\nHello world 6\nHello world 7\nHello world 8\nHello world 9\nHello world 10"}

    PLAY RECAP ******************************************************************** 
    vagrant1                   : ok=4    changed=2    unreachable=0    failed=0
SadBunny
źródło

Odpowiedzi:

16

Wystarczy użyć akcji asynchronicznej z poll: 0:

- command: yourscript.sh
  async: 45
  poll: 0

Te opcje są potrzebne, aby zapobiec zabiciu przez ansible procesów potomnych tego zadania za pomocą os.killpg .

Następnie w yourscript.sh:

java Test &
disown

disown usuwa proces z tabeli zadań, więc SIGHUP nie jest do niego wysyłany. nohup robi to samo, ale nie jest konieczne.

Edycja : Zauważ, że disown nie jest dostępny we wszystkich powłokach (np. Myślnik)

użytkownik1338062
źródło
Cześć, co należy zrobić, aby uruchomić polecenie w nieskończoność w tle i nie blokować odpowiedzi? Opcja pozwala asynchroniczny skrypt do uruchomienia tylko przez 45 sekund, a następnie kończy to chcę, aby uruchomić polecenie nieskończoność jestem już przy użyciu polecenia nohup & opcję ale polecenie kończy się czas chwila asynchroniczny jest obecnie I ustawione ankieta do 0
Mrunal Gosar
Cześć, mam do czynienia z tym samym problemem, a zadania asynchroniczne działają dobrze. Jednak nie znalazłem jasnego wyjaśnienia, a także nie znalazłem części kodu programu ansible, która zabija proces potomny. Jakaś pomoc ?
Kassav '12
6

Uruchamianie skryptu jako demona z start-stop-demonem wydaje się tutaj bardziej eleganckim rozwiązaniem. http://manpages.ubuntu.com/manpages/raring/man8/start-stop-daemon.8.html

- name: Start application
  shell: "start-stop-daemon --start --quiet --pidfile /var/run/test --exec /tmp/test.sh"
  args:
    executable: "/bin/bash"
MillerGeek
źródło
Podaj wszystkie istotne informacje w swojej odpowiedzi. Linki zewnętrzne świetnie nadają się na odniesienia i dalsze czytanie, ale nie powinny stanowić całej treści odpowiedzi.
David Richerby
5

Serwery Google muszą już palić, ale znalazłem rozwiązanie. Kiedy zdałem sobie sprawę, że Ansible wykonuje wszystkie swoje zdalne polecenia za pomocą oddzielnych wywołań ssh, przetestowałem to ręcznie z serwera ansible i stwierdziłem, że ma to związek z funkcjonalnością ssh.

Najwyraźniej odpowiedzią jest, aby skrypt, który wezwałem do wykonania podwójnej sztuczki w tle, był połączony z nohup, aby ignorować sygnały zawieszenia (SIGHUP) i połączone z rozłączaniem strumieni stdout i stderr. Tak więc skrypt zdalnego uruchamiania nie wykonuje już:

java Test &

... ale zamiast tego teraz:

( ( nohup java Test 1>/dev/null 2>&1 ) & )

co robi co chcę. Poradnik ansible uruchamia teraz zdalny skrypt, który z kolei uruchamia aplikację Java, ale następnie uruchamia podwójne tło i nie uruchamia go oraz rozłącza strumienie wyjściowe.

Ten wątek przepełnienia stosu pomógł mi.

SadBunny
źródło