zoukankan      html  css  js  c++  java
  • puppet-type

    puppet语法-type

    Table of Contents

    1. [Custom Source](#Custom Source)
    2. 基本技能要求
    3. Types简介
    4. Type-Documentation
    5. Type-Properties
    6. Type-Parameters
    7. [Automatic Relationships](#Automatic Relationships)
    8. [Agent-side Pre-Run Resource](#Agent-side Pre-Run Resource)

    Custom Source

    Custom Source可以理解为自定义的资源类型,必须使用ruby语言进行书写,Custom Source主要包含两个模块:type和provider。
    type和provider是需要配合使用的,type定义了能做什么,provider定义了怎么做,type和provider是相互依赖的关系。

    注:学习开发type和provider最好的方法是阅读现有的type和provider,最好是puppet核心代码块。
    假如你是初次接触type和provider的开发,建议阅读和参考Package和User资源,而不要使用File资源。

    基本技能

    阅读本文之前你应该掌握的基本技能:

    • 有一定Linux运维经验,熟悉Linux常用命令行
    • 对ruby的语法有一定了解
    • 有使用puppet部署集群的经验

    types简介

    当创建一个type资源时候,应该关注于这个资源能做什么,而不是如何去做

    通常创建type是通过调用Puppet::Type的newtype方法,示例如下:

    # lib/puppet/type/database.rb
    Puppet::Type.newtype(:database) do
      @doc = "Create a new database."
      # ... the code ...
    end
    

    或者开头使用module Puppet

    # lib/puppet/type/package.rb
    module Puppet
      Type.newtype(:package) do
        @doc = "Manage a Package."
        # ... the code ...
      end
    
    • 创建一个新的type只需调用newtype方法即可
    • type的名字必须遵从于ruby语法,并且要和文件名称相同
    • 调用newtype方法时后面需要接代码块,可以通过do ... end或者( { ... } )包含代码块里的所有propertys和providers。

    notice: 当创建type时,可以在名字后面指定参数,并且只有一个参数是可用的:
    :self_refresh => true --- 会造成这个资源类型的刷新(类似于这个资源类型通过nogify/subscribe等关联资源方法收到了刷新的指令),这个最常用的是用在mount类型上

    Type-Documentation

    在代码块里创建property和provider之前,通常会对这个资源类型有一个说明,通过@doc方法。字符串使用markdown格式,示例如下:

    Puppet::Type.newtype(:database) do
      @doc = %q{Creates a new database. Depending
        on the provider, this may create relational
        databases or NoSQL document stores.
    
        Example:
    
            database {'mydatabase':
              ensure => present,
              owner  => root
            }
      }
    end
    

    Type-Properties

    前面我们说道一个新的type名称后面是代码块,一个代码块里的主要内容就是properties和parameters,它们都能生成资源的属性。

    Properties和Parameters又是怎样的区别呢?它们的区别很微妙而且很重要

    • Properties会直接管理目标系统里这个属性的参数,例如一个用户的UID或者GID,因为GID和UID是可能会被更改,所以要使用Properties去定义。
    • Parameters指定puppet如何管理这个资源,而不是设置特定属性,例如user类型的managehome属性就要使用Parameter定义,这个属性会影响puppet做什么。

    那么property是怎么工作的呢?
    假如你定义了一个owner的property,首先property会调用provider的方法去检测并获取当前owner的状态,当当前资源状态与我们设置的不一致时,property或调用类似于owner=methon的方法将资源状态改变为我们所期望的。

    ensurable

    通常我们定义property是通过"def xxx { ... }"方式定义的,但是有一个特殊的property,因为是比较常用的,所以有了简化的写法,那就是ensure property。它可以简单定义为ensurable,示例如下:

    Puppet::Type.newtype(:database) do
      ensurable
      ...
    end
    

    这个property会调用provider的三个方法:create, destroy, and exists? . 顾名思义,create就是创建(更改)当前的资源状态,destory就是删除当前资源,exists?是检测当前资源是否存在。如果ensure属性定义为“不要求同步”,那么其他的properties将都不会执行。

    其他property定义方式采用“newproperty(:xxx)do ... end”的形式,示例如下:

    Puppet::Type.newtype(:database) do
      ensurable
      newproperty(:owner) do
        desc "The owner of the database."
        ...
      end
    end
    

    其中desc是描述这个property的作用,类似于type类型的@doc方法。

    values

    puppet最开始发展时候,properties里面会有很多代码,然而经过优化与规范,properties里面只需要定义可用的参数或者设置validation和munging(后面的parameters讲解会说到这两个方法),如果你定义了一些参数,那么puppet只会接受这些你定义的参数。通常来讲,只需要定义允许的参数,但是这些参数对其他的property也是生效的。

    newproperty(:enable) do
      newvalue(:true)
      newvalue(:false)
    end
    

    validate

    validate方法可以对property设置的参数进行处理,例如,当需要参数是字符串时,可以这样写:

    newproperty(:owner) do
      validate do |value|
        unless value =~ /^w+/
          raise ArgumentError, "%s is not a valid user name" % value
        end
      end
    end
    

    执行顺序

    puppet根据property定义顺序执行,所以对一个目标系统资源进行检查和修复的顺序也是根据我们定义property的顺序执行的。

    日志输出

    日志输出是必不可少的,通过puppet日志你可以看到目标系统资源都进行了怎样的变化,通过如下三个方法可以实现日志输出功能:

    1. is_to_s:日志内容描述目标资源当前参数。
    2. should_to_s: 日志内容描述目标资源应该是什么参数,但不做更改。
    3. change_to_s:日志内容描述目标资源被改成了什么参数。

    示例:

    def should_to_s(newvalue)
      if provider.respond_to?(:package_settings_should_to_s)
        provider.package_settings_should_to_s(should, newvalue)
      else
        super(newvalue)
      end
    end
    
    def is_to_s(currentvalue)
      if provider.respond_to?(:package_settings_is_to_s)
        provider.package_settings_is_to_s(should, currentvalue)
      else
        super(currentvalue)
      end
    end
    
    def change_to_s(currentvalue, newvalue)
      if provider.respond_to?(:package_settings_change_to_s)
        provider.package_settings_change_to_s(currentvalue, newvalue)
      else
        super(currentvalue,newvalue)
      end
    end
    

    property参数传递与使用

    当创建一个资源时候,我们指定的参数会被存储在每一个property的@should方法中,我们可以在资源中使用如下方式去调用这些参数:

    myval = should(:color)
    

    当然有时候也会调用parameters里的参数,parameters里的参数不能使用should方法了,而应该使用value方法。所以当你不确定你调用的参数是properties里的还是parameters里的时候,使用value方法肯定是没错的:

    myvalue = value(:color)
    

    Type-Parameters

    parameters方法的使用和property大体上是相同的,唯一的不同是parameters不会调用providers的方法。

    定义一个新的parameter使用newparam方法,后面的语法和property方法一样。示例如下:

    newparam(:name) do
      desc "The name of the database."
    end
    

    Namevar

    每个type都应该有至少一个必有的parameter:namevar。这个parameter是该资源的唯一标识,例如:磁盘上的路径,用户名称,包的名称等等。
    如果声明的资源里不指定namevar方法,那么这个资源的title将会是namevar的默认值。

    有三个方法声明namevar:

    1. 创建名称为:name的parameter会被认为是namevar
    newparam(:name) do
      desc "The name of the database."
    end
    
    1. 设置:namevar => true参数指定namevar:
    newparam(:path, :namevar => true) do
      ...
    end
    
    1. 直接调用isnamevar方法,不用指定任何参数:
    newparam(:path) do
      isnamevar
      ...
    end
    

    当没有namevar的定义时候会报错,puppet2.7和puppet3的报错信息如下:
    puppet 2.7:

    $ puppet apply -e "testing { h: }"
    Error: undefined method `merge' for []:Array
    

    Puppet 3:

    $ puppet apply -e "testing { h: }"
    Error: No set of title patterns matched the title "h".
    

    Values

    一次声明多个变量的方法:

    newparam(:color) do
      newvalues(:red, :green, :blue, :purple)
    end
    

    声明变量也可以使用正则表达式的形式:

    newparam(:color) do
      desc "Your color, and stuff."
    
      newvalues(:blue, :red, /.+/)
    end
    

    Validation和Munging方法

    一些parameters是没必要定义参数列表的,或者想要对传进来的参数进行一些处理,那么我们可以使用validate和munge方法:

    newparam(:color) do
      desc "Your color, and stuff."
    
      newvalues(:blue, :red, /.+/)
    
      validate do |value|
        if value == "green"
          raise ArgumentError,
            "Everyone knows green databases don't have enough RAM"
        else
          super
        end
      end
    
      munge do |value|
        case value
        when :mauve, :violet # are these colors really any different?
          :purple
        else
          super
        end
      end
    end
    

    validate和munge的区别:

    validate只会处理使用newvalues定义过的参数,然而munge方法会处理所有传进来的参数,包括newvalues定义过的和其他被指定的参数。假如传递进来的参数都没有经过处理,那么必须使用调用super方法(也就是说else后面必须使用super方法),否则传进来的数值就因被丢失而失效。super方法的使用可以参考我的另一篇博客ruby语法-super用法

    一般来讲,参数总是先经过validate方法再经过munged方法。

    最后要说明的一点:validate和munge方法只会处理传进来的参数(该参数已经是确定我们期望的值了),而不会处理方法里预定义的参数。

    布尔类型参数

    因为声明布尔类型的参数是很常见的,所以为了定义的方便,可以使用下面的方式:

    require 'puppet/parameter/boolean'
    # ...
    newparam(:force, :boolean => true, :parent => Puppet::Parameter::Boolean)
    

    其中:parent => Puppet::Parameter::Boolean会配置parameter接受许多的名称(变量等),并判断其真假,返回true或false。:boolean => true部分会创建一个布尔方法并返回parameter的最终参数,在上面的例子中,等同于:boolean => true创建了一个force?的方法。

    Automatic Relationships

    一个type资源可以指定要自动关联的资源,通过使用autorequire,autobefore,autonotify和autosubscribe方法,这些方法需要一个资源类型的名字作为参数,并且会返回一个资源列表,这个资源列表可能会与你定义的type方法有某些关联。示例:

    autorequire(:user) do
        self[:user]
    end
    

    需要注意的一点:当使用这四个方法时,即使调用的资源名称(例如上例中的user)并不是一个有效的资源,也不会报错。

    Agent-side Pre-Run Resource

    这是一个发生在agent端的事情,在agent端有时我们需要设置一些先决条件,当先决条件不被满足时,就会跳出部署catalog。这个先决条件的定义就是pre_run_check方法了。
    如果type资源里面定义了pre_run_check方法,在Puppet agent或puppet apply部署catalog之前,首先会运行所有资源里的pre_run_check方法,一旦有错误产生,就会将错误信息打印出来告知使用者并停止部署catalog。

    参考文档:
    https://puppet.com/docs/puppet/4.7/custom_types.html

  • 相关阅读:
    Android 2.2 r1 API 中文文档系列(11) —— RadioButton
    Android API 中文 (15) —— GridView
    Android 中文 API (16) —— AnalogClock
    Android2.2 API 中文文档系列(7) —— ImageButton
    Android2.2 API 中文文档系列(6) —— ImageView
    Android 2.2 r1 API 中文文档系列(12) —— Button
    Android2.2 API 中文文档系列(8) —— QuickContactBadge
    [Android1.5]TextView跑马灯效果
    [Android1.5]ActivityManager: [1] Killed am start n
    Android API 中文(14) —— ViewStub
  • 原文地址:https://www.cnblogs.com/mauricewei/p/8762309.html
Copyright © 2011-2022 走看看