/
new.py
133 lines (109 loc) · 3.58 KB
/
new.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import errno
import logging
import os
import uuid
import struct
import time
import base64
import socket
from . import exc
from .cliutil import priority
from .conf import CephConf
from .util import arg_validators
from .misc import mon_hosts
LOG = logging.getLogger(__name__)
def generate_auth_key():
key = os.urandom(16)
header = struct.pack('<hiih',
1, # le16 type: CEPH_CRYPTO_AES
int(time.time()), # le32 created: seconds
0, # le32 created: nanoseconds,
len(key), # le16: len(key)
)
return base64.b64encode(header + key)
def get_nonlocal_ip(host):
"""
Search result of getaddrinfo() for a non-localhost-net address
"""
ailist = socket.getaddrinfo(host, None)
for ai in ailist:
# an ai is a 5-tuple; the last element is (ip, port)
ip = ai[4][0]
if not ip.startswith('127.'):
return ip
raise exc.UnableToResolveError(host)
def new(args):
LOG.debug('Creating new cluster named %s', args.cluster)
cfg = CephConf()
cfg.add_section('global')
fsid = uuid.uuid4()
cfg.set('global', 'fsid', str(fsid))
mon_initial_members = []
mon_host = []
for (name, host) in mon_hosts(args.mon):
LOG.debug('Resolving host %s', host)
ip = None
ip = get_nonlocal_ip(host)
LOG.debug('Monitor %s at %s', name, ip)
mon_initial_members.append(name)
mon_host.append(ip)
LOG.debug('Monitor initial members are %s', mon_initial_members)
LOG.debug('Monitor addrs are %s', mon_host)
cfg.set('global', 'mon initial members', ', '.join(mon_initial_members))
# no spaces here, see http://tracker.newdream.net/issues/3145
cfg.set('global', 'mon host', ','.join(mon_host))
# override undesirable defaults, needed until bobtail
# http://tracker.newdream.net/issues/3136
cfg.set('global', 'auth supported', 'cephx')
# http://tracker.newdream.net/issues/3137
cfg.set('global', 'osd journal size', '1024')
# http://tracker.newdream.net/issues/3138
cfg.set('global', 'filestore xattr use omap', 'true')
path = '{name}.conf'.format(
name=args.cluster,
)
# FIXME: create a random key
LOG.debug('Creating a random mon key...')
mon_keyring = '[mon.]\nkey = %s\ncaps mon = allow *\n' % generate_auth_key()
keypath = '{name}.mon.keyring'.format(
name=args.cluster,
)
LOG.debug('Writing initial config to %s...', path)
if not args.dry_run:
tmp = '%s.tmp' % path
with file(tmp, 'w') as f:
cfg.write(f)
try:
os.rename(tmp, path)
except OSError as e:
if e.errno == errno.EEXIST:
raise exc.ClusterExistsError(path)
else:
raise
LOG.debug('Writing monitor keyring to %s...', keypath)
if not args.dry_run:
tmp = '%s.tmp' % keypath
with file(tmp, 'w') as f:
f.write(mon_keyring)
try:
os.rename(tmp, keypath)
except OSError as e:
if e.errno == errno.EEXIST:
raise exc.ClusterExistsError(keypath)
else:
raise
@priority(10)
def make(parser):
"""
Start deploying a new cluster, and write a CLUSTER.conf and keyring for it.
"""
parser.add_argument(
'mon',
metavar='MON',
nargs='+',
help='initial monitor hostname, fqdn, or hostname:fqdn pair',
type=arg_validators.Hostname(),
)
parser.set_defaults(
func=new,
)