Confusão de herança de classe de fantoches

6

Eu li a documentação sobre o escopo, mas ainda estou tendo problemas para resolver isso. Eu tenho dois ambientes que são muito semelhantes - então eu tenho:

modules / django-env / manifestos / init.pp

class django-env {
    package { "python26":
        ensure => installed
    }
    # etc ...
}
import "er.pp"

modules / django-env / manifests / er.pp

$venvname = "er"
$venvpath = "/home/django/virtualenvs"

class er {
    file { "$venvpath/$venvname" :
        ensure => directory
    }
    # etc ...
}
class er-dev {
    include er
}
class er-bce-dev {
    $venvname = "er-bce"
    include er
}

manifests / modules.pp

import "django-env"

manifests / nodes.pp

node default {
    # etc ...
}
node 'centos-dev' imports default {
    include django-env
    include er-bce-dev
    include er-dev
}

O resultado aqui é que a "herança" funciona - mas apenas o primeiro item "er-" sob o nó "centos-dev" é acionado, ou eu pego er-bce-dev ou er-dev, mas não ambos. Deve haver alguma coisa básica que eu estou entendendo mal aqui.

É a diferença entre import e include ? (não tenho certeza eu entendo isso)

    
por EMiller 03.11.2010 / 22:40

2 respostas

11

O Puppet não suporta esse tipo de configuração, mas a restrição pode ser facilmente contornada. A razão está em duas "regras" básicas de fantoches:

  1. Uma classe pode ser incluída apenas uma vez (as inclusões subsequentes não farão nada)
  2. A ordem de execução não é estritamente definida e pode até ser aleatória

er-dev e er-bce-dev incluem a classe er . Mas a classe não pode ser incluída duas vezes, portanto, er class é executada apenas com o padrão $venvname = "er" ou com a substituição $venvname = "er-dev" , mas não com ambas.

A solução: altere a classe er para uma definição (consulte "Definições" no Tutorial da linguagem de marionetes ( link )):

modules / django-env / manifests / er.pp

# Create new er resource definition
define django-env::er($vpath="/home/django/virtualenvs", $vname="er") {
    file { "$vpath/$vname" :
        ensure => directory
    }
    # etc ...
}

Não precisamos das variáveis $venvname e $venvpath , elas são especificadas como valores padrão na definição. O nome django-env::er adiciona a definição ao namespace django-env e permite a importação automática (veja abaixo).

Importar e incluir

A diferença entre import e include statemens é:

  • import funciona com arquivos e não executa classes
  • include executa classes
  • Os arquivos
  • devem ser importados antes que as classes possam ser incluídas

Observação: há uma exceção muito strong à última regra: consulta ao módulo Puppet . A declaração include faz importações automáticas em muitas situações. Aqui estão alguns deles:

  • include foo tenta importar o arquivo module_dir/foo/manifests/init.pp
  • include foo::bar imports module_dir/foo/manifests/bar.pp

Com essas importações automáticas e a definição de recursos, você pode definir vários ambientes virtuais com muita facilidade. Alterar node 'centos-dev' :

node 'centos-dev' imports default {
    include django-env
    # The er resource with default values:
    django-env::er { 'er-bce': }
    # Another er resource with different environment name:
    django-env::er { 'er-bce-dev': vname => 'bce-dev'}
}

E você pode remover basicamente todas as declarações import considerando django-env module.

Feliz Puppeting!

    
por 16.01.2011 / 12:19
0

A sintaxe do Puppet evoluiu, desde o Puppet 3.7 você receberá muitos avisos de desaprovação. As palavras-chave import e inherits estão obsoletas. Em vez de usar layout como:

 /etc/puppet
   /manifests
      /nodes
      site.pp
   /modules
   puppet.conf

Você deve usar:

 /etc/puppet
   /environments
     /production
       /manifests
          01_base_node.pp
       /modules
       environment.conf
   puppet.conf

Em vez de usar o tradicional site.pp config:

import 'nodes/*.pp'

node default {
   classs{'ntp': }
}

você deve usar o padrão class (mas não pode chamá-lo de class default , pois é um palavra reservada ), um arquivo manifets/01_common.pp :

class common {
  classs{'ntp': }
}

Os arquivos são carregados em ordem alfabética, portanto, você deve garantir que as "classes básicas" serão carregadas primeiro (a numeração pode ser uma boa ideia).

Então, em vez de definir um nó como:

node /^web\d+/ inherits default {
}

use um pouco (resolve o problema clássico de herança múltipla, chamado de problema de diamante ), por exemplo definido em manifests/web.pp

node /^web\d+/ {
  include common
  # include something_else   
}
    
por 13.03.2016 / 14:07

Tags