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

Марионетка не выполняет команду

Puppet 0.25.4 в ubuntu в упор отказывается выполнять следующую команду:

exec {"initiate replica set":
    command => "echo 'rs.initiate()' | mongo",
    path => ["/usr/bin","/usr/sbin","/bin"],
    user => "root",
    require => Class["mongodb"]
}

Я могу выполнить команду как root, так что я предполагаю, что это проблема оболочки. К сожалению, обновление марионетки невозможно (и в любом случае вызывает другие проблемы).

Я попытался указать явные пути к двоичным файлам вместо того, чтобы полагаться на параметр пути, а также изменил команду на:

"bash -c \"echo 'rs.initiate()' | mongo\""

По-прежнему не работает.

Любые идеи?

Я получаю сообщение об ошибке вроде «не удалось изменить с notrun на 0»

Посмотрите, что на самом деле возвращает команда при запуске в качестве оболочки от root, запустив echo $? после выполнения фактической команды, вероятно, она вернет не 0. Если это так, вам нужно изменить оператор на:

exec {"initiate replica set":
    command => "echo 'rs.initiate()' | mongo",
    path => ["/usr/bin","/usr/sbin","/bin"],
    user => "root",
    require => Class["mongodb"],
    returns => $ActualReturnCode
}

Где $ ActualReturnCode - это код, который вы получаете от echo $? после выполнения команды от имени пользователя root.

Есть еще одна вещь о mongodb, которую я забыл упомянуть - когда вы устанавливаете пакет, потребуется некоторое время для инициализации основной базы данных mongodb, до тех пор, пока вы не сможете получить к ней доступ. Таким образом, обходным путем здесь было бы также добавить сон и несколько повторных попыток, чтобы код выглядел так:

exec {"initiate replica set":
    command => "echo 'rs.initiate()' | mongo",
    path => ["/usr/bin","/usr/sbin","/bin"],
    user => "root",
    require => Class["mongodb"],
    retries => 5,
    sleep   => 60,
}

Puppet 3 имеет новый синтаксис для типа ресурса exec:

https://puppet.com/docs/puppet/3.8/types/exec.html

как таковой, код из LogicWreck и Golja немного устарел. Параметр retries сейчас tries и sleep параметр сейчас try_sleep.

  exec { 'rs.initiate()':
     command     => 'echo "rs.initiate()" | mongo',
     path        => ['/usr/bin', '/usr/sbin', '/bin'],
     user        => root,
     require     => Service[mongodb],
     tries       => 5,
     try_sleep   => 60,
     unless      => 'echo "rs.status()" | mongo | grep "members"'
  }

Вы можете подумать об использовании здесь параметра 'except' или 'onlyif', чтобы ваш ресурс оценивался только при первой настройке набора реплик.

Один из способов сделать это:

exec {"initiate replica set":
      command => mongo admin /path/to/init.js",
      path => ["/usr/bin","/usr/sbin","/bin"],
      user => "root",
      require => Class["mongodb"],
      sleep => 60,
      retries => 5,
}

Где init.js:

res = rs.initiate()
printjson(res)

Это вернет 0, если команда была выполнена без ошибок. Использовать printjson(res) только для режима разработки / отладки. В дальнейшем от этого можно избавиться.

Также, как сказал Logic Wreck, обязательно используйте sleep, потому что выполнение initiate может занять несколько секунд.