From tashi-commits-return-127-apmail-incubator-tashi-commits-archive=incubator.apache.org@incubator.apache.org Tue Jan 05 15:57:01 2010 Return-Path: Delivered-To: apmail-incubator-tashi-commits-archive@minotaur.apache.org Received: (qmail 84202 invoked from network); 5 Jan 2010 15:57:01 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 5 Jan 2010 15:57:01 -0000 Received: (qmail 19179 invoked by uid 500); 5 Jan 2010 15:57:01 -0000 Delivered-To: apmail-incubator-tashi-commits-archive@incubator.apache.org Received: (qmail 19154 invoked by uid 500); 5 Jan 2010 15:57:01 -0000 Mailing-List: contact tashi-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: tashi-dev@incubator.apache.org Delivered-To: mailing list tashi-commits@incubator.apache.org Received: (qmail 19144 invoked by uid 99); 5 Jan 2010 15:57:00 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 05 Jan 2010 15:57:00 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 05 Jan 2010 15:56:55 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 03E9C23888E7; Tue, 5 Jan 2010 15:56:35 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r896107 [1/2] - /incubator/tashi/import/zoni-intel-r843/ Date: Tue, 05 Jan 2010 15:56:34 -0000 To: tashi-commits@incubator.apache.org From: mryan3@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20100105155635.03E9C23888E7@eris.apache.org> Author: mryan3 Date: Tue Jan 5 15:56:32 2010 New Revision: 896107 URL: http://svn.apache.org/viewvc?rev=896107&view=rev Log: Initial Zoni import Added: incubator/tashi/import/zoni-intel-r843/ incubator/tashi/import/zoni-intel-r843/Makefile incubator/tashi/import/zoni-intel-r843/ZONI_DEFAULT.conf incubator/tashi/import/zoni-intel-r843/__init__.py incubator/tashi/import/zoni-intel-r843/bootmanagementinterface.py incubator/tashi/import/zoni-intel-r843/delldrac.py incubator/tashi/import/zoni-intel-r843/dhcpdns.py incubator/tashi/import/zoni-intel-r843/hwswitch.py incubator/tashi/import/zoni-intel-r843/hwswitchinterface.py incubator/tashi/import/zoni-intel-r843/infostore.py incubator/tashi/import/zoni-intel-r843/ipmi.py incubator/tashi/import/zoni-intel-r843/phyassigninterface.py incubator/tashi/import/zoni-intel-r843/pxe.py incubator/tashi/import/zoni-intel-r843/raritanpdu.py incubator/tashi/import/zoni-intel-r843/resourcequerysql.py incubator/tashi/import/zoni-intel-r843/systemassignment.py incubator/tashi/import/zoni-intel-r843/systemmanagementinterface.py incubator/tashi/import/zoni-intel-r843/usermanagement.py incubator/tashi/import/zoni-intel-r843/usermanagementinterface.py incubator/tashi/import/zoni-intel-r843/util.py incubator/tashi/import/zoni-intel-r843/version.py incubator/tashi/import/zoni-intel-r843/zoni-cli.py (with props) Added: incubator/tashi/import/zoni-intel-r843/Makefile URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/Makefile?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/Makefile (added) +++ incubator/tashi/import/zoni-intel-r843/Makefile Tue Jan 5 15:56:32 2010 @@ -0,0 +1,24 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +clean: + if [ `find . -name "*.pyc" | wc -l` -gt 0 ]; then echo Removing python byte-code...; rm `find . -name "*.pyc"`; fi + @echo Done + Added: incubator/tashi/import/zoni-intel-r843/ZONI_DEFAULT.conf URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/ZONI_DEFAULT.conf?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/ZONI_DEFAULT.conf (added) +++ incubator/tashi/import/zoni-intel-r843/ZONI_DEFAULT.conf Tue Jan 5 15:56:32 2010 @@ -0,0 +1,64 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +# Logfile +[logging] +LOG_FILE = /tmp/prs_logfile.txt + +# DB host +[dbConnection] +DB_HOST = xx_hostname_or_ip_ +DB_PORT = 3306 +DB_USER = xx_db_username_xx +DB_INST = xx_db_inst_xx +DB_PASSWORD = "xx_db_password_xx" + +# TFTP +[tftp] +TFTP_ROOT_DIR = /var/lib/tftpboot +TFTP_IMAGE_DIR = /var/lib/tftpboot/pxelinux.cfg +TFTP_BOOT_OPTIONS_DIR = /var/lib/tftpboot/pxelinux.cfg/boot_options_prs +TFTP_UPDATE_FILE = /var/lib/tftpboot/pxelinux.cfg/update.prs +TFTP_BASE_FILE = /var/lib/tftpboot/pxelinux.cfg/base.prs +TFTP_BASE_MENU_FILE = /var/lib/tftpboot/pxelinux.cfg/base-menu + +[snmp] +SNMP_COMMUNITY = xx_snmp_community_name_xx + +# Vlan Config +[vlan] +VLAN_RESERVED = {10, {"name", internal}, 999,{"name", "tashi-vm"}, 1000, {"name", "management"}, 1001, {"name", "dmz"}} +VLAN_MAX = 4095 + + +[hardware] +HARDWARE_CONTROL = ["ipmi", "drac", "pdu"] +HARDWARE_PDU = "raritan" +HARDWARE_DRAC = "DELL DRAC" + +[DhcpDns] +# Key file must be in the same directory or this will get denied +dnsKeyFile = xx_Kname.+157+36480.private_xx +dnsServer = xx_dns_server_ip_xx xx_port_xx +dnsDomain = xx_fqdn_xx +dnsExpire = 60 +dhcpServer = xx_dhcpserver_host_or_ip_xx +dhcpKeyName = xx_dhcpservername_xx +dhcpSecretKey = xx_secretkey_xx Added: incubator/tashi/import/zoni-intel-r843/__init__.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/__init__.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/__init__.py (added) +++ incubator/tashi/import/zoni-intel-r843/__init__.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +import os +import sys + +from util import * Added: incubator/tashi/import/zoni-intel-r843/bootmanagementinterface.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/bootmanagementinterface.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/bootmanagementinterface.py (added) +++ incubator/tashi/import/zoni-intel-r843/bootmanagementinterface.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,38 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os +import optparse + + +class BootManagementInterface(object): + """ Interface description for booting + """ + def __init__(self, config): + self.config = config + + #def updateDatabase(self, query): + #raise NotImplementedError + + + def createPxeConfig(self): + ''' Create the pxe config file''' + raise NotImplementedError Added: incubator/tashi/import/zoni-intel-r843/delldrac.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/delldrac.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/delldrac.py (added) +++ incubator/tashi/import/zoni-intel-r843/delldrac.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,207 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os +import pexpect +import time + +from systemmanagementinterface import SystemManagementInterface + + +#class systemmagement(): + #def __init__(self, proto): + #self.proto = proto + +def log(f): + def myF(*args, **kw): + print "calling %s%s" % (f.__name__, str(args)) + res = f(*args, **kw) + print "returning from %s -> %s" % (f.__name__, str(res)) + return res + myF.__name__ = f.__name__ + return myF + +import time + +def timeF(f): + def myF(*args, **kw): + start = time.time() + res = f(*args, **kw) + end = time.time() + print "%s took %f" % (f.__name__, end-start) + return res + myF.__name__ = f.__name__ + return myF + + +class dellDrac(SystemManagementInterface): + def __init__(self, host): + self.hostname = host['location'] + self.host = host['drac_name'] + self.user = host['drac_userid'] + self.password = host['drac_password'] + self.port = host['drac_port'] + self.powerStatus = None + self.verbose = 0 + self.server = "Server-" + str(self.port) + + def setVerbose(self, verbose): + self.verbose = verbose + + def __login(self): + switchIp = "telnet " + self.host + child = pexpect.spawn(switchIp) + + if self.verbose: + child.logfile = sys.stdout + + opt = child.expect(['Login:', pexpect.EOF, pexpect.TIMEOUT]) + + + #XXX Doesn't seem to do what I want:( + child.setecho(False) + if opt == 0: + child.sendline(self.user) + time.sleep(.5) + child.sendline(self.password) + time.sleep(.5) + i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + else: + mesg = "Error" + sys.stderr.write(mesg) + exit(1) + + return child + + @timeF + @log + def getPowerStatus(self): + child = self.__login() + cmd = "getmodinfo -m " + self.server + child.sendline(cmd) + #i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + #exit() + val = child.readline() + val = child.readline() + while self.server not in val: + val = child.readline() + + if "ON" in val: + mesg = self.hostname + " Power is on\n\n" + self.powerStatus = 1 + if "OFF" in val: + mesg = self.hostname + " Power is off\n\n" + self.powerStatus = 0 + + sys.stdout.write(mesg) + + #while status not in val: + #val = child.readline() + # + #print "val for", status, "is ", val + #i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + #val = child.readlines() + child.close() + child.terminate() + + + @timeF + def isPowered(self): + if self.powerStatus == None: + self.getPowerStatus() + if self.powerStatus: + return 1; + if not self.powerStatus: + return 0; + + + @timeF + def powerOn(self): + if self.powerStatus == 1: + mesg = self.hostname + " Power On\n\n" + exit(1) + + child = self.__login() + cmd = "racadm serveraction -m " + self.server + " powerup" + child.sendline(cmd) + val = child.readline() + val = child.readline() + if "OK" in val: + mesg = self.hostname + " Power On\n\n" + else: + mesg = self.hostname + " Power On Fail\n\n" + sys.stdout.write(mesg) + #i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + child.terminate() + + @timeF + def powerOff(self): + child = self.__login() + cmd = "racadm serveraction -m " + self.server + " powerdown" + child.sendline(cmd) + val = child.readline() + val = child.readline() + if "OK" in val: + mesg = self.hostname + " Power Off\n\n" + else: + mesg = self.hostname + " Power Off Fail\n\n" + sys.stdout.write(mesg) + #i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + child.terminate() + + @timeF + def powerCycle(self): + child = self.__login() + cmd = "racadm serveraction -m " + self.server + " powercycle" + child.sendline(cmd) + val = child.readline() + val = child.readline() + if "OK" in val: + mesg = self.hostname + " Power Cycle\n\n" + else: + mesg = self.hostname + " Power Cycle Fail\n\n" + sys.stdout.write(mesg) + #i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + child.terminate() + + @timeF + def powerReset(self): + child = self.__login() + cmd = "racadm serveraction -m " + self.server + " hardreset" + child.sendline(cmd) + val = child.readline() + val = child.readline() + if "OK" in val: + mesg = self.hostname + " Power Reset\n\n" + else: + mesg = self.hostname + " Power Reset Fail\n\n" + sys.stdout.write(mesg) + #i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + child.terminate() + + def activateConsole(self): + child = self.__login() + cmd = "connect -F " + self.server + child.sendline(cmd) + i=child.expect(['DRAC/MC:', pexpect.EOF, pexpect.TIMEOUT]) + child.terminate() + +#ipmitool -I lanplus -E -H r2r1c3b0-ipmi -U root chassis power status Added: incubator/tashi/import/zoni-intel-r843/dhcpdns.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/dhcpdns.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/dhcpdns.py (added) +++ incubator/tashi/import/zoni-intel-r843/dhcpdns.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,265 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import logging +import os +import signal +import socket +import subprocess +import time +#from instancehook import InstanceHook +#from tashi.services.ttypes import Instance, NetworkConfiguration +#from tashi import boolean + + +class DhcpDns(): + def __init__(self, config, verbose=None): + self.verbose = verbose + self.dnsKeyFile = config['dnsKeyFile'] + self.dnsServer = config['dnsServer'] + self.dnsDomain = config['dnsDomain'] + self.dnsExpire = int(config['dnsExpire']) + self.dhcpServer = config['dhcpServer'] + self.dhcpKeyName = config['dhcpKeyName'] + self.dhcpSecretKey = config['dhcpSecretKey'] + #exit() + #items.sort() + #self.ipRange = {} + #for item in items: + #(name, value) = item + #name = name.lower() + #if (name.startswith('iprange')): + #network = name[7:] + #try: + #network = int(network) + #except: + #continue + #self.ipRange[network] = value + self.reverseDns = True + #self.log = logging.getLogger(__file__) + #self.ipMin = {} + #self.ipMax = {} + #self.currentIP = {} + #self.usedIPs = {} + #for k in self.ipRange: + #ipRange = self.ipRange[k] + #(min, max) = ipRange.split("-") + #min = min.strip() + #max = max.strip() + #ipNum = self.strToIp(min) + #self.ipMin[k] = self.strToIp(min) + #self.ipMax[k] = self.strToIp(max) + #self.currentIP[k] = self.ipMin[k] + #instances = self.client.getInstances() + #for i in instances: + #for nic in i.nics: + #try: + #ip = nic.ip + #ipNum = self.strToIp(ip) + #self.log.info('Added %s->%s during reinitialization' % (i.name, ip)) + #self.usedIPs[ipNum] = ip + #except Exception, e: + #pass + # + def strToIp(self, s): + ipNum = -1 + try: + ipNum = reduce(lambda x, y: x*256+y, map(int, s.split("."))) + except: + pass + return ipNum + + def ipToStr(self, ip): + return "%d.%d.%d.%d" % (ip>>24, (ip>>16)%256, (ip>>8)%256, ip%256) + + def allocateIP(self, nic): + network = nic.network + allocatedIP = None + requestedIP = self.strToIp(nic.ip) + if (requestedIP <= self.ipMax[network] and requestedIP >= self.ipMin[network] and (requestedIP not in self.usedIPs)): + allocatedIP = requestedIP + while (allocatedIP == None): + if (self.currentIP[network] > self.ipMax[network]): + self.currentIP[network] = self.ipMin[network] + elif (self.currentIP[network] in self.usedIPs): + self.currentIP[network] = self.currentIP[network] + 1 + else: + allocatedIP = self.currentIP[network] + ipString = self.ipToStr(allocatedIP) + self.usedIPs[allocatedIP] = ipString + return ipString + + def addDhcp(self, name, ipaddr, hwaddr): + try: + self.removeDhcp(name) + self.removeDhcp(name, ipaddr) + except: + pass + cmd = "omshell" + (stdin, stdout) = os.popen2(cmd) + stdin.write("server %s\n" % (self.dhcpServer)) + if (self.dhcpSecretKey != ""): + stdin.write("key %s %s\n" % (self.dhcpKeyName, self.dhcpSecretKey)) + stdin.write("connect\n") + stdin.write("new \"host\"\n") + stdin.write("set name = \"%s\"\n" % (name)) + stdin.write("set ip-address = %s\n" % (ipaddr)) + stdin.write("set hardware-address = %s\n" % (hwaddr)) + stdin.write("set hardware-type = 00:00:00:01\n") # Ethernet + stdin.write("create\n") + stdin.close() + output = stdout.read() + print output + stdout.close() + + def removeDhcp(self, name, ipaddr=None): + cmd = "omshell" + (stdin, stdout) = os.popen2(cmd) + stdin.write("server %s\n" % (self.dhcpServer)) + if (self.dhcpSecretKey != ""): + stdin.write("key %s %s\n" % (self.dhcpKeyName, self.dhcpSecretKey)) + stdin.write("connect\n") + stdin.write("new \"host\"\n") + if (ipaddr == None): + stdin.write("set name = \"%s\"\n" % (name)) + else: + stdin.write("set ip-address = %s\n"%(ipaddr)) + stdin.write("open\n") + stdin.write("remove\n") + stdin.close() + output = stdout.read() + print output + stdout.close() + + def addDns(self, name, ip): + try: + self.removeDns(name) + except Exception, e: + pass + #print "Removal of DNS entry failed. Did you use sudo? " + #return 1 + + if (self.dnsKeyFile != ""): + cmd = "nsupdate -k %s" % (self.dnsKeyFile) + else: + cmd = "nsupdate" + child = subprocess.Popen(args=cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE) + try: + (stdin, stdout) = (child.stdin, child.stdout) + stdin.write("server %s\n" % (self.dnsServer)) + stdin.write("update add %s.%s %d A %s\n" % (name, self.dnsDomain, self.dnsExpire, ip)) + stdin.write("\n") + if (self.reverseDns): + ipSegments = map(int, ip.split(".")) + ipSegments.reverse() + reverseIpStr = ("%d.%d.%d.%d.in-addr.arpa" % (ipSegments[0], ipSegments[1], ipSegments[2], ipSegments[3])) + stdin.write("update add %s %d IN PTR %s.%s.\n" % (reverseIpStr, self.dnsExpire, name, self.dnsDomain)) + stdin.write("\n") + stdin.close() + output = stdout.read() + stdout.close() + finally: + os.kill(child.pid, signal.SIGTERM) + (pid, status) = os.waitpid(child.pid, os.WNOHANG) + while (pid == 0): + time.sleep(0.5) + os.kill(child.pid, signal.SIGTERM) + (pid, status) = os.waitpid(child.pid, os.WNOHANG) + + def removeDns(self, name): + if (self.dnsKeyFile != ""): + cmd = "nsupdate -k %s" % (self.dnsKeyFile) + else: + cmd = "nsupdate" + child = subprocess.Popen(args=cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE) + try: + (stdin, stdout) = (child.stdin, child.stdout) + stdin.write("server %s\n" % (self.dnsServer)) + if (self.reverseDns): + ip = socket.gethostbyname(name) + ipSegments = map(int, ip.split(".")) + ipSegments.reverse() + reverseIpStr = ("%d.%d.%d.%d.in-addr.arpa" % (ipSegments[0], ipSegments[1], ipSegments[2], ipSegments[3])) + stdin.write("update delete %s IN PTR\n" % (reverseIpStr)) + stdin.write("\n") + stdin.write("update delete %s.%s A\n" % (name, self.dnsDomain)) + stdin.write("\n") + stdin.close() + output = stdout.read() + stdout.close() + finally: + os.kill(child.pid, signal.SIGTERM) + (pid, status) = os.waitpid(child.pid, os.WNOHANG) + while (pid == 0): + time.sleep(0.5) + os.kill(child.pid, signal.SIGTERM) + (pid, status) = os.waitpid(child.pid, os.WNOHANG) + + def doUpdate(self, instance): + newInstance = Instance() + newInstance.id = instance.id + newInstance.nics = instance.nics + self.client.vmUpdate(instance.id, newInstance, None) + + def preCreate(self, instance): + if (len(instance.nics) < 1): + return + for i in range(0, len(instance.nics)): + nic = instance.nics[i] + ip = self.allocateIP(nic) + nic.ip = ip + try: + if (i == 0): + self.log.info("Adding %s:{%s->%s} to DNS" % (instance.name, instance.name, ip)) + self.addDns(instance.name, ip) + if (i == 0): + dhcpName = instance.name + else: + dhcpName = instance.name + "-nic%d" % (i) + self.log.info("Adding %s:{%s->%s} to DHCP" % (dhcpName, nic.mac, ip)) + self.addDhcp(dhcpName, ip, nic.mac) + except Exception, e: + self.log.exception("Failed to add host %s to DHCP/DNS" % (instance.name)) + self.doUpdate(instance) + + def postDestroy(self, instance): + if (len(instance.nics) < 1): + return + self.log.info("Removing %s from DHCP/DNS" % (instance.name)) + for i in range(0, len(instance.nics)): + nic = instance.nics[i] + ip = nic.ip + try: + ipNum = self.strToIp(ip) + del self.usedIPs[ipNum] + except Exception, e: + self.log.exception("Failed to remove host %s, ip %s from pool of usedIPs" % (instance.name, ip)) + try: + if (i == 0): + dhcpName = instance.name + else: + dhcpName = instance.name + "-nic%d" % (i) + self.removeDhcp(dhcpName) + except Exception, e: + self.log.exception("Failed to remove host %s from DHCP" % (instance.name)) + try: + self.removeDns(instance.name) + except Exception, e: + self.log.exception("Failed to remove host %s from DNS" % (instance.name)) Added: incubator/tashi/import/zoni-intel-r843/hwswitch.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/hwswitch.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/hwswitch.py (added) +++ incubator/tashi/import/zoni-intel-r843/hwswitch.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,359 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import os +import sys +import pexpect +import datetime +import thread + + +from hwswitchinterface import HwSwitchInterface +from resourcequerysql import ResourceQuerySql +from util import logit + + +''' Using pexpect to control switches because couldn't get snmp to work +''' + +class HwDellSwitch(HwSwitchInterface): + def __init__(self, config, host=None): + self.host = host + self.verbose = False + self.logFile = config['logFile'] + + + def setVerbose(self, verbose): + self.verbose = verbose + + def __login(self): + + switchIp = "ssh " + self.host['hw_userid'] + "@" + self.host['hw_name'] + child = pexpect.spawn(switchIp) + opt = child.expect(['Name:', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + print "opt is ", opt + #XXX Doesn't seem to do what I want:( + child.setecho(False) + if opt == 0: + child.sendline(self.host['hw_userid']) + #i=child.expect(['test','password:','Password:', pexpect.EOF, pexpect.TIMEOUT]) + + # Be Verbose and print everything + if self.verbose: + child.logfile = sys.stdout + + child.sendline(self.host['hw_password']) + i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT]) + if i == 2: + mesg = "ERROR: Login failed\n" + logit(self.logFile, mesg) + + sys.stderr.write() + exit(1) + # on the 6448 dell, need to send enable + if opt == 1: + child.sendline('enable') + i=child.expect(['#', pexpect.EOF, pexpect.TIMEOUT]) + + return child + + def __getPrsLabel(self): + dadate = datetime.datetime.now().strftime("%Y%m%d-%H%M-%S") + return "PRS_" + dadate + + + def enableHostPort(self): + child = self.__login() + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + cmd = "no shutdown" + child.sendline(cmd) + child.sendline('exit') + child.terminate() + + def disableHostPort(self): + child = self.__login() + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + cmd = "shutdown" + child.sendline(cmd) + child.sendline('exit') + child.terminate() + + def removeVlan(self, num): + # Check for important vlans + + cmd = "no vlan " + num + child = self.__login() + child.sendline('config') + child.sendline('vlan database') + child.sendline(cmd) + child.sendline('exit') + child.terminate() + + def addVlanToTrunk(self, vlan): + mesg = "Adding Vlan to trunks on switch" + logit(self.logFile, mesg) + child = self.__login() + child.sendline('config') + cmd = "interface range port-channel all" + child.sendline(cmd) + child.expect(["config-if", pexpect.EOF]) + cmd = "switchport trunk allowed vlan add " + vlan + child.sendline(cmd) + child.sendline('exit') + + def createVlansThread(self, vlan, switch,host): + mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch) + print "host is ", host + logit(self.logFile, mesg) + print "create" + self.createVlan(vlan) + print "cend" + self.addVlanToTrunk(vlan); + thread.exit() + + def createVlans(self, vlan, switchlist, query): + for switch in switchlist: + #print "working on switch ", switch + #self.host = query.getSwitchInfo(switch) + #thread.start_new_thread(self.createVlansThread, (vlan, switch, self.host)) + mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch) + logit(self.logFile, mesg) + self.host = query.getSwitchInfo(switch) + self.createVlan(vlan) + self.addVlanToTrunk(vlan); + + def removeVlans(self, vlan, switchlist, query): + for switch in switchlist: + mesg = "Deleting vlan " + str(vlan) + " on switch " + str(switch) + logit(self.logFile, mesg) + self.host = query.getSwitchInfo(switch) + self.removeVlan(vlan) + + def createVlan(self, val): + + vlanname = False + if ":" in val: + num = int(val.split(":")[0]) + vlanname = val.split(":")[1] + else: + vlanname = self.__getPrsLabel() + num = int(val) + + #if type(num) != int: + #mesg = "ERROR: Vlan must be a number (0-4095)\n" + #sys.stderr.write(mesg) + #exit(1) + if num > 4095 or num < 0: + mesg = "ERROR: Vlan out of range. Must be < 4095" + logit(self.logFile, mesg) + exit(1) + + child = self.__login() + child.sendline('config') + child.expect(["config",pexpect.EOF, pexpect.TIMEOUT]) + child.sendline('vlan database') + child.expect(["config-vlan",pexpect.EOF, pexpect.TIMEOUT]) + cmd = "vlan " + str(num) + child.sendline(cmd) + child.sendline('exit') + child.expect(["config",pexpect.EOF, pexpect.TIMEOUT]) + + if vlanname: + cmd = "interface vlan " + str(num) + child.sendline(cmd) + child.expect(["config-if",pexpect.EOF, pexpect.TIMEOUT]) + cmd = "name " + vlanname + child.sendline(cmd) + child.expect(["config-if",pexpect.EOF, pexpect.TIMEOUT]) + + child.sendline('exit') + child.sendline('exit') + + # Raw Switch commands. DEBUG ONLY!, Doesn't work! + def sendSwitchCommand(self, cmds): + if len(cmds) > 0: + child = self.__login() + child.logfile = sys.stdout + for cmd in cmds.split(";"): + child.sendline(cmd) + try: + i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2) + i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2) + + except EOF: + print "EOF", i + #child.sendline() + except TIMEOUT: + print "TIMEOUT", i + #child.interact(escape_character='\x1d', input_filter=None, output_filter=None) + + child.terminate() + #print "before", child.before + #print "after", child.after + + def addNodeToVlan(self, vlan): + print "Adding Node to vlan ", vlan + child = self.__login() + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + child.expect(["config-if", pexpect.EOF]) + cmd = "switchport trunk allowed vlan add " + vlan + child.sendline(cmd) + child.sendline('exit') + + NOVLAN = "VLAN was not created by user." + i=child.expect(['config-if',NOVLAN, pexpect.EOF, pexpect.TIMEOUT]) + # Vlan must exist in order to add a host to it. + # If it doesn't exist, try to create it + if i == 1: + sys.stderr.write("WARNING: Vlan doesn't exist, trying to create\n") + # Add a tag showing this was created by PRS + newvlan = vlan + ":" + self.__getPrsLabel() + self.createVlan(newvlan) + self.addNodeToVlan(vlan) + + child.sendline('exit') + child.sendline('exit') + child.terminate() + sys.stdout.write("Success\n") + + def removeNodeFromVlan(self, vlan): + child = self.__login() + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + cmd = "switchport trunk allowed vlan remove " + vlan + child.sendline(cmd) + child.sendline('exit') + child.sendline('exit') + child.terminate() + + + #def __checkVlan(self, child, vlan): + #NO_VLAN_EXISTS = "VLAN was not created by user." + #i=child.expect(['config',NO_VLAN_EXISTS, pexpect.EOF, pexpect.TIMEOUT]) + #print "i is ", i + #if i == 1: + #sys.stderr.write("WARNING: Vlan doesn't exist, trying to create") + #i=child.expect(['config',NO_VLAN_EXISTS, pexpect.EOF, pexpect.TIMEOUT]) + #return "NOVLAN" + ##newvlan = vlan + ":CREATED_BY_PRS" + ##self.createVlan(newvlan) + ##self.setNativeVlan(vlan) + + + def setNativeVlan(self, vlan): + child = self.__login() + child.logfile = sys.stdout + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + i=child.expect(['config-if', pexpect.EOF, pexpect.TIMEOUT]) + if i > 0: + sys.stderr.write("ERROR: setNativeVlan ", cmd, " failed\n") + + NOVLAN = "VLAN was not created by user." + cmd = "switchport trunk native vlan " + vlan + child.sendline(cmd) + i=child.expect(['config-if', NOVLAN, pexpect.EOF, pexpect.TIMEOUT]) + # Vlan must exist in order to add a host to it. + # If it doesn't exist, try to create it + if i == 1: + sys.stderr.write("WARNING: Vlan doesn't exist, trying to create") + # Add a tag showing this was created by PRS + newvlan = vlan + ":" + self.__getPrsLabel() + self.createVlan(newvlan) + self.setNativeVlan(vlan) + + child.sendline('exit') + child.sendline('exit') + child.terminate() + + # Restore Native Vlan. In Dell's case, this is vlan 1 + def restoreNativeVlan(self): + child = self.__login() + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + cmd = "switchport trunk native vlan 1" + child.sendline(cmd) + child.sendline('exit') + child.sendline('exit') + #child.terminate() + child.terminate() + + # Setup the switch for node allocation + def allocateNode(self): + pass + + # Remove all vlans from the interface + def removeAllVlans(self): + child = self.__login() + child.logfile = sys.stdout + child.sendline('config') + cmd = "interface ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + i=child.expect(['config-if', pexpect.EOF, pexpect.TIMEOUT]) + if i > 0: + sys.stderr.write("ERROR: setNativeVlan ", cmd, " failed\n") + + NOVLAN = "VLAN was not created by user." + cmd = "switchport trunk allowed vlan remove all" + child.sendline(cmd) + i=child.expect(['config-if', NOVLAN, pexpect.EOF, pexpect.TIMEOUT]) + # Vlan must exist in order to add a host to it. + # If it doesn't exist, try to create it + if i == 1: + pass + + child.sendline('exit') + child.sendline('exit') + child.terminate() + + def showInterfaceConfig(self): + child = self.__login() + print "\n------------------------------------" + print "SWITCH - " + self.host['hw_name'] + "/" + str(self.host['hw_port']) + print "NODE - " + self.host['location'] + print "------------------------------------\n" + child.logfile = sys.stdout + cmd = "show interface switchport ethernet g" + str(self.host['hw_port']) + child.sendline(cmd) + i = child.expect(['sw(.*)', pexpect.EOF, pexpect.TIMEOUT]) + i = child.expect(['sw(.*)', pexpect.EOF, pexpect.TIMEOUT]) + child.terminate() + + def interactiveSwitchConfig(self): + switchIp = "ssh " + self.host['hw_name'] + child = pexpect.spawn(switchIp) + child.setecho(False) + #child.expect('Name:') + child.sendline(self.host['hw_userid']) + #i=child.expect(['test','password:','Password:', pexpect.EOF, pexpect.TIMEOUT]) + #child.logfile = sys.stdout + child.sendline(self.host['hw_password']) + child.interact(escape_character='\x1d', input_filter=None, output_filter=None) + + Added: incubator/tashi/import/zoni-intel-r843/hwswitchinterface.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/hwswitchinterface.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/hwswitchinterface.py (added) +++ incubator/tashi/import/zoni-intel-r843/hwswitchinterface.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,65 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os + +class HwSwitchInterface(object): + """ Interface description for hardware switches + - Dell + """ + def __init__(self, configFile, hostInst = None): + ''' + hostInst is all data that makes up a host + hw_port - port number node is connected to + hw_userid - userid node uses to configure switch + hw_password - userid node uses to configure switch + hw_name - switch name node is connected to + ''' + #self.host = hostInst + + + def enablePort(self): + raise NotImplementedError + + def disablePort(self): + raise NotImplementedError + + def removeVlan(self, vlan): + raise NotImplementedError + + def createVlan(self, vlan): + raise NotImplementedError + + def addNode2Vlan(self, vlan): + raise NotImplementedError + + def removeNodeFromVlan(self, vlan): + raise NotImplementedError + + def addNativeVlan(self, vlan): + raise NotImplementedError + + def restoreNativeVlan(self): + raise NotImplementedError + + def isolateNetwork(self): + raise NotImplementedError + Added: incubator/tashi/import/zoni-intel-r843/infostore.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/infostore.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/infostore.py (added) +++ incubator/tashi/import/zoni-intel-r843/infostore.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,58 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os +import optparse + + +class InfoStore (object): + """ Interface description for query system resources + """ + def __init__(self, config): + self.config = config + + #def updateDatabase(self, query): + #raise NotImplementedError + + + def printAll(self): + raise NotImplementedError + + def showResources(self, cmdargs): + raise NotImplementedError + + def printResources(self): + raise NotImplementedError + + def showAllocation(self): + raise NotImplementedError + + def showPxeImages(self): + raise NotImplementedError + + def showPxeImagesToSystemMap(self): + raise NotImplementedError + + def getHwAccessMethod(self): + ''' Get hardware access method and return a list + ''' + raise NotImplementedError + Added: incubator/tashi/import/zoni-intel-r843/ipmi.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/ipmi.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/ipmi.py (added) +++ incubator/tashi/import/zoni-intel-r843/ipmi.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,105 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os + +from systemmanagementinterface import SystemManagementInterface + + +#class systemmagement(): + #def __init__(self, proto): + #self.proto = proto + +class Ipmi(SystemManagementInterface): + def __init__(self, host, user, password): + self.host = host + "-ipmi" + self.password = password + self.user = user + self.powerStatus = None + self.verbose = False + self.ipmicmd = "ipmitool -I lanplus -U" + self.user + " -H" + self.host + \ + " -P " + self.password + " " + + + def setVerbose(self, verbose): + self.verbose = verbose + + def getPowerStatus(self): + if self.verbose: + print self.ipmicmd + cmd = self.ipmicmd + "chassis power status" + a = os.popen(cmd) + output = a.read() + + print "%s\n%s" % (self.host, output) + if "off" in output: + self.powerStatus = 0 + if "on" in output: + self.powerStatus = 1 + if "Unable" in output: + print "unable to get the status" + self.powerStatus = 0 + + return output + #return a.read() + #for line in a.readlines(): + #print line + + def isPowered(self): + if self.powerStatus == None: + self.getPowerStatus() + if self.powerStatus: + return 1; + if not self.powerStatus: + return 0; + + + def powerOn(self): + cmd = self.ipmicmd + "chassis power on" + a = os.popen(cmd) + output = a.read() + print "output is ", output + + def powerOff(self): + cmd = self.ipmicmd + "chassis power off" + a = os.popen(cmd) + output = a.read() + print "output is ", output + + def powerCycle(self): + cmd = self.ipmicmd + "chassis power cycle" + a = os.popen(cmd) + output = a.read() + print "output is ", output + + def powerReset(self): + cmd = self.ipmicmd + "chassis power reset" + a = os.popen(cmd) + output = a.read() + print "output is ", output + + def activateConsole(self): + cmd = self.ipmicmd + "sol activate" + a = os.popen(cmd) + output = a.read() + print "output is ", output + +#ipmitool -I lanplus -E -H r2r1c3b0-ipmi -U root chassis power status Added: incubator/tashi/import/zoni-intel-r843/phyassigninterface.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/phyassigninterface.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/phyassigninterface.py (added) +++ incubator/tashi/import/zoni-intel-r843/phyassigninterface.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,39 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os + + +class PhyAssignInterface(object): + """ Interface description for query system resources + """ + def __init__(self, config): + self.config = config + + + def assignImage(self): + raise NotImplementedError + + def reservePhy(self): + raise NotImplementedError + + def uploadImage(self): + raise NotImplementedError Added: incubator/tashi/import/zoni-intel-r843/pxe.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/pxe.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/pxe.py (added) +++ incubator/tashi/import/zoni-intel-r843/pxe.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,100 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import os +import sys +import string +import datetime +import subprocess +import MySQLdb +import traceback + +from util import logit +from bootmanagementinterface import BootManagementInterface + +class Pxe(BootManagementInterface): + def __init__(self, config, verbose=None): + self.verbose = verbose + self.host = config['dbHost'] + self.user = config['dbUser'] + self.passwd = config['dbPassword'] + self.db = config['dbInst'] + + self.tftpRootDir = config['tftpRootDir'] + self.tftpImageDir = config['tftpImageDir'] + self.tftpBootOptionsDir = config['tftpBootOptionsDir'] + self.tftpUpdateFile = config['tftpUpdateFile'] + self.tftpBaseFile = config['tftpBaseFile'] + self.tftpBaseMenuFile = config['tftpBaseMenuFile'] + + self.logFile = config['logFile'] + + if config['dbPort'] == "": + config['dbPort'] = 3306 + + self.port = config['dbPort'] + + self.vlan_max = config['vlan_max'] + self.vlan_reserved = config['vlan_reserved'] + + # Connect to DB + self.conn = MySQLdb.connect(host = self.host, port = self.port, user = self.user, passwd = self.passwd, db = self.db) + #cursor.execute ("SELECT VERSION()") + #print "server version:", row[0] + #mysql -Dirp-cluster -hrodimus -u reader -e "select * from hostinfo;" + + + + + ''' This will create the update file tftpUpdateFile used to generate all the pxe boot files + pass in a list of available images + ''' + def createPxeUpdateFile (self, images): + try: + f = open(self.tftpUpdateFile, "w") + except Exception: + traceback.print_exc(sys.exc_info()) + + dadate = datetime.datetime.now().strftime("%Y%m%d.%H%M.%S") + val = "# Generated by PRS : " + dadate + f.write(val) + for image in images: + val = "\n# IMAGE " + image + "\n" + f.write(val) + base = "cat " + self.tftpBaseFile + " | sed 's/MAGIC1/" + image + "/' > " + self.tftpBootOptionsDir + "/" + image + "\n" + basemenu= "cat " + self.tftpBaseMenuFile + " | sed 's/LABEL " + image + "/LABEL " + image + "\\n\\tMENU DEFAULT/' > " + self.tftpBootOptionsDir + "/" + image + "-menu\n" + f.write(base) + f.write(basemenu) + f.close() + + + def updatePxe(self): + cmd = "chmod 755 " + self.tftpUpdateFile + try: + os.system(cmd) + except Exception: + traceback.print_exc(sys.exc_info()) + + cmd = self.tftpUpdateFile + try: + os.system(cmd) + except Exception: + traceback.print_exc(sys.exc_info()) + Added: incubator/tashi/import/zoni-intel-r843/raritanpdu.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/raritanpdu.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/raritanpdu.py (added) +++ incubator/tashi/import/zoni-intel-r843/raritanpdu.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,121 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os +from pysnmp.entity.rfc3413.oneliner import cmdgen +from pysnmp.proto import rfc1902 + +#import netsnmp + +from systemmanagementinterface import SystemManagementInterface + + +#class systemmagement(): + #def __init__(self, proto): + #self.proto = proto + +class raritanDominionPx(SystemManagementInterface): + def __init__(self, host): + self.host = host['location'] + self.pdu_name = host['pdu_name'] + self.port = host['pdu_port'] + self.user = host['pdu_userid'] + self.password = host['pdu_password'] + self.oid = "1,3,6,1,4,1,13742,4,1,2,2,1" + self.oid_name = ",2" + self.oid_set = ",3" + self.oid_status = ",3" + # this works + #errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd(cmdgen.CommunityData('my-agent', 'public', 0), cmdgen.UdpTransportTarget(('pdu0-r1r1', 161)), (1,3,6,1,4,1,13742,4,1,2,2,1,3,2)) + + #print varBinds + #oid = netsnmp.Varbind('sysDescr') + #result = netsnmp.snmpwalk(oid, Version = 2,DestHost="localhost",Community="public") + #print result + + + + + + #var = netsnmp.Varbind('sysDescr.0') + #res = netsnmp.snmpget(var, ...:Version=1,...:DestHost = 'pdu0-r1r1',...: Community = 'prs-domain') + #print res + + #print cmdgen + #set snmp = /usr/bin/snmpset -v 2c -c intel pdu .1.3.6.1.4.1.13742.4.1.2.2.1.3.$outletnumber i $state + #name snmp = /usr/bin/snmpset -v 2c -c intel pdu .1.3.6.1.4.1.13742.4.1.2.2.1.2.$outletnumber i $state + #status snmp = /usr/bin/snmpset -v 2c -c intel pdu .1.3.6.1.4.1.13742.4.1.2.2.1.1.$outletnumber i $state + #self.snmp_status_oid = ".1.3.6.1.4.1.13742.4.1.2.2.1.1." + #self.powerStatus = None + #print self.__dict__ + + def getPowerStatus(self): + thisoid = eval(str(self.oid) + str(self.oid_status) + "," + str(self.port)) + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().getCmd( \ + cmdgen.CommunityData('my-agent', self.user, 0), \ + cmdgen.UdpTransportTarget((self.pdu_name, 161)), thisoid) + output = varBinds[0][1] + + if output == 1: + self.powerStatus = 1 + powerstat = "on" + if output == 0: + self.powerStatus = 0 + powerstat = "off" + + print "PDU Power for %s is %s" % (self.host, powerstat) + + if output: + return 1 + return 0 + + + def isPowered(self): + if self.powerStatus == None: + self.getPowerStatus() + if self.powerStatus: + return 1; + if not self.powerStatus: + return 0; + + + def powerOn(self): + thisoid = eval(str(self.oid) + str(self.oid_status) + "," + str(self.port)) + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().setCmd( \ + cmdgen.CommunityData('my-agent', self.user, 1), \ + cmdgen.UdpTransportTarget((self.pdu_name, 161)), \ + (thisoid, rfc1902.Integer('1'))) + self.getPowerStatus() + + def powerOff(self): + thisoid = eval(str(self.oid) + str(self.oid_status) + "," + str(self.port)) + errorIndication, errorStatus, errorIndex, varBinds = cmdgen.CommandGenerator().setCmd( \ + cmdgen.CommunityData('my-agent', self.user, 1), \ + cmdgen.UdpTransportTarget((self.pdu_name, 161)), \ + (thisoid, rfc1902.Integer('0'))) + self.getPowerStatus() + + def powerCycle(self): + self.powerOff() + self.powerOn() + + def powerReset(self): + self.powerCycle() Added: incubator/tashi/import/zoni-intel-r843/resourcequerysql.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/resourcequerysql.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/resourcequerysql.py (added) +++ incubator/tashi/import/zoni-intel-r843/resourcequerysql.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,961 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import os +import sys +import string +import MySQLdb +import subprocess +import traceback + +import usermanagement + +from infostore import InfoStore +from util import logit +from dhcpdns import DhcpDns + +def timeF(f): + def myF(*args, **kw): + start = time.time() + res = f(*args, **kw) + end = time.time() + print "%s took %f" % (f.__name__, end-start) + return res + myF.__name__ = f.__name__ + return myF + +def checkSuper(f): + def myF(*args, **kw): + if os.getuid() != 0: + print "Please use sudo!" + exit() + res = f(*args, **kw) + return res + return myF + +class ResourceQuerySql(InfoStore): + def __init__(self, config, verbose=None): + self.config = config + self.verbose = verbose + self.host = config['dbHost'] + self.user = config['dbUser'] + self.passwd = config['dbPassword'] + self.db = config['dbInst'] + + self.tftpRootDir = config['tftpRootDir'] + self.tftpImageDir = config['tftpImageDir'] + self.tftpBootOptionsDir = config['tftpBootOptionsDir'] + + self.logFile = config['logFile'] + + if config['dbPort'] == "": + config['dbPort'] = 3306 + + self.port = config['dbPort'] + + self.vlan_max = config['vlan_max'] + self.vlan_reserved = config['vlan_reserved'] + + # Connect to DB + try: + self.conn = MySQLdb.connect(host = self.host, port = self.port, user = self.user, passwd = self.passwd, db = self.db) + except MySQLdb.OperationalError, e: + if e[0] == 2005: + print "ZONI ERROR:" + str(e[1]) + exit(1) + #traceback.print_exc(sys.exc_info()) + #cursor.execute ("SELECT VERSION()") + #print "server version:", row[0] + #mysql -Dirp-cluster -hrodimus -u reader -e "select * from hostinfo;" + + #def gethost(self, host): + #obj = {} + #self.conn + #createConn() + # + + def __create_queryopts(self, cmdargs, extra=None): + cmdlen = len(cmdargs) + queryopt = "" + + if extra: + queryopt += extra + + if cmdlen == 0: + pass + else: + num = cmdlen + if extra: + queryopt += " and " + for k, v in cmdargs.iteritems(): + if k == "num_procs": + queryopt += k + " = " + v + " " + if k == "mem_total": + queryopt += k + " >= " + v + " " + if k == "clock_speed": + queryopt += k + " >= " + v + " " + if k == "num_cores": + queryopt += k + " = " + v + " " + if k == "cpu_flags": + queryopt += k + " like \"%" + v + "%\" " + if k == "node_id": + queryopt += " location = " + "\'" + v + "\' " + + if num > 1: + queryopt += " and " + + num -= 1 + + if queryopt: + tmp = " where " + queryopt + queryopt = tmp + + return queryopt + + def updateDatabase(self, table, query): + pass + + + def showResources(self, cmdargs): + + queryopt = "" + defaultFields = "mac_addr, location, num_procs, num_cores, clock_speed, mem_total " + #defaultFields = "*" + + queryopt = self.__create_queryopts(cmdargs) + + #query = "show fields from sysinfo" + #results = self.__selectDb(query) + + query = "select " + defaultFields + "from sysinfo " + queryopt + result = self.__selectDb(query) + + line = "" + for i in defaultFields.split(","): + #line += string.strip(str(i)) + "\t" + line += str(i.center(20)) + print line + + for row in result.fetchall(): + line = "" + for val in row: + line += str(val).center(20) + print line + print str(result.rowcount) + " systems returned" + + #mysql -h rodimus -u reader irp-cluster -e "select * from sysinfo where location like 'r1%' and num_procs = 1" + + def getLocationFromSysId (self, nodeId): + query = "select location from sysinfo where sys_id = \"" + str(nodeId) + "\"" + result = self.__selectDb(query) + return result.fetchall()[0][0] + + def getMacFromSysId(self, nodeId): + query = "select mac_addr from sysinfo where sys_id = \"" + str(nodeId) + "\"" + result = self.__selectDb(query) + return result.fetchall()[0][0] + + def getIpFromSysId(self, nodeId): + query = "select ip_addr from sysinfo where sys_id = \"" + str(nodeId) + "\"" + result = self.__selectDb(query) + return result.fetchall()[0][0] + + + def getAllSwitches(self): + switchList = [] + query = "select hw_name from hardwareinfo where hw_type = \"switch\"" + result = self.__selectDb(query) + for switch in result.fetchall(): + switchList.append(switch[0]) + + # Use static list until we get all switches installed + switchList = ['sw1-r1r2', 'sw0-r1r1', 'sw0-r1r2', 'sw0-r1r3', 'sw0-r1r4', 'sw0-r2r3', 'sw0-r3r3', 'sw0-r3r2', 'sw0-r2r1c3', 'sw2-r1r2'] + #switchList = ['sw2-r1r2'] + #switchList = ['sw1-r1r2'] + + + print switchList + + return switchList + + def getAvailableVlan(self): + # Get list of available vlans + query = "select vlan_num from vlaninfo where domain = 'private'" + result = self.__selectDb(query) + for vlan in result.fetchall()[0]: + avail = self.isVlanAvailable(vlan) + if avail: + myvlan = vlan + break + if not myvlan: + mesg = "No Vlans for you! You Go Now\n" + logit(self.logFile, mesg) + return myvlan + + def isVlanAvailable(self, vlan): + query = "select a.vlan_id, v.vlan_num from allocationinfo a, vlaninfo v where a.vlan_id = v.vlan_id and v.vlan_num = " + str(vlan) + result = self.__selectDb(query) + if result.rowcount > 1: + return 0 + else: + return 1 + + def getVlanId(self, vlan): + query = "select vlan_id from vlaninfo where vlan_num = \"" + str(vlan) + "\"" + result = self.__selectDb(query) + #print result.rowcount + if result.rowcount > 0: + return result.fetchall()[0][0] + else: + mesg = "ERROR: VLAN does not exist: " + str(vlan) + logit(self.logFile, mesg) + exit() + + def isIpAvailable(self, ip_addr, vlan_id): + query = "select * from allocationinfo where ip_addr = \"" + str(ip_addr) + "\" and vlan_id = \"" + str(vlan_id) + "\"" + #print "query ", query + result = self.__selectDb(query) + #print "select row count is ", result.rowcount + if result.rowcount > 0: + return 0 + else: + return 1 + + + def getDomainIp(self, vlan): + ip_start = 30 + query = "select ip_network from vlaninfo where vlan_num = " + str(vlan) + result = self.__selectDb(query) + ip_network = result.fetchall()[0][0] + v = ip_network.split(".") + ip_base = v[0] + "." + v[1] + "." + v[2] + + # Check for other allocations and assign IP address + query = "select a.vlan_id, v.vlan_num from allocationinfo a, vlaninfo v where a.vlan_id = v.vlan_id and v.vlan_num = " + str(vlan) + #print "ip is ", ip_network + + query = "select a.ip_addr from allocationinfo a, vlaninfo v where a.vlan_id = v.vlan_id and v.vlan_num = " + str(vlan); + result = self.__selectDb(query) + #print "row count is ", result.rowcount + if result.rowcount > 0: + for ip in xrange(ip_start, 255): + ip_check = ip_base + "." + str(ip) + check = self.isIpAvailable(ip_check, self.getVlanId(vlan)) + if check: + ip_addr = ip_check + break + else: + ip_addr = ip_base + "." + str(ip_start) + #print "ip_addr", ip_addr + + return ip_addr + + + def showArchive(self): + query = "select * from allocationarchive" + result = self.__selectDb(query) + for i in result: + print i + + def showAllocation(self, userId=None): + #from IPython.Shell import IPShellEmbed + #shell = IPShellEmbed(argv="") + #shell(local_ns=locals(), global_ns=globals()) + + # specify usermanagement - ldap or files + usermgt = usermanagement.ldap() + + query = "select r.user_id, s.location, s.num_cores, s.mem_total, \ + r.reservation_expiration, r.notes, r.reservation_id, v.vlan_num, a.ip_addr, a.hostname,\ + a.notes, i.image_name \ + from allocationinfo a, sysinfo s, reservationinfo r, vlaninfo v, imageinfo i, imagemap m where \ + s.mac_addr = m.mac_addr and \ + m.image_id = i.image_id and \ + s.sys_id = a.node_id and \ + v.vlan_id = a.vlan_id and \ + r.reservation_id = a.reservation_id " + if userId: + myid = userId + if type(userId) == str: + # convert username to id + myid = usermgt.getUserId(userId) + + query += " and user_id = " + myid + " " + + query += "order by r.reservation_id asc, s.location" + + result = self.__selectDb(query) + + print "NODE ALLOCATION" + print "---------------------------------------------------------------------------------" + if self.verbose: + #print "Res_id\tUser \tNode \tCores\tMemory \tExpiration\t\tVLAN\tHOSTNAME \tIPADDR \t\tReservationNotes|AllocationNotes" + print "%-5s%-10s%-10s%-12s%-12s%-5s%-15s%-18s%-24s%s" % ("Res", "User", "Host", "Cores/Mem","Expiration", "Vlan", "Hostname", "IP Addr", "Boot Image Name", "Notes") + else: + print "%-10s%-10s%-12s%-12s%s" % ("User", "Node", "Cores/Mem","Expiration", "Notes") + + for i in result.fetchall(): + uid = i[0] + host = i[1] + cores = i[2] + memory = i[3] + expire = str(i[4])[0:10] + if expire == "None": + expire = "0000-00-00" + rnotes = i[5] + resId= i[6] + vlanId= i[7] + ip_addr = i[8] + hostname = i[9] + anotes = i[10] + image_name = i[11] + userName = usermgt.getUserName(uid) + combined_notes = str(rnotes) + "|" + str(anotes) + if self.verbose: + #print "%s\t%s \t%s \t%s\t%s \t%s\t%s\t%s \t%s \t%s" % (resId, userName, host, cores, memory,expire, vlanId, hostname, ip_addr, combined_notes) + print "%-5s%-10s%-10s%-2s%-10s%-12s%-5s%-15s%-18s%-24s%s" % (resId, userName, host, cores, memory,expire, vlanId, hostname, ip_addr, image_name, combined_notes) + else: + print "%-10s%-10s%-2s%-10s%-12s%s" % (userName, host, cores, memory,expire, combined_notes) + print "---------------------------------------------------------------------------------" + print str(result.rowcount) + " systems returned" + + def showReservation(self, userId=None): + #from IPython.Shell import IPShellEmbed + #shell = IPShellEmbed(argv="") + #shell(local_ns=locals(), global_ns=globals()) + + # specify usermanagement - ldap or files + usermgt = usermanagement.ldap() + + query = "select reservation_id, user_id, \ + reservation_expiration, notes \ + from reservationinfo order by reservation_id" + if self.verbose: + query = "select r.reservation_id, r.user_id, r.reservation_expiration, r.notes, count(a.reservation_id) \ + from reservationinfo r, allocationinfo a \ + where r.reservation_id = a.reservation_id \ + group by r.reservation_id order by reservation_id" + #if userId: + #myid = userId + #if type(userId) == str: + ## convert username to id + #myid = usermgt.getUserId(userId) + + #query += " and user_id = " + myid + " " + + #query += "order by r.user_id, s.location" + + result = self.__selectDb(query) + + print "RESERVATIONS" + print "---------------------------------------------------------------------------------" + if self.verbose: + print "%-7s%-10s%-12s%-7s%s" % ("ResId", "UserName", "Expire", "Total", "Notes") + else: + print "%-7s%-10s%-12s%s" % ("ResId", "UserName", "Expire", "Notes") + + total = 0 + for i in result.fetchall(): + resId= i[0] + uid = i[1] + expire = str(i[2])[0:10] + if expire == "None": + expire = "0000-00-00" + notes = i[3] + userName = usermgt.getUserName(uid) + if self.verbose: + num_nodes = i[4] + total += num_nodes + #print "%s \t%s \t%s\t%s\t\t%s " % (resId, userName, expire, num_nodes, notes) + print "%-7s%-10s%-12s%-7s%s" % (resId, userName, expire, num_nodes, notes) + else: + print "%-7s%-10s%-12s%s" % (resId, userName, expire, notes) + if self.verbose: + print "---------------------------------------------------------------------------------" + print "Total number of nodes - %s" % (total) + + + def getPxeImages(self): + cursor = self.conn.cursor () + line = "select image_name from imageinfo" + cursor.execute (line) + row = cursor.fetchall() + desc = cursor.description + + imagelist = [] + for i in row: + imagelist.append(i[0]) + + return imagelist + + + def showPxeImages(self): + cursor = self.conn.cursor () + line = "select image_name, dist, dist_ver from imageinfo" + cursor.execute (line) + row = cursor.fetchall() + desc = cursor.description + + for i in row: + print i + + cursor.close () + + def showPxeImagesToSystemMap(self, cmdargs): + extra = "l.mac_addr = j.mac_addr and j.image_id = i.image_id" + queryopt = self.__create_queryopts(cmdargs, extra=extra) + print queryopt + + query = "select l.location, j.mac_addr, i.image_name from sysinfo l , imageinfo i, imagemap j " + queryopt + " order by l.location" + #print query + result = self.__selectDb(query) + + for i in result.fetchall(): + print i + + def close(self): + self.conn.close() + + def getHwAccessMethod(self): + pass + + mylist = [] + + return mylist + + def getHostInfo(self, node): + host = {} + query = "select * from sysinfo where location = \"" + node + "\"" + #print "query is ", query + result = self.__selectDb(query) + if result.rowcount > 1: + print "Mulitple entries for system exist. Please correct" + exit() + if result.rowcount < 1: + mesg = "node does not exist :" + str(node) + "\n" + sys.stderr.write(mesg) + exit() + + for i in result.fetchall(): + host['mac_addr'] = host.get("mac_addr", "") + host['node_id'] = int(i[0]) + host['mac_addr'] = i[1] + host['num_procs'] = int(i[2]) + host['num_cores'] = int(i[3]) + host['mem_total'] = int(i[6]) + host['clock_speed'] = int(i[8]) + host['sys_vendor'] = i[9] + host['sys_model'] = i[10] + host['proc_vendor'] = i[11] + host['proc_model'] = i[12] + host['proc_cache'] = i[13] + host['cpu_flags'] = i[15] + host['bios_rev'] = i[17] + host['location'] = i[16] + host['dell_tag'] = host.get("dell_tag", "") + host['dell_tag'] = i[14] + ''' + for k, v in host.iteritems(): + print k, v, "\n" + ''' + + # Get IPMI info + query = "select * from ipmiinfo where node_id = " + str(host['node_id']) + "" + result = self.__selectDb(query) + if result.rowcount> 1: + print "Mulitple entries for system exist. Please correct" + exit() + for i in result.fetchall(): + host['ipmi_user'] = i[2] + host['ipmi_password'] = i[3] + host['ipmi_addr'] = i[1] + + # Get image info + query = "select image_name from imagemap i, imageinfo j where i.image_id = j.image_id and mac_addr = \"" + host['mac_addr'] + "\"" + result = self.__selectDb(query) + if result.rowcount == 0: + host['pxe_image_name'] = "None" + else: + for i in result.fetchall(): + host['pxe_image_name'] = i[0] + + # Get switch info + query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password, p.port_num from hardwareinfo h, portmap p where p.hw_id = h.hw_id and hw_type = 'switch' and node_id = " + str(host['node_id']) + result = self.__selectDb(query) + for i in result.fetchall(): + host['hw_id'] = int(i[0]) + host['hw_name'] = i[1] + host['hw_model'] = i[2] + host['hw_ipaddr'] = i[3] + host['hw_userid'] = i[4] + host['hw_password'] = i[5] + host['hw_port'] = int(i[6]) + + # Get drac info + query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password, p.port_num from hardwareinfo h, portmap p where p.hw_id = h.hw_id and hw_type = 'drac' and node_id = " + str(host['node_id']) + result = self.__selectDb(query) + if result.rowcount > 0: + for i in result.fetchall(): + host['drac_id'] = int(i[0]) + host['drac_name'] = i[1] + host['drac_model'] = i[2] + host['drac_ipaddr'] = i[3] + host['drac_userid'] = i[4] + host['drac_password'] = i[5] + host['drac_port'] = int(i[6]) + + # Get PDU info + query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password, p.port_num from hardwareinfo h, portmap p where p.hw_id = h.hw_id and hw_type = 'pdu' and node_id = " + str(host['node_id']) + result = self.__selectDb(query) + for i in result.fetchall(): + host['pdu_id'] = int(i[0]) + host['pdu_name'] = i[1] + host['pdu_model'] = i[2] + host['pdu_ipaddr'] = i[3] + host['pdu_userid'] = i[4] + host['pdu_password'] = i[5] + host['pdu_port'] = int(i[6]) + + + #print "host is ", host + return host + + def getSwitchInfo(self, switchName): + host = {} + # Get switch info + #switchList = self.getAllSwitches() + query = "select h.hw_id, h.hw_name, h.hw_model, h.hw_ipaddr, h.hw_userid, h.hw_password from hardwareinfo h where h.hw_name = \"" + str(switchName) + "\"" + #print "query is ", query + result = self.__selectDb(query) + #desc = cursor.description + for i in result.fetchall(): + host['hw_id'] = int(i[0]) + host['hw_name'] = i[1] + host['hw_model'] = i[2] + host['hw_ipaddr'] = i[3] + host['hw_userid'] = i[4] + host['hw_password'] = i[5] + return host + + def __queryDb(self, query): + cursor = self.conn.cursor() + cursor.execute (query) + row = cursor.fetchall() + desc = cursor.description + return row + + def execQuery(self, query): + cursor = self.conn.cursor() + try: + cursor.execute (query) + #except Exception: + #traceback.print_exc(sys.exc_info()) + except MySQLdb.OperationalError, e: + msg = "ERROR: " + e[1] + sys.stderr.write(msg) + logit(self.logFile, msg) + #traceback.print_exc(sys.exc_info()) + exit() + return cursor + + def __selectDb(self, query): + cursor = self.conn.cursor() + try: + cursor.execute (query) + #except Exception: + #traceback.print_exc(sys.exc_info()) + except MySQLdb.OperationalError, e: + msg = "ERROR: " + e[1] + sys.stderr.write(msg) + logit(self.logFile, msg) + #traceback.print_exc(sys.exc_info()) + exit() + return cursor + + def __updateDb(self, query): + cursor = self.conn.cursor() + try: + cursor.execute (query) + except MySQLdb.OperationalError, e: + msg = "ERROR: " + e[1] + sys.stderr.write(msg) + logit(self.logFile, msg) + #traceback.print_exc(sys.exc_info()) + exit() + + def __insertDb(self, query): + cursor = self.conn.cursor() + try: + cursor.execute (query) + #except Exception: + #traceback.print_exc(sys.exc_info()) + except MySQLdb.OperationalError, e: + msg = "ERROR: " + e[1] + sys.stderr.write(msg) + logit(self.logFile, msg) + #traceback.print_exc(sys.exc_info()) + exit() + + + def updateReservation (self, reservationId, userId=None, reservationDuration=None, vlanIsolate=None, allocationNotes=None): + + + mesg = "Updating reservation" + logit(self.logFile, mesg) + + if reservationDuration: + if len(resDuration) == 8: + expireDate = resDuration + elif len(resDuration) < 4: + numdays = resDuration + cmd = "date +%Y%m%d --date=\"" + numdays + " day\"" + p = os.popen(cmd) + expireDate = string.strip(p.read()) + else: + mesg = "ERROR: Invalid reservation duration\n" + sys.stderr.write(mesg) + logit(self.logFile, mesg) + exit() + + mesg = "Updating reservationDuration :" + resDuration + logit(self.logFile, mesg) + query = "update reservationinfo set reservation_exiration = \"" + expireDate_ + "\" where reservation_id = \"" + str(reservationId) + "\"" + self.__updateDb(query) + + if allocationNotes: + mesg = "Updating allocationNotes to " + allocationNotes + logit(self.logFile, mesg) + query = "update reservationinfo set notes = \"" + allocationNotes + "\" where reservation_id = \"" + str(reservationId) + "\"" + self.__updateDb(query) + if vlanIsolate: + mesg = "UPDATING Vlan: " + logit(self.logFile, mesg) + query = "update reservationinfo set vlan_num = " + vlanIsolate + " where reservation_id = \"" + str(reservationId) + "\"" + print "query is ", query + self.__updateDb(query) + if userId: + mesg = "UPDATING USER:" + logit(self.logFile, mesg) + query = "update reservationinfo set user_id = " + userId + " where reservation_id = \"" + str(reservationId) + "\"" + self.__updateDb(query) + + def addReservation (self, userId, reservationDuration=None, reservationNotes=None): + + # set default for reservation duration to 15 days + if not reservationDuration: + resDuration = str(15) + else: + resDuration = str(reservationDuration) + + + if len(resDuration) == 8: + expireDate = resDuration + elif len(resDuration) < 4: + numdays = resDuration + cmd = "date +%Y%m%d --date=\"" + numdays + " day\"" + p = os.popen(cmd) + expireDate = string.strip(p.read()) + else: + mesg = "ERROR: Invalid reservation duration\n" + sys.stderr.write(mesg) + logit(self.logFile, mesg) + exit() + + # create reservation + # Create the reservation + print userId, expireDate,reservationNotes + query = "insert into reservationinfo (user_id, reservation_expiration, notes) values (\"" + str(userId) + "\", " + str(expireDate) + ", \"" + reservationNotes + "\")" + mesg = "Creating new reservation\n" + query + logit(self.logFile, mesg) + self.__selectDb(query) + # Get the res_id + query = "select max(reservation_id) from reservationinfo" + res_id = self.__selectDb(query).fetchone()[0] + mesg = " Reservation created - ID :" + str(res_id) + logit(self.logFile, mesg) + return res_id + + + def archiveAllocation(self, nodeId, ip_addr, hostName, vlan_id, user_id, reservation_type, res_notes, notes): + combined_notes = str(res_notes) + "|" + str(notes) + mesg = "Insert to allocation archive:" + query = "insert into allocationarchive (node_id, ip_addr, hostname, vlan_id, user_id, reservation_type, notes) \ + values (\"" + \ + str(nodeId) + "\", \"" + str(ip_addr) + "\", \"" + \ + str(hostName) + "\", \"" + str(vlan_id) + "\", \"" + \ + str(user_id) + "\", \"" + str(reservation_type) + "\", \"" + \ + str(combined_notes) + "\")" + + self.__insertDb(query) + + @checkSuper + def allocateNode(self, reservationId, nodeId, hostName, vlanIsolate=None, ip_addr=None, notes=None): + #print "nodeId", nodeId, self.getMacFromSysId(nodeId) + + # Check if node is already allocated + query = "select * from allocationinfo where node_id = \"" + str(nodeId) + "\"" + result = self.__selectDb(query) + if result.rowcount > 0: + val = str(result.fetchone()) + mesg = "ERROR: Node already allocated " + val + "\n" + logit(self.logFile, mesg) + exit() + + + # Check if reservation exists + + query = "select reservation_id, user_id, reservation_date, \ + reservation_expiration, notes from reservationinfo \ + where reservation_id = \"" + str(reservationId) + "\"" + result = self.__selectDb(query) + + if result.rowcount > 0: + res_results = result.fetchall()[0] + val = str(res_results) + res_id= res_results[0] + user_id = res_results[1] + res_notes = res_results[4] + if self.verbose: + mesg = "Reservation: " + val + logit(self.logFile, mesg) + else: + mesg = "ERROR: Reservation does not exist: " + reservationId + "\n" + logit(self.logFile, mesg) + exit() + + + if not vlanIsolate: + vlan = self.getAvailableVlan() + else: + vlan = vlanIsolate + + # Allocate nodes to the reservation + # Reserve the node and assign to user + vlan_id = self.getVlanId(vlan) + if vlan != 999: + if not ip_addr: + ip_addr = self.getDomainIp(vlan) + else: + # Check to see if IP is free + query = "select * from allocationinfo where ip_addr = \"" + str(ip_addr) + "\"" + result = self.__selectDb(query) + if result.rowcount > 0: + mesg = "ERROR: IP Address specified (" + str(ip_addr) + ") already in use\n" + mesg += str(result.fetchone()) + logit(self.logFile, mesg) + exit() + else: + ip_addr = self.getIpFromSysId(nodeId) + #print "ip is ", ip_addr + + # If there is no hostname, set to default + if not hostName: + hostName = self.getLocationFromSysId(nodeId) + + #print "hostname is ", hostName, "ip is ", ip_addr, "vlan is ", vlan_id + + # Assign IP address to node + dhcpdns = DhcpDns(self.config, verbose=1) + dnscheck = dhcpdns.addDhcp(hostName, ip_addr, self.getMacFromSysId(nodeId)) + dhcpdns.addDns(hostName, ip_addr) + + + mesg = "Insert to Node allocation:" + query = "insert into allocationinfo (reservation_id, node_id, ip_addr, hostname, vlan_id, notes) \ + values (\"" + str(reservationId) + "\", \"" + str(nodeId) + "\", \"" + \ + str(ip_addr) + "\", \"" + str(hostName) + "\", \"" + str(vlan_id) + "\", \"" + \ + str(notes) + "\")" + self.__insertDb(query) + + #Archive + reservation_type = "allocation" + self.archiveAllocation(nodeId, ip_addr, hostName, vlan_id, user_id, reservation_type, res_notes, notes) + + + def rgasstest(self, vlan_num): + query = "select * from vlaninfo where vlan_num = " + vlan_num + res = self.__selectDb(query).fetchall() + print res + + + + def removeReservation(self, res): + query = "delete from reservationinfo where reservation_id = " + str(res) + self.__updateDb(query) + query = "delete from allocationinfo where reservation_id = " + str(res) + self.__updateDb(query) + + @checkSuper + def releaseNode(self, nodeName): + # Get the nodeId + query = "select node_id, r.reservation_id, a.ip_addr, hostname, vlan_id, a.notes, r.notes,r.user_id from allocationinfo a, sysinfo s, reservationinfo r where a.node_id = s.sys_id and a.reservation_id = r.reservation_id and location = \"" + nodeName + "\"" + print query + result = self.__selectDb(query) + if result.rowcount == 0: + mesg = "ERROR: Node not allocated\n" + sys.stderr.write(mesg) + exit(1) + if result.rowcount > 1: + mesg = "WARNING: Node allocated multiple times (" + str(result.rowcount) + ")" + logit(self.logFile, mesg) + + val = result.fetchone() + nodeId = int(val[0]) + resId = int(val[1]) + ip_addr = val[2] + hostName = val[3] + vlan_id = int(val[4]) + allocation_notes = val[5] + reservation_notes = val[6] + user_id = val[7] + + print "hostname is ", hostName + # Assign IP address to node + dhcpdns = DhcpDns(self.config, verbose=1) + dnscheck = dhcpdns.removeDns(hostName) + dhcpdns.removeDhcp(hostName) + + ''' + query = "select reservation_id, notes from reservationinfo where node_id = " + str(nodeId) + result = self.__selectDb(query) + for i in result: + print i + print result.rowcount + if result.rowcount == 0: + mesg = "No Reservation for this node.\n Please check" + logit(self.logFile, mesg) + exit(1) + if result.rowcount > 1: + mesg = "WARNING: Muliple reservations exist (" + str(result.rowcount) + ")" + logit(self.logFile, mesg) + + resId = int(result.fetchone()[0]) + res_notes = int(result.fetchone()[1]) + + print resId, res_notes + ''' + + # Eventually should add count =1 so deletes do get out of control + query = "delete from allocationinfo where reservation_id = " + str(resId) + " and node_id = " + str(nodeId) + result = self.__selectDb(query) + + # Archive node release + reservation_type = "release" + self.archiveAllocation(nodeId, ip_addr, hostName, vlan_id, user_id, reservation_type, reservation_notes, allocation_notes) + + def addImage(self, imageName): + name = "" + dist = "" + dist_ver = "" + + if len(imageName.split(":")) > 1: + name = imageName.split(":")[0] + if len(imageName.split(":")) > 2: + dist = imageName.split(":")[1] + if len(imageName.split(":")) >= 3: + dist_ver = imageName.split(":")[2] + + query = "select * from imageinfo where image_name = \"" + name + "\"" + result = self.__selectDb(query) + if result.rowcount > 0: + mesg = "ERROR: Image already exists\n" + sys.stderr.write(mesg) + exit() + + if name == "": + mesg = "ERROR: Image details not specified\n" + logit(self.logFile, mesg) + mesg = "Example amd64-rgass-testing:Ubuntu:8.04\n" + mesg += "or amd64-rgass-testing::\n" + sys.stderr.write(mesg) + exit() + + query = "insert into imageinfo (image_name, dist, dist_ver) values(\"" + name + "\", \"" + dist + "\", \"" + dist_ver + "\")" + self.__insertDb(query) + + + def delImage(self, imageName): + query = "delete from imageinfo where image_name = \"" + imageName + "\"" + result = self.__selectDb(query) + if result.rowcount == 0: + mesg = "ERROR: No images match your entry\n" + sys.stderr.write(mesg) + exit() + + def assignImagetoHost(self, host, image): + # imagemap db should be sys_id instead of mac_addr + # change later + + cur_image = host['pxe_image_name'] + # Get the id of the new image + query = "select image_id from imageinfo where image_name = " + "\"" + image + "\"" + row = self.__queryDb(query) + if len(row) < 1: + mesg = "ERROR: Image \"" + image + "\" does not exist" + logit(self.logFile, mesg) + exit() + new_image_id = str(row[0][0]) + + # check for entry and delete in exists + query = "select * from imagemap where mac_addr = \"" + host['mac_addr'] + "\"" + result = self.__selectDb(query) + if result.rowcount > 0: + query = "delete from imagemap where mac_addr = \"" + host['mac_addr'] + "\"" + result = self.__selectDb(query) + + + # update the database entry with the new image for the host + query = "insert into imagemap (mac_addr, image_id) values (\"" + host['mac_addr'] + "\", " + new_image_id + ")" + self.__selectDb(query) + + + # Update tftp link + mac_addr = "01-" + string.lower(string.replace(host['mac_addr'], ":", "-")) + maclink = self.tftpImageDir + "/" + mac_addr + #print "mac link is ", maclink + # Check if it exists first + if os.path.exists(maclink): + try: + os.unlink(maclink) + except Exception, e: + traceback.print_exc(sys.exc_info()) + if OSError: + print OSError + mesg = "Cannot modify file. Please use sudo\n" + sys.stderr.write(mesg) + return 1 + print e + return 1 + # Relink + newlink = os.path.basename(self.tftpBootOptionsDir) + "/" + image + try: + os.symlink(newlink, maclink) + mesg = "Image assignment Successful " + host['location'] + " " + host['mac_addr'] + " " + image + logit(self.logFile, mesg) + except Exception, e: + if OSError: + mesg = "Cannot modify file. Please use sudo\n" + sys.stderr.write(mesg) + return 1 + print e + return 1 + + return 0 + Added: incubator/tashi/import/zoni-intel-r843/systemassignment.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/systemassignment.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/systemassignment.py (added) +++ incubator/tashi/import/zoni-intel-r843/systemassignment.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,31 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + + +class SystemAssignment(): + + +def addDns(): + pass + +def assignPxeImage(): + pass + + Added: incubator/tashi/import/zoni-intel-r843/systemmanagementinterface.py URL: http://svn.apache.org/viewvc/incubator/tashi/import/zoni-intel-r843/systemmanagementinterface.py?rev=896107&view=auto ============================================================================== --- incubator/tashi/import/zoni-intel-r843/systemmanagementinterface.py (added) +++ incubator/tashi/import/zoni-intel-r843/systemmanagementinterface.py Tue Jan 5 15:56:32 2010 @@ -0,0 +1,64 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# +# $Id$ +# + +import sys +import os + + +class SystemManagementInterface(object): + """ Interface description for hardware management controllers + - IPMI + - IOL + """ + def __init__(self, config): + self.config = config + + + def getPowerStatus(self): + raise NotImplementedError + + def isPowered(self): + ''' Return boolean if system is powered on or not ''' + raise NotImplementedError + + def powerOn(self): + ''' Powers on a system ''' + raise NotImplementedError + + def powerOff(self): + ''' Powers off a system ''' + raise NotImplementedError + + def powerCycle(self): + ''' Powers cycles a system ''' + raise NotImplementedError + + def powerReset(self): + ''' Resets a system ''' + raise NotImplementedError + + def activateConsole(self): + ''' Activate Console''' + raise NotImplementedError + + + + +