def do_unconfigure(sub_cmd, options): '''Performs the requested unconfigure operations''' try: create_config_profiles(sub_cmd, options) except IOError: print _("IO error creating profile") sys.exit(SU_FATAL_ERR) if not options.alt_root: try: apply_profiles([CONFIG_PROFILE_DEST, UNCONFIG_PROFILE_DEST]) except: print _("Unable to apply the unconfigure parameters to the image") sys.exit(SU_FATAL_ERR) # system-unconfig is an SMF milestone. Bring the # system down to the milestone. cmd = [SVCADM, "milestone", "unconfig"] try: Popen.check_call(cmd, stderr=Popen.PIPE, check_result=(Popen.STDERR_EMPTY, 0)) except CalledProcessError as err: print err.popen.stderr print _("Unable to initiate unconfiguration process.") sys.exit(SU_FATAL_ERR)
def tearDown(self): '''Delete test instance of dhcp SMF service''' cmd = [dhcp.SVCCFG, "delete", self.dhcp_srv_inst] Popen.check_call(cmd) dhcp.DHCP_SERVER_IPV4_SVC = self.dhcp_srv_orig if os.path.exists(self.dhcp_dir): shutil.rmtree(self.dhcp_dir)
def set(self, propname, propvalue, dry_run): """ method to set a property for the pool """ cmd = [ZPOOL, "set", "%s=%s" % (propname, propvalue), self.name] if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def execute(self, dry_run=False): ''' The AbstractCheckpoint class requires this method in sub-classes. Execute in a subprocess the following command: /usr/sbin/bootadm update-archive -R target_directory Parameters: - the dry_run keyword paramater. The default value is False. If set to True, the log message describes the checkpoint tasks. Returns: - Nothing On failure, errors raised are managed by the engine. ''' self.logger.debug('ICT current task: updating the boot archive') # parse_doc populates variables necessary to execute the checkpoint self.parse_doc() # Run bootadm #XXX This should probably eventually be migrated once libbootmgt #goes back cmd = [ICT.BOOTADM, 'update-archive', '-R', self.target_dir] if dry_run: self.logger.debug('Executing: %s', cmd) if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=self.logger)
def create(self, dry_run, options=[]): """ method to create the zpool from the vdevs options - optional list of pool and/or dataset options to pass to the create flag """ cmd = [ZPOOL, "create", "-f"] if options: cmd.extend(options) # add the mountpoint if specified if self.mountpoint is not None: cmd.append("-m") cmd.append(self.mountpoint) cmd.append(self.name) if None in self.vdev_list: raise RuntimeError("Invalid entry in vdev_list: " + \ str(self.vdev_list)) # add the vdev_list to the cmd to preserve the format Popen needs cmd += self.vdev_list if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def _write_loader(self, devname, data_root): """Invoked by the MenuLstBootLoaderMixIn. Invoke installboot to write the bootblk to disk.""" args = ['/sbin/installboot', '-F', 'zfs'] # If a version is present, try to use it during installation if self.version is not None: args += ['-u', self.version] args += [data_root + (ZFSBootLoader.BOOTBLK_PATH % {'platformname': platform_name()}), devname] self._debug('_write_loader: Invoking command: ' + ' '.join(args)) try: Popen.check_call(args, stdout=Popen.STORE, stderr=Popen.STORE) except CalledProcessError as cpe: self._debug('_write_loader: Return code = %d' % cpe.returncode) if cpe.returncode != ZFSBootLoader.INSTALLBOOT_NOUPDT: output = '' if cpe.popen is not None and cpe.popen.stderr is not None: output = '\nOutput was:\n' + cpe.popen.stderr raise BootLoaderInstallError('installboot failed for ' 'device ' + devname + ': Return code ' + str(cpe.returncode) + output) except OSError as ose: raise BootLoaderInstallError('Error while trying to ' 'invoke installboot for ' 'device ' + devname + ': ' + str(ose))
def set(self, prop, value, dry_run): """ method to set a property on the ZFS filesystem """ cmd = [ZFS, "set", "%s=%s" % (prop, value), self.full_name] if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def unmount(self, dry_run): """ method to unmount the ramdisk """ if self.mounted: cmd = [UMOUNT, "-f", self.mountpoint] if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) self.mounted = False
def create_ramdisk(self, dry_run): """ create_ramdisk - method to create the ramdisk, if needed """ if not self.exists: # create the file first cmd = [MKFILE, "%dk" % self.size, self.ramdisk] if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def rollback(self, to_snapshot, recursive=False): """ rollback - method to rollback a ZFS filesystem to a given checkpoint """ cmd = [ZFS, "rollback"] if recursive: cmd.append("-r") cmd.append(self.snapname(to_snapshot)) Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def check_install_SMF(): ''' Check if install/server SMF services is available. returning True if available and False if not. ''' # Ensure system/install/server SMF service is available cmd = ["/usr/bin/svcs", "svc:/system/install/server"] try: Popen.check_call(cmd, stdout=Popen.DEVNULL, stderr=Popen.DEVNULL) except CalledProcessError: # This system does not have the service so skip the test raise SkipTest("svc:/system/install/server not installed")
def unpack(cls, iso, targetdir): '''Unpacks an AI ISO into targetdir, and returns an InstalladmImage object representing the unpacked image. ''' cmd = [com.SETUP_IMAGE_SCRIPT, com.IMAGE_CREATE, iso, targetdir] Popen.check_call(cmd, stderr=Popen.STORE) iso_img = cls(targetdir) iso_img.verify() iso_img._prep_ai_webserver() return iso_img
def reboot(is_x86): '''Reboot the machine, attempting fast reboot first if available''' cmds = _reboot_cmds(is_x86) for cmd in cmds: try: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=LOGGER) except (CalledProcessError): LOGGER.warn("Reboot failed:\n\t'%s'", " ".join(cmd)) else: LOGGER.warn("Reboot failed:\n\t'%s'.\nWill attempt" " standard reboot", " ".join(cmd))
def apply_profiles(profile_list): '''Apply config profiles to the SMF repository.''' for profile in profile_list: cmd = [SVCCFG, "apply", profile] try: Popen.check_call(cmd, stderr=Popen.PIPE, check_result=(Popen.STDERR_EMPTY, 0)) except CalledProcessError as err: print err.popen.stderr print _("Unable to apply SMF profile %s." % profile) raise
def destroy(self, dry_run, force=False): """ method to destroy the zpool """ if self.exists: cmd = [ZPOOL, "destroy"] if force: cmd.append("-f") cmd.append(self.name) if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def destroy(self, dry_run): """ method to unmount and destroy the lofi device """ if not self.exists: return self.unmount(dry_run) # there is an undocumented -f flag to lofiadm to 'force' the destroy cmd = [LOFIADM, "-f", "-d", self.lofi_device] if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def test_check_result(self): '''Popen.check_call() check_result keyword arg raises errors appropriately''' try: popen = Popen.check_call(self.cmd(0), check_result=(0, 4)) except CalledProcessError as err: self.fail("Unexpected CalledProcessError: %s" % err) try: popen = Popen.check_call(self.cmd(4), check_result=(0, 4)) except CalledProcessError as err: self.fail("Unexpected CalledProcessError: %s" % err) self.assertRaises(CalledProcessError, Popen.check_call, self.cmd(5), check_result=(0, 4))
def test_overlay_1(self): ''' Put original manifest together from pieces, and verify it. ''' mim = ManifestInput(self.AIM_MANIFEST_FILE) mim.load(self.TARGET_XML, not self.OVERLAY) mim.load(self.ADD_DRIVER_XML, self.OVERLAY) mim.load(self.SOFTWARE_XML, self.OVERLAY) mim.commit() TestOverlayA.strip_blank_lines(self.AIM_MANIFEST_FILE) # Raises an exception if diff command finds differences from original. Popen.check_call([self.DIFF, self.FULL_XML, self.AIM_MANIFEST_FILE])
def snapshot(self, snapshot_name, overwrite=False): """ snapshot - method to create a ZFS shapshot of the filesystem snapshot_name - name of the snapshot to create overwrite - boolean argument to determine if ZFS should delete an existing snapshot with the same name (if it exists) """ snap = self.snapname(snapshot_name) if overwrite and snap in self.snapshot_list: self.destroy(dry_run=False, snapshot=snapshot_name) cmd = [ZFS, "snapshot", snap] Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def destroy(self, dry_run, snapshot=None, recursive=False): """ destroy the filesystem """ if self.exists: if not dry_run: cmd = [ZFS, "destroy"] if recursive: cmd.append("-r") if snapshot is not None: cmd.append(self.snapname(snapshot)) else: cmd.append(self.full_name) Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def _run_dhcpinfo(self, code, maxent=1): '''Run the dhcpinfo command against this NIC, requesting 'code' maxent - for lists, if >1, return a list with maxent max length This function always returns successfully; if the underlying call to dhcpinfo fails, then None is returned. ''' nic_link = self.get_nic_link(self.nic_iface) if not self._nic_is_under_dhcp_control(): LOGGER().warn("This connection is not using DHCP") return None argslist = ['/sbin/dhcpinfo', '-i', nic_link, '-n', str(maxent), code] try: dhcp_popen = Popen.check_call(argslist, stdout=Popen.STORE, stderr=Popen.STORE, logger=LOGGER()) except CalledProcessError as error: LOGGER().warn("'dhcpinfo -i %s -n %s %s' failed with following " "error: %s", nic_link, str(maxent), code, error) return None # pylint: disable-msg=E1103 # dhcpout is a string return dhcp_popen.stdout.rstrip("\n")
def _nic_is_under_dhcp_control(self): '''Returns True if selected NIC is controlled by DHCP. Returns False otherwise. ''' # # Obtain type for all ipadm address objects created over given NIC. # Then search for presence of 'dhcp' type which indicates IPv4 # address object controlled by DHCP. # argslist = ['/usr/sbin/ipadm', 'show-addr', '-p', '-o', 'type', self.get_nic_link(self.nic_iface) + "/"] try: ipadm_popen = Popen.check_call(argslist, stdout=Popen.STORE, stderr=Popen.STORE, logger=LOGGER()) except CalledProcessError as error: LOGGER().warn("'ipadm' failed with following error: %s", error) return False if 'dhcp' in ipadm_popen.stdout.split(): return True else: return False
def exists(self): """ property to check for the existance of the filesystem """ cmd = [ZFS, "list", self.full_name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, check_result=Popen.ANY) return p.returncode == 0
def get(self, prop): """ method to return the value for a ZFS property of the filesystem """ cmd = [ZFS, "get", "-H", "-o", "value", prop, self.full_name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, stderr_loglevel=logging.DEBUG, logger=ILN) return p.stdout.strip()
def create(self, dry_run=False): """ create the filesystem """ if not self.exists: cmd = [ZFS, "create", "-p"] zfs_options = self.get_first_child(class_type=Options) if zfs_options is not None: cmd.extend(zfs_options.get_arg_list()) if self.mountpoint is not None: cmd.extend(["-o", "mountpoint=%s" % self.mountpoint]) cmd.append(self.full_name) if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, env={"LC_ALL": "C"})
def exists(self): """ property to check for the existance of the zpool """ cmd = [ZPOOL, "list", self.name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, check_result=Popen.ANY) return p.returncode == 0
def test_log_out(self): '''Popen.check_call(..., logger=some_logger) logs stdout''' logger = MockLogger(100) popen = Popen.check_call(self.cmd(0), stdout=Popen.STORE, logger=logger, stdout_loglevel=100) self.assertTrue(sys.executable in logger.msgs[100][0]) self.assertEqual("--stdout--", logger.msgs[100][1])
def print_zpool(doc): """ prints the output from the -z argument """ print "Zpool discovery" target = doc.persistent.get_children(class_type=Target)[0] logical = target.get_children(class_type=Logical)[0] zpool_list = logical.get_children(class_type=Zpool) print_format = "{0:>10} | {1:>20} | {2:>20} | {3:>7} | {4:>8} |" zpool_line = '-' * 79 print zpool_line print print_format.format( *["name", "bootfs", "guid", "size", "capacity"]) print zpool_line for zpool in zpool_list: # extract zpool information cmd = [ "/usr/sbin/zpool", "get", "bootfs,guid,size,capacity", zpool.name ] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE) # strip out just the third column. Exclude the header row and # trailing newline (bootfs, guid, size, capacity) = \ [line.split()[2] for line in p.stdout.split("\n")[1:-1]] print print_format.format( *[zpool.name, bootfs, guid, size, capacity]) print zpool_line
def exists(self): """ property to check for the existance of the zvol """ cmd = [ZFS, "list", self.full_name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, check_result=Popen.ANY) return p.returncode == 0
def create(self, dry_run): """ create the filesystem """ if not self.exists: cmd = [ZFS, "create", "-p"] zfs_options = self.get_first_child(class_type=Options) if zfs_options is not None: cmd.extend(zfs_options.get_arg_list()) if self.mountpoint is not None: cmd.extend(["-o", "mountpoint=%s" % self.mountpoint]) cmd.append(self.full_name) if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, env={"LC_ALL": "C"})
def validate_profile_external_dtd(prof_str, dtd='/usr/share/lib/xml/dtd/service_bundle.dtd.1'): ''' Given a profile in string format, a root directory and a DTD name, validate the profile against the external DTD using svccfg Args: prof_str - profile as string dtd - path to external DTD Returns: stderr output from 'svccfg apply -n', empty if no error ''' # specify DTD for external reference by svccfg os.environ["SVCCFG_DTD"] = dtd # string must be written to temporary file for svccfg # non-root user cannot write to /system/volatile if os.geteuid() == 0: tmpdir = '/system/volatile' else: tmpdir = '/tmp' prof_fo = tempfile.NamedTemporaryFile(dir=tmpdir, delete=False) prof_fo.write(prof_str) profname = prof_fo.name prof_fo.close() # validate against DTD using svccfg apply -n pargs = ['/usr/sbin/svccfg', 'apply', '-n', profname] # invoke command, save stderr, do not throw exception on failure cmdpipe = Popen.check_call(pargs, stderr=Popen.STORE, check_result=Popen.ANY) os.unlink(profname) if cmdpipe.returncode == 0: # success return '' # validation failure, return stderr return cmdpipe.stderr
def setUp(self): '''Create test instance of dhcp SMF service''' # save the original svc name of dhcp SMF service instance self.dhcp_srv_orig = dhcp.DHCP_SERVER_IPV4_SVC self.dhcp_srv = "svc:/network/dhcp/server" # First check whether dhcp SMF service is available on test machine # using svcs svc:/network/dhcp/server cmd = [dhcp.SVCS, self.dhcp_srv] try: Popen.check_call(cmd) except: # If svcs command fails from any reason skip this test raise SkipTest("DHCP SMF service not available") # name of our test instance self.instance_name = "ai-unittest" self.dhcp_srv_inst = self.dhcp_srv + ':' + self.instance_name self.dhcp_dir = tempfile.mkdtemp(dir="/tmp") # redefine DHCP_SERVER_IPV4_SVC to our test SMF service dhcp.DHCP_SERVER_IPV4_SVC = self.dhcp_srv_inst # construct list of svccfg commands cmds = list() # create new instance of dhcp service cmds.append( [dhcp.SVCCFG, "-s", self.dhcp_srv, "add", self.instance_name]) svccmd = [dhcp.SVCCFG, "-s", self.dhcp_srv_inst] # add config property group cmds.append(svccmd + ["addpg config application"]) # set test config file cmds.append(svccmd + [ "setprop config/config_file = astring: " + self.dhcp_dir + "/dhcpd4.conf" ]) # set lease file cmds.append(svccmd + [ "setprop config/lease_file = astring: " + self.dhcp_dir + "/dhcpd4.leases" ]) # general/complete must be set-up cmds.append(svccmd + ["addpg general framework"]) cmds.append(svccmd + ['setprop general/complete = astring: ""']) # disable service cmds.append([dhcp.SVCADM, "disable", self.dhcp_srv_inst]) for cmd in cmds: Popen.check_call(cmd)
def enable_install_service(svcname): ''' Enable an install service Enable the specified install service and update the service's installation properties. This function requires the service properties to already exist. Input: svcname - Service name Return: none Raises: ServiceCfgError if service properties are missing or install service properties do not exist. ''' logging.log(com.XDEBUG, '**** START service_config.enable_install_service ****') # Get the install properties for this service. The properties # should have already been created, even if the service is new. props = get_service_props(svcname) if not props: raise ServiceCfgError(_('\nError: installation service properties' ' do not exist for %s.\n') % (svcname)) # Confirm required keys are available and exit if not verify_key_properties(svcname, props) # Update status in service's properties props[PROP_STATUS] = STATUS_ON set_service_props(svcname, props) # ensure SMF install service is online aismf.service_enable_attempt() # Actually register service cmd = [com.SETUP_SERVICE_SCRIPT, com.SERVICE_REGISTER, svcname, props[PROP_TXT_RECORD]] try: logging.log(com.XDEBUG, "Executing: %s", cmd) Popen.check_call(cmd) except CalledProcessError: # Revert status in service's properties props = {PROP_STATUS: STATUS_OFF} set_service_props(svcname, props) raise ServiceCfgError()
def _snapshots(self): ''' Get list of snapshots. Snapshots returned will be in creation time order with the earliest first ''' cmd = [ZFS, "list", "-H", "-o", "name", "-t", "snapshot", "-s", "creation", "-r", self.full_name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) return p.stdout.splitlines()
def test_log_err(self): '''Popen.check_call(..., logger=some_logger) logs stderr''' logger = MockLogger(100) popen = Popen.check_call(self.cmd(0), stderr=Popen.STORE, logger=logger, stderr_loglevel=100, check_result=(0,)) self.assertTrue("--stderr--" in logger.msgs[100][0], logger.msgs[100][0])
def create(self, dry_run): """ create - method to create, newfs and mount a lofi device """ # create the ramdisk (if needed) self.create_ramdisk(dry_run) # create the lofi device cmd = [LOFIADM, "-a", self.ramdisk] if not dry_run: p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) self.lofi_device = p.stdout.strip() # newfs it cmd = [NEWFS, "-m", "0", "-o", "space"] if self.nbpi is not None: cmd.append("-i") cmd.append(str(self.nbpi)) cmd.append(self.lofi_device.replace("lofi", "rlofi")) if not dry_run: # due to the way Popen works, we can not assign a logger to the # call, otherwise the process will complete before we can pass the # "y" to newfs logger = logging.getLogger(ILN) logger.debug("Executing: %s" % " ".join(cmd)) p = Popen(cmd, stdin=Popen.PIPE, stdout=Popen.DEVNULL, stderr=Popen.DEVNULL) p.communicate("y\n") # ensure a directory exists to mount the lofi device to if not os.path.exists(self.mountpoint) and not dry_run: os.makedirs(self.mountpoint) cmd = [ MOUNT, "-F", "ufs", "-o", "rw", self.lofi_device, self.mountpoint ] if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) self.mounted = True
def create(self, dry_run): """ method to create a zvol. """ if not self.exists: # check self.size. If it's a Size() object, convert it to a string # ZFS expects if isinstance(self.size, Size): zvol_size = str(int(self.size.get(Size.mb_units))) + "M" else: zvol_size = self.size cmd = [ZFS, "create", "-p", "-V", zvol_size] zfs_options = self.get_first_child(class_type=Options) if zfs_options is not None: cmd.extend(zfs_options.get_arg_list()) cmd.append(self.full_name) if not dry_run: Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, env={"LC_ALL": "C"}) # check the "use" attribute if self.use == "swap": cmd = [SWAP, "-a", os.path.join("/dev/zvol/dsk", self.full_name)] Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, stderr_loglevel=logging.DEBUG) elif self.use == "dump": cmd = [DUMPADM, "-d", os.path.join("/dev/zvol/dsk", self.full_name)] if self.create_failure_ok: results = (0, 1) else: results = (0,) p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, stderr_loglevel=logging.DEBUG, check_result=results) if p.returncode == 1: logger = logging.getLogger(ILN) logger.warning("Unable to create dump Zvol " "with size %s." % zvol_size)
def _start_tftpd(): '''Start the tftp/udp6 service, a dependency of installadm. If necessary, adjust the inetd_start/exec property to run tftp out of /etc/netboot. Raises ServicesError if tftp/udp6 is configured to use a different directory, and that directory exists and has files. ''' getprop = [SVCPROP, '-p', INET_START_PROP, TFTP_FMRI] svcprop_popen = Popen.check_call(getprop, stdout=Popen.STORE, stderr=Popen.STORE) inet_start = svcprop_popen.stdout.strip().split() if inet_start[-1] != com.BOOT_DIR: if (os.path.exists(inet_start[-1]) and os.path.isdir(inet_start[-1]) and os.listdir(inet_start[-1])): raise ServicesError(cw(_("The %(svc)s service has been configured " "to use the %(dir)s directory; " "installadm is incompatible with these " "settings. Please use svccfg to change " "the %(prop)s property of the %(svc)s " "service to migrate to the %(desired)s " "directory.") % {'svc': TFTP_FMRI, 'dir': inet_start[-1], 'desired': com.BOOT_DIR, 'prop': INET_START_PROP})) setprop = [SVCCFG, '-s', TFTP_FMRI, 'setprop', 'inetd_start/exec', '=', INET_START % com.BOOT_DIR] Popen.check_call(setprop) Popen.check_call([SVCADM, 'refresh', TFTP_FMRI]) Popen.check_call([SVCADM, 'enable', TFTP_FMRI])
def setUp(self): # Before running any tests, ensure Multicast DNS SMF is enabled. cmd = ["/usr/bin/svcs", "-H", "-o", "STATE", "svc:/network/dns/multicast:default"] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE) if p.stdout.strip() != "online": raise SkipTest("Unable to run FindAPI tests - enable SMF service " "svc:/network/dns/multicast:default") self.bogosvc = None
def test_log_err(self): '''Popen.check_call(..., logger=some_logger) logs stderr''' logger = MockLogger(100) popen = Popen.check_call(self.cmd(0), stderr=Popen.STORE, logger=logger, stderr_loglevel=100, check_result=(0, )) self.assertTrue("--stderr--" in logger.msgs[100][0], logger.msgs[100][0])
def _write_loader(self, devname, data_root): """Invoke installgrub to write stage1 and stage2 to disk. Slice nodes (and only slice nodes) are required.""" if not ((len(devname) > 2 and devname[-2] == 's' and devname[-1].isdigit()) or (len(devname) > 3 and devname[-3] == 's' and devname[-2:].isdigit())): raise BootLoaderInstallError('Device node is not a slice: ' + devname) args = ['/sbin/installgrub'] # installgrub will autodetect when to use the -m switch # If a version is present, try to use it during installation. if self.version is not None: args += ['-u', self.version] args += [ data_root + '/boot/grub/stage1', data_root + '/boot/grub/stage2', devname ] self._debug('_write_loader: Invoking command: ' + ' '.join(args)) try: Popen.check_call(args, stdout=Popen.STORE, stderr=Popen.STORE) except CalledProcessError as cpe: self._debug('_write_loader: Return code = %d' % cpe.returncode) if cpe.returncode != LegacyGRUBBootLoader.INSTALLGRUB_NOUPDT: output = '' if cpe.popen is not None and cpe.popen.stderr is not None: output = '\nOutput was:\n' + cpe.popen.stderr raise BootLoaderInstallError('installgrub failed for ' 'device ' + devname + ': Return code ' + str(cpe.returncode) + output) except OSError as ose: raise BootLoaderInstallError('Error while trying to ' 'invoke installgrub for ' 'device ' + devname + ': ' + str(ose))
def create_file(self, path, size="64m"): # look for the file first. if it exists, remove if if os.path.isfile(path): os.unlink(path) # create the file with mkfile cmd = [MKFILE, size, path] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE) # add the file to the list to destroy later self.file_list.append(path)
def get_imagedir(): ''' get value of default image basedir from AI SMF service ''' getprop = [SVCPROP, '-p', com.BASEDIR_PROP, com.SRVINST] try: svcprop_popen = Popen.check_call(getprop, stdout=Popen.STORE, stderr=Popen.DEVNULL) imagedir = svcprop_popen.stdout.strip() except CalledProcessError: imagedir = com.IMAGE_DIR_PATH return imagedir
def test_stderr_exception(self): '''Popen.check_call(..., check_result=(Popen.STDERR_EMPTY, 0) raises exception on stderr''' try: popen = Popen.check_call(self.cmd(0), stderr=Popen.STORE, check_result=(Popen.STDERR_EMPTY, 0)) except CalledProcessError as err: self.assertEquals("--stderr--\n", err.popen.stderr) self.assertEquals(0, err.popen.returncode) else: self.fail("Expected CalledProcessError when stderr non-empty")
def check_install_SMF(): ''' Check if install/server SMF services is available. returning True if available and False if not. ''' # Ensure system/install/server SMF service is available and online cmd = ["/usr/bin/svcs", "svc:/system/install/server"] try: output = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE) if output.stdout.split()[3] != 'online': raise SkipTest("svc:/system/install/server not enabled") except CalledProcessError: # This system does not have the service so skip the test raise SkipTest("svc:/system/install/server not installed")
def store_pid(): '''Store the process ID for registering all services. Args None Globals PIDFILE - location to store the register PID, the PID is used by installadm delete-service/create-service, used REMOVE_PID - flag to indicate if the PID file should be removed, modified Returns None Raises None ''' global REMOVE_PID # ensure that the PIDFILE is removed REMOVE_PID = True if os.path.exists(PIDFILE): try: linecache.checkcache(PIDFILE) pid = int(linecache.getline(PIDFILE, 1).strip('\n')) # see if aimdns is still running via pgrep cmd = ["/usr/bin/pgrep", "aimdns"] pgrep_proc = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, check_result=Popen.ANY) if pgrep_proc.stderr: print pgrep_proc.stderr else: for pgrep_pid in pgrep_proc.stdout.split('\n')[:-1]: runpid = int(pgrep_pid) if runpid == pid: sys.stderr.write( _('error: aimdns already running ' '(pid %d)\n') % pid) sys.exit(1) except ValueError: # var/run/aimdns file left over, truncate via open it. pass with open(PIDFILE, 'w+') as pidfile: mystr = str(os.getpid()) + '\n' pidfile.write(mystr)
def profile_is_valid(profile_name): '''Validate system configuration profile: - profile has to have .xml extension, otherwise smf(5) refuses to apply it - profile has to syntactically validate using 'svccfg apply -n' Return: True if profile is valid, otherwise False ''' # Check if profile contains .xml suffix. if not profile_name.endswith(".xml"): print _("Custom site profile %s is invalid, missing .xml suffix." % profile_name) return False # Validate file syntactically. try: Popen.check_call([SVCCFG, "apply", "-n", profile_name]) except CalledProcessError: print _("Custom site profile %s is invalid or has" "invalid permissions." % profile_name) return False return True
def test_check_result_ignore(self): '''Popen.check_call(..., check_result=Popen.ANY) ignores return codes''' try: popen = Popen.check_call(self.cmd(0), check_result=Popen.ANY) except CalledProcessError as err: self.fail("Unexpected CalledProcessError: %s" % err) cmd2 = [ sys.executable, "-c", "import sys;" "print '--stdout--';" "sys.exit(0)" ] try: popen = Popen.check_call(cmd2, check_result=Popen.ANY) except CalledProcessError as err: self.fail("Unexpected CalledProcessError: %s" % err) self.assertEquals(0, popen.returncode) try: popen = Popen.check_call(self.cmd(4), check_result=Popen.ANY) except CalledProcessError as err: self.fail("Unexpected CalledProcessError: %s" % err) self.assertEquals(4, popen.returncode)
def filesystems(self): """ method to return all filesystems which belong to the pool """ filesystem_list = [] # if the zpool doesn't yet exist, return an empty list if not self.exists: return filesystem_list cmd = [ZFS, "list", "-H", "-t", "filesystem", "-o", "name", "-r", self.name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) for fs in p.stdout.splitlines(): filesystem_list.append(Filesystem(fs)) return filesystem_list
def is_iso(filepath): '''Check if the supplied file spec is an (hsfs) ISO file, by using fstyp(1M) Input: filepath - The file at this path will be checked Return: True - file is an ISO False - otherwise ''' if not filepath: return False cmd = [_FILE, filepath] file_type = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.DEVNULL) return ('ISO 9660' in file_type.stdout)
def destroy(self, dry_run): """ method to destroy a zvol. """ if self.exists: if not dry_run: full_path = os.path.join("/dev/zvol/dsk", self.full_name) # look to see if this zvol is in use by swap. If so, remove it # from swap control cmd = [SWAP, "-l"] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, check_result=Popen.ANY, stderr_loglevel=logging.DEBUG) # remove the header and look for the zvol swap_list = p.stdout.splitlines()[1:] for entry in swap_list: if entry.startswith(full_path): cmd = [SWAP, "-d", full_path] Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN, stderr_loglevel=logging.DEBUG) # TODO: CR 6910925 prevents the removal of zvols marked for # use by dumpadm. Until that bug is fixed, we can not remove # the zvol from dumpadm control or destroy the zvol. # look to see if this zvol is under dumpadm control. If it is, # we can't remove it. p = Popen.check_call([DUMPADM], stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) for line in p.stdout.splitlines(): if line.lstrip().startswith("Dump device:"): if full_path in line: logger = logging.getLogger(ILN) logger.warning("Unable to destroy Zvol '%s' as it " "is under dumpadm control" % self.full_name) break else: cmd = [ZFS, "destroy", self.full_name] Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN)
def test_log_blank_lines_ignored(self): '''Popen.check_call() skips logging of blank lines of output''' logger = MockLogger(100) lines = '\\n' * 6 expected_log = ['\n' * 6] cmd = [ sys.executable, "-c", "import sys;" "sys.stderr.write('%s')" % lines ] popen = Popen.check_call(cmd, stderr=subprocess.PIPE, logger=logger, stdout_loglevel=0, stderr_loglevel=100, check_result=Popen.ANY) # No output should have been logged to the MockLogger self.assertFalse(100 in logger.msgs, logger.msgs.get(100, ''))
def get(self, propname="all"): """ get() - method to return a specific zpool property. propname - name of the property to return. If the user does not specify a propname, return all pool properties """ cmd = [ZPOOL, "get", propname, self.name] p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE, logger=ILN) # construct a dictionary of properties prop_dict = dict() # skip the header line for line in p.stdout.splitlines()[1:]: # The output from zpool get is in four columns: # NAME PROPERTY VALUE SOURCE # We're only interested in the PROPERTY and VALUE columns _none, prop, value, _none = line.strip().split() prop_dict[prop] = value return prop_dict
def set_system_clock(self): ''' Set the system date/time, based on the values entered on the screen. ''' # Set system time as per the entered date/time values year = self.yearspinner.get_value() month = self.monthspinner.get_value() day = self.dayspinner.get_value() hour = self.hourspinner.get_value() minute = self.minutespinner.get_value() # Preserve the current seconds values second = datetime.now().second newdatetime = "%02d%02d%02d%02d%04d.%02d" % \ (month, day, hour, minute, year, second) cmd = [DATE_CMD, newdatetime] LOGGER.info("Running command: %s" % cmd) try: p = Popen.check_call(cmd, stdout=Popen.STORE) except CalledProcessError, err: LOGGER.error("ERROR: [%s] [%s]" % (cmd, err)) return False