如何使用人偶脚本创建具有同名主要组的用户?

How to create user having a primary group with the same name using puppet script?

我正在阅读 this article,它建议使用以下代码创建用户:

user { 'myuser':
  ensure     => present,
  uid        => '1000',
  gid        => '1000',
  shell      => '/bin/bash',
  home       => '/home/myuser'
}

然而,当我 运行 它时,抛出以下错误:

Error: Could not create user myuser: Execution of '/usr/sbin/useradd -g 1000 -G wheel -d /home/myuser -s /bin/bash -u 1000 -M myuser' returned 6: useradd: group '1000' does not exist

我让它与以下项目一起工作:

group {'myuser':
  ensure     => present
}

user { 'myuser':
  ensure     => present,
  uid        => '1000',
  gid        => 'myuser',
  shell      => '/bin/bash',
  home       => '/home/myuser'
}

但我不确定这种方法是否正确。有没有办法只使用 user 人偶资源来实现我想要的?

我认为答案取决于您用来创建用户的 OS and/or 提供商。在您的配置中它是 useradd。根据 documentation,当与 -g 选项一起使用时:

The group name must exist. A group number must refer to an already existing group.

可能的解决方案是删除 gid:

user { 'myuser':
    ensure     => present,
    uid        => '1020',
    shell      => '/bin/bash',
    home       => '/home/myuser',
    managehome => true,
}

然后puppet会自动创建poper组:

root@vagrant-ubuntu-trusty-64:/home# su myuser

myuser@vagrant-ubuntu-trusty-64:/home$ id

uid=1020(myuser) gid=1020(myuser) groups=1020(myuser)

添加一个选项是个好主意managehome => true,。它将:

create the home directory when ensure => present, and delete the home directory when ensure => absent

这实际上非常简单,Puppet 正在尝试创建您要求的新用户,但 OS 告诉它不能,因为具有您指定的 GID 的组确实不存在。

您为解决此问题所做的工作是正确的,但可以说遗漏了几件事。首先,您应该指定有关组的更多信息,而不仅仅是名称(从资源标题 'myuser' 中收集)。这不是什么大问题,但在您的第一个块中,用户和组的 ID 均为 1000。而在您的第二个块中,将生成 GID,但 OS 决定生成它。您可以通过指定组的 GID 然后在您的用户声明中使用该 GID 来更紧密地管理它。

其次,由于在 Puppet 中无法保证顺序,因此您需要考虑这样一种可能性,即使您的组已声明为您现在拥有的组,它也可能并不总是 运行 首先,比如当用户资源出现在编译目录中的组之前。在这种情况下,您将 运行 陷入同样的​​问题。

这是解决此问题的一种方法:

group {'myuser':
  ensure     => present,
  gid        => 1000,
  before     = User['myuser']
}

user { 'myuser':
  ensure     => present,
  uid        => '1000',
  gid        => '1000',
  shell      => '/bin/bash',
  home       => '/home/myuser',
  requires   => Group['myuser']
}

注意在用户和组中设置的requiresbefore参数。将 requires 参数设置为 Group['myuser'] 将确保指定的组始终在声明用户之前应用。 before 也是如此,两者都可用于获得相同的结果。

另一种处理方法是使用 notifiessubscribe。 Puppet 有一个关于资源排序的很棒的页面:https://docs.puppetlabs.com/puppet/latest/reference/lang_relationships.html

最后,我最喜欢的资源链接之一是资源链:

group {'myuser':
  ensure     => present,
  gid        => 1000
} ->
user { 'myuser':
  ensure     => present,
  uid        => '1000',
  gid        => '1000',
  shell      => '/bin/bash',
  home       => '/home/myuser'
}

这也保证了上面提到的相同配置,真正可以派上用场。正如我之前所说,尤其是在模块的 init 中订购 classes 时。

例如:

class sampleclass (
    $ensure,
)inherits sampleclass::params{
  class { 'sampleclass::accounts': } ->
  class { 'sampleclass::files': } ->
  class { 'sampleclass::repo': } ->
  class { 'sampleclass::links': } ->
  class { 'sampleclass::config': }
}

希望对您有所帮助!