def test_sign(self): foo = "Some random data." sig = utils.sign_data(foo) self.assertTrue(sig) basepath = os.path.dirname(__file__) with open(os.path.join(basepath, "../device_inventory/data/public.key")) as pubkey: self.gpg.import_keys(pubkey.read()) verify = self.gpg.verify(sig) self.assertTrue(verify.valid)
def main(argv=None): if not os.geteuid() == 0: sys.exit("Only root can run this script") # configure logging setup_logging() logger = logging.getLogger(__name__) parser = argparse.ArgumentParser() # allow enabling/disabling debug mode group = parser.add_mutually_exclusive_group() group.add_argument('--debug', action='store_true', help='enable debug mode (extended output file!)') group.add_argument('--no-debug', dest='debug', action='store_false', help='disable debug mode') parser.set_defaults(debug=None) parser.add_argument('--smart', choices=['none', 'short', 'long']) parser.add_argument('--erase', choices=['ask', 'yes', 'no']) parser.add_argument('--stress', metavar='MINUTES', type=int, help='run stress test for the given MINUTES (0 to disable, default)') parser.add_argument('--install', choices=['ask', 'yes', 'no'], help='install a system image ("yes" avoids confirmation)') parser.add_argument('--image-name', metavar='NAME', help='select the system image with the given NAME for installation') parser.add_argument('--settings', help='file to be loaded as config file') args = parser.parse_args() # try to get custom config file from PXE server server = settings.get('server', 'address') username = settings.get('server', 'username') password = settings.get('server', 'password') localpath = '/tmp/remote_custom_config.ini' remotepath = '/home/ereuse/config.ini' try: storage.get_file_from_server(remotepath, localpath, username, password, server) except Exception as e: # TODO catch specific exceptions to avoid mask errors logging.error("Error retrieving config file '%s' from server '%s'", remotepath, server) logging.debug(e) else: print("Loading configuration from '%s'" % localpath) settings.load_config(config_file=localpath) # load specified config file (if any) if args.settings: cfg = settings.load_config(config_file=args.settings) # override settings with command line args if args.smart: settings.set('DEFAULT', 'smart', args.smart) if args.erase: settings.set('eraser', 'erase', args.erase) if args.stress is not None: settings.set('DEFAULT', 'stress', str(args.stress)) if args.install is not None: settings.set('installer', 'install', args.install) if args.image_name is not None: settings.set('installer', 'image_name', args.image_name) if args.debug is not None: settings.set('DEFAULT', 'debug', str(args.debug).lower()) debug = settings.getboolean('DEFAULT', 'debug') user_input = get_user_input() kwargs = dict(type=user_input.pop('device_type'), smart=args.smart) device = Computer(**kwargs) # TODO move smart call here!!! # call eraser for every hard disk! for hd in device.hard_disk: hd.erasure = eraser.do_erasure(hd.logical_name) hd.benchmark = benchmark_hdd(hd.logical_name) # FIXME hack to exclude logical_name from serialization # create serializer where you can exclude fields delattr(hd, 'logical_name') data = serializers.export_to_devicehub_schema(device, user_input, debug) # Add a temporary, meaningless unique identifier just to avoid uploading # the very same file twice (this doesn't cover the case of e.g. running # the inventory twice on the same machine with different labels). See # issue #57. data['_uuid'] = str(uuid.uuid4()) # random UUID # TODO save on the home filebase = ((data.get('label') or device.verbose_name) .replace(':', '-') .replace(os.path.sep, '-')) filename = "{0}.json".format(filebase) # get_option localpath = os.path.join("/tmp", filename) with open(localpath, "w") as outfile: json.dump(data, outfile, indent=4, sort_keys=True, cls=InvEncoder) # sign output if settings.getboolean('signature', 'sign_output'): signed_data = utils.sign_data(json.dumps(data, indent=4, sort_keys=True, cls=InvEncoder)) filename = "{0}.json.asc".format(filebase) localpath = os.path.join("/tmp", filename) with open(localpath, "w") as outfile: outfile.write(signed_data) # send files to the PXE Server if settings.getboolean('DEFAULT', 'sendtoserver'): remotepath = os.path.join(settings.get('server', 'remotepath'), filename) username = settings.get('server', 'username') password = settings.get('server', 'password') server = settings.get('server', 'address') try: storage.copy_file_to_server(localpath, remotepath, username, password, server) print("The file `{0}` has been successfully sent to the server.".format(localpath)) except Exception as e: logger.error("Error copying file '%s' to server '%s'", localpath, server) logger.debug(e, exc_info=True) # copy file to an USB drive if settings.getboolean('DEFAULT', 'copy_to_usb'): try: storage.copy_file_to_usb(localpath) except KeyboardInterrupt: print("Copy to USB cancelled by user!") except Exception as e: logger.error("Error copying file '%s' to USB", localpath) logger.debug(e, exc_info=True) # run stress test stress_mins = settings.getint('DEFAULT', 'stress') if stress_mins > 0: print("Performing stress test for %d minutes, press Ctrl+C at any time to cancel." % stress_mins) try: if stress(stress_mins): print("Stress test succeeded.") else: print("Stress test failed, please note this down.") except KeyboardInterrupt: print("Stress test cancelled by user!") except Exception as e: logger.error("Error running stress test") logger.debug(e, exc_info=True) else: print("Skipping stress test (not enabled in remote configuration file).") # install system image install_image = settings.get('installer', 'install') if install_image in ('yes', 'ask'): image_name = settings.get('installer', 'image_name') print("Starting installation of system image.") try: install(name=image_name, confirm=(install_image == 'ask')) except KeyboardInterrupt: print("System installation cancelled by user!") except Exception as e: logger.error("Error installing system image") logger.debug(e, exc_info=True) else: print("Skipping installation (not enabled in remote configuration file).") print("Device Inventory has finished properly: {0}".format(localpath))