Editando arquivos do tipo INI com um script

Editando arquivos do tipo INI com um script

Estou escrevendo um script para automatizar a configuração dos arquivos de configuração do agente Puppet no Docker.

Basicamente, preciso garantir que a seguinte seção esteja em /etc/puppet/puppet.conf:

[agent]
server=$PUPPETMASTER_HOSTNAME
masterport=$PUPPETMASTER_PORT

O que tenho feito até agora em meu script runit do agente Puppet é o seguinte:

function write_puppet_config () {
    read -d '' puppet_config <<EOF
[agent]
server=$1
masterport=$2
EOF

    echo -e "$puppet_config" >> /etc/puppet/puppet.conf
}

# default puppet master port is 8410
test -z "$PUPPET_MASTER_TCP_PORT" && export PUPPET_MASTER_TCP_PORT="8410"

# if there is a puppet master host defined, rewrite the config to match
if [ ! -z "$PUPPET_MASTER_TCP_HOST" ]; then 
    write_puppet_config "$PUPPET_MASTER_TCP_HOST" "$PUPPET_MASTER_TCP_PORT"
fi

O problema deve ser bastante aparente. Se a configuração do Puppet já especifica a configuração, estou apenas anexando outra [agent]seção, o que é ruim.

Eu poderia simplesmente ativar a lógica condicional (ou seja: grep se estiver lá e reescrevê-la com sed se estiver), mas existe uma maneira de fazer uma edição na linha de comando? Eu gostaria basicamente de executar um comando que diz "se não houver uma seção de agente, adicione-a e certifique-se de que o servidor e a porta mestre estejam definidos com os valores corretos nessa seção".

Eu sei que existem ferramentas estruturadas como essa para XML, mas e os arquivos no estilo INI?

Responder1

Dê uma olhada emcrudini, que é uma ferramenta shell projetada para isso

conf=/etc/puppet/puppet.conf
crudini --set "$conf" agent server "$PUPPET_MASTER_TCP_HOST"
crudini --set "$conf" agent masterport "$PUPPET_MASTER_TCP_PORT"

ou uma única invocação atômica como:

echo "
[agent]
server=$1
masterport=$2" |

crudini --merge /etc/puppet/puppet.conf

Responder2

Aqui estão alguns exemplos de script. Eles são o mínimo e não se preocupam com verificação de erros, opções de linha de comando, etc. Indiquei se executei o script sozinho para verificar sua correção.

Rubi

Instale o inifilerubygem para este script. Este roteiro étestado.

#!/usr/bin/env ruby
# filename: ~/config.rb

require 'inifile'

PUPPETMASTER_HOSTNAME='hello'
PUPPETMASTER_PORT='world'

ini = IniFile::load('/etc/puppet/puppet.conf')
ini['agent']['server'] = PUPPETMASTER_HOSTNAME
ini['agent']['masterport'] = PUPPETMASTER_PORT
ini.save

Uso:

$ chmod 700 ~/config.rb
$ sudo ~/config.rb     # or, if using rvm, rvmsudo ~/config.rb

Perl

Instale Config::IniFilesusando cpano gerenciador de pacotes do seu sistema operacional (se houver um pacote disponível). Este roteiro énão testadocomo parei de usar perl no meu sistema. Pode precisar de um pouco de trabalho e correções são bem-vindas.

#!/usr/bin/env perl
# filename: ~/config.pl

use Config::IniFiles;

my $PUPPETMASTER_HOSTNAME='perl';
my $PUPPETMASTER_PORT='1234';

my $ini = Config::IniFiles->new(-file => '/etc/puppet/puppet.conf');

if (! $ini->SectionExists('agent')) {
    $ini->AddSection('agent');
}

if ($ini->exists('agent', 'server')) {
    $ini->setval('agent', 'server', $PUPPETMASTER_HOSTNAME);
}
else {
    $ini->newval('agent', 'server', $PUPPETMASTER_HOSTNAME);
}

if ($ini->exists('agent', 'masterport')) {
    $ini->setval('agent', 'masterport', $PUPPETMASTER_PORT);
}
else {
    $ini->newval('agent', 'masterport', $PUPPETMASTER_PORT);
}

$ini->RewriteConfig();

Uso:

$ chmod 700 ~/config.pl
$ sudo ~/config.pl

estranho

Este script é mais compatível com Bash e *nix e usa um utilitário comum dos sistemas operacionais *nix, awk. Este roteiro étestado.

#!/usr/bin/env awk
# filename: ~/config.awk

BEGIN {
    in_agent_section=0;
    is_host_done=0;
    is_port_done=0;
    host = "awk.com";
    port = "4567";
}

in_agent_section == 1 {
    if ($0 ~ /^server[[:space:]]*=/) {
        print "server="host;
        is_host_done = 1;
        next;
    }
    else if ($0 ~ /^masterport[[:space:]]*=/) {
        print "masterport="port;
        is_port_done = 1;
        next;
    }
    else if ($0 ~ /^\[/) {
        in_agent_section = 0;
        if (! is_host_done) {
            print "server="host;
        }
        if (! is_port_done) {
            print "masterport="port;
        }
    }
}

/^\[agent\]/ {
    in_agent_section=1;
}

{ print; }

Uso:

$ awk -f ~/config.awk < /etc/puppet/puppet.conf > /tmp/puppet.conf
$ sudo mv /tmp/puppet.conf /etc/puppet/puppet.conf

Responder3

Se você puder instalar ferramentas externas, eu recomendaria Augeas - esta é a única ferramenta para trabalhar com arquivos de configuração que você precisará. Ele representa configurações como uma árvore. Consulte Mais informaçãoaqui.

informação relacionada