New Solaris 11.2 features: SMF stencils

As much as there is often a lot discussion about configuration items inside the SMF repository (like the hostname), it brings an important advantage: It introduces the concept of dependencies to configuration changes. What services have be restarted when i change a configuration item. Do you remember all the services that are dependent on the hostname and need a restart after changing it? SMF solves this by putting the information about dependencies into it configuration. You define it with the manifests. However, as much configuration you may put into SMF, most applications still insists to get it’s configuration inside the traditional configuration files, like the resolv.conf for the resolver or the puppet.conf for Puppet. So you need a way to take the information in the SMF repository and generate a traditional config file with it. In the past the way to do so, was some scripting inside the start method that generated the config file before the service started. Solaris 11.2 offers a new feature in this area. It introduces a generic method to enable you to create config files from SMF properties. It’s called SMF stencils.

Making a service stencil-aware

In the following blog entry i want to give you a first insight how to use this feature with a well known type of config files. Let’s assume you have a service like /network/http:apache22 and you want to create a config file for it with the SMF stencil facility. For example you want to put the virtual host configuration into the SMF repository. At first you have to do some configuration tasks in the SMF to tell Solaris that this service has a stencil. Create a property group with the type configfile. When it has such property group, Solaris SMF knows it has stencils. You don’t have to activate it explicitly. You can have multiple stencils by having multiple property groups with the type configfile.

root@master:~# svccfg -s /network/http:apache22
svc:/network/http:apache22> addpg virtualhosts_stencil configfile
svc:/network/http:apache22> setprop virtualhosts_stencil/path = astring: "/etc/apache2/2.2/conf.d/vhost_smf.conf"
svc:/network/http:apache22> setprop virtualhosts_stencil/stencil = astring: "vhost_smf.conf"
svc:/network/http:apache22> setprop virtualhosts_stencil/mode = astring: "0444"
svc:/network/http:apache22> setprop virtualhosts_stencil/user = astring: "root"
svc:/network/http:apache22> setprop virtualhosts_stencil/group = astring: "sys"

path is the absolute location of the file you want to generate. stencil is the location of the template relative to /lib/svc/stencils/. So when you set stencil to vhost_smf.conf, the stencil file is /lib/svc/stencils/vhost_smf.conf. mode,user and group should speak for themselves. Okay, now create the stencil file. This file acts as the template for the configuration file. Let’s start with a simple example. A file that does nothing in apache contact, but is explicitly stating, that you should keep your fingers from it

root@master:~# cat << EOT > /lib/svc/stencils/vhost_smf.conf
> # Automatically generated ... do not edit
> EOT
root@master:~#

Okay, now refresh the service and dis- and enable it.

root@master:~# svcadm refresh apache22
root@master:~# svcadm disable apache22;svcadm enable apache22

Directly afterwards you will see the content of your stencil in the config file location.

root@master:~# cat /etc/apache2/2.2/conf.d/vhost_smf.conf
# Automatically generated ... do not edit

Inserting property values into the config file

Okay, but now we want to put the value of properties from the SMF repository into our config file for virtualhosts. Okay, For a virtual host config, we “need” the NameVirtualHost directive. At first i create a property group for this kind of common configuration, let’s call it vhost_config. Then i will create a property in it, containing the value for NameVirtualHost

root@master:~# svccfg -s svc:/network/http:apache22 addpg vhost_config application 
root@master:~# svccfg -s svc:/network/http:apache22 setprop vhost_config/namevirtalhost = astring: "\*:80"

Now put the following content into the stencil file.

root@master:~# cat << EOT > /lib/svc/stencils/vhost_smf.conf
# Do not edit
NameVirtualHost $%{vhost_config/namevirtualhost}
# Do not edit
EOT

Refresh, disable,enable again.

root@master:~# svcadm refresh apache22
root@master:~# svcadm disable apache22;svcadm enable apache22

And now you see that you have used the content of the property as a value for your config file.

root@master:~# cat /etc/apache2/2.2/conf.d/vhost_smf.conf
# Do not edit

NameVirtualHost \*:80

# Do not edit

That was simple.

Repeating structures in the config file

When you think about your apache configuration, you will surely remember that you have repeating structures in your configfile for each virtual host. How do i create such structures with stencils. SMF Stencils has a construct for it. Let’s use this stencil file.

root@master:~# cat << EOT > /lib/svc/stencils/vhost_smf.conf
# Do not edit
NameVirtualHost $%{vhost_config/namevirtualhost}

$%/vhosts_([0-9]\*)/ {
<VirtualHost $%{vhost_config/namevirtualhost}>
ServerName $%{vhosts_$%1/servername}
ServerAlias $%{vhosts_$%1/serveralias}
DocumentRoot $%{vhosts_$%1/documentroot}
</VirtualHost>
}
# Do not edit
EOT

The translation is quite easy. Simply said, for each property group starting that matches on vhosts_, repeat the part between the following curly brakes and use the respective properties servername, serveralias and documentroot and insert them in this block. When you configure a property group vhost_1

root@master:~# svccfg -s apache22 addpg vhosts_1 application
root@master:~# svccfg -s apache22 setprop vhosts_1/serveralias = astring: 'c0t0d0s0.org'
root@master:~# svccfg -s apache22 setprop vhosts_1/servername = astring: 'www.c0t0d0s0.org'
root@master:~# svccfg -s apache22 setprop vhosts_1/documentroot = astring: '/var/www/c0t0d0s0.org'
root@master:~# svcadm refresh apache22
root@master:~# svcadm disable apache22; svcadm enable apache22

… it will yield a configuration file with one Virtualhost-block.

root@master:~# svcadm refresh apache22
root@master:~# svcadm disable apache22; svcadm enable apache22
root@master:~# cat /etc/apache2/2.2/conf.d/vhost_smf.conf
# Do not edit
NameVirtualHost \*:80


<VirtualHost \*:80>
ServerName www.c0t0d0s0.org
ServerAlias c0t0d0s0.org
DocumentRoot /var/www/c0t0d0s0.org
</VirtualHost>

# Do not edit
root@master:~#

When you create a second property group …

root@master:~# svccfg -s apache22 addpg vhosts_2 application
root@master:~# svccfg -s apache22 setprop vhosts_2/serveralias = astring: 'moellenkamp.org'
root@master:~# svccfg -s apache22 setprop vhosts_2/servername = astring: 'www.moellenkamp.org'
root@master:~# svccfg -s apache22 setprop vhosts_2/documentroot = astring: '/var/www/moellenkamp.org'
root@master:~# svcadm refresh apache22
root@master:~# svcadm disable apache22; svcadm enable apache22

… a second Virtualhost block will appear.

root@master:~# cat /etc/apache2/2.2/conf.d/vhost_smf.conf
# Do not edit
NameVirtualHost \*:80


<VirtualHost \*:80>
ServerName www.c0t0d0s0.org
ServerAlias c0t0d0s0.org
DocumentRoot /var/www/c0t0d0s0.org
</VirtualHost>

<VirtualHost \*:80>
ServerName www.moellenkamp.org
ServerAlias moellenkamp.org
DocumentRoot /var/www/moellenkamp.org
</VirtualHost>

Conclusion

This is only a very basic example. However it should give you a first insight how you can create configfiles with the SMF stencil facility from the properties in the SMF repository.

Do you want to learn more

On a Solaris 11.2 system you will find more information about stencils with man smf_stencils and man svcio. I will link to the man pages as soon as they are available at docs.oracle.com