def detach(device=" ", logger=False): """ Eject the ramdisk Detach (on the mac) is a better solution than unmount and eject separately.. Besides unmounting the disk, it also stops any processes related to the mntPoint @author: Roy Nielsen """ success = False if not logger: logger = CyLogger() else: logger = logger myRunWith = RunWith(logger) if not re.match("^\s*$", device): cmd = ["/usr/bin/hdiutil", "detach", device] myRunWith.setCommand(cmd) myRunWith.communicate() retval, reterr, retcode = myRunWith.getNlogReturns() if not reterr: success = True myRunWith.getNlogReturns() else: raise Exception("Cannot eject a device with an empty name..") return success
def setUpClass(self): """ """ ##### # Set up logging self.logger = CyLogger(debug_mode=True) self.logger.initializeLogs() self.rw = RunWith(self.logger) ##### # Start timer in miliseconds self.test_start_time = datetime.now()
def __init__(self, logger, userName="", userShell="/bin/bash", userComment="", userUid=1000, userPriGid=20, userHomeDir="/tmp"): super(MacOSUser, self).__init__(logger, userName, userShell, userComment, userUid, userPriGid, userHomeDir) self.module_version = '20160225.125554.540679' if isinstance(logger, CyLogger): self.logger = logger else: raise NotACyLoggerError("Passed in value for logger is invalid, try again.") self.dscl = "/usr/bin/dscl" self.userData = [] self.runWith = RunWith(self.logger)
def __init__(self, conf, parent=None) : """ Initialization method @author: Roy Nielsen """ super(AdministratorCredentials, self).__init__(parent) self.ui = Ui_AdministratorCredentials() self.ui.setupUi(self) self.conf = conf self.logger = self.conf.getLogger() self.mu = ManageUser(logger=self.logger) self.rw = RunWith(self.logger) self.username = "" self.password = "" self.cmd = "" self.tmpDir = "" ##### # Set up signals and slots self.ui.authUserButton.clicked.connect(self.isPassValid) self.ui.cancelButton.clicked.connect(self.rejectApp) self.logger.log(lp.DEBUG, "Finished initializing AdministratorCredentials Class...")
def __init__(self, conf, parent=None): """ Initialization method... @author: Roy Nielsen """ super(SettingsOk, self).__init__(parent) self.ui = Ui_Dialog() self.ui.setupUi(self) ##### # initialization of class variables. self.conf = conf self.conf.loggerSelf() self.logger = self.conf.getLogger() #self.logger = self.conf.get_logger() self.logger.log(lp.DEBUG, str(self.logger)) self.runWith = RunWith(self.logger) self.libc = getLibc(self.logger) ##### # Handle button box self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.close) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.processVm) ##### # Rename Apply button self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Apply).setText("Change Vm Settings") btn = self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Apply) btn.clicked.connect(self.deltaVmSettings) ##### # Acquire current json varfile data and print it. self.varFilePath = self.conf.getCurrentVarFilePath() if self.varFilePath and isSaneFilePath(self.varFilePath): try: self.pjh = PackerJsonHandler(self.logger) jsonData = self.pjh.readExistingJsonVarfile( self.conf.getCurrentVarFilePath()) except Exception, err: QtWidgets.QMessageBox.critical( self, "Error", "...Exception trying to read packer json...", QtWidgets.QMessageBox.Ok) self.logger.log(lp.WARNING, traceback.format_exc()) self.logger.log(lp.WARNING, str(err)) raise err else: self.ui.labelVmName.setText(self.pjh.getVmName()) self.ui.labelDesktop.setText(self.pjh.getDesktop()) self.ui.labelCpus.setText(self.pjh.getCpus()) self.ui.labelMemSize.setText(self.pjh.getMemSize()) self.ui.labelDiskSize.setText(self.pjh.getDiskSize())
def __init__(self, **kwargs): """ Variables that can be passed in: logger userName userShell userComment userUid userPriGid userHomeDir """ if 'logDispatcher' not in kwargs: raise ValueError("Variable 'logDispatcher' a required parameter for " + str(self.__class__.__name__)) super(MacOSUser, self).__init__(**kwargs) self.module_version = '20160225.125554.540679' self.dscl = "/usr/bin/dscl" self.runWith = RunWith(self.logger)
def __init__(self, size=0, mountpoint="", logger=False, mode=700, uid=None, gid=None, fstype="tmpfs", nr_inodes=None, nr_blocks=None): """ """ super(RamDisk, self).__init__(size, mountpoint, logger) ##### # The passed in size of ramdisk should be in 1Mb chunks self.module_version = '20160224.032043.009191' self.logger = logger if not sys.platform.startswith("linux"): raise self.NotValidForThisOS("This ramdisk is only viable for a Linux.") if fstype in ["tmpfs", "ramfs"]: self.fstype = fstype if fstype == "tmpfs": self.myRamdiskDev = "/dev/tmpfs" else: raise self.BadRamdiskArguments("Not a valid argument for " + \ "'fstype'...") if isinstance(mode, int): self.mode = mode else: self.mode = 700 if not isinstance(uid, int): self.uid = os.getuid() else: self.uid = uid if not isinstance(gid, int): self.gid = os.getgid() else: self.gid = gid if isinstance(nr_inodes, basestring): self.nr_inodes = nr_inodes else: self.nr_inodes = None if isinstance(nr_blocks, basestring): self.nr_blocks = nr_blocks else: self.nr_blocks = None self.printData() ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) self.runWith.getNlogReturns() self.success = self._mount()
def __init__(self, conf, parent=None): """ Initialization method... @author: Roy Nielsen """ super(PrepareIso, self).__init__(parent) self.ui = Ui_PrepareMacosImage() self.ui.setupUi(self) ##### # initialization of class variables. self.conf = conf self.conf.loggerSelf() self.logger = self.conf.getLogger() #self.logger = self.conf.get_logger() self.logger.log(lp.DEBUG, str(self.logger)) self.runWith = RunWith(self.logger) self.libc = getLibc(self.logger) ##### # Handle button box self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.reject) self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.accept) ##### # Handle other buttons self.ui.bOpenInstallerApp.clicked.connect(self.openInstallerApp) self.ui.bPrepareIso.clicked.connect(self.prepareIso) ##### # Set up collection of administrator credentials self.adminCreds = AdministratorCredentials(self.conf) self.adminCreds.creds.connect(self.setUserAndPass) ##### # Instanciate a PackerJsonHandler self.pjh = PackerJsonHandler(self.logger)
def remount(self, size=0, mountpoint="", mode=700, uid=None, gid=None, nr_inodes=None, nr_blocks=None): """ Use the tmpfs ability to be remounted with different options If bad input is given, the previous values will be used. @author: Roy Nielsen """ ##### # Input Validation: ##### # tmpfs is the only viable ramdisk that handles remounting ok. # this includes mouting tmpfs with msdos, ext2,3,4, etc. if not self.fstype == "tmpfs": raise self.BadRamdiskArguments("Can only use 'remount' with " + \ "tmpfs...") if size and isinstance(size, int): self.diskSize = size if mountpoint and isinstance(mountpoint, type.string): self.mntPoint = mountpoint if mode and isinstance(mode, int): self.mode = mode if uid and isinstance(uid, int): self.uid = uid if gid and isinstance(gid, int): self.gid = gid if nr_inodes and isinstance(nr_inodes, (int, long)): self.nr_inodes = nr_inodes if nr_blocks and isinstance(nr_blocks, (int, long)): self.nr_blocks = nr_blocks ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) self.buildCommand() self._mount()
def unmount(mnt_point="", logger=False): """ Unmount the ramdisk @author: Roy Nielsen """ success = False if mnt_point: runWith = RunWith(logger) command = ["/bin/umount", mnt_point] runWith.setCommand(command) runWith.communicate() retval, reterr, retcode = runWith.getNlogReturns() if not reterr: success = True return success
def main(): """ Main program @author: Roy Nielsen """ prog_opts = ProgramOptions() conf = prog_opts.returnConf() conf.loggerSelf() environ = conf.getEnviron() logger = conf.getLogger() #print str(logger) rw = RunWith(logger) logger.log(lp.INFO, "#==--- Initializing VmBuilder.app ---==#") ##### # Instantiate & execute application... app = QtWidgets.QApplication(sys.argv) ''' ##### # Set up dialog mydialog = Work(conf) mydialog.setOpenExternalLinks(True) mydialog.setWindowTitle("Vm Builder") mydialog.show() mydialog.raise_() ''' mydialog = VirtualMachineBuilder(conf) mydialog.setOpenExternalLinks(True) #mydialog.setModal(True) mydialog.setWindowTitle("Virtual Machine Builder") mydialog.show() mydialog.raise_() app.exec_()
def umount(mnt_point="", logger=False): """ Unmount the ramdisk @author: Roy Nielsen """ success = False if mnt_point: paths = [ "/bin", "/usr/bin", "/sbin", "/usr/sbin", "/usr/local/bin", "/user/local/sbin" ] ##### # Look for the umount command umountFound = False umountPath = "" for path in paths: possibleFullPath = os.path.join(path, "umount") if os.path.exists(possibleFullPath): umountPath = possibleFullPath umountFound = True if not umountFound: raise SystemToolNotAvailable("Cannot find umount command...") ##### # Run the umount command... runWith = RunWith(logger) command = [umountPath, mnt_point] runWith.setCommand(command) runWith.communicate() retval, reterr, retcode = runWith.getNlogReturns() if not reterr: success = True return success
class RamDisk(RamDiskTemplate) : """ Class to manage a ramdisk utilizes commands I've used to manage ramdisks Size passed in must be passed in as 1Mb chunks @param: size - size of the ramdisk to create - must have a value on the Mac or the creation will fail. @param: mountpoint - where to mount the disk, if left empty, will mount on locaiton created by tempfile.mkdtemp. @param: message_level - level at which to log. @author: Roy Nielsen """ def __init__(self, size=0, mountpoint="", logger=False) : """ Constructor """ super(RamDisk, self).__init__(size, mountpoint, logger) if not getOsFamily() == "darwin": raise NotValidForThisOS("This ramdisk is only viable for a MacOS.") self.module_version = '20160225.125554.540679' ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) ##### # Calculating the size of ramdisk in 1Mb chunks self.diskSize = str(int(size) * 1024 * 1024 / 512) self.hdiutil = "/usr/bin/hdiutil" self.diskutil = "/usr/sbin/diskutil" ##### # Just /dev/disk<#> self.myRamdiskDev = "" ##### # should take the form of /dev/disk2s1, where disk 2 is the assigned # disk and s1 is the slice, or partition number. While just /dev/disk2 # is good for some things, others will need the full path to the # device, such as formatting the disk. self.devPartition = "" ##### # Indicate if the ramdisk is "mounted" in the Mac sense - attached, # but not mounted. self.mounted = False success = False ##### # Passed in disk size must have a non-default value if not self.diskSize == 0 : success = True ##### # Checking to see if memory is availalbe... if not self.__isMemoryAvailable() : self.logger.log(lp.DEBUG, "Physical memory not available to create ramdisk.") success = False else: success = True if success : ##### # If a mountpoint is passed in, use that, otherwise, set up for a # random mountpoint. if mountpoint: self.logger.log(lp.INFO, "\n\n\n\tMOUNTPOINT: " + str(mountpoint) + "\n\n\n") self.mntPoint = mountpoint ##### # eventually have checking to make sure that directory # doesn't already exist, and have data in it. else : ##### # If a mountpoint is not passed in, create a randomized # mount point. self.logger.log(lp.DEBUG, "Attempting to acquire a radomized mount " + \ "point. . .") if not self.getRandomizedMountpoint() : success = False ##### # The Mac has a more complicated method of managing ramdisks... if success: ##### # Attempt to create the ramdisk if not self.__create(): success = False self.logger.log(lp.WARNING, "Create appears to have failed..") else: ##### # Ramdisk created, try mounting it. if not self.__mount(): success = False self.logger.log(lp.WARNING, "Mount appears to have failed..") else: ##### # Filessystem journal will only slow the ramdisk down... # No need to keep it as when the journal is unmounted # all memory is de-allocated making it impossible to do # forensics on the volume. if not self.__remove_journal(): success = False self.logger.log(lp.WARNING, "Remove journal " + \ "appears to have failed..") self.success = success if success: self.logger.log(lp.INFO, "Mount point: " + str(self.mntPoint)) self.logger.log(lp.INFO, "Device: " + str(self.myRamdiskDev)) self.logger.log(lp.INFO, "Success: " + str(self.success)) ########################################################################### def __create(self) : """ Create a ramdisk device @author: Roy Nielsen """ retval = None reterr = None success = False ##### # Create the ramdisk and attach it to a device. cmd = [self.hdiutil, "attach", "-nomount", "ram://" + self.diskSize] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if reterr: success = False raise Exception("Error trying to create ramdisk(" + \ str(reterr).strip() + ")") else: self.myRamdiskDev = retval.strip() self.logger.log(lp.DEBUG, "Device: \"" + str(self.myRamdiskDev) + "\"") success = True self.logger.log(lp.DEBUG, "Success: " + str(success) + " in __create") return success ########################################################################### def getData(self): """ Getter for mount data, and if the mounting of a ramdisk was successful Does not print or log the data. @author: Roy Nielsen """ return (self.success, str(self.mntPoint), str(self.myRamdiskDev)) ########################################################################### def getNlogData(self): """ Getter for mount data, and if the mounting of a ramdisk was successful Also logs the data. @author: Roy Nielsen """ self.logger.log(lp.INFO, "Success: " + str(self.success)) self.logger.log(lp.INFO, "Mount point: " + str(self.mntPoint)) self.logger.log(lp.INFO, "Device: " + str(self.myRamdiskDev)) return (self.success, str(self.mntPoint), str(self.myRamdiskDev)) ########################################################################### def getNprintData(self): """ Getter for mount data, and if the mounting of a ramdisk was successful """ print "Success: " + str(self.success) print "Mount point: " + str(self.mntPoint) print "Device: " + str(self.myRamdiskDev) return (self.success, str(self.mntPoint), str(self.myRamdiskDev)) ########################################################################### def __mount(self) : """ Mount the disk - for the Mac, just run self.__attach @author: Roy Nielsen """ success = False success = self.__attach() if success: self.mounted = True return success ########################################################################### def __attach(self): """ Attach the device so it can be formatted @author: Roy Nielsen """ success = False ##### # Attempt to partition the disk. if self.__partition(): success = True ##### # eraseVolume format name device if self.mntPoint: ##### # "Mac" unmount (not eject) cmd = [self.diskutil, "unmount", self.myRamdiskDev + "s1"] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True if success: ##### # remount to self.mntPoint cmd = [self.diskutil, "mount", "-mountPoint", self.mntPoint, self.devPartition] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True self.runWith.getNlogReturns() self.getData() self.logger.log(lp.DEBUG, "Success: " + str(success) + " in __mount") return success ########################################################################### def __remove_journal(self) : """ Having a journal in ramdisk makes very little sense. Remove the journal after creating the ramdisk device cmd = ["/usr/sbin/diskutil", "disableJournal", "force", myRamdiskDev] using "force" doesn't work on a mounted filesystem, without it, the command will work on a mounted file system @author: Roy Nielsen """ success = False cmd = [self.diskutil, "disableJournal", self.myRamdiskDev + "s1"] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True self.logger.log(lp.DEBUG, "Success: " + str(success) + " in __remove_journal") return success ########################################################################### def unionOver(self, target="", fstype="hfs", nosuid=None, noowners=True, noatime=None, nobrowse=None): """ Use unionfs to mount a ramdisk on top of a location already on the filesystem. @parameter: target - where to lay the ramdisk on top of, ie the lower filesystem layer. @parameter: nosuid - from the mount manpage: "Do not allow set-user-identifier bits to take effect. @parameter: fstype - What supported filesystem to use. @parameter: noowners - From the mount manpage: "Ignore the ownership field for the entire volume. This causes all objects to appear as owned by user ID 99 and group ID 99. User ID 99 is interpreted as the current effective user ID, while group 99 is used directly and translates to "unknown". @parameter: noatime - from the mount manpage: "Do not update the file access time when reading from a file. This option is useful on file systems where there are large numbers of files and performance is more critical than updating the file access time (which is rarely ever important). @parameter: nobrowse - from the mount manpage: "This option indicates that the mount point should not be visible via the GUI (i.e., appear on the Desktop as a separate volume). @author: Roy Nielsen """ success = False ##### # If the ramdisk is mounted, unmount it (not eject...) if self.mounted: self._unmount() ##### # Create the target directory if it doesn't exist yet... if not os.path.isdir(target): if os.path.isfile(target): shutil.move(target, target + ".bak") os.makedirs(target) ##### # Put together the command if the base options are given if fstype and self.devPartition: ##### # Compile the options options = "union" if nosuid: options = options + ",nosuid" if noowners: options = options + ",noowners" if noatime: options = options + ",noatime" if nobrowse: options = options + ",nobrowse" ##### # Put the command together. cmd = ["/sbin/mount", "-t", str(fstype), "-o", options, self.devPartition, target] ##### # Run the command self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True return success ########################################################################### def unmount(self) : """ Unmount the disk - same functionality as __eject on the mac @author: Roy Nielsen """ success = False if self.eject() : success = True self.logger.log(lp.DEBUG, "Success: " + str(success) + " in unmount") return success ########################################################################### def detach(self) : """ Unmount the disk - same functionality as __eject on the mac @author: Roy Nielsen """ success = False if self.eject() : success = True self.logger.log(lp.DEBUG, "Success: " + str(success) + " in detach") return success ########################################################################### def _unmount(self) : """ Unmount in the Mac sense - ie, the device is still accessible. @author: Roy Nielsen """ success = False cmd = [self.diskutil, "unmount", self.devPartition] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True return success ########################################################################### def _mount(self) : """ Mount in the Mac sense - ie, mount an already accessible device to a mount point. @author: Roy Nielsen """ success = False cmd = [self.diskutil, "mount", "-mountPoint", self.mntPoint, self.devPartition] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True return success ########################################################################### def eject(self) : """ Eject the ramdisk Detach (on the mac) is a better solution than unmount and eject separately.. Besides unmounting the disk, it also stops any processes related to the mntPoint @author: Roy Nielsen """ success = False cmd = [self.hdiutil, "detach", self.myRamdiskDev] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True self.runWith.getNlogReturns() return success ########################################################################### def _format(self) : """ Format the ramdisk @author: Roy Nielsen """ success = False ##### # Unmount (in the mac sense - the device should still be accessible) # Cannot format the drive unless only the device is accessible. success = self._unmount() ##### # Format the disk (partition) cmd = ["/sbin/newfs_hfs", "-v", "ramdisk", self.devPartition] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True ##### # Re-mount the disk self._mount() return success ########################################################################### def __partition(self) : """ Partition the ramdisk (mac specific) @author: Roy Nielsen """ success=False size = str(int(self.diskSize)/(2*1024)) cmd = [self.diskutil, "partitionDisk", self.myRamdiskDev, str(1), "MBR", "HFS+", "ramdisk", str(size) + "M"] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True if success: ##### # Need to get the partition device out of the output to assign to # self.devPartition for line in retval.split("\n"): if re.match("^Initialized (\S+)\s+", line): linematch = re.match("Initialized\s+(\S+)", line) rdevPartition = linematch.group(1) self.devPartition = re.sub("rdisk", "disk", rdevPartition) break self.runWith.getNlogReturns() return success ########################################################################### def __isMemoryAvailable(self) : """ Check to make sure there is plenty of memory of the size passed in before creating the ramdisk Best method to do this on the Mac is to get the output of "top -l 1" and re.search("unused\.$", line) @author: Roy Nielsen """ #mem_free = psutil.phymem_usage()[2] #print "Memory free = " + str(mem_free) success = False found = False almost_size = 0 size = 0 self.free = 0 line = "" freeMagnitude = None ##### # Set up and run the command cmd = ["/usr/bin/top", "-l", "1"] proc = Popen(cmd, stdout=PIPE, stderr=PIPE) while True: line = proc.stdout.readline().strip() ##### # Split on spaces line = line.split() ##### # Get the last item in the list found = line[-1] almost_size = line[:-1] size = almost_size[-1] found = found.strip() #almost_size = almost_size.strip() size = size.strip() self.logger.log(lp.INFO, "size: " + str(size)) self.logger.log(lp.INFO, "found: " + str(found)) if re.search("unused", found) or re.search("free", found): ##### # Found the data we wanted, stop the search. break proc.kill() ##### # Find the numerical value and magnitute of the ramdisk if size: sizeCompile = re.compile("(\d+)(\w+)") split_size = sizeCompile.search(size) freeNumber = split_size.group(1) freeMagnitude = split_size.group(2) if re.match("^\d+$", freeNumber.strip()): if re.match("^\w$", freeMagnitude.strip()): if freeMagnitude: ##### # Calculate the size of the free memory in Megabytes if re.search("G", freeMagnitude.strip()): self.free = 1024 * int(freeNumber) self.free = str(self.free) elif re.search("M", freeMagnitude.strip()): self.free = freeNumber self.logger.log(lp.DEBUG, "free: " + str(self.free)) self.logger.log(lp.DEBUG, "Size requested: " + str(self.diskSize)) if int(self.free) > int(self.diskSize)/(2*1024): success = True print str(self.free) print str(success) return success ########################################################################### def getDevice(self): """ Getter for the device name the ramdisk is using @author: Roy Nielsen """ return self.myRamdiskDev ########################################################################### def setDevice(self, device=None): """ Setter for the device so it can be ejected. @author: Roy Nielsen """ if device: self.myRamdiskDev = device else: raise Exception("Problem trying to set the device..") ########################################################################### def getVersion(self): """ Getter for the version of the ramdisk @author: Roy Nielsen """ return self.module_version
class RamDisk(RamDiskTemplate): """ http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html In this example, remount /dev/shm with 8G size as follows: # mount -o remount,size=8G /dev/shm To be frank, if you have more than 2GB RAM + multiple Virtual machines, this hack always improves performance. In this example, you will give you tmpfs instance on /disk2/tmpfs which can allocate 5GB RAM/SWAP in 5K inodes and it is only accessible by root: # mount -t tmpfs -o size=5G,nr_inodes=5k,mode=700 tmpfs /disk2/tmpfs Where, -o opt1,opt2 : Pass various options with a -o flag followed by a comma separated string of options. In this examples, I used the following options: remount : Attempt to remount an already-mounted filesystem. In this example, remount the system and increase its size. size=8G or size=5G : Override default maximum size of the /dev/shm filesystem. he size is given in bytes, and rounded up to entire pages. The default is half of the memory. The size parameter also accepts a suffix % to limit this tmpfs instance to that percentage of your pysical RAM: the default, when neither size nor nr_blocks is specified, is size=50%. In this example it is set to 8GiB or 5GiB. The tmpfs mount options for sizing ( size, nr_blocks, and nr_inodes) accept a suffix k, m or g for Ki, Mi, Gi (binary kilo, mega and giga) and can be changed on remount. nr_inodes=5k : The maximum number of inodes for this instance. The default is half of the number of your physical RAM pages, or (on a machine with highmem) the number of lowmem RAM pages, whichever is the lower. mode=700 : Set initial permissions of the root directory. tmpfs : Tmpfs is a file system which keeps all files in virtual memory. --------------------------------------------------------------------------- Another link: http://www.jamescoyle.net/how-to/943-create-a-ram-disk-in-linux Exerpt: mount -t [TYPE] -o size=[SIZE],opt2=[opt2],opt3=[opt3] [FSTYPE] [MOUNTPOINT] Substitute the following attirbutes for your own values: [TYPE] is the type of RAM disk to use; either tmpfs or ramfs. [SIZE] is the size to use for the file system. Remember that ramfs does not have a physical limit and is specified as a starting size. [FSTYPE] is the type of RAM disk to use; either tmpfs, ramfs, ext4, etc. Example: mount -t tmpfs -o size=512m tmpfs /mnt/ramdisk """ def __init__(self, size=0, mountpoint="", logger=False, mode=700, uid=None, gid=None, fstype="tmpfs", nr_inodes=None, nr_blocks=None): """ """ super(RamDisk, self).__init__(size, mountpoint, logger) ##### # The passed in size of ramdisk should be in 1Mb chunks self.module_version = '20160224.032043.009191' self.logger = logger if not sys.platform.startswith("linux"): raise self.NotValidForThisOS("This ramdisk is only viable for a Linux.") if fstype in ["tmpfs", "ramfs"]: self.fstype = fstype if fstype == "tmpfs": self.myRamdiskDev = "/dev/tmpfs" else: raise self.BadRamdiskArguments("Not a valid argument for " + \ "'fstype'...") if isinstance(mode, int): self.mode = mode else: self.mode = 700 if not isinstance(uid, int): self.uid = os.getuid() else: self.uid = uid if not isinstance(gid, int): self.gid = os.getgid() else: self.gid = gid if isinstance(nr_inodes, basestring): self.nr_inodes = nr_inodes else: self.nr_inodes = None if isinstance(nr_blocks, basestring): self.nr_blocks = nr_blocks else: self.nr_blocks = None self.printData() ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) self.runWith.getNlogReturns() self.success = self._mount() ########################################################################### def buildCommand(self): """ Build a command based on the "fstype" passed in. For more options on the tmpfs filesystem, check the mount manpage. @author: Roy Nielsen """ command=None if self.fstype == "ramfs": command = ["/bin/mount", "-t", "ramfs"] elif self.fstype == "tmpfs": options = ["size=" + str(self.diskSize) + "m"] options.append("uid=" + str(self.uid)) options.append("gid=" + str(self.gid)) options.append("mode=" + str(self.mode)) """ try: options.append(self.nr_inodes) except AttributeError: pass try: options.append("nr_blocks=" + str(self.nr_blocks)) except AttributeError: pass """ command = ["/bin/mount", "-t", "tmpfs", "-o", ",".join(options), "tmpfs", self.mntPoint] #/bin/mount -t tmpfs -o size=500m,uid=0,gid=0,mode=700 /tmp/tmp0gnLNt return command ########################################################################### def _mount(self) : """ Mount the disk @author: Roy Nielsen """ success = False command = self.buildCommand() self.runWith.setCommand(command) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True self.printData() self.runWith.getNlogReturns() return success def remount(self, size=0, mountpoint="", mode=700, uid=None, gid=None, nr_inodes=None, nr_blocks=None): """ Use the tmpfs ability to be remounted with different options If bad input is given, the previous values will be used. @author: Roy Nielsen """ ##### # Input Validation: ##### # tmpfs is the only viable ramdisk that handles remounting ok. # this includes mouting tmpfs with msdos, ext2,3,4, etc. if not self.fstype == "tmpfs": raise self.BadRamdiskArguments("Can only use 'remount' with " + \ "tmpfs...") if size and isinstance(size, int): self.diskSize = size if mountpoint and isinstance(mountpoint, type.string): self.mntPoint = mountpoint if mode and isinstance(mode, int): self.mode = mode if uid and isinstance(uid, int): self.uid = uid if gid and isinstance(gid, int): self.gid = gid if nr_inodes and isinstance(nr_inodes, (int, long)): self.nr_inodes = nr_inodes if nr_blocks and isinstance(nr_blocks, (int, long)): self.nr_blocks = nr_blocks ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) self.buildCommand() self._mount() ########################################################################### def unmount(self) : """ Unmount the disk @author: Roy Nielsen """ success = False command = ["/bin/umount", self.mntPoint] self.runWith.setCommand(command) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True return success ########################################################################### def detach(self) : """ Unmount the disk @author: Roy Nielsen """ success = False success = self.unmount() return success ########################################################################### def __isMemoryAvailable(self): """ Check to make sure there is plenty of memory of the size passed in before creating the ramdisk Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ #mem_free = psutil.phymem_usage()[2] #print "Memory free = " + str(mem_free) success = False return success ########################################################################### def getVersion(self): """ Getter for the version of the ramdisk @author: Roy Nielsen """ return self.module_version
def __init__(self, **kwargs): """ Variables that can be passed in: logger userName userShell userComment userUid userPriGid userHomeDir """ if 'logDispatcher' not in kwargs: raise ValueError( "Variable 'logDispatcher' a required parameter for " + str(self.__class__.__name__)) else: self.logger = kwargs.get('logDispatcher') if 'userName' not in kwargs: self.userName = "" else: self.userName = kwargs.get('userName') if 'userShell' not in kwargs: self.userShell = "/bin/bash" else: userShell = kwargs.get('userShell') if 'userComment' not in kwargs: self.userComment = "" else: self.userComment = kwargs.get('userComment') if 'userUid' not in kwargs: self.userUid = 10000 else: self.userUid = kwargs.get('userUid') if 'userPriGid' not in kwargs: self.userPriGid = 20 else: self.userPriGid = kwargs.get('userPriGid') if 'userHomeDir' not in kwargs: self.userHomeDir = "" else: self.userHomeDir = kwargs.get('userHomeDir') self.module_version = '20160225.125554.540679' ##### # Acqure the environment self.environ = Environment() ##### # THIS IS A LIBRARY, SO LOGS SHOULD BE INITIALIZED ELSEWHERE... # self.logger.initializeLogs() self.logger.log(lp.INFO, "Logger: " + str(self.logger)) ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger)
def __init__(self, conf, parent=None): """ Initialization method... @author: Roy Nielsen """ super(ConfigureRepos, self).__init__(parent) self.ui = Ui_Dialog() self.ui.setupUi(self) ##### # initialization of class variables. self.conf = conf self.environ = Environment() self.conf.loggerSelf() self.logger = self.conf.getLogger() #self.logger = self.conf.get_logger() self.logger.log(lp.DEBUG, str(self.logger)) self.runWith = RunWith(self.logger) self.libc = getLibc(self.logger) self.chkApp = CheckApplicable(self.environ, self.logger) macOsWhiteListApplicable = { 'type': 'white', 'os': { 'Mac OS X': ['10.0.0', 'r', '20.12.10'] } } ##### # Handle button box self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.close) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.okDone) ##### # Handle other buttons self.ui.downloadReposButton.clicked.connect(self.downloadRepos) self.ui.prepareIsoButton.clicked.connect(self.prepareIso) self.ui.gitResetHardButton.clicked.connect(self.resetRepos) self.ui.gitPullButton.clicked.connect(self.updateRepos) if self.chkApp.isApplicable(macOsWhiteListApplicable): self.ui.prepareIsoButton.clicked.connect(self.prepareIso) else: self.ui.prepareIsoButton.hide() self.ui.macosCheckBox.hide() ##### # default boxcutter repo path self.reposRoot = self.conf.getRepoRoot() ##### # Future features self.ui.winCheckBox.hide() self.ui.label_2.hide() self.ui.leReposPath.hide() self.ui.proxyButton.hide() ##### # Future features self.ui.winCheckBox.hide() self.ui.label_2.hide() self.ui.leReposPath.hide() self.ui.proxyButton.hide() self.git = "/usr/bin/git" ##### # repos self.repos2process = [] self.getSelected()
class MacOSUser(ParentManageUser): '''Class to manage users on Mac OS. #----- Getters @method findUniqueUid @method uidTaken @method getUser @method getUserShell @method getUserComment @method getUserUid @method getUserPriGid @method getUserHomeDir @method isUserInstalled @method isUserInGroup @method authenticate #----- Setters @method createStandardUser @method createBasicUser @method setUserShell @method setUserComment @method setUserUid @method setUserPriGid @method setUserHomeDir @method createHomeDirectory @method addUserToGroup @method setUserPassword @method fixUserHome #----- User removal @method rmUser @method rmUserFromGroup @method rmUserHome @author: Roy Nielsen ''' def __init__(self, **kwargs): """ Variables that can be passed in: logger userName userShell userComment userUid userPriGid userHomeDir """ if 'logDispatcher' not in kwargs: raise ValueError("Variable 'logDispatcher' a required parameter for " + str(self.__class__.__name__)) super(MacOSUser, self).__init__(**kwargs) self.module_version = '20160225.125554.540679' self.dscl = "/usr/bin/dscl" self.runWith = RunWith(self.logger) #---------------------------------------------------------------------- # Getters #---------------------------------------------------------------------- def findUniqueUid(self): '''We need to make sure to find an unused uid (unique ID) for the user, $ dscl . -list /Users UniqueID will list all the existing users, an unused number above 500 is good. @author: Roy Nielsen ''' success = False maxUserID = 0 newUserID = 0 userList = self.getDscl(".", "-list", "/Users", "UniqueID") ##### # Sort the list, add one to the highest value and return that # value for user in str(userList).split("\n"): if int(user.split()[1]) > maxUserID: maxUserID = int(user.split()[1]) newUserID = str(int(maxUserID + 1)) return newUserID #---------------------------------------------------------------------- def uidTaken(self, uid): '''See if the UID requested has been taken. Only approve uid's over 1k $ dscl . -list /Users UniqueID @author: Roy Nielsen :param uid: ''' uidList = [] success = False userList = self.getDscl(".", "-list", "/Users", "UniqueID") ##### # Sort the list, add one to the highest value and return that # value for user in str(userList).split("\n"): uidList.append(str(user.split()[1])) if str(uid) in uidList: success = True return success #---------------------------------------------------------------------- def getUser(self, userName=""): ''' :param userName: (Default value = "") ''' userInfo = False if self.isSaneUserName(userName): output = self.getDscl(".", "read", "/Users/" + str(userName), "RecordName") try: userInfo = output.split()[1] except (KeyError, IndexError) as err: self.logger.log(lp.INFO, "Error attempting to find user" + \ str(userName) + " in the " + \ "directory service.") else: raise BadUserInfoError("Need a valid user name...") return userInfo #---------------------------------------------------------------------- def getUserShell(self, userName=""): ''' :param userName: (Default value = "") ''' userShell = False if self.isSaneUserName(userName): output = self.getDscl(".", "read", "/Users/" + str(userName), "UserShell") try: userShell = output.split()[1] except (KeyError, IndexError) as err: self.logger.log(lp.INFO, "Error attempting to find user" + \ str(userName) + " in the " + \ "directory service.") else: raise BadUserInfoError("Need a valid user name...") return userShell #---------------------------------------------------------------------- def getUserComment(self, userName=""): ''' :param userName: (Default value = "") ''' userComment = False if self.isSaneUserName(userName): ##### # Need to process the output to get the right information due to a # spurrious "\n" in the output output = self.getDscl(".", "read", "/Users/" + str(userName), "RealName") try: userComment = output[1] except (KeyError, IndexError) as err: self.logger.log(lp.INFO, "Error attempting to find user" + \ str(userName) + " in the " + \ "directory service.") else: raise BadUserInfoError("Need a valid user name...") return userComment #---------------------------------------------------------------------- def getUserUid(self, userName=""): ''' :param userName: (Default value = "") ''' userUid = False if self.isSaneUserName(userName): output = self.getDscl(".", "read", "/Users/" + str(userName), "UniqueID") ##### # Process to get out the right information.... try: userUid = output.split()[1] except (KeyError, IndexError) as err: self.logger.log(lp.INFO, "Error attempting to find user" + \ str(userName) + " in the " + \ "directory service.") else: raise BadUserInfoError("Need a valid user name...") return userUid #---------------------------------------------------------------------- def getUserPriGid(self, userName=""): ''' :param userName: (Default value = "") ''' userPriGid = False if self.isSaneUserName(userName): output = self.getDscl(".", "read", "/Users/" + str(userName), "PrimaryGroupID") ##### # Process to get out the right information.... try: userPriGid = output.split()[1] except (KeyError, IndexError) as err: self.logger.log(lp.INFO, "Error attempting to find user" + \ str(userName) + " in the " + \ "directory service.") else: raise BadUserInfoError("Need a valid user name...") return userPriGid #---------------------------------------------------------------------- def getUserHomeDir(self, userName=""): ''' :param userName: (Default value = "") ''' userHomeDir = False if self.isSaneUserName(userName): output = self.getDscl(".", "read", "/Users/" + str(userName), "NFSHomeDirectory") ##### # Process to get out the right information.... try: userHomeDir = output.split()[1] except (KeyError, IndexError) as err: self.logger.log(lp.INFO, "Error attempting to find user" + \ str(userName) + " in the " + \ "directory service.") else: raise BadUserInfoError("Need a valid user name...") return userHomeDir #---------------------------------------------------------------------- def isUserInstalled(self, user=""): '''Check if the user "user" is installed @author Roy Nielsen :param user: (Default value = "") ''' success = False if self.isSaneUserName(user): cmd = [self.dscl, ".", "-read", "/Users/" + str(user)] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True return success #---------------------------------------------------------------------- def isUserInGroup(self, userName="", groupName=""): '''Check if this user is in this group @author: Roy Nielsen :param userName: (Default value = "") :param groupName: (Default value = "") ''' self.logger.log(lp.DEBUG, "U: " + str(userName)) self.logger.log(lp.DEBUG, "G: " + str(groupName)) success = False if self.isSaneUserName(userName) and self.isSaneGroupName(groupName): output = self.getDscl(".", "-read", "/Groups/" + groupName, "users") self.logger.log(lp.CRITICAL, "Output: " + str(output)) users = output[1:] self.logger.log(lp.CRITICAL, "Users: " + str(users)) if userName in users: success = True return success #---------------------------------------------------------------------- def validateUser(self, userName=False, userShell=False, userComment=False, userUid=False, userPriGid=False, userHomeDir=False): '''Future functionality... validate that the passed in parameters to the class instanciation match. @author: :param userName: (Default value = False) :param userShell: (Default value = False) :param userComment: (Default value = False) :param userUid: (Default value = False) :param userPriGid: (Default value = False) :param userHomeDir: (Default value = False) ''' sane = False ##### # Look up all user attributes and check that they are accurate. # Only check the "SANE" parameters passed in. if self.isSaneUserName(userName): self.userName = userName sane = True else: raise BadUserInfoError("Need a valid user name...") if self.isSaneUserShell(userShell) and sane: self.userShell = userShell elif not userShell: pass else: sane = False if self.isSaneUserComment(userComment) and sane: self.userComment = userComment elif not userComment: pass else: sane = False if self.isSaneUserUid(str(userUid)) and sane: self.userUid = self.userUid elif not userUid: pass else: sane = False if self.isSaneUserPriGid(str(userPriGid)) and sane: self.userUid = userUid elif not userPriGid: pass else: sane = False if self.isSaneUserHomeDir(userHomeDir) and sane: self.userHomeDir = userHomeDir elif not userHomeDir: pass else: sane = False return sane def authenticate(self, user="", password=""): '''Open a pty to run "su" to see if the password is correct... :param user: (Default value = "") :param password: (Default value = "") ''' authenticated = False if not self.isSaneUserName(user) or \ re.match("^\s+$", password) or not password: self.logger.log(lp.INFO, "Cannot pass in empty or bad parameters...") self.logger.log(lp.INFO, "user = \"" + str(user) + "\"") self.logger.log(lp.INFO, "check password...") else: output = "" internal_command = ["/usr/bin/su", "-", str(user), "-c", "/bin/echo hello world"] command = " ".join(internal_command) self.logger.log(lp.INFO, "command: " + str(command)) (master, slave) = pty.openpty() process = Popen(internal_command, stdin=slave, stdout=slave, stderr=slave, shell=False) ##### # Read password prompt prompt = os.read(master, 512) ##### # send the password os.write(master, password + "\n") ##### # catch the password prompt = os.read(master, 512) ##### # catch the output output = os.read(master, 512) os.close(master) os.close(slave) process.wait() output = output.strip() ##### # Check if valid or not... if re.match("^su: Sorry", str(output)): authenticated = False elif re.match("^hello world", str(output)): authenticated = True else: authenticated = False self.logger.log(lp.INFO, "Leaving authenticate method with " + \ "output of: \"" + str(output) + "\"") return authenticated #---------------------------------------------------------------------- # Setters #---------------------------------------------------------------------- def createStandardUser(self, userName, password): '''Creates a user that has the "next" uid in line to be used, then puts in in a group of the same id. Uses /bin/bash as the standard shell. The userComment is left empty. Primary use is managing a user during test automation, when requiring a "user" context. It does not set a login keychain password as that is created on first login to the GUI. @author: Roy Nielsen :param userName: :param password: ''' self.createBasicUser(userName) newUserID = self.findUniqueUid() newUserGID = newUserID self.setUserUid(userName, newUserID) self.setUserPriGid(userName, newUserID) self.setUserHomeDir(userName) self.setUserShell(userName, "/bin/bash") self.setUserPassword(userName, password) ##### # Don't need to set the user login keychain password as it should be # created on first login. #---------------------------------------------------------------------- def createBasicUser(self, userName=""): '''Create a username with just a moniker. Allow the system to take care of the rest. Only allow usernames with letters and numbers. On the MacOS platform, all other steps must also be done. @author: Roy Nielsen :param userName: (Default value = "") ''' success = False reterr = "" if isinstance(userName, str)\ and re.match("^[A-Za-z][A-Za-z0-9]*$", userName): cmd = [self.dscl, ".", "-create", "/Users/" + str(userName)] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True else: raise DsclError("Error trying to set a value with dscl (" + \ str(reterr).strip() + ")") return success #---------------------------------------------------------------------- def setUserShell(self, user="", shell=""): '''dscl . -create /Users/luser UserShell /bin/bash @author: Roy Nielsen :param user: (Default value = "") :param shell: (Default value = "") ''' success = False if self.isSaneUserName(user) and self.isSaneUserShell(shell): isSetDSL = self.setDscl(".", "-create", "/Users/" + str(user), "UserShell", str(shell)) if isSetDSL: success = True return success #---------------------------------------------------------------------- def setUserComment(self, user="", comment=""): '''dscl . -create /Users/luser RealName "Real A. Name" @author: Roy Nielsen :param user: (Default value = "") :param comment: (Default value = "") ''' success = False if self.isSaneUserName(user) and comment: isSetDSL = self.setDscl(".", "-create", "/Users/" + str(user), "RealName", str(comment)) if isSetDSL: success = True return success #---------------------------------------------------------------------- def setUserUid(self, user="", uid=""): '''dscl . -create /Users/luser UniqueID "503" @author: Roy Nielsen :param user: (Default value = "") :param uid: (Default value = "") ''' success = False if self.isSaneUserName(user) and uid: isSetDSL = self.setDscl(".", "-create", "/Users/" + str(user), "UniqueID", str(uid)) if isSetDSL: success = True return success #---------------------------------------------------------------------- def setUserPriGid(self, user="", priGid=""): '''dscl . -create /Users/luser PrimaryGroupID 20 @author: Roy Nielsen :param user: (Default value = "") :param priGid: (Default value = "") ''' success = False if self.isSaneUserName(user) and priGid: isSetDSL = self.setDscl(".", "-create", "/Users/" + str(user), "PrimaryGroupID", str(priGid)) if isSetDSL: success = True return success #---------------------------------------------------------------------- def setUserHomeDir(self, user="", userHome=""): '''Create a "local" home directory dscl . -create /Users/luser NFSHomeDirectory /Users/luser better yet: createhomedir -l -u <username> @author: Roy Nielsen :param user: (Default value = "") :param userHome: (Default value = "") ''' success = False ##### # Creating a non-standard userHome is not currently permitted #if self.saneUserName(user) and self.saneUserHomeDir(userHome): if self.isSaneUserName(user): isSetDSCL = self.setDscl(".", "-create", "/Users/" + str(user), "NFSHomeDirectory", str("/Users/" + str(user))) if isSetDSCL: success = True return success #---------------------------------------------------------------------- def createHomeDirectory(self, user=""): '''createhomedir -c -u luser This should use the system "User Template" for standard system user settings. @author: Roy Nielsen :param user: (Default value = "") ''' success = False reterr = "" if user: cmd = ["/usr/sbin/createhomedir", "-c", " -u", + str(user)] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True else: raise CreateHomeDirError("Error trying to create user home (" + \ str(reterr).strip() + ")") return success #---------------------------------------------------------------------- def addUserToGroup(self, user="", group=""): '''dscl . -append /Groups/admin GroupMembership luser @author: Roy Nielsen :param user: (Default value = "") :param group: (Default value = "") ''' success = False if self.isSaneUserName(user) and self.isSaneGroupName(group): isSetDSCL = self.setDscl(".", "-append", "/Groups/" + str(group), "GroupMembership", str(user)) if isSetDSCL: success = True return success #---------------------------------------------------------------------- def setUserPassword(self, user="", password="", oldPassword=""): '''dscl . -passwd /Users/luser password -- or -- dscl . -passwd /Users/luser oldPassword password @author: Roy Nielsen :param user: (Default value = "") :param password: (Default value = "") :param oldPassword: (Default value = "") ''' success = False if self.isSaneUserName(user): if oldPassword: isSetDSCL = self.setDscl(".", "-passwd", "/Users/" + str(user), '%s'%oldPassword, '%s'%password) else: isSetDSCL = self.setDscl(".", "-passwd", "/Users/" + str(user), '%s'%password) self.logger.log(lp.DEBUG, "isSetDSCL: " + str(isSetDSCL)) else: self.logger.log(lp.DEBUG, "Tribbles in the bulkhead Jim!") if not isSetDSCL: success = False else: success = True return success #---------------------------------------------------------------------- def fixUserHome(self, userName=""): '''Get the user information from the local directory and fix the user ownership and group of the user's home directory to reflect what is in the local directory service. @author: Roy Nielsen :param userName: (Default value = "") ''' success = False if self.isSaneUserName(userName): ##### # Acquire the user data based on the username first. try: userUid = self.getUserUid(userName) userPriGid = self.getUserPriGid(userName) userHomeDir = self.getUserHomeDir(userName) except BadUserInfoError as err: self.logger.log(lp.INFO, "Exception trying to find: \"" + \ str(userName) + "\" user information") self.logger.log(lp.INFO, "err: " + str(err)) else: success = True if success: try: for root, dirs, files in os.walk(userHomeDir): for d in dirs: os.chown(os.path.join(root, d), userUid, userPriGid) for f in files: os.chown(os.path.join(root, d, f), userUid, userPriGid) except: success = False self.logger.log(lp.INFO, "Exception attempting to chown...") raise err else: success = True return success #---------------------------------------------------------------------- # User Property Removal #---------------------------------------------------------------------- def rmUser(self, user=""): '''dscl . delete /Users/<user> @author: Roy Nielsen :param user: (Default value = "") ''' success = False if self.isSaneUserName(user): cmd = [self.dscl, ".", "-delete", "/Users/" + str(user)] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True else: raise Exception("Error trying to remove a user (" + \ str(reterr).strip() + ")") return success #---------------------------------------------------------------------- def rmUserHome(self, user=""): '''Remove the user home... right now only default location, but should look up the user home in the directory service and remove that specifically. @author: Roy Nielsen :param user: (Default value = "") ''' success = False if self.isSaneUserName(user): ##### # # ***** WARNING WILL ROBINSON ***** # # Please refactor to do a lookup of the user in the directory # service, and use the home directory specified there.. # try: shutil.rmtree("/Users/" + str(user)) except IOError or OSError as err: self.logger.log(lp.INFO, "Exception trying to remove user home...") self.logger.log(lp.INFO, "Exception: " + str(err)) raise err else: success = True return success #---------------------------------------------------------------------- def rmUserFromGroup(self, user="", group=""): ''' :param user: (Default value = "") :param group: (Default value = "") ''' success = False if self.isSaneUserName(user) and self.isSaneGroupName(group): isSetDSCL = self.setDscl(".", "-delete", "/Groups/" + str(group), "GroupMembership", str(user)) if isSetDSCL: success = True return success #---------------------------------------------------------------------- # Mac OS Specific Methods #---------------------------------------------------------------------- def setDscl(self, directory=".", action="", object="", property="", value=""): '''Using dscl to set a value in a directory... @author: Roy Nielsen :param directory: (Default value = ".") :param action: (Default value = "") :param object: (Default value = "") :param property: (Default value = "") :param value: (Default value = "") ''' success = False reterr = "" retval = "" ##### # If elevated, use the liftDown runWith method to run the command as # a regular user. if directory and action and object and property: if directory and action and object and property and value: cmd = [self.dscl, directory, action, object, property, value] else: cmd = [self.dscl, directory, action, object, property] self.runWith.setCommand(cmd) if re.match("^%0$", str(os.getuid()).strip()): ##### # Run the command, lift down... self.logger.log(lp.DEBUG, "dscl-cmd: " + str(cmd)) self.runWith.liftDown(self.userName) self.logger.log(lp.INFO, "Took the lift down...") retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True else: ##### # Run the command retval, reterr, retcode = self.runWith.communicate() if not reterr: success = True retval, reterr, retcode = self.runWith.getNlogReturns() return success #---------------------------------------------------------------------- def getDscl(self, directory="", action="", dirobj="", dirprop=""): '''Using dscl to retrieve a value from the directory @author: Roy Nielsen :param directory: (Default value = "") :param action: (Default value = "") :param dirobj: (Default value = "") :param dirprop: (Default value = "") ''' success = False reterr = "" retval = "" ##### # FIRST VALIDATE INPUT!! if isinstance(directory, str) and re.match("^[/\.][A-Za-z0-9/]*", directory): success = True else: success = False if isinstance(action, str) and re.match("^[-]*[a-z]+", action) and success: success = True else: success = False if isinstance(dirobj, str) and re.match("^[A-Za-z0=9/]+", dirobj) and success: success = True else: success = False if isinstance(dirprop, str) and re.match("^[A-Za-z0-9]+", dirprop) and success: success = True else: success = False self.logger.log(lp.CRITICAL, "SUCCESS: " + str(success)) ##### # Now do the directory lookup. if success: cmd = [self.dscl, directory, action, dirobj, dirprop] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True else: raise DsclError("Error trying to get a value with dscl (" + \ str(reterr).strip() + ")") return retval #---------------------------------------------------------------------- def isUserAnAdmin(self, userName=""): '''Check if this user is in this group @author: Roy Nielsen :param userName: (Default value = "") ''' success = False if self.isSaneUserName(userName): success = self.isUserInGroup(userName, "admin") return success #---------------------------------------------------------------------- def acquireUserData(self): '''Acquire user data for local user lookup information. @author: Roy Nielsen ''' pass
class MacOSUser(ManageUserTemplate): """ Class to manage users on Mac OS. #----- Getters @method findUniqueUid @method uidTaken @method getUser @method getUserShell @method getUserComment @method getUserUid @method getUserPriGid @method getUserHomeDir @method isUserInstalled @method isUserInGroup @method authenticate #----- Setters @method createStandardUser @method createBasicUser @method setUserShell @method setUserComment @method setUserUid @method setUserPriGid @method setUserHomeDir @method createHomeDirectory @method addUserToGroup @method setUserPassword @method fixUserHome #----- User removal @method rmUser @method rmUserHome @method rmUserFromGroup @author: Roy Nielsen """ def __init__(self, logger, userName="", userShell="/bin/bash", userComment="", userUid=1000, userPriGid=20, userHomeDir="/tmp"): super(MacOSUser, self).__init__(logger, userName, userShell, userComment, userUid, userPriGid, userHomeDir) self.module_version = '20160225.125554.540679' if isinstance(logger, CyLogger): self.logger = logger else: raise NotACyLoggerError("Passed in value for logger is invalid, try again.") self.dscl = "/usr/bin/dscl" self.userData = [] self.runWith = RunWith(self.logger) #---------------------------------------------------------------------- # Getters #---------------------------------------------------------------------- def findUniqueUid(self): """ """ pass #---------------------------------------------------------------------- def uidTaken(self, uid): """ """ pass #---------------------------------------------------------------------- def getUser(self, userName=""): """ """ pass #---------------------------------------------------------------------- def getUserShell(self, userName=""): """ """ pass #---------------------------------------------------------------------- def getUserComment(self, userName=""): """ """ pass #---------------------------------------------------------------------- def getUserUid(self, userName=""): """ """ pass #---------------------------------------------------------------------- def getUserPriGid(self, userName=""): """ """ pass #---------------------------------------------------------------------- def getUserHomeDir(self, userName=""): """ """ pass #---------------------------------------------------------------------- def isUserInstalled(self, user=""): """ """ pass #---------------------------------------------------------------------- def isUserInGroup(self, userName="", groupName=""): """ """ pass #---------------------------------------------------------------------- def authenticate(self, user="", password=""): """ """ pass #---------------------------------------------------------------------- # Setters #---------------------------------------------------------------------- def createStandardUser(self, userName, password): """ Creates a user that has the "next" uid in line to be used, then puts in in a group of the same id. Uses /bin/bash as the standard shell. The userComment is left empty. Primary use is managing a user during test automation, when requiring a "user" context. @author: Roy Nielsen """ pass #---------------------------------------------------------------------- def createBasicUser(self, userName=""): """ Create a username with just a moniker. Allow the system to take care of the rest. Only allow usernames with letters and numbers. @author: Roy Nielsen """ pass #---------------------------------------------------------------------- def setUserShell(self, user="", shell=""): """ """ pass #---------------------------------------------------------------------- def setUserComment(self, user="", comment=""): """ """ pass #---------------------------------------------------------------------- def setUserUid(self, user="", uid=""): """ """ pass #---------------------------------------------------------------------- def setUserPriGid(self, user="", priGid=""): """ """ pass #---------------------------------------------------------------------- def setUserHomeDir(self, user="", userHome=""): """ """ pass #---------------------------------------------------------------------- def addUserToGroup(self, user="", group=""): """ """ pass #---------------------------------------------------------------------- def rmUserFromGroup(self, user="", group=""): """ """ pass #---------------------------------------------------------------------- def setUserPassword(self, user="", password=""): """ """ pass #---------------------------------------------------------------------- # User Property Removal #---------------------------------------------------------------------- def rmUser(self, user=""): """ """ pass #---------------------------------------------------------------------- def rmUserHome(self, user=""): """ """ pass #---------------------------------------------------------------------- def fixUserHome(self, userName=""): """ Get the user information from the local directory and fix the user ownership and group of the user's home directory to reflect what is in the local directory service. @author: Roy Nielsen """ pass #---------------------------------------------------------------------- # Unix related OS Specific Methods, uses /etc/password user management #---------------------------------------------------------------------- def acquireUserData(self): """ Acquire local user data that can be found in /etc/password and /etc/shadow. @author: Roy Nielsen """ success = False ##### # Check the UID of the user, only try processing what is available # to the uid running this code. if not os.getuid() == 0: success = self.processEtcPassword() if success: self.processEtcGroup() else: success = self.processEtcPassword() if success: success = self.processEtcGroup() if success: self.processEtcShadow() return success def processEtcPassword(self): """ Acquire user data from /etc/passwd """ success = False userinfo = {} ##### # Process /etc/passwd try: pass_file = open("/etc/password", 'r') except OSError as err: self.logger.log(lp.INFO, "Error trying to acquire /etc/password data: " + str(err)) else: for line in pass_file.readlines(): ##### # Pull apart the line from the password file to acquire the data col = line.split(':') userinfo = {} user = col[0] userinfo['uid'] = col[2] userinfo['pgid'] = col[3] userinfo['ucomment'] = col[4] userinfo['uhome'] = col[5] userinfo['ushell'] = col[6] ##### # Put the acquired user data into the class variable self.userData[user] = userinfo pass_file.close() success = True return success def processEtcShadow(self): """ Acquire user data from /etc/shadow @author: Roy Nielsen """ success = False ##### # Process /etc/passwd try: pass_file = open("/etc/password", 'r') except OSError as err: self.logger.log(lp.INFO, "Error trying to acquire /etc/shadow data: " + str(err)) else: for line in pass_file.readlines(): ##### # Pull apart the line from the password file to acquire the data col = line.split(':') userinfo = {} user = "" user = col[0] userinfo['lastchanged'] = col[2] userinfo['min'] = col[3] userinfo['max'] = col[4] userinfo['warn'] = col[5] userinfo['inactive'] = col[6] userinfo['expore'] = col[5] ##### # Put the acquired user data into the class variable self.userData[user] = userinfo pass_file.close() success = True return success def processEtcGroup(self): """ Acqure a list of groups each user is in @author: Roy Nielsen """ success = False grps = "/usr/bin/groups" for user in self.userData: ##### # Run the 'groups <user>' command to acquire the user's groups cmd = [grps, user] self.runWith.setCommand(cmd) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() ##### # If there is no error, process the data. if not reterr: ##### # Acquire the user's groups from the output userGrps = retval.split() ##### # create a dictionary, which will later be added to userData # class variable. groups = {'groups' : userGrps} ##### # Add the groups the user is a member of. self.userData[user] += groups return success
def __init__(self, conf, parent=None): """ Initialization method... @author: Roy Nielsen """ super(VirtualMachineSettings, self).__init__(parent) self.ui = Ui_VmSettings_ui() self.ui.setupUi(self) ##### # initialization of class variables. self.conf = conf self.conf.loggerSelf() self.logger = self.conf.getLogger() #self.logger = self.conf.get_logger() self.logger.log(lp.DEBUG, str(self.logger)) self.runWith = RunWith(self.logger) self.libc = getLibc(self.logger) self.vPjh = PackerJsonHandler(self.logger) # variables file self.tPjh = PackerJsonHandler(self.logger) # template file self.jsonData = {} self.vmTypes = [] self.doVagrantBox = False self.vmSelected = False #################### ### TEMPORARY until functionality is supported self.ui.userButton.hide() self.ui.proxiesButton.hide() #################### ##### # Attempt to reset button roles self.ui.openJsonBtn = QtWidgets.QPushButton("Open Json") self.ui.openJsonBtn.clicked.connect(self.loadPreviousFile) self.ui.buttonBox.addButton(self.ui.openJsonBtn, QtWidgets.QDialogButtonBox.ActionRole) ##### # Handle button box #self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.reject) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Apply).clicked.connect(self.processVm) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Save).clicked.connect(self.saveForLater) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Reset).clicked.connect( self.resetToDefault) ##### # buttons for the stacked widget. self.ui.generalButton.clicked.connect(self.selectGeneral) self.ui.isoButton.clicked.connect(self.selectIso) self.ui.hardwareButton.clicked.connect(self.selectHardware) self.ui.userButton.clicked.connect(self.selectUser) self.ui.proxiesButton.clicked.connect(self.selectProxies) ##### # Acquire current json varfile data and print it. self.varFilePath = self.conf.getCurrentVarFilePath() self.templateFilePath = "" self.workingDir = os.path.abspath(os.path.dirname(self.varFilePath)) self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, "Working dir: " + str(self.workingDir)) self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.logger.log(lp.DEBUG, ".") self.loadValuesToUI(self.varFilePath) self.selectGeneral()
def __init__(self, size, mountpoint, logger, mode=700, uid=None, gid=None, fstype="tmpfs", nr_inodes=None, nr_blocks=None): """ """ super(RamDisk, self).__init__(size, mountpoint, logger) ##### # The passed in size of ramdisk should be in 1Mb chunks self.module_version = '20160224.032043.009191' self.logger = logger if not sys.platform.startswith("linux"): raise NotValidForThisOS("This ramdisk is only viable for a Linux.") if fstype in ["tmpfs", "ramfs"]: self.fstype = fstype if fstype == "tmpfs": self.myRamdiskDev = "/dev/tmpfs" else: raise BadRamdiskArguments("Not a valid argument for " + \ "'fstype'...") if isinstance(mode, int): self.mode = mode else: self.mode = 700 if not isinstance(uid, int): self.uid = os.getuid() else: self.uid = uid if not isinstance(gid, int): self.gid = os.getgid() else: self.gid = gid if isinstance(nr_inodes, basestring): self.nr_inodes = nr_inodes else: self.nr_inodes = None if isinstance(nr_blocks, basestring): self.nr_blocks = nr_blocks else: self.nr_blocks = None ##### # Initialize the mount and umount command paths... self.mountPath = "" self.umountPath = "" self.getCmds() ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) #self.runWith.getNlogReturns() self.success = self._mount() self.logger.log(lp.DEBUG, "Finishing linux ramdisk init...")
class RamDisk(RamDiskTemplate): """ http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html In this example, remount /dev/shm with 8G size as follows: # mount -o remount,size=8G /dev/shm To be frank, if you have more than 2GB RAM + multiple Virtual machines, this hack always improves performance. In this example, you will give you tmpfs instance on /disk2/tmpfs which can allocate 5GB RAM/SWAP in 5K inodes and it is only accessible by root: # mount -t tmpfs -o size=5G,nr_inodes=5k,mode=700 tmpfs /disk2/tmpfs Where, -o opt1,opt2 : Pass various options with a -o flag followed by a comma separated string of options. In this examples, I used the following options: remount : Attempt to remount an already-mounted filesystem. In this example, remount the system and increase its size. size=8G or size=5G : Override default maximum size of the /dev/shm filesystem. he size is given in bytes, and rounded up to entire pages. The default is half of the memory. The size parameter also accepts a suffix % to limit this tmpfs instance to that percentage of your pysical RAM: the default, when neither size nor nr_blocks is specified, is size=50%. In this example it is set to 8GiB or 5GiB. The tmpfs mount options for sizing ( size, nr_blocks, and nr_inodes) accept a suffix k, m or g for Ki, Mi, Gi (binary kilo, mega and giga) and can be changed on remount. nr_inodes=5k : The maximum number of inodes for this instance. The default is half of the number of your physical RAM pages, or (on a machine with highmem) the number of lowmem RAM pages, whichever is the lower. mode=700 : Set initial permissions of the root directory. tmpfs : Tmpfs is a file system which keeps all files in virtual memory. --------------------------------------------------------------------------- Another link: http://www.jamescoyle.net/how-to/943-create-a-ram-disk-in-linux Exerpt: mount -t [TYPE] -o size=[SIZE],opt2=[opt2],opt3=[opt3] [FSTYPE] [MOUNTPOINT] Substitute the following attirbutes for your own values: [TYPE] is the type of RAM disk to use; either tmpfs or ramfs. [SIZE] is the size to use for the file system. Remember that ramfs does not have a physical limit and is specified as a starting size. [FSTYPE] is the type of RAM disk to use; either tmpfs, ramfs, ext4, etc. Example: mount -t tmpfs -o size=512m tmpfs /mnt/ramdisk """ def __init__(self, size, mountpoint, logger, mode=700, uid=None, gid=None, fstype="tmpfs", nr_inodes=None, nr_blocks=None): """ """ super(RamDisk, self).__init__(size, mountpoint, logger) ##### # The passed in size of ramdisk should be in 1Mb chunks self.module_version = '20160224.032043.009191' self.logger = logger if not sys.platform.startswith("linux"): raise NotValidForThisOS("This ramdisk is only viable for a Linux.") if fstype in ["tmpfs", "ramfs"]: self.fstype = fstype if fstype == "tmpfs": self.myRamdiskDev = "/dev/tmpfs" else: raise BadRamdiskArguments("Not a valid argument for " + \ "'fstype'...") if isinstance(mode, int): self.mode = mode else: self.mode = 700 if not isinstance(uid, int): self.uid = os.getuid() else: self.uid = uid if not isinstance(gid, int): self.gid = os.getgid() else: self.gid = gid if isinstance(nr_inodes, basestring): self.nr_inodes = nr_inodes else: self.nr_inodes = None if isinstance(nr_blocks, basestring): self.nr_blocks = nr_blocks else: self.nr_blocks = None ##### # Initialize the mount and umount command paths... self.mountPath = "" self.umountPath = "" self.getCmds() ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) #self.runWith.getNlogReturns() self.success = self._mount() self.logger.log(lp.DEBUG, "Finishing linux ramdisk init...") ########################################################################### def getCmds(self): """ Acquire the paths for mount and umount on the system... @author: Roy Nielsen """ success = False paths = [ "/bin", "/usr/bin", "/sbin", "/usr/sbin", "/usr/local/bin", "/user/local/sbin" ] ##### # Look for the mount command mountFound = False for path in paths: possibleFullPath = os.path.join(path, "mount") if os.path.exists(possibleFullPath): self.mountPath = possibleFullPath mountFound = True if not mountFound: raise SystemToolNotAvailable("Cannot find mount command...") ##### # Look for the umount command umountFound = False for path in paths: possibleFullPath = os.path.join(path, "umount") if os.path.exists(possibleFullPath): self.umountPath = possibleFullPath umountFound = True if not umountFound: raise SystemToolNotAvailable("Cannot find umount command...") ##### # Figure out if this method was successfull or not. if mountFound and umountFound: success = True return success ########################################################################### def buildCommand(self): """ Build a command based on the "fstype" passed in. For more options on the tmpfs filesystem, check the mount manpage. @author: Roy Nielsen """ command = None if self.fstype == "ramfs": command = [self.mountPath, "-t", "ramfs"] elif self.fstype == "tmpfs": options = ["size=" + str(self.diskSize) + "m"] options.append("uid=" + str(self.uid)) options.append("gid=" + str(self.gid)) options.append("mode=" + str(self.mode)) """ try: options.append(self.nr_inodes) except AttributeError: pass try: options.append("nr_blocks=" + str(self.nr_blocks)) except AttributeError: pass """ command = [ self.mountPath, "-t", "tmpfs", "-o", ",".join(options), "tmpfs", self.mntPoint ] self.logger.log(lp.DEBUG, "command: " + str(command)) #/bin/mount -t tmpfs -o size=500m,uid=0,gid=0,mode=700 /tmp/tmp0gnLNt return command ########################################################################### def _format(self): """ One can't really format a tmpfs disk, so this will mimic a format by unmounting an recreating the disk. @author: Roy Nielsen """ success = False successOne = self.umount() successTwo = self._mount() if successOne and successTwo: success = True return success ########################################################################### def _mount(self): """ Mount the disk @author: Roy Nielsen """ success = False command = self.buildCommand() self.logger.log(lp.WARNING, "Command: " + str(command)) if self.runWith.setCommand(command): self.logger.log(lp.DEBUG, "All is Stars, Rainbows and Unicorns...") output, error, returncode = self.runWith.communicate() self.logger.log(lp.DEBUG, "All is Stars, Rainbows and Unicorns...") else: raise Exception( "Cannot Grok Command.................................") self.logger.log(lp.DEBUG, "output : " + str(output)) self.logger.log(lp.DEBUG, "error : " + str(error)) self.logger.log(lp.DEBUG, "returncode: " + str(returncode)) if not error: success = True self.logger.log(lp.DEBUG, "Damn it Jim! The Damn Thing worked!!!") self.getNlogData() return success ########################################################################### def remount(self, size=0, mountpoint="", mode=700, uid=None, gid=None, nr_inodes=None, nr_blocks=None): """ Use the tmpfs ability to be remounted with different options If bad input is given, the previous values will be used. @author: Roy Nielsen """ ##### # Input Validation: ##### # tmpfs is the only viable ramdisk that handles remounting ok. # this includes mouting tmpfs with msdos, ext2,3,4, etc. if not self.fstype == "tmpfs": raise BadRamdiskArguments("Can only use 'remount' with " + \ "tmpfs...") if size and isinstance(size, int): self.diskSize = size if mountpoint and isinstance(mountpoint, type.string): self.mntPoint = mountpoint if mode and isinstance(mode, int): self.mode = mode if uid and isinstance(uid, int): self.uid = uid if gid and isinstance(gid, int): self.gid = gid if nr_inodes and isinstance(nr_inodes, (int, long)): self.nr_inodes = nr_inodes if nr_blocks and isinstance(nr_blocks, (int, long)): self.nr_blocks = nr_blocks self.buildCommand() self._mount() ########################################################################### def unmount(self): """ Unmount the disk @author: Roy Nielsen """ success = False command = [self.umountPath, self.mntPoint] self.runWith.setCommand(command) self.runWith.communicate() retval, reterr, retcode = self.runWith.getNlogReturns() if not reterr: success = True return success ########################################################################### def umount(self): """ Unmount the disk @author: Roy Nielsen """ success = False success = self.unmount() return success ########################################################################### def detach(self): """ Unmount the disk @author: Roy Nielsen """ success = False success = self.umount() return success ########################################################################### def __isMemoryAvailable(self): """ Check to make sure there is plenty of memory of the size passed in before creating the ramdisk Must be over-ridden to provide OS/Method specific functionality @author: Roy Nielsen """ #mem_free = psutil.phymem_usage()[2] #print "Memory free = " + str(mem_free) success = False return success ########################################################################### def getVersion(self): """ Getter for the version of the ramdisk @author: Roy Nielsen """ return self.module_version
myout, myerr = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=None).communicate() except OSError, err: print traceback.format_exc(err) print str(err) else: sys.stdout.flush() print "myout: " + str(myout) print "\n" print "myerr: " + str(myerr) logger = CyLogger(debug_mode=True) logger.initializeLogs() rw = RunWith(logger) cmd = [ "/usr/bin/osascript", "-e", '\'do shell script "{0}" user name "{1}" password "{2}" with administrator privileges\'' .format(subcmd, user, userpass) ] rw.setCommand(cmd) rw.waitNpassThruStdout() for line in rw.getStdout().split("\n"): print line + "\n"
class PrepareIso(QtWidgets.QDialog): """ Class to manage the prepare_iso dialog... @author: Roy Nielsen """ def __init__(self, conf, parent=None): """ Initialization method... @author: Roy Nielsen """ super(PrepareIso, self).__init__(parent) self.ui = Ui_PrepareMacosImage() self.ui.setupUi(self) ##### # initialization of class variables. self.conf = conf self.conf.loggerSelf() self.logger = self.conf.getLogger() #self.logger = self.conf.get_logger() self.logger.log(lp.DEBUG, str(self.logger)) self.runWith = RunWith(self.logger) self.libc = getLibc(self.logger) ##### # Handle button box self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.reject) self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.accept) ##### # Handle other buttons self.ui.bOpenInstallerApp.clicked.connect(self.openInstallerApp) self.ui.bPrepareIso.clicked.connect(self.prepareIso) ##### # Set up collection of administrator credentials self.adminCreds = AdministratorCredentials(self.conf) self.adminCreds.creds.connect(self.setUserAndPass) ##### # Instanciate a PackerJsonHandler self.pjh = PackerJsonHandler(self.logger) def setUserAndPass(self, user="", password=""): ''' ''' self.username = user.strip() self.password = password.strip() def openInstallerApp(self): ''' ''' self.installerApp = "" fname, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file', "/Applications", "Install*.app") if not os.path.isdir(fname) or not re.match(".*\.app$", fname): ##### # Throw an error QtWidgets.QMessageBox.critical(self, "Error", "...Not a valid installer Application...", QtWidgets.QMessageBox.Ok) else: self.ui.leInstallAppLocation.setText(fname) self.installerApp = re.sub(" ", "\\\\\ ", fname.strip()) #self.installerApp = fname.strip() self.logger.log(lp.DEBUG, "installerApp: " + str(self.installerApp)) def prepareIso(self): ''' The commands to create the disk image packer can use are: cd ~boxcutter/macos sudo prepare_iso/prepare_iso.sh /Applications/Install\ OS\ X\ El\ Capitan.app dmg "do shell script \"/Applications/stonix4mac.app/Contents/Resources/stonix.app/Contents/MacOS/stonix > /dev/null 2>&1 &\" with administrator privileges" ''' adminCredsReturns = self.adminCreds.exec_() self.adminCreds.raise_() returnDir = os.getcwd() os.chdir(self.conf.getRepoRoot() + "/macos") print os.getcwd() scriptPath = self.conf.getRepoRoot() + "/macos/prepare_iso/prepare_iso.sh" installerApp = re.sub(r"\\", r"", self.installerApp) dmgPath = "/Contents/SharedSupport/InstallESD.dmg" subcmd = "%s %s%s dmg"%(scriptPath, self.installerApp, dmgPath) self.logger.log(lp.DEBUG, "Subcmd: " + str(subcmd)) #subcmd = re.sub(r"\\", r"", subcmd) #self.logger.log(lp.DEBUG, "Subcmd: " + str(subcmd)) cmd = ["/usr/bin/osascript", "-e", "do shell script \"{0}\" user name \"{1}\" password \"{2}\" with administrator privileges".format(subcmd, self.username, self.password)] self.runWith.setCommand(cmd, myshell=False) output, error, retcode = self.runWith.waitNpassThruStdout() self.logger.log(lp.DEBUG, "out: " + str(output)) self.logger.log(lp.DEBUG, "err: " + str(error)) self.logger.log(lp.DEBUG, "retcode: " + str(ord(retcode))) dmgName = "" ##### # Get the (\w+_InstallESD_\w+\.dmg) name out of the output to write it # into the appropriate varfile compile_dmg_name = re.compile(".*(OSX_InstallESD_[\d+\.]+_\w+\.dmg).*") #dmgName = "" if not re.search("\n", output): matcher = "\r" else: matcher = "\n" for line in output.split(matcher): try: if not line: continue self.logger.log(lp.DEBUG, str(line)) search = compile_dmg_name.search(line) dmgName = search.group(1) break except (AttributeError, KeyError), err: pass # self.logger.log(lp.DEBUG, traceback.format_exc(err)) if not dmgName: compile_dmg_name = re.compile(".*_(InstallESD_[\d+\.]+_\w+\.dmg).*") if not re.search("\n", error): matcher = "\r" else: matcher = "\n" for line in error.split(matcher): try: print str(line) if not line: continue self.logger.log(lp.DEBUG, str(line)) search = compile_dmg_name.search(line) dmgName = search.group(1) break except (AttributeError, KeyError), err: print "Could not grok, Jim..." pass
def __init__(self, size=0, mountpoint="", logger=False) : """ Constructor """ super(RamDisk, self).__init__(size, mountpoint, logger) if not getOsFamily() == "darwin": raise NotValidForThisOS("This ramdisk is only viable for a MacOS.") self.module_version = '20160225.125554.540679' ##### # Initialize the RunWith helper for executing shelled out commands. self.runWith = RunWith(self.logger) ##### # Calculating the size of ramdisk in 1Mb chunks self.diskSize = str(int(size) * 1024 * 1024 / 512) self.hdiutil = "/usr/bin/hdiutil" self.diskutil = "/usr/sbin/diskutil" ##### # Just /dev/disk<#> self.myRamdiskDev = "" ##### # should take the form of /dev/disk2s1, where disk 2 is the assigned # disk and s1 is the slice, or partition number. While just /dev/disk2 # is good for some things, others will need the full path to the # device, such as formatting the disk. self.devPartition = "" ##### # Indicate if the ramdisk is "mounted" in the Mac sense - attached, # but not mounted. self.mounted = False success = False ##### # Passed in disk size must have a non-default value if not self.diskSize == 0 : success = True ##### # Checking to see if memory is availalbe... if not self.__isMemoryAvailable() : self.logger.log(lp.DEBUG, "Physical memory not available to create ramdisk.") success = False else: success = True if success : ##### # If a mountpoint is passed in, use that, otherwise, set up for a # random mountpoint. if mountpoint: self.logger.log(lp.INFO, "\n\n\n\tMOUNTPOINT: " + str(mountpoint) + "\n\n\n") self.mntPoint = mountpoint ##### # eventually have checking to make sure that directory # doesn't already exist, and have data in it. else : ##### # If a mountpoint is not passed in, create a randomized # mount point. self.logger.log(lp.DEBUG, "Attempting to acquire a radomized mount " + \ "point. . .") if not self.getRandomizedMountpoint() : success = False ##### # The Mac has a more complicated method of managing ramdisks... if success: ##### # Attempt to create the ramdisk if not self.__create(): success = False self.logger.log(lp.WARNING, "Create appears to have failed..") else: ##### # Ramdisk created, try mounting it. if not self.__mount(): success = False self.logger.log(lp.WARNING, "Mount appears to have failed..") else: ##### # Filessystem journal will only slow the ramdisk down... # No need to keep it as when the journal is unmounted # all memory is de-allocated making it impossible to do # forensics on the volume. if not self.__remove_journal(): success = False self.logger.log(lp.WARNING, "Remove journal " + \ "appears to have failed..") self.success = success if success: self.logger.log(lp.INFO, "Mount point: " + str(self.mntPoint)) self.logger.log(lp.INFO, "Device: " + str(self.myRamdiskDev)) self.logger.log(lp.INFO, "Success: " + str(self.success))
def __init__(self, conf, parent=None): """ Initialization method... @author: Roy Nielsen """ super(VirtualMachineBuilder, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) ##### # initialization of class variables. self.conf = conf self.conf.loggerSelf() self.logger = self.conf.getLogger() self.environ = Environment() #self.logger = self.conf.get_logger() self.logger.log(lp.DEBUG, str(self.logger)) self.runWith = RunWith(self.logger) self.libc = getLibc(self.logger) ##### # Set label states self.ui.packerLabel.setText( "( <a href='https://www.packer.io'>https://www.packer.io</a> - Download and install packer separately )" ) self.ui.boxcutterLabel.setText( "( <a href='https://github.com/boxcutter'>https://github.com/boxcutter</a> - Clone repos separately )" ) ##### # Handle button box # self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Close).clicked.connect( self.closeApplication) self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Ok).clicked.connect(self.processVm) ##### # Rename Save button self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Save).setText("Configure Repos") btn = self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Save) btn.clicked.connect(self.configureRepos) ##### # Rename Apply button self.ui.buttonBox.button( QtWidgets.QDialogButtonBox.Apply).setText("Install packer") btnTwo = self.ui.buttonBox.button(QtWidgets.QDialogButtonBox.Apply) btnTwo.clicked.connect(self.installPacker) btnTwo.hide() self.chkApp = CheckApplicable(self.environ, self.logger) self.macOsBlackListApplicable = { 'type': 'black', 'os': { 'Mac OS X': ['10.0.0', 'r', '20.12.10'] } } self.linuxWhitelistApplicable = {'type': 'white', 'family': 'linux'} self.freebsdWhitelistApplicable = { 'type': 'white', 'family': 'freebsd' } self.macosWhitelistApplicable = {'type': 'white', 'family': 'darwin'} #openbsdWhitelistApplicable = {} #windowsWhitelistApplicable = {} ##### # Set up the configure dialog self.configRepos = ConfigureRepos(self.conf) self.configRepos.setWindowTitle("Configure Repos") ##### # Connect the configure 'done' signal to the refreshFamilyComboBox slot self.configRepos.doneConfigure.connect(self.refreshFamilyComboBox) ##### # Signal/slot to deal with osFamily combo box change self.ui.osFamily.currentIndexChanged.connect(self.osFamilySelected) self.refreshFamilyComboBox() self.osFamilySelected(0) self.logger.log(lp.DEBUG, "Done with VirtualMachineBuilder init...")
class test_run_commands(unittest.TestCase): """ """ @classmethod def setUpClass(self): """ """ ##### # Set up logging self.logger = CyLogger(debug_mode=True) self.logger.initializeLogs() self.rw = RunWith(self.logger) ##### # Start timer in miliseconds self.test_start_time = datetime.now() @classmethod def tearDownClass(self): """ """ pass def test_RunCommunicateWithBlankCommand(self): self.rw.__init__(self.logger) self.assertRaises(SetCommandTypeError, self.rw.setCommand, "") self.assertRaises(SetCommandTypeError, self.rw.setCommand, []) self.assertRaises(SetCommandTypeError, self.rw.setCommand, None) self.assertRaises(SetCommandTypeError, self.rw.setCommand, True) self.assertRaises(SetCommandTypeError, self.rw.setCommand, {}) def test_setCommand(self): self.rw.__init__(self.logger) command = ['/bin/ls', 1, '.'] self.assertRaises(SetCommandTypeError, self.rw.setCommand, [command]) def test_communicate(self): """ """ self.rw.__init__(self.logger) self.logger.log(lp.DEBUG, "=============== Starting test_communicate...") self.rw.setCommand('/bin/ls /var/spool', myshell=True) _, _, retval = self.rw.communicate(silent=False) self.assertEquals( retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.rw.setCommand(['/bin/ls', '-l', '/usr/local']) _, _, retval = self.rw.communicate(silent=False) self.assertEquals( retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.logger.log(lp.DEBUG, "=============== Ending test_communicate...") def test_wait(self): """ """ self.rw.__init__(self.logger) self.logger.log(lp.DEBUG, "=============== Starting test_wait...") self.rw.setCommand('/bin/ls /var/spool') _, _, retval = self.rw.communicate(silent=False) self.assertEquals( retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.rw.setCommand(['/bin/ls', '-l', '/usr/local']) _, _, retval = self.rw.communicate(silent=False) self.assertEquals( retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.rw.setCommand(['/bin/ls', '/1', '/']) _, _, retcode = self.rw.wait() self.logger.log(lp.WARNING, "retcode: " + str(retcode)) if sys.platform == 'darwin': self.assertEquals(retcode, 1, "Returncode Test failed...") else: self.assertEquals(retcode, 2, "Returncode Test failed...") def test_waitNpassThruStdout(self): """ """ self.rw.__init__(self.logger) self.rw.setCommand(['/bin/ls', '-l', '/usr/local']) _, _, retval = self.rw.waitNpassThruStdout() self.assertEquals( retval, 0, "Valid [] command execution failed: " + '/bin/ls /var/spool --- retval: ' + str(retval)) self.rw.setCommand(['/bin/ls', '/1', '/']) _, _, retval = self.rw.waitNpassThruStdout() if sys.platform == 'darwin': self.assertEquals(retval, 1, "Returncode Test failed...") else: self.assertEquals(retval, 2, "Returncode Test failed...") def test_timeout(self): """ """ self.rw.__init__(self.logger) if os.path.exists("/sbin/ping"): ping = "/sbin/ping" elif os.path.exists('/bin/ping'): ping = "/bin/ping" self.rw.setCommand([ping, '8.8.8.8']) startTime = time.time() self.rw.timeout(3) elapsed = (time.time() - startTime) self.assertTrue(elapsed < 4, "Elapsed time is greater than it should be...") def test_runAs(self): """ """ pass def test_liftDown(self): """ """ pass def test_runAsWithSudo(self): """ """ pass def test_runWithSudo(self): """ """ pass def test_getecho(self): """ """ pass def test_waitnoecho(self): """ """ pass def test_RunThread(self): """ """ pass def test_runMyThreadCommand(self): """ """ pass