1. Goal

This guide helps SIE Mystics set up and use Razor for unattended OS installs on (B)are (M)etal [physical] computers.

Razor’s software written by EMC and maintained by Puppet (the company), though it doesn’t actually require Puppet (the software) in order to work.

Stuff you’ll need to follow this guide:
  • One VM running CentOS 7 x86_64.

  • One physical computer that supports PXE booting.

Table 1. Robroy’s VM

Host

ESX 5.5 U3b

VM config

2 vCPUs; 8GB RAM; VMXNET3; 'Tools running

ISO

CentOS-7-x86_64-DVD-1611.iso

Profile

Development and Creative Workstation

Customizations

SELinux and firewall disabled

Patched as of

October 3rd, 2017 (yum -y update)

Table 2. Robroy’s physical computers

Type

Hitachi CR220

Quanta D52B-1U

BIOS

7TTSHE-F13

3A08-H2

Hostname

ost6

skylake (unofficial)

Location

SIE RK-8 U25 [L-68x212]

SIE RK-21 U10 [L-100x200]

NIC

Onboard Intel 82576 Gigabit Ethernet

Onboard Intel X722 10GbE SFP+

NIC Intel Boot Agent

v1.3.31, PXE 2.1 Build 086 (WfM 2.0)

40G v1.0.60

NIC MAC

50:e5:49:44:61:ba

a8:1e:84:a2:26:00

Raritan ID

SIE_SRV_Hitachi_CR220-4

N/A

BMC

172.17.58.34

172.17.11.12

OS IP

172.17.58.33

172.17.11.72

2. Hardware configuration

The hardware configuration steps required to use Razor are the same steps required for traditional unattended OS installs.

2.1. Network connectivity

All computers used for this exercise should be on the same subnet.

This is because DHCP uses broadcasts, and most routers (including our lab’s) don’t pass broadcast packets between subnets.

The computers in this guide are all on 172.17.58.0/24.

2.2. Ethernet switch setup

If spanning-tree’s enabled on the bare-metal host’s switch port (used to get DHCP leases), enable Port Fast mode.

If Port Fast mode is not enabled, spanning-tree’s negotiation activity will block outgoing frames for up to thirty seconds after the port first becomes active.

Since the DHCP client in some NIC option ROMs times out in less than thirty seconds, this can prevent the NIC from getting a lease during POST.

In Port Fast mode, delays introduced by spanning-tree when the port first comes online are bypassed, at the cost of possibly disrupting spanning-tree’s functionality. Yet when the port goes to a computer’s NIC (and not another switch), that trade-off doesn’t matter—and this makes DHCP work.

Example: Cisco Nexus 9000
CN93180-01# configure
Enter configuration commands, one per line. End with CNTL/Z.
CN93180-01(config)# interface Eth1/3
CN93180-01(config-if)# spanning-tree port type edge
Edge port type (portfast) should only be enabled on ports connected to a single
 host. Connecting hubs, concentrators, switches, bridges, etc...  to this
 interface when edge port type (portfast) is enabled, can cause temporary bridging loops.
 Use with CAUTION

Edge Port Type (Portfast) has been configured on Ethernet1/3 but will only
 have effect when the interface is in a non-trunking mode.
Note Switches managed by TechOps will need a ticket for this change; see NET-1197 for an example.

2.3. Hitachi CR220 setup

BIOS
  1. Configure the BIOS to load the NIC’s option ROM during POST:

    If the computer you’re using has an option to skip loading the "option ROM" (code loaded from the NIC’s firmware and put on-processor during POST, which is what makes the Intel Boot Agent prompt appear). On my physical computer, the BIOS configuration item is located under Advanced → PnP Configuration:

    CR220 NIC Option ROM screen
  2. Configure the computer to boot using the (I)ntel (B)oot (A)gent (the code in the NIC’s firmware), as shown.

    Note Depending on the computer’s existing configuration, it may be necessary to configure option ROM loading, save changes, exit the BIOS setup program, and allow POST to finish once (so that the NIC’s option ROM actually gets loaded), before the IBA boot option will appear on this screen.
    CR220 BIOS boot order screen
NIC
  1. Enter the NIC’s option ROM configuration program by hitting <Ctrl><s> during POST, at this screen:

    CR220 NIC option ROM load
  2. Verify that the NIC’s configured for PXE booting; it should look like this:

    CR220 NIC IBA config

2.4. Quanta D52B-1U setup

Caution

Avoid BIOS level 3A08-H4.

When non-UEFI (Legacy) booting’s enabled, this BIOS level will cause the computer to begin an infinite reset loop during POST, leaving no way to enter the BIOS setup program to correct the problem.

If y’all encounter this trap:

  1. Power the computer down, slide it out, and open its lid.

  2. Look at the illustration on the bottom of the lid, and locate DIP switch SW3.

  3. Toggle BIT 1, "CMOS clear" to ON, and wait for fifteen seconds.

  4. Toggle BIT 1, "CMOS clear" back to OFF.

  5. Bring the computer back up, and carry on to victory.

  1. Configure the computer to boot using Legacy (non-EUFI) mode [Boot → Boot mode select]:

    D52B-1U BIOS Legacy mode
  2. Enable PXE [Advanced → Network Stack Configuration]:

    D52B-1U BIOS Network
  3. Enable Legacy (non-UEFI) PXE loading [Advanced → Onboard Device Configuration]:

    D52B-1U BIOS PXE Legacy
  4. Order the Intel Boot Agent entry to make the computer boot from it [Boot → FIXED BOOT ORDER]:

    D52B-1U BIOS boot order

3. Software configuration

3.1. Traditional services

Razor depends on the same traditional TFTP and DHCP services used by all typical PC-style unattended network-based installs.

Because there are two general approaches to providing these services (the relatively old-school daemons, versus dnsmasq), both are documented here.

Warning

All DHCP services in the Hitachi vAnTaRa lab must be configured using reservations, to provide leases only to one’s intended equipment.

This guide’s steps result in a configuration that abides by this.

Old-school versus Dnsmasq

These services can be provided using the old-school daemons (the ISC DHCP service and Peter Anvin’s BSD-derived tftpd), or dnsmasq.

Benefit Old-school Dnsmasq

Tried-and-true

Yes

Less so

Recommended by Puppet (company) for Razor

Yes

No, but not recommended against

Present in CentOS 7 by default

No

Yes1

One program for both TFTP and DHCP

No

Yes

1 dnsmasq was present by default on CentOS 7 when installed using the "Development and Creative Workstation" profile. I’m not sure about the other profiles.

3.1.1. Old-school: xinetd, tftpd-hpa and ISC dhcpd

Note Choose either the old-school approach or dnsmasq (next section), but not both.
TFTP
  1. Install the tftp daemon and xinetd:

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # yum -y install xinetd tftp-server
  2. Turn them on:

    # systemctl enable xinetd tftp
    # systemctl start xinetd tftp
DHCP
  1. Install the ISC DHCP server:

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # yum -y install dhcp
  2. Make the DHCP server’s configuration file:

    # ex /etc/dhcp/dhcpd.conf
    "/etc/dhcp/dhcpd.conf" [New File]
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :i
    option domain-name "sie.hds.com";
    
    default-lease-time 600;
    max-lease-time 7200;
    authoritative;
    
    subnet 172.17.58.0 netmask 255.255.255.0 {
        option routers 172.17.58.1;
        option domain-name-servers 172.17.58.254, 172.17.59.254;
    }
    
    host ost6 {
        hardware ethernet 50:e5:49:44:61:ba;
        fixed-address 172.17.58.33;
        if exists user-class and option user-class = "iPXE" {    1
            filename "bootstrap.ipxe";
        } else {
            filename "undionly.kpxe";
        }
        next-server 172.17.58.151;                               2
    }
    .
    :x!
    1 Don’t worry about this crazy iPXE stuff for now; that’ll get set up while installing Razor.
    2 This is the TFTP server’s IP address.
  3. Turn it on:

    # systemctl enable dhcpd
    # systemctl start dhcpd

3.1.2. dnsmasq

Note Choose either dnsmasq or the old-school approach (above), but not both.
  1. Make a TFTP directory:

    # mkdir /var/lib/tftpboot
  2. Make /etc/dnsmasq.d/hitachi-puma.conf:

    # ex /etc/dnsmasq.d/hitachi-puma.conf
    "/etc/dnsmasq.d/hitachi-puma.conf" [New File]
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :i
    # dnsmasq always binds to all IPs on the loopback interface w/o this.
    except-interface=lo
    
    # This makes dnsmasq bind to all IPs on ens160 (see with "ss -l -u").
    interface=ens160
    bind-interfaces
    
    #-----------------------------------------------------------------------------
    # The "static" keyword causes dnsmasq to give out only reserved leases.
    # This computer's IP before "static" yields a range definition that won't be
    # used (since "static" is present), of 172.17.0.0/16.  This is because
    # dnsmasq gleans the netmask from the provided IP's class (A, B or C).
    #-----------------------------------------------------------------------------
    
    dhcp-range=172.17.58.154,static
    dhcp-host=50:e5:49:44:61:ba,ost6.sie.hds.com,172.17.58.33
    dhcp-authoritative
    domain=sie.hds.com
    
    #-----------------------------------------------------------------------------
    # Though dnsmasq is supposed to glean DNS resolver configuration values from
    # the computer upon which it runs, this did not work with iPXE, so it's
    # hard-coded here instead.
    #-----------------------------------------------------------------------------
    
    dhcp-option=option:dns-server,172.17.58.254
    
    #-----------------------------------------------------------------------------
    # This "175" number identifies iPXE to dnsmasq's DHCP server, as opposed to
    # traditional PXE (loaded from the NIC's ROM).  When PXE gets a DHCP lease,
    # its next-server filename option's undionly.kpxe; when iPXE gets a DHCP
    # lease, its option's bootstrap.ipxe (a script).  This trickery makes Razor's
    # PXE -> iPXE -> OS chain-loading work.
    #-----------------------------------------------------------------------------
    
    dhcp-match=IPXEBOOT,175
    dhcp-boot=net:IPXEBOOT,bootstrap.ipxe
    dhcp-boot=undionly.kpxe
    
    enable-tftp
    tftp-root=/var/lib/tftpboot
    
    # Disable dnsmasq's DNS service.
    port=0
    .
    :x!
  3. Turn it on:

    # systemctl enable dnsmasq
    # systemctl start dnsmasq

3.2. Razor setup

3.2.1. PostgreSQL setup

  1. Install PostgreSQL:

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # yum -y install postgresql-server postgresql-contrib
    # postgresql-setup initdb
  2. Configure PostgreSQL for password-based authentication:

    # cp /var/lib/pgsql/data/pg_hba.conf /var/lib/pgsql/data/pg_hba.conf.orig
    # ex /var/lib/pgsql/data/pg_hba.conf
    "/var/lib/pgsql/data/pg_hba.conf" 89L, 4228C
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :g/ident/#
    
         46 # "krb5", "ident", "peer", "pam", "ldap", "radius" or "cert".  Note that
         82 host    all             all             127.0.0.1/32            ident
         84 host    all             all             ::1/128                 ident
         88 #host    replication     postgres        127.0.0.1/32            ident
         89 #host    replication     postgres        ::1/128                 ident
    :82s/ident/md5
    host    all             all             127.0.0.1/32            md5
    :84s/ident/md5
    host    all             all             ::1/128                 md5
    :x!
    # diff /var/lib/pgsql/data/pg_hba.conf.orig /var/lib/pgsql/data/pg_hba.conf
    82c82
    < host    all             all             127.0.0.1/32            ident
    ---
    > host    all             all             127.0.0.1/32            md5
    84c84
    < host    all             all             ::1/128                 ident
    ---
    > host    all             all             ::1/128                 md5
  3. Turn it on:

    # systemctl enable postgresql
    # systemctl start postgresql
  4. Make a PostgreSQL database and account for Razor. The password I use is squirrelmax.

    # su - postgres
    $ id
    uid=26(postgres) gid=26(postgres) groups=26(postgres)
    $ createuser -P razor
    Enter password for new role:
    Enter it again:
    $ createdb -O razor razor_prd
  5. Optionally confirm that the database exists:

    $ psql -l -h 127.0.0.1 -U razor razor_prd
    Password for user razor:
                                      List of databases
       Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
    -----------+----------+----------+-------------+-------------+-----------------------
     postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
     razor_prd | razor    | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
     template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
               |          |          |             |             | postgres=CTc/postgres
     template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
               |          |          |             |             | postgres=CTc/postgres
    (4 rows)

3.2.2. Razor setup

  1. Install Razor:

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # yum -y install http://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
    # yum -y install razor-server
  2. Secure the file that’ll soon contain a clear-text password:

    # cp /etc/puppetlabs/razor-server/config.yaml /etc/puppetlabs/razor-server/config.yaml.orig
    # ls -l /etc/puppetlabs/razor-server/config.yaml
    -rw-r--r-- 1 root root 5808 Oct 11 14:14 /etc/puppetlabs/razor-server/config.yaml
    # chgrp razor /etc/puppetlabs/razor-server/config.yaml
    # chmod o-r /etc/puppetlabs/razor-server/config.yaml
    # ls -l /etc/puppetlabs/razor-server/config.yaml
    -rw-r----- 1 root razor 5808 Oct 11 14:14 /etc/puppetlabs/razor-server/config.yaml
  3. Configure Razor to access PostgreSQL (the password is squirrelmax):

    # ex /etc/puppetlabs/razor-server/config.yaml
    "/etc/puppetlabs/razor-server/config.yaml" 146L, 5798C
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :g/database_url/#
    
          7 # The *database_url* setting must be a connection URL for
         11   database_url: 'jdbc:postgresql:razor_prd?user=razor&password=mypass'
         13   database_url: 'jdbc:postgresql:razor_dev'
         15   database_url: 'jdbc:postgresql:razor?user=razor&password=mypass'
        145     - database_url
    :11s/mypass/squirrelmax
      database_url: 'jdbc:postgresql:razor_prd?user=razor&password=squirrelmax'
    :15s/mypass/squirrelmax
      database_url: 'jdbc:postgresql:razor?user=razor&password=squirrelmax'
    :x!
    # diff /etc/puppetlabs/razor-server/config.yaml /etc/puppetlabs/razor-server/config.yaml.orig
    11c11
    <   database_url: 'jdbc:postgresql:razor_prd?user=razor&password=squirrelmax'
    ---
    >   database_url: 'jdbc:postgresql:razor_prd?user=razor&password=mypass'
    15c15
    <   database_url: 'jdbc:postgresql:razor?user=razor&password=squirrelmax'
    ---
    >   database_url: 'jdbc:postgresql:razor?user=razor&password=mypass'
  4. Tell Razor to put its stuff in PostgreSQL:

    # su - razor
    $ id
    uid=987(razor) gid=982(razor) groups=982(razor)
    $ razor-admin -e production migrate-database
  5. Turn it on:

    # systemctl enable razor-server
    # systemctl start razor-server
  6. Optionally view the Razor API to try it out (partial success output’s shown here):

    # env | grep http
    # curl localhost:8150/api
    {"commands":[{"name":"add-policy-tag","rel":"http://api.puppetlabs.com/razor/v1/commands/add-policy-tag"
    ...
  7. Install the Linux kernel used by Razor (which they call the "microkernel;" kids these days…):

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # wget http://pup.pt/razor-microkernel-latest
    # tar xvf razor-microkernel-latest --directory=/opt/puppetlabs/server/data/razor-server/repo
  8. Ask Razor to generate an iPXE script, and prepare it for TFTP access:

    This script’s used by iPXE during its "chain load" phase (between the NIC’s regular PXE code and the OS boot code).

    Note Run wget with a URL that includes a hostname or IP that’ll also work when used by iPXE code on the physical computer; don’t use a self-reference (localhost or 127.0.0.1) in the URL. This matters because Razor uses this URL to automatically generate the iPXE script itself.
    # env | grep http
    # wget http://172.17.58.154:8150/api/microkernel/bootstrap?nic_max=1
    # mv bootstrap\?nic_max\=1 /var/lib/tftpboot/bootstrap.ipxe
  9. Download iPXE and prepare it for TFTP access:

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # wget http://boot.ipxe.org/undionly.kpxe
    # mv undionly.kpxe /var/lib/tftpboot
  10. Install the Razor client and try it out:

    # env | grep http
    http_proxy=http://10.78.0.111:8080
    https_proxy=http://10.78.0.111:8080
    # gem install razor-client
    # razor --help

4. Using Razor

Razor has its own REST API, and also a client coded to use it. These examples show how to perform OS installs using the client.

4.1. Unattended CentOS 7.x

These steps install a physical computer using the regular CentOS installer ISO (though Razor does unpack and modify the ISO’s contents, yet that part’s automatic).

  1. Place an unmodified CentOS installer ISO on the Razor host:

    % scp CentOS-7-x86_64-DVD-1611.iso razor-host:/tmp
  2. Make a Razor "broker" config, where "broker" means Puppet, or something else that smells like Puppet. Since we’re not using Puppet, we’ll make a noop broker (to have Razor skip its hand-off to Puppet):

    # razor create-broker --name t5k --broker-type noop
  3. Make a Razor "repo," which is a configuration object corresponding to where Razor keeps OS install ISOs and files.

    # razor create-repo --name alf7.b --iso-url file:///tmp/CentOS-7-x86_64-DVD-1611.iso --task centos/7
  4. Make a Razor "policy."

    # razor create-policy --name alf7.b --repo alf7.b --task 
    centos/7 --broker t5k --enabled --hostname ost6.sie.hds.com 
    --root-password Hitachi1 --max-count 20
  5. Verify that the Razor operations were successful before moving on:

    # razor commands
    From http://localhost:8150/api/collections/commands:
    
    +------+---------------+----------------+--------+----------+
    | name | command       | name parameter | errors | status   |
    +------+---------------+----------------+--------+----------+
    | 3    | create-policy | alf7.b         | 0      | finished |
    +------+---------------+----------------+--------+----------+
    | 2    | create-repo   | alf7.b         | 0      | finished |
    +------+---------------+----------------+--------+----------+
    | 1    | create-broker | t5k            | 0      | finished |
    +------+---------------+----------------+--------+----------+
  6. Reboot the physical computer, and allow the BIOS → PXE → iPXE → Razor → OS installer chain-loading lunacy begin!

    During this process, you’ll no doubt want to keep your eyes glued to the remote console, to watch Razor go.

    Tip
    Re-installing

    If this isn’t your first pass through these steps, it may be necessary to tell Razor to clear the "installed" flag for this node, before Razor will install it again.

    Find the node ID with razor nodes, then clear the flag with razor reinstall-node node_ID, where node_ID will resemble "node1."

4.2. Unattended OEL

Razor doesn’t come with pre-defined tasks to handle unattended OEL installs, so I’m not sure how to handle this one yet.

4.3. Unattended SLES 12 SP3

Tip

The SLES installer’s DHCP client is configured with a very short timeout.

If the installation fails due to not having received a lease in time, verify that the Ethernet switch the computer’s plugged in to is configured correctly (see Ethernet switch setup for more information).

  1. Place the unmodified SLES 12 SP3 installer ISO on the Razor host:

    % scp SLE-12-SP3-Server-DVD-x86_64-GM-DVD1.iso razor-host:/tmp
  2. Make a non-op Razor "broker" config, since we’re skipping Puppet.

    # razor create-broker --name t5k --broker-type noop
  3. Make a Razor "repo," which is a configuration object corresponding to where Razor keeps OS install ISOs and files.

    # razor create-repo --name sles12sp3 --iso-url file:///tmp/SLE-12-SP3-Server-DVD-x86_64-GM-DVD1.iso --task sles/12
  4. Make a Razor "policy."

    # razor create-policy --name sles12sp3 --repo sles12sp3 
    --task sles/12 --broker t5k --enabled --hostname skylake --root-password
     Hitachi1 --max-count 20
  5. Reboot the physical computer, and allow the BIOS → PXE → iPXE → Razor → OS installer chain-loading lunacy begin!

4.4. Unattended ESX 5.5 U3b

These steps install a physical computer using the regular ESX 5.5 U3b ISO:

  1. Place the unmodified ESX installer ISO on the Razor host:

    % scp VMware-VMvisor-Installer-201512001-3248547.x86_64.iso razor-host:/tmp
  2. Make a non-op Razor "broker" config, since we’re skipping Puppet.

    # razor create-broker --name t5k --broker-type noop
  3. Make a Razor "repo," which is a configuration object corresponding to where Razor keeps OS install ISOs and files.

    # razor create-repo --name esx55u3b --iso-url 
    file:///tmp/VMware-VMvisor-Installer-201512001-3248547.x86_64.iso --task
     vmware_esxi
  4. Make a Razor "policy."

    # razor create-policy --name esx55u3b --repo esx55u3b --task 
    vmware_esxi --broker t5k --enabled --hostname ost6.sie.hds.com 
    --root-password Hitachi1 --max-count 20
  5. Verify that the Razor operations were successful before moving on (rows 1, 4 and 5):

    # razor commands
    From http://localhost:8150/api/collections/commands:
    
    +------+----------------+----------------+--------+----------+
    | name | command        | name parameter | errors | status   |
    +------+----------------+----------------+--------+----------+
    | 7    | reinstall-node | node1          | 0      | finished |
    +------+----------------+----------------+--------+----------+
    | 6    | delete-policy  | alf7.b         | 0      | finished |
    +------+----------------+----------------+--------+----------+
    | 5    | create-policy  | esx55u3b       | 0      | finished |
    +------+----------------+----------------+--------+----------+
    | 4    | create-repo    | esx55u3b       | 0      | finished |
    +------+----------------+----------------+--------+----------+
    | 3    | create-policy  | alf7.b         | 0      | finished |
    +------+----------------+----------------+--------+----------+
    | 2    | create-repo    | alf7.b         | 0      | finished |
    +------+----------------+----------------+--------+----------+
    | 1    | create-broker  | t5k            | 0      | finished |
    +------+----------------+----------------+--------+----------+
  6. Reboot the physical computer, and allow the BIOS → PXE → iPXE → Razor → OS installer chain-loading lunacy begin!

5. Customizing Razor

5.1. Post-install scripts

Razor doesn’t have general support for post-install scripts, because once the install’s finished, Razor normally hands all follow-up configuration off to Puppet.

But it’s possible to achieve post-install script functionality without Puppet, using either of two methods: broker, or task.

To choose between these two methods, first decide how the failure case of post-install scripts should be handled.

  • Use the broker method to have Razor ignore post-install script failures.

    This means that if the OS install succeeds but the post-install script fails, Razor will mark the OS install as successful/complete.

  • Use the task method to have Razor observe post-install script failures.

    This means that if the OS install succeeds but the post-install script fails, Razor will mark the OS install as failed/incomplete.

5.1.1. The broker method

RHEL 7
  1. Place an unmodified RHEL installer ISO on the Razor host:

    % scp rhel-server-7.4-x86_64-dvd.iso razor-host:/tmp
  2. Make a Razor repo.

    # razor create-repo --name hitachi-rhel74 --iso-url file:///tmp/rhel-server-7.4-x86_64-dvd.iso --task redhat/7
  3. Make a place to store custom broker definitions:

    # mkdir -p /opt/hitachi/puma/puppetlabs/razor-server/brokers
    Caution

    Puppet employee Scott McClellan recommended keeping custom task and broker definitions outside of /opt/puppetlabs, because keeping custom definitions there will break their upgrade system

  4. Configure Razor to search our custom broker folder:

    # cp /etc/puppetlabs/razor-server/config.yaml /etc/puppetlabs/razor-server/config.yaml.old
    # ex /etc/puppetlabs/razor-server/config.yaml
    "/etc/puppetlabs/razor-server/config.yaml" 146L, 5808C
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :g/brokers/p#
    
         90   broker_path: brokers
    :90s#$#:/opt/hitachi/puma/puppetlabs/razor-server/brokers#
      broker_path: brokers:/opt/hitachi/puma/puppetlabs/razor-server/brokers
    :x!
    # diff /etc/puppetlabs/razor-server/config.yaml /etc/puppetlabs/razor-server/config.yaml.old
    86c86
    <   broker_path: brokers:/opt/hitachi/puma/puppetlabs/razor-server/brokers
    ---
    >   broker_path: brokers
  5. Put the path configuration in to effect by re-starting Razor:

    # systemctl stop razor-server
    # systemctl start razor-server
  6. Make a custom broker.

    # cd /opt/hitachi/puma/puppetlabs/razor-server/brokers
    # mkdir hitachi-rhel74.broker
  7. Copy in the embedded Ruby template file from the supplied noop broker:

    # cd hitachi-rhel74.broker
    # cp /opt/puppetlabs/server/apps/razor-server/share/razor-server/brokers/noop.broker/install.erb .
  8. Update the install.erb embedded Ruby template with a shell command to make an empty /T5K_is_Glorious file:

    # ex install.erb
    "install.erb" 17L, 507C
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :%#
          1 #! /bin/bash
          2 set -u
          3 set -e
          4
          5 # Some utility functions.
          6 fail() { echo >&2 "$@"; exit 1; }
          7 warn() { echo >&2 "$@"; }
          8 cmd()  { hash "$1" >&/dev/null; } # portable 'which'
          9
         10 # Log that the broker is finished.
         11 if cmd curl; then
         12     curl -sL "<%= stage_done_url %>" || fail "curl failed to log broker completion"
         13 elif cmd wget; then
         14     wget -qO- "<%= stage_done_url %>" || fail "wget failed to log broker completion" &> /dev/null
         15 else
         16     warn "neither curl nor wget installed; cannot log completion of broker"
         17 fi
    :9i
    touch /T5K_is_Glorious
    .
    :x!
  9. Tell Razor about the custom broker definition:

    # razor create-broker --name hitachi-rhel74 --broker-type hitachi-rhel74
  10. Make a policy using the custom broker:

    # razor create-policy --name hitachi-rhel74 --repo 
    hitachi-rhel74 --task redhat/7 --broker hitachi-rhel74 --enabled 
    --hostname skylake --root-password Hitachi1 --max-count 20
  11. Reboot the physical computer and allow Razor to install the OS. When Razor’s finished, verify that /T5K_is_Glorious exists.

5.1.2. The task method

The task post-install script approach varies between different OSes, because each OS has its own specific task object (reflecting the specific actions required to perform an unattended install of that OS).

RHEL 7
  1. Place an unmodified RHEL installer ISO on the Razor host:

    % scp rhel-server-7.4-x86_64-dvd.iso razor-host:/tmp
  2. Make a non-op Razor broker config.

    # razor create-broker --name hitachi-noop --broker-type noop
  3. Make a Razor repo. Although we’ll soon make a custom task, it’s OK to use a supplied task (in this case, redhat/7) at this stage.

    # razor create-repo --name hitachi-rhel74 --iso-url file:///tmp/rhel-server-7.4-x86_64-dvd.iso --task redhat/7
  4. Make a place to store custom task configurations:

    # mkdir -p /opt/hitachi/puma/puppetlabs/razor-server/tasks
    Caution

    Puppet employee Scott McClellan recommended keeping custom task and broker definitions outside of /opt/puppetlabs, because keeping custom definitions there will break their upgrade system.

    See References for a link to his mail.

  5. Configure Razor to search our custom task folder:

    # cp /etc/puppetlabs/razor-server/config.yaml /etc/puppetlabs/razor-server/config.yaml.old
    # ex /etc/puppetlabs/razor-server/config.yaml
    "/etc/puppetlabs/razor-server/config.yaml" 146L, 5808C
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :g/tasks/p#
    
         85   # we should look for tasks
         86   task_path: tasks
    :86s#$#:/opt/hitachi/puma/puppetlabs/razor-server/tasks#
      task_path: tasks:/opt/hitachi/puma/puppetlabs/razor-server/tasks
    :x!
    # diff /etc/puppetlabs/razor-server/config.yaml /etc/puppetlabs/razor-server/config.yaml.old
    86c86
    <   task_path: tasks:/opt/hitachi/puma/puppetlabs/razor-server/tasks
    ---
    >   task_path: tasks
  6. Put the path configuration in to effect by re-starting Razor:

    # systemctl stop razor-server
    # systemctl start razor-server
  7. Make a new Razor task named hitachi-rhel74. At a minimum, each task requires a directory in the path shown below, and a metadata.yaml file (next step).

    # cd /opt/hitachi/puma/puppetlabs/razor-server/tasks
    # mkdir hitachi-rhel74.task
  8. Make a metadata.yaml file to define the new task; other tasks under the same path can be used for reference.

    # cd hitachi-rhel74.task
    # pwd
    /opt/hitachi/puma/puppetlabs/razor-server/tasks/hitachi-rhel74.task
    # ex metadata.yaml
    "metadata.yaml" [New File]
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :i
    os_version: 7
    label: Red Hat Enterprise Linux 7
    description: Red Hat Linux 7 installer (Hitachi)     1
    base: redhat/7                                       2
    .
    :x!
    1 This string appears in the output of razor tasks.
    2 This makes hitachi-rhel74 a child task of redhat/7, which is itself a child task of redhat.
    Tip
    Parent and child tasks
    Children inherit settings from parents. If settings exist in the child which conflict with those in the parent, the child wins. This means that beyond the metadata.yaml file, a child task only needs to contain files that differ from its parent task(s).
  9. Copy post_install.erb from the redhat grandparent task, and customize it. This customization simply makes a /T5K_is_Glorious file after the install’s finished.

    # pwd
    /opt/hitachi/puma/puppetlabs/razor-server/tasks/hitachi-rhel74.task
    # cp /opt/puppetlabs/server/apps/razor-server/share/razor-server/tasks/redhat.task/post_install.erb .
    # ex post_install.erb
    "post_install.erb" 24L, 659C
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :%#
          1 #!/bin/bash
          2
          3 exec >> /var/log/razor.log 2>&1
          4
          5 echo "Starting post_install"
          6
          7 # Wait for network to come up when using NetworkManager.
          8 if service NetworkManager status >/dev/null 2>&1 && type -P nm-online; then
          9     nm-online -q --timeout=10 || nm-online -q -x --timeout=30
         10     [ "$?" -eq 0 ] || exit 1
         11 fi
         12
         13 <%= render_template("set_hostname") %>
         14
         15 <%= render_template("store_ip") %>
         16
         17 # @todo lutter 2013-09-12: we should register the system with RHN; be
         18 # careful though, since this file is also used by the CentOS installer, for
         19 # which there is no RHN registration
         20
         21 <%= render_template("os_complete") %>
         22
         23 # We are done
         24 curl -s <%= stage_done_url("finished") %>
    :22i
    touch /T5K_is_Glorious
    .
    :x!
  10. Make a policy for the custom task.

    # razor create-policy --name hitachi-rhel74 --repo 
    hitachi-rhel74 --task hitachi-rhel74 --broker hitachi-noop --enabled 
    --hostname skylake --root-password Hitachi1 --max-count 20
  11. Reboot the physical computer and allow Razor to install the OS. When Razor’s finished, verify that /T5K_is_Glorious exists.

6. Working OSes

OS D52B-1U (Skylake) D52B-1U Comment

ESX 5.5 U3b

Not working

Missing NIC drivers

ESX 5.5 U3b OEM

Not working

Missing NIC drivers

ESX 6.0 U3a

Not working

Missing NIC drivers

ESX 6.0 U3a OEM

Working

ESX 6.5 U1

Working

ESX 6.5 U1 OEM

Working

SLES 12 SP1

Not working

Missing NIC drivers

SLES 12 SP2

Not working

Missing NIC drivers

SLES 12 SP3

Working

RHEL 7.3

Working

RHEL 7.4

Working

7. References

8. About this page

This was written in AsciiDoc; its source is index.txt. To re-make this HTML file after editing the source:

% asciidoc index.txt
Powered by FreeBSD