• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

Configuration Management Recipes

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

Stratus_ss

Overclockix Snake Charming Senior, Alt OS Content
Joined
Jan 24, 2006
Location
South Dakota
So I thought that I would start a thread (hopefully a sticky) that is similar to "/bin". The purpose of this thread will be to post recipes/bundles/promises for your configuration management tools. At current I am thinking about CFEngine/Puppet/Chef, but if you have others feel free to clearly identify which system you are applying the configuration to before posting the code.

Without further adu....

CFEngine 3

The purpose of this simple bundle is to take a base install of a virtualbox vm, and install the guest additions, change its networking and hostname from the default image.

It makes most of its decisions based on the mac address and may take up to 15 minutes to converge completely because I have 2 reboot statements. This is obviously for a YUM based system

Code:
bundle agent vbox_install
{
        #I am attempting to define a class only of the vbox guest additions are installed
       	classes:
               	"additions_installed" and => { fileexists("/etc/init.d/vboxadd") };
       	vars:
               	"install_me" slist => { "nmap", "htop", "samba", "samba-winbind", "gcc", "kernel-devel", "kernel-headers", "dkms", "make", "bzip2", "nautilu$

       	packages:
               	mac_08_00_27_6d_9f_fe::
                        "$(install_me)"
                       	package_policy => "add",
                       	package_method => yum;

        #In this section I am making decisions about a host based on its mac address
       	files:
               	mac_08_00_27_6d_9f_fe::
                #If the mac address matches, set the networking and hostname
                "/etc/sysconfig/network"
                       	create => "true",
                       	edit_line => ChangeHost,
                       	edit_defaults => empty;
                "/etc/sysconfig/network-scripts/ifcfg-eth0"
                       	create => "true",
                       	edit_line => SetNetworking,
                       	edit_defaults => empty;
        #This command will execute only if the mac address AND the correct hostname are not found
        #This is to ensure that the changes will take effect
       	commands:
               	mac_08_00_27_6d_9f_fe&!cfengineclient_stratus_sphere&!additions_installed::
                       	"/usr/bin/yum update -y";
                       	"/sbin/reboot";
               	mac_08_00_27_6d_9f_fe&!additions_installed::
                       	"/bin/mount /dev/sr0 /mnt";
                       	"/bin/sh /mnt/VBoxLinuxAdditions.run";
                       	"/sbin/reboot";
}
bundle edit_line ChangeHost
{
                #I emptied the file above and so I am now putting contents back in it
               	insert_lines:
                       	"NETWORKING=yes";
                       	"HOSTNAME=cfEngineClient.stratus-sphere";
}

bundle edit_line SetNetworking
{
                #Insert the networking information
               	insert_lines:
"DEVICE=\"eth0\"
BOOTPROTO=\"static\"
HWADDR=08:00:27:6d:9f:fe
IPADDR=192.168.56.200
NM_CONTROLLED=\"yes\"
ONBOOT=yes
TYPE=\"Ethernet\"
NAME=\"System eth0\"";
}


For those interested, I have created syntax highlight (in basic form) for gedit
Code:
<?xml version="1.0" encoding="UTF-8"?>
<!--

 Author: Gustavo Giráldez <[email protected]>
 Copyright (C) 2003 Gustavo Giráldez <[email protected]>
 Copyright (C) 2004 Benoît Dejean <[email protected]>
 Copyright (C) 2006 Steve Frécinaux <[email protected]>

 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
 License as published by the Free Software Foundation; either
 version 2 of the License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Library General Public License for more details.

 You should have received a copy of the GNU Library General Public
 License along with this library; if not, write to the
 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.

-->
<language id="cfengine" _name="CFEninge" version="2.0" _section="Scripts">
  <metadata>
    <property name="mimetypes">text/x-cfengine;application/x-cfengine</property>
    <property name="globs">*.cf</property>
    <property name="line-comment-start">#</property>
  </metadata>

  <styles>
    <style id="module-handler"    _name="Module Handler"        map-to="def:preprocessor"/>
    <style id="keyword"           _name="Keyword"               map-to="def:keyword"/>
    <style id="multiline-string"  _name="Multiline string"      map-to="def:string"/>
    <style id="string"            _name="String"                map-to="def:string"/>
    <style id="escaped-char"      _name="Escaped Character"     map-to="def:special-char"/>
    <style id="format"            _name="Format"                map-to="def:character"/>
    <style id="string-conversion" _name="string-conversion"/>
    <style id="special-variable"  _name="Special Variable"      map-to="def:identifier"/>
    <style id="boolean"           _name="Boolean"               map-to="def:boolean"/>
    <style id="floating-point"    _name="Floating point number" map-to="def:floating-point"/>
    <style id="decimal"           _name="Decimal number"        map-to="def:decimal"/>
    <style id="base-n-integer"    _name="Base-N number"         map-to="def:base-n-integer"/>
    <style id="complex"           _name="Complex number"        map-to="def:complex"/>
    <style id="builtin-constant"  _name="Builtin Constant"      map-to="def:special-constant"/>
    <style id="builtin-object"    _name="Builtin Object"        map-to="def:type"/>
    <style id="builtin-function"  _name="Builtin Function"      map-to="def:builtin"/>
  </styles>

  <definitions>
    <define-regex id="identifier">[_a-zA-Z][_a-zA-Z0-9]*</define-regex>
    <define-regex id="number">[1-9][0-9]*</define-regex>

    <!-- http://docs.cfengine.org/lib/typesseq-strings.html -->
    <context id="format" style-ref="format" extend-parent="false">
      <match extended="true">
        %                       # leading % sign
        \(\%{identifier}\)?     # mapping key
        [#0\-\ \+]*             # conversion flags
        (\-?\%{number}|\*)?     # minimum field width
        (\.(\-?\%{number}|\*))? # precision
        (hlL)?                  # lentgh modifier
        [diouxXeEfFgGcrs%]      # conversion type
      </match>
    </context>

    <!-- http://docs.cfengine.org/ref/strings.html -->
    <context id="escaped-char" style-ref="escaped-char" extend-parent="true">
      <match extended="true">
        \\(                 # leading backslash
        [\\'"abfnrtv]     | # single escaped char
        N\{[A-Z\ ]+\}     | # named unicode character
        u[0-9A-Fa-f]{4}   | # xxxx - character with 16-bit hex value xxxx
        U[0-9A-Fa-f]{8}   | # xxxxxxxx - character with 32-bit hex value xxxxxxxx
        x[0-9A-Fa-f]{1,2} | # \xhh - character with hex value hh
        [0-7]{1,3}          # \ooo - character with octal value ooo
        )
      </match>
    </context>

    <define-regex id="string-prefix">(u|U)?</define-regex>
    <define-regex id="raw-string-prefix">(r|ur|R|UR|Ur|uR)</define-regex>

    <context id="multiline-double-quoted-string" style-ref="multiline-string" class="string" class-disabled="no-spell-check">
      <start>\%{string-prefix}"""</start>
      <end>"""</end>
      <include>
        <context ref="format"/>
        <context ref="escaped-char"/>
      </include>
    </context>

    <context id="multiline-single-quoted-string" style-ref="multiline-string" class="string" class-disabled="no-spell-check">
      <start>\%{string-prefix}'''</start>
      <end>'''</end>
      <include>
        <context ref="format"/>
        <context ref="escaped-char"/>
      </include>
    </context>

    <context id="double-quoted-string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
      <start>\%{string-prefix}"</start>
      <end>"</end>
      <include>
        <context ref="format"/>
        <context ref="escaped-char"/>
        <context ref="def:line-continue"/>
      </include>
    </context>

    <context id="single-quoted-string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
      <start>\%{string-prefix}'</start>
      <end>'</end>
      <include>
        <context ref="format"/>
        <context ref="escaped-char"/>
        <context ref="def:line-continue"/>
      </include>
    </context>

    <context id="multiline-double-quoted-raw-string" style-ref="multiline-string" class="string" class-disabled="no-spell-check">
      <start>\%{raw-string-prefix}"""</start>
      <end>"""</end>
      <include>
        <context ref="format"/>
      </include>
    </context>

    <context id="multiline-single-quoted-raw-string" style-ref="multiline-string" class="string" class-disabled="no-spell-check">
      <start>\%{raw-string-prefix}'''</start>
      <end>'''</end>
      <include>
        <context ref="format"/>
      </include>
    </context>

    <context id="double-quoted-raw-string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
      <start>\%{raw-string-prefix}"</start>
      <end>"</end>
      <include>
        <context ref="format"/>
        <context ref="def:line-continue"/>
      </include>
    </context>

    <context id="single-quoted-raw-string" style-ref="string" end-at-line-end="true" class="string" class-disabled="no-spell-check">
      <start>\%{raw-string-prefix}'</start>
      <end>'</end>
      <include>
        <context ref="format"/>
        <context ref="def:line-continue"/>
      </include>
    </context>

    <context id="cfengine" class="no-spell-check">
      <include>
        <context ref="def:shebang"/>
        <context ref="def:shell-like-comment"/>

        <context ref="multiline-double-quoted-string"/>
        <context ref="multiline-single-quoted-string"/>
        <context ref="double-quoted-string"/>
        <context ref="single-quoted-string"/>

        <context ref="multiline-double-quoted-raw-string"/>
        <context ref="multiline-single-quoted-raw-string"/>
        <context ref="double-quoted-raw-string"/>
        <context ref="single-quoted-raw-string"/>

        <context id="string-conversion" style-ref="string-conversion" end-at-line-end="true">
          <start>`</start>
          <end>`</end>
          <include>
            <context ref="cfengine"/>
          </include>
        </context>

        <context id="special-variables" style-ref="special-variable">
          <prefix>(?<![\w\.])</prefix>
          <keyword>self</keyword>
          <keyword>__name__</keyword>
          <keyword>__debug__</keyword>
        </context>

        <context id="boolean" style-ref="boolean">
          <prefix>(?<![\w\.])</prefix>
          <keyword>False</keyword>
          <keyword>True</keyword>
        </context>

        <define-regex id="float" extended="true">
          ( (\d+)?\.\d+ | \d+\. ) |
          ( (\d+|(\d+)?\.\d+|\d+\.)[eE][+-]?\d+ )
        </define-regex>

        <context id="complex" style-ref="complex">
          <match>(?<![\w\.])(\%{float}|\d+)[jJ]\b</match>
        </context>

        <context id="float" style-ref="floating-point">
          <match>(?<![\w\.])\%{float}(?![\w\.])</match>
        </context>

        <context id="decimal" style-ref="decimal">
          <match>(?<![\w\.])([1-9][0-9]*|0)[lL]?(?![\w\.])</match>
        </context>

        <context id="octal" style-ref="base-n-integer">
          <match>(?<![\w\.])0[0-7]+[lL]?(?![\w\.])</match>
        </context>

        <context id="hex" style-ref="base-n-integer">
          <match>(?<![\w\.])0[xX][0-9A-Fa-f]+[lL]?(?![\w\.])</match>
        </context>

        <context id="module-handler" style-ref="module-handler">
          <keyword>import</keyword>
          <keyword>from</keyword>
          <keyword>as</keyword>
        </context>

        <context id="keyword" style-ref="keyword">
          <keyword>bundle agent</keyword>
          <keyword>bundle common</keyword>
          <keyword>bundle sequence</keyword>
          <keyword>bundle eddit_line</keyword>
          <keyword>body common control</keyword>
          <keyword>body control</keyword>
          <keyword>body acl</keyword>
          <keyword>body action</keyword>
          <keyword>body changes</keyword>
          <keyword>body classes</keyword>
          <keyword>body contain</keyword>
          <keyword>body copy_from</keyword>
          <keyword>body delete</keyword>
          <keyword>body depth_search</keyword>
          <keyword>body edit_defaults</keyword>
          <keyword>body edit_field</keyword>
          <keyword>body file_select</keyword>
          <keyword>body location</keyword>
          <keyword>body match_value</keyword>
          <keyword>lambda</keyword>
          <keyword>body mount</keyword>
          <keyword>body package_method</keyword>
          <keyword>body perms</keyword>
          <keyword>body process_count</keyword>
          <keyword>body process_select</keyword>
          <keyword>body rename</keyword>
          <keyword>body replace_with</keyword>
          <keyword>body service_method</keyword>
          <keyword>body volume</keyword>
        </context>

        <context id="builtin-constants" style-ref="builtin-constant">
          <prefix>(?<![\w\.])</prefix>
          <keyword>Ellipsis</keyword>
          <keyword>None</keyword>
          <keyword>NotImplemented</keyword>
        </context>


	<context id="sequence_define" style-ref="keyword">
	  <match>[".*?"\s+(.*?)\s]</match>
          
        </context>
        <context id="builtin-objects" style-ref="builtin-object">
          <prefix>(?<![\w\.])</prefix>
          <keyword>AssertionError</keyword>
          <keyword>any</keyword>
          <keyword>cfengine</keyword>
        </context>

        <context id="builtin-function" style-ref="builtin-function">
          <prefix>(?<![\w\.])</prefix>
          <keyword>reports</keyword>
          <keyword>classes</keyword>
          <keyword>methods</keyword>
          <keyword>vars</keyword>
          <keyword>xrange</keyword>
          <keyword>zip</keyword>
        </context>
      </include>
    </context>
  </definitions>
</language>

And a much better version for nano
Code:
## Here is an example for cfengine files
##
syntax "cfengine" "\.cf"
## String highlighting.  You will in general want your comments and
## strings to come last, because syntax highlighting rules will be
## applied in the order they are read in.
icolor brightblue "def [0-9A-Z_]+"

#Declarations are denoted in red
color red "[^*]*[>]"

color yellow start="\<^(bundle)" end="(agent)\>|(common)\>|(edit_line)\>" start="\<^(body)" end="(control)\>|(acl)\>|(action)\>|(changes)\>|(classes)\>|(contain)\>|(copy_from)\>|(delete)\>|(depth_search)\>|(edit_defaults)\>|(edit_field)\>|(file_select)\>|(location)\>|(match_value)\>|(mount)\>|(package_method)\>|(perms)\>|(process_count)\>|(process_select)\>|(rename)\>|(replace_with)\>|(service_method)\>|(volume)\>"
## 
color green "[^*]*[:]"
color cyan "[^>]*[;]"
color magenta "[(nt)]* [:space:]*$"
## Comment highlighting
color brightblue "["][^"]*[^\\]"
 
This promise does a series of file copies which have the effect of setting the networking, hostname, winbind, samba, nsswitch and sudoers file in place based on mac address

Code:
bundle agent setup_opservice1
{
        #This is the list of packages which will be installed
           vars:
                   "install_me" slist => { "nmap", "htop", "samba", "samba-winbind", "gcc", "kernel-devel", "kernel-headers", "dkms", "make", "bzip2", "nautilus-open-terminal" };
        #This class will only be defined if vboxadd exists on the system. If it does, the chances are high that the guest additions exist
           classes:
                   "additions_installed" and => { fileexists("/etc/init.d/vboxadd") };
           packages:
                   mac_08_00_27_6d_9f_fe::
                        "$(install_me)"
                           package_policy => "add",
                           package_method => yum;
        #In this section I am making decisions about a host based on its mac address
           files:
                   mac_08_00_27_6d_9f_fe::
                #If the mac address matches, copy the files into place
                #This is the name of the file as it will exist on the machine executing the promise
                #I.E. on the machine matching the mac address specified, the file in quotations will be created/replaced
                "/etc/sysconfig/network"
 
                #The copy_from takes on the following format: secure_copy("Location of file", "hostname holding the files")
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_network", "$(sys.policy_hub)");
 
                #To read this in english it reads "create this file on the local machine from this file location on a remote computer"
                "/etc/sysconfig/network-scripts/ifcfg-eth1"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_ifcfg-eth0", "$(sys.policy_hub)");
                "/etc/httpd/conf/httpd.conf"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_httpd.conf", "$(sys.policy_hub)");
                "/etc/nsswitch.conf"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_nsswitch.conf", "$(sys.policy_hub)");
                "/etc/samba/smb.conf"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_smb.conf", "$(sys.policy_hub)");
                "/etc/ssh/sshd_config"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_sshd_config", "$(sys.policy_hub)");
                "/etc/sudoers"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_sudoers", "$(sys.policy_hub)");
                "/var/spool/cron/root"
                   copy_from => secure_cp("$(sys.workdir)/masterfiles/files/service1_files/service1_var_spool_cron_root", "$(sys.policy_hub)");
        #This command will execute only if the mac address AND the correct hostname are not found
        #This is to ensure that the changes will take effect
           commands:
                  #In order to successfully install the virtualbox guest additions, we want the system to be fully up to date, and
                  #running the latest kernel. To acheive this, issue the reboot command after the update.
                  #yum update will only be read if the host has the correct mac address and does not have the guest additions installed
                  # and does not have the hostname "ln_op_service1" as defined in cfengine's hard class. It is assumed that the file
                  #Copies will have completed successfully at this point, but have not taken affect yet
                  mac_08_00_27_6d_9f_fe&!additions_installed&!ln_op_service1::
                           "/usr/bin/yum update -y";
                        "/sbin/reboot";
                  #This code should only execute after a reboot, the host name should have changed and therefore the above conditions
                  #are no longer true. Therefore we are only going to attempt to install the guest additions on the correct host only
                  #if they do not exist already. After the installation has been completed, reboot for the guest additions to take full effect.
                  mac_08_00_27_6d_9f_fe&!additions_installed::
                           "/bin/mount /dev/sr0 /mnt";
                        "/bin/sh /mnt/VBoxLinuxAdditions.run";
                           "/sbin/reboot";
 
This is related, cfengine uses a stdlib that controls services on a machine. It is incomplete though, so this python script will take sysv-rc-conf/chkconfig input and add them into the standard library

Code:
#!/usr/bin/python
#This script will attempt to add services to your cfengine stdlib.cf

import os
import sys
import platform
import fileinput

bundle_start = False

start_line = False
#Attempt to figure out which version of linux you are running
linux_version = platform.platform().lower()
redhat_types = "centos", "fedora", "redhat"
debian_types = "linuxmint", "ubuntu", "debian"
stdlib_file = "/var/cfengine/masterfiles/libraries/cfengine_stdlib.cf"
try:
    chkconfig_file = open(sys.argv[1]).readlines()
except:
    print "I need at least 1 input file to work"
    print "USAGE: add_to_stdlib.py <chkconfig list> <(optional) location of cfengine_stdlib.cf>"
    sys.exit()
  
#I need both a readline and the plain text file because I am going to do an inplace substitution
try:
    stdlib_file = sys.argv[2]
except:
    pass
stdlib = open(stdlib_file).readlines()

if any(similar_os in linux_version for similar_os in redhat_types):
    insert_after = " redhat::"
elif any(similar_os in linux_version for similar_os in debian_types):
    insert_after = " debian|ubuntu::"

#Create a list which will hold all of the services from chkconfig
services_list = []
for line in chkconfig_file:
        #If a line is blank, skip it
        if line in ['\n', '\r\n']:
            pass
        else:
            #Split the line so that we only have the service name
            line = line.split()[0]
            services_list.append(line)

#I am going to create a duplicate list     
sanitized_services = services_list[:]
#Service list is the original list, and we are going to use it to pop entries out of the sanitized list
for new_service in services_list:
    for stdlib_service in stdlib:
        if new_service in stdlib_service:
            if new_service in sanitized_services:
                #If the service already exists in the file, pop it from the sanitized list
                sanitized_services.remove(new_service)
sanitized_services.reverse()
#This does the inplace line additions to the file
for service in sanitized_services:
    for line in fileinput.input(stdlib_file, inplace=1):
            if "standard_services" in line:
                bundle_start = True

            if insert_after in line:
                start_line = True
            else:
                if start_line and bundle_start:

                    print '"startcommand[%s]" string => "/etc/init.d/%s start";' % (service,service)
                    print '"stopcommand[%s]" string => "/etc/init.d/%s stop";' % (service,service)
                    print '"pattern[%s]" string => ".*%s.*";' % (service,service)
                    print ""
                start_line = False
            if "# METHODS that implement these ....." in line:
                 bundle_start = False
            print line,

In conjunction with this, I have created 2 more scripts which will chkconfig on/off the services under redhat::

To turn them off

Code:
#!/usr/bin/python
#This script will attempt to prevent services from starting on boot by editing the cfengine_stdlib.cf

import os
import sys
import platform
import fileinput

#Look for the stop_word, start off being false
start_line = False
#Look for the bundle's start, begin being false
bundle_start = False
#Are we dealing with a redhat:: stanza? Start as false
redhat = False
stop_word = "stopcommand"

#Check to see if the user has entered a parameter on the CLI
try:
    cfengine_file = sys.argv[1]
except:
    cfengine_file = "/var/cfengine/masterfiles/libraries/cfengine_stdlib.cf"
    print "You didn't provide a stdlib file so I am assuming I should edit %s" % cfengine_file

services_list = []
chkconfig_list = []

for line in open(cfengine_file).readlines():
    if "stopcommand" in line and "chkconfig" not in line:
        line = line.split("[")[1].split("]")[0]
        if line in services_list:
            pass
        else:
            services_list.append(line)
    if "stopcommand" in line and "chkconfig" in line:
        line = line.split("[")[1].split("]")[0]
        chkconfig_list.append(line)    

for x in chkconfig_list:
    try:
        services_list.remove(x)
    except:
        pass
services_list.sort()       
for service in services_list:
    for line in fileinput.input(cfengine_file, inplace=1):
            #Locate the start of the bundle
            if "standard_services" in line:
                bundle_start = True
            #Find the redhat section
            if "redhat::" in line and bundle_start:
                redhat = True
            #If the line does not start with redhat:: but has "::" in the line, assume that we have
            #moved onto another distro
            if "redhat::" not in line and "::" in line:
                redhat = False
            #Parse the service name out from the list of services
            if stop_word in line:
                service2 = "[%s]" % service
                if service2 in line:
                    start_line = True
            else:
                #Insert the line into the text fiel
                if start_line and bundle_start and redhat:
                    print '  "stopcommand[%s]" string => "/sbin/chkconfig %s off";' % (service,service)
                start_line = False
            if "# METHODS that implement these ....." in line:
                 bundle_start = False
            print line,

To turn them on:

Code:
#!/usr/bin/python
#This script will attempt to prevent services from starting on boot by editing the cfengine_stdlib.cf

import os
import sys
import platform
import fileinput

#Look for the stop_word, start off being false
start_line = False
#Look for the bundle's start, begin being false
bundle_start = False
#Are we dealing with a redhat:: stanza? Start as false
redhat = False
stop_word = "startcommand"

#Check to see if the user has entered a parameter on the CLI
try:
    cfengine_file = sys.argv[1]
except:
    cfengine_file = "/var/cfengine/masterfiles/libraries/cfengine_stdlib.cf"
    print "You didn't provide a stdlib file so I am assuming I should edit %s" % cfengine_file

services_list = []
chkconfig_list = []

for line in open(cfengine_file).readlines():
    if "startcommand" in line and "chkconfig" not in line:
        line = line.split("[")[1].split("]")[0]
        if line in services_list:
            pass
        else:
            services_list.append(line)
    if "startcommand" in line and "chkconfig" in line:
        line = line.split("[")[1].split("]")[0]
        chkconfig_list.append(line)    

for x in chkconfig_list:
    try:
        services_list.remove(x)
    except:
        pass
services_list.sort()       
for service in services_list:
    for line in fileinput.input(cfengine_file, inplace=1):
            #Locate the start of the bundle
            if "standard_services" in line:
                bundle_start = True
            #Find the redhat section
            if "redhat::" in line and bundle_start:
                redhat = True
            #If the line does not start with redhat:: but has "::" in the line, assume that we have
            #moved onto another distro
            if "redhat::" not in line and "::" in line:
                redhat = False
            #Parse the service name out from the list of services
            if stop_word in line:
                service2 = "[%s]" % service
                if service2 in line:
                    start_line = True
            else:
                #Insert the line into the text fiel
                if start_line and bundle_start and redhat:
                    print '  "startcommand[%s]" string => "/sbin/chkconfig %s on";' % (service,service)
                start_line = False
            if "# METHODS that implement these ....." in line:
                 bundle_start = False
            print line,
 
Last edited:
Back