]>
Commit | Line | Data |
---|---|---|
dc0a9f0e | 1 | #!/usr/bin/env python |
9d8b5dfe BZ |
2 | # -*- Mode: Python; python-indent: 8; indent-tabs-mode: t -*- |
3 | ||
4 | import sys, os, argparse, errno | |
5 | ||
6 | def find_service(service, runlevel): | |
7 | priority = -1 | |
8 | ||
d16cf1fc | 9 | for l in os.listdir("/etc/rc.d/rc%i.d" % runlevel): |
9d8b5dfe BZ |
10 | if len(l) < 4: |
11 | continue | |
12 | ||
13 | if l[0] != 'S' or l[3:] != service: | |
14 | continue | |
15 | ||
16 | p = int(l[1:3]) | |
17 | ||
18 | if p >= 0 and p <= 99 and p >= priority: | |
19 | priority = p; | |
20 | ||
21 | return priority | |
22 | ||
23 | def lookup_database(services): | |
24 | try: | |
25 | database = open("/var/lib/systemd/sysv-convert/database", "r") | |
26 | except IOError, e: | |
27 | if e.errno != errno.ENOENT: | |
28 | raise e | |
29 | ||
30 | return {} | |
31 | ||
32 | found = {} | |
33 | k = 0 | |
34 | ||
35 | for line in database: | |
36 | service, r, p = line.strip().split("\t", 3) | |
37 | k += 1 | |
38 | ||
39 | try: | |
40 | runlevel = int(r) | |
41 | priority = int(p) | |
42 | except ValueError, e: | |
43 | sys.stderr.write("Failed to parse database line %i. Ignoring." % k) | |
44 | continue | |
45 | ||
46 | if runlevel not in (2, 3, 4, 5): | |
47 | sys.stderr.write("Runlevel out of bounds in database line %i. Ignoring." % k) | |
48 | continue | |
49 | ||
50 | if priority < 0 or priority > 99: | |
51 | sys.stderr.write("Priority out of bounds in database line %i. Ignoring." % k) | |
52 | continue | |
53 | ||
54 | if service not in services: | |
55 | continue | |
56 | ||
57 | if service not in found: | |
58 | found[service] = {} | |
59 | ||
60 | if runlevel not in found[service] or found[service][runlevel] < priority: | |
61 | found[service][runlevel] = priority | |
62 | ||
63 | return found | |
64 | ||
65 | def mkdir_p(path): | |
66 | try: | |
67 | os.makedirs(path, 0755) | |
68 | except OSError, e: | |
69 | if e.errno != errno.EEXIST: | |
70 | raise e | |
71 | ||
72 | if os.geteuid() != 0: | |
73 | sys.stderr.write("Need to be root.\n") | |
74 | sys.exit(1) | |
75 | ||
76 | parser = argparse.ArgumentParser(description='Save and Restore SysV Service Runlevel Information') | |
77 | ||
78 | parser.add_argument('services', metavar='SERVICE', type=str, nargs='+', | |
79 | help='Service names') | |
80 | ||
81 | parser.add_argument('--save', dest='save', action='store_const', | |
82 | const=True, default=False, | |
83 | help='Save SysV runlevel information for one or more services') | |
84 | ||
85 | parser.add_argument('--show', dest='show', action='store_const', | |
86 | const=True, default=False, | |
87 | help='Show saved SysV runlevel information for one or more services') | |
88 | ||
89 | parser.add_argument('--apply', dest='apply', action='store_const', | |
90 | const=True, default=False, | |
91 | help='Apply saved SysV runlevel information for one or more services to systemd counterparts') | |
92 | ||
93 | a = parser.parse_args() | |
94 | ||
95 | if a.save: | |
96 | for service in a.services: | |
97 | if not os.access("/etc/rc.d/init.d/%s" % service, os.F_OK): | |
98 | sys.stderr.write("SysV service %s does not exist.\n" % service) | |
99 | sys.exit(1) | |
100 | ||
101 | mkdir_p("/var/lib/systemd/sysv-convert") | |
102 | database = open("/var/lib/systemd/sysv-convert/database", "a") | |
103 | ||
104 | for runlevel in (2, 3, 4, 5): | |
105 | priority = find_service(service, runlevel) | |
106 | ||
107 | if priority >= 0: | |
108 | database.write("%s\t%s\t%s\n" % (service, runlevel, priority)) | |
109 | ||
110 | elif a.show: | |
111 | found = lookup_database(a.services) | |
112 | ||
113 | if len(found) <= 0: | |
114 | sys.stderr.write("No information about passed services found.\n") | |
115 | sys.exit(1) | |
116 | ||
117 | for service, data in found.iteritems(): | |
118 | for runlevel, priority in data.iteritems(): | |
119 | sys.stdout.write("SysV service %s enabled in runlevel %s at priority %s\n" % (service, runlevel, priority)) | |
120 | ||
121 | elif a.apply: | |
122 | for service in a.services: | |
123 | if not os.access("/lib/systemd/system/%s.service" % service, os.F_OK): | |
124 | sys.stderr.write("systemd service %s.service does not exist.\n" % service) | |
125 | sys.exit(1) | |
126 | ||
127 | found = lookup_database(a.services) | |
128 | ||
129 | if len(found) <= 0: | |
130 | sys.stderr.write("No information about passed services found.\n") | |
131 | sys.exit(1) | |
132 | ||
133 | for service, data in found.iteritems(): | |
134 | for runlevel in data.iterkeys(): | |
135 | ||
136 | sys.stderr.write("ln -sf /lib/systemd/system/%s.service /etc/systemd/system/runlevel%i.target.wants/%s.service\n" % (service, runlevel, service)) | |
137 | ||
138 | mkdir_p("/etc/systemd/system/runlevel%i.target.wants" % runlevel) | |
139 | ||
140 | try: | |
141 | os.symlink("/lib/systemd/system/%s.service" % service, | |
142 | "/etc/systemd/system/runlevel%i.target.wants/%s.service" % (runlevel, service)) | |
143 | except OSError, e: | |
144 | if e.errno != errno.EEXIST: | |
145 | raise e | |
146 | ||
147 | else: | |
148 | parser.print_help() |