Skip to content

Commit 7815e78

Browse files
author
markburgess
committed
Merge pull request #2 from markburgess/master
Cleanups, new edit_template feature, documentation
2 parents 301f16a + 41e42f7 commit 7815e78

File tree

11 files changed

+722
-243
lines changed

11 files changed

+722
-243
lines changed

docs/guides/SpecialTopic_Editing.texinfo

Lines changed: 475 additions & 241 deletions
Large diffs are not rendered by default.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
3+
@verbatim
4+
#This is a template file /templates/input.tmpl
5+
6+
These lines apply to anyone
7+
8+
[%CFEngine solaris.Monday:: %]
9+
Everything after here applies only to solaris on Mondays
10+
until overridden...
11+
12+
[%CFEngine linux:: %]
13+
Everything after here now applies now to linux only.
14+
15+
[%CFEngine BEGIN %]
16+
This is a block of text
17+
That contains list variables: $(some.list)
18+
With text before and after.
19+
[%CFEngine END %]
20+
21+
nameserver $(some.list)
22+
@end verbatim
23+
24+
For example:
25+
26+
@verbatim
27+
[%CFEngine any:: %]
28+
<VirtualHost $(sys.ipv4[eth0]):80>
29+
ServerAdmin $(stage_file.params[apache_mail_address][1])
30+
DocumentRoot /var/www/htdocs
31+
ServerName $(stage_file.params[apache_server_name][1])
32+
AddHandler cgi-script cgi
33+
ErrorLog /var/log/httpd/error.log
34+
AddType application/x-x509-ca-cert .crt
35+
AddType application/x-pkcs7-crl .crl
36+
SSLEngine off
37+
CustomLog /var/log/httpd/access.log
38+
</VirtualHost>
39+
40+
[%CFEngine webservers_prod:: %]
41+
[%CFEngine BEGIN %]
42+
<VirtualHost $(sys.ipv4[$(bundle.interfaces)]):443>
43+
ServerAdmin $(stage_file.params[apache_mail_address][1])
44+
DocumentRoot /var/www/htdocs
45+
ServerName $(stage_file.params[apache_server_name][1])
46+
AddHandler cgi-script cgi
47+
ErrorLog /var/log/httpd/error.log
48+
AddType application/x-x509-ca-cert .crt
49+
AddType application/x-pkcs7-crl .crl
50+
SSLEngine on
51+
SSLCertificateFile $(stage_file.params[apache_ssl_crt][1])
52+
SSLCertificateKeyFile $(stage_file.params[apache_ssl_key][1])
53+
CustomLog /var/log/httpd/access.log
54+
</VirtualHost>
55+
[%CFEngine END %]
56+
@end verbatim
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
@i{History}: Was introduced in 3.3.0, Nova 2.2.0, Constellation 1.0.0 (2012)
3+
4+
The template format uses inline tags to mark regions and classes.
5+
Each line represents an @code{insert_lines} promise, unless the promises
6+
are grouped into a block using:
7+
8+
@verbatim
9+
[%CFEngine BEGIN %]
10+
...
11+
[%CFEngine END %]
12+
@end verbatim
13+
14+
@noindent Variables, scalars and list variables are expanded within each
15+
promise; so, if lines are grouped into a block, the whole block is repeated
16+
when lists are expanded (see the Special Topics Guide on editing).
17+
18+
If a class-context modified is used:
19+
20+
@verbatim
21+
[%CFEngine class-expression:: %]
22+
@end verbatim
23+
@noindent then the lines that follow are only inserted if the context
24+
matches the agent's current context. This allows conditional insertion.
25+
26+

src/attributes.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ void SetChecksumUpdates(bool enabled)
4545
CHECKSUMUPDATES = enabled;
4646
}
4747

48+
/*******************************************************************/
49+
4850
Attributes GetFilesAttributes(Promise *pp)
4951
{
5052
Attributes attr = { {0} };
@@ -61,9 +63,11 @@ Attributes GetFilesAttributes(Promise *pp)
6163
attr.havechange = GetBooleanConstraint("changes", pp);
6264
attr.havecopy = GetBooleanConstraint("copy_from", pp);
6365
attr.havelink = GetBooleanConstraint("link_from", pp);
66+
67+
attr.template = (char *)GetConstraintValue("edit_template", pp, CF_SCALAR);
6468
attr.haveeditline = GetBundleConstraint("edit_line", pp);
6569
attr.haveeditxml = GetBundleConstraint("edit_xml", pp);
66-
attr.haveedit = attr.haveeditline || attr.haveeditxml;
70+
attr.haveedit = attr.haveeditline || attr.haveeditxml || attr.template;
6771

6872
/* Files, specialist */
6973

src/cf3.defs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,7 @@ typedef struct
17541754
char *transformer;
17551755
char *pathtype;
17561756
char *repository;
1757+
char *template;
17571758
int touch;
17581759
int create;
17591760
int move_obstructions;

src/env_monitor.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ void MonitorInitialize(void)
110110
LOCALAV.Q[i].expect = 0.0;
111111
LOCALAV.Q[i].var = 0.0;
112112
LOCALAV.Q[i].q = 0.0;
113+
LOCALAV.Q[i].dq = 0.0;
113114
}
114115

115116
for (i = 0; i < 7; i++)
@@ -369,6 +370,9 @@ static Averages EvalAvQ(char *t)
369370
newvals.Q[i].expect = WAverage(This[i], currentvals->Q[i].expect, WAGE);
370371
LOCALAV.Q[i].expect = WAverage(newvals.Q[i].expect, LOCALAV.Q[i].expect, ITER);
371372

373+
newvals.Q[i].dq = newvals.Q[i].q - currentvals->Q[i].q;
374+
LOCALAV.Q[i].dq = newvals.Q[i].q - currentvals->Q[i].q;
375+
372376
delta2 = (This[i] - currentvals->Q[i].expect) * (This[i] - currentvals->Q[i].expect);
373377

374378
if (currentvals->Q[i].var > delta2 * 2.0)

src/files_editline.c

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,132 @@ int ScheduleEditLineOperations(char *filename, Bundle *bp, Attributes a, Promise
163163
return true;
164164
}
165165

166+
/*****************************************************************************/
167+
168+
Bundle *MakeTemporaryBundleFromTemplate(Attributes a, Promise *pp)
169+
{
170+
char bundlename[CF_MAXVARSIZE], buffer[CF_BUFSIZE];
171+
char *sp, *promiser, context[CF_BUFSIZE] = "any";
172+
Bundle *bp;
173+
Promise *np;
174+
SubType *tp;
175+
FILE *fp;
176+
int level = 0, size, lineno = 0;
177+
Item *ip, *lines = NULL;
178+
179+
snprintf(bundlename, CF_MAXVARSIZE, "temp_cf_bundle_%s", CanonifyName(a.template));
180+
181+
bp = xcalloc(1, sizeof(Bundle));
182+
bp->name = xstrdup(bundlename);
183+
bp->type = xstrdup("edit_line");
184+
bp->args = NULL;
185+
bp->next = NULL;
186+
187+
tp = AppendSubType(bp, "insert_lines");
188+
189+
// Now parse the template file
190+
191+
if ((fp = fopen(a.template,"r")) == NULL)
192+
{
193+
cfPS(cf_error, CF_INTERPT, "", pp, a, " !! Unable to open template file \"%s\" to make \"%s\"", a.template, pp->promiser);
194+
return NULL;
195+
}
196+
197+
while(!feof(fp))
198+
{
199+
buffer[0] = '\0';
200+
fgets(buffer, CF_BUFSIZE-1, fp);
201+
lineno++;
202+
203+
// Check closing syntax
204+
205+
// Get Action operator
206+
if (strncmp(buffer, "[%CFEngine", strlen("[%CFEngine")) == 0)
207+
{
208+
char operator[CF_BUFSIZE], brack[CF_SMALLBUF];
209+
210+
sscanf(buffer+strlen("[%CFEngine"), "%1024s %s", operator, brack);
211+
212+
if (strcmp(brack, "%]") != 0)
213+
{
214+
cfPS(cf_error, CF_INTERPT, "", pp, a, " !! Template file \"%s\" syntax error, missing close \"%%]\" at line %d", a.template, lineno);
215+
return NULL;
216+
}
217+
218+
if (strcmp(operator, "BEGIN") == 0)
219+
{
220+
// start new buffer
221+
222+
if (++level > 1)
223+
{
224+
cfPS(cf_error, CF_INTERPT, "", pp, a, " !! Template file \"%s\" contains nested blocks which are not allowed, near line %d", a.template, lineno);
225+
return NULL;
226+
}
227+
228+
continue;
229+
}
230+
231+
if (strcmp(operator, "END") == 0)
232+
{
233+
// install buffer
234+
level--;
235+
}
236+
237+
if (strcmp(operator+strlen(operator)-2, "::") == 0)
238+
{
239+
*(operator+strlen(operator)-2) = '\0';
240+
strcpy(context, operator);
241+
continue;
242+
}
243+
244+
// In all these cases, we should start a new promise
245+
246+
promiser = NULL;
247+
size = 0;
248+
249+
for (ip = lines; ip != NULL; ip = ip->next)
250+
{
251+
size += strlen(ip->name);
252+
}
253+
254+
sp = promiser = xcalloc(1, size+1);
255+
256+
for (ip = lines; ip != NULL; ip = ip->next)
257+
{
258+
int len = strlen(ip->name);
259+
strncpy(sp, ip->name, len);
260+
sp += len;
261+
}
262+
263+
*(sp-1) = '\0'; // StripTrailingNewline(promiser) and terminate
264+
265+
np = AppendPromise(tp, promiser, (Rval) { NULL, CF_NOPROMISEE }, context, bundlename, "edit_line");
266+
AppendConstraint(&(np->conlist), "insert_type", (Rval) { xstrdup("preserve_block"), CF_SCALAR }, "any", false);
267+
268+
DeleteItemList(lines);
269+
free(promiser);
270+
lines = NULL;
271+
}
272+
else
273+
{
274+
if (level > 0)
275+
{
276+
AppendItem(&lines, buffer, NULL);
277+
}
278+
else
279+
{
280+
//install independent promise line
281+
StripTrailingNewline(buffer);
282+
np = AppendPromise(tp, buffer, (Rval) { NULL, CF_NOPROMISEE }, context, bundlename, "edit_line");
283+
AppendConstraint(&(np->conlist), "insert_type", (Rval) { xstrdup("preserve_block"), CF_SCALAR }, "any", false);
284+
}
285+
}
286+
}
287+
288+
fclose(fp);
289+
return bp;
290+
}
291+
166292
/***************************************************************************/
167293
/* Level */
168294
/***************************************************************************/

src/files_operators.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,24 @@ int ScheduleEditOperation(char *filename, Attributes a, Promise *pp)
504504
}
505505
}
506506

507+
if (a.template)
508+
{
509+
if ((bp = MakeTemporaryBundleFromTemplate(a,pp)))
510+
{
511+
BannerSubBundle(bp,params);
512+
513+
DeleteScope(bp->name);
514+
NewScope(bp->name);
515+
HashVariables(bp->name);
516+
517+
PushPrivateClassContext();
518+
retval = ScheduleEditLineOperations(filename,bp,a,pp);
519+
PopPrivateClassContext();
520+
DeleteScope(bp->name);
521+
}
522+
// FIXME: why it crashes? DeleteBundles(bp);
523+
}
524+
507525
FinishEditContext(pp->edcontext, a, pp);
508526
YieldCurrentLock(thislock);
509527
return retval;

src/instrumentation.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ static void NotePerformance(char *eventname, time_t t, double value)
117117
lastseen = now - e.t;
118118
newe.t = t;
119119
newe.Q.q = value;
120+
newe.Q.dq = value - e.Q.q;
120121
newe.Q.expect = GAverage(value, e.Q.expect, 0.3);
121122
delta2 = (value - e.Q.expect) * (value - e.Q.expect);
122123
newe.Q.var = GAverage(delta2, e.Q.var, 0.3);
@@ -133,6 +134,7 @@ static void NotePerformance(char *eventname, time_t t, double value)
133134
lastseen = 0.0;
134135
newe.t = t;
135136
newe.Q.q = value;
137+
newe.Q.dq = 0;
136138
newe.Q.expect = value;
137139
newe.Q.var = 0.001;
138140
}
@@ -207,6 +209,7 @@ void NoteClassUsage(AlphaList baselist, int purge)
207209
lastseen = now - e.t;
208210
newe.t = now;
209211
newe.Q.q = vtrue;
212+
newe.Q.dq = vtrue - e.Q.q;
210213
newe.Q.expect = GAverage(vtrue, e.Q.expect, 0.7);
211214
delta2 = (vtrue - e.Q.expect) * (vtrue - e.Q.expect);
212215
newe.Q.var = GAverage(delta2, e.Q.var, 0.7);
@@ -216,6 +219,7 @@ void NoteClassUsage(AlphaList baselist, int purge)
216219
lastseen = 0.0;
217220
newe.t = now;
218221
newe.Q.q = 0.5 * vtrue;
222+
newe.Q.dq = 0;
219223
newe.Q.expect = 0.5 * vtrue; /* With no data it's 50/50 what we can say */
220224
newe.Q.var = 0.000;
221225
}
@@ -277,6 +281,7 @@ void NoteClassUsage(AlphaList baselist, int purge)
277281
{
278282
newe.t = then;
279283
newe.Q.q = 0;
284+
newe.Q.dq = entry.Q.dq;
280285
newe.Q.expect = GAverage(0.0, av, 0.5);
281286
delta2 = av * av;
282287
newe.Q.var = GAverage(delta2, var, 0.5);
@@ -385,9 +390,11 @@ static void UpdateLastSawHost(char *rkey, char *ipaddress)
385390
lastseen = 300;
386391
q.Q.expect = 0;
387392
q.Q.var = 0;
393+
q.Q.dq = 0;
388394
}
389395

390396
newq.Q.q = (double) now;
397+
newq.Q.dq = newq.Q.q - q.Q.q;
391398
newq.Q.expect = GAverage(lastseen, q.Q.expect, 0.4);
392399
delta2 = (lastseen - q.Q.expect) * (lastseen - q.Q.expect);
393400
newq.Q.var = GAverage(delta2, q.Q.var, 0.4);
@@ -397,6 +404,7 @@ static void UpdateLastSawHost(char *rkey, char *ipaddress)
397404
{
398405
lastseen = 0.0;
399406
newq.Q.q = (double) now;
407+
newq.Q.dq = 0;
400408
newq.Q.expect = 0.0;
401409
newq.Q.var = 0.0;
402410
strncpy(newq.address, ipaddress, CF_ADDRSIZE - 1);

src/mod_files.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,9 +379,10 @@ BodySyntax CF_FILES_BODIES[] =
379379
{"create", cf_opts, CF_BOOL, "true/false whether to create non-existing file", "false"},
380380
{"delete", cf_body, CF_TIDY_BODY, "Criteria for deleting files"},
381381
{"depth_search", cf_body, CF_RECURSION_BODY, "Criteria for file depth searches"},
382+
{"edit_defaults", cf_body, CF_EDITS_BODY, "Default promise details for file edits"},
382383
{"edit_line", cf_bundle, CF_BUNDLE, "Line editing model for file"},
384+
{"edit_template", cf_str, CF_ABSPATHRANGE, "The name of a special CFEngine template file to expand"},
383385
{"edit_xml", cf_bundle, CF_BUNDLE, "XML editing model for file"},
384-
{"edit_defaults", cf_body, CF_EDITS_BODY, "Default promise details for file edits"},
385386
{"file_select", cf_body, CF_FILEFILTER_BODY, "Choose which files select in a search"},
386387
{"link_from", cf_body, CF_LINKTO_BODY, "Criteria for linking file from a source"},
387388
{"move_obstructions", cf_opts, CF_BOOL, "true/false whether to move obstructions to file-object creation", "false"},

0 commit comments

Comments
 (0)