By Jeff Victor-Oracle on Mar 10, 2015
IntroductionHave you used Solaris 11 and wondered how to maintain customized system configuration files? In the past, and on other Unix/Linux systems, maintaining these configuration files was fraught with peril: extra bolt-on tools are needed to track changes, verify that inappropriate changes were not made, and fix them when something broke them.
A combination of features added to Solaris 10 and 11 address those problems. This blog entry describes the current state of related features, and demonstrates the method that was designed and implemented to automatically deploy and track changes to configuration files, verify consistency, and fix configuration files that "broke." Further, these new features are tightly integrated with the Solaris Service Management Facility introduced in Solaris 10 and the packaging system introduced in Solaris 11.
Solaris 10 added the Service Management Facility, which significantly improved on the old, unreliable pile of scripts in /etc/rc#.d directories. This also allowed us to move from the old model of system configuration information stored in ASCII files to a database of configuration information. The latter change reduces the risk associated with manual or automated modifications of text files. Each modification is the result of a command that verifies the correctness of the change before applying it. That verification process greatly reduces the opportunities for a mistake that can be very difficult to troubleshoot.
During updates to Solaris 10 and 11 we continued to move configuration files into SMF service properties. However, there are still configuration files, and we wanted to provide better integration between the Solaris 11 packaging facility (IPS), and those remaining configuration files. This blog entry demonstrates some of that integration, using features added up through Solaris 11.1.
Many Solaris systems need customized email delivery rules. In the past, providing those rules required replacing /etc/mail/sendmail.cf with a custom file. However, this created the need to maintain that file - restoring it after a system udpate, verifying its integrity periodically, and potentially fixing it if someone or something broke it.
IPS provides the tools to accomplish those goals, specifically:
- maintain one or more versions of a configuration file in an IPS repository
- use IPS and AI (Automated Installer) to install, update, verify, and potentially fix that configuration file
- automatically perform the steps necessary to re-configure the system with a configuration file that has just been installed or updated.
The rest of this assumes that you understand Solaris 11 and IPS.
In this example, we want to deliver a custom sendmail.cf file to multiple systems. We will do that by creating a new IPS package that contains just one configuration file. We need to create the "precursor" to a sendmail.cf file, (sendmail.mc) that will be expanded by sendmail when it starts. We also need to create a custom manifest for the package. Finally, we must create an SMF service profile, which will cause Solaris to understand that a new sendmail configuration is available and should be integrated into its database of configuration information.
Here are the steps in more detail.
- Create a directory ("mypkgdir") that will hold the package manifest and a
directory ("contents") for package contents.
$ mkdir -p mypkgdir/contents $ cd mypkgdirThen create the configuration file that you want to deploy with this package. For this example, we simply copy an existing configuration file.
$ cp /etc/mail/cf/cf/sendmail.mc contents/custom_sm.mc
- Create a manifest file in mypkgdir/sendmail-config.p5m: (the entity that owns the computers is the
fictional corporation Consolidated Widgets, Inc.)
set name=pkg.fmri value=pkg://firstname.lastname@example.org,1.0 set name=com.cwi.info.name value=Solaris11sendmail set name=pkg.description value="ConWid sendmail.mc file for Solaris 11, accepts only local connections." set name=com.cwi.info.description value="Sendmail configuration" set name=pkg.summary value="Sendmail configuration" set name=variant.opensolaris.zone value=global value=nonglobal set name=com.cwi.info.version value=8.14.9 set name=info.classification value=org.opensolaris.category.2008:System/Core set name=org.opensolaris.smf.fmri value=svc:/network/smtp:sendmail depend fmri=pkg://solaris/service/network/smtp/sendmail type=require file custom_sm.mc group=mail mode=0444 owner=root \ path=etc/mail/cf/cf/custom_sm.mc file custom_sm_mc.xml group=mail mode=0444 owner=root \ path=lib/svc/manifest/site/custom_sm_mc.xml \ restart_fmri=svc:/system/manifest-import:default \ refresh_fmri=svc:/network/smtp:sendmail \ restart_fmri=svc:/network/smtp:sendmailThe "depend" line tells IPS that the package smtp/sendmail must already be installed on this system. If it isn't, Solaris will install that package before proceeding to install this package.
The line beginning "file custom_sm.mc" gives IPS detailed metadata about the configuration file, and indicates the full pathname - within an image - at which the macro should be stored. The last line specifies the local file name of of the service profile (more on that later), and the location to store it during package installation. It also lists three actuators: SMF services to refresh (re-configure) or restart at the end of package installation. The first of those imports new manifests and service profiles. Importing the service profile changes the property path_to_sendmail_mc. The other two re-configure and restart sendmail. Those two actions expand and then use the new configuration file - the goal of this entire exercise!
- Create a service profile:
$ svcbundle -o contents/custom_sm_mc.xml -s bundle-type=profile \ -s service-name=network/smtp -s instance-name=sendmail -s enabled=true \ -s instance-property=config:path_to_sendmail_mc:astring:/etc/mail/cf/cf/custom_sm.mcThat command creates the file custom_sm_mc.xml, which describes the profile. The sole profile of that profile is to set the sendmail service property "config/path_to_sendmail_mc" to the name of the new sendmail macro file.
- Verify correctness of the manifest. In this example, the Solaris repository is mounted at /mnt/repo1. For most systems, "-r" will be followed by the repository's URI, e.g. http://pkg.oracle.com/solaris/release/ or a data center's repository.
$ pkglint -c /tmp/pkgcache -r /mnt/repo1 sendmail-config.p5m Lint engine setup... Starting lint run... $As usual, the lack of output indicates success.
- Create the package, make it available in a repo to a test IPS client.
Note: The documentation explains these steps in more detail.
Note: this example stores a repo in /var/tmp/cwirepo. This will work, but I am not suggesting that you place repositories in /var/tmp. You should a repo in a directory that is publicly available.
$ pkgrepo create /var/tmp/cwirepo $ pkgrepo -s /var/tmp/cwirepo set publisher/prefix=cwi $ pkgsend -s /var/tmp/cwirepo publish -d contents sendmail-config.p5m pkg://email@example.com,1.0:20150305T163445Z PUBLISHED $ pkgrepo verify -s /var/tmp/cwirepo Initiating repository verification. $ pkgrepo info -s /var/tmp/cwirepo PUBLISHER PACKAGES STATUS UPDATED cwi 1 online 2015-03-05T16:39:13.906678Z $ pkgrepo list -s /var/tmp/cwirepo PUBLISHER NAME O VERSION cwi site/sendmail-config 8.14.9,1.0:20150305T163913Z $ pkg list -afv -g /var/tmp/cwirepo FMRI IFO pkg://firstname.lastname@example.org,1.0:20150305T163913Z ---
With all of that, you can use the usual IPS packaging commands. I tested this by adding the "cwi" publisher to a running native Solaris Zone and making the repo available as a loopback mount:
# zlogin testzone mkdir /var/tmp/cwirepo # zonecfg -rz testzone zonecfg:testzone> add fs zonecfg:testzone:fs> set dir=/var/tmp/cwirepo zonecfg:testzone:fs> set special=/var/tmp/cwirepo zonecfg:testzone:fs> set type=lofs zonecfg:testzone:fs> end zonecfg:testzone> commit zone 'testzone': Checking: Mounting fs dir=/var/tmp/cwirepo zone 'testzone': Applying the changes zonecfg:testzone> exit # zlogin testzone root@testzone:~# pkg set-publisher -g /var/tmp/cwirepo cwi root@testzone:~# pkg info -r sendmail-config Name: site/sendmail-config Summary: Sendmail configuration Description: ConWid sendmail.mc file for Solaris 11, accepts only local connections. Category: System/Core State: Not installed Publisher: cwi Version: 8.14.9 Build Release: 1.0 Branch: None Packaging Date: March 5, 2015 08:14:22 PM Size: 1.59 kB FMRI: pkg://email@example.com,1.0:20150305T201422Z root@testzone:~# pkg install site/sendmail-config Packages to install: 1 Services to change: 2 Create boot environment: No Create backup boot environment: No DOWNLOAD PKGS FILES XFER (MB) SPEED Completed 1/1 2/2 0.0/0.0 0B/s PHASE ITEMS Installing new actions 12/12 Updating package state database Done Updating package cache 0/0 Updating image state Done Creating fast lookup database Done Updating package cache 2/2 root@testzone:~# pkg verify site/sendmail-config root@testzone:~#
Installation of that package causes several effects. Obviously, the custom sendmail configuration file custom_sm.mc is placed into the directory /etc/mail/sendmail/cf/cf. The sendmail daemon is restarted, automatically expanding that file into a sendmail.cf file and using it. I have noticed that on occasion, it is necessary to refresh and restart the sendmail service.
ConclusionThe result of all of that is an easily maintained configuration file. These concepts can be used with other configuration files, and can be extended to more complex sets of configuration files.
For more information, see these documents:
- SMF Best Practices and Troubleshooting
- Tools for Package Self-Assembly
- Specifying System Changes on Package Actions