                       EXERCISES



1. Write a policy to signal TERM and then KILL to any
process matching "trn".

  Testing it:

    cp /bin/sleep ~/trn
    ~/trn 1000 &
    cf-agent -f ...

1b. Make a list of processes you don't want to run
(let's say "trn" and "eggdrop") and put this list 
into an slist variable.  Write a promise to signal
'term' and then 'kill' to any process in that
list.
 


EXERCISE 2

Write a policy to create /tmp/myname.txt and put
your name in it.




EXERCISE 3

Manually create a template:
echo 'Hello, $(mybundle.myname).  The time is $(sys.date).' > /tmp/file.dat


Note: a fully qualified variable consists of the bundle 
name wherein the variable is defined plus the variable 
name.  Example: 

    bundle agent mybundle { vars: "myvar" string => "myvalue"; }

The fully qualified variable name is $(mybundle.myvar).


Now write a policy to populate contents of /tmp/file.txt
using this template file, /tmp/file.dat. 

Make sure your bundle defines the variable embedded in the
template, and that your bundle name matches the bundle name
embedded in the template.

Your policy should use an edit_lines bundle containing an
insert_lines promise with the following attributes:

      insert_type => "file",
      expand_scalars => "true";

If you finish before rest of the group, finish studying 
the CFEngine Reference Manual chapters 1 -4, and if you
finish that, then study the Special Topic guide on Editing
File Content.


EXERCISE 4.  Classes.

Set a custom class based on the existance of a file.
For example:

    classes:

       "file_exists"
         
           expression  =>  fileexists("/etc/site_id") ;

Then write another promise that is conditional on the 
above class.

Run it when the file exists, and when it does not, and
observe how CFEngine dynamically configures your server.








EXERCISE 5.  File Editing

Write a policy to create /etc/motd as follows:
It should *always* say "Unauthorized use forbidden."

EXERCISE 5b.  File Editing and Classes

/etc/motd should *always* say "Unauthorized use forbidden."

On weekends, it should also say "Go home, it's the weekend".

Test by defining "Saturday" class on the command line:

  cf-agent -D Saturday  --file ... --bundle ...


















EXERCISE 6.  Running CFEngine Non-Interactively (as a Service)

Demonstrating of CFEngine running in non-interactive
mode, using /var/cfengine/inputs/promises.cf as its
input:



EXERCISE 6a.

Set a variable, and then display its value in a report.

EXERCISE 6b.

Report the current time using:

     a) output from /bin/date (captured using execresult() function)

     b) built-in special variable $(sys.date)


EXERCISE 6c.  File Editing - replace_patterns - uses CFEngine Standard Library

Create (manually) a data file:

   /tmp/data.txt

        line 1
        line 2
        line 3

Use cf-agent to replace "line 2" with "line two".


EXERCISE 6d.  File Editing - replace_patterns - uses CFEngine Standard Library

Manually create a template
/var/cfengine/masterfiles/templates/motd.dat:

    This system is property of __ORGANIZATION__.
    Unauthorized use forbidden.  
    CFEngine maintains this system.
    CFEngine last ran on $(sys.date).

Write a CFEngine policy to generate /etc/motd from 
/var/cfengine/inputs/templates/motd.dat as follows:

  - Replace __ORGANIZATION__ with the
    name of your organization.

  - Expand the special variable $(sys.date).

Use all of the following promise types:

delete_lines
insert_lines
replace_patterns



EXERCISE 7. Integrate your motd policy from exercise 6b
into the default cfengine policy in masterfiles so 
that it propagates to all servers.



EXERCISE 8. Reporting when CFEngine makes a change to your system

Write a promise that logs when it is repaired 
to /var/log/cfengine/repairs.log

Reference: Special Topics guide on Reporting.



EXERCISE 11 - Precision File Editing


Insert the following three lines (and you can keep them
in order, as a single block, using
insert_lines attribute
   insert_type => "preserve_block";
) into /etc/profile BEFORE the HOSTNAME=... line.
(Hint: look at the "location" attribute of insert_lines)


if [ -x /bin/custom ]
  then /bin/custom
fi




EXERCISE 15 - Using Classes to time Command Execution

Problem:  All practice machines should be shutdown
at end of class at 17:00

Desired state:  The command "/sbin/shutdown -h now"
is running when we are in the 17th hour of the day,
so the system shuts down cleanly and on time.



EXERCISE 16 - CFEngine Standard Library

Given a file /tmp/file.txt:

apples
oranges

Use the CFEngine Standard Library to comment out
"oranges" and append "bananas", resulting in:

apples
# oranges
bananas

Hint: use the following:
 - bundle edit_line insert_lines 
 - bundle edit_line comment_lines_matching


EXERCISE 17 - CFEngine Standard Library - run a command as a specific user

Run the command /usr/bin/id as user "nobody".

Hint: use "body contain setuid".



EXERCISE 18 - CFEngine Standard Library - linking promises

Problem: Increase security by ensuring sshd is
running with "PermitRootLogin no".

How does the system look like in the correct configuration:

1. Make sure /etc/ssh/sshd_config contains the line
"PermitRootLogin no"

2. Make sure sshd is running using this configuration

How to code it in CFEngine:

1. a files promise to edit sshd_config

2. a commands promise to restart sshd to reload the new
   config

Exercise:  use the "body classes if_repaired" to link
1 and 2 above to make sure 2 happens.


EXERCISE 19 - Bonus Points - Restart sshd if process
start time of sshd predates the modification timestamp
of /etc/ssh/sshd_config
(Process selection is demonstrated in
*Process_Selection* in
verticalsysadmin_training_examples)

EXERCISE 20 - Write a CFEngine policy to install and
configure a Wiki web service.

