Package backend :: Package satellite_tools :: Module geniso
[hide private]
[frames] | no frames]

Source Code for Module backend.satellite_tools.geniso

  1  # 
  2  # Copyright (c) 2008--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15  # 
 16   
 17  import os 
 18  import sys 
 19  import tempfile 
 20  import time 
 21  from stat import ST_SIZE 
 22  from optparse import Option, OptionParser 
 23  from spacewalk.common.rhnConfig import PRODUCT_NAME 
 24   
 25  MOUNT_POINT = '/tmp' 
 26  IMAGE_SIZE = "630M" 
 27  DVD_IMAGE_SIZE = "4380M" 
 28   
 29   
30 -def main(arglist):
31 optionsTable = [ 32 Option('-m', '--mountpoint', action='store', 33 help="mount point"), 34 Option('-s', '--size', action='store', 35 help="image size (eg. 630M)"), 36 Option('-p', '--file-prefix', action='store', 37 help='Filename prefix'), 38 Option('-o', '--output', action='store', 39 help='output directory'), 40 Option('-v', '--version', action='store', 41 help='version string'), 42 Option('-r', '--release', action='store', 43 help='release string'), 44 Option('--copy-iso-dir', action='store', 45 help='directory to copy the isos to after they have been generated.'), 46 Option('-t', '--type', action='store', 47 help='the type of iso being generated.\ 48 this flag is optional, but can be set to spanning, non-spanning, or base.'), 49 ] 50 parser = OptionParser(option_list=optionsTable) 51 options, _args = parser.parse_args(arglist) 52 53 # Check to see if mkisofs is installed 54 if not os.path.exists('/usr/bin/mkisofs'): 55 print("ERROR:: mkisofs is not Installed. Cannot Proceed iso build. " \ 56 + "Please install mkisofs and rerun this command.") 57 return 58 59 mountPoint = options.mountpoint or MOUNT_POINT 60 if options.type == "dvd": 61 print("Building DVD Iso ...") 62 sizeStr = options.size or DVD_IMAGE_SIZE 63 else: 64 sizeStr = options.size or IMAGE_SIZE 65 imageSize = sizeStrToInt(sizeStr) 66 if imageSize == 0: 67 print("Unknown size %s" % sizeStr) 68 return 69 70 if options.version is None: 71 options.version = time.strftime("%Y%m%d", time.gmtime(time.time())) 72 73 if options.release is None: 74 options.release = '0' 75 76 if options.output is None: 77 options.output = "/tmp/satellite-isos" 78 79 file_prefix = options.file_prefix or "rhn-satellite" 80 if not os.path.isdir(options.output): 81 os.makedirs(options.output) 82 83 # Get rid of the extra files in that directory 84 for f in os.listdir(options.output): 85 os.unlink(os.path.join(options.output, f)) 86 87 # Normalize the directory name 88 mountPoint = os.path.normpath(mountPoint) 89 90 # Generate the listings for each CD 91 files = findFiles(mountPoint) 92 cds = [] 93 while files: 94 cd = [] 95 sz = 0 96 while files: 97 filePath, fileSize = files[0] 98 if sz + fileSize > imageSize: 99 # Overflow 100 break 101 102 cd.append(filePath) 103 sz = sz + fileSize 104 # Advance to the next record 105 del files[0] 106 cds.append(cd) 107 108 # We now have the CD contents available; generate the ISOs 109 cdcount = len(cds) 110 111 # Create an empty temp file 112 fd, empty_file_path = tempfile.mkstemp(dir='/tmp', prefix='empty.file-') 113 os.close(fd) 114 115 # command-line template 116 mkisofsTemplate = "mkisofs -r -J -D -file-mode 0444 -new-dir-mode 0555 -dir-mode 0555 " \ 117 + "-graft-points %s -o %s /DISK_%s_OF_%s=%s" 118 for i in range(cdcount): 119 print("---------- %s/%s" % (i + 1, cdcount)) 120 121 # if options.type is None: 122 filename = "%s/%s-%s.%s-%02d.iso" % (options.output, file_prefix, 123 options.version, options.release, i + 1) 124 # else: 125 # filename = "%s/%s-%s-%s.%s-%02d.iso" % (options.output, file_prefix, 126 # options.type, options.version, options.release, i+1) 127 128 # Create a temp file to store the path specs 129 pathfiles_fd, pathfiles = tempfile.mkstemp(dir='/tmp', prefix='geniso-') 130 131 # Command-line options; the keys are supposed to start with a dash 132 opts = { 133 'preparer': PRODUCT_NAME, 134 'publisher': PRODUCT_NAME, 135 'volid': "RHNSAT_%s/%s" % (i + 1, cdcount), 136 'path-list': pathfiles, 137 } 138 opts = ['-%s "%s"' % x for x in list(opts.items())] 139 140 # Generate the file list that will go into the CD 141 # See the man page for mkisofs to better understand how graft points 142 # work (although the man page is not great) 143 grafts = [] 144 for f in cds[i]: 145 # Compute the relative path 146 relpath = os.path.relpath(f, mountPoint) 147 # Append to the graft list: relative=real 148 relpath = os.path.dirname(relpath) 149 grafts.append("%s/=%s" % (relpath, f)) 150 151 # Generate the command line 152 cmd = mkisofsTemplate % (' '.join(opts), filename, i + 1, cdcount, 153 empty_file_path) 154 155 # Write the path specs in pathfiles 156 for graft in grafts: 157 os.write(pathfiles_fd, graft) 158 os.write(pathfiles_fd, "\n") 159 os.close(pathfiles_fd) 160 161 print("Creating %s" % filename) 162 # And run it 163 fd = os.popen(cmd, "r") 164 print(fd.read()) 165 166 if options.copy_iso_dir is not None: 167 copy_iso_path = os.path.join(options.copy_iso_dir, os.path.basename(os.path.dirname(filename))) 168 if not os.path.exists(copy_iso_path): 169 os.mkdir(copy_iso_path) 170 fd = os.popen("mv %s %s" % (filename, copy_iso_path), "r") 171 print(fd.read()) 172 fd = os.popen("rm %s" % filename) 173 print(fd.read()) 174 175 # Remove the temp file 176 os.unlink(pathfiles) 177 178 # Remove the file we used to label the CDs 179 os.unlink(empty_file_path)
180 181
182 -def sizeStrToInt(s):
183 # Converts s to an int 184 if s is None or s == "": 185 # Don't know how to interpret it 186 return 0 187 188 s = str(s) 189 # Strip the dashes in front - we don't want the number to be negative 190 while s and s[0] == '-': 191 s = s[1:] 192 193 try: 194 return int(s) 195 except ValueError: 196 # not an int 197 pass 198 199 if s[-1] in ('k', 'K', 'm', 'M'): 200 # Specified a multiplier 201 if s[-1].lower() == 'k': 202 mult = 1024 203 else: 204 mult = 1024 * 1024 205 206 try: 207 return mult * int(s[:-1]) 208 except ValueError: 209 pass 210 211 # Don't know how to interpret it 212 return 0
213 214 # The visitfunc argument for os.path.walk 215 216
217 -def __visitfunc(arg, dirname, names):
218 for f in names: 219 filename = os.path.normpath("%s/%s" % (dirname, f)) 220 if os.path.isdir(filename): 221 # walk will process it later 222 continue 223 # Get the size 224 sz = os.stat(filename)[ST_SIZE] 225 # Append the filename and size to the list 226 arg.append((filename, sz))
227 228 # Given a directory name, returns the paths of all the files from that 229 # directory, together with the file size 230 231
232 -def findFiles(start):
233 a = [] 234 os.path.walk(start, __visitfunc, a) 235 return a
236 237 238 if __name__ == '__main__': 239 main(sys.argv) 240