Editando arquivos semelhantes ao INI com um script

5

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

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

[agent]
server=$PUPPETMASTER_HOSTNAME
masterport=$PUPPETMASTER_PORT

O que eu tenho feito até agora no script runit do meu agente Puppet é este:

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 bem aparente. Se a configuração do Puppet já especificar a configuração, estou apenas anexando outra seção [agent] , o que é ruim.

Eu poderia apenas ligar a lógica condicional (isto é: grep se estiver lá e então reescrevê-la com sed se estiver), mas existe uma maneira de fazer uma edição a partir da linha de comando? Eu gostaria basicamente de executar um comando que diz "se não houver uma seção de agente, inclua-a e verifique se o servidor e a masterport estão configurados com os valores corretos nessa seção".

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

    
por Naftuli Kay 17.06.2014 / 17:42

3 respostas

5

Aqui estão alguns exemplos de script. Estes são mínimos e não se incomodam com verificação de erros, opções de linha de comando, etc. Indiquei se já executei o script para verificar sua exatidão.

Ruby

Instale o inifile rubygem para este script. Este script é 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::IniFiles usando cpan ou seu gerenciador de pacotes do SO (se houver um pacote disponível). Este script é não testado porque parei de usar perl no meu sistema. Pode precisar de um pouco de trabalho e as 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

awk

Este script é mais amigável ao Bash and * nix e usa um utilitário comum do * nix OS, awk . Este script é 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
    
por 18.06.2014 / 02:58
17

Dê uma olhada em crudini , que é uma ferramenta de shell criada 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
    
por 25.08.2014 / 16:30
0

Se você pode se dar ao luxo de instalar ferramentas externas, então eu recomendaria Augeas - esta é a única ferramenta para trabalhar com arquivos de configuração que você irá precisar. Representa configs como uma árvore. Leia mais aqui .

    
por 02.03.2015 / 12:40