<s> import json <EOL> import logging <EOL> import re <EOL> import os <EOL> import time <EOL> from ceph_deploy import conf , exc , admin <EOL> from ceph_deploy . cliutil import priority <EOL> from ceph_deploy . util . help_formatters import ToggleRawTextHelpFormatter <EOL> from ceph_deploy . util import paths , net , files , packages , system <EOL> from ceph_deploy . lib import remoto <EOL> from ceph_deploy . new import new_mon_keyring <EOL> from ceph_deploy import hosts <EOL> from ceph_deploy . misc import mon_hosts <EOL> from ceph_deploy import gatherkeys <EOL> LOG = logging . getLogger ( __name__ ) <EOL> def mon_status_check ( conn , logger , hostname , args ) : <EOL> """<STR_LIT>""" <EOL> asok_path = paths . mon . asok ( args . cluster , hostname ) <EOL> out , err , code = remoto . process . check ( <EOL> conn , <EOL> [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( cluster = args . cluster ) , <EOL> '<STR_LIT>' , <EOL> asok_path , <EOL> '<STR_LIT>' , <EOL> ] , <EOL> ) <EOL> for line in err : <EOL> logger . error ( line ) <EOL> try : <EOL> return json . loads ( '<STR_LIT>' . join ( out ) ) <EOL> except ValueError : <EOL> return { } <EOL> def catch_mon_errors ( conn , logger , hostname , cfg , args ) : <EOL> """<STR_LIT>""" <EOL> monmap = mon_status_check ( conn , logger , hostname , args ) . get ( '<STR_LIT>' , { } ) <EOL> mon_initial_members = get_mon_initial_members ( args , _cfg = cfg ) <EOL> public_addr = cfg . safe_get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> public_network = cfg . safe_get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> mon_in_monmap = [ <EOL> mon . get ( '<STR_LIT:name>' ) <EOL> for mon in monmap . get ( '<STR_LIT>' , [ { } ] ) <EOL> if mon . get ( '<STR_LIT:name>' ) == hostname <EOL> ] <EOL> if mon_initial_members is None or not hostname in mon_initial_members : <EOL> logger . warning ( '<STR_LIT>' , hostname ) <EOL> if not mon_in_monmap : <EOL> logger . warning ( '<STR_LIT>' , hostname ) <EOL> if not public_addr and not public_network : <EOL> logger . warning ( '<STR_LIT>' ) <EOL> logger . warning ( '<STR_LIT>' ) <EOL> def mon_status ( conn , logger , hostname , args , silent = False ) : <EOL> """<STR_LIT>""" <EOL> mon = '<STR_LIT>' % hostname <EOL> try : <EOL> out = mon_status_check ( conn , logger , hostname , args ) <EOL> if not out : <EOL> logger . warning ( '<STR_LIT>' % mon ) <EOL> return False <EOL> if not silent : <EOL> logger . debug ( '<STR_LIT:*>' * <NUM_LIT> ) <EOL> logger . debug ( '<STR_LIT>' % mon ) <EOL> for line in json . dumps ( out , indent = <NUM_LIT:2> , sort_keys = True ) . split ( '<STR_LIT:\n>' ) : <EOL> logger . debug ( line ) <EOL> logger . debug ( '<STR_LIT:*>' * <NUM_LIT> ) <EOL> if out [ '<STR_LIT>' ] >= <NUM_LIT:0> : <EOL> logger . info ( '<STR_LIT>' % mon ) <EOL> return True <EOL> if out [ '<STR_LIT>' ] == - <NUM_LIT:1> and out [ '<STR_LIT:state>' ] : <EOL> logger . info ( '<STR_LIT>' % ( mon , out [ '<STR_LIT:state>' ] ) ) <EOL> return True <EOL> logger . info ( '<STR_LIT>' % mon ) <EOL> return False <EOL> except RuntimeError : <EOL> logger . info ( '<STR_LIT>' % mon ) <EOL> return False <EOL> def keyring_parser ( path ) : <EOL> """<STR_LIT>""" <EOL> sections = [ ] <EOL> with open ( path ) as keyring : <EOL> lines = keyring . readlines ( ) <EOL> for line in lines : <EOL> line = line . strip ( '<STR_LIT:\n>' ) <EOL> if line . startswith ( '<STR_LIT:[>' ) and line . endswith ( '<STR_LIT:]>' ) : <EOL> sections . append ( line . strip ( '<STR_LIT>' ) ) <EOL> return sections <EOL> def concatenate_keyrings ( args ) : <EOL> """<STR_LIT>""" <EOL> keyring_path = os . path . abspath ( args . keyrings ) <EOL> LOG . info ( '<STR_LIT>' % keyring_path ) <EOL> LOG . info ( '<STR_LIT>' ) <EOL> keyrings = [ <EOL> os . path . join ( keyring_path , f ) for f in os . listdir ( keyring_path ) <EOL> if os . path . isfile ( os . path . join ( keyring_path , f ) ) and f . endswith ( '<STR_LIT>' ) <EOL> ] <EOL> contents = [ ] <EOL> seen_sections = { } <EOL> if not keyrings : <EOL> path_from_arg = os . path . abspath ( args . keyrings ) <EOL> raise RuntimeError ( '<STR_LIT>' % path_from_arg ) <EOL> for keyring in keyrings : <EOL> path = os . path . abspath ( keyring ) <EOL> for section in keyring_parser ( path ) : <EOL> if not seen_sections . get ( section ) : <EOL> seen_sections [ section ] = path <EOL> LOG . info ( '<STR_LIT>' % ( section , path ) ) <EOL> with open ( path ) as k : <EOL> contents . append ( k . read ( ) ) <EOL> else : <EOL> LOG . warning ( '<STR_LIT>' % path ) <EOL> LOG . warning ( '<STR_LIT>' % ( section , path ) ) <EOL> LOG . warning ( '<STR_LIT>' % seen_sections [ section ] ) <EOL> return '<STR_LIT>' . join ( contents ) <EOL> def mon_add ( args ) : <EOL> cfg = conf . ceph . load ( args ) <EOL> mon_host = args . mon [ <NUM_LIT:0> ] <EOL> try : <EOL> with file ( '<STR_LIT>' . format ( cluster = args . cluster ) , <EOL> '<STR_LIT:rb>' ) as f : <EOL> monitor_keyring = f . read ( ) <EOL> except IOError : <EOL> raise RuntimeError ( <EOL> '<STR_LIT>' <EOL> ) <EOL> LOG . info ( '<STR_LIT>' , mon_host ) <EOL> args . client = args . mon <EOL> admin . admin ( args ) <EOL> LOG . debug ( <EOL> '<STR_LIT>' , <EOL> args . cluster , <EOL> mon_host , <EOL> ) <EOL> mon_section = '<STR_LIT>' % mon_host <EOL> cfg_mon_addr = cfg . safe_get ( mon_section , '<STR_LIT>' ) <EOL> if args . address : <EOL> LOG . debug ( '<STR_LIT>' % args . address ) <EOL> mon_ip = args . address <EOL> elif cfg_mon_addr : <EOL> LOG . debug ( '<STR_LIT>' % cfg_mon_addr ) <EOL> mon_ip = cfg_mon_addr <EOL> else : <EOL> mon_ip = net . get_nonlocal_ip ( mon_host ) <EOL> LOG . debug ( '<STR_LIT>' % mon_ip ) <EOL> try : <EOL> LOG . debug ( '<STR_LIT>' , mon_host ) <EOL> distro = hosts . get ( <EOL> mon_host , <EOL> username = args . username , <EOL> callbacks = [ packages . ceph_is_installed ] <EOL> ) <EOL> LOG . info ( '<STR_LIT>' , distro . name , distro . release , distro . codename ) <EOL> rlogger = logging . getLogger ( mon_host ) <EOL> hostname_is_compatible ( distro . conn , rlogger , mon_host ) <EOL> rlogger . debug ( '<STR_LIT>' , mon_host ) <EOL> args . address = mon_ip <EOL> distro . mon . add ( distro , args , monitor_keyring ) <EOL> time . sleep ( <NUM_LIT:2> ) <EOL> catch_mon_errors ( distro . conn , rlogger , mon_host , cfg , args ) <EOL> mon_status ( distro . conn , rlogger , mon_host , args ) <EOL> distro . conn . exit ( ) <EOL> except RuntimeError as e : <EOL> LOG . error ( e ) <EOL> raise exc . GenericError ( '<STR_LIT>' % mon_host ) <EOL> def mon_create ( args ) : <EOL> cfg = conf . ceph . load ( args ) <EOL> if not args . mon : <EOL> args . mon = get_mon_initial_members ( args , error_on_empty = True , _cfg = cfg ) <EOL> if args . keyrings : <EOL> monitor_keyring = concatenate_keyrings ( args ) <EOL> else : <EOL> keyring_path = '<STR_LIT>' . format ( cluster = args . cluster ) <EOL> try : <EOL> monitor_keyring = files . read_file ( keyring_path ) <EOL> except IOError : <EOL> LOG . warning ( '<STR_LIT>' % keyring_path ) <EOL> new_mon_keyring ( args ) <EOL> monitor_keyring = files . read_file ( keyring_path ) <EOL> LOG . debug ( <EOL> '<STR_LIT>' , <EOL> args . cluster , <EOL> '<STR_LIT:U+0020>' . join ( args . mon ) , <EOL> ) <EOL> errors = <NUM_LIT:0> <EOL> for ( name , host ) in mon_hosts ( args . mon ) : <EOL> try : <EOL> LOG . debug ( '<STR_LIT>' , name ) <EOL> distro = hosts . get ( <EOL> host , <EOL> username = args . username , <EOL> callbacks = [ packages . ceph_is_installed ] <EOL> ) <EOL> LOG . info ( '<STR_LIT>' , distro . name , distro . release , distro . codename ) <EOL> rlogger = logging . getLogger ( name ) <EOL> hostname_is_compatible ( distro . conn , rlogger , name ) <EOL> rlogger . debug ( '<STR_LIT>' , name ) <EOL> distro . mon . create ( distro , args , monitor_keyring ) <EOL> time . sleep ( <NUM_LIT:2> ) <EOL> mon_status ( distro . conn , rlogger , name , args ) <EOL> catch_mon_errors ( distro . conn , rlogger , name , cfg , args ) <EOL> distro . conn . exit ( ) <EOL> except RuntimeError as e : <EOL> LOG . error ( e ) <EOL> errors += <NUM_LIT:1> <EOL> if errors : <EOL> raise exc . GenericError ( '<STR_LIT>' % errors ) <EOL> def hostname_is_compatible ( conn , logger , provided_hostname ) : <EOL> """<STR_LIT>""" <EOL> logger . debug ( '<STR_LIT>' ) <EOL> remote_hostname = conn . remote_module . shortname ( ) <EOL> if remote_hostname == provided_hostname : <EOL> return <EOL> logger . warning ( '<STR_LIT:*>' * <NUM_LIT> ) <EOL> logger . warning ( '<STR_LIT>' ) <EOL> logger . warning ( '<STR_LIT>' % provided_hostname ) <EOL> logger . warning ( '<STR_LIT>' % remote_hostname ) <EOL> logger . warning ( '<STR_LIT>' ) <EOL> logger . warning ( '<STR_LIT:*>' * <NUM_LIT> ) <EOL> def destroy_mon ( conn , cluster , hostname ) : <EOL> import datetime <EOL> import time <EOL> retries = <NUM_LIT:5> <EOL> path = paths . mon . path ( cluster , hostname ) <EOL> if conn . remote_module . path_exists ( path ) : <EOL> remoto . process . run ( <EOL> conn , <EOL> [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( cluster = cluster ) , <EOL> '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' . format ( path = path ) , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> hostname , <EOL> ] , <EOL> timeout = <NUM_LIT:7> , <EOL> ) <EOL> if conn . remote_module . path_exists ( os . path . join ( path , '<STR_LIT>' ) ) or system . is_upstart ( conn ) : <EOL> status_args = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT:status>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( cluster = cluster ) , <EOL> '<STR_LIT>' . format ( hostname = hostname ) , <EOL> ] <EOL> elif conn . remote_module . path_exists ( os . path . join ( path , '<STR_LIT>' ) ) : <EOL> status_args = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT:status>' , <EOL> '<STR_LIT>' . format ( hostname = hostname ) , <EOL> ] <EOL> elif system . is_systemd ( conn ) : <EOL> status_args = [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' . format ( hostname = hostname ) , <EOL> ] <EOL> else : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> while retries : <EOL> conn . logger . info ( '<STR_LIT>' ) <EOL> if is_running ( conn , status_args ) : <EOL> time . sleep ( <NUM_LIT:5> ) <EOL> retries -= <NUM_LIT:1> <EOL> if retries <= <NUM_LIT:0> : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> else : <EOL> break <EOL> fn = '<STR_LIT>' . format ( <EOL> hostname = hostname , <EOL> cluster = cluster , <EOL> stamp = datetime . datetime . utcnow ( ) . strftime ( "<STR_LIT>" ) , <EOL> ) <EOL> remoto . process . run ( <EOL> conn , <EOL> [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] , <EOL> ) <EOL> conn . remote_module . make_mon_removed_dir ( path , fn ) <EOL> def mon_destroy ( args ) : <EOL> errors = <NUM_LIT:0> <EOL> for ( name , host ) in mon_hosts ( args . mon ) : <EOL> try : <EOL> LOG . debug ( '<STR_LIT>' , name ) <EOL> distro = hosts . get ( <EOL> host , <EOL> username = args . username , <EOL> callbacks = [ packages . ceph_is_installed ] <EOL> ) <EOL> hostname = distro . conn . remote_module . shortname ( ) <EOL> destroy_mon ( <EOL> distro . conn , <EOL> args . cluster , <EOL> hostname , <EOL> ) <EOL> distro . conn . exit ( ) <EOL> except RuntimeError as e : <EOL> LOG . error ( e ) <EOL> errors += <NUM_LIT:1> <EOL> if errors : <EOL> raise exc . GenericError ( '<STR_LIT>' % errors ) <EOL> def mon_create_initial ( args ) : <EOL> mon_initial_members = get_mon_initial_members ( args , error_on_empty = True ) <EOL> args . mon = mon_initial_members <EOL> mon_create ( args ) <EOL> mon_in_quorum = set ( [ ] ) <EOL> mon_members = set ( [ host for host in mon_initial_members ] ) <EOL> for host in mon_initial_members : <EOL> mon_name = '<STR_LIT>' % host <EOL> LOG . info ( '<STR_LIT>' , mon_name ) <EOL> sleeps = [ <NUM_LIT:20> , <NUM_LIT:20> , <NUM_LIT:15> , <NUM_LIT:10> , <NUM_LIT:10> , <NUM_LIT:5> ] <EOL> tries = <NUM_LIT:5> <EOL> rlogger = logging . getLogger ( host ) <EOL> distro = hosts . get ( <EOL> host , <EOL> username = args . username , <EOL> callbacks = [ packages . ceph_is_installed ] <EOL> ) <EOL> while tries : <EOL> status = mon_status_check ( distro . conn , rlogger , host , args ) <EOL> has_reached_quorum = status . get ( '<STR_LIT:state>' , '<STR_LIT>' ) in [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> if not has_reached_quorum : <EOL> LOG . warning ( '<STR_LIT>' % ( mon_name , tries ) ) <EOL> tries -= <NUM_LIT:1> <EOL> sleep_seconds = sleeps . pop ( ) <EOL> LOG . warning ( '<STR_LIT>' , sleep_seconds ) <EOL> time . sleep ( sleep_seconds ) <EOL> else : <EOL> mon_in_quorum . add ( host ) <EOL> LOG . info ( '<STR_LIT>' , mon_name ) <EOL> break <EOL> distro . conn . exit ( ) <EOL> if mon_in_quorum == mon_members : <EOL> LOG . info ( '<STR_LIT>' ) <EOL> LOG . info ( '<STR_LIT>' ) <EOL> gatherkeys . gatherkeys ( args ) <EOL> else : <EOL> LOG . error ( '<STR_LIT>' ) <EOL> for host in mon_members - mon_in_quorum : <EOL> LOG . error ( '<STR_LIT:%s>' , host ) <EOL> raise SystemExit ( '<STR_LIT>' ) <EOL> def mon ( args ) : <EOL> if args . subcommand == '<STR_LIT>' : <EOL> mon_create ( args ) <EOL> elif args . subcommand == '<STR_LIT>' : <EOL> mon_add ( args ) <EOL> elif args . subcommand == '<STR_LIT>' : <EOL> mon_destroy ( args ) <EOL> elif args . subcommand == '<STR_LIT>' : <EOL> mon_create_initial ( args ) <EOL> else : <EOL> LOG . error ( '<STR_LIT>' , args . subcommand ) <EOL> @ priority ( <NUM_LIT:30> ) <EOL> def make ( parser ) : <EOL> """<STR_LIT>""" <EOL> parser . formatter_class = ToggleRawTextHelpFormatter <EOL> mon_parser = parser . add_subparsers ( dest = '<STR_LIT>' ) <EOL> mon_add = mon_parser . add_parser ( <EOL> '<STR_LIT>' , <EOL> help = ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> ) <EOL> mon_add . add_argument ( <EOL> '<STR_LIT>' , <EOL> nargs = '<STR_LIT:?>' , <EOL> ) <EOL> mon_add . add_argument ( <EOL> '<STR_LIT>' , <EOL> nargs = <NUM_LIT:1> , <EOL> ) <EOL> mon_create = mon_parser . add_parser ( <EOL> '<STR_LIT>' , <EOL> help = ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> ) <EOL> mon_create . add_argument ( <EOL> '<STR_LIT>' , <EOL> nargs = '<STR_LIT:?>' , <EOL> help = '<STR_LIT>' , <EOL> ) <EOL> mon_create . add_argument ( <EOL> '<STR_LIT>' , <EOL> nargs = '<STR_LIT:*>' , <EOL> ) <EOL> mon_create_initial = mon_parser . add_parser ( <EOL> '<STR_LIT>' , <EOL> help = ( '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> ) <EOL> mon_create_initial . add_argument ( <EOL> '<STR_LIT>' , <EOL> nargs = '<STR_LIT:?>' , <EOL> help = '<STR_LIT>' , <EOL> ) <EOL> mon_destroy = mon_parser . add_parser ( <EOL> '<STR_LIT>' , <EOL> help = '<STR_LIT>' <EOL> ) <EOL> mon_destroy . add_argument ( <EOL> '<STR_LIT>' , <EOL> nargs = '<STR_LIT:+>' , <EOL> ) <EOL> parser . set_defaults ( <EOL> func = mon , <EOL> ) <EOL> def get_mon_initial_members ( args , error_on_empty = False , _cfg = None ) : <EOL> """<STR_LIT>""" <EOL> if _cfg : <EOL> cfg = _cfg <EOL> else : <EOL> cfg = conf . ceph . load ( args ) <EOL> mon_initial_members = cfg . safe_get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if not mon_initial_members : <EOL> if error_on_empty : <EOL> raise exc . NeedHostError ( <EOL> '<STR_LIT>' <EOL> ) <EOL> else : <EOL> mon_initial_members = re . split ( r'<STR_LIT>' , mon_initial_members ) <EOL> return mon_initial_members <EOL> def is_running ( conn , args ) : <EOL> """<STR_LIT>""" <EOL> stdout , stderr , _ = remoto . process . check ( <EOL> conn , <EOL> args <EOL> ) <EOL> result_string = '<STR_LIT:U+0020>' . join ( stdout ) <EOL> for run_check in [ '<STR_LIT>' , '<STR_LIT>' ] : <EOL> if run_check in result_string : <EOL> return True <EOL> return False </s>
