Template Extensions

 The first step towards making it easier to configure (and making it easy to make it easier to configure) OpenSolaris is to provide a means of describing the lowest-level of configuration data.

 In an smf(5) service manifest, we have already carved out a region for holding service metadata called the "template". It currently only holds things like man/web page references and a localizable service name. We've long hoped to grow this section to encompass more information.

 One of the neat things we were able to do with the Visual Panels demo was provide automatically-generated panels for services that put configuration in SMF. One of the first things you'd notice when using it, though, is that you had to decipher whatever arcane names the service author chose for the service's properties. In most cases these names are documented in a man page, and we happened to also provide ready access to the man page, but flipping between documentation and configuration is tedious. We can and should give better context in this situation.

 What follows is description of some changes to the template section we've been mulling over. They let us do things like specify human-readable names and descriptions for properties and values, let us indicate when a property isn't something a user should see or modify, let us put some basic constraints on the values a property can take on, and do so in a way that can be wildcarded across classes of property groups, services, or instances.

 For those of you who prefer code over prose, an updated DTD and console-login manifest are also available.

 Please let us know what you think.


Property groups

 The pg_pattern element contains the definitions for a property group:


  <template>
  <pg_pattern name="pgname" type="pgtype" target="this" required="true">
  </pg_pattern>
  </template>

name is the property group's name, and type is the property group's type.

target specifies what the target of this definition is. this would refer to the defining service or instance. instance can only be used in a service's template block, and means the definition applies to all instances of this service. delegate can only be used in a restarter's template block, and applies to all instances that are delegated to that restarter. all, only usable by the master restarter, would refer to all services on the system. The default value of target is this.

 "required" indicates whether this property group is required or not. The default value of required is false. If required is true, both name and type must be specified.

 If name or type is omitted, it acts like a wildcard. It might make more sense to (instead?) allow the explicit use of wildcards.

Properties

 The prop_pattern element contains the definitions for a specific property:


  <pg_pattern ...>
  <prop_pattern name="propname" type="proptype" required="true">
  </prop_pattern>
  </pg_pattern>

name is the property's name, and type is the property's type.

required indicates whether this property is required. The default value of required is false.

name is always required. type is optional only if required is false.

Property names

 The common_name element contains the localized, human-readable name for the property:


  <prop_pattern ...>
  <common_name>
    <loctext xml:lang='C'>Platen width</loctext>
  </common_name>
  </prop_pattern>

 This name should short -- probably no longer than a word or two -- as its intended use would be as a label in a GUI or CLI.

Property units

 The units element contains the localized, human-readable units for a numerical property:


  <prop_pattern ...>
  <units>
    <loctext xml:lang='C'>furlongs</loctext>
  </units>
  </prop_pattern>

Property description

 The description element contains a longer description of the property, suitable for a status line or a tool-tip:


  <prop_pattern ...>
  <description>
    <loctext xml:lang='C'>Not the height.</loctext>
  </description>
  </prop_pattern>

 Should be a single line of text (though what the allowable length should be is an interesting problem).

Property visibility

 The visibility element specifies what access we provide to the property:


  <prop_pattern ...>
  <visibility value="hidden | readonly | readwrite"/>
  </prop_pattern>

 Some properties are internal implementation details and should be presented to the user in a configuration setting. Others may merely be read-only. This property lets us declare which. A value of hidden indicates that the property shouldn't be displayed, readonly means that the property isn't intended to be modified, and readwrite indicates the property is modifiable.

 It is important to note that this *is not* a security mechanism, it is solely intended to help prevent the user from shooting himself in the foot, and to remove unnecessary clutter from CLI output or a GUI display.

Property format

 The cardinality and internal_separators elements constrain the structure of a property:


  <prop_pattern ...>
  <cardinality value="?"/>
  <internal_separators>,</internal_separators>
  </prop_pattern>

cardinality indicates the acceptable number of values (possible values would be non-negative integers, +, ?, and *).

internal_separators tells us the separators characters used for those property values into which we unfortunately pack multiple real values instead of using multi-value properties, e.g. ignore_on (unnecessarily, sigh), and console-login's ttymon/modules (necessarily, for ordering).

Value constraints

 The constraints element specifies what values are acceptable for a property:


  <prop_pattern ...>
  <constraints>
	<value name="blue" />
	<range min="1" max="7"/>
	<valueset set="terminals"/>
  </constraints>
  </prop_pattern>

 The value element includes a possible property value. range includes an integer range. valueset includes a system-provided set of values we might not want hard-coded into a manifest (possibly because it's dynamic or large and frequently used) but want service developers to have access to -- e.g. terminals types, error types, projects, restarters, etc.

value, range, and valueset may be used in any combination, as restricting their use would prohibit many valid descriptions. If no value constraints are specified, the property can take on any value.

Value choices

 There is a difference between constraints and choices. For example, we might not want to list all terminal types in the UI, only the most commonly used ones (though we'd want to retain the ability to accept all terminal types, of course). The choices block indicates which values a UI should offer the user:


  <prop_pattern ...>
  <choices>
	<range min="1" max="3"/>
	<value name="vt100" />
	<value name="xterm" />
	<valueset set="restarters" />
	<allvalues type="constraints"/>
	<allvalues type="values"/>
  </choices>
  </prop_pattern>

range, value, and valueset include ranges, individual values, and value sets like they do for constraints.

allvalues includes all values specified by either the constraints block or the values block (see next section).

Value descriptions

 Like property names, the values a property can take on can also have inscrutible representations. The values element contains localized, human-readable descriptions for specific property values:


  <prop_pattern ...>
  <values>
	<value name="blue">
		<common_name>
			<loctext xml:lang='C'>Blue</loctext>
		</common_name>
		<description>
			<loctext xml:lang='C'>
				The color between green and indigo.
			</loctext>
		</description>
	</value>
  </values>
  </prop_pattern>

 Tying these descriptions to the constraint definitions doesn't make sense, as we may want descriptions for a known subset of an otherwise unbounded property value set. Tying them to the choice definitions also doesn't make sense because the set of things we offer in a UI should be a separate decision from the the set of things we need to, or are willing to, provide extended descriptions for.

Questions and thoughts

 These definitions borrow the common_name and description elements which were originally defined for use in the top-level template element. These definitions are close to what we are using them for, but not spot on. Should we create new elements specifically for use within the pattern elements?

 Element names have to be globally unique, so some of the common-sense names we'd use in a template description are unavailable, and some of the ones we propose using might need future use elsewhere in a manifest. Though SMF is theoretically one "XML application", should we use a separate namespace for the template elements?

 How exactly should we map these definitions to property group/property names?

 We need to more stringently define how the free-form fields, such as common_name, are to be formatted and used. Guidelines should cover length, content, and capitalization.

 What value sets would be useful?

 The choices mechanism gets into the realm of providing hints that a consumer may or may not choose to follow, and the realm of making guesses as to how consumers are using services. While it is provided based on the premise that multiple consumers could make use of the hint, and that the party most familiar with how the service is going to be configured is the service author, you could also argue that the UI author is in the best position to decide what the user is prepared to see.

Example

 We might want to include the following in inetd:default's template section:


  <pg_pattern name="inetd" type="framework" target="delegate" required="true">
	<prop_pattern name="endpoint_type" type="astring" required="true">
		<common_name>
			<loctext xml:lang='C'>Endpoint type</loctext>
		</common_name>
		<description>
			<loctext xml:lang='C'>The type of endpoint
			    (can be TLI or one of several socket types).
			</loctext>
		</description>
		<visibility value="readwrite" />
		<cardinality value="1" />
		<values>
			<value name="tli">
				<common_name>
					<loctext xml:lang='C'>TLI</loctext>
				</common_name>
				<description>
					<loctext xml:lang='C'>
						TLI endpoint
					</loctext>
				</description>
			</value>
			<value name="stream">
				<common_name>
					<loctext xml:lang='C'>Stream</loctext>
				</common_name>
				<description>
					<loctext xml:lang='C'>
						Stream socket
					</loctext>
				</description>
			</value>
			<value name="dgram">
				<common_name>
					<loctext xml:lang='C'>Datagram</loctext>
				</common_name>
				<description>
					<loctext xml:lang='C'>
						Datagram socket
					</loctext>
				</description>
			</value>
			<value name="raw">
				<common_name>
					<loctext xml:lang='C'>Raw</loctext>
				</common_name>
				<description>
					<loctext xml:lang='C'>
						Raw socket
					</loctext>
				</description>
			</value>
			<value name="seqpacket">
				<common_name>
					<loctext xml:lang='C'>Sequenced
					</loctext>
				</common_name>
				<description>
					<loctext xml:lang='C'>
						Sequenced packet socket
					</loctext>
				</description>
			</value>
		</values>
		<constraints>
			<value name="tli" />
			<value name="stream" />
			<value name="dgram" />
			<value name="raw" />
			<value name="seqpacket" />
		</constraints>
		<choices>
			<value name="stream" />
			<value name="dgram" />
		</choices>
	</prop_pattern>
  </pg_pattern>

 This obviously isn't complete; it only defines a single property.

 The effect of this definition is to:

  • require tools creating delegates of inetd:default to include an inetd property group of type framework.
  • require that property group to include a endpoint_type property of type astring.
  • restrict the property to having 1 value.
  • restrict the property's values to tli, stream, dgram, raw, and seqpacket.
  • provide human-readable names, so we can improve our CLIs and write GUI's that will say
Endpoint type: Datagram

 instead of

inetd/endpoint_type: dgram
  • suggest to a UI that might offer a pull-down or other selection mechanism that stream and dgram are the most common choices. (This is admittedly a bit contrived; in this case you'd probably want to include them all. It also assumes that you want to let someone modify the property, which you probably wouldn't.)

Possible applications

 In addition to providing a means to describe the occasional one-off property group, here are some of the larger immediate applications we envision:

  • Method definitions for startd and inetd (or any other restarter)
  • The inetd property group
  • NFS "share group" instances
  • Shares within a share group
  • Defining a "valid restarters" property

Inconsistency in localizations

 One problem that we need to keep in mind is that of synchronization between the author-delivered manifest and l10n-delivered localized manifests. The C localization should be viewed as authoritative as far as the existence of values and properties is concerned. That is, if a localized manifest provides translations for a value which isn't declared in the base manifest, we should treat the value it as if it doesn't exist and ignore the localization.

Higher-level directions

 Though the above definitions may span multiple instances or services, the annotations only benefit the user once they are looking at a property of some specific service or instance. There is a lot that we could do to help the user understand the relationships between different properties and between different services, find the services they are looking for, or control services in a higher-level fashion that doesn't require knowlege of the internals of the system.

 The ideas which follow are intended as food for thought, not a formal part of the proposal.

Service metadata

 One area we could expand into is providing data which attempts to describe classes of behaviors. For example, we know which port any service which is started by svc:/network/inetd:default listens on. But what about things like Apache and sshd which are stand-alone services? We could provide a means of expressing their use of network ports:


    <metadata>
	  <listens_on port="80"/>
    </metadata>

 or


    <metadata>
	  <listens_on propval="apache/port"/>
    </metadata>

 Another potential piece of metadata would be a pointer to property telling the service to run in local-only mode:


    <metadata>
	  <local_only_switch property="config/local_only" />
    </metadata>

 Together these could be used to provide an integrated view of what services are running/could run on your system, and an automated way to restrict network access.

 In general, such metadata should be provided in an extensible hierarchy so we could add more as needed.

Grouping

 In addition to selecting which properties are hidden or writable, a service which provides a large number of properties in several property groups may want to suggest how they could be grouped together visually. This could be expressed as:


    <grouping id="serverside">
	<description>
		<loctext xml:lang='C'>
			Server-side configuration
		</loctext>
	</description>
	<property name="daemon/port" />
	<property name="daemon/usesll" />
	<property name="crypto/certloc" />
    </grouping>

last modified by admin on 2009/10/26 13:17
Collectives
Project


© Sun Microsystems Inc. 2009
XWiki Enterprise 1.8.2.19075 - Documentation
Terms Of Use | Privacy | Trademarks | Copyright Policy | Site Guidelines | Site map | Help
Your use of this web site or any of its content or software indicates your agreement to be bound by these Terms of Use.