1

I am writing configuration program for my own Linux distribution. The configuration is divided into sections: general, networking, session, etc. - which groups similar options. E.g. in section general there are computer name, description, workgroup, language options.

I think every section should be presented by the class, and each option should have corresponding property (getter and maybe setter).

Moreover it would be nice for generalization if there was function to test if given option is enabled (i.e. if system meets requirements for this option) i.e.:

class General(object):

     @property
     def name(self):
         return self.get_computer_name()

     @name.setter
     def name(self, name):
         self.set_computer_name(name)

     def is_option_enabled(self, option):
         return True_or_False

What is more I need these options (and sections too) link together with corresponding translated name and description (using gettext).

I know that hard coding presentation layer in classes is not good idea... I need something like design pattern, general idea/template how to implement this so it was high quality, easy to manage and extend.

I am going to create several front ends for these classes (text, gui, web) so I don't want every time to repeat same code.

I am thinking very hard, but unfortunately I don't have idea how to do this or have some doubts...

Thank you :)

marcinpz
  • 675
  • 7
  • 15
  • Have you considered using [configparser](http://docs.python.org/py3k/library/configparser.html)? – Rik Poggi Jan 25 '12 at 09:01
  • Not really... what for? But I will write program to import and apply / export these options from JSON format. – marcinpz Jan 25 '12 at 09:07
  • To import/export you configuration into a file, it's the first the came to mind, I never used json, but it's supported in the std-lib, so I guess it's the same. – Rik Poggi Jan 25 '12 at 10:09
  • OK. now I understand Your post. But I've chosen JSON because it is easier to use - as normal dict. This is not a problem for me anyway. I don't know how to implement config classes so they were easy to extend and use from front-ends. – marcinpz Jan 25 '12 at 12:05

2 Answers2

1

I'd say that your project looks quite ambitious.

And using a class for every section doesn't seems a good idea to me, because it basically means that adding, removing or modifying sections will require changes to the code, it's not dynamic, and implies the release of a new version incomptable with the previous one.

It would be better if every section will be treated in the same way.

For the core I think you'll need:

  1. A protected file with the declaration of the acceptable sections and options
  2. A configuration holder with access to such file.
  3. A loader for your config files:
    • Read/parse your config files.
    • Build your configuration holder.
  4. Commands with access to your configuration holder:
    • An abstract BaseCommand that implements this access,
    • Subclasses for every actual command: Get, Add, Remove.

Then every front-ends will just be an interface for those commands.

Rik Poggi
  • 28,332
  • 6
  • 65
  • 82
  • Thank You for your explanation. I've to say I thought about creating pluginable system [Yapsy](http://yapsy.sourceforge.net/) is quite good). Adding configuration file (ini or JSON) for plugin manager will give me possibility to enable/disable particular plugin. So to conclude: create command and plugin class for each action and configurable PluginManager which will find these plugins and activate them according to config file. Will it be good? – marcinpz Jan 25 '12 at 13:53
  • @marcinpz: If you're not sure about how to build this thing, maybe you want to make a new more general question and ask directions. Before starting to code you should really have your design complete. Anyway I think I would not make my system configuration pluggable, but only its front-ends, I guess there will also be subsets of conf informations to hand over to other parts of the system or other apps. – Rik Poggi Jan 25 '12 at 23:02
  • Yes You have right. Only gui should be pluggable and some config should exists. I some have idea how all should work but still have problems with implementation of base classes. Anyway thank you :) – marcinpz Jan 26 '12 at 07:22
1

I assume your configurations builds a tree with nodes beings sections and leaf being configuration options.

Given that setup you can represent a 2 depth deep configuration like network with the following classes using a declarative API:

class InterfaceConfiguration(Configuration):
    mask = IPField()
    dns = IPField()
    IP = IPField()
    dhcp = BooleanField()
    driver = ChoiceField(choices=('madwifi', 'atheros', 'whatever'))

class NetworkConfiguration(Configuration):

   eth0 = InterfaceConfiguration(verbose_name='network interface eth0')
   eth1 = InterfaceConfiguration(verbose_name='network interface eth1')
   wlan0 = InterfaceConfiguration(verboxe_name='wireless network interface wlan0')
   hostname = StringField()
   domain = StringField()

This kind of declarative API is achieved with metaclasses have a look at dictshield, and the many ORMs and more that implements such feature.

Given this set of class you would be able to manipulate them as follow:

>>> configuration = NetworkConfiguration('/path/to/config/file')
>>> configuration.eth0.verbose_name
'network interface eth0'
>>> configuration.eth0.mask.set('192.168.0.255')
True
>>> configuration.eth0.driver.choices
('madwifi', 'atheros', 'whatever')
>>> configuration.hostname.set('amokrane')
>>> configuration.domain.set('imazighen')
>>> configuration.wlan0.dhcp.get_value()
True

This kind of API is simpler to implement and doesn't require specific python construction (see below) and provide the ability to have other methods besides get and set.

If you don't need other methods besides get/set you can use python descriptors to implement the different kind of fields, I recommand you read the article Python attributes and methods about the subject and have deeper looks and the above links about Python ORMs since that is the used method.

Community
  • 1
  • 1
amirouche
  • 7,682
  • 6
  • 40
  • 94
  • I like Your idea, but I need to read/write these values from system. For example NetworkConfiguration should be able to read/write interfaces from /etc/network/interfaces file (in Ubuntu). I am not sure if simply write read/write methods in Configuration and reimplement them in every subclass? Second I am not sure if hostname should belong to NetworkConfiguration class too because this is stored in another file... – marcinpz Jan 26 '12 at 16:11
  • 1) I took the exemple of a network configuration where one file controls every aspects of network configuration, to show how it can be implemented. Describe a complex configuration that you need implemented I will update the exemple in consequence – amirouche Jan 26 '12 at 17:55
  • write/read are handled by the base classes via introspection, so you never actually write new code to implement new configurations files. But you might write new code if you want to support new Field types. – amirouche Jan 26 '12 at 17:56
  • NetworkConfiguration is most complex example as for me :). Actually I need FTP account info (host,user, password, file), hostname, workgroup, OCS Inventory server info, some info about computer (CPU, memory, Ip, disks), etc... It will be rather simple tool, because my system is for thin clients and only a few system params can be changed (for example there is no access to terminal and it is not possible to install/remove packages). – marcinpz Jan 27 '12 at 09:05
  • a) could you format this example into the question please ? b) you example seems to be a flat configuration, isn't it ? – amirouche Jan 27 '12 at 10:49
  • Yours tree like configuration is the best choice I think. But I am not sure how base classes should looks like. For example to read/write network configuration I need to use my own parser. For FTP config I need to use ConfigParser. For hostname I have to read/write /etc/hostname file. But logically hostname should belong to Networking group (section). So I need something like connector to let NetworkConfiguration use functions/classes which will change system settings. – marcinpz Jan 27 '12 at 11:56
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7097/discussion-between-marcinpz-and-abki) – marcinpz Jan 27 '12 at 12:19