shebags mention python2 explicitly
[bootmanager.git] / source / BootServerRequest.py
index 1c2dad5..e1b8c1e 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2
 #
 # Copyright (c) 2003 Intel Corporation
 # All rights reserved.
@@ -8,19 +8,14 @@
 
 from __future__ import print_function
 
-import os, sys
+import sys
+import os
 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:
@@ -55,18 +50,13 @@ class BootServerRequest:
     CURL_CMD = 'curl'
 
     # use TLSv1 and not SSLv3 anymore
-    if PYCURL_LOADED:
-        CURL_SSL_VERSION = pycurl.SSLVERSION_TLSv1
-    else:
-        # used to be '3' for SSLv3
-        # xxx really not sure what this means when pycurl is not loaded
-        CURL_SSL_VERSION = 1
+    CURL_SSL_VERSION = pycurl.SSLVERSION_TLSv1
 
     def __init__(self, vars, verbose=0):
 
         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
         # a boot cd, or something else is mounted
@@ -76,12 +66,12 @@ class BootServerRequest:
             self.Message("Checking existance of boot cd on {}".format(path))
 
             os.system("/bin/mount {} > /dev/null 2>&1".format(path))
-                
+
             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
@@ -91,22 +81,22 @@ class BootServerRequest:
 
             # check the version of the boot cd, and locate the certs
             self.Message("Getting boot cd version.")
-        
+
             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.close()
-            
+
             match = versionRegExp.findall(line)
             if match:
                 (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")
-            
+
             bootservers = [ self.VARS['BOOT_SERVER'] ]
             for bootserver in bootservers:
                 bootserver = string.strip(bootserver)
@@ -139,7 +129,7 @@ class BootServerRequest:
         # see if we have any proxy info from the machine
         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())
@@ -161,10 +151,10 @@ class BootServerRequest:
         self.Error(Msg)
 
     def MakeRequest(self, PartialPath, GetVars,
-                     PostVars, DoSSL, DoCertCheck,
-                     ConnectTimeout = DEFAULT_CURL_CONNECT_TIMEOUT,
-                     MaxTransferTime = DEFAULT_CURL_MAX_TRANSFER_TIME,
-                     FormData = None):
+                    PostVars, DoSSL, DoCertCheck,
+                    ConnectTimeout=DEFAULT_CURL_CONNECT_TIMEOUT,
+                    MaxTransferTime=DEFAULT_CURL_MAX_TRANSFER_TIME,
+                    FormData=None):
 
         fd, buffer_name = tempfile.mkstemp("MakeRequest-XXXXXX")
         os.close(fd)
@@ -191,7 +181,7 @@ class BootServerRequest:
             os.unlink(buffer_name)
         except OSError:
             pass
-            
+
         return ret
 
     def DownloadFile(self, PartialPath, GetVars, PostVars,
@@ -207,10 +197,6 @@ class BootServerRequest:
             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")
@@ -226,7 +212,7 @@ class BootServerRequest:
             dopostdata = 1
             postdata = urllib.urlencode(PostVars)
             self.Message("Posting data:\n{}\n".format(postdata))
-            
+
         getstr = ""
         if GetVars:
             getstr = "?" + urllib.urlencode(GetVars)
@@ -238,21 +224,21 @@ class BootServerRequest:
             cert_list = self.MONITORSERVER_CERTS
         else:
             cert_list = self.BOOTSERVER_CERTS
-        
+
         for server in cert_list:
             self.Message("Contacting server {}.".format(server))
-                        
+
             certpath = cert_list[server]
 
-            
+
             # output what we are going to be doing
             self.Message("Connect timeout is {} seconds".format(ConnectTimeout))
             self.Message("Max transfer time is {} seconds".format(MaxTransferTime))
 
             if DoSSL:
                 url = "https://{}/{}{}".format(server, PartialPath, getstr)
-                
-                if DoCertCheck and PYCURL_LOADED:
+
+                if DoCertCheck:
                     self.Message("Using SSL version {} and verifying peer."
                                  .format(self.CURL_SSL_VERSION))
                 else:
@@ -260,139 +246,77 @@ class BootServerRequest:
                                  .format(self.CURL_SSL_VERSION))
             else:
                 url = "http://{}/{}{}".format(server, PartialPath, getstr)
-                
+
             self.Message("URL: {}".format(url))
-            
-            # setup a new pycurl instance, or a curl command line string
-            # if we don't have pycurl
-            
-            if PYCURL_LOADED:
-                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)
-
-                # 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 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 dopostdata:
-                    curl.setopt(pycurl.POSTFIELDS, postdata)
-
-                # setup multipart/form-data upload
-                if FormData:
-                    curl.setopt(pycurl.HTTPPOST, FormData)
-
-                curl.setopt(pycurl.URL, url)
-            else:
 
-                cmdline = "{} " \
-                          "--connect-timeout {} " \
-                          "--max-time {} " \
-                          "--header Pragma: " \
-                          "--output {} " \
-                          "--fail "\
-                          .format(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 {} ".format(self.PROXY)
-
-                if DoSSL:
-                    cmdline = cmdline + "--sslv{} ".format(self.CURL_SSL_VERSION)
-                    if DoCertCheck:
-                        cmdline = cmdline + "--cacert {} ".format(certpath)
-                 
-                cmdline = cmdline + url
-
-                self.Message("curl command: {}".format(cmdline))
-                
-                
-            if PYCURL_LOADED:
-                try:
-                    # setup the output file
-                    outfile = open(DestFilePath,"wb")
-                    
+            # 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)
+
+            # 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 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 dopostdata:
+                curl.setopt(pycurl.POSTFIELDS, postdata)
+
+            # setup multipart/form-data upload
+            if FormData:
+                curl.setopt(pycurl.HTTPPOST, FormData)
+
+            curl.setopt(pycurl.URL, url)
+
+            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...")
                     curl.perform()
                     self.Message("Done.")
-                
+
                     http_result = curl.getinfo(pycurl.HTTP_CODE)
                     curl.close()
-                
-                    outfile.close()
-                    self.Message("Results saved in {}".format(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: {}"
-                                     .format(http_result))
-
-                except pycurl.error as err:
-                    errno, errstr = err
-                    self.Error("connect to {} failed; curl error {}: '{}'\n"
-                               .format(server, errno, errstr))
-        
-                if not outfile.closed:
-                    try:
-                        os.unlink(DestFilePath)
-                        outfile.close()
-                    except OSError:
-                        pass
 
-            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: {}".format(rc))
-                    self.Message("Removed {}".format(DestFilePath))
-                else:
+                self.Message("Results saved in {}".format(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: {}"
+                                 .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
 
 
 
-
 def usage():
     print(
     """
@@ -403,13 +327,13 @@ Options:
  -o/--output <file>    Write result to file
  -s/--ssl              Make the request over HTTPS
  -v                    Makes the operation more talkative
-""");  
+""");
 
 
 
 if __name__ == "__main__":
     import getopt
-    
+
     # check out our command line options
     try:
         opt_list, arg_list = getopt.getopt(sys.argv[1:],
@@ -421,15 +345,15 @@ if __name__ == "__main__":
         checkcert = 0
         output_file = None
         verbose = 0
-        
+
         for opt, arg in opt_list:
             if opt in ("-h","--help"):
                 usage(0)
                 sys.exit()
-            
+
             if opt in ("-c","--checkcert"):
                 checkcert = 1
-            
+
             if opt in ("-s","--ssl"):
                 ssl = 1
 
@@ -438,7 +362,7 @@ if __name__ == "__main__":
 
             if opt == "-v":
                 verbose = 1
-    
+
         if len(arg_list) != 1:
             raise Exception
 
@@ -452,10 +376,10 @@ if __name__ == "__main__":
 
     # got the command line args straightened out
     requestor = BootServerRequest(verbose)
-        
+
     if output_file:
         requestor.DownloadFile(partialpath, None, None, ssl,
-                                checkcert, output_file)
+                               checkcert, output_file)
     else:
         result = requestor.MakeRequest(partialpath, None, None, ssl, checkcert)
         if result: