]>
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 | ||
d2e6a577 FG |
60 | ['/path/to/ceph-volume-systemd', '<type>-<extra metadata>'] |
61 | ||
62 | For example:: | |
63 | ||
64 | [ | |
65 | '/usr/bin/ceph-volume-systemd', | |
66 | 'lvm-0-8715BEB4-15C5-49DE-BA6F-401086EC7B41' | |
67 | ] | |
68 | ||
69 | The first part of the argument is the only interesting bit, which contains | |
70 | the metadata needed to proxy the call to ``ceph-volume`` itself. | |
71 | ||
72 | Reusing the example, the proxy call to ``ceph-volume`` would look like:: | |
73 | ||
74 | ceph-volume lvm trigger 0-8715BEB4-15C5-49DE-BA6F-401086EC7B41 | |
75 | ||
76 | That means that ``lvm`` is used as the subcommand and it is **expected** | |
77 | that a ``trigger`` sub-commmand will be present to make sense of the extra | |
78 | piece of the string. | |
79 | ||
80 | """ | |
81 | log.setup(name='ceph-volume-systemd.log', log_path='/var/log/ceph/ceph-volume-systemd.log') | |
82 | logger = logging.getLogger('systemd') | |
83 | ||
84 | args = args if args is not None else sys.argv | |
85 | try: | |
86 | suffix = args[-1] | |
87 | except IndexError: | |
88 | raise RuntimeError('no arguments supplied') | |
89 | sub_command = parse_subcommand(suffix) | |
90 | extra_data = parse_extra_data(suffix) | |
91 | logger.info('raw systemd input received: %s', suffix) | |
92 | logger.info('parsed sub-command: %s, extra data: %s', sub_command, extra_data) | |
93 | command = ['ceph-volume', sub_command, 'trigger', extra_data] | |
94 | ||
95 | tries = os.environ.get('CEPH_VOLUME_SYSTEMD_TRIES', 30) | |
96 | interval = os.environ.get('CEPH_VOLUME_SYSTEMD_INTERVAL', 5) | |
97 | while tries > 0: | |
98 | try: | |
99 | # don't log any output to the terminal, just rely on stderr/stdout | |
100 | # going to logging | |
101 | process.run(command, terminal_logging=False) | |
102 | logger.info('successfully trggered activation for: %s', extra_data) | |
103 | break | |
104 | except RuntimeError as error: | |
105 | logger.warning(error) | |
106 | logger.warning('failed activating OSD, retries left: %s', tries) | |
107 | tries -= 1 | |
108 | time.sleep(interval) |