]>
Commit | Line | Data |
---|---|---|
d2e6a577 FG |
1 | """ |
2 | This file is used only by systemd units that are passing their instance suffix | |
3 | as arguments to this script so that it can parse the suffix into arguments that | |
4 | ``ceph-volume <sub command>`` can consume | |
5 | """ | |
6 | import os | |
7 | import sys | |
8 | import time | |
9 | import logging | |
10 | from ceph_volume import log, process | |
11 | from ceph_volume.exceptions import SuffixParsingError | |
12 | ||
13 | ||
14 | def parse_subcommand(string): | |
15 | subcommand = string.split('-', 1)[0] | |
16 | if not subcommand: | |
17 | raise SuffixParsingError('subcommand', string) | |
18 | return subcommand | |
19 | ||
20 | ||
21 | def parse_extra_data(string): | |
22 | # get the subcommand to split on that | |
23 | sub_command = parse_subcommand(string) | |
24 | ||
25 | # the split will leave data with a dash, so remove that | |
26 | data = string.split(sub_command)[-1] | |
27 | if not data: | |
28 | raise SuffixParsingError('data', string) | |
29 | return data.lstrip('-') | |
30 | ||
31 | ||
32 | def parse_osd_id(string): | |
33 | osd_id = string.split('-', 1)[0] | |
34 | if not osd_id: | |
35 | raise SuffixParsingError('OSD id', string) | |
36 | if osd_id.isdigit(): | |
37 | return osd_id | |
38 | raise SuffixParsingError('OSD id', string) | |
39 | ||
40 | ||
41 | def parse_osd_uuid(string): | |
42 | osd_id = '%s-' % parse_osd_id(string) | |
43 | osd_subcommand = '-%s' % parse_subcommand(string) | |
44 | # remove the id first | |
45 | trimmed_suffix = string.split(osd_id)[-1] | |
46 | # now remove the sub command | |
47 | osd_uuid = trimmed_suffix.split(osd_subcommand)[0] | |
48 | if not osd_uuid: | |
49 | raise SuffixParsingError('OSD uuid', string) | |
50 | return osd_uuid | |
51 | ||
52 | ||
53 | def main(args=None): | |
54 | """ | |
55 | Main entry point for the ``ceph-volume-systemd`` executable. ``args`` are | |
56 | optional for easier testing of arguments. | |
57 | ||
58 | Expected input is similar to:: | |
59 | ||
60 | ['/path/to/ceph-volume-systemd', '<osd id>-<osd uuid>-<device type>'] | |
61 | ['/path/to/ceph-volume-systemd', '<type>-<extra metadata>'] | |
62 | ||
63 | For example:: | |
64 | ||
65 | [ | |
66 | '/usr/bin/ceph-volume-systemd', | |
67 | 'lvm-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41' | |
68 | ] | |
69 | ||
70 | The first part of the argument is the only interesting bit, which contains | |
71 | the metadata needed to proxy the call to ``ceph-volume`` itself. | |
72 | ||
73 | Reusing the example, the proxy call to ``ceph-volume`` would look like:: | |
74 | ||
75 | ceph-volume lvm trigger 0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 | |
76 | ||
77 | That means that ``lvm`` is used as the subcommand and it is **expected** | |
78 | that a ``trigger`` sub-commmand will be present to make sense of the extra | |
79 | piece of the string. | |
80 | ||
81 | """ | |
82 | log.setup(name='ceph-volume-systemd.log', log_path='/var/log/ceph/ceph-volume-systemd.log') | |
83 | logger = logging.getLogger('systemd') | |
84 | ||
85 | args = args if args is not None else sys.argv | |
86 | try: | |
87 | suffix = args[-1] | |
88 | except IndexError: | |
89 | raise RuntimeError('no arguments supplied') | |
90 | sub_command = parse_subcommand(suffix) | |
91 | extra_data = parse_extra_data(suffix) | |
92 | logger.info('raw systemd input received: %s', suffix) | |
93 | logger.info('parsed sub-command: %s, extra data: %s', sub_command, extra_data) | |
94 | command = ['ceph-volume', sub_command, 'trigger', extra_data] | |
95 | ||
96 | tries = os.environ.get('CEPH_VOLUME_SYSTEMD_TRIES', 30) | |
97 | interval = os.environ.get('CEPH_VOLUME_SYSTEMD_INTERVAL', 5) | |
98 | while tries > 0: | |
99 | try: | |
100 | # don't log any output to the terminal, just rely on stderr/stdout | |
101 | # going to logging | |
102 | process.run(command, terminal_logging=False) | |
103 | logger.info('successfully trggered activation for: %s', extra_data) | |
104 | break | |
105 | except RuntimeError as error: | |
106 | logger.warning(error) | |
107 | logger.warning('failed activating OSD, retries left: %s', tries) | |
108 | tries -= 1 | |
109 | time.sleep(interval) |