def wmon(w): cpid, _ = self.monitor(w, argv, cpids) time.sleep(1) self.lock.acquire() for cpid in cpids: os.kill(cpid, signal.SIGKILL) self.lock.release() finalize(exval=1)
def wmon(w): cpid, _ = self.monitor(w, argv, cpids, agents) time.sleep(1) self.lock.acquire() for cpid in cpids: os.kill(cpid, signal.SIGKILL) self.lock.release() finalize(exval=1)
def wmon(w): cpid, _ = self.monitor(w, argv, cpids, slave_vol, slave_host, master, suuid, slavenodes) time.sleep(1) self.lock.acquire() for cpid in cpids: errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH]) self.lock.release() finalize(exval=1)
def errfail(self): """fail nicely if child did not terminate with success""" filling = "" if self.elines: filling = ", saying:" logging.error("""command "%s" returned with %s%s""" % (" ".join(self.args), repr(self.returncode), filling)) for l in self.elines: for ll in l.rstrip().split("\n"): logging.error(self.args[0] + "> " + ll.rstrip()) syncdutils.finalize(exval=1)
def errfail(self): """fail nicely if child did not terminate with success""" filling = None if self.elines: filling = ", saying:" logging.error("""command "%s" returned with %d%s""" % \ (" ".join(self.args), self.returncode, filling)) for l in self.elines: for ll in l.rstrip().split("\n"): logging.error(self.args[0] + "> " + ll.rstrip()) syncdutils.finalize(exval=1)
def wmon(w): cpid, _ = self.monitor(w, argv, cpids, agents, slave_vol, slave_host, master) time.sleep(1) self.lock.acquire() for cpid in cpids: os.kill(cpid, signal.SIGKILL) for apid in agents: os.kill(apid, signal.SIGKILL) self.lock.release() finalize(exval=1)
def main(): signal.signal(signal.SIGTERM, lambda *a: finalize(*a, **{'exval': 1})) GLogger.setup() excont = FreeObject(exval = 0) try: try: main_i() except: log_raise_exception(excont) finally: finalize(exval = excont.exval)
def wmon(w): cpid, _ = self.monitor(w, argv, cpids, agents, slave_vol, slave_host, master) time.sleep(1) self.lock.acquire() for cpid in cpids: errno_wrap(os.kill, [cpid, signal.SIGKILL], [ESRCH]) for apid in agents: errno_wrap(os.kill, [apid, signal.SIGKILL], [ESRCH]) self.lock.release() finalize(exval=1)
def main(): signal.signal(signal.SIGTERM, lambda *a: finalize(*a, **{'exval': 1})) GLogger.setup() excont = FreeObject(exval=0) try: try: main_i() except: log_raise_exception(excont) finally: finalize(exval=excont.exval)
def wmon(w): cpid, _ = self.monitor(w, argv, cpids, agents, slave_vol, slave_host) time.sleep(1) self.lock.acquire() for cpid in cpids: os.kill(cpid, signal.SIGKILL) for apid in agents: os.kill(apid, signal.SIGKILL) self.lock.release() finalize(exval=1)
def main(): """main routine, signal/exception handling boilerplates""" signal.signal(signal.SIGTERM, lambda *a: finalize(*a, **{'exval': 1})) GLogger.setup() excont = FreeObject(exval=0) try: try: main_i() except: log_raise_exception(excont) finally: finalize(exval=excont.exval)
def main(): """main routine, signal/exception handling boilerplates""" signal.signal(signal.SIGTERM, lambda *a: finalize(*a, **{'exval': 1})) GLogger.setup() excont = FreeObject(exval = 0) try: try: main_i() except: log_raise_exception(excont) finally: finalize(exval = excont.exval)
def main(): """main routine, signal/exception handling boilerplates""" gconf.starttime = time.time() set_term_handler() GLogger.setup() excont = FreeObject(exval=0) try: try: main_i() except: log_raise_exception(excont) finally: finalize(exval=excont.exval)
def main(): """main routine, signal/exception handling boilerplates""" gconf.starttime = time.time() set_term_handler() GLogger.setup() excont = FreeObject(exval = 0) try: try: main_i() except: log_raise_exception(excont) finally: finalize(exval = excont.exval)
def service_loop(self): """start a RePCe server serving self's server stop servicing if a timeout is configured and got no keep-alime in that inteval """ if boolify(gconf.use_rsync_xattrs) and not privileged(): raise GsyncdError( "using rsync for extended attributes is not supported") repce = RepceServer( self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread(target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info( "connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select((), (), ())
def service_loop(self): """start a RePCe server serving self's server stop servicing if a timeout is configured and got no keep-alime in that inteval """ if boolify(gconf.use_rsync_xattrs) and not privileged(): raise GsyncdError( "using rsync for extended attributes is not supported") repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread( target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info( "connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select((), (), ())
def __init__(self, obj, fd_tup): (inf, ouf, rw, ww) = fd_tup.split(',') repce = RepceServer(obj, int(inf), int(ouf), 1) t = syncdutils.Thread( target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info('Agent listining...') select((), (), ())
def __init__(self, obj, fd_tup): (inf, ouf, rw, ww) = fd_tup.split(',') repce = RepceServer(obj, int(inf), int(ouf), 1) t = syncdutils.Thread(target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info('Agent listining...') select((), (), ())
def service_loop(self): repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread(target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info("connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select.select((), (), ())
def service_loop(self): """start a RePCe server serving self's server stop servicing if a timeout is configured and got no keep-alime in that inteval """ repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread(target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info("connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select((), (), ())
def service_loop(self): """start a RePCe server serving self's server stop servicing if a timeout is configured and got no keep-alime in that inteval """ repce = RepceServer(self.server, sys.stdin, sys.stdout, int(gconf.sync_jobs)) t = syncdutils.Thread( target=lambda: (repce.service_loop(), syncdutils.finalize())) t.start() logging.info("slave listening") if gconf.timeout and int(gconf.timeout) > 0: while True: lp = self.server.last_keep_alive time.sleep(int(gconf.timeout)) if lp == self.server.last_keep_alive: logging.info( "connection inactive for %d seconds, stopping" % int(gconf.timeout)) break else: select((), (), ())
def errfail(self): """fail nicely if child did not terminate with success""" self.errlog() syncdutils.finalize(exval=1)
def inhibit(self, *a): """inhibit a gluster filesystem Mount glusterfs over a temporary mountpoint, change into the mount, and lazy unmount the filesystem. """ mpi, mpo = os.pipe() mh = Popen.fork() if mh: os.close(mpi) fcntl.fcntl(mpo, fcntl.F_SETFD, fcntl.FD_CLOEXEC) d = None margv = self.make_mount_argv(*a) if self.mntpt: # mntpt is determined pre-mount d = self.mntpt os.write(mpo, d + '\0') po = Popen(margv, **self.mountkw) self.handle_mounter(po) po.terminate_geterr() logging.debug('auxiliary glusterfs mount in place') if not d: # mntpt is determined during mount d = self.mntpt os.write(mpo, d + '\0') os.write(mpo, 'M') t = syncdutils.Thread(target=lambda: os.chdir(d)) t.start() tlim = gconf.starttime + int(gconf.connection_timeout) while True: if not t.isAlive(): break if time.time() >= tlim: syncdutils.finalize(exval=1) time.sleep(1) os.close(mpo) _, rv = syncdutils.waitpid(mh, 0) if rv: rv = (os.WIFEXITED(rv) and os.WEXITSTATUS(rv) or 0) - \ (os.WIFSIGNALED(rv) and os.WTERMSIG(rv) or 0) logging.warn('stale mount possibly left behind on ' + d) raise GsyncdError("cleaning up temp mountpoint %s failed with status %d" % \ (d, rv)) else: rv = 0 try: os.setsid() os.close(mpo) mntdata = '' while True: c = os.read(mpi, 1) if not c: break mntdata += c if mntdata: mounted = False if mntdata[-1] == 'M': mntdata = mntdata[:-1] assert (mntdata) mounted = True assert (mntdata[-1] == '\0') mntpt = mntdata[:-1] assert (mntpt) if mounted: po = self.umount_l(mntpt) po.terminate_geterr(fail_on_err=False) if po.returncode != 0: po.errlog() rv = po.returncode self.cleanup_mntpt(mntpt) except: logging.exception('mount cleanup failure:') rv = 200 os._exit(rv) logging.debug('auxiliary glusterfs mount prepared')
def main(): rconf.starttime = time.time() # If old Glusterd sends commands in old format, below function # converts the sys.argv to new format. This conversion is added # temporarily for backward compatibility. This can be removed # once integrated with Glusterd2 # This modifies sys.argv globally, so rest of the code works as usual argsupgrade.upgrade() # Default argparse version handler prints to stderr, which is fixed in # 3.x series but not in 2.x, using custom parser to fix this issue if "--version" in sys.argv: print(GSYNCD_VERSION) sys.exit(0) parser = ArgumentParser() parser.add_argument("--inet6", action="store_true") sp = parser.add_subparsers(dest="subcmd") # Monitor Status File update p = sp.add_parser("monitor-status") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("status", help="Update Monitor Status") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Monitor p = sp.add_parser("monitor") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--pause-on-start", action="store_true", help="Start with Paused state") p.add_argument("--local-node-id", help="Local Node ID") p.add_argument("--debug", action="store_true") p.add_argument("--use-gconf-volinfo", action="store_true") # Worker p = sp.add_parser("worker") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("--local-path", help="Local Brick Path") p.add_argument("--feedback-fd", type=int, help="feedback fd between monitor and worker") p.add_argument("--local-node", help="Local master node") p.add_argument("--local-node-id", help="Local Node ID") p.add_argument("--rpc-fd", help="Read and Write fds for worker-agent communication") p.add_argument("--subvol-num", type=int, help="Subvolume number") p.add_argument("--is-hottier", action="store_true", help="Is this brick part of hot tier") p.add_argument("--resource-remote", help="Remote node to connect to Slave Volume") p.add_argument("--resource-remote-id", help="Remote node ID to connect to Slave Volume") p.add_argument("--slave-id", help="Slave Volume ID") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Agent p = sp.add_parser("agent") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("--local-path", help="Local brick path") p.add_argument("--local-node", help="Local master node") p.add_argument("--local-node-id", help="Local Node ID") p.add_argument("--slave-id", help="Slave Volume ID") p.add_argument("--rpc-fd", help="Read and Write fds for worker-agent communication") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Slave p = sp.add_parser("slave") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("--session-owner") p.add_argument("--master-brick", help="Master brick which is connected to the Slave") p.add_argument("--master-node", help="Master node which is connected to the Slave") p.add_argument("--master-node-id", help="Master node ID which is connected to the Slave") p.add_argument("--local-node", help="Local Slave node") p.add_argument("--local-node-id", help="Local Slave ID") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # All configurations which are configured via "slave-" options # DO NOT add default values for these configurations, default values # will be picked from template config file p.add_argument("--slave-timeout", type=int, help="Timeout to end gsyncd at Slave side") p.add_argument("--use-rsync-xattrs", action="store_true") p.add_argument("--slave-log-level", help="Slave Gsyncd Log level") p.add_argument("--slave-gluster-log-level", help="Slave Gluster mount Log level") p.add_argument("--slave-gluster-command-dir", help="Directory where Gluster binaries exist on slave") p.add_argument("--slave-access-mount", action="store_true", help="Do not lazy umount the slave volume") # Status p = sp.add_parser("status") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--local-path", help="Local Brick Path") p.add_argument("--debug", action="store_true") p.add_argument("--json", action="store_true") # Config-check p = sp.add_parser("config-check") p.add_argument("name", help="Config Name") p.add_argument("--value", help="Config Value") p.add_argument("--debug", action="store_true") # Config-get p = sp.add_parser("config-get") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("--name", help="Config Name") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") p.add_argument("--show-defaults", action="store_true") p.add_argument("--only-value", action="store_true") p.add_argument("--use-underscore", action="store_true") p.add_argument("--json", action="store_true") # Config-set p = sp.add_parser("config-set") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("-n", "--name", help="Config Name") p.add_argument("-v", "--value", help="Config Value") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Config-reset p = sp.add_parser("config-reset") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("name", help="Config Name") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # voluuidget p = sp.add_parser("voluuidget") p.add_argument("host", help="Hostname") p.add_argument("volname", help="Volume Name") p.add_argument("--debug", action="store_true") # Delete p = sp.add_parser("delete") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("-c", "--config-file", help="Config File") p.add_argument('--path', dest='paths', action="append") p.add_argument("--reset-sync-time", action="store_true", help="Reset Sync Time") p.add_argument("--debug", action="store_true") # Parse arguments args = parser.parse_args() # Extra template values, All arguments are already part of template # variables, use this for adding extra variables extra_tmpl_args = {} # Add First/Primary Slave host, user and volume if getattr(args, "slave", None) is not None: hostdata, slavevol = args.slave.split("::") hostdata = hostdata.split("@") slavehost = hostdata[-1] slaveuser = "******" if len(hostdata) == 2: slaveuser = hostdata[0] extra_tmpl_args["primary_slave_host"] = slavehost extra_tmpl_args["slaveuser"] = slaveuser extra_tmpl_args["slavevol"] = slavevol # Add Bricks encoded path if getattr(args, "local_path", None) is not None: extra_tmpl_args["local_id"] = escape(args.local_path) # Add Master Bricks encoded path(For Slave) if getattr(args, "master_brick", None) is not None: extra_tmpl_args["master_brick_id"] = escape(args.master_brick) # Load configurations config_file = getattr(args, "config_file", None) # Subcmd accepts config file argument but not passed # Set default path for config file in that case # If an subcmd accepts config file then it also accepts # master and Slave arguments. if config_file is None and hasattr(args, "config_file"): config_file = "%s/geo-replication/%s_%s_%s/gsyncd.conf" % ( GLUSTERD_WORKDIR, args.master, extra_tmpl_args["primary_slave_host"], extra_tmpl_args["slavevol"]) # If Config file path not exists, log error and continue using default conf config_file_error_msg = None if config_file is not None and not os.path.exists(config_file): # Logging not yet initialized, create the error message to # log later and reset the config_file to None config_file_error_msg = lf( "Session config file not exists, using the default config", path=config_file) config_file = None rconf.config_file = config_file # Override gconf values from argument values only if it is slave gsyncd override_from_args = False if args.subcmd == "slave": override_from_args = True if args.subcmd == "monitor": ret = gconf.is_config_file_old(config_file, args.master, extra_tmpl_args["slavevol"]) if ret is not None: gconf.config_upgrade(config_file, ret) # Load Config file gconf.load(GLUSTERFS_CONFDIR + "/gsyncd.conf", config_file, vars(args), extra_tmpl_args, override_from_args) # Default label to print in log file label = args.subcmd if args.subcmd in ("worker", "agent"): # If Worker or agent, then add brick path also to label label = "%s %s" % (args.subcmd, args.local_path) elif args.subcmd == "slave": # If Slave add Master node and Brick details label = "%s %s%s" % (args.subcmd, args.master_node, args.master_brick) # Setup Logger # Default log file log_file = gconf.get("cli-log-file") log_level = gconf.get("cli-log-level") if getattr(args, "master", None) is not None and \ getattr(args, "slave", None) is not None: log_file = gconf.get("log-file") log_level = gconf.get("log-level") # Use different log file location for Slave log file if args.subcmd == "slave": log_file = gconf.get("slave-log-file") log_level = gconf.get("slave-log-level") if args.debug: log_file = "-" log_level = "DEBUG" # Create Logdir if not exists try: if log_file != "-": os.mkdir(os.path.dirname(log_file)) except OSError as e: if e.errno != EEXIST: raise setup_logging(log_file=log_file, level=log_level, label=label) if config_file_error_msg is not None: logging.warn(config_file_error_msg) # Log message for loaded config file if config_file is not None: logging.info(lf("Using session config file", path=config_file)) set_term_handler() excont = FreeObject(exval=0) # Gets the function name based on the input argument. For example # if subcommand passed as argument is monitor then it looks for # function with name "subcmd_monitor" in subcmds file func = getattr(subcmds, "subcmd_" + args.subcmd.replace("-", "_"), None) try: try: if func is not None: rconf.args = args func(args) except: log_raise_exception(excont) finally: finalize(exval=excont.exval)
def main(): rconf.starttime = time.time() # If old Glusterd sends commands in old format, below function # converts the sys.argv to new format. This conversion is added # temporarily for backward compatibility. This can be removed # once integrated with Glusterd2 # This modifies sys.argv globally, so rest of the code works as usual argsupgrade.upgrade() # Default argparse version handler prints to stderr, which is fixed in # 3.x series but not in 2.x, using custom parser to fix this issue if "--version" in sys.argv: print(GSYNCD_VERSION) sys.exit(0) parser = ArgumentParser() parser.add_argument("--inet6", action="store_true") sp = parser.add_subparsers(dest="subcmd") # Monitor Status File update p = sp.add_parser("monitor-status") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("status", help="Update Monitor Status") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Monitor p = sp.add_parser("monitor") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--pause-on-start", action="store_true", help="Start with Paused state") p.add_argument("--local-node-id", help="Local Node ID") p.add_argument("--debug", action="store_true") p.add_argument("--use-gconf-volinfo", action="store_true") # Worker p = sp.add_parser("worker") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("--local-path", help="Local Brick Path") p.add_argument("--feedback-fd", type=int, help="feedback fd between monitor and worker") p.add_argument("--local-node", help="Local master node") p.add_argument("--local-node-id", help="Local Node ID") p.add_argument("--rpc-fd", help="Read and Write fds for worker-agent communication") p.add_argument("--subvol-num", type=int, help="Subvolume number") p.add_argument("--is-hottier", action="store_true", help="Is this brick part of hot tier") p.add_argument("--resource-remote", help="Remote node to connect to Slave Volume") p.add_argument("--resource-remote-id", help="Remote node ID to connect to Slave Volume") p.add_argument("--slave-id", help="Slave Volume ID") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Agent p = sp.add_parser("agent") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("--local-path", help="Local brick path") p.add_argument("--local-node", help="Local master node") p.add_argument("--local-node-id", help="Local Node ID") p.add_argument("--slave-id", help="Slave Volume ID") p.add_argument("--rpc-fd", help="Read and Write fds for worker-agent communication") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Slave p = sp.add_parser("slave") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave details user@host::vol format") p.add_argument("--session-owner") p.add_argument("--master-brick", help="Master brick which is connected to the Slave") p.add_argument("--master-node", help="Master node which is connected to the Slave") p.add_argument("--master-node-id", help="Master node ID which is connected to the Slave") p.add_argument("--local-node", help="Local Slave node") p.add_argument("--local-node-id", help="Local Slave ID") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # All configurations which are configured via "slave-" options # DO NOT add default values for these configurations, default values # will be picked from template config file p.add_argument("--slave-timeout", type=int, help="Timeout to end gsyncd at Slave side") p.add_argument("--use-rsync-xattrs", action="store_true") p.add_argument("--slave-log-level", help="Slave Gsyncd Log level") p.add_argument("--slave-gluster-log-level", help="Slave Gluster mount Log level") p.add_argument("--slave-gluster-command-dir", help="Directory where Gluster binaries exist on slave") p.add_argument("--slave-access-mount", action="store_true", help="Do not lazy umount the slave volume") # Status p = sp.add_parser("status") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--local-path", help="Local Brick Path") p.add_argument("--debug", action="store_true") p.add_argument("--json", action="store_true") # Config-check p = sp.add_parser("config-check") p.add_argument("name", help="Config Name") p.add_argument("--value", help="Config Value") p.add_argument("--debug", action="store_true") # Config-get p = sp.add_parser("config-get") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("--name", help="Config Name") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") p.add_argument("--show-defaults", action="store_true") p.add_argument("--only-value", action="store_true") p.add_argument("--use-underscore", action="store_true") p.add_argument("--json", action="store_true") # Config-set p = sp.add_parser("config-set") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("-n", "--name", help="Config Name") p.add_argument("-v", "--value", help="Config Value") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # Config-reset p = sp.add_parser("config-reset") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("name", help="Config Name") p.add_argument("-c", "--config-file", help="Config File") p.add_argument("--debug", action="store_true") # voluuidget p = sp.add_parser("voluuidget") p.add_argument("host", help="Hostname") p.add_argument("volname", help="Volume Name") p.add_argument("--debug", action="store_true") # Delete p = sp.add_parser("delete") p.add_argument("master", help="Master Volume Name") p.add_argument("slave", help="Slave") p.add_argument("-c", "--config-file", help="Config File") p.add_argument('--path', dest='paths', action="append") p.add_argument("--reset-sync-time", action="store_true", help="Reset Sync Time") p.add_argument("--debug", action="store_true") # Parse arguments args = parser.parse_args() # Extra template values, All arguments are already part of template # variables, use this for adding extra variables extra_tmpl_args = {} # Add First/Primary Slave host, user and volume if getattr(args, "slave", None) is not None: hostdata, slavevol = args.slave.split("::") hostdata = hostdata.split("@") slavehost = hostdata[-1] slaveuser = "******" if len(hostdata) == 2: slaveuser = hostdata[0] extra_tmpl_args["primary_slave_host"] = slavehost extra_tmpl_args["slaveuser"] = slaveuser extra_tmpl_args["slavevol"] = slavevol # Add Bricks encoded path if getattr(args, "local_path", None) is not None: extra_tmpl_args["local_id"] = escape(args.local_path) # Add Master Bricks encoded path(For Slave) if getattr(args, "master_brick", None) is not None: extra_tmpl_args["master_brick_id"] = escape(args.master_brick) # Load configurations config_file = getattr(args, "config_file", None) # Subcmd accepts config file argument but not passed # Set default path for config file in that case # If an subcmd accepts config file then it also accepts # master and Slave arguments. if config_file is None and hasattr(args, "config_file"): config_file = "%s/geo-replication/%s_%s_%s/gsyncd.conf" % ( GLUSTERD_WORKDIR, args.master, extra_tmpl_args["primary_slave_host"], extra_tmpl_args["slavevol"]) # If Config file path not exists, log error and continue using default conf config_file_error_msg = None if config_file is not None and not os.path.exists(config_file): # Logging not yet initialized, create the error message to # log later and reset the config_file to None config_file_error_msg = lf( "Session config file not exists, using the default config", path=config_file) config_file = None rconf.config_file = config_file # Override gconf values from argument values only if it is slave gsyncd override_from_args = False if args.subcmd == "slave": override_from_args = True # Load Config file gconf.load(GLUSTERFS_CONFDIR + "/gsyncd.conf", config_file, vars(args), extra_tmpl_args, override_from_args) # Default label to print in log file label = args.subcmd if args.subcmd in ("worker", "agent"): # If Worker or agent, then add brick path also to label label = "%s %s" % (args.subcmd, args.local_path) elif args.subcmd == "slave": # If Slave add Master node and Brick details label = "%s %s%s" % (args.subcmd, args.master_node, args.master_brick) # Setup Logger # Default log file log_file = gconf.get("cli-log-file") log_level = gconf.get("cli-log-level") if getattr(args, "master", None) is not None and \ getattr(args, "slave", None) is not None: log_file = gconf.get("log-file") log_level = gconf.get("log-level") # Use different log file location for Slave log file if args.subcmd == "slave": log_file = gconf.get("slave-log-file") log_level = gconf.get("slave-log-level") if args.debug: log_file = "-" log_level = "DEBUG" # Create Logdir if not exists try: if log_file != "-": os.mkdir(os.path.dirname(log_file)) except OSError as e: if e.errno != EEXIST: raise setup_logging( log_file=log_file, level=log_level, label=label ) if config_file_error_msg is not None: logging.warn(config_file_error_msg) # Log message for loaded config file if config_file is not None: logging.info(lf("Using session config file", path=config_file)) set_term_handler() excont = FreeObject(exval=0) # Gets the function name based on the input argument. For example # if subcommand passed as argument is monitor then it looks for # function with name "subcmd_monitor" in subcmds file func = getattr(subcmds, "subcmd_" + args.subcmd.replace("-", "_"), None) try: try: if func is not None: rconf.args = args func(args) except: log_raise_exception(excont) finally: finalize(exval=excont.exval)
def inhibit(self, *a): """inhibit a gluster filesystem Mount glusterfs over a temporary mountpoint, change into the mount, and lazy unmount the filesystem. """ mpi, mpo = os.pipe() mh = Popen.fork() if mh: os.close(mpi) fcntl.fcntl(mpo, fcntl.F_SETFD, fcntl.FD_CLOEXEC) d = None margv = self.make_mount_argv(*a) if self.mntpt: # mntpt is determined pre-mount d = self.mntpt os.write(mpo, d + '\0') po = Popen(margv, **self.mountkw) self.handle_mounter(po) po.terminate_geterr() logging.debug('auxiliary glusterfs mount in place') if not d: # mntpt is determined during mount d = self.mntpt os.write(mpo, d + '\0') os.write(mpo, 'M') t = syncdutils.Thread(target=lambda: os.chdir(d)) t.start() tlim = gconf.starttime + int(gconf.connection_timeout) while True: if not t.isAlive(): break if time.time() >= tlim: syncdutils.finalize(exval = 1) time.sleep(1) os.close(mpo) _, rv = syncdutils.waitpid(mh, 0) if rv: rv = (os.WIFEXITED(rv) and os.WEXITSTATUS(rv) or 0) - \ (os.WIFSIGNALED(rv) and os.WTERMSIG(rv) or 0) logging.warn('stale mount possibly left behind on ' + d) raise GsyncdError("cleaning up temp mountpoint %s failed with status %d" % \ (d, rv)) else: rv = 0 try: os.setsid() os.close(mpo) mntdata = '' while True: c = os.read(mpi, 1) if not c: break mntdata += c if mntdata: mounted = False if mntdata[-1] == 'M': mntdata = mntdata[:-1] assert(mntdata) mounted = True assert(mntdata[-1] == '\0') mntpt = mntdata[:-1] assert(mntpt) if mounted: po = self.umount_l(mntpt) po.terminate_geterr(fail_on_err = False) if po.returncode != 0: po.errlog() rv = po.returncode self.cleanup_mntpt(mntpt) except: logging.exception('mount cleanup failure:') rv = 200 os._exit(rv) logging.debug('auxiliary glusterfs mount prepared')
def errfail(self): """fail nicely if child did not terminate with success""" self.errlog() syncdutils.finalize(exval = 1)