Назад | Перейти на главную страницу

Остановить мастер марионеток, пока Exec запускает сценарий

Я новичок в марионетке и думаю, есть ли способ применить ресурс только после того, как команда, инициированная Exec, завершит свою работу. Мое требование состоит в том, что я должен планировать задание резервного копирования только после завершения другого задания. Мой код, приведенный ниже, не работает. Хрон будет запланирован, как только будет инициировано задание основного резервного копирования.

Изменить: мне нужно запускать основное задание только один раз за время жизни контейнера (с помощью докера). Первичное задание резервного копирования может занять до 5 часов, а вторичное - около часа. Primary-backup-script.py использует модуль subprocess.popen для запуска задания, которое разветвляет задание в фоновом режиме, но я не думаю, что это важно. Поправьте меня, если я ошибаюсь.

exec{ 'primary-backup-job':
    command     => '/path/primary-backup-script.py',
    require     => File['/path/primary-backup-script.py'],
    refreshonly => true,
    }

# Schedule cron job only after primary backup is completed.
cron{ schedule-secondary-backup:
    command => "/path/secondary-backup-script.py",
    require => Exec['primary-backup-job'],
    user    => root,
    hour    => 05,
    minute  => 00,
    weekday => 1-5;
    }

Есть мысли или предложения?

Хм .. Ну так как он работает в фоновом режиме, сложно что-то вызвать в ответ на его завершение. Как бы вы относились к переключению вторичного на что-то вроде этого:

exec { 'secondary-backup':
    command => "/path/secondary-backup-script.py",
    unless  => "/bin/ps -ef | /bin/grep primary-backup-script",
}

..с параметрами grep, установленными на то, что найдет основной процесс резервного копирования?

Это приведет к вторичному срабатыванию при следующем запуске Puppet после завершения первичного резервного копирования.

Вы неправильно используете инструмент. Puppet - это декларативный язык, то есть вы должны объявлять состояния с помощью puppet, а не управлять вещами. Вы, конечно, можете это сделать, но это сложнее, это будет выглядеть неуклюже и подвержено ошибкам.

При использовании марионетки следует по возможности избегать использования ресурса exec. Зачем? Поскольку exec является внешним по отношению к «конечному автомату» - это означает, что exec будет изменять систему (для марионетки) неконтролируемым и неизвестным образом.

Связывание других ресурсов с exec может даже ухудшить ситуацию.

Следующая проблема заключается в том, что puppet - это не задание cron, поэтому вам следует избегать запуска заданий через exec из самого Puppet. Вот почему у нас есть cron.

В вашем конкретном случае, не было бы проще добавить однострочник для создания задания cron в конец исходного скрипта? У вас будет несколько преимуществ:

  • нет необходимости внедрять сложные и подверженные ошибкам хаки для обмена сообщениями с другими процессами
  • нет необходимости внедрять сторожевой таймер
  • нет необходимости отлаживать различные проблемы, которые воля выйти из этого решения.

Если возможно - просто добавьте создание cron в конец исходного скрипта первого резервного копирования. Если это проприетарный инструмент или скрипт - и вы не можете его редактировать, просто создайте простую оболочку bash и вызовите эту оболочку через ресурс exec.

Если вы хотите управлять cron из самой марионетки, вы все равно можете это сделать, но старайтесь избегать связывания ресурсов exec и cron вместе.

Что я бы сделал в этом случае (где вы хотите / должны управлять cron из кода марионетки):

cron { schedule-secondary-backup:
  command => "pgrep primary-backup-script && echo 'still running' || /path/secondary-backup-script.py",
  user    => root,
  hour    => 05,
  minute  => 00,
  weekday => 1-5;
}

Другое решение - изменить первичный скрипт для создания файла в файловой системе, когда он завершится выполнением, и использовать следующую команду cron в предыдущем определении ресурса:

  command => "[ ! -e /path/to/first_script_finished_file ] && /path/secondary-backup-script.py",

Надеюсь это поможет.