# Copyright (c) 2004-2006 The Trustees of Princeton University
# All rights reserved.
+from __future__ import print_function
+
import os, sys
import re
import string
import urllib
import tempfile
-# try to load pycurl
-try:
- import pycurl
- PYCURL_LOADED= 1
-except:
- PYCURL_LOADED= 0
-
+import pycurl
# if there is no cStringIO, fall back to the original
try:
class BootServerRequest:
- VERBOSE = 0
-
# all possible places to check the cdrom mount point.
# /mnt/cdrom is typically after the machine has come up,
# and /usr is when the boot cd is running
- CDROM_MOUNT_PATH = ("/mnt/cdrom/","/usr/")
- BOOTSERVER_CERTS= {}
- MONITORSERVER_CERTS= {}
- BOOTCD_VERSION=""
- HTTP_SUCCESS=200
- HAS_BOOTCD=0
- USE_PROXY=0
- PROXY=0
+ CDROM_MOUNT_PATH = ("/mnt/cdrom/", "/usr/")
+ BOOTSERVER_CERTS = {}
+ MONITORSERVER_CERTS = {}
+ BOOTCD_VERSION = ""
+ HTTP_SUCCESS = 200
+ HAS_BOOTCD = 0
+ USE_PROXY = 0
+ PROXY = 0
# in seconds, how maximum time allowed for connect
- DEFAULT_CURL_CONNECT_TIMEOUT=30
+ DEFAULT_CURL_CONNECT_TIMEOUT = 30
# in seconds, maximum time allowed for any transfer
- DEFAULT_CURL_MAX_TRANSFER_TIME=3600
+ DEFAULT_CURL_MAX_TRANSFER_TIME = 3600
# location of curl executable, if pycurl isn't available
# and the DownloadFile method is called (backup, only
# really need for the boot cd environment where pycurl
# doesn't exist
CURL_CMD = 'curl'
- CURL_SSL_VERSION=3
+
+ # use TLSv1 and not SSLv3 anymore
+ CURL_SSL_VERSION = pycurl.SSLVERSION_TLSv1
def __init__(self, vars, verbose=0):
- self.VERBOSE= verbose
- self.VARS=vars
+ self.VERBOSE = verbose
+ self.VARS = vars
# see if we have a boot cd mounted by checking for the version file
# if HAS_BOOTCD == 0 then either the machine doesn't have
self.HAS_BOOTCD = 0
for path in self.CDROM_MOUNT_PATH:
- self.Message( "Checking existance of boot cd on %s" % path )
+ self.Message("Checking existance of boot cd on {}".format(path))
- os.system("/bin/mount %s > /dev/null 2>&1" % path )
+ os.system("/bin/mount {} > /dev/null 2>&1".format(path))
- version_file= self.VARS['BOOTCD_VERSION_FILE'] % {'path' : path}
- self.Message( "Looking for version file %s" % version_file )
+ version_file = self.VARS['BOOTCD_VERSION_FILE'].format(path=path)
+ self.Message("Looking for version file {}".format(version_file))
if os.access(version_file, os.R_OK) == 0:
- self.Message( "No boot cd found." );
+ self.Message("No boot cd found.");
else:
- self.Message( "Found boot cd." )
- self.HAS_BOOTCD=1
+ self.Message("Found boot cd.")
+ self.HAS_BOOTCD = 1
break
if self.HAS_BOOTCD:
# check the version of the boot cd, and locate the certs
- self.Message( "Getting boot cd version." )
+ self.Message("Getting boot cd version.")
- versionRegExp= re.compile(r"PlanetLab BootCD v(\S+)")
+ versionRegExp = re.compile(r"PlanetLab BootCD v(\S+)")
- bootcd_version_f= file(version_file,"r")
- line= string.strip(bootcd_version_f.readline())
+ bootcd_version_f = file(version_file, "r")
+ line = string.strip(bootcd_version_f.readline())
bootcd_version_f.close()
- match= versionRegExp.findall(line)
+ match = versionRegExp.findall(line)
if match:
- (self.BOOTCD_VERSION)= match[0]
+ (self.BOOTCD_VERSION) = match[0]
# right now, all the versions of the bootcd are supported,
# so no need to check it
- self.Message( "Getting server from configuration" )
+ self.Message("Getting server from configuration")
- bootservers= [ self.VARS['BOOT_SERVER'] ]
+ bootservers = [ self.VARS['BOOT_SERVER'] ]
for bootserver in bootservers:
bootserver = string.strip(bootserver)
- cacert_path= "%s/%s/%s" % \
- (self.VARS['SERVER_CERT_DIR'] % {'path' : path},
- bootserver,self.VARS['CACERT_NAME'])
+ cacert_path = "{}/{}/{}".format(
+ self.VARS['SERVER_CERT_DIR'].format(path=path),
+ bootserver,
+ self.VARS['CACERT_NAME'])
if os.access(cacert_path, os.R_OK):
- self.BOOTSERVER_CERTS[bootserver]= cacert_path
+ self.BOOTSERVER_CERTS[bootserver] = cacert_path
- monitorservers= [ self.VARS['MONITOR_SERVER'] ]
+ monitorservers = [ self.VARS['MONITOR_SERVER'] ]
for monitorserver in monitorservers:
monitorserver = string.strip(monitorserver)
- cacert_path= "%s/%s/%s" % \
- (self.VARS['SERVER_CERT_DIR'] % {'path' : path},
- monitorserver,self.VARS['CACERT_NAME'])
+ cacert_path = "{}/{}/{}".format(
+ self.VARS['SERVER_CERT_DIR'].format(path=path),
+ monitorserver,
+ self.VARS['CACERT_NAME'])
if os.access(cacert_path, os.R_OK):
- self.MONITORSERVER_CERTS[monitorserver]= cacert_path
+ self.MONITORSERVER_CERTS[monitorserver] = cacert_path
- self.Message( "Set of servers to contact: %s" %
- str(self.BOOTSERVER_CERTS) )
- self.Message( "Set of servers to upload to: %s" %
- str(self.MONITORSERVER_CERTS) )
+ self.Message("Set of servers to contact: {}".format(self.BOOTSERVER_CERTS))
+ self.Message("Set of servers to upload to: {}".format(self.MONITORSERVER_CERTS))
else:
- self.Message( "Using default boot server address." )
- self.BOOTSERVER_CERTS[self.VARS['DEFAULT_BOOT_SERVER']]= ""
- self.MONITORSERVER_CERTS[self.VARS['DEFAULT_BOOT_SERVER']]= ""
+ self.Message("Using default boot server address.")
+ self.BOOTSERVER_CERTS[self.VARS['DEFAULT_BOOT_SERVER']] = ""
+ self.MONITORSERVER_CERTS[self.VARS['DEFAULT_BOOT_SERVER']] = ""
- def CheckProxy( self ):
+ def CheckProxy(self):
# see if we have any proxy info from the machine
- self.USE_PROXY= 0
- self.Message( "Checking existance of proxy config file..." )
+ self.USE_PROXY = 0
+ self.Message("Checking existance of proxy config file...")
if os.access(self.VARS['PROXY_FILE'], os.R_OK) and \
os.path.isfile(self.VARS['PROXY_FILE']):
- self.PROXY= string.strip(file(self.VARS['PROXY_FILE'],'r').readline())
- self.USE_PROXY= 1
- self.Message( "Using proxy %s." % self.PROXY)
+ self.PROXY = string.strip(file(self.VARS['PROXY_FILE'], 'r').readline())
+ self.USE_PROXY = 1
+ self.Message("Using proxy {}.".format(self.PROXY))
else:
- self.Message( "Not using any proxy." )
-
-
-
- def Message( self, Msg ):
- if( self.VERBOSE ):
- print( Msg )
-
+ self.Message("Not using any proxy.")
- def Error( self, Msg ):
- sys.stderr.write( Msg + "\n" )
+ def Message(self, Msg):
+ if(self.VERBOSE):
+ print(Msg)
+ def Error(self, Msg):
+ sys.stderr.write(Msg + "\n")
- def Warning( self, Msg ):
+ def Warning(self, Msg):
self.Error(Msg)
+ def MakeRequest(self, PartialPath, GetVars,
+ PostVars, DoSSL, DoCertCheck,
+ ConnectTimeout = DEFAULT_CURL_CONNECT_TIMEOUT,
+ MaxTransferTime = DEFAULT_CURL_MAX_TRANSFER_TIME,
+ FormData = None):
-
- def MakeRequest( self, PartialPath, GetVars,
- PostVars, DoSSL, DoCertCheck,
- ConnectTimeout= DEFAULT_CURL_CONNECT_TIMEOUT,
- MaxTransferTime= DEFAULT_CURL_MAX_TRANSFER_TIME,
- FormData= None):
-
- (fd, buffer_name) = tempfile.mkstemp("MakeRequest-XXXXXX")
+ fd, buffer_name = tempfile.mkstemp("MakeRequest-XXXXXX")
os.close(fd)
buffer = open(buffer_name, "w+b")
def DownloadFile(self, PartialPath, GetVars, PostVars,
DoSSL, DoCertCheck, DestFilePath,
- ConnectTimeout= DEFAULT_CURL_CONNECT_TIMEOUT,
- MaxTransferTime= DEFAULT_CURL_MAX_TRANSFER_TIME,
- FormData= None):
+ ConnectTimeout = DEFAULT_CURL_CONNECT_TIMEOUT,
+ MaxTransferTime = DEFAULT_CURL_MAX_TRANSFER_TIME,
+ FormData = None):
- self.Message( "Attempting to retrieve %s" % PartialPath )
+ self.Message("Attempting to retrieve {}".format(PartialPath))
# we can't do ssl and check the cert if we don't have a bootcd
if DoSSL and DoCertCheck and not self.HAS_BOOTCD:
- self.Error( "No boot cd exists (needed to use -c and -s.\n" )
+ self.Error("No boot cd exists (needed to use -c and -s.\n")
return 0
- if DoSSL and not PYCURL_LOADED:
- self.Warning( "Using SSL without pycurl will by default " \
- "check at least standard certs." )
-
# ConnectTimeout has to be greater than 0
if ConnectTimeout <= 0:
- self.Error( "Connect timeout must be greater than zero.\n" )
+ self.Error("Connect timeout must be greater than zero.\n")
return 0
self.CheckProxy()
- dopostdata= 0
+ dopostdata = 0
# setup the post and get vars for the request
if PostVars:
- dopostdata= 1
+ dopostdata = 1
postdata = urllib.urlencode(PostVars)
- self.Message( "Posting data:\n%s\n" % postdata )
+ self.Message("Posting data:\n{}\n".format(postdata))
- getstr= ""
+ getstr = ""
if GetVars:
- getstr= "?" + urllib.urlencode(GetVars)
- self.Message( "Get data:\n%s\n" % getstr )
+ getstr = "?" + urllib.urlencode(GetVars)
+ self.Message("Get data:\n{}\n".format(getstr))
# now, attempt to make the request, starting at the first
# server in the list
cert_list = self.BOOTSERVER_CERTS
for server in cert_list:
- self.Message( "Contacting server %s." % server )
+ self.Message("Contacting server {}.".format(server))
certpath = cert_list[server]
# output what we are going to be doing
- self.Message( "Connect timeout is %s seconds" % \
- ConnectTimeout )
-
- self.Message( "Max transfer time is %s seconds" % \
- MaxTransferTime )
+ self.Message("Connect timeout is {} seconds".format(ConnectTimeout))
+ self.Message("Max transfer time is {} seconds".format(MaxTransferTime))
if DoSSL:
- url = "https://%s/%s%s" % (server,PartialPath,getstr)
+ url = "https://{}/{}{}".format(server, PartialPath, getstr)
- if DoCertCheck and PYCURL_LOADED:
- self.Message( "Using SSL version %d and verifying peer." %
- self.CURL_SSL_VERSION )
+ if DoCertCheck:
+ self.Message("Using SSL version {} and verifying peer."
+ .format(self.CURL_SSL_VERSION))
else:
- self.Message( "Using SSL version %d." %
- self.CURL_SSL_VERSION )
+ self.Message("Using SSL version {}."
+ .format(self.CURL_SSL_VERSION))
else:
- url = "http://%s/%s%s" % (server,PartialPath,getstr)
+ url = "http://{}/{}{}".format(server, PartialPath, getstr)
- self.Message( "URL: %s" % url )
-
- # setup a new pycurl instance, or a curl command line string
- # if we don't have pycurl
+ self.Message("URL: {}".format(url))
- if PYCURL_LOADED:
- curl= pycurl.Curl()
+ # setup a new pycurl instance
+ curl = pycurl.Curl()
- # don't want curl sending any signals
- curl.setopt(pycurl.NOSIGNAL, 1)
-
- curl.setopt(pycurl.CONNECTTIMEOUT, ConnectTimeout)
- curl.setopt(pycurl.TIMEOUT, MaxTransferTime)
+ # don't want curl sending any signals
+ curl.setopt(pycurl.NOSIGNAL, 1)
+
+ curl.setopt(pycurl.CONNECTTIMEOUT, ConnectTimeout)
+ curl.setopt(pycurl.TIMEOUT, MaxTransferTime)
- # do not follow location when attempting to download a file
- curl.setopt(pycurl.FOLLOWLOCATION, 0)
+ # do not follow location when attempting to download a file
+ curl.setopt(pycurl.FOLLOWLOCATION, 0)
- if self.USE_PROXY:
- curl.setopt(pycurl.PROXY, self.PROXY )
+ if self.USE_PROXY:
+ curl.setopt(pycurl.PROXY, self.PROXY)
- if DoSSL:
- curl.setopt(pycurl.SSLVERSION, self.CURL_SSL_VERSION)
+ if DoSSL:
+ curl.setopt(pycurl.SSLVERSION, self.CURL_SSL_VERSION)
- if DoCertCheck:
- curl.setopt(pycurl.CAINFO, certpath)
- curl.setopt(pycurl.SSL_VERIFYPEER, 2)
-
- else:
- curl.setopt(pycurl.SSL_VERIFYPEER, 0)
+ if DoCertCheck:
+ curl.setopt(pycurl.CAINFO, certpath)
+ curl.setopt(pycurl.SSL_VERIFYPEER, 2)
+ else:
+ curl.setopt(pycurl.SSL_VERIFYPEER, 0)
- if dopostdata:
- curl.setopt(pycurl.POSTFIELDS, postdata)
+ if dopostdata:
+ curl.setopt(pycurl.POSTFIELDS, postdata)
- # setup multipart/form-data upload
- if FormData:
- curl.setopt(pycurl.HTTPPOST, FormData)
+ # setup multipart/form-data upload
+ if FormData:
+ curl.setopt(pycurl.HTTPPOST, FormData)
- curl.setopt(pycurl.URL, url)
- else:
+ curl.setopt(pycurl.URL, url)
- cmdline = "%s " \
- "--connect-timeout %d " \
- "--max-time %d " \
- "--header Pragma: " \
- "--output %s " \
- "--fail " % \
- (self.CURL_CMD, ConnectTimeout,
- MaxTransferTime, DestFilePath)
-
- if dopostdata:
- cmdline = cmdline + "--data '" + postdata + "' "
-
- if FormData:
- cmdline = cmdline + "".join(["--form '" + field + "' " for field in FormData])
-
- if not self.VERBOSE:
- cmdline = cmdline + "--silent "
-
- if self.USE_PROXY:
- cmdline = cmdline + "--proxy %s " % self.PROXY
-
- if DoSSL:
- cmdline = cmdline + "--sslv%d " % self.CURL_SSL_VERSION
- if DoCertCheck:
- cmdline = cmdline + "--cacert %s " % certpath
-
- cmdline = cmdline + url
-
- self.Message( "curl command: %s" % cmdline )
-
-
- if PYCURL_LOADED:
- try:
- # setup the output file
- outfile = open(DestFilePath,"wb")
-
- self.Message( "Opened output file %s" % DestFilePath )
+ try:
+ # setup the output file
+ with open(DestFilePath,"wb") as outfile:
+ self.Message("Opened output file {}".format(DestFilePath))
+
curl.setopt(pycurl.WRITEDATA, outfile)
-
- self.Message( "Fetching..." )
+
+ self.Message("Fetching...")
curl.perform()
- self.Message( "Done." )
-
- http_result= curl.getinfo(pycurl.HTTP_CODE)
+ self.Message("Done.")
+
+ http_result = curl.getinfo(pycurl.HTTP_CODE)
curl.close()
-
- outfile.close()
- self.Message( "Results saved in %s" % DestFilePath )
-
- # check the code, return 1 if successfull
- if http_result == self.HTTP_SUCCESS:
- self.Message( "Successfull!" )
- return 1
- else:
- self.Message( "Failure, resultant http code: %d" % \
- http_result )
-
- except pycurl.error, err:
- errno, errstr= err
- self.Error( "connect to %s failed; curl error %d: '%s'\n" %
- (server,errno,errstr) )
-
- if not outfile.closed:
- try:
- os.unlink(DestFilePath)
- outfile.close()
- except OSError:
- pass
+
+ self.Message("Results saved in {}".format(DestFilePath))
- else:
- self.Message( "Fetching..." )
- rc = os.system(cmdline)
- self.Message( "Done." )
-
- if rc != 0:
- try:
- os.unlink( DestFilePath )
- except OSError:
- pass
- self.Message( "Failure, resultant curl code: %d" % rc )
- self.Message( "Removed %s" % DestFilePath )
- else:
- self.Message( "Successfull!" )
+ # check the code, return 1 if successfull
+ if http_result == self.HTTP_SUCCESS:
+ self.Message("Successfull!")
return 1
-
- self.Error( "Unable to successfully contact any boot servers.\n" )
- return 0
+ else:
+ self.Message("Failure, resultant http code: {}"
+ .format(http_result))
+ except pycurl.error as err:
+ errno, errstr = err
+ self.Error("connect to {} failed; curl error {}: '{}'\n"
+ .format(server, errno, errstr))
+
+ self.Error("Unable to successfully contact any boot servers.\n")
+ return 0
[ "output=", "verbose", \
"help","ssl","checkcert"])
- ssl= 0
- checkcert= 0
- output_file= None
- verbose= 0
+ ssl = 0
+ checkcert = 0
+ output_file = None
+ verbose = 0
for opt, arg in opt_list:
if opt in ("-h","--help"):
sys.exit()
if opt in ("-c","--checkcert"):
- checkcert= 1
+ checkcert = 1
if opt in ("-s","--ssl"):
- ssl= 1
+ ssl = 1
if opt in ("-o","--output"):
- output_file= arg
+ output_file = arg
if opt == "-v":
- verbose= 1
+ verbose = 1
if len(arg_list) != 1:
raise Exception
- partialpath= arg_list[0]
+ partialpath = arg_list[0]
if string.lower(partialpath[:4]) == "http":
raise Exception
sys.exit(2)
# got the command line args straightened out
- requestor= BootServerRequest(verbose)
+ requestor = BootServerRequest(verbose)
if output_file:
- requestor.DownloadFile( partialpath, None, None, ssl,
+ requestor.DownloadFile(partialpath, None, None, ssl,
checkcert, output_file)
else:
- result= requestor.MakeRequest( partialpath, None, None, ssl, checkcert)
+ result = requestor.MakeRequest(partialpath, None, None, ssl, checkcert)
if result:
- print result
+ print(result)
else:
sys.exit(1)