def mount(parent, device): mountpoint, options = query_mount(parent, device) if not mountpoint: return None command = ('mount', '-t', 'ocfs2', device, mountpoint) if options: command = list(command) command[1:1] = ('-o', options) p = Process(command, 'Mount', 'Mounting...', parent, spin_now=True) success, output, killed = p.reap() if not success: if killed: error_box( parent, 'mount died unexpectedly! Your system is ' 'probably in an inconsistent state. You ' 'should reboot at the earliest opportunity') else: error_box(parent, '%s: Could not mount %s' % (output, device)) return None else: return mountpoint
def mount(parent, device): mountpoint, options = query_mount(parent, device) if not mountpoint: return None command = ('mount', '-t', 'ocfs2', device, mountpoint) if options: command = list(command) command[1:1] = ('-o', options) p = Process(command, 'Mount', 'Mounting...', parent, spin_now=True) success, output, killed = p.reap() if not success: if killed: error_box(parent, 'mount died unexpectedly! Your system is ' 'probably in an inconsistent state. You ' 'should reboot at the earliest opportunity') else: error_box(parent, '%s: Could not mount %s' % (output, device)) return None else: return mountpoint
def apply_changes(self): success = False for name, ip_address, ip_port in self.new_node_attrs(): success, output, k = o2cb_ctl.add_node(name, self.cluster_name, ip_address, ip_port, self) if not success: error_box(self, '%s\nCould not add node %s' % (output, name)) break self.load_cluster_state() return success
def unmount(parent, device, mountpoint): command = ('umount', mountpoint) p = Process(command, 'Unmount', 'Unmounting...', parent) success, output, killed = p.reap() if not success: if killed: error_box(parent, 'umount died unexpectedly! Your system is ' 'probably in an inconsistent state. You ' 'should reboot at the earliest opportunity') else: error_box(parent, '%s: Could not unmount %s mounted on %s' % (output, device, mountpoint))
def node_config(parent=None): success, output, k = o2cb_ctl.init_status(None, parent) if not success: msg = ('Could not query the state of the cluster stack.' 'This must be resolved before any OCFS2 filesystem' 'can be mounted.') info = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_CLOSE, message_format=msg) info.run() info.destroy() return if (output.find('Not loaded') != -1) or (output.find('Not mounted') != -1): success, output, k = o2cb_ctl.init_load(parent) if success: msg_type = gtk.MESSAGE_INFO msg = ('The cluster stack has been started. It needs to be ' 'running for any clustering functionality to happen. ' 'Please run "%s enable" to have it started upon bootup.' % o2cb_ctl.O2CB_INIT) else: msg_type = gtk.MESSAGE_WARNING msg = ('Could not start cluster stack. This must be resolved ' 'before any OCFS2 filesystem can be mounted') info = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=msg_type, buttons=gtk.BUTTONS_CLOSE, message_format=msg) info.run() info.destroy() if not success: return try: cluster_name = o2cb_ctl.get_active_cluster_name(parent) except o2cb_ctl.CtlError, e: error_box(parent, str(e)) return
def add_node(self, b): if len(self.store) == o2cb.O2NM_MAX_NODES: error_box(self, 'Cannot have more than %d nodes in a cluster' % o2cb.O2NM_MAX_NODES) return node_attrs = self.node_query(title='Add Node') if node_attrs is None: return self.new_nodes += 1 name, ip_addr, ip_port = node_attrs iter = self.store.append((True, name, -self.new_nodes, ip_addr, ip_port)) self.sel.select_iter(iter) self.tv.scroll_to_cell(self.store.get_path(iter)) self.can_apply(True)
def add_node(self, b): if len(self.store) == o2cb.O2NM_MAX_NODES: error_box( self, 'Cannot have more than %d nodes in a cluster' % o2cb.O2NM_MAX_NODES) return node_attrs = self.node_query(title='Add Node') if node_attrs is None: return self.new_nodes += 1 name, ip_addr, ip_port = node_attrs iter = self.store.append( (True, name, -self.new_nodes, ip_addr, ip_port)) self.sel.select_iter(iter) self.tv.scroll_to_cell(self.store.get_path(iter)) self.can_apply(True)
info.run() info.destroy() if not success: return try: cluster_name = o2cb_ctl.get_active_cluster_name(parent) except o2cb_ctl.CtlError, e: error_box(parent, str(e)) return try: conf = ClusterConfig(cluster_name, parent) except ConfigError, e: error_box(parent, '%s: Could not query cluster configuration' % str(e)) return conf.run() conf.destroy() success, output, k = o2cb_ctl.init_status(cluster_name, parent) if not success: msg = ('Could not query the state of the cluster.' 'This must be resolved before any OCFS2 filesystem' 'can be mounted.') info = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_CLOSE, message_format=msg)
def format_partition(parent, device): partitions = [] def add_partition(device, fstype): partitions.append((device, fstype)) partition_list(add_partition, unmounted=True) if not partitions: error_box(parent, 'No unmounted partitions') return False def sort_partition(x, y): return cmp(x[0], y[0]) partitions.sort(sort_partition) dialog = Dialog(parent=parent, title='Format', buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=5, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) widgets = [] for row, widget_type in enumerate(entries): widget = widget_type() label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') label.set_mnemonic_widget(widget) set_props(label, xalign=0.0) table.attach(label, 0, 1, row, row + 1) if widget_type == Device: widget.fill(partitions, device) if isinstance(widget, gtk.Entry): widget.set_activates_default(True) if isinstance(widget, gtk.SpinButton): attach_widget = gtk.HBox() attach_widget.pack_start(widget, expand=False, fill=False) else: attach_widget = widget table.attach(attach_widget, 1, 2, row, row + 1) widgets.append(widget) widgets[0].grab_focus() dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return False dev = widgets[0].get_device() msg = 'Are you sure you want to format %s?' % dev ask = gtk.MessageDialog(parent=dialog, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=msg) if ask.run() == gtk.RESPONSE_YES: break else: ask.destroy() command = list(base_command) for widget in widgets[1:]: arg = widget.get_arg() if arg: command.extend(arg) command.append(dev) dialog.destroy() mkfs = Process(command, 'Format', 'Formatting...', parent, spin_now=True) success, output, k = mkfs.reap() if not success: error_box(parent, 'Format error: %s' % output) return False return True
def push_config(parent=None): try: cluster_name, hosts = get_hosts(parent) except o2cb_ctl.CtlError, e: error_box(parent, str(e)) return
def node_query(self, title='Node Attributes', defaults=None, editing=False): existing_names = {} existing_ip_addrs = {} for row in self.store: name = row[COLUMN_NAME] ip_addr = row[COLUMN_IP_ADDRESS] if not (editing and name == defaults[COLUMN_NAME]): existing_names[name] = 1 if not (editing and ip_addr == defaults[COLUMN_IP_ADDRESS]): existing_ip_addrs[ip_addr] = name dialog = Dialog(parent=self, title=title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=4, columns=2) set_props(table, row_spacing=4, column_spacing=4, border_width=4, parent=dialog.vbox) widgets = [] for row, field in enumerate(fields): if field.widget_type is None: widgets.append(None) continue label = gtk.Label(field.title + ':') set_props(label, xalign=1.0) table.attach(label, 0, 1, row, row + 1) widget = field.widget_type() table.attach(widget, 1, 2, row, row + 1) if field.column == COLUMN_NAME: widget.set_max_length(o2cb.O2NM_MAX_NAME_LEN) elif field.column == COLUMN_IP_PORT: widget.set_numeric(True) adjustment = gtk.Adjustment(PORT_DEFAULT, PORT_MINIMUM, PORT_MAXIMUM, 1, 100) widget.set_adjustment(adjustment) widget.set_value(PORT_DEFAULT) widgets.append(widget) if defaults: for w, d in zip(widgets, defaults): if w and d: w.set_text(d) dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return None ip_port = widgets[COLUMN_IP_PORT].get_text() name = widgets[COLUMN_NAME].get_text() if not name: error_box(dialog, 'Node name not specified') continue try: ip_addr = widgets[COLUMN_IP_ADDRESS].get_text() except (IPMissing, IPError), msg: error_box(dialog, msg[0]) continue if name in existing_names: error_box(dialog, 'Node %s already exists in the configuration' % name) elif ip_addr in existing_ip_addrs: error_box(dialog, 'IP %s is already assigned to node %s' % (ip_addr, existing_ip_addrs[ip_addr])) else: break
def tune_action(widget_type, parent, device): try: widget = widget_type(device) except ocfs2.error: desc = widget_type.label.replace('_', '') desc = desc.lower() error_box(parent, 'Could not get current %s for device %s' % (desc, device)) return False dialog = Dialog(parent=parent, title=widget_type.title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=1, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') set_props(label, xalign=0.0) table.attach(label, 0, 1, 0, 1) label.set_mnemonic_widget(widget) table.attach(widget, 1, 2, 0, 1) if isinstance(widget, gtk.Entry): widget.set_activates_default(True) widget.grab_focus() dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return False new_label = widget.get_text() if not new_label: if widget_type.empty_ok: msg = ('Are you sure you want to clear the %s on %s?' % (widget_type.lower(), device)) ask = gtk.MessageDialog(parent=dialog, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=msg) if ask.run() == gtk.RESPONSE_YES: break else: ask.destroy() else: error_box( dialog, '%s cannot be empty.' % widget_type.lower().ucfirst()) else: break command = list(base_command) command.extend(widget.get_arg()) command.append(device) dialog.destroy() tunefs = Process(command, widget_type.title, widget_type.action + '...', parent, spin_now=True) success, output, k = tunefs.reap() if not success: error_box(parent, 'File system tune error: %s' % output) return False return True
def node_query(self, title='Node Attributes', defaults=None, editing=False): existing_names = {} existing_ip_addrs = {} for row in self.store: name = row[COLUMN_NAME] ip_addr = row[COLUMN_IP_ADDRESS] if not (editing and name == defaults[COLUMN_NAME]): existing_names[name] = 1 if not (editing and ip_addr == defaults[COLUMN_IP_ADDRESS]): existing_ip_addrs[ip_addr] = name dialog = Dialog(parent=self, title=title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order( (gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=4, columns=2) set_props(table, row_spacing=4, column_spacing=4, border_width=4, parent=dialog.vbox) widgets = [] for row, field in enumerate(fields): if field.widget_type is None: widgets.append(None) continue label = gtk.Label(field.title + ':') set_props(label, xalign=1.0) table.attach(label, 0, 1, row, row + 1) widget = field.widget_type() table.attach(widget, 1, 2, row, row + 1) if field.column == COLUMN_NAME: widget.set_max_length(o2cb.O2NM_MAX_NAME_LEN) elif field.column == COLUMN_IP_PORT: widget.set_numeric(True) adjustment = gtk.Adjustment(PORT_DEFAULT, PORT_MINIMUM, PORT_MAXIMUM, 1, 100) widget.set_adjustment(adjustment) widget.set_value(PORT_DEFAULT) widgets.append(widget) if defaults: for w, d in zip(widgets, defaults): if w and d: w.set_text(d) dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return None ip_port = widgets[COLUMN_IP_PORT].get_text() name = widgets[COLUMN_NAME].get_text() if not name: error_box(dialog, 'Node name not specified') continue try: ip_addr = widgets[COLUMN_IP_ADDRESS].get_text() except (IPMissing, IPError), msg: error_box(dialog, msg[0]) continue if name in existing_names: error_box(dialog, 'Node %s already exists in the configuration' % name) elif ip_addr in existing_ip_addrs: error_box( dialog, 'IP %s is already assigned to node %s' % (ip_addr, existing_ip_addrs[ip_addr])) else: break
command = ('ssh', 'root@%s' % host, remote_command) terminal.feed('Propagating cluster configuration to %s...\r\n' % host, -1) terminal.fork_command(command=command[0], argv=command) def push_config(parent=None): try: cluster_name, hosts = get_hosts(parent) except o2cb_ctl.CtlError, e: error_box(parent, str(e)) return try: command = generate_command(cluster_name) except IOError, e: error_box(parent, str(e)) return title = 'Propagate Cluster Configuration' dialog = TerminalDialog(parent=parent, title=title) terminal = dialog.terminal dialog.finished = False dialog.show_all() host_iter = iter(hosts) terminal.connect('child-exited', propagate, dialog, command, host_iter) propagate(terminal, dialog, command, host_iter)
def tune_action(widget_type, parent, device): try: widget = widget_type(device) except ocfs2.error: desc = widget_type.label.replace('_', '') desc = desc.lower() error_box(parent, 'Could not get current %s for device %s' % (desc, device)) return False dialog = Dialog(parent=parent, title=widget_type.title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=1, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') set_props(label, xalign=0.0) table.attach(label, 0, 1, 0, 1) label.set_mnemonic_widget(widget) table.attach(widget, 1, 2, 0, 1) if isinstance(widget, gtk.Entry): widget.set_activates_default(True) widget.grab_focus() dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return False new_label = widget.get_text() if not new_label: if widget_type.empty_ok: msg = ('Are you sure you want to clear the %s on %s?' % (widget_type.lower(), device)) ask = gtk.MessageDialog(parent=dialog, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=msg) if ask.run() == gtk.RESPONSE_YES: break else: ask.destroy() else: error_box(dialog, '%s cannot be empty.' % widget_type.lower().ucfirst()) else: break command = list(base_command) command.extend(widget.get_arg()) command.append(device) dialog.destroy() tunefs = Process(command, widget_type.title, widget_type.action + '...', parent, spin_now=True) success, output, k = tunefs.reap() if not success: error_box(parent, 'File system tune error: %s' % output) return False return True