使用 Puppet 同步两个目录

使用 Puppet 同步两个目录

我有一堆服务器,上面有两个目录需要同步。例如,在同一台服务器上/var/path/to/dir1/var/path/to/dir2每个目录下都有文件和文件夹。我想同步/var/path/to/dir1/var/path/to/dir2作为“备份”。

有人知道在 Puppet 中同步这两个目录的有效方法吗?我是否必须创建一个自定义脚本来执行此操作并使用execPuppet 清单文件中的方法?

我的猜测是创建一个脚本,以递归方式验证主目录中每个文件的 MD5 哈希值,然后使用该列表验证第二个目录中的文件。我不确定是否有办法在 Puppet 中原生执行此操作。

答案1

您在使用 puppet 方面走在正确的道路上。让 puppetmaster 充当事实来源,将它们放在运行 puppetmaster 的服务器中,并在那里声明应该存在的文件和规范版本。您甚至可能希望使用 SVN 或 GIT 之类的工具对在 puppetmaster 服务器中提供的文件进行版本控制。

这为您提供了有关这两个位置的情况的有力保证。

file { '/var/path/to/dir1/':
  ensure   => 'present',
  source   => 'puppet:///path/to/dir1',
  recurse  => 'true',
} 
file { '/var/path/to/dir2/':
  ensure   => 'present',
  source   => 'puppet:///path/to/dir1',
  recurse  => 'true',
}

如上所述,您可能需要使用类似以下命令删除所有收集到的不受欢迎的额外内容

{
  purge => 'true',
  force => 'true',
}

正如有人向我指出的那样(谢谢!!),如果“/var/path/to/dir1/”下有大量文件或深层子文件夹,完成 puppet 运行的时间可能会迅速增加。我仍然建议将 puppet 服务器作为事实来源,但使用 rsync 可能会更好,例如:

rsync::get { '/var/path/to/dir1/':
  source  => 'puppet:///path/to/dir1',
  purge   => true,
}

rsync::get { '/var/path/to/dir2/':
  source  => 'puppet:///path/to/dir1',
  purge   => true,
}

答案2

我很好奇并尝试了一下:

[root@localhost vagrant]# cat test.pp
file { '/tmp/path2':
  ensure  => directory,
  source  => 'file:///tmp/path1',
  recurse => true,
  purge   => true,
  force   => true,
}

[root@localhost vagrant]# ls -lR /tmp/path1
/tmp/path1:
total 4
-rw-r--r-- 1 root root    0 Nov 29 01:55 bar
drwxr-xr-x 2 root root 4096 Nov 29 02:07 folder
-rw-r--r-- 1 root root    0 Nov 29 01:55 foo
-rw-r--r-- 1 root root    0 Nov 29 01:55 x

/tmp/path1/folder:
total 0
-rw-r--r-- 1 root root 0 Nov 29 02:07 xxx
[root@localhost vagrant]# ls -lR /tmp/path2/
/tmp/path2/:
total 4
-rw-r--r-- 1 root root    0 Nov 29 02:17 deleteme
drwxr-xr-x 2 root root 4096 Nov 29 02:17 folder2

/tmp/path2/folder2:
total 0
-rw-r--r-- 1 root root 0 Nov 29 02:17 deleteme
[root@localhost vagrant]# puppet apply test.pp 
Notice: Compiled catalog for localhost in environment production in 0.04 seconds
Notice: /Stage[main]/Main/File[/tmp/path2/x]/ensure: defined content as '{md5}d41d8cd98f00b204e9800998ecf8427e'
Notice: /Stage[main]/Main/File[/tmp/path2/deleteme]/ensure: removed
Notice: /Stage[main]/Main/File[/tmp/path2/folder]/ensure: created
Notice: /Stage[main]/Main/File[/tmp/path2/folder/xxx]/ensure: defined content as '{md5}d41d8cd98f00b204e9800998ecf8427e'
Notice: /Stage[main]/Main/File[/tmp/path2/bar]/ensure: defined content as '{md5}d41d8cd98f00b204e9800998ecf8427e'
Notice: /Stage[main]/Main/File[/tmp/path2/folder2]/ensure: removed
Notice: /Stage[main]/Main/File[/tmp/path2/foo]/ensure: defined content as '{md5}d41d8cd98f00b204e9800998ecf8427e'
Notice: Finished catalog run in 0.06 seconds
[root@localhost vagrant]# diff -r /tmp/path1 /tmp/path2
[root@localhost vagrant]#

这样就行了。
请注意,您force => true,也需要这样做。
否则目标路径中的现有文件夹将不会被删除。

或者类似这样的方法也可以:

rsync::get { '/backup/foo':
  source  => '/foo',
  purge   => true,
}

相关内容