261 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			261 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| NUT configuration management with Augeas
 | |
| ========================================
 | |
| 
 | |
| Introduction
 | |
| ------------
 | |
| 
 | |
| Configuration has long been one of the two main NUT weaknesses. This is
 | |
| mostly due to the framework nature of NUT, and its many components and
 | |
| features, which make NUT configuration a very complex task.
 | |
| 
 | |
| In order to address this point, NUT now provides configuration tools and
 | |
| manipulation abstraction, to anybody who want to manipulate NUT configuration,
 | |
| through Augeas lenses and modules.
 | |
| 
 | |
| From link:http://augeas.net[Augeas homepage]:
 | |
| 
 | |
| "Augeas is a configuration editing tool. It parses configuration files in their
 | |
| native formats and transforms them into a tree. Configuration changes are made
 | |
| by manipulating this tree and saving it back into native config files."
 | |
| 
 | |
| In other words, Augeas is the dreamed Registry, with all the advantages
 | |
| (such as a uniform interface and tools), and the added bonus of being
 | |
| free/libre open source software and letting liberty on configuration file
 | |
| format.
 | |
| 
 | |
| Requirements
 | |
| ------------
 | |
| 
 | |
| To be able to use Augeas with NUT, you will need to install Augeas,
 | |
| and also the NUT provided lenses, which describe NUT configuration
 | |
| files format.
 | |
| 
 | |
| Augeas
 | |
| ~~~~~~
 | |
| 
 | |
| Having link:http://augeas.net[Augeas] installed.
 | |
| You will need at least version 0.5.1 (prior versions may work too, reports
 | |
| are welcome).
 | |
| 
 | |
| As an example, on Debian and derivatives, do the following:
 | |
| 
 | |
| 	$ apt-get install augeas-lenses augeas-tools
 | |
| 
 | |
| And optionaly:
 | |
| 
 | |
| 	$ apt-get install libaugeas0 libaugeas-dev python-augeas 
 | |
| 
 | |
| On RedHat and derivatives, you have to install the packages 'augeas' and
 | |
| 'augeas-libs'.
 | |
| 
 | |
| [[augeas_user]]
 | |
| 
 | |
| NUT lenses and modules for Augeas
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| These are the *.aug files in the present directory.
 | |
| 
 | |
| You can either install the files to the right location on your system,
 | |
| generally in '/usr/share/augeas/lenses/', or use these from NUT
 | |
| source directory ('nut/scripts/augeas'). The latter is to be prefered for
 | |
| the time being.
 | |
| 
 | |
| 
 | |
| Create a test sandbox
 | |
| ---------------------
 | |
| 
 | |
| NOTE: for now, it's easier to include an existing /etc/nut/ directory.
 | |
| 
 | |
| 	$ export AUGEAS_ROOT=./augeas-sandbox
 | |
| 	$ mkdir $AUGEAS_ROOT
 | |
| 	$ sudo cp -pr /etc/nut $AUGEAS_ROOT
 | |
| 	$ sudo chown -R $(id -nu):$(id -ng) $AUGEAS_ROOT
 | |
| 
 | |
| 
 | |
| Start testing and using
 | |
| -----------------------
 | |
| 
 | |
| Augeas provides many tools and
 | |
| link:http://augeas.net/download.html[languages bindings] (Python, Perl,
 | |
| Java, PHP, Ruby, ...), still with the same simple logic.
 | |
| 
 | |
| This chapter will only illustrate some of these. Refer to the language
 | |
| binding's help and link:http://augeas.net/docs/index.html[Augeas documentation]
 | |
| for more information.
 | |
| 
 | |
| 
 | |
| Shell
 | |
| ~~~~~
 | |
| 
 | |
| Start an augeas shell using:
 | |
| 
 | |
| 	$ augtool -b
 | |
| 
 | |
| NOTE: if you have not installed NUT lenses, add '-I/path/to/nut/scripts/augeas'.
 | |
| 
 | |
| From there, you can perform different actions like:
 | |
| 
 | |
| - list existing nut related files:
 | |
| 
 | |
| 	augtool> ls /files/etc/nut/
 | |
| 	nut.conf/ = (none)
 | |
| 	upsd.users/ = (none)
 | |
| 	upsmon.conf = (none)
 | |
| 	ups.conf/ = (none)
 | |
| 	upsd.conf/ = (none
 | |
| +
 | |
| or using:
 | |
| +
 | |
| 	augtool> match /files/etc/nut/*
 | |
| 	/files/etc/nut/nut.conf = (none)
 | |
| 	/files/etc/nut/upsd.users = (none)
 | |
| 	/files/etc/nut/upsmon.conf = (none)
 | |
| 	/files/etc/nut/ups.conf = (none)
 | |
| 	/files/etc/nut/upsd.conf = (none)
 | |
| 
 | |
| NOTE: if you don't see anything, you may search for error messages by using:
 | |
| +
 | |
| 	augtool> ls /augeas/files/etc/nut/*/errors
 | |
| and
 | |
| 	augtool> get /augeas/files/etc/nut/ups.conf/error/message
 | |
| 	/augeas/files/etc/nut/ups.conf/error/message = Permission denied
 | |
| 
 | |
| - create a new device entry (in ups.conf), called 'augtest':
 | |
| 
 | |
| 	augtool> set /files/etc/nut/ups.conf/augtest/driver dummy-ups
 | |
| 	augtool> set /files/etc/nut/ups.conf/augtest/port auto
 | |
| 	augtool> save
 | |
| 
 | |
| - list the devices using the 'usbhid-ups' driver:
 | |
| 
 | |
| 	augtool> match /files/etc/nut/ups.conf/*/driver dummy-ups
 | |
| 
 | |
| 
 | |
| C
 | |
| ~
 | |
| 
 | |
| A library is available for C programs, along with pkg-config support.
 | |
| 
 | |
| You can get the compilation and link flags using the following code
 | |
| in your configure script or Makefile:
 | |
| 
 | |
| 	CFLAGS="`pkg-config --silence-errors --cflags augeas`"
 | |
| 	LDFLAGS="`pkg-config --silence-errors --libs augeas`"
 | |
| 
 | |
| Here is an code sample using this library for NUT configuration:
 | |
| 
 | |
| --------------------------------------------------------------------------------
 | |
| augeas *a = aug_init(NULL, NULL, AUG_NONE);
 | |
| ret = aug_match(a, "/files/etc/nut/*", &matches_p);
 | |
| ret = aug_set(a, "/files/etc/nut/ups.conf/augtest/driver", "dummy-ups");
 | |
| ret = aug_set(a, "/files/etc/nut/ups.conf/augtest/port", "auto");
 | |
| ret = aug_save(a);
 | |
| --------------------------------------------------------------------------------
 | |
| 
 | |
| Python
 | |
| ~~~~~~
 | |
| 
 | |
| The `augeas` class abstracts access to the configuration files. 
 | |
| 
 | |
|   $ python
 | |
|   Python 2.5.1 (r251:54863, Apr  8 2008, 01:19:33)
 | |
|   [GCC 4.3.0 20080404 (Red Hat 4.3.0-6)] on linux2
 | |
|   Type "help", "copyright", "credits" or "license" for more information.
 | |
|   >>> import augeas
 | |
|   >>> a = augeas.augeas()
 | |
|   >>> a.match("/files/etc/nut/*")
 | |
|   ['/files/etc/nut/upsd.users', '/files/etc/nut/upsmon.conf', '/files/etc/nut/ups.conf', '/files/etc/nut/upsd.conf']
 | |
|   >>> a.set("/files/etc/nut/ups.conf/augtest/driver", "dummy-ups")
 | |
|   True
 | |
|   >>> a.set("/files/etc/nut/ups.conf/augtest/port", "auto")
 | |
|   True
 | |
|   >>> a.save()
 | |
|   True
 | |
|   >>>
 | |
| 
 | |
|   $ grep -A 2 augtest /etc/nut/ups.conf
 | |
|   [augtest]
 | |
|   driver=dummy-ups
 | |
|   port=auto
 | |
| 
 | |
| 
 | |
| Perl
 | |
| ~~~~
 | |
| 
 | |
| The Perl binding is available through CPAN and packages.
 | |
| 
 | |
|   use Config::Augeas;
 | |
| 
 | |
|   my $aug = Config::Augeas->new( root => $aug_root ) ;
 | |
| 
 | |
|   my @a = $aug->match("/files/etc/nut/*") ;
 | |
|   my $nb = $aug->count_match("/files/etc/nut/*") ;
 | |
| 
 | |
|   $aug->set("/files/etc/nut/ups.conf/augtest/driver", "dummy-ups") ;
 | |
|   $aug->set("/files/etc/nut/ups.conf/augtest/port", "auto") ;
 | |
| 
 | |
|   $aug->save ;
 | |
| 
 | |
| 
 | |
| Test the conformity testing module
 | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| 
 | |
| Existing configuration files can be tested for conformity. To do so, use:
 | |
|  
 | |
| 	$ augparse -I ./ ./test_nut.aug
 | |
| 
 | |
| 
 | |
| Complete configuration wizard example
 | |
| -------------------------------------
 | |
| 
 | |
| Here is a Python example that generate a complete and usable standalone configuration:
 | |
| 
 | |
| --------------------------------------------------------------------------------
 | |
| import augeas
 | |
| 
 | |
| device_name="dev1"
 | |
| driver_name="usbhid-ups"
 | |
| port_name="auto"
 | |
| 
 | |
| a = augeas.augeas()
 | |
|   
 | |
| # Generate nut.conf
 | |
| a.set("/files/etc/nut/nut.conf/MODE", "standalone")
 | |
| 
 | |
| # Generate ups.conf
 | |
| # FIXME: chroot, driverpath?
 | |
| a.set(("/files/etc/nut/ups.conf/%s/driver" % device_name), driver_name)
 | |
| a.set(("/files/etc/nut/ups.conf/%s/port" % device_name), port_name)
 | |
| 
 | |
| # Generate upsd.conf
 | |
| a.set("/files/etc/nut/upsd.conf/#comment[1]", "just to touch the file!")
 | |
| 
 | |
| # Generate upsd.users
 | |
| user = "admin"
 | |
| a.set(("/files/etc/nut/upsd.users/%s/password" % user), "dummypass")
 | |
| a.set(("/files/etc/nut/upsd.users/%s/actions/SET" % user), "")
 | |
| # FIXME: instcmds lens should be fixed, as per the above rule
 | |
| a.set(("/files/etc/nut/upsd.users/%s/instcmds" % user), "ALL")
 | |
| 
 | |
| monuser = "monuser"
 | |
| monpasswd = "******"
 | |
| a.set(("/files/etc/nut/upsd.users/%s/password" % monuser), monpasswd)
 | |
| a.set(("/files/etc/nut/upsd.users/%s/upsmon" % monuser), "master")
 | |
| 
 | |
| # Generate upsmon.conf
 | |
| a.set("/files/etc/nut/upsmon.conf/MONITOR/system/upsname", device_name)
 | |
| # Note: we prefer to omit localhost, not to be bound to a specific
 | |
| # entry in /etc/hosts, and thus be more generic
 | |
| #a.set("/files/etc/nut/upsmon.conf/MONITOR/system/hostname", "localhost")
 | |
| a.set("/files/etc/nut/upsmon.conf/MONITOR/powervalue", "1")
 | |
| a.set("/files/etc/nut/upsmon.conf/MONITOR/username", monuser)
 | |
| a.set("/files/etc/nut/upsmon.conf/MONITOR/password", monpasswd)
 | |
| a.set("/files/etc/nut/upsmon.conf/MONITOR/type", "master")
 | |
| 
 | |
| # FIXME: glitch on the generated content
 | |
| a.set("/files/etc/nut/upsmon.conf/SHUTDOWNCMD", "/sbin/shutdown -h +0")
 | |
| 
 | |
| # save config
 | |
| a.save()
 | |
| a.close()
 | |
| --------------------------------------------------------------------------------
 |