]> git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/devices/simple/activate.py
update sources to 12.2.2
[ceph.git] / 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(['sudo', '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(['sudo', '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)