Welcome, guest | Sign In | My Account | Store | Cart

If you're administering a number of machines and each account on these machines has a number of cronjobs this recipe can be used to generate an HTML report listing all crontabs on all your machines. You can use this script in a cronjob to regenerate this report periodically.

Python, 116 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!python
# -*- coding: iso-8859-1 -*-

import datetime

import py

from ll.xist import xsc
from ll.xist.ns import xml, html, meta


codetemplate = """
import os
base = %r
crontabs = os.listdir(base)
channel.send(len(crontabs))
for file in crontabs:
    channel.send((file, os.popen('crontab -u %%s -l' %% file).read()))
"""


class Host(object):
    def __init__(self, name, dir="/var/spool/cron/crontabs", python="python2.4"):
        self.name = name
        self.dir = dir
        self.python = python

    def getcrontabs(self):
        code = py.code.Source(codetemplate % self.dir)
        gateway = py.execnet.SshGateway("root@%s" % self.name, remotepython=self.python)
        channel = gateway.remote_exec(code)
        count = channel.receive()
        for i in xrange(count):
            yield channel.receive()
        gateway.exit()


hosts = [
    Host("host1.example.com"),
    Host("host2.example.org"),
    Host("host3.example.net"),
]


style = """
body {
    margin: 0;
    padding: 0;
    background-color: #fff;
    color: #000;
}

.note
{
    font-size: 13px;
}
h1, h2, h3
{
    color: #0063a8;
    font-family: "Trebuchet MS", sans-serif;
    font-weight: normal;
}

h1
{
    font-size: 30px;
    color: #fff;
    background-color: #0063a8;
    padding: 8px 30px;
}

h2
{
    font-size: 20px;
    margin: 30px 30px -10px 30px;
}

h3
{
    font-size: 14px;
    margin: 20px 30px 2px 30px;
}

pre
{
    margin: 0px 30px 10px 30px;
    font-size: 11px;
    line-height: 18px;
    border: 1px solid #eee;
    background-color: #fafafa;
    padding: 1px 5px 2px 5px;
    overflow: auto;
}
"""

now = datetime.datetime.now()

node = xsc.Frag(html.h1("Cronjobs ", html.span("(generated at %s)" % now.strftime("%d.%m.%Y %H:%M"), class_="note")))

for host in hosts:
    node.append(html.h2(host.name))
    for (user, crontab) in sorted(host.getcrontabs()):
        node.append(html.h3(user, "@", host.name))
        node.append(html.pre(crontab.decode("latin-1").strip()))

node = xsc.Frag(
    xml.XML10(), "\n",
    html.head(
        meta.contenttype(),
        html.title("Cronjobs"),
        html.style(style, type="text/css"),
    ),
    html.body(node)
)

print e.asBytes(encoding="iso-8859-1")

This recipe requires the py library (http://codespeak.net/py/current/doc/). It uses py.execnet to communicate with each host and get back the crontab for each user. Furthermore XIST (http://www.livinglogic.de/Python/xist/) is used for generating HTML.

For this to work non-interactively, you need to setup each host so that you can log into the machine via ssh without requiring a password. The remote host must provide Python for py.execnet to work.

1 comment

holger krekel 14 years, 2 months ago  # | flag

Recently, py lib and execnet were separated so you need to drag in the "execnet" package and use it instead of "py.execnet". Also execnet.SshGateway is deprecated in favour of "execnet.makegateway('ssh=HOST')". cheers, holger