diff --git a/i18n/cl_install_ru.mo b/i18n/cl_install_ru.mo index 565f55a..663ccb5 100644 Binary files a/i18n/cl_install_ru.mo and b/i18n/cl_install_ru.mo differ diff --git a/pym/cl_fill_install.py b/pym/cl_fill_install.py index 4baee20..4794b96 100644 --- a/pym/cl_fill_install.py +++ b/pym/cl_fill_install.py @@ -24,13 +24,15 @@ from os import path from os import readlink,access,R_OK from cl_utils import isMount,typeFile,getTupleVersion,pathJoin,isFstabMount,\ listDirectory, getAvailableX11Drivers, getUUIDDict, \ - isPkgInstalled, process + isPkgInstalled, process, checkUtils, readLinesFile, \ + lspci from cl_distr import DistributiveRepository,PartitionDistributive from cl_fill import clLocale from operator import itemgetter from cl_template import _terms from subprocess import PIPE, Popen from cl_install import convertDictOpt +from utils import ip from cl_lang import lang tr = lang() @@ -89,34 +91,53 @@ class fillVars(object, glob_attr): return "up" return "" + def get_os_install_net_hash(self): + """Get net hash""" + rePci = re.compile(r"(\d\d:\d\d\.\d)(?:/[^/]+){2}$") + def getPci(interface): + pathname = path.realpath(path.join('/sys/class/net', + interface)) + pci = rePci.search(pathname) + if pci: + return pci.group(1) + else: + return "" + interfaces = ip.getInterfaces() + net_hash = {} + pciEthernet = lspci("Ethernet controller",shortInfo=True) + for interface in interfaces: + ipaddr,mask = ip.receiveIpAndMask(interface) + dhcp = ip.isDhcpIp(interface) + mac = ip.receiveMac(interface) + pciInfo = pciEthernet.get(getPci(interface), + {'vendor':_("Unknown"), + 'name':_("vendor")}) + mapInterface = {} + mapInterface["ip"] = ipaddr + mapInterface["mask"] = mask + mapInterface["dhcp"] = "on" if dhcp else "off" + mapInterface["mac"] = mac + mapInterface["name"] = "{vendor} {name}".format(**pciInfo) + net_hash[interface]=mapInterface + return net_hash + + def get_os_install_net_dhcp_set(self): + """DHCP or not""" + return self.getAttributeFromHash('os_install_net_hash','dhcp') + def get_os_net_interfaces_info(self): """Информация о существующих сетевых интерфейсах""" netInterfaces=self.Get("os_net_interfaces") listInterfacesInfo = [] # Получена ли сеть по DHCP если нет to ip или off - for interfaces in netInterfaces: - fdhcpLeases = "/var/lib/dhcp/dhclient.leases" - if access(fdhcpLeases, R_OK) and\ - interfaces in open(fdhcpLeases).read(): - listInterfacesInfo.append((interfaces, "DHCP")) - continue - fdhcpInfo = "/var/lib/dhcpcd/dhcpcd-%s.info"%interfaces - fdhcpLease = "/var/lib/dhcpcd/dhcpcd-%s.lease"%interfaces - if path.exists(fdhcpInfo) or path.exists(fdhcpLease): - listInterfacesInfo.append((interfaces, "DHCP")) - # Если интерфейс без DHCP - if not (interfaces, "DHCP") in listInterfacesInfo: - # Находим ip - res = self._runos("/sbin/ifconfig %s"%interfaces) - ip = "" - for j in res: - sIP=re.search('addr:([0-9\.]+).+',j) - if sIP: - ip = sIP.group(1) - listInterfacesInfo.append((interfaces, ip)) - break - if not ip: - listInterfacesInfo.append((interfaces, "Off")) + for interface,ipaddr,dhcp in zip(self.Get('os_install_net_interfaces'), + self.Get('os_install_net_ip'), + self.Get('os_install_net_dhcp_set')): + if dhcp == "on": + listInterfacesInfo.append((interface, "DHCP")) + else: + listInterfacesInfo.append((interface, + ipaddr if ipaddr else "Off")) return ", ".join(map(lambda x:"%s (%s)"%(x[0],x[1]), listInterfacesInfo)) @@ -853,7 +874,8 @@ class fillVars(object, glob_attr): def get_os_install_x11_video_drv(self): """Video driver used by xorg""" if self.Get('os_install_root_type') == 'usb-hdd': - available_drivers = getAvailableX11Drivers() + available_drivers = \ + getAvailableX11Drivers(prefix=self.Get('cl_chroot_path')) videoVal = self.getValueFromCmdLine("calculate","video") videoVal = {'i915':'intel'}.get(videoVal,videoVal) if not isPkgInstalled('xorg-server', @@ -971,12 +993,63 @@ class fillVars(object, glob_attr): return self.Get("os_net_allow") def get_os_install_net_ip(self): - """Ip for all network interfaces""" - return self.Get("os_net_ip") + """Current ip""" + return self.getAttributeFromHash('os_install_net_hash','ip') + + def get_os_install_net_mask(self): + """Current mask""" + return self.getAttributeFromHash('os_install_net_hash','mask') + + def get_os_install_net_mac(self): + """Current mac""" + return self.getAttributeFromHash('os_install_net_hash','mac') + + def get_os_install_net_name(self): + """Current mac""" + return self.getAttributeFromHash('os_install_net_hash','name') + + def get_os_install_net_gateway(self): + """Get default gateway""" + ipCmd = checkUtils("/sbin/ip") + reDefault = re.compile("^default via ({0})".format(ip.IP_ADDR)) + gw = map(lambda x:x.group(1), + filter(lambda x:x, + map(reDefault.search, + process(ipCmd,"route")))) + if gw: + return gw[0] + else: + return "" + + def get_os_install_net_dns(self): + """Get current name servers""" + dnsIps = filter(ip.checkIp, + map(lambda x:x.strip().partition("nameserver")[2].strip(), + filter(lambda x:x.lstrip().startswith("nameserver"), + readLinesFile('/etc/resolv.conf')))) + return " ".join(dnsIps) + + def get_os_install_net_dns_search(self): + """Get current name servers""" + dnsSearch = " ".join( + map(lambda x:x.strip().partition("search")[2].strip(), + filter(lambda x:x.lstrip().startswith("search"), + readLinesFile('/etc/resolv.conf')))) + return dnsSearch + + def get_os_install_net_setup(self): + """Net setup (networkmanager or openrc)""" + if filter(lambda x:x.lower() == ("networkmanager"), + listDirectory('/etc/runlevels/boot')+ + listDirectory('/etc/runlevels/default')): + if isPkgInstalled("net-misc/networkmanager", + prefix=self.Get('cl_chroot_path')): + return "networkmanager" + return "openrc" def get_os_install_net_interfaces(self): """Net interfaces""" - return self.Get("os_net_interfaces") + return sorted(self.Get('os_install_net_hash').keys()) def get_os_install_net_domain(self): """Domain""" diff --git a/pym/cl_install.py b/pym/cl_install.py index 756f62f..db0b7c7 100644 --- a/pym/cl_install.py +++ b/pym/cl_install.py @@ -33,6 +33,7 @@ from cl_kernel_utils import KernelConfig,InitRamFs import cl_overriding from StringIO import StringIO +from utils import ip install_errors = "" def installExit(*args,**kwars): @@ -819,9 +820,9 @@ class cl_install(color_print, SignalInterrupt): return instnextres return curnextres - def printInstallTables(self): + def printLocationTables(self): """Print install report""" - title, headerList, dataList = self.generateTableData() + title, headerList, dataList = self.generateTableMountData() tableObj = tableReport("", headerList, dataList) tableObj.printReport(False) title, headerList, dataList = self.generateTableBindData() @@ -829,8 +830,13 @@ class cl_install(color_print, SignalInterrupt): tableObj = tableReport(title, headerList, dataList) tableObj.printReport(False) + def printNetworkTables(self): + """Print install report""" + title, headerList, dataList = self.generateTableNetworkData() + tableObj = tableReport("", headerList, dataList) + tableObj.printReport(False) + def printInfo(self,update=False): - self.printSUCCESS(_("Installation") + " Calculate Linux") clGet = self.clVars.Get installedSystem = "%s %s"%(clGet('os_linux_name'), clGet('os_linux_ver')) @@ -857,14 +863,25 @@ class cl_install(color_print, SignalInterrupt): else: musers = _("none") + self.printSUCCESS(_("Installation") + " Calculate Linux") printData = [ [(_("System information"),True), (_("Computer name"),clGet('os_install_net_hostname'),not flash), (_("Domain name"),clGet('os_install_net_domain'),not flash), (_("Users"), musers,not flash), - (_("Network devices"),clGet('os_net_interfaces_info'),hdd), (_("Installed system"),installedSystem,True) ], + [(_("Localization"),not flash), + (_("Language"), + clGet('os_install_locale_lang'),True), + (_("Keymap"),clGet('os_install_locale_xkbname'),True), + (_("Timezone"),clGet('os_install_clock_timezone'),True), + ], + [(_("Network services"),hdd), + (_("PROXY"), + clGet('os_install_proxy') or _("none"),True), + (_("NTP"),clGet('os_install_ntp') or _("none"),True) + ], [(_("Hardware"),True), (_("Machine hardware name"), clGet('os_install_arch_machine'),True), @@ -874,20 +891,12 @@ class cl_install(color_print, SignalInterrupt): clGet('os_install_x11_video_drv'),hdd), (_("Screen resolution"),clGet('os_install_x11_resolution'),hdd) ], - [(_("Localization"),not flash), - (_("Language"), - clGet('os_install_locale_lang'),True), - (_("Keymap"),clGet('os_install_locale_xkbname'),True), - (_("Timezone"),clGet('os_install_clock_timezone'),True), + [(_("Network devices"),not flash), + (self.printNetworkTables,None,True) ], [(_("Location"),True), (_("Master boot record")+" (MBR)",mbrdisk,True), - (self.printInstallTables,None,True) - ], - [(_("Network services"),hdd), - (_("PROXY"), - clGet('os_install_proxy') or _("none"),True), - (_("NTP"),clGet('os_install_ntp') or _("none"),True) + (self.printLocationTables,None,True) ], [(_("Perform pre-install checkups"),True)] ] @@ -1581,7 +1590,7 @@ class cl_install(color_print, SignalInterrupt): if grubProcess.failed(): raise DistributiveError(_("Cann't install bootloader")) - def generateTableData(self): + def generateTableMountData(self): """Get data from print table""" title = _("Location") allDevicesOpt = self.listDisksOptions + self.listSwapsOptions @@ -1639,6 +1648,27 @@ class cl_install(color_print, SignalInterrupt): return title, headerList, zip(self.clVars.Get('os_install_bind_path'), self.clVars.Get('os_install_bind_mountpoint')) + def generateTableNetworkData(self): + """Get bind data for print table""" + def ipInformation(listIpMaskDhcp): + ipaddr,mask,dhcp = listIpMaskDhcp + if dhcp == "on": + return _("DHCP") + elif ipaddr: + return "{ip}/{net}".format(ip=ipaddr,net=ip.maskToNet(mask)) + else: + return _("Off") + clGet = self.clVars.Get + title = _("Network devices") + headerList = [_("Device"),_("Name"),_("MAC address"),_("IP address")] + return title, headerList, zip(clGet('os_install_net_interfaces'), + clGet('os_install_net_name'), + clGet('os_install_net_mac'), + map(ipInformation, + zip(clGet('os_install_net_ip'), + clGet('os_install_net_mask'), + clGet('os_install_net_dhcp_set')))) + def getPwdHashUser(self, userName, stdinRead=False): if stdinRead: try: diff --git a/pym/cl_install_cmd.py b/pym/cl_install_cmd.py index 99f5d1c..90ca44a 100644 --- a/pym/cl_install_cmd.py +++ b/pym/cl_install_cmd.py @@ -22,10 +22,13 @@ from cl_install import cl_install, InstallError, __app__, __version__,\ from cl_vars_share import varsShare from cl_opt import opt from cl_share_cmd import share_cmd +from utils import ip as iputils +from cl_utils import isPkgInstalled from cl_lang import lang lang().setLanguage(sys.modules[__name__]) OSSYSTEM_LIST=sorted(varsShare.dictNameSystem.keys()) +NM_LIST=sorted(varsShare.dictNetworkManagers.keys()) DESCRIPTION = _("The Calculate Linux installation and configuration utility") CMD_OPTIONS = [{'shortOption':"d", @@ -90,6 +93,27 @@ CMD_OPTIONS = [{'shortOption':"d", 'optVal':"HOSTNAME", 'help':_("set short hostname of full hostname") }, + {'longOption':"netsetup", + 'optVal':"NETMANAGER", + 'type':'choice', + 'choices_regignore': NM_LIST, + 'help':_("network manager (%s)"% + "%s or %s" % (",".join(NM_LIST[0:-1]),NM_LIST[-1]))}, + {'longOption':"dhcp", + 'help':_("get ip address by %s")%"DHCP" + }, + {'longOption':"ip", + 'optVal':"IP", + 'help':_("ip address with net (example:%s)")%"192.168.1.1/24" + }, + {'longOption':"dns", + 'optVal':"DNS", + 'help':_("domain name servers (comma delimeter)") + }, + {'longOption':"gateway", + 'optVal':"GATEWAY", + 'help':_("default gateway") + }, {'longOption':"proxy", 'optVal':"PROXY", 'help':_("set proxy server for system") @@ -126,6 +150,9 @@ CMD_OPTIONS = [{'shortOption':"d", (from standard input)") }] +class OptException(Exception): + pass + class install_cmd(share_cmd): """Class for work with cl_install by console""" def __init__(self): @@ -143,6 +170,7 @@ class install_cmd(share_cmd): # names incompatible options with --live self.optionsLiveIncompatible = ["type","d", "b", "mbr", "w", "f","U", "s","install","uninstall","build","u"] + self.optionsDhcpIncompatible = ["ip","gateway","dns"] def _getNamesAllSetOptions(self): """Get list set options""" @@ -165,6 +193,14 @@ class install_cmd(share_cmd): self.optobj.error(_("incompatible options")+":"+" %s"\ %self.getStringIncompatibleOptions(incompatible+["live"])) + def checkIncompatibleDhcp(self): + """Check incompatible options for option --dchp""" + incompatible = list(set(self._getNamesAllSetOptions()) & + set(self.optionsDhcpIncompatible)) + if incompatible: + self.optobj.error(_("incompatible options")+":"+" %s"\ + %self.getStringIncompatibleOptions(incompatible+["dhcp"])) + def checkIncompatibleInstallUninstall(self): """Check incompatible options for options --install and --uninstall""" opts = self._getNamesAllSetOptions() @@ -180,17 +216,32 @@ class install_cmd(share_cmd): self.checkIncompatibleInstallUninstall() if values.live: self.checkIncompatibleLive() + if values.dhcp: + self.checkIncompatibleDhcp() if not values.v: if values.filter: errMsg = _("incorrect option") + ":" + " %s" %"--filter" +\ ": " + _("use with option '-v'") self.optobj.error(errMsg) - return False if values.xml: errMsg = _("incorrect option") + ":" + " %s" %"--xml" +\ ": " + _("use with option '-v'") self.optobj.error(errMsg) - return False + if values.ip: + if not re.match("^%s$"%iputils.IP_ADDR_NET,values.ip): + self.optobj.error(_("option %s:") %"--ip" +\ + " " + _("ip specifing error: '%s'") %\ + values.ip) + if values.dns: + if not re.match("^{0}(,{0})*$".format(iputils.IP_ADDR),values.dns): + self.optobj.error(_("option %s:") %"--dns" +\ + " " + _("dns specifing error: '%s'") %\ + values.dns) + if values.gateway: + if not iputils.checkIp(values.gateway): + self.optobj.error(_("option %s:") %"--gateway" +\ + " " + _("gateway specifing error: '%s'") %\ + values.gateway) if not (values.install or values.uninstall or values.live): if values.v is False and \ values.d is None and \ @@ -221,7 +272,6 @@ class install_cmd(share_cmd): self.optobj.error(_("option %s:") %"w" +\ " " + _("mount bind specifing error: '%s'")\ %", ".join(wrongValue)) - #check boot device if values.mbr: bootDisk = values.mbr @@ -229,7 +279,6 @@ class install_cmd(share_cmd): if not reBootDisk.match(bootDisk): self.optobj.error(_("option %s:") %"mbr" + " " +\ _("disk specifing error: '%s'")%bootDisk) - # check syntax --set self.optobj.checkVarSyntax(values) return (values, args) @@ -244,24 +293,58 @@ class install_cmd(share_cmd): def setProxyNtpHostname(self,proxy,ntp,hostname): """Process set locales by lang""" + getVar = self.logicObj.clVars.Get + setVar = self.logicObj.clVars.Set + setWriteVar = self.logicObj.clVars.SetWriteVar if proxy: - if not self.logicObj.clVars.SetWriteVar('os_install_proxy',proxy): + if not setWriteVar('os_install_proxy',proxy): self.printERROR(get_install_errors(),printBR=False) return False if ntp: - if not self.logicObj.clVars.SetWriteVar('os_install_ntp',ntp): + if not setWriteVar('os_install_ntp',ntp): self.printERROR(get_install_errors(),printBR=False) return False if hostname: if "." in hostname: hostname, op, domain = hostname.partition('.') - self.logicObj.clVars.Set('os_install_net_hostname', - hostname,True) - self.logicObj.clVars.Set('os_install_net_domain', - domain,True) + setVar('os_install_net_hostname', hostname,True) + setVar('os_install_net_domain', domain,True) + dns_search = getVar("os_install_net_dns_search") + if not domain in dns_search: + setVar("os_install_net_dns_search",domain,True) else: - self.logicObj.clVars.Set('os_install_net_hostname', - hostname,True) + setVar('os_install_net_hostname', hostname,True) + return True + + def setNetworkParams(self,ipaddr,gateway,dns,setup,dhcp): + """Set nework params""" + #if dhcp: + # self.logicObj.clVars.Set("os_install_net_dhcp_set","on",True) + # return True + #if ipaddr: + # self.logicObj.clVars.Set("os_install_net_dhcp_set","off",True) + # ip,op,net = ipaddr.partition('/') + # mask = iputils.netToMask(int(net)) + # self.logicObj.clVars.Set("os_install_net_ip",ip,True) + # self.logicObj.clVars.Set("os_install_net_mask", mask,True) + #else: + # ip = self.logicObj.clVars.Get("os_install_net_ip") + # mask = self.logicObj.clVars.Get("os_install_net_mask") + # ipaddr = "{ip}/{net}".format(ip=ip, net=iputils.maskToNet(mask)) + #if gateway: + # if not iputils.isIpInNet(gateway,ipaddr): + # self.printERROR( + # _("Specified gateway is unreachable for net %s")% + # iputils.getIpNet(ip,mask)) + # return False + # self.logicObj.clVars.Set("os_install_net_ip",gateway,True) + #if dns: + # self.logicObj.clVars.Set("os_install_net_dns",dns,True) + #if setup: + # if not isPkgInstalled(setup): + # self.printERROR(_("Network manager %s is not installed")%setup) + # return False + # self.logicObj.clVars.Set("os_install_net_setup",setup,True) return True def setVars(self,options): @@ -301,6 +384,7 @@ class install_cmd(share_cmd): if self.optobj.values.type: self.logicObj.clVars.Set('os_install_root_type', self.optobj.values.type, True) + listDiskOptions = [] listBindOptions = [] listSwapOptions = [] diff --git a/pym/cl_vars_install.py b/pym/cl_vars_install.py index 6ba5155..008cb9b 100644 --- a/pym/cl_vars_install.py +++ b/pym/cl_vars_install.py @@ -248,17 +248,44 @@ class Data: # keyboard layout name for X server os_install_locale_xkbname = {} + # hash for information about net + os_install_net_hash = {} + # computer hostname os_install_net_hostname = {'mode':"w"} # allowed network os_install_net_allow ={} + # net interfaces + os_install_net_interfaces={} + + # net device name + os_install_net_name={} + + # net devices mac + os_install_net_mac={} + # ip for all network interfaces - os_install_net_ip ={} + os_install_net_ip = {} - # net interfaces - os_install_net_interfaces={'hide':True} + # ip mask + os_install_net_mask = {} + + # default gateway + os_install_net_gateway = {} + + # dns servers + os_install_net_dns = {} + + # net setup (networkmanager or openrc) + os_install_net_setup = {} + + # dhcp or not + os_install_net_dhcp_set = {} + + # dns search + os_install_net_dns_search = {'mode':"w"} # domain os_install_net_domain = {'mode':"w"} diff --git a/scripts/cl-install b/scripts/cl-install index e123fc6..abeae0b 100644 --- a/scripts/cl-install +++ b/scripts/cl-install @@ -40,6 +40,9 @@ if __name__ == "__main__": install.setPrintNoColor(options) # init variables install.setProxyNtpHostname(options.proxy,options.ntp,options.hostname) + if not install.setNetworkParams(options.ip,options.gateway,options.dns, + options.netsetup,options.dhcp): + sys.exit(1) if options.l: if not install.setLang(options.l): sys.exit(1)