1 from __future__
import print_function
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
12 logger
= logging
.getLogger(__name__
)
15 class Activate(object):
17 help = 'Enable systemd units to mount configured devices and start a Ceph OSD'
19 def __init__(self
, argv
, systemd
=False):
21 self
.systemd
= systemd
23 @decorators.needs_root
24 def activate(self
, args
):
25 with
open(args
.json_config
, 'r') as fp
:
26 osd_metadata
= json
.load(fp
)
28 osd_id
= osd_metadata
.get('whoami', args
.osd_id
)
29 osd_fsid
= osd_metadata
.get('fsid', args
.osd_fsid
)
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')
36 'Unable to activate OSD %s - no "uuid" key found for data' % args
.osd_id
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')
46 if not system
.device_is_mounted(data_device
, destination
=osd_dir
):
47 process
.run(['sudo', 'mount', '-v', data_device
, osd_dir
])
50 'journal': journal_device
,
51 'block': block_device
,
52 'block.db': block_db_device
,
53 'block.wal': block_wal_device
56 for name
, device
in device_map
.items():
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
])
64 # make sure that the journal has proper permissions
68 # enable the ceph-volume unit for this OSD
69 systemctl
.enable_volume(osd_id
, osd_fsid
, 'simple')
71 # disable any/all ceph-disk units
72 systemctl
.mask_ceph_disk()
75 systemctl
.enable_osd(osd_id
)
78 systemctl
.start_osd(osd_id
)
81 terminal
.success('Successfully activated OSD %s with FSID %s' % (osd_id
, osd_fsid
))
83 ('All ceph-disk systemd units have been disabled to '
84 'prevent OSDs getting triggered by UDEV events')
88 sub_command_help
= dedent("""
89 Activate OSDs by mounting devices previously configured to their
90 appropriate destination::
92 ceph-volume simple activate {ID} {FSID}
94 Or using a JSON file directly::
96 ceph-volume simple activate --file /etc/ceph/osd/{ID}-{FSID}.json
98 The OSD must have been "scanned" previously (see ``ceph-volume simple
99 scan``), so that all needed OSD device information and metadata exist.
101 A previously scanned OSD would exist like::
103 /etc/ceph/osd/{ID}-{FSID}.json
106 Environment variables supported:
108 CEPH_VOLUME_SIMPLE_JSON_DIR: Directory location for scanned OSD JSON configs
110 parser
= argparse
.ArgumentParser(
111 prog
='ceph-volume simple activate',
112 formatter_class
=argparse
.RawDescriptionHelpFormatter
,
113 description
=sub_command_help
,
119 help='The ID of the OSD, usually an integer, like 0'
125 help='The FSID of the OSD, similar to a SHA1'
129 help='The path to a JSON file, from a scanned OSD'
131 if len(self
.argv
) == 0:
132 print(sub_command_help
)
134 args
= parser
.parse_args(self
.argv
)
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/')
146 json_config
= args
.file
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