Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / ceph-volume / ceph_volume / devices / simple / activate.py
1 from __future__ import print_function
2 import argparse
3 import json
4 import logging
5 import os
6 from textwrap import dedent
7 from ceph_volume import process, decorators, terminal
8 from ceph_volume.util import system, disk
9 from ceph_volume.systemd import systemctl
10
11
12 logger = logging.getLogger(__name__)
13
14
15 class Activate(object):
16
17     help = 'Enable systemd units to mount configured devices and start a Ceph OSD'
18
19     def __init__(self, argv, systemd=False):
20         self.argv = argv
21         self.systemd = systemd
22
23     @decorators.needs_root
24     def activate(self, args):
25         with open(args.json_config, 'r') as fp:
26             osd_metadata = json.load(fp)
27
28         osd_id = osd_metadata.get('whoami', args.osd_id)
29         osd_fsid = osd_metadata.get('fsid', args.osd_fsid)
30
31         cluster_name = osd_metadata.get('cluster_name', 'ceph')
32         osd_dir = '/var/lib/ceph/osd/%s-%s' % (cluster_name, osd_id)
33         data_uuid = osd_metadata.get('data', {}).get('uuid')
34         if not data_uuid:
35             raise RuntimeError(
36                 'Unable to activate OSD %s - no "uuid" key found for data' % args.osd_id
37             )
38         data_device = disk.get_device_from_partuuid(data_uuid)
39         journal_device = disk.get_device_from_partuuid(osd_metadata.get('journal', {}).get('uuid'))
40         block_device = disk.get_device_from_partuuid(osd_metadata.get('block', {}).get('uuid'))
41         block_db_device = disk.get_device_from_partuuid(osd_metadata.get('block.db', {}).get('uuid'))
42         block_wal_device = disk.get_device_from_partuuid(
43             osd_metadata.get('block.wal', {}).get('uuid')
44         )
45
46         if not system.device_is_mounted(data_device, destination=osd_dir):
47             process.run(['mount', '-v', data_device, osd_dir])
48
49         device_map = {
50             'journal': journal_device,
51             'block': block_device,
52             'block.db': block_db_device,
53             'block.wal': block_wal_device
54         }
55
56         for name, device in device_map.items():
57             if not device:
58                 continue
59             # always re-do the symlink regardless if it exists, so that the journal
60             # device path that may have changed can be mapped correctly every time
61             destination = os.path.join(osd_dir, name)
62             process.run(['ln', '-snf', device, destination])
63
64             # make sure that the journal has proper permissions
65             system.chown(device)
66
67         if not self.systemd:
68             # enable the ceph-volume unit for this OSD
69             systemctl.enable_volume(osd_id, osd_fsid, 'simple')
70
71             # disable any/all ceph-disk units
72             systemctl.mask_ceph_disk()
73
74         # enable the OSD
75         systemctl.enable_osd(osd_id)
76
77         # start the OSD
78         systemctl.start_osd(osd_id)
79
80         if not self.systemd:
81             terminal.success('Successfully activated OSD %s with FSID %s' % (osd_id, osd_fsid))
82             terminal.warning(
83                 ('All ceph-disk systemd units have been disabled to '
84                  'prevent OSDs getting triggered by UDEV events')
85             )
86
87     def main(self):
88         sub_command_help = dedent("""
89         Activate OSDs by mounting devices previously configured to their
90         appropriate destination::
91
92             ceph-volume simple activate {ID} {FSID}
93
94         Or using a JSON file directly::
95
96             ceph-volume simple activate --file /etc/ceph/osd/{ID}-{FSID}.json
97
98         The OSD must have been "scanned" previously (see ``ceph-volume simple
99         scan``), so that all needed OSD device information and metadata exist.
100
101         A previously scanned OSD would exist like::
102
103             /etc/ceph/osd/{ID}-{FSID}.json
104
105
106         Environment variables supported:
107
108         CEPH_VOLUME_SIMPLE_JSON_DIR: Directory location for scanned OSD JSON configs
109         """)
110         parser = argparse.ArgumentParser(
111             prog='ceph-volume simple activate',
112             formatter_class=argparse.RawDescriptionHelpFormatter,
113             description=sub_command_help,
114         )
115         parser.add_argument(
116             'osd_id',
117             metavar='ID',
118             nargs='?',
119             help='The ID of the OSD, usually an integer, like 0'
120         )
121         parser.add_argument(
122             'osd_fsid',
123             metavar='FSID',
124             nargs='?',
125             help='The FSID of the OSD, similar to a SHA1'
126         )
127         parser.add_argument(
128             '--file',
129             help='The path to a JSON file, from a scanned OSD'
130         )
131         if len(self.argv) == 0:
132             print(sub_command_help)
133             return
134         args = parser.parse_args(self.argv)
135         if not args.file:
136             if not args.osd_id and not args.osd_fsid:
137                 terminal.error('ID and FSID are required to find the right OSD to activate')
138                 terminal.error('from a scanned OSD location in /etc/ceph/osd/')
139                 raise RuntimeError('Unable to activate without both ID and FSID')
140         # don't allow a CLI flag to specify the JSON dir, because that might
141         # implicitly indicate that it would be possible to activate a json file
142         # at a non-default location which would not work at boot time if the
143         # custom location is not exposed through an ENV var
144         json_dir = os.environ.get('CEPH_VOLUME_SIMPLE_JSON_DIR', '/etc/ceph/osd/')
145         if args.file:
146             json_config = args.file
147         else:
148             json_config = os.path.join(json_dir, '%s-%s.json' % (args.osd_id, args.osd_fsid))
149         if not os.path.exists(json_config):
150             raise RuntimeError('Expected JSON config path not found: %s' % json_config)
151         args.json_config = json_config
152         self.activate(args)