Tags:
create new tag
view all tags

LCFG Language

Paul Anderson's Call for Ideas (December 2015)

The LCFG meeting was interesting yesterday - I would have liked to be there longer. I'm working on some new language things and I was interested in ...

Kenny said it would be useful to be able to use variable names in included pathnames (at least that's what I think you said). Do you have any examples of where you would use this? What would be the source of the variable value? (does that make sense?)

I'd be interested in examples of any particularly "creative" macros that anyone has.

Actually, I'd be interested in any comments that anyone has on the LCFG language (rather than the components/deployment stuff). Things that are good/bad/missing, examples of interesting (ab)use, etc. etc.

Kenny MacDonald Ideas

Computed Include Directives

I would like to be able to write code that includes functionality based on properties of the profile. In particular, I've found it frustrating that I have to explicitly add a new include line for each OS in a component defaults header, e.g.

 #ifdef MACOSX
 #if OS_VERSION == 9
 #include <defaults/component-osx9.h>
 #elif OS_VERSION == 10
 #include <defaults/component-osx10.h>
 #elif OS_VERSION == 11
 #include <defaults/component-osx11.h>
 #endif

It would be great to be able to generalise this to

 #ifdef MACOSX
 #include <defaults/component-osx${OS_VERSION}.h>
 #endif

In fact, if we could do that we'd probably just use the full OS name and version in the header file name too.

 #include <defaults/component-${OS_ID}.h>

The source of these variables should be any variable that's already set. The LCFG language is interpreted like any other language, so we'd simply have to ensure it was set appropriately beforehand. We do this using cpp macros now. It would be nice to be able to reference LCFG resources at this time, though.

Unify Variable Spaces

The fact we have cpp macro expansion and LCFG resource referencing in the same language is confusing for users. A future language should only have one variable space, namely the LCFG resources themselves.

Here Documents

It is quite common to wish to set a resource to some verbatim text, but the current language and use of cpp makes this awkward. Stephen has recently added support for the Unicode NL (or is it LF) character to specify newlines in a cpp safe way.

Here document support would greatly ease copy'n'paste from files into profiles. Imagine this ...

 file.tmpl_example '''This is an example file.
 It has multiple newlines in it.
 
 Even blank lines like above.
 '''

No messy continuation characters.

Existing Languages

We quickly wish to use an existing language to output a simple list of LCFG language lines with all resources already calculated. Only leaving in spanning map entries for the compiler to handle.

Shane Voss Ideas

Tagged Objects

What I really want to be able to do is create resources without inventing names for them. The names are mostly used to add to other lists.

In pseudo-python perhaps:

 myfile = file("/at/this/path", mode=0755, owner=root)
 myfile.tmpl = """..."""

 files.append(myfile)

Perhaps I could specify a tag name, but if I don't the compiler can call it file0001 or something, and avoid clashes with any explicitly tagged ones.

If I'd given it an explicit tag, I could perhaps later refer to it as:

files.get(tagname) or files[tagname]

Most of my macros are bashing together tag elements to automatically create things and put them in the right lists.

It would be great to be able to create tagged objects in one call and optionally have the compiler generate a unique tag on your behalf.

NEW(file.dir,
  tmpl => /tmp/mydir,
  mode => 0755,
  owner => root,
  group => root
)

Conditionals

My most "creative" macros are getting round the lack of conditionals and are based around mIF():

#define mIF(C,M) \
  do{ my $z = length $_ ? $_ : ""; do{ C } ? do{ $_ = $z; M } : $z}

It applies the mutation M if and only if the condition C is true. (Except it always replaces undef with "" )

The lack of any block if means that I often create things that can go in a tag list and then conditionally add them.

The hairiest set of macros I have build on the conditional to find which subnet a machine is on and set parameters appropriately. To do that I need to do arithmetic on IP addresses:

 
#define mIPTOINT(H) \
 do{my($a,$b,$c,$d)=split/\./,mIPADDR(H);($a<<24)+($b<<16)+($c<<8)+$d}
 #define mINTTOIP(I) \
   $_=I;$_=($_>>24).'.'.($_>>16&255).'.'.($_>>8&255).'.'.($_&255)
 
 #define NETWORK_MIF(nam,var,val) \
 !file.variables mIF(« nam » eq « <%%file.v_network_netname%%> »,mADD(network_/**/var)) ¢ \
 !file.v_network_/**/var mIF(« nam » eq « <%%file.v_network_netname%%> »,mADD(network_/**/var)) ¢ \
 !file.v_network_/**/var mIF(« nam » eq « <%%file.v_network_netname%%> »,  val) ¢ \
 !file.v_net_/**/nam/**/_/**/var val

 NETWORK_MIF(nam,broadcast,mINTTOIP (mIPTOINT(num) | (0xffffffff ^ mIPTOINT(msk)) ))

I would love to be able to treat component resources as objects and program th em in conditional blocks.

Shane Voss Example 1

defaultfile = { mode:"0755", owner:"root" }

// two blocks which inherit (and possibly override) stuff from the 
// default file spec

myfile1 = $defaultfile +> { path:"/at/this/path1" }

myfile2 = $defaultfile +> { path:"/at/this/path2", owner:"shane" }

// files is a list with one element (which is tagged)

files = [ mytag:$myfile1 ]

// $myfile2 has no tag specified. the compiler will invent a unique one

// the "mytag" here (with no value) is simply used to establish the order
// (order no longer depends on the order in which things appear in the source!)
// the value of the tag is inherited from the $files

myfiles: $files +> [ mytag:, $myfile2 ]

Output:

myfiles: [
  mytag: {
    path: "/at/this/path1"
    owner: "root"
    mode: "0755"
  }
  __01: {
    path: "/at/this/path2" 
    owner: "shane"
    mode: "0755"
  }
]

Shane Voss Example 2

defaultfile = { mode:"0755", owner:"root" }

name = "shane"

myfile: if ($name == "shane")
   then $defaultfile +> { owner:"shane" }
   else $defaultfile

Output:

myfile: {
  owner: "shane"
  mode: "0755"
}

-- kenny - 2017-11-23

Comments

%COMMENT%

Topic revision: r1 - 2017-11-23 - kenny
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback