def uploader(uploader_method, profile, simulate=True): """ Context-managed uploader implementation. Invoke sorta like:: with uploader() as obj: obj.upload_file('filename') This will automatically call that object's :meth:`dput.uploader.AbstractUploader.initialize`, pre-hook, yield the object, call the post hook and invoke it's :meth:`dput.uploader.AbstractUploader.shutdown`. """ cls = get_obj('uploaders', uploader_method) if not cls: logger.error( "Failed to resolve method %s to an uploader class" % ( uploader_method ) ) raise DputConfigurationError( "Failed to resolve method %s to an uploader class" % ( uploader_method ) ) obj = cls(profile) if not simulate or simulate >= 2: obj.initialize() obj._pre_hook() try: yield obj finally: if not simulate: obj._post_hook() if not simulate or simulate >= 2: obj.shutdown()
def run_command(command): """ Run a synchronized command. The argument must be a list of arguments. Returns a triple (stdout, stderr, exit_status) If there was a problem to start the supplied command, (None, None, -1) is returned """ if not isinstance(command, list): command = shlex.split(command) try: pipe = subprocess.Popen(command, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except OSError as e: logger.error("Could not execute %s: %s" % (" ".join(command), e)) return (None, None, -1) (output, stderr) = pipe.communicate() #if pipe.returncode != 0: # error("Command %s returned failure: %s" % (" ".join(command), stderr)) return (output, stderr, pipe.returncode)
def invoke_dcut(args): profile = dput.profile.load_profile(args.host) fqdn = None if "fqdn" in profile: fqdn = profile["fqdn"] if not "allow_dcut" in profile or not profile["allow_dcut"]: raise UploadException( "Profile %s does not allow command file uploads" "Please set allow_dcut=1 to allow such uploads" ) logger.info("Uploading commands file to %s (incoming: %s)" % (fqdn or profile["name"], profile["incoming"])) if args.simulate: logger.warning("Not uploading for real - dry run") command = args.command assert issubclass(type(command), AbstractCommand) command.validate(args) if args.passive: force_passive_ftp_upload(profile) upload_path = None fh = None upload_filename = command.generate_commands_name(profile) try: if command.cmd_name == "upload": logger.debug("Uploading file %s as is to %s" % (args.upload_file, profile["name"])) if not os.access(args.upload_file, os.R_OK): raise DcutError("Cannot access %s: No such file" % (args.upload_file)) upload_path = args.upload_file else: fh = tempfile.NamedTemporaryFile(mode="w+r", delete=False) (name, email) = write_header(fh, profile, args) command.produce(fh, args) fh.flush() # print fh.name fh.close() signing_key = None if "default_keyid" in profile: signing_key = profile["default_keyid"] if args.keyid: signing_key = args.keyid sign_file(fh.name, signing_key, profile, name, email) upload_path = fh.name if not args.simulate and not args.output: upload_commands_file(upload_path, upload_filename, profile, args) elif args.output and not args.simulate: if os.access(args.output, os.R_OK): logger.error("Not writing %s: File already exists" % (args.output)) # ... but intentionally do nothing # TODO: or raise exception? return shutil.move(fh.name, args.output) elif args.simulate: pass else: # we should *never* come here assert False finally: if fh and os.access(fh.name, os.R_OK): os.unlink(fh.name)