blob: 34c13f42f8f8fd15fd14afbe73a85d5037a178b1 [file] [log] [blame]
# 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
import logging
from zoni.extra.util import normalizeMac
from zoni.bootstrap.bootstrapinterface import BootStrapInterface
class Pxe(BootStrapInterface):
def __init__(self, config, data, 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.initrdRoot = config['initrdRoot']
self.kernelRoot = config['kernelRoot']
self.log = logging.getLogger(os.path.basename(__file__))
if config['dbPort'] == "":
config['dbPort'] = 3306
self.port = config['dbPort']
self.vlan_max = config['vlanMax']
self.data = data
#self.vlan_reserved = config['vlanReserved']
#data = instantiateImplementation("zoni.data.resourcequerysql.ResourceQuerySql", configs, options.verbosity)
# Connect to DB
#self.conn = MySQLdb.connect(host = self.ho st, 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 ZONI " + 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())
def generateBootOptions(self, image):
name = self.tftpBootOptionsDir + "/" + image
tftpdir = os.path.basename(self.tftpImageDir)
bootdir = os.path.basename(self.tftpBootOptionsDir)
imagedir = os.path.join(tftpdir, bootdir, image)
# Write out boot image file
val = "DISPLAY boot-screens/boot.txt\n"
val += "DEFAULT vesamenu.c32\n"
val += "TIMEOUT 2\n"
val += "PROMPT 0\n"
val += "MENU BACKGROUND boot-screens/zoni_pxe.jpg\n"
val += "MENU COLOR border 49;37 #00FFFFFF #00FFFFFF none\n"
val += "MENU INCLUDE %s-menu\n" % imagedir
f = open(name, "w")
f.write(val)
f.close()
# Write out the menu file
# Eventually iterate over all images this machine should be able to select from
name = self.tftpBootOptionsDir + "/" + image + "-menu"
kOpt= self.data.getKernelOptions(image)
kernelPath = os.path.join(self.kernelRoot, kOpt['kernel_arch'], kOpt['kernel_name'])
initrdPath = os.path.join(self.initrdRoot, kOpt['kernel_arch'], kOpt['initrd_name'])
val = "DISPLAY boot-screens/boot.txt\n\n"
val += "LABEL %s\n" % kOpt['image_name']
val += " MENU DEFAULT\n"
val += " kernel %s\n" % kernelPath
val += " append initrd=%s %s\n" % (initrdPath, kOpt['initrd_options'])
f = open(name, "w")
f.write(val)
f.close()
def setBootImage(self, mac, image):
mac_addr = "01-" + string.replace(normalizeMac(mac), ":", "-")
maclink = self.tftpImageDir + "/" + mac_addr
self.generateBootOptions(image)
# 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, e
mesg = "ERROR : %s\n" % e
self.log.error(mesg)
return 1
return 1
# Create the boot option file
# Relink
newlink = os.path.basename(self.tftpBootOptionsDir) + "/" + image
try:
os.symlink(newlink, maclink)
mesg = "Image assignment Successful %s -> %s " % (mac, image)
self.log.info(mesg)
except Exception, e:
if OSError:
#mesg = "Cannot modify file. Please use sudo\n"
mesg = "ERROR : %s\n" % e
self.log.info(mesg)
return 1
return 1