update hacking requirement to version 0.10
This patch updates hacking requiremes and fixes all pep8 errors, including python3 syntax. Almost all errors are comments, not separated by space from sharp symbol. Also there was one xrange usage and 'file', which are not available in python3. Change-Id: I13af226e8409d2e8576d07a974e34676cfa8137c Closes-bug: #1546446
This commit is contained in:
parent
8313c4d8ab
commit
8228aefe5a
@ -56,7 +56,8 @@ class WidgetType(object):
|
|||||||
class ModuleHelper(object):
|
class ModuleHelper(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_setting(cls, settings, key):
|
def get_setting(cls, settings, key):
|
||||||
"""Retrieving setting by key
|
"""Retrieving setting by key.
|
||||||
|
|
||||||
:param settings: settings from config file
|
:param settings: settings from config file
|
||||||
:param key: setting name (format: '[{section_name}/]{setting_name}')
|
:param key: setting name (format: '[{section_name}/]{setting_name}')
|
||||||
:returns: setting value
|
:returns: setting value
|
||||||
@ -71,7 +72,8 @@ class ModuleHelper(object):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def set_setting(cls, settings, key, value, default_settings=None):
|
def set_setting(cls, settings, key, value, default_settings=None):
|
||||||
"""Sets new setting by key
|
"""Sets new setting by key.
|
||||||
|
|
||||||
:param settings: settings from config file
|
:param settings: settings from config file
|
||||||
:param key: setting name (format: '[{section_name}/]{setting_name}')
|
:param key: setting name (format: '[{section_name}/]{setting_name}')
|
||||||
:param value: new value
|
:param value: new value
|
||||||
|
@ -55,15 +55,15 @@ def getCidrSize(cidr):
|
|||||||
|
|
||||||
|
|
||||||
def getNetwork(ip, netmask, additionalip=None):
|
def getNetwork(ip, netmask, additionalip=None):
|
||||||
#Return a list excluding ip and broadcast IPs
|
# Return a list excluding ip and broadcast IPs
|
||||||
try:
|
try:
|
||||||
ipn = netaddr.IPNetwork("%s/%s" % (ip, netmask))
|
ipn = netaddr.IPNetwork("%s/%s" % (ip, netmask))
|
||||||
ipn_list = list(ipn)
|
ipn_list = list(ipn)
|
||||||
#Drop broadcast and network ip
|
# Drop broadcast and network ip
|
||||||
ipn_list = ipn_list[1:-1]
|
ipn_list = ipn_list[1:-1]
|
||||||
#Drop ip
|
# Drop ip
|
||||||
ipn_list[:] = [value for value in ipn_list if str(value) != ip]
|
ipn_list[:] = [value for value in ipn_list if str(value) != ip]
|
||||||
#Drop additionalip
|
# Drop additionalip
|
||||||
if additionalip:
|
if additionalip:
|
||||||
ipn_list[:] = [value for value in ipn_list if
|
ipn_list[:] = [value for value in ipn_list if
|
||||||
str(value) != additionalip]
|
str(value) != additionalip]
|
||||||
@ -117,7 +117,7 @@ def list_host_ip_addresses(interfaces="all"):
|
|||||||
|
|
||||||
|
|
||||||
def range(startip, endip):
|
def range(startip, endip):
|
||||||
#Return a list of IPs between startip and endip
|
# Return a list of IPs between startip and endip
|
||||||
try:
|
try:
|
||||||
return list(netaddr.iter_iprange(startip, endip))
|
return list(netaddr.iter_iprange(startip, endip))
|
||||||
except netaddr.AddrFormatError:
|
except netaddr.AddrFormatError:
|
||||||
@ -125,7 +125,7 @@ def range(startip, endip):
|
|||||||
|
|
||||||
|
|
||||||
def intersects(range1, range2):
|
def intersects(range1, range2):
|
||||||
#Returns true if any IPs in range1 exist in range2
|
# Returns true if any IPs in range1 exist in range2
|
||||||
return range1 & range2
|
return range1 & range2
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +134,8 @@ def netmaskToCidr(netmask):
|
|||||||
|
|
||||||
|
|
||||||
def duplicateIPExists(ip, iface, arping_bind=False):
|
def duplicateIPExists(ip, iface, arping_bind=False):
|
||||||
"""Checks for duplicate IP addresses using arping
|
"""Checks for duplicate IP addresses using arping.
|
||||||
|
|
||||||
Don't use arping_bind unless you know what you are doing.
|
Don't use arping_bind unless you know what you are doing.
|
||||||
|
|
||||||
:param ip: IP to scan for
|
:param ip: IP to scan for
|
||||||
|
@ -55,7 +55,7 @@ def puppetApply(classes):
|
|||||||
if cls['type'] == consts.PUPPET_TYPE_LITERAL:
|
if cls['type'] == consts.PUPPET_TYPE_LITERAL:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
#Build params
|
# Build params
|
||||||
for key, value in six.iteritems(cls["params"]):
|
for key, value in six.iteritems(cls["params"]):
|
||||||
cmd_input.extend([key, "=>", _to_string(value)])
|
cmd_input.extend([key, "=>", _to_string(value)])
|
||||||
cmd_input.append('}')
|
cmd_input.append('}')
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
import random
|
import random
|
||||||
import string
|
import string
|
||||||
|
|
||||||
|
from six.moves import range
|
||||||
|
|
||||||
|
|
||||||
def password(arg=None):
|
def password(arg=None):
|
||||||
try:
|
try:
|
||||||
@ -22,4 +24,4 @@ def password(arg=None):
|
|||||||
except Exception:
|
except Exception:
|
||||||
length = 24
|
length = 24
|
||||||
chars = string.letters + string.digits
|
chars = string.letters + string.digits
|
||||||
return ''.join([random.choice(chars) for _ in xrange(length)])
|
return ''.join([random.choice(chars) for _ in range(length)])
|
||||||
|
@ -37,7 +37,8 @@ def TextField(keyword, label, width, default_value=None, tooltip=None,
|
|||||||
if disabled:
|
if disabled:
|
||||||
wrapped_obj = urwid.WidgetDisable(urwid.AttrWrap(edit_obj,
|
wrapped_obj = urwid.WidgetDisable(urwid.AttrWrap(edit_obj,
|
||||||
'important', 'editfc'))
|
'important', 'editfc'))
|
||||||
#Add get_edit_text and set_edit_text to wrapped_obj so we can use later
|
# Add get_edit_text and set_edit_text to
|
||||||
|
# wrapped_obj so we can use later
|
||||||
wrapped_obj.set_edit_text = edit_obj.set_edit_text
|
wrapped_obj.set_edit_text = edit_obj.set_edit_text
|
||||||
wrapped_obj.get_edit_text = edit_obj.get_edit_text
|
wrapped_obj.get_edit_text = edit_obj.get_edit_text
|
||||||
return wrapped_obj
|
return wrapped_obj
|
||||||
@ -54,7 +55,7 @@ def ChoicesGroup(choices, default_value=None, fn=None):
|
|||||||
user_data=txt),
|
user_data=txt),
|
||||||
'buttn', 'buttnf')
|
'buttn', 'buttnf')
|
||||||
wrapped_choices = TabbedGridFlow(rb_group, 13, 3, 0, 'left')
|
wrapped_choices = TabbedGridFlow(rb_group, 13, 3, 0, 'left')
|
||||||
#Bundle rb_group so it can be used later easily
|
# Bundle rb_group so it can be used later easily
|
||||||
wrapped_choices.rb_group = rb_group
|
wrapped_choices.rb_group = rb_group
|
||||||
return wrapped_choices
|
return wrapped_choices
|
||||||
|
|
||||||
@ -235,15 +236,15 @@ class TabbedListWalker(urwid.ListWalker):
|
|||||||
self.focus = pos
|
self.focus = pos
|
||||||
self._modified()
|
self._modified()
|
||||||
try:
|
try:
|
||||||
#Reset focus to first selectable widget in item
|
# Reset focus to first selectable widget in item
|
||||||
if hasattr(item, 'original_widget'):
|
if hasattr(item, 'original_widget'):
|
||||||
item.original_widget.set_focus(
|
item.original_widget.set_focus(
|
||||||
item.original_widget.first_selectable())
|
item.original_widget.first_selectable())
|
||||||
else:
|
else:
|
||||||
item.set_focus(item.first_selectable())
|
item.set_focus(item.first_selectable())
|
||||||
except Exception:
|
except Exception:
|
||||||
#Ignore failure. Case only applies to TabbedColumns and
|
# Ignore failure. Case only applies to TabbedColumns and
|
||||||
#TabbedGridFlow. Other items should fail silently.
|
# TabbedGridFlow. Other items should fail silently.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def tab_prev(self):
|
def tab_prev(self):
|
||||||
@ -266,8 +267,8 @@ class TabbedListWalker(urwid.ListWalker):
|
|||||||
else:
|
else:
|
||||||
item.set_focus(len(item.contents) - 1)
|
item.set_focus(len(item.contents) - 1)
|
||||||
except Exception:
|
except Exception:
|
||||||
#Ignore failure. Case only applies to TabbedColumns and
|
# Ignore failure. Case only applies to TabbedColumns and
|
||||||
#TabbedGridFlow. Other items should fail silently.
|
# TabbedGridFlow. Other items should fail silently.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_focus(self):
|
def get_focus(self):
|
||||||
|
@ -57,7 +57,7 @@ def dict_merge(a, b):
|
|||||||
else:
|
else:
|
||||||
result[k] = copy.deepcopy(v)
|
result[k] = copy.deepcopy(v)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
#Non-iterable objects should be just returned
|
# Non-iterable objects should be just returned
|
||||||
return b
|
return b
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class FuelSetup(object):
|
|||||||
"settings.yaml")
|
"settings.yaml")
|
||||||
self.settingsfile = consts.SETTINGS_FILE
|
self.settingsfile = consts.SETTINGS_FILE
|
||||||
self.managediface = network.get_physical_ifaces()[0]
|
self.managediface = network.get_physical_ifaces()[0]
|
||||||
#Set to true to move all settings to end
|
# Set to true to move all settings to end
|
||||||
self.globalsave = True
|
self.globalsave = True
|
||||||
self.version = utils.get_fuel_version()
|
self.version = utils.get_fuel_version()
|
||||||
self.main()
|
self.main()
|
||||||
@ -100,7 +100,7 @@ class FuelSetup(object):
|
|||||||
urwid.connect_signal(button, 'click', self.menu_chosen, c)
|
urwid.connect_signal(button, 'click', self.menu_chosen, c)
|
||||||
body.append(urwid.AttrMap(button, None, focus_map='reversed'))
|
body.append(urwid.AttrMap(button, None, focus_map='reversed'))
|
||||||
return urwid.ListBox(urwid.SimpleListWalker(body))
|
return urwid.ListBox(urwid.SimpleListWalker(body))
|
||||||
#return urwid.ListBox(urwid.SimpleFocusListWalker(body))
|
# return urwid.ListBox(urwid.SimpleFocusListWalker(body))
|
||||||
|
|
||||||
def menu_chosen(self, button, choice):
|
def menu_chosen(self, button, choice):
|
||||||
size = self.screen.get_cols_rows()
|
size = self.screen.get_cols_rows()
|
||||||
@ -162,11 +162,11 @@ class FuelSetup(object):
|
|||||||
% self.version)
|
% self.version)
|
||||||
text_footer = (u"Status messages go here.")
|
text_footer = (u"Status messages go here.")
|
||||||
|
|
||||||
#Top and bottom lines of frame
|
# Top and bottom lines of frame
|
||||||
self.header = urwid.AttrWrap(urwid.Text(text_header), 'header')
|
self.header = urwid.AttrWrap(urwid.Text(text_header), 'header')
|
||||||
self.footer = urwid.AttrWrap(urwid.Text(text_footer), 'footer')
|
self.footer = urwid.AttrWrap(urwid.Text(text_footer), 'footer')
|
||||||
|
|
||||||
#Prepare submodules
|
# Prepare submodules
|
||||||
loader = Loader(self)
|
loader = Loader(self)
|
||||||
moduledir = "%s/modules" % (os.path.dirname(__file__))
|
moduledir = "%s/modules" % (os.path.dirname(__file__))
|
||||||
self.children, self.choices = loader.load_modules(module_dir=moduledir)
|
self.children, self.choices = loader.load_modules(module_dir=moduledir)
|
||||||
@ -174,7 +174,7 @@ class FuelSetup(object):
|
|||||||
if len(self.children) == 0:
|
if len(self.children) == 0:
|
||||||
import sys
|
import sys
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
#Build list of choices excluding visible
|
# Build list of choices excluding visible
|
||||||
self.visiblechoices = []
|
self.visiblechoices = []
|
||||||
for child, choice in zip(self.children, self.choices):
|
for child, choice in zip(self.children, self.choices):
|
||||||
if child.visible:
|
if child.visible:
|
||||||
@ -199,9 +199,9 @@ class FuelSetup(object):
|
|||||||
urwid.Divider(" ")]))
|
urwid.Divider(" ")]))
|
||||||
], 1)
|
], 1)
|
||||||
self.listwalker = urwid.SimpleListWalker([self.cols])
|
self.listwalker = urwid.SimpleListWalker([self.cols])
|
||||||
#self.listwalker = urwid.TreeWalker([self.cols])
|
# self.listwalker = urwid.TreeWalker([self.cols])
|
||||||
self.listbox = urwid.ListBox(self.listwalker)
|
self.listbox = urwid.ListBox(self.listwalker)
|
||||||
#listbox = urwid.ListBox(urwid.SimpleListWalker(listbox_content))
|
# listbox = urwid.ListBox(urwid.SimpleListWalker(listbox_content))
|
||||||
|
|
||||||
self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'),
|
self.frame = urwid.Frame(urwid.AttrWrap(self.listbox, 'body'),
|
||||||
header=self.header, footer=self.footer)
|
header=self.header, footer=self.footer)
|
||||||
@ -240,7 +240,7 @@ class FuelSetup(object):
|
|||||||
|
|
||||||
self.mainloop = urwid.MainLoop(self.frame, palette, self.screen,
|
self.mainloop = urwid.MainLoop(self.frame, palette, self.screen,
|
||||||
unhandled_input=unhandled)
|
unhandled_input=unhandled)
|
||||||
#Initialize each module completely before any events are handled
|
# Initialize each module completely before any events are handled
|
||||||
for child in reversed(self.children):
|
for child in reversed(self.children):
|
||||||
self.setChildScreen(name=child.name)
|
self.setChildScreen(name=child.name)
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ class FuelSetup(object):
|
|||||||
self.mainloop.run()
|
self.mainloop.run()
|
||||||
|
|
||||||
def exit_program(self, button):
|
def exit_program(self, button):
|
||||||
#Fix /etc/hosts before quitting
|
# Fix /etc/hosts before quitting
|
||||||
dnsobj = self.children[int(self.choices.index("DNS & Hostname"))]
|
dnsobj = self.children[int(self.choices.index("DNS & Hostname"))]
|
||||||
dnsobj.fixEtcHosts()
|
dnsobj.fixEtcHosts()
|
||||||
|
|
||||||
@ -280,9 +280,9 @@ class FuelSetup(object):
|
|||||||
self.exit_program(None)
|
self.exit_program(None)
|
||||||
|
|
||||||
def global_save(self):
|
def global_save(self):
|
||||||
#Runs save function for every module
|
# Runs save function for every module
|
||||||
for module, modulename in zip(self.children, self.choices):
|
for module, modulename in zip(self.children, self.choices):
|
||||||
#Run invisible modules. They may not have screen methods
|
# Run invisible modules. They may not have screen methods
|
||||||
if not module.visible:
|
if not module.visible:
|
||||||
try:
|
try:
|
||||||
module.apply(None)
|
module.apply(None)
|
||||||
@ -324,8 +324,8 @@ def save_only(iface, settingsfile=consts.SETTINGS_FILE):
|
|||||||
"Run fuelmenu manually to make changes.")
|
"Run fuelmenu manually to make changes.")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
#Calculate and set Static/DHCP pool fields
|
# Calculate and set Static/DHCP pool fields
|
||||||
#Max IPs = net size - 2 (master node + bcast)
|
# Max IPs = net size - 2 (master node + bcast)
|
||||||
try:
|
try:
|
||||||
ip = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr']
|
ip = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['addr']
|
||||||
netmask = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['netmask']
|
netmask = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]['netmask']
|
||||||
@ -358,7 +358,7 @@ def save_only(iface, settingsfile=consts.SETTINGS_FILE):
|
|||||||
if num_dhcp == 0:
|
if num_dhcp == 0:
|
||||||
log.debug("No DHCP servers found")
|
log.debug("No DHCP servers found")
|
||||||
else:
|
else:
|
||||||
#Problem exists, but permit user to continue
|
# Problem exists, but permit user to continue
|
||||||
log.error("%s foreign DHCP server(s) found: %s" %
|
log.error("%s foreign DHCP server(s) found: %s" %
|
||||||
(num_dhcp, dhcp_server_data))
|
(num_dhcp, dhcp_server_data))
|
||||||
print("ERROR: %s foreign DHCP server(s) found: %s" %
|
print("ERROR: %s foreign DHCP server(s) found: %s" %
|
||||||
@ -417,7 +417,7 @@ def save_only(iface, settingsfile=consts.SETTINGS_FILE):
|
|||||||
if "/" in setting:
|
if "/" in setting:
|
||||||
part1, part2 = setting.split("/")
|
part1, part2 = setting.split("/")
|
||||||
settings.setdefault(part1, {})
|
settings.setdefault(part1, {})
|
||||||
#Keep old values for passwords if already set
|
# Keep old values for passwords if already set
|
||||||
if "password" in setting:
|
if "password" in setting:
|
||||||
settings[part1].setdefault(part2, settings_upd[setting])
|
settings[part1].setdefault(part2, settings_upd[setting])
|
||||||
else:
|
else:
|
||||||
@ -428,7 +428,7 @@ def save_only(iface, settingsfile=consts.SETTINGS_FILE):
|
|||||||
else:
|
else:
|
||||||
settings[setting] = settings_upd[setting]
|
settings[setting] = settings_upd[setting]
|
||||||
|
|
||||||
#Write astute.yaml
|
# Write astute.yaml
|
||||||
Settings().write(settings, defaultsfile=default_settings_file,
|
Settings().write(settings, defaultsfile=default_settings_file,
|
||||||
outfn=settingsfile)
|
outfn=settingsfile)
|
||||||
|
|
||||||
|
@ -42,10 +42,10 @@ class cobblerconf(urwid.WidgetWrap):
|
|||||||
self.activeiface = sorted(self.netsettings.keys())[0]
|
self.activeiface = sorted(self.netsettings.keys())[0]
|
||||||
self.parent.managediface = self.activeiface
|
self.parent.managediface = self.activeiface
|
||||||
|
|
||||||
#UI text
|
# UI text
|
||||||
text1 = "Settings for PXE booting of slave nodes."
|
text1 = "Settings for PXE booting of slave nodes."
|
||||||
text2 = "Select the interface where PXE will run:"
|
text2 = "Select the interface where PXE will run:"
|
||||||
#Placeholder for network settings text
|
# Placeholder for network settings text
|
||||||
self.net_choices = widget.ChoicesGroup(sorted(self.netsettings.keys()),
|
self.net_choices = widget.ChoicesGroup(sorted(self.netsettings.keys()),
|
||||||
default_value=self.activeiface,
|
default_value=self.activeiface,
|
||||||
fn=self.radioSelect)
|
fn=self.radioSelect)
|
||||||
@ -87,20 +87,20 @@ to advertise via DHCP to nodes",
|
|||||||
self.parent.footer.set_text("Checking data...")
|
self.parent.footer.set_text("Checking data...")
|
||||||
self.parent.refreshScreen()
|
self.parent.refreshScreen()
|
||||||
|
|
||||||
#Refresh networking to make sure IP matches
|
# Refresh networking to make sure IP matches
|
||||||
self.getNetwork()
|
self.getNetwork()
|
||||||
|
|
||||||
#Get field information
|
# Get field information
|
||||||
responses = dict()
|
responses = dict()
|
||||||
|
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname != "blank" and "label" not in fieldname:
|
if fieldname != "blank" and "label" not in fieldname:
|
||||||
responses[fieldname] = self.edits[index].get_edit_text()
|
responses[fieldname] = self.edits[index].get_edit_text()
|
||||||
|
|
||||||
###Validate each field
|
# Validate each field
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
#Set internal_{ipaddress,netmask,interface}
|
# Set internal_{ipaddress,netmask,interface}
|
||||||
responses["ADMIN_NETWORK/interface"] = self.activeiface
|
responses["ADMIN_NETWORK/interface"] = self.activeiface
|
||||||
responses["ADMIN_NETWORK/netmask"] = self.netsettings[
|
responses["ADMIN_NETWORK/netmask"] = self.netsettings[
|
||||||
self.activeiface]["netmask"]
|
self.activeiface]["netmask"]
|
||||||
@ -109,7 +109,7 @@ to advertise via DHCP to nodes",
|
|||||||
responses["ADMIN_NETWORK/ipaddress"] = self.netsettings[
|
responses["ADMIN_NETWORK/ipaddress"] = self.netsettings[
|
||||||
self.activeiface]["addr"]
|
self.activeiface]["addr"]
|
||||||
|
|
||||||
#ensure management interface is valid
|
# ensure management interface is valid
|
||||||
if responses["ADMIN_NETWORK/interface"] not in self.netsettings.keys():
|
if responses["ADMIN_NETWORK/interface"] not in self.netsettings.keys():
|
||||||
errors.append("Management interface not valid")
|
errors.append("Management interface not valid")
|
||||||
else:
|
else:
|
||||||
@ -129,11 +129,11 @@ Please wait...")
|
|||||||
if num_dhcp == 0:
|
if num_dhcp == 0:
|
||||||
log.debug("No DHCP servers found")
|
log.debug("No DHCP servers found")
|
||||||
else:
|
else:
|
||||||
#Problem exists, but permit user to continue
|
# Problem exists, but permit user to continue
|
||||||
log.error("%s foreign DHCP server(s) found: %s" %
|
log.error("%s foreign DHCP server(s) found: %s" %
|
||||||
(num_dhcp, dhcp_server_data))
|
(num_dhcp, dhcp_server_data))
|
||||||
|
|
||||||
#Build dialog elements
|
# Build dialog elements
|
||||||
dhcp_info = []
|
dhcp_info = []
|
||||||
dhcp_info.append(urwid.Padding(
|
dhcp_info.append(urwid.Padding(
|
||||||
urwid.Text(("header", "!!! WARNING !!!")),
|
urwid.Text(("header", "!!! WARNING !!!")),
|
||||||
@ -154,19 +154,19 @@ else deployment will likely fail."))
|
|||||||
dialog.display_dialog(self, urwid.Pile(dhcp_info),
|
dialog.display_dialog(self, urwid.Pile(dhcp_info),
|
||||||
"DHCP Servers Found on %s"
|
"DHCP Servers Found on %s"
|
||||||
% self.activeiface)
|
% self.activeiface)
|
||||||
###Ensure pool start and end are on the same subnet as mgmt_if
|
# Ensure pool start and end are on the same subnet as mgmt_if
|
||||||
#Ensure mgmt_if has an IP first
|
# Ensure mgmt_if has an IP first
|
||||||
if len(self.netsettings[responses[
|
if len(self.netsettings[responses[
|
||||||
"ADMIN_NETWORK/interface"]]["addr"]) == 0:
|
"ADMIN_NETWORK/interface"]]["addr"]) == 0:
|
||||||
errors.append("Go to Interfaces to configure management \
|
errors.append("Go to Interfaces to configure management \
|
||||||
interface first.")
|
interface first.")
|
||||||
else:
|
else:
|
||||||
#Ensure ADMIN_NETWORK/interface is not running DHCP
|
# Ensure ADMIN_NETWORK/interface is not running DHCP
|
||||||
if self.netsettings[responses[
|
if self.netsettings[responses[
|
||||||
"ADMIN_NETWORK/interface"]]["bootproto"] == "dhcp":
|
"ADMIN_NETWORK/interface"]]["bootproto"] == "dhcp":
|
||||||
errors.append("%s is running DHCP. Change it to static "
|
errors.append("%s is running DHCP. Change it to static "
|
||||||
"first." % self.activeiface)
|
"first." % self.activeiface)
|
||||||
#Ensure DHCP Pool Start and DHCP Pool are valid IPs
|
# Ensure DHCP Pool Start and DHCP Pool are valid IPs
|
||||||
try:
|
try:
|
||||||
if netaddr.valid_ipv4(responses[
|
if netaddr.valid_ipv4(responses[
|
||||||
"ADMIN_NETWORK/dhcp_pool_start"]):
|
"ADMIN_NETWORK/dhcp_pool_start"]):
|
||||||
@ -202,7 +202,8 @@ interface first.")
|
|||||||
except Exception:
|
except Exception:
|
||||||
errors.append("Invalid IP address for DHCP Pool end")
|
errors.append("Invalid IP address for DHCP Pool end")
|
||||||
|
|
||||||
#Ensure pool start and end are in the same subnet of each other
|
# Ensure pool start and end are in the same
|
||||||
|
# subnet of each other
|
||||||
netmask = self.netsettings[responses[
|
netmask = self.netsettings[responses[
|
||||||
"ADMIN_NETWORK/interface"
|
"ADMIN_NETWORK/interface"
|
||||||
]]["netmask"]
|
]]["netmask"]
|
||||||
@ -212,7 +213,7 @@ interface first.")
|
|||||||
errors.append("DHCP Pool start and end are not in the "
|
errors.append("DHCP Pool start and end are not in the "
|
||||||
"same subnet.")
|
"same subnet.")
|
||||||
|
|
||||||
#Ensure pool start and end are in the right netmask
|
# Ensure pool start and end are in the right netmask
|
||||||
mgmt_if_ipaddr = self.netsettings[responses[
|
mgmt_if_ipaddr = self.netsettings[responses[
|
||||||
"ADMIN_NETWORK/interface"]]["addr"]
|
"ADMIN_NETWORK/interface"]]["addr"]
|
||||||
if network.inSameSubnet(responses[
|
if network.inSameSubnet(responses[
|
||||||
@ -292,20 +293,20 @@ interface first.")
|
|||||||
return oldsettings
|
return oldsettings
|
||||||
|
|
||||||
def save(self, responses):
|
def save(self, responses):
|
||||||
## Generic settings start ##
|
# Generic settings start ##
|
||||||
newsettings = ModuleHelper.save(self, responses)
|
newsettings = ModuleHelper.save(self, responses)
|
||||||
for setting in responses.keys():
|
for setting in responses.keys():
|
||||||
if "/" in setting:
|
if "/" in setting:
|
||||||
part1, part2 = setting.split("/")
|
part1, part2 = setting.split("/")
|
||||||
if part1 not in newsettings:
|
if part1 not in newsettings:
|
||||||
#We may not touch all settings, so copy oldsettings first
|
# We may not touch all settings, so copy oldsettings first
|
||||||
newsettings[part1] = self.oldsettings[part1]
|
newsettings[part1] = self.oldsettings[part1]
|
||||||
newsettings[part1][part2] = responses[setting]
|
newsettings[part1][part2] = responses[setting]
|
||||||
else:
|
else:
|
||||||
newsettings[setting] = responses[setting]
|
newsettings[setting] = responses[setting]
|
||||||
## Generic settings end ##
|
# Generic settings end
|
||||||
|
|
||||||
## Need to calculate and netmask
|
# Need to calculate and netmask
|
||||||
newsettings['ADMIN_NETWORK']['netmask'] = \
|
newsettings['ADMIN_NETWORK']['netmask'] = \
|
||||||
self.netsettings[newsettings['ADMIN_NETWORK']['interface']][
|
self.netsettings[newsettings['ADMIN_NETWORK']['interface']][
|
||||||
"netmask"]
|
"netmask"]
|
||||||
@ -314,9 +315,9 @@ interface first.")
|
|||||||
defaultsfile=self.parent.defaultsettingsfile,
|
defaultsfile=self.parent.defaultsettingsfile,
|
||||||
outfn=self.parent.settingsfile)
|
outfn=self.parent.settingsfile)
|
||||||
|
|
||||||
#Set oldsettings to reflect new settings
|
# Set oldsettings to reflect new settings
|
||||||
self.oldsettings = newsettings
|
self.oldsettings = newsettings
|
||||||
#Update self.defaults
|
# Update self.defaults
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname != "blank" and "label" not in fieldname:
|
if fieldname != "blank" and "label" not in fieldname:
|
||||||
self.defaults[fieldname]['value'] = responses[fieldname]
|
self.defaults[fieldname]['value'] = responses[fieldname]
|
||||||
@ -334,9 +335,9 @@ interface first.")
|
|||||||
|
|
||||||
def radioSelect(self, current, state, user_data=None):
|
def radioSelect(self, current, state, user_data=None):
|
||||||
"""Update network details and display information."""
|
"""Update network details and display information."""
|
||||||
### Urwid returns the previously selected radio button.
|
# Urwid returns the previously selected radio button.
|
||||||
### The previous object has True state, which is wrong.
|
# The previous object has True state, which is wrong.
|
||||||
### Somewhere in rb group a RadioButton is set to True.
|
# Somewhere in rb group a RadioButton is set to True.
|
||||||
for rb in current.group:
|
for rb in current.group:
|
||||||
if rb.get_label() == current.get_label():
|
if rb.get_label() == current.get_label():
|
||||||
continue
|
continue
|
||||||
@ -370,12 +371,12 @@ interface first.")
|
|||||||
self.net_text4.set_text("WARNING: This interface is DOWN. "
|
self.net_text4.set_text("WARNING: This interface is DOWN. "
|
||||||
"Configure it first.")
|
"Configure it first.")
|
||||||
|
|
||||||
#If DHCP pool start and matches activeiface network, don't update
|
# If DHCP pool start and matches activeiface network, don't update
|
||||||
#This means if you change your pool values, go to another page, then
|
# This means if you change your pool values, go to another page, then
|
||||||
#go back, it will not reset your changes. But what is more likely is
|
# go back, it will not reset your changes. But what is more likely is
|
||||||
#you will change the network settings for admin interface and then come
|
# you will change the network settings for admin interface and then
|
||||||
#back to this page to update your DHCP settings. If the inSameSubnet
|
# come back to this page to update your DHCP settings. If the
|
||||||
#test fails, just recalculate and set new values.
|
# inSameSubnet test fails, just recalculate and set new values.
|
||||||
for index, key in enumerate(self.fields):
|
for index, key in enumerate(self.fields):
|
||||||
if key == "ADMIN_NETWORK/dhcp_pool_start":
|
if key == "ADMIN_NETWORK/dhcp_pool_start":
|
||||||
dhcp_start = self.edits[index].get_edit_text()
|
dhcp_start = self.edits[index].get_edit_text()
|
||||||
@ -390,9 +391,9 @@ interface first.")
|
|||||||
log.debug("Existing network settings missing or invalid. "
|
log.debug("Existing network settings missing or invalid. "
|
||||||
"Updating...")
|
"Updating...")
|
||||||
|
|
||||||
#Calculate and set Static/DHCP pool fields
|
# Calculate and set Static/DHCP pool fields
|
||||||
#Max IPs = net size - 2 (master node + bcast)
|
# Max IPs = net size - 2 (master node + bcast)
|
||||||
#Add gateway so we exclude it
|
# Add gateway so we exclude it
|
||||||
net_ip_list = network.getNetwork(
|
net_ip_list = network.getNetwork(
|
||||||
self.netsettings[self.activeiface]['addr'],
|
self.netsettings[self.activeiface]['addr'],
|
||||||
self.netsettings[self.activeiface]['netmask'],
|
self.netsettings[self.activeiface]['netmask'],
|
||||||
@ -405,7 +406,7 @@ interface first.")
|
|||||||
self.net_text4.set_text("This network configuration can "
|
self.net_text4.set_text("This network configuration can "
|
||||||
"support %s nodes." % len(dhcp_pool))
|
"support %s nodes." % len(dhcp_pool))
|
||||||
except Exception:
|
except Exception:
|
||||||
#We don't have valid values, so mark all fields empty
|
# We don't have valid values, so mark all fields empty
|
||||||
dynamic_start = ""
|
dynamic_start = ""
|
||||||
dynamic_end = ""
|
dynamic_end = ""
|
||||||
for index, key in enumerate(self.fields):
|
for index, key in enumerate(self.fields):
|
||||||
|
@ -43,7 +43,7 @@ class dnsandhostname(urwid.WidgetWrap):
|
|||||||
self.extdhcp = True
|
self.extdhcp = True
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
#UI Text
|
# UI Text
|
||||||
self.header_content = ["DNS and hostname setup", "Note: Leave "
|
self.header_content = ["DNS and hostname setup", "Note: Leave "
|
||||||
"External DNS blank if you do not have "
|
"External DNS blank if you do not have "
|
||||||
"Internet access."]
|
"Internet access."]
|
||||||
@ -78,7 +78,7 @@ is accessible"}
|
|||||||
self.fixEtcHosts()
|
self.fixEtcHosts()
|
||||||
|
|
||||||
def fixEtcHosts(self):
|
def fixEtcHosts(self):
|
||||||
#replace ip for env variable HOSTNAME in /etc/hosts
|
# replace ip for env variable HOSTNAME in /etc/hosts
|
||||||
if self.netsettings[self.parent.managediface]["addr"] != "":
|
if self.netsettings[self.parent.managediface]["addr"] != "":
|
||||||
managediface_ip = self.netsettings[
|
managediface_ip = self.netsettings[
|
||||||
self.parent.managediface]["addr"]
|
self.parent.managediface]["addr"]
|
||||||
@ -102,7 +102,7 @@ is accessible"}
|
|||||||
"""Validate that all fields have valid values through sanity checks."""
|
"""Validate that all fields have valid values through sanity checks."""
|
||||||
self.parent.footer.set_text("Checking data...")
|
self.parent.footer.set_text("Checking data...")
|
||||||
self.parent.refreshScreen()
|
self.parent.refreshScreen()
|
||||||
#Get field information
|
# Get field information
|
||||||
responses = dict()
|
responses = dict()
|
||||||
|
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
@ -111,38 +111,38 @@ is accessible"}
|
|||||||
else:
|
else:
|
||||||
responses[fieldname] = self.edits[index].get_edit_text()
|
responses[fieldname] = self.edits[index].get_edit_text()
|
||||||
|
|
||||||
###Validate each field
|
# Validate each field
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
#hostname must be under 60 chars
|
# hostname must be under 60 chars
|
||||||
if len(responses["HOSTNAME"]) >= 60:
|
if len(responses["HOSTNAME"]) >= 60:
|
||||||
errors.append("Hostname must be under 60 chars.")
|
errors.append("Hostname must be under 60 chars.")
|
||||||
|
|
||||||
#hostname must not be empty
|
# hostname must not be empty
|
||||||
if len(responses["HOSTNAME"]) == 0:
|
if len(responses["HOSTNAME"]) == 0:
|
||||||
errors.append("Hostname must not be empty.")
|
errors.append("Hostname must not be empty.")
|
||||||
|
|
||||||
#hostname needs to have valid chars
|
# hostname needs to have valid chars
|
||||||
if re.search('[^a-z0-9-]', responses["HOSTNAME"]):
|
if re.search('[^a-z0-9-]', responses["HOSTNAME"]):
|
||||||
errors.append(
|
errors.append(
|
||||||
"Hostname must contain only alphanumeric and hyphen.")
|
"Hostname must contain only alphanumeric and hyphen.")
|
||||||
|
|
||||||
#domain must be under 180 chars
|
# domain must be under 180 chars
|
||||||
if len(responses["DNS_DOMAIN"]) >= 180:
|
if len(responses["DNS_DOMAIN"]) >= 180:
|
||||||
errors.append("Domain must be under 180 chars.")
|
errors.append("Domain must be under 180 chars.")
|
||||||
|
|
||||||
#domain must not be empty
|
# domain must not be empty
|
||||||
if len(responses["DNS_DOMAIN"]) == 0:
|
if len(responses["DNS_DOMAIN"]) == 0:
|
||||||
errors.append("Domain must not be empty.")
|
errors.append("Domain must not be empty.")
|
||||||
|
|
||||||
#domain needs to have valid chars
|
# domain needs to have valid chars
|
||||||
if re.match('[^a-z0-9-.]', responses["DNS_DOMAIN"]):
|
if re.match('[^a-z0-9-.]', responses["DNS_DOMAIN"]):
|
||||||
errors.append(
|
errors.append(
|
||||||
"Domain must contain only alphanumeric, period and hyphen.")
|
"Domain must contain only alphanumeric, period and hyphen.")
|
||||||
#ensure external DNS is valid
|
# ensure external DNS is valid
|
||||||
if len(responses["DNS_UPSTREAM"]) == 0:
|
if len(responses["DNS_UPSTREAM"]) == 0:
|
||||||
#We will allow empty if user doesn't need external networking
|
# We will allow empty if user doesn't need external networking
|
||||||
#and present a strongly worded warning
|
# and present a strongly worded warning
|
||||||
msg = "If you continue without DNS, you may not be able to access"\
|
msg = "If you continue without DNS, you may not be able to access"\
|
||||||
+ " external data necessary for installation needed for " \
|
+ " external data necessary for installation needed for " \
|
||||||
+ "some OpenStack Releases."
|
+ "some OpenStack Releases."
|
||||||
@ -153,8 +153,8 @@ is accessible"}
|
|||||||
else:
|
else:
|
||||||
upstream_nameservers = responses["DNS_UPSTREAM"].split(',')
|
upstream_nameservers = responses["DNS_UPSTREAM"].split(',')
|
||||||
|
|
||||||
#external DNS must contain only numbers, periods, and commas
|
# external DNS must contain only numbers, periods, and commas
|
||||||
#Needs more serious ip address checking
|
# Needs more serious ip address checking
|
||||||
if re.match('[^0-9.,]', responses["DNS_UPSTREAM"]):
|
if re.match('[^0-9.,]', responses["DNS_UPSTREAM"]):
|
||||||
errors.append(
|
errors.append(
|
||||||
"External DNS must contain only IP addresses and commas.")
|
"External DNS must contain only IP addresses and commas.")
|
||||||
@ -170,18 +170,18 @@ is accessible"}
|
|||||||
errors.append(
|
errors.append(
|
||||||
"Unable to specify more than 3 External DNS addresses.")
|
"Unable to specify more than 3 External DNS addresses.")
|
||||||
|
|
||||||
#ensure test DNS name isn't empty
|
# ensure test DNS name isn't empty
|
||||||
if len(responses["TEST_DNS"]) == 0:
|
if len(responses["TEST_DNS"]) == 0:
|
||||||
errors.append("Test DNS must not be empty.")
|
errors.append("Test DNS must not be empty.")
|
||||||
#Validate first IP address
|
# Validate first IP address
|
||||||
for nameserver in upstream_nameservers:
|
for nameserver in upstream_nameservers:
|
||||||
if not netaddr.valid_ipv4(nameserver):
|
if not netaddr.valid_ipv4(nameserver):
|
||||||
errors.append("Not a valid IP address for DNS server:"
|
errors.append("Not a valid IP address for DNS server:"
|
||||||
" {0}".format(nameserver))
|
" {0}".format(nameserver))
|
||||||
|
|
||||||
#Try to resolve with first address
|
# Try to resolve with first address
|
||||||
if not self.checkDNS(upstream_nameservers[0]):
|
if not self.checkDNS(upstream_nameservers[0]):
|
||||||
#Warn user that DNS resolution failed, but continue
|
# Warn user that DNS resolution failed, but continue
|
||||||
msg = "Unable to resolve %s.\n\n" % responses['TEST_DNS']\
|
msg = "Unable to resolve %s.\n\n" % responses['TEST_DNS']\
|
||||||
+ "Possible causes for DNS failure include:\n"\
|
+ "Possible causes for DNS failure include:\n"\
|
||||||
+ "* Invalid DNS server\n"\
|
+ "* Invalid DNS server\n"\
|
||||||
@ -210,10 +210,10 @@ is accessible"}
|
|||||||
|
|
||||||
self.save(responses)
|
self.save(responses)
|
||||||
|
|
||||||
#Update network details so we write correct IP address
|
# Update network details so we write correct IP address
|
||||||
self.getNetwork()
|
self.getNetwork()
|
||||||
|
|
||||||
#Apply hostname
|
# Apply hostname
|
||||||
cmd = ["/usr/bin/hostnamectl", "set-hostname", responses["HOSTNAME"]]
|
cmd = ["/usr/bin/hostnamectl", "set-hostname", responses["HOSTNAME"]]
|
||||||
err_code, _, errout = utils.execute(cmd)
|
err_code, _, errout = utils.execute(cmd)
|
||||||
if err_code != 0:
|
if err_code != 0:
|
||||||
@ -223,7 +223,7 @@ is accessible"}
|
|||||||
"for more details.")
|
"for more details.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
#remove old hostname from /etc/hosts
|
# remove old hostname from /etc/hosts
|
||||||
f = open("/etc/hosts", "r")
|
f = open("/etc/hosts", "r")
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
f.close()
|
f.close()
|
||||||
@ -240,7 +240,7 @@ is accessible"}
|
|||||||
etchosts.write(line)
|
etchosts.write(line)
|
||||||
etchosts.close()
|
etchosts.close()
|
||||||
|
|
||||||
#append hostname and ip address to /etc/hosts
|
# append hostname and ip address to /etc/hosts
|
||||||
with open("/etc/hosts", "a") as etchosts:
|
with open("/etc/hosts", "a") as etchosts:
|
||||||
if self.netsettings[self.parent.managediface]["addr"] != "":
|
if self.netsettings[self.parent.managediface]["addr"] != "":
|
||||||
managediface_ip = self.netsettings[
|
managediface_ip = self.netsettings[
|
||||||
@ -284,7 +284,7 @@ is accessible"}
|
|||||||
# /etc/resolv.conf
|
# /etc/resolv.conf
|
||||||
oldsettings = ModuleHelper.load(self, ignoredparams=['TEST_DNS'])
|
oldsettings = ModuleHelper.load(self, ignoredparams=['TEST_DNS'])
|
||||||
|
|
||||||
#Read hostname from uname
|
# Read hostname from uname
|
||||||
try:
|
try:
|
||||||
hostname, sep, domain = os.uname()[1].partition('.')
|
hostname, sep, domain = os.uname()[1].partition('.')
|
||||||
oldsettings["HOSTNAME"] = hostname
|
oldsettings["HOSTNAME"] = hostname
|
||||||
@ -341,34 +341,34 @@ is accessible"}
|
|||||||
return searches, domain, ",".join(nameservers)
|
return searches, domain, ",".join(nameservers)
|
||||||
|
|
||||||
def save(self, responses):
|
def save(self, responses):
|
||||||
## Generic settings start ##
|
# Generic settings start
|
||||||
newsettings = dict()
|
newsettings = dict()
|
||||||
for setting in responses.keys():
|
for setting in responses.keys():
|
||||||
if "/" in setting:
|
if "/" in setting:
|
||||||
part1, part2 = setting.split("/")
|
part1, part2 = setting.split("/")
|
||||||
if part1 not in newsettings:
|
if part1 not in newsettings:
|
||||||
#We may not touch all settings, so copy oldsettings first
|
# We may not touch all settings, so copy oldsettings first
|
||||||
newsettings[part1] = self.oldsettings[part1]
|
newsettings[part1] = self.oldsettings[part1]
|
||||||
newsettings[part1][part2] = responses[setting]
|
newsettings[part1][part2] = responses[setting]
|
||||||
else:
|
else:
|
||||||
newsettings[setting] = responses[setting]
|
newsettings[setting] = responses[setting]
|
||||||
## Generic settings end ##
|
# Generic settings end
|
||||||
|
|
||||||
#log.debug(str(newsettings))
|
# log.debug(str(newsettings))
|
||||||
Settings().write(newsettings,
|
Settings().write(newsettings,
|
||||||
defaultsfile=self.parent.defaultsettingsfile,
|
defaultsfile=self.parent.defaultsettingsfile,
|
||||||
outfn=self.parent.settingsfile)
|
outfn=self.parent.settingsfile)
|
||||||
|
|
||||||
#Set oldsettings to reflect new settings
|
# Set oldsettings to reflect new settings
|
||||||
self.oldsettings = newsettings
|
self.oldsettings = newsettings
|
||||||
#Update self.defaults
|
# Update self.defaults
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname != "blank":
|
if fieldname != "blank":
|
||||||
self.defaults[fieldname]['value'] = newsettings[fieldname]
|
self.defaults[fieldname]['value'] = newsettings[fieldname]
|
||||||
|
|
||||||
def checkDNS(self, server):
|
def checkDNS(self, server):
|
||||||
#Note: Python's internal resolver caches negative answers.
|
# Note: Python's internal resolver caches negative answers.
|
||||||
#Therefore, we should call dig externally to be sure.
|
# Therefore, we should call dig externally to be sure.
|
||||||
|
|
||||||
command = ["dig", "+short", "+time=3", "+retries=1",
|
command = ["dig", "+short", "+time=3", "+retries=1",
|
||||||
self.defaults["TEST_DNS"]['value'], "@{0}".format(server)]
|
self.defaults["TEST_DNS"]['value'], "@{0}".format(server)]
|
||||||
|
@ -32,7 +32,7 @@ class feature_groups(urwid.WidgetWrap):
|
|||||||
self.visible = True
|
self.visible = True
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
#UI details
|
# UI details
|
||||||
self.header_content = [
|
self.header_content = [
|
||||||
"Feature groups",
|
"Feature groups",
|
||||||
"Note: Depending on which feature groups are enabled, "
|
"Note: Depending on which feature groups are enabled, "
|
||||||
|
@ -33,7 +33,7 @@ from fuelmenu.common import utils
|
|||||||
blank = urwid.Divider()
|
blank = urwid.Divider()
|
||||||
|
|
||||||
|
|
||||||
#Need to define fields in order so it will render correctly
|
# Need to define fields in order so it will render correctly
|
||||||
|
|
||||||
|
|
||||||
class interfaces(urwid.WidgetWrap):
|
class interfaces(urwid.WidgetWrap):
|
||||||
@ -51,11 +51,11 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
self.activeiface = sorted(self.netsettings.keys())[0]
|
self.activeiface = sorted(self.netsettings.keys())[0]
|
||||||
self.extdhcp = True
|
self.extdhcp = True
|
||||||
|
|
||||||
#UI text
|
# UI text
|
||||||
self.net_choices = widget.ChoicesGroup(sorted(self.netsettings.keys()),
|
self.net_choices = widget.ChoicesGroup(sorted(self.netsettings.keys()),
|
||||||
default_value=self.activeiface,
|
default_value=self.activeiface,
|
||||||
fn=self.radioSelectIface)
|
fn=self.radioSelectIface)
|
||||||
#Placeholders for network settings text
|
# Placeholders for network settings text
|
||||||
self.net_text1 = widget.TextLabel("")
|
self.net_text1 = widget.TextLabel("")
|
||||||
self.net_text2 = widget.TextLabel("")
|
self.net_text2 = widget.TextLabel("")
|
||||||
self.net_text3 = widget.TextLabel("")
|
self.net_text3 = widget.TextLabel("")
|
||||||
@ -92,7 +92,7 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def fixEtcHosts(self):
|
def fixEtcHosts(self):
|
||||||
#replace ip for env variable HOSTNAME in /etc/hosts
|
# replace ip for env variable HOSTNAME in /etc/hosts
|
||||||
if self.netsettings[self.parent.managediface]["addr"] != "":
|
if self.netsettings[self.parent.managediface]["addr"] != "":
|
||||||
managediface_ip = self.netsettings[self.parent.managediface][
|
managediface_ip = self.netsettings[self.parent.managediface][
|
||||||
"addr"]
|
"addr"]
|
||||||
@ -113,7 +113,7 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def check(self, args):
|
def check(self, args):
|
||||||
"""Validate that all fields have valid values and sanity checks."""
|
"""Validate that all fields have valid values and sanity checks."""
|
||||||
#Get field information
|
# Get field information
|
||||||
responses = dict()
|
responses = dict()
|
||||||
self.parent.footer.set_text("Checking data...")
|
self.parent.footer.set_text("Checking data...")
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
@ -134,10 +134,10 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
else:
|
else:
|
||||||
responses[fieldname] = self.edits[index].get_edit_text()
|
responses[fieldname] = self.edits[index].get_edit_text()
|
||||||
|
|
||||||
###Validate each field
|
# Validate each field
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
#Check for the duplicate IP provided
|
# Check for the duplicate IP provided
|
||||||
for k, v in six.iteritems(self.netsettings):
|
for k, v in six.iteritems(self.netsettings):
|
||||||
if (k != self.activeiface and responses["ipaddr"] != ''
|
if (k != self.activeiface and responses["ipaddr"] != ''
|
||||||
and responses["ipaddr"] == v.get('addr')):
|
and responses["ipaddr"] == v.get('addr')):
|
||||||
@ -153,8 +153,8 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
numactiveifaces += 1
|
numactiveifaces += 1
|
||||||
if numactiveifaces < 2 and \
|
if numactiveifaces < 2 and \
|
||||||
self.netsettings[self.activeiface]['addr'] != "":
|
self.netsettings[self.activeiface]['addr'] != "":
|
||||||
#Block user because puppet l23network fails if all interfaces
|
# Block user because puppet l23network fails if all interfaces
|
||||||
#are disabled.
|
# are disabled.
|
||||||
errors.append("Cannot disable all interfaces.")
|
errors.append("Cannot disable all interfaces.")
|
||||||
elif responses["bootproto"] == "dhcp":
|
elif responses["bootproto"] == "dhcp":
|
||||||
self.parent.footer.set_text("Scanning for DHCP servers. "
|
self.parent.footer.set_text("Scanning for DHCP servers. "
|
||||||
@ -172,7 +172,7 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
if len(dhcp_server_data) < 1:
|
if len(dhcp_server_data) < 1:
|
||||||
errors.append("No DHCP servers found. Cannot enable DHCP")
|
errors.append("No DHCP servers found. Cannot enable DHCP")
|
||||||
|
|
||||||
#Check ipaddr, netmask, gateway only if static
|
# Check ipaddr, netmask, gateway only if static
|
||||||
elif responses["bootproto"] == "none":
|
elif responses["bootproto"] == "none":
|
||||||
try:
|
try:
|
||||||
if netaddr.valid_ipv4(responses["ipaddr"]):
|
if netaddr.valid_ipv4(responses["ipaddr"]):
|
||||||
@ -194,10 +194,10 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
errors.append("Not a valid netmask: %s" % responses["netmask"])
|
errors.append("Not a valid netmask: %s" % responses["netmask"])
|
||||||
try:
|
try:
|
||||||
if len(responses["gateway"]) > 0:
|
if len(responses["gateway"]) > 0:
|
||||||
#Check if gateway is valid
|
# Check if gateway is valid
|
||||||
if netaddr.valid_ipv4(responses["gateway"]) is False:
|
if netaddr.valid_ipv4(responses["gateway"]) is False:
|
||||||
raise BadIPException("Gateway IP address is not valid")
|
raise BadIPException("Gateway IP address is not valid")
|
||||||
#Check if gateway is in same subnet
|
# Check if gateway is in same subnet
|
||||||
if network.inSameSubnet(responses["ipaddr"],
|
if network.inSameSubnet(responses["ipaddr"],
|
||||||
responses["gateway"],
|
responses["gateway"],
|
||||||
responses["netmask"]) is False:
|
responses["netmask"]) is False:
|
||||||
@ -339,10 +339,10 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def radioSelectIface(self, current, state, user_data=None):
|
def radioSelectIface(self, current, state, user_data=None):
|
||||||
"""Update network details and display information."""
|
"""Update network details and display information."""
|
||||||
### This makes no sense, but urwid returns the previous object.
|
# This makes no sense, but urwid returns the previous object.
|
||||||
### The previous object has True state, which is wrong.
|
# The previous object has True state, which is wrong.
|
||||||
### Somewhere in current.group a RadioButton is set to True.
|
# Somewhere in current.group a RadioButton is set to True.
|
||||||
### Our quest is to find it.
|
# Our quest is to find it.
|
||||||
for rb in current.group:
|
for rb in current.group:
|
||||||
if rb.get_label() == current.get_label():
|
if rb.get_label() == current.get_label():
|
||||||
continue
|
continue
|
||||||
@ -354,10 +354,10 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def radioSelect(self, current, state, user_data=None):
|
def radioSelect(self, current, state, user_data=None):
|
||||||
"""Update network details and display information."""
|
"""Update network details and display information."""
|
||||||
### This makes no sense, but urwid returns the previous object.
|
# This makes no sense, but urwid returns the previous object.
|
||||||
### The previous object has True state, which is wrong.
|
# The previous object has True state, which is wrong.
|
||||||
### Somewhere in current.group a RadioButton is set to True.
|
# Somewhere in current.group a RadioButton is set to True.
|
||||||
### Our quest is to find it.
|
# Our quest is to find it.
|
||||||
for rb in current.group:
|
for rb in current.group:
|
||||||
if rb.get_label() == current.get_label():
|
if rb.get_label() == current.get_label():
|
||||||
continue
|
continue
|
||||||
@ -376,7 +376,7 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
self.net_text3.set_text("Netmask: %-15s Gateway: %s" % (
|
self.net_text3.set_text("Netmask: %-15s Gateway: %s" % (
|
||||||
self.netsettings[self.activeiface]['netmask'],
|
self.netsettings[self.activeiface]['netmask'],
|
||||||
self.gateway))
|
self.gateway))
|
||||||
#Set text fields to current netsettings
|
# Set text fields to current netsettings
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname == "ifname":
|
if fieldname == "ifname":
|
||||||
self.edits[index].base_widget.set_edit_text(self.activeiface)
|
self.edits[index].base_widget.set_edit_text(self.activeiface)
|
||||||
@ -398,7 +398,7 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
rb_group[0].set_state(True)
|
rb_group[0].set_state(True)
|
||||||
rb_group[1].set_state(False)
|
rb_group[1].set_state(False)
|
||||||
else:
|
else:
|
||||||
#onboot should only be no if the interface is also down
|
# onboot should only be no if the interface is also down
|
||||||
if self.netsettings[self.activeiface]['addr'] == "":
|
if self.netsettings[self.activeiface]['addr'] == "":
|
||||||
rb_group[0].set_state(False)
|
rb_group[0].set_state(False)
|
||||||
rb_group[1].set_state(True)
|
rb_group[1].set_state(True)
|
||||||
@ -413,7 +413,7 @@ class interfaces(urwid.WidgetWrap):
|
|||||||
self.edits[index].set_edit_text(self.netsettings[
|
self.edits[index].set_edit_text(self.netsettings[
|
||||||
self.activeiface]['netmask'])
|
self.activeiface]['netmask'])
|
||||||
elif fieldname == "gateway":
|
elif fieldname == "gateway":
|
||||||
#Gateway is for this iface only if gateway is matches subnet
|
# Gateway is for this iface only if gateway is matches subnet
|
||||||
if network.inSameSubnet(
|
if network.inSameSubnet(
|
||||||
self.netsettings[self.activeiface]['addr'],
|
self.netsettings[self.activeiface]['addr'],
|
||||||
self.gateway,
|
self.gateway,
|
||||||
|
@ -33,7 +33,7 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
self.visible = True
|
self.visible = True
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
#UI details
|
# UI details
|
||||||
self.header_content = ["NTP Setup", "Note: If you continue without "
|
self.header_content = ["NTP Setup", "Note: If you continue without "
|
||||||
"NTP, you may have issues with deployment "
|
"NTP, you may have issues with deployment "
|
||||||
"due to time synchronization issues. These "
|
"due to time synchronization issues. These "
|
||||||
@ -60,7 +60,7 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
"value": "time-b.nist.gov"},
|
"value": "time-b.nist.gov"},
|
||||||
}
|
}
|
||||||
|
|
||||||
#Load info
|
# Load info
|
||||||
self.gateway = self.get_default_gateway_linux()
|
self.gateway = self.get_default_gateway_linux()
|
||||||
|
|
||||||
self.oldsettings = self.load()
|
self.oldsettings = self.load()
|
||||||
@ -70,7 +70,7 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
"""Validate that all fields have valid values and sanity checks."""
|
"""Validate that all fields have valid values and sanity checks."""
|
||||||
self.parent.footer.set_text("Checking data...")
|
self.parent.footer.set_text("Checking data...")
|
||||||
self.parent.refreshScreen()
|
self.parent.refreshScreen()
|
||||||
#Get field information
|
# Get field information
|
||||||
responses = dict()
|
responses = dict()
|
||||||
|
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
@ -85,7 +85,7 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
else:
|
else:
|
||||||
responses[fieldname] = self.edits[index].get_edit_text()
|
responses[fieldname] = self.edits[index].get_edit_text()
|
||||||
|
|
||||||
###Validate each field
|
# Validate each field
|
||||||
errors = []
|
errors = []
|
||||||
warnings = []
|
warnings = []
|
||||||
if responses['ntpenabled'] == "No":
|
if responses['ntpenabled'] == "No":
|
||||||
@ -101,31 +101,31 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
return responses
|
return responses
|
||||||
if all(map(lambda f: (len(responses[f]) == 0), self.fields)):
|
if all(map(lambda f: (len(responses[f]) == 0), self.fields)):
|
||||||
pass
|
pass
|
||||||
#We will allow empty if user doesn't need external networking
|
# We will allow empty if user doesn't need external networking
|
||||||
#and present a strongly worded warning
|
# and present a strongly worded warning
|
||||||
#msg = "If you continue without NTP, you may have issues with "\
|
# msg = "If you continue without NTP, you may have issues with "\
|
||||||
# + "deployment due to time synchronization issues. These "\
|
# + "deployment due to time synchronization issues. These "\
|
||||||
# + "problems are exacerbated in virtualized deployments."
|
# + "problems are exacerbated in virtualized deployments."
|
||||||
|
|
||||||
#dialog.display_dialog(
|
# dialog.display_dialog(
|
||||||
# self, widget.TextLabel(msg), "Empty NTP Warning")
|
# self, widget.TextLabel(msg), "Empty NTP Warning")
|
||||||
del responses['ntpenabled']
|
del responses['ntpenabled']
|
||||||
for ntpfield, ntpvalue in responses.iteritems():
|
for ntpfield, ntpvalue in responses.iteritems():
|
||||||
#NTP must be under 255 chars
|
# NTP must be under 255 chars
|
||||||
if len(ntpvalue) >= 255:
|
if len(ntpvalue) >= 255:
|
||||||
errors.append("%s must be under 255 chars." %
|
errors.append("%s must be under 255 chars." %
|
||||||
self.defaults[ntpfield]['label'])
|
self.defaults[ntpfield]['label'])
|
||||||
|
|
||||||
#NTP needs to have valid chars
|
# NTP needs to have valid chars
|
||||||
if re.search('[^a-zA-Z0-9-.]', ntpvalue):
|
if re.search('[^a-zA-Z0-9-.]', ntpvalue):
|
||||||
errors.append("%s contains illegal characters." %
|
errors.append("%s contains illegal characters." %
|
||||||
self.defaults[ntpfield]['label'])
|
self.defaults[ntpfield]['label'])
|
||||||
|
|
||||||
#ensure external NTP is valid
|
# ensure external NTP is valid
|
||||||
if len(ntpvalue) > 0:
|
if len(ntpvalue) > 0:
|
||||||
#Validate first NTP address
|
# Validate first NTP address
|
||||||
try:
|
try:
|
||||||
#Try to test NTP via ntpdate
|
# Try to test NTP via ntpdate
|
||||||
if not self.checkNTP(ntpvalue):
|
if not self.checkNTP(ntpvalue):
|
||||||
warnings.append("%s unable to perform NTP."
|
warnings.append("%s unable to perform NTP."
|
||||||
% self.defaults[ntpfield]['label'])
|
% self.defaults[ntpfield]['label'])
|
||||||
@ -158,9 +158,9 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.save(responses)
|
self.save(responses)
|
||||||
#Apply NTP now, ignoring errors
|
# Apply NTP now, ignoring errors
|
||||||
if len(responses['NTP1']) > 0:
|
if len(responses['NTP1']) > 0:
|
||||||
#Stop ntpd, run ntpdate, start ntpd
|
# Stop ntpd, run ntpdate, start ntpd
|
||||||
start_command = ["service", "ntpd", "start"]
|
start_command = ["service", "ntpd", "start"]
|
||||||
stop_command = ["service", "ntpd", "stop"]
|
stop_command = ["service", "ntpd", "stop"]
|
||||||
ntpdate_command = ["ntpdate", "-t5", responses['NTP1']]
|
ntpdate_command = ["ntpdate", "-t5", responses['NTP1']]
|
||||||
@ -179,26 +179,26 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
return ModuleHelper.load(self, ignoredparams=['ntpenabled'])
|
return ModuleHelper.load(self, ignoredparams=['ntpenabled'])
|
||||||
|
|
||||||
def save(self, responses):
|
def save(self, responses):
|
||||||
## Generic settings start ##
|
# Generic settings start
|
||||||
newsettings = dict()
|
newsettings = dict()
|
||||||
for setting in responses.keys():
|
for setting in responses.keys():
|
||||||
if "/" in setting:
|
if "/" in setting:
|
||||||
part1, part2 = setting.split("/")
|
part1, part2 = setting.split("/")
|
||||||
if part1 not in newsettings:
|
if part1 not in newsettings:
|
||||||
#We may not touch all settings, so copy oldsettings first
|
# We may not touch all settings, so copy oldsettings first
|
||||||
newsettings[part1] = self.oldsettings[part1]
|
newsettings[part1] = self.oldsettings[part1]
|
||||||
newsettings[part1][part2] = responses[setting]
|
newsettings[part1][part2] = responses[setting]
|
||||||
else:
|
else:
|
||||||
newsettings[setting] = responses[setting]
|
newsettings[setting] = responses[setting]
|
||||||
## Generic settings end ##
|
# Generic settings end
|
||||||
|
|
||||||
Settings().write(newsettings,
|
Settings().write(newsettings,
|
||||||
defaultsfile=self.parent.defaultsettingsfile,
|
defaultsfile=self.parent.defaultsettingsfile,
|
||||||
outfn=self.parent.settingsfile)
|
outfn=self.parent.settingsfile)
|
||||||
|
|
||||||
#Set oldsettings to reflect new settings
|
# Set oldsettings to reflect new settings
|
||||||
self.oldsettings = newsettings
|
self.oldsettings = newsettings
|
||||||
#Update defaults
|
# Update defaults
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname != "blank" and fieldname in newsettings:
|
if fieldname != "blank" and fieldname in newsettings:
|
||||||
self.defaults[fieldname]['value'] = newsettings[fieldname]
|
self.defaults[fieldname]['value'] = newsettings[fieldname]
|
||||||
@ -211,7 +211,7 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.gateway = self.get_default_gateway_linux()
|
self.gateway = self.get_default_gateway_linux()
|
||||||
#If gateway is empty, disable NTP
|
# If gateway is empty, disable NTP
|
||||||
if self.gateway is None:
|
if self.gateway is None:
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname == "ntpenabled":
|
if fieldname == "ntpenabled":
|
||||||
@ -222,10 +222,10 @@ class ntpsetup(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def radioSelect(self, current, state, user_data=None):
|
def radioSelect(self, current, state, user_data=None):
|
||||||
"""Update network details and display information."""
|
"""Update network details and display information."""
|
||||||
### This makes no sense, but urwid returns the previous object.
|
# This makes no sense, but urwid returns the previous object.
|
||||||
### The previous object has True state, which is wrong.
|
# The previous object has True state, which is wrong.
|
||||||
### Somewhere in current.group a RadioButton is set to True.
|
# Somewhere in current.group a RadioButton is set to True.
|
||||||
### Our quest is to find it.
|
# Our quest is to find it.
|
||||||
for rb in current.group:
|
for rb in current.group:
|
||||||
if rb.get_label() == current.get_label():
|
if rb.get_label() == current.get_label():
|
||||||
continue
|
continue
|
||||||
|
@ -101,7 +101,7 @@ class rootpw(urwid.WidgetWrap):
|
|||||||
def save(self, password):
|
def save(self, password):
|
||||||
hashed = crypt.crypt(password, utils.gensalt())
|
hashed = crypt.crypt(password, utils.gensalt())
|
||||||
log.info("Changing root password")
|
log.info("Changing root password")
|
||||||
#clear any locks first
|
# clear any locks first
|
||||||
rm_command = ["rm", "-f", "/etc/passwd.lock", "/etc/shadow.lock"]
|
rm_command = ["rm", "-f", "/etc/passwd.lock", "/etc/shadow.lock"]
|
||||||
utils.execute(rm_command)
|
utils.execute(rm_command)
|
||||||
usermod_command = ["usermod", "-p", hashed, "root"]
|
usermod_command = ["usermod", "-p", hashed, "root"]
|
||||||
|
@ -23,14 +23,14 @@ import urwid.web_display
|
|||||||
blank = urwid.Divider()
|
blank = urwid.Divider()
|
||||||
|
|
||||||
|
|
||||||
class saveandquit():
|
class saveandquit(object):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.name = "Quit Setup"
|
self.name = "Quit Setup"
|
||||||
self.priority = 99
|
self.priority = 99
|
||||||
self.visible = True
|
self.visible = True
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.screen = None
|
self.screen = None
|
||||||
#UI text
|
# UI text
|
||||||
saveandcontinue_button = widget.Button("Save and Continue",
|
saveandcontinue_button = widget.Button("Save and Continue",
|
||||||
self.save_and_continue)
|
self.save_and_continue)
|
||||||
saveandquit_button = widget.Button("Save and Quit", self.save_and_quit)
|
saveandquit_button = widget.Button("Save and Quit", self.save_and_quit)
|
||||||
|
@ -35,7 +35,7 @@ class servicepws(urwid.WidgetWrap):
|
|||||||
self.priority = 99
|
self.priority = 99
|
||||||
self.visible = False
|
self.visible = False
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
#UI text
|
# UI text
|
||||||
self.header_content = ["Set service passwords", ""]
|
self.header_content = ["Set service passwords", ""]
|
||||||
self.defaults = \
|
self.defaults = \
|
||||||
{
|
{
|
||||||
@ -120,7 +120,7 @@ class servicepws(urwid.WidgetWrap):
|
|||||||
self.screen = None
|
self.screen = None
|
||||||
|
|
||||||
def check(self, args):
|
def check(self, args):
|
||||||
#Get field information
|
# Get field information
|
||||||
responses = dict()
|
responses = dict()
|
||||||
|
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
@ -147,13 +147,13 @@ class servicepws(urwid.WidgetWrap):
|
|||||||
return ModuleHelper.load(self)
|
return ModuleHelper.load(self)
|
||||||
|
|
||||||
def save(self, responses):
|
def save(self, responses):
|
||||||
## Generic settings start ##
|
# Generic settings start
|
||||||
newsettings = OrderedDict()
|
newsettings = OrderedDict()
|
||||||
for setting in responses.keys():
|
for setting in responses.keys():
|
||||||
if "/" in setting:
|
if "/" in setting:
|
||||||
part1, part2 = setting.split("/")
|
part1, part2 = setting.split("/")
|
||||||
if part1 not in newsettings:
|
if part1 not in newsettings:
|
||||||
#We may not touch all settings, so copy oldsettings first
|
# We may not touch all settings, so copy oldsettings first
|
||||||
try:
|
try:
|
||||||
newsettings[part1] = self.oldsettings[part1]
|
newsettings[part1] = self.oldsettings[part1]
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -168,12 +168,12 @@ class servicepws(urwid.WidgetWrap):
|
|||||||
defaultsfile=self.parent.defaultsettingsfile,
|
defaultsfile=self.parent.defaultsettingsfile,
|
||||||
outfn=self.parent.settingsfile)
|
outfn=self.parent.settingsfile)
|
||||||
|
|
||||||
## Generic settings end ##
|
# Generic settings end
|
||||||
log.debug('done saving servicepws')
|
log.debug('done saving servicepws')
|
||||||
|
|
||||||
#Set oldsettings to reflect new settings
|
# Set oldsettings to reflect new settings
|
||||||
self.oldsettings = newsettings
|
self.oldsettings = newsettings
|
||||||
#Update defaults
|
# Update defaults
|
||||||
for index, fieldname in enumerate(self.fields):
|
for index, fieldname in enumerate(self.fields):
|
||||||
if fieldname != "blank" and fieldname in newsettings:
|
if fieldname != "blank" and fieldname in newsettings:
|
||||||
self.defaults[fieldname]['value'] = newsettings[fieldname]
|
self.defaults[fieldname]['value'] = newsettings[fieldname]
|
||||||
|
@ -23,14 +23,14 @@ import urwid.web_display
|
|||||||
blank = urwid.Divider()
|
blank = urwid.Divider()
|
||||||
|
|
||||||
|
|
||||||
class shell():
|
class shell(object):
|
||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
self.name = "Shell Login"
|
self.name = "Shell Login"
|
||||||
self.priority = 90
|
self.priority = 90
|
||||||
self.visible = True
|
self.visible = True
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.screen = None
|
self.screen = None
|
||||||
#UI text
|
# UI text
|
||||||
text1 = "Press the button below to enter a shell login."
|
text1 = "Press the button below to enter a shell login."
|
||||||
login_button = widget.Button("Shell Login", self.start_shell)
|
login_button = widget.Button("Shell Login", self.start_shell)
|
||||||
self.header_content = [text1, blank, login_button]
|
self.header_content = [text1, blank, login_button]
|
||||||
|
@ -98,7 +98,7 @@ class Settings(object):
|
|||||||
settings = self.read(defaultsfile)
|
settings = self.read(defaultsfile)
|
||||||
settings.update(self.read(outfn))
|
settings.update(self.read(outfn))
|
||||||
settings.update(newvalues)
|
settings.update(newvalues)
|
||||||
outfile = file(outfn, 'w')
|
with open(outfn, 'w') as outfile:
|
||||||
yaml.dump(settings, outfile, default_style='"',
|
yaml.dump(settings, outfile, default_style='"',
|
||||||
default_flow_style=False)
|
default_flow_style=False)
|
||||||
return True
|
return True
|
||||||
|
Loading…
Reference in New Issue
Block a user