Conciso
A soma de verificação do arquivo será verificada e subseqüentemente liberada. Esta soma de verificação será comparada com o arquivo que será gravado. Se houver uma discrepância, a gravação falhará.
Verbose
O erro é lançado pelo seguinte método, que é definido no arquivo. rb :
# Make sure the file we wrote out is what we think it is.
def fail_if_checksum_is_wrong(path, content_checksum)
newsum = parameter(:checksum).sum_file(path)
return if [:absent, nil, content_checksum].include?(newsum)
self.fail "File written to disk did not match checksum; discarding changes (#{content_checksum} vs #{newsum})"
end
e este método contém o seguinte método que reside na soma de verificação. rb :
def sum_file(path)
type = digest_algorithm()
method = type.to_s + "_file"
"{#{type}}" + send(method, path).to_s
end
Como é calculado o checksum?
O método responsável por isso também reside no arquivo.rb:
def write(property)
remove_existing(:file)
mode = self.should(:mode) # might be nil
mode_int = mode ? symbolic_mode_to_int(mode, Puppet::Util::DEFAULT_POSIX_MODE) : nil
if write_temporary_file?
Puppet::Util.replace_file(self[:path], mode_int) do |file|
file.binmode
content_checksum = write_content(file)
file.flush
fail_if_checksum_is_wrong(file.path, content_checksum) if validate_checksum?
if self[:validate_cmd]
output = Puppet::Util::Execution.execute(self[:validate_cmd].gsub(self[:validate_replacement], file.path), :failonfail => true, :combine => true)
output.split(/\n/).each { |line|
self.debug(line)
}
end
end
else
umask = mode ? 000 : 022
Puppet::Util.withumask(umask) { ::File.open(self[:path], 'wb', mode_int ) { |f| write_content(f) } }
end
# make sure all of the modes are actually correct
property_fix
end
O snippet que verifica a soma de verificação: content_checksum = write_content(file)
:
# write the current content. Note that if there is no content property
# simply opening the file with 'w' as done in write is enough to truncate
# or write an empty length file.
def write_content(file)
(content = property(:content)) && content.write(file)
end
O seguinte snippet:
content_checksum = write_content(file)
file.flush
fail_if_checksum_is_wrong(file.path, content_checksum) if validate_checksum?
indica que há uma discrepância entre o arquivo que será gravado e realmente está escrito.
Discussão
The latter checksum (d41d8...) is the checksum of an empty file.
Como você verificou isso?
So I think this is what's happening: Puppet sees that the change needs to be made, and makes the change. But it checksums the file again before the write is committed, so it doesn't see that the change was successfully made, and so it rolls back.
O código, conforme explicado acima, funciona sempre como explicado e, de acordo com minha experiência, a verificação de checksum funciona.
Conclusão
Parece que há problemas com o GlusterFS, por exemplo O arquivo que foi implantado usando o Puppet foi alterado por algum motivo pelo GlusterFS.
Sugestão
Sugiro depurar o problema da seguinte forma:
- Implantar o arquivo 1 com o conteúdo X no Puppet
- Implemente este arquivo no GlusterFS usando o Puppet
- Verifique a soma de verificação do arquivo 1 que reside no servidor de puppets manualmente
- Verifique a soma de verificação do arquivo 1 que reside no GlusterFS manualmente
- Execute o Puppet no GlusterFS e verifique se o problema ocorre