### 使用類的繼承和重載
正如節點可以從其他節點繼承一樣,這可以為相似的節點復制很多代碼, 同樣的思想也可以用于類。
例如,假設你有一個管理 Apache Web 服務器的 apache 類, 你想要使用略有不同的配置文件設置一臺新的 Apache 機器?—?也許是監聽的端口不同。
你可以復制整個 apache 類,除了配置文件。另外,你可以從 apache 類中提取配置文件并創建兩個新類,每個新類都包含 apache 基類并添加一個新版本的配置文件。
一個更簡潔的做法是從 apache 類繼承,而后僅覆蓋其配置文件。
#### 準備工作
1. 為新的 apache 模塊創建目錄結構:
```
# mkdir /etc/puppet/modules/apache
# mkdir /etc/puppet/modules/apache/manifests
# mkdir /etc/puppet/modules/apache/files
```
2. 使用如下代碼創建 /etc/puppet/modules/apache/manifests/init.pp 文件:
```
class apache {
package { "apache2-mpm-worker": ensure => installed }
service { "apache2":
enable => true,
ensure => running,
require => Package["apache2-mpm-worker"],
}
file { "/etc/apache2/ports.conf":
source => "puppet:///modules/apache/port80.conf.apache",
notify => Service["apache2"],
}
}
```
3. 若 Apache 軟件包還未安裝,安裝它,復制其包含的文件 ports.conf 到 Puppet:
```
# apt-get install apache2-mpm-worker
# cp /etc/apache2/ports.conf \
/etc/puppet/modules/apache/files/port80.conf.apache
```
4. 添加 apache 類到一個節點,例如:
```
node cookbook {
include apache
}
```
5. 運行 Puppet 驗證配置清單是否正常工作。
#### 操作步驟
1. 創建 port80.conf.apache 文件的一個新版本 port8000.conf.apache,并做如下改動:
```
NameVirtualHost *:8000
Listen 8000
```
2. 使用如下內容創建一個新文件 /etc/puppet/modules/apache/manifests/port8000.pp:
```
class apache::port8000 inherits apache {
File["/etc/apache2/ports.conf"] {
source => "puppet:///modules/apache/port8000.conf.apache",
}
}
```
3. 改變你的節點配置,使其包含 apache::port8000 類而不是 apache 類:
```
node cookbook {
include apache::port8000
}
```
4. 運行 Puppet 檢查它是否會按照要求的那樣發生改變:
```
# puppet agent --test
info: Retrieving plugin
info: Caching catalog for cookbook.bitfieldconsulting.com
info: Applying configuration version '1302970905'
--- /etc/apache2/ports.conf 2010-11-18 14:16:23.000000000 -0700
+++ /tmp/puppet-file20110416-6165-pzeivi-0 2011-04-16
10:21:47.204294334 -0600
@@ -5,8 +5,8 @@
# Debian etch). See /usr/share/doc/apache2.2-common/NEWS.Debian.gz and
# README.Debian.gz
-NameVirtualHost *:80
-Listen 80
+NameVirtualHost *:8000
+Listen 8000
<IfModule mod_ssl.c>
# If you add NameVirtualHost *:443 here, you will also have
to change
info: FileBucket adding /etc/apache2/ports.conf as {md5}38b31d2032
6f3640a8dfbe1ff5d1c4ad
info: /Stage[main]/Apache/File[/etc/apache2/ports.conf]:
Filebucketed /etc/apache2/ports.conf to puppet with sum
38b31d20326f3640a8dfbe1ff5d1c4ad
notice: /Stage[main]/Apache/File[/etc/apache2/ports.conf]/content:
content changed '{md5}38b31d20326f3640a8dfbe1ff5d1c4ad' to '{md5}4
1d9d446f779c55f13c5fe5a7477d943'
info: /Stage[main]/Apache/File[/etc/apache2/ports.conf]:
Scheduling refresh of Service[apache2]
notice: /Stage[main]/Apache/Service[apache2]: Triggered 'refresh'
from 1 events
notice: Finished catalog run in 4.85 seconds
```
#### 工作原理
讓我們再看看這個新類:
```
class apache::port8000 inherits apache {
File["/etc/apache2/ports.conf"] {
source => "puppet:///modules/apache/port8000.conf.apache",
}
}
```
你可以從類名后看出,此類繼承(inherits)自 apache 類。這將創建一個與 apache 類完全相同的副本,除了跟隨其后的變化。
如下的代碼片段:
```
File["/etc/apache2/ports.conf"] {
```
指定了我們想要改變父類中名為 /etc/apache2/ports.conf 的 file 資源 (注意 File 是首字母大寫的,這意味著,我們指的是現有的資源,而不是定義一個新資源)。
如下的代碼片段:
```
source => "puppet:///modules/apache/port8000.conf.apache",
```
意味著我們將使用一個新的值覆蓋父類中 source 資源的參數值。 如果我們復制整個 apache 類的定義并改變資源 source 的值,那么結果將是完全一樣的:
```
class apache {
package { "apache2-mpm-worker": ensure => installed }
service { "apache2":
enable => true,
ensure => running,
require => Package["apache2-mpm-worker"],
}
file { "/etc/apache2/ports.conf":
source => "puppet:///modules/apache/port8000.conf.apache",
notify => Service["apache2"],
}
}
```
#### 更多用法
首先覆蓋被繼承的類看上去有些復雜。然而一旦你掌握了這種思想,就會發現這實際上很簡單。 這是一種使你的配置清單更具可讀性的強大方式,因為這樣消除了大量的重復代碼, 使你僅專注于編寫不同的代碼部分。下面給出幾種使用覆蓋的方法。
##### 取消參數的定義
有時候你不想改變一個參數的值,只是想完全移除它的值。 為了實現這一點,可以使用 undef 值覆蓋原有值。 其結果就像是此參數從未在先前定義過一樣。
```
class apache::norestart inherits apache {
File["/etc/apache2/ports.conf"] {
notify => undef,
}
}
```
##### 使用 +> 操作符添加額外的值
與替換一個值類似,你可能想要在父類定義的基礎上添加更多的值。 使用 **plusignment** 操作符 +> 可以實現這一功能:
```
class apache::ssl inherits apache {
file { "/etc/ssl/certs/cookbook.pem":
source => "puppet:///modules/apache/cookbook.pem",
}
Service["apache2"] {
require +> File["/etc/ssl/certs/cookbook.pem"],
}
}
```
操作符 +> 在父類定義的值的基礎上添加一個值(或使用方括號括起來的一個數組)。 對于上面的例子,我們最終得到的代碼相當于:
```
service { "apache2":
enable => true,
ensure => running,
require => [ Package["apache2-mpm-worker"], File["/etc/ssl/certs/
cookbook.pem"] ],
}
```
##### 禁用資源
繼承和覆蓋最常見的用途之一就是禁用服務或其他資源:
```
class apache::disabled inherits apache {
Service["apache2"] {
enable => false,
ensure => stopped,
}
}
```
#### 參見本書
* 第 4 章的 [使用節點繼承](#ch04sec04) 一節
* 第 4 章的 [給類傳遞參數](#ch04sec06) 一節
* 第 3 章的 [使用標準的命名規范](#ch03sec03) 一節
- Puppet 2.7 Cookbook 中文版
- 中文翻譯版
- 譯者序
- 項目緣起
- 翻譯方法
- 社區鏈接
- 社區建議
- 貢獻者
- 原書版權頁
- 關于作者
- 前言
- 本書內容
- 閱讀前提
- 適用讀者
- 格式約定
- 讀者反饋
- 客戶支持
- 下載案例代碼
- 勘誤表
- Puppet 基礎設施
- 使用版本控制
- 使用提交鉤子
- 使用 Rake 部署變更
- 配置 Puppet 的文件服務器
- 從 cron 運行 Puppet
- 使用自動簽名
- 預簽名證書
- 從 Puppet 的 filebucket 檢索文件
- 使用 Passenger 擴展 Puppet 的部署規模
- 創建去中心化的分布式 Puppet 架構
- 監控、報告和排錯
- 生成報告
- 通過 Email 發送包含特定標簽的日志信息
- 創建圖形化報告
- 自動生成 HTML 文檔
- 繪制依賴關系圖
- 測試你的 Puppet 配置清單
- 執行模擬運行
- 檢測編譯錯誤
- 理解 Puppet 的錯誤信息
- 顯示命令的輸出結果
- 輸出調試信息
- 檢查配置設置
- 使用標簽
- 使用運行階段
- 使用不同的環境
- Puppet 語言及其寫作風格
- 使用 Puppet 社區規范
- 使用模塊
- 使用標準的命名規范
- 使用嵌入式 Ruby 代碼
- 使用純 Ruby 代碼書寫配置清單
- 遍歷多個項目
- 書寫強大的條件語句
- 在 if 語句中使用正則表達式
- 使用選擇器和 case 語句
- 檢測字符串中是否包含指定的值
- 使用正則表達式替換
- 書寫更優質的配置清單
- 使用資源的數組
- 使用 define 資源
- 指定資源的依賴關系
- 使用節點繼承
- 使用類的繼承和重載
- 給類傳遞參數
- 書寫可重用的跨平臺配置清單
- 獲得系統的環境信息
- 導入動態信息
- 從 CSV 文件導入數據
- 給 Shell 命令傳遞參數
- 使用文件和軟件包
- 為配置文件添加配置行
- 使用 Augeas 自動修改配置文件
- 使用配置片段構建配置文件
- 使用 ERB 模板
- 在模板中遍歷數組
- 從第三方倉庫安裝軟件包
- 配置 APT 軟件倉庫
- 配置 GEM 倉庫
- 從源碼包自動構建軟件
- 比較軟件包的版本
- 用戶和虛擬資源
- 使用虛擬資源
- 使用虛擬資源管理用戶
- 管理用戶基于密鑰的 SSH 訪問
- 管理用戶的自定義文件
- 有效地分發 cron 任務
- 當文件更新時運行命令
- 使用主機資源
- 為文件資源指定多個源
- 使用文件資源遞歸地分發整個目錄樹
- 清理過期的舊文件
- 使用日程表資源
- 資源的審計
- 臨時禁用資源
- 管理時區
- 應用程序
- 管理 Apache 服務
- 創建 Apache 虛擬主機
- 創建 Nginx 虛擬主機
- 創建 MySQL 數據庫及用戶
- 管理 Drupal 站點
- 管理 Rails 應用程序
- 服務器和云基礎設施
- 部署 Nagios 監控服務器
- 使用 Heartbeat 構建高可用服務
- 管理 NFS 服務和文件共享
- 使用 HAProxy 為多個 web 服務器實現負載均衡
- 使用 iptables 管理防火墻
- 管理 Amazon 的 EC2 實例
- 使用 Vagrant 管理虛擬機
- 外部工具和 Puppet 生態環境
- 創建 Facter 的自定義 fact
- 在運行 Puppet 之前和之后執行命令
- 從 Shell 會話生成 Puppet 配置清單
- 從運行的系統上生成 Puppet 配置清單
- 使用 Puppet Dashboard
- 使用 Foreman
- 使用 MCollective
- 使用公共模塊
- 使用外部節點分類器
- 創建自定義的資源類型
- 創建自定義的提供者